From fa89274e2d90ad3273c98a3059184f8d06195528 Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Tue, 16 Nov 2021 20:58:44 -0500 Subject: [PATCH 001/614] add PCT_URBAN in landuse.timeseries data In normalizencheck_landuse, still reduce crop and natveg proportionally when urban exist. --- tools/mksurfdata_map/mksurfdata.pl | 3 + tools/mksurfdata_map/src/mkfileMod.F90 | 7 + tools/mksurfdata_map/src/mksurfdat.F90 | 185 +++++++++++++-------- tools/mksurfdata_map/src/mkurbanparMod.F90 | 29 +++- 4 files changed, 150 insertions(+), 74 deletions(-) diff --git a/tools/mksurfdata_map/mksurfdata.pl b/tools/mksurfdata_map/mksurfdata.pl index f9961c7f9e..9d2fe238d3 100755 --- a/tools/mksurfdata_map/mksurfdata.pl +++ b/tools/mksurfdata_map/mksurfdata.pl @@ -284,6 +284,9 @@ sub write_transient_timeseries_file { my $hrvtypyr = `$scrdir/../../bld/queryDefaultNamelist.pl $queryfilopts $resolhrv -options sim_year='$yr',ssp_rcp=${ssp_rcp}${mkcrop} -var mksrf_fvegtyp -namelist clmexp`; chomp( $hrvtypyr ); printf $fh_landuse_timeseries $dynpft_format, $hrvtypyr, $yr; + my $urbanyr = "/glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_".$yr."_new_NoAdjust.nc"; + chomp( $urbanyr); + printf $fh_landuse_urban_timeseries $dynpft_format, $urbanyr, $yr; # Keer: I don't quiet understand the 'pft_override' option so I made no change to the "landuse_timeseries_override_$desc.txt" if ( $yr % 100 == 0 ) { print "year: $yr\n"; } diff --git a/tools/mksurfdata_map/src/mkfileMod.F90 b/tools/mksurfdata_map/src/mkfileMod.F90 index 43bdda4c12..963e386348 100644 --- a/tools/mksurfdata_map/src/mkfileMod.F90 +++ b/tools/mksurfdata_map/src/mkfileMod.F90 @@ -540,7 +540,14 @@ subroutine mkfile(domain, fname, harvdata, dynlanduse) deallocate(ind1D, ind2D) else + call ncd_def_spatial_var(ncid=ncid, varname='PCT_URBAN', xtype=xtype, & + lev1name='numurbl', lev2name='time', & + long_name='percent urban for each density type', units='unitless') + call ncd_def_spatial_var(ncid=ncid, varname='PCT_URBAN_MAX', xtype=xtype, & + lev1name='numurbl', & + long_name='maximum percent urban for each density type', units='unitless') + call harvdata%getFieldsIdx( ind1D, ind2D ) do j = 1, harvdata%num1Dfields() call ncd_def_spatial_var(ncid=ncid, varname=mkharvest_fieldname(ind1D(j),constant=.false.), xtype=xtype, & diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index bc6ef6f028..d1ae730130 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -29,7 +29,7 @@ program mksurfdat use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride use mkharvestMod , only : harvestDataType use mkurbanparCommonMod, only : mkelev - use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, numurbl + use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, numurbl, update_max_array_urban use mkutilsMod , only : normalize_classes_by_gcell use mkfileMod , only : mkfile use mkvarpar , only : nlevsoi, elev_thresh, numstdpft @@ -80,6 +80,7 @@ program mksurfdat character(len=256) :: fdyndat ! dynamic landuse data file name character(len=256) :: fname ! generic filename character(len=256) :: fhrvname ! generic harvest filename + character(len=256) :: furbname ! generic transient urban land cover filename character(len=256) :: string ! string read in integer :: t1 ! timer real(r8),parameter :: p5 = 0.5_r8 ! constant @@ -108,6 +109,7 @@ program mksurfdat real(r8), allocatable :: pctlak(:) ! percent of grid cell that is lake real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland real(r8), allocatable :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) + real(r8), allocatable :: pcturb_max(:,:) ! maximum percent cover of each urban class, as % of grid cell real(r8), allocatable :: urbn_classes(:,:) ! percent cover of each urban class, as % of total urban area real(r8), allocatable :: urbn_classes_g(:,:)! percent cover of each urban class, as % of grid cell real(r8), allocatable :: elev(:) ! glc elevation (m) @@ -134,6 +136,10 @@ program mksurfdat real(r8), allocatable :: vic_dsmax(:) ! VIC Dsmax parameter (mm/day) real(r8), allocatable :: vic_ds(:) ! VIC Ds parameter (unitless) real(r8), allocatable :: lakedepth(:) ! lake depth (m) + real(r8), allocatable :: pctlak_orig(:) ! percent lake of gridcell before dynamic land use adjustments + real(r8), allocatable :: pctwet_orig(:) ! percent wetland of gridcell before dynamic land use adjustments + real(r8), allocatable :: pcturb_orig(:) ! percent urban of gridcell before dynamic land use adjustments + real(r8), allocatable :: pctgla_orig(:) ! percent glacier of gridcell before dynamic land use adjustments real(r8) :: std_elev = -999.99_r8 ! Standard deviation of elevation (m) to use for entire grid @@ -277,7 +283,7 @@ program mksurfdat ! ====================================== ! Optionally specify setting for: ! ====================================== - ! mksrf_fdynuse ----- ASCII text file that lists each year of pft files to use + ! mksrf_fdynuse ----- ASCII text file that lists each year of pft and urban files to use ! mksrf_gridtype ---- Type of grid (default is 'global') ! outnc_double ------ If output should be in double precision ! outnc_large_files - If output should be in NetCDF large file format @@ -442,6 +448,7 @@ program mksurfdat pctlak(ns_o) , & pctwet(ns_o) , & pcturb(ns_o) , & + pcturb_max(ns_o,numurbl) , & urban_region(ns_o) , & urbn_classes(ns_o,numurbl) , & urbn_classes_g(ns_o,numurbl) , & @@ -459,7 +466,11 @@ program mksurfdat vic_dsmax(ns_o) , & vic_ds(ns_o) , & lakedepth(ns_o) , & - glacier_region(ns_o) ) + glacier_region(ns_o) , & + pctlak_orig(ns_o) , & + pctwet_orig(ns_o) , & + pcturb_orig(ns_o) , & + pctgla_orig(ns_o) ) landfrac_pft(:) = spval pctlnd_pft(:) = spval pftdata_mask(:) = -999 @@ -644,6 +655,12 @@ program mksurfdat ndiag=ndiag, zero_out=all_veg, urbn_o=pcturb, urbn_classes_o=urbn_classes, & region_o=urban_region) + ! Save special land unit areas of surface dataset + pctlak_orig(:) = pctlak(:) + pctwet_orig(:) = pctwet(:) + pcturb_orig(:) = pcturb(:) + pctgla_orig(:) = pctgla(:) + ! Make elevation [elev] from [ftopo, ffrac] dataset ! Used only to screen pcturb ! Screen pcturb by elevation threshold from elev dataset @@ -662,7 +679,6 @@ program mksurfdat where (elev .gt. elev_thresh) pcturb = 0._r8 end where - deallocate(elev) end if ! Compute topography statistics [topo_stddev, slope] from [ftopostats] @@ -709,62 +725,6 @@ program mksurfdat call change_landuse( ldomain, dynpft=.false. ) - do n = 1,ns_o - - ! Truncate all percentage fields on output grid. This is needed to - ! insure that wt is zero (not a very small number such as - ! 1e-16) where it really should be zero - - do k = 1,nlevsoi - pctsand(n,k) = float(nint(pctsand(n,k))) - pctclay(n,k) = float(nint(pctclay(n,k))) - end do - pctlak(n) = float(nint(pctlak(n))) - pctwet(n) = float(nint(pctwet(n))) - pctgla(n) = float(nint(pctgla(n))) - - ! Assume wetland, glacier and/or lake when dataset landmask implies ocean - ! (assume medium soil color (15) and loamy texture). - ! Also set pftdata_mask here - - if (pctlnd_pft(n) < 1.e-6_r8) then - pftdata_mask(n) = 0 - soicol(n) = 15 - if (pctgla(n) < 1.e-6_r8) then - pctwet(n) = 100._r8 - pctlak(n) - pctgla(n) = 0._r8 - else - pctwet(n) = max(100._r8 - pctgla(n) - pctlak(n), 0.0_r8) - end if - pcturb(n) = 0._r8 - call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) - pctsand(n,:) = 43._r8 - pctclay(n,:) = 18._r8 - organic(n,:) = 0._r8 - else - pftdata_mask(n) = 1 - end if - - ! Make sure sum of land cover types does not exceed 100. If it does, - ! subtract excess from most dominant land cover. - - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - if (suma > 250._r4) then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb and pctgla is greater than 250%' - write (6,*)'n,pctlak,pctwet,pcturb,pctgla= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n) - call abort() - else if (suma > 100._r4) then - pctlak(n) = pctlak(n) * 100._r8/suma - pctwet(n) = pctwet(n) * 100._r8/suma - pcturb(n) = pcturb(n) * 100._r8/suma - pctgla(n) = pctgla(n) * 100._r8/suma - end if - - end do - call normalizencheck_landuse(ldomain) ! Write out sum of PFT's @@ -1062,14 +1022,11 @@ program mksurfdat ! Deallocate arrays NOT needed for dynamic-pft section of code - deallocate ( organic ) deallocate ( ef1_btr, ef1_fet, ef1_fdt, ef1_shr, ef1_grs, ef1_crp ) deallocate ( pctglcmec, topoglcmec) if ( outnc_3dglc ) deallocate ( pctglc_gic, pctglc_icesheet) deallocate ( elevclass ) deallocate ( fmax ) - deallocate ( pctsand, pctclay ) - deallocate ( soicol ) deallocate ( gdp, fpeat, agfirepkmon ) deallocate ( soildepth ) deallocate ( topo_stddev, slope ) @@ -1130,6 +1087,7 @@ program mksurfdat pctnatpft_max = pctnatpft pctcft_max = pctcft + pcturb_max = urbn_classes_g ntim = 0 do @@ -1159,6 +1117,13 @@ program mksurfdat call abort() end if end if + ! Read input urban data + read(nfdyn, '(A195,1x,I4)', iostat=ier) furbname, year2 + if ( year2 /= year ) then + write(6,*) subname, ' error: year for urban not equal to year for PFT files' + call abort() + end if + write(6,*)'input urban dynamic dataset for year ', year2, ' is : ', trim(furbname) ntim = ntim + 1 ! Create pctpft data at model resolution @@ -1187,21 +1152,43 @@ program mksurfdat end if end do + + call mkurban (ldomain, mapfname=map_furban, datfname=furbname, & + ndiag=ndiag, zero_out=all_veg, urbn_o=pcturb, urbn_classes_o=urbn_classes, & + region_o=urban_region) + ! screen pcturb using elevation + if ( .not. all_urban .and. .not. all_veg )then + where (elev .gt. elev_thresh) + pcturb = 0._r8 + end where + end if + + ! For landunits NOT read each year: reset to their pre-adjustment values in preparation for redoing landunit area normalization + pctwet(:) = pctwet_orig(:) + pctlak(:) = pctlak_orig(:) + pctgla(:) = pctgla_orig(:) + call change_landuse(ldomain, dynpft=.true.) call normalizencheck_landuse(ldomain) - + call normalize_classes_by_gcell(urbn_classes, pcturb, urbn_classes_g) + call update_max_array(pctnatpft_max,pctnatpft) call update_max_array(pctcft_max,pctcft) + call update_max_array_urban(pcturb_max,urbn_classes_g) ! Output time-varying data for current year - + call check_ret(nf_inq_varid(ncid, 'PCT_NATVEG', varid), subname) + call ncd_put_time_slice(ncid, varid, ntim, get_pct_l2g_array(pctnatpft)) + call check_ret(nf_inq_varid(ncid, 'PCT_NAT_PFT', varid), subname) call ncd_put_time_slice(ncid, varid, ntim, get_pct_p2l_array(pctnatpft)) call check_ret(nf_inq_varid(ncid, 'PCT_CROP', varid), subname) call ncd_put_time_slice(ncid, varid, ntim, get_pct_l2g_array(pctcft)) - + + call check_ret(nf_inq_varid(ncid, 'PCT_URBAN', varid), subname) + call ncd_put_time_slice(ncid, varid, ntim, urbn_classes_g) if (num_cft > 0) then call check_ret(nf_inq_varid(ncid, 'PCT_CFT', varid), subname) call ncd_put_time_slice(ncid, varid, ntim, get_pct_p2l_array(pctcft)) @@ -1241,6 +1228,9 @@ program mksurfdat call check_ret(nf_inq_varid(ncid, 'PCT_CROP_MAX', varid), subname) call check_ret(nf_put_var_double(ncid, varid, get_pct_l2g_array(pctcft_max)), subname) + call check_ret(nf_inq_varid(ncid, 'PCT_URBAN_MAX', varid), subname) + call check_ret(nf_put_var_double(ncid, varid, pcturb_max), subname) + if (num_cft > 0) then call check_ret(nf_inq_varid(ncid, 'PCT_CFT_MAX', varid), subname) call check_ret(nf_put_var_double(ncid, varid, get_pct_p2l_array(pctcft_max)), subname) @@ -1339,7 +1329,7 @@ subroutine normalizencheck_landuse(ldomain) ! Normalize land use and make sure things add up to 100% as well as ! checking that things are as they should be. ! -! Precondition: pctlak + pctwet + pcturb + pctgla <= 100 (within roundoff) +! ! ! !USES: use mkpftConstantsMod , only : baregroundindex @@ -1369,14 +1359,61 @@ subroutine normalizencheck_landuse(ldomain) real(r8), parameter :: toosmallPFT = 1.e-10_r8 ! tolerance for PFT's to ignore character(len=32) :: subname = 'normalizencheck_landuse' ! subroutine name !----------------------------------------------------------------------- - - ! ------------------------------------------------------------------------ - ! Normalize vegetated area so that vegetated + special area is 100% - ! ------------------------------------------------------------------------ - ns_o = ldomain%ns do n = 1,ns_o + ! Truncate all percentage fields on output grid. This is needed to + ! insure that wt is zero (not a very small number such as + ! 1e-16) where it really should be zero + + do k = 1,nlevsoi + pctsand(n,k) = float(nint(pctsand(n,k))) + pctclay(n,k) = float(nint(pctclay(n,k))) + end do + pctlak(n) = float(nint(pctlak(n))) + pctwet(n) = float(nint(pctwet(n))) + pctgla(n) = float(nint(pctgla(n))) + + ! Assume wetland, glacier and/or lake when dataset landmask implies ocean + ! (assume medium soil color (15) and loamy texture). + ! Also set pftdata_mask here + + if (pctlnd_pft(n) < 1.e-6_r8) then + pftdata_mask(n) = 0 + soicol(n) = 15 + if (pctgla(n) < 1.e-6_r8) then + pctwet(n) = 100._r8 - pctlak(n) + pctgla(n) = 0._r8 + else + pctwet(n) = max(100._r8 - pctgla(n) - pctlak(n), 0.0_r8) + end if + pcturb(n) = 0._r8 + call pctnatpft(n)%set_pct_l2g(0._r8) + call pctcft(n)%set_pct_l2g(0._r8) + pctsand(n,:) = 43._r8 + pctclay(n,:) = 18._r8 + organic(n,:) = 0._r8 + else + pftdata_mask(n) = 1 + end if + + ! Make sure sum of land cover types does not exceed 100. If it does, + ! subtract excess from most dominant land cover. + + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + if (suma > 250._r4) then + write (6,*) subname, ' error: sum of pctlak, pctwet,', & + 'pcturb and pctgla is greater than 250%' + write (6,*)'n,pctlak,pctwet,pcturb,pctgla= ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n) + call abort() + else if (suma > 100._r4) then + pctlak(n) = pctlak(n) * 100._r8/suma + pctwet(n) = pctwet(n) * 100._r8/suma + pcturb(n) = pcturb(n) * 100._r8/suma + pctgla(n) = pctgla(n) * 100._r8/suma + end if + ! Check preconditions if ( pctlak(n) < 0.0_r8 )then write(6,*) subname, ' ERROR: pctlak is negative!' @@ -1407,7 +1444,9 @@ subroutine normalizencheck_landuse(ldomain) n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) call abort() end if - + ! ------------------------------------------------------------------------ + ! Normalize vegetated area so that vegetated + special area is 100% + ! ------------------------------------------------------------------------ ! First normalize vegetated (natural veg + crop) cover so that the total of ! (vegetated + (special excluding urban)) is 100%. We'll deal with urban later. ! diff --git a/tools/mksurfdata_map/src/mkurbanparMod.F90 b/tools/mksurfdata_map/src/mkurbanparMod.F90 index 07319b1f27..35bbb0ad82 100644 --- a/tools/mksurfdata_map/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_map/src/mkurbanparMod.F90 @@ -23,7 +23,8 @@ module mkurbanparMod public :: mkurbanInit public :: mkurban public :: mkurbanpar - + public :: update_max_array_urban + ! The following could be private, but because there are associated test routines in a ! separate module, it needs to be public public :: normalize_urbn_by_tot @@ -756,4 +757,30 @@ end subroutine lookup_and_check_err end subroutine mkurbanpar !------------------------------------------------------------------------------ +!----------------------------------------------------------------------- +subroutine update_max_array_urban(pct_urbmax_arr,pct_urban_arr) + ! + ! !DESCRIPTION: + ! Update the maximum percent cover of each urban class + ! + ! !ARGUMENTS: + real(r8) , intent(inout):: pct_urbmax_arr(:,:) ! max percent cover of each urban class + real(r8) , intent(in):: pct_urban_arr(:,:) ! percent cover of each urban class that is used to update the old pct_urbmax_arr + ! + ! !LOCAL VARIABLES: + integer :: n,k,ns ! indices + + character(len=*), parameter :: subname = 'update_max_array_urban' + !----------------------------------------------------------------------- + ns = size(pct_urban_arr,1) + do n = 1, ns + do k =1, numurbl + if (pct_urban_arr(n,k) > pct_urbmax_arr(n,k)) then + pct_urbmax_arr(n,k) = pct_urban_arr(n,k) + end if + end do + end do + +end subroutine update_max_array_urban + end module mkurbanparMod From 5c69e8ceea71f6b6c6ab6b6728f83ed8eae1d405 Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Wed, 17 Nov 2021 09:28:53 -0500 Subject: [PATCH 002/614] changed a txt file name changed a txt file name --- tools/mksurfdata_map/mksurfdata.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_map/mksurfdata.pl b/tools/mksurfdata_map/mksurfdata.pl index 9d2fe238d3..3caa4eb009 100755 --- a/tools/mksurfdata_map/mksurfdata.pl +++ b/tools/mksurfdata_map/mksurfdata.pl @@ -286,7 +286,7 @@ sub write_transient_timeseries_file { printf $fh_landuse_timeseries $dynpft_format, $hrvtypyr, $yr; my $urbanyr = "/glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_".$yr."_new_NoAdjust.nc"; chomp( $urbanyr); - printf $fh_landuse_urban_timeseries $dynpft_format, $urbanyr, $yr; # Keer: I don't quiet understand the 'pft_override' option so I made no change to the "landuse_timeseries_override_$desc.txt" + printf $fh_landuse_timeseries $dynpft_format, $urbanyr, $yr; # Keer: I don't quiet understand the 'pft_override' option so I made no change to the "landuse_timeseries_override_$desc.txt" if ( $yr % 100 == 0 ) { print "year: $yr\n"; } From 71318fa36e1c578a7464095b62623eeaa716d9b9 Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Wed, 17 Nov 2021 11:36:05 -0500 Subject: [PATCH 003/614] Add PCT_NATVEG for testing purpose Add PCT_NATVEG for testing purpose --- tools/mksurfdata_map/src/mkfileMod.F90 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/mksurfdata_map/src/mkfileMod.F90 b/tools/mksurfdata_map/src/mkfileMod.F90 index 963e386348..bb854a9490 100644 --- a/tools/mksurfdata_map/src/mkfileMod.F90 +++ b/tools/mksurfdata_map/src/mkfileMod.F90 @@ -547,7 +547,11 @@ subroutine mkfile(domain, fname, harvdata, dynlanduse) call ncd_def_spatial_var(ncid=ncid, varname='PCT_URBAN_MAX', xtype=xtype, & lev1name='numurbl', & long_name='maximum percent urban for each density type', units='unitless') - + + call ncd_def_spatial_var(ncid=ncid, varname='PCT_NATVEG', xtype=xtype, & + lev1name='time', & + long_name='total percent natural vegetation landunit', units='unitless') + call harvdata%getFieldsIdx( ind1D, ind2D ) do j = 1, harvdata%num1Dfields() call ncd_def_spatial_var(ncid=ncid, varname=mkharvest_fieldname(ind1D(j),constant=.false.), xtype=xtype, & From 88f822a43ce000ab7046931e686a9d4d5a4a2f19 Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Wed, 17 Nov 2021 20:37:52 -0500 Subject: [PATCH 004/614] Delete variable PCT_NATVEG in landuse.timeseries file --- tools/mksurfdata_map/src/mkfileMod.F90 | 3 --- tools/mksurfdata_map/src/mksurfdat.F90 | 2 -- tools/mksurfdata_map/src/mkurbanparMod.F90 | 2 +- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/tools/mksurfdata_map/src/mkfileMod.F90 b/tools/mksurfdata_map/src/mkfileMod.F90 index bb854a9490..d77fe838fb 100644 --- a/tools/mksurfdata_map/src/mkfileMod.F90 +++ b/tools/mksurfdata_map/src/mkfileMod.F90 @@ -548,9 +548,6 @@ subroutine mkfile(domain, fname, harvdata, dynlanduse) lev1name='numurbl', & long_name='maximum percent urban for each density type', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='PCT_NATVEG', xtype=xtype, & - lev1name='time', & - long_name='total percent natural vegetation landunit', units='unitless') call harvdata%getFieldsIdx( ind1D, ind2D ) do j = 1, harvdata%num1Dfields() diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index d1ae730130..81a0f731cf 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -1178,8 +1178,6 @@ program mksurfdat call update_max_array_urban(pcturb_max,urbn_classes_g) ! Output time-varying data for current year - call check_ret(nf_inq_varid(ncid, 'PCT_NATVEG', varid), subname) - call ncd_put_time_slice(ncid, varid, ntim, get_pct_l2g_array(pctnatpft)) call check_ret(nf_inq_varid(ncid, 'PCT_NAT_PFT', varid), subname) call ncd_put_time_slice(ncid, varid, ntim, get_pct_p2l_array(pctnatpft)) diff --git a/tools/mksurfdata_map/src/mkurbanparMod.F90 b/tools/mksurfdata_map/src/mkurbanparMod.F90 index 35bbb0ad82..b47adfb61e 100644 --- a/tools/mksurfdata_map/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_map/src/mkurbanparMod.F90 @@ -761,7 +761,7 @@ end subroutine mkurbanpar subroutine update_max_array_urban(pct_urbmax_arr,pct_urban_arr) ! ! !DESCRIPTION: - ! Update the maximum percent cover of each urban class + ! Update the maximum percent cover of each urban class for landuse.timeseries file ! ! !ARGUMENTS: real(r8) , intent(inout):: pct_urbmax_arr(:,:) ! max percent cover of each urban class From 87b5fbddc8a89a92c73d3b18fd07cc74c9ac72cc Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Mon, 6 Dec 2021 15:49:00 -0500 Subject: [PATCH 005/614] Add hasurban --- tools/mksurfdata_map/src/mkfileMod.F90 | 3 +++ tools/mksurfdata_map/src/mksurfdat.F90 | 14 +++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/mksurfdata_map/src/mkfileMod.F90 b/tools/mksurfdata_map/src/mkfileMod.F90 index d77fe838fb..746d0b3229 100644 --- a/tools/mksurfdata_map/src/mkfileMod.F90 +++ b/tools/mksurfdata_map/src/mkfileMod.F90 @@ -548,6 +548,9 @@ subroutine mkfile(domain, fname, harvdata, dynlanduse) lev1name='numurbl', & long_name='maximum percent urban for each density type', units='unitless') + call ncd_def_spatial_var(ncid=ncid, varname='HASURBAN', xtype=xtype, & + lev1name='numurbl', & + long_name='whether the grid ever has urban during the considered time period', units='unitless') call harvdata%getFieldsIdx( ind1D, ind2D ) do j = 1, harvdata%num1Dfields() diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index 81a0f731cf..03f64bad17 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -110,6 +110,7 @@ program mksurfdat real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland real(r8), allocatable :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) real(r8), allocatable :: pcturb_max(:,:) ! maximum percent cover of each urban class, as % of grid cell + integer , allocatable :: hasurban(:,:) ! whether the urban class should be active in transient urban simulations real(r8), allocatable :: urbn_classes(:,:) ! percent cover of each urban class, as % of total urban area real(r8), allocatable :: urbn_classes_g(:,:)! percent cover of each urban class, as % of grid cell real(r8), allocatable :: elev(:) ! glc elevation (m) @@ -449,6 +450,7 @@ program mksurfdat pctwet(ns_o) , & pcturb(ns_o) , & pcturb_max(ns_o,numurbl) , & + hasurban(ns_o,numurbl) , & urban_region(ns_o) , & urbn_classes(ns_o,numurbl) , & urbn_classes_g(ns_o,numurbl) , & @@ -478,6 +480,7 @@ program mksurfdat pctlak(:) = spval pctwet(:) = spval pcturb(:) = spval + hasurban(:,:) = 0 urban_region(:) = -999 urbn_classes(:,:) = spval urbn_classes_g(:,:) = spval @@ -1219,13 +1222,22 @@ program mksurfdat call check_ret(nf_sync(ncid), subname) end do ! end of read loop - + do n = 1,ns_o + do k =1, numurbl + if pcturb_max(n,k) > 1.e-6_r8 then + hasurban(n,k) = 1 + end if + end do + end do call check_ret(nf_inq_varid(ncid, 'PCT_NAT_PFT_MAX', varid), subname) call check_ret(nf_put_var_double(ncid, varid, get_pct_p2l_array(pctnatpft_max)), subname) call check_ret(nf_inq_varid(ncid, 'PCT_CROP_MAX', varid), subname) call check_ret(nf_put_var_double(ncid, varid, get_pct_l2g_array(pctcft_max)), subname) + call check_ret(nf_inq_varid(ncid, 'HASURBAN', varid), subname) + call check_ret(nf_put_var_double(ncid, varid, hasurban), subname) + call check_ret(nf_inq_varid(ncid, 'PCT_URBAN_MAX', varid), subname) call check_ret(nf_put_var_double(ncid, varid, pcturb_max), subname) From f506bc92cb9f76e0e2ffa7da39f9374ac0bed337 Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Mon, 6 Dec 2021 15:51:44 -0500 Subject: [PATCH 006/614] Fix type (double--int) --- tools/mksurfdata_map/src/mksurfdat.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index 03f64bad17..33aa782303 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -1236,7 +1236,7 @@ program mksurfdat call check_ret(nf_put_var_double(ncid, varid, get_pct_l2g_array(pctcft_max)), subname) call check_ret(nf_inq_varid(ncid, 'HASURBAN', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, hasurban), subname) + call check_ret(nf_put_var_int(ncid, varid, hasurban), subname) call check_ret(nf_inq_varid(ncid, 'PCT_URBAN_MAX', varid), subname) call check_ret(nf_put_var_double(ncid, varid, pcturb_max), subname) From 64abee13ba54736e07f8219789630b7c78424d14 Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Mon, 6 Dec 2021 15:53:33 -0500 Subject: [PATCH 007/614] fix syntax error --- tools/mksurfdata_map/src/mksurfdat.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index 33aa782303..f91cda67f8 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -1224,7 +1224,7 @@ program mksurfdat end do ! end of read loop do n = 1,ns_o do k =1, numurbl - if pcturb_max(n,k) > 1.e-6_r8 then + if (pcturb_max(n,k) > 1.e-6_r8) then hasurban(n,k) = 1 end if end do From b3a6e5a164a6aca59853eff8a083d92f8c460a0b Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Tue, 7 Dec 2021 12:04:16 -0500 Subject: [PATCH 008/614] Delete PCT_URBAN_MAX --- tools/mksurfdata_map/src/mkfileMod.F90 | 6 +----- tools/mksurfdata_map/src/mksurfdat.F90 | 5 +---- tools/mksurfdata_map/src/mkurbanparMod.F90 | 2 +- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/tools/mksurfdata_map/src/mkfileMod.F90 b/tools/mksurfdata_map/src/mkfileMod.F90 index 746d0b3229..084848f5d8 100644 --- a/tools/mksurfdata_map/src/mkfileMod.F90 +++ b/tools/mksurfdata_map/src/mkfileMod.F90 @@ -544,11 +544,7 @@ subroutine mkfile(domain, fname, harvdata, dynlanduse) lev1name='numurbl', lev2name='time', & long_name='percent urban for each density type', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='PCT_URBAN_MAX', xtype=xtype, & - lev1name='numurbl', & - long_name='maximum percent urban for each density type', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='HASURBAN', xtype=xtype, & + call ncd_def_spatial_var(ncid=ncid, varname='HASURBAN', xtype=nf_int, & lev1name='numurbl', & long_name='whether the grid ever has urban during the considered time period', units='unitless') diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index f91cda67f8..3d4043de74 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -1238,9 +1238,6 @@ program mksurfdat call check_ret(nf_inq_varid(ncid, 'HASURBAN', varid), subname) call check_ret(nf_put_var_int(ncid, varid, hasurban), subname) - call check_ret(nf_inq_varid(ncid, 'PCT_URBAN_MAX', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pcturb_max), subname) - if (num_cft > 0) then call check_ret(nf_inq_varid(ncid, 'PCT_CFT_MAX', varid), subname) call check_ret(nf_put_var_double(ncid, varid, get_pct_p2l_array(pctcft_max)), subname) @@ -1449,7 +1446,7 @@ subroutine normalizencheck_landuse(ldomain) suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) if (suma > (100._r8 + tol_loose)) then write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla must be' - write(6,*) '<= 100% before calling this subroutine' + write(6,*) '<= 100% before normalizing vegetated area' write(6,*) 'n, pctlak, pctwet, pcturb, pctgla = ', & n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) call abort() diff --git a/tools/mksurfdata_map/src/mkurbanparMod.F90 b/tools/mksurfdata_map/src/mkurbanparMod.F90 index b47adfb61e..4cbef42b11 100644 --- a/tools/mksurfdata_map/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_map/src/mkurbanparMod.F90 @@ -778,7 +778,7 @@ subroutine update_max_array_urban(pct_urbmax_arr,pct_urban_arr) if (pct_urban_arr(n,k) > pct_urbmax_arr(n,k)) then pct_urbmax_arr(n,k) = pct_urban_arr(n,k) end if - end do + end do end do end subroutine update_max_array_urban From 0dc8ca414b277f4fc76c54ad8e36ad1712b706ed Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Tue, 7 Dec 2021 12:26:07 -0500 Subject: [PATCH 009/614] fixed a wrong indentation --- tools/mksurfdata_map/src/mksurfdat.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index 3d4043de74..c3732d7751 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -1174,7 +1174,7 @@ program mksurfdat call change_landuse(ldomain, dynpft=.true.) call normalizencheck_landuse(ldomain) - call normalize_classes_by_gcell(urbn_classes, pcturb, urbn_classes_g) + call normalize_classes_by_gcell(urbn_classes, pcturb, urbn_classes_g) call update_max_array(pctnatpft_max,pctnatpft) call update_max_array(pctcft_max,pctcft) From f57a3e4bf017021b3478595f4280268bd2dadedf Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Wed, 8 Dec 2021 10:04:53 -0500 Subject: [PATCH 010/614] Declare hasurban as a double variable --- tools/mksurfdata_map/src/mkfileMod.F90 | 2 +- tools/mksurfdata_map/src/mksurfdat.F90 | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/mksurfdata_map/src/mkfileMod.F90 b/tools/mksurfdata_map/src/mkfileMod.F90 index 084848f5d8..5cc6bfaf9a 100644 --- a/tools/mksurfdata_map/src/mkfileMod.F90 +++ b/tools/mksurfdata_map/src/mkfileMod.F90 @@ -544,7 +544,7 @@ subroutine mkfile(domain, fname, harvdata, dynlanduse) lev1name='numurbl', lev2name='time', & long_name='percent urban for each density type', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='HASURBAN', xtype=nf_int, & + call ncd_def_spatial_var(ncid=ncid, varname='HASURBAN', xtype=xtype, & lev1name='numurbl', & long_name='whether the grid ever has urban during the considered time period', units='unitless') diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index c3732d7751..1f124d9bc8 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -110,7 +110,7 @@ program mksurfdat real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland real(r8), allocatable :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) real(r8), allocatable :: pcturb_max(:,:) ! maximum percent cover of each urban class, as % of grid cell - integer , allocatable :: hasurban(:,:) ! whether the urban class should be active in transient urban simulations + real(r8), allocatable :: hasurban(:,:) ! whether the urban class should be active in transient urban simulations real(r8), allocatable :: urbn_classes(:,:) ! percent cover of each urban class, as % of total urban area real(r8), allocatable :: urbn_classes_g(:,:)! percent cover of each urban class, as % of grid cell real(r8), allocatable :: elev(:) ! glc elevation (m) @@ -480,7 +480,7 @@ program mksurfdat pctlak(:) = spval pctwet(:) = spval pcturb(:) = spval - hasurban(:,:) = 0 + hasurban(:,:) = spval urban_region(:) = -999 urbn_classes(:,:) = spval urbn_classes_g(:,:) = spval @@ -1225,7 +1225,9 @@ program mksurfdat do n = 1,ns_o do k =1, numurbl if (pcturb_max(n,k) > 1.e-6_r8) then - hasurban(n,k) = 1 + hasurban(n,k) = 1._r8 + else + hasurban(n,k) = 0._r8 end if end do end do @@ -1236,7 +1238,7 @@ program mksurfdat call check_ret(nf_put_var_double(ncid, varid, get_pct_l2g_array(pctcft_max)), subname) call check_ret(nf_inq_varid(ncid, 'HASURBAN', varid), subname) - call check_ret(nf_put_var_int(ncid, varid, hasurban), subname) + call check_ret(nf_put_var_double(ncid, varid, hasurban), subname) if (num_cft > 0) then call check_ret(nf_inq_varid(ncid, 'PCT_CFT_MAX', varid), subname) From da0814061ce7057f04474885c48dd22aceda58cf Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Fri, 10 Dec 2021 12:07:38 -0500 Subject: [PATCH 011/614] Change HASURBAN type as integer --- tools/mksurfdata_map/src/mkfileMod.F90 | 2 +- tools/mksurfdata_map/src/mksurfdat.F90 | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/mksurfdata_map/src/mkfileMod.F90 b/tools/mksurfdata_map/src/mkfileMod.F90 index 5cc6bfaf9a..084848f5d8 100644 --- a/tools/mksurfdata_map/src/mkfileMod.F90 +++ b/tools/mksurfdata_map/src/mkfileMod.F90 @@ -544,7 +544,7 @@ subroutine mkfile(domain, fname, harvdata, dynlanduse) lev1name='numurbl', lev2name='time', & long_name='percent urban for each density type', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='HASURBAN', xtype=xtype, & + call ncd_def_spatial_var(ncid=ncid, varname='HASURBAN', xtype=nf_int, & lev1name='numurbl', & long_name='whether the grid ever has urban during the considered time period', units='unitless') diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index 1f124d9bc8..81dc4d9914 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -110,7 +110,7 @@ program mksurfdat real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland real(r8), allocatable :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) real(r8), allocatable :: pcturb_max(:,:) ! maximum percent cover of each urban class, as % of grid cell - real(r8), allocatable :: hasurban(:,:) ! whether the urban class should be active in transient urban simulations + integer , allocatable :: hasurban(:,:) ! whether the urban class should be active in transient urban simulations real(r8), allocatable :: urbn_classes(:,:) ! percent cover of each urban class, as % of total urban area real(r8), allocatable :: urbn_classes_g(:,:)! percent cover of each urban class, as % of grid cell real(r8), allocatable :: elev(:) ! glc elevation (m) @@ -480,7 +480,7 @@ program mksurfdat pctlak(:) = spval pctwet(:) = spval pcturb(:) = spval - hasurban(:,:) = spval + hasurban(:,:) = 0 urban_region(:) = -999 urbn_classes(:,:) = spval urbn_classes_g(:,:) = spval @@ -1225,9 +1225,9 @@ program mksurfdat do n = 1,ns_o do k =1, numurbl if (pcturb_max(n,k) > 1.e-6_r8) then - hasurban(n,k) = 1._r8 + hasurban(n,k) = 1 else - hasurban(n,k) = 0._r8 + hasurban(n,k) = 0 end if end do end do @@ -1238,7 +1238,7 @@ program mksurfdat call check_ret(nf_put_var_double(ncid, varid, get_pct_l2g_array(pctcft_max)), subname) call check_ret(nf_inq_varid(ncid, 'HASURBAN', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, hasurban), subname) + call check_ret(nf_put_var_int(ncid, varid, hasurban), subname) if (num_cft > 0) then call check_ret(nf_inq_varid(ncid, 'PCT_CFT_MAX', varid), subname) From 5316eb54c5285e8a9a32a383bcaef2fd51ca7596 Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Thu, 16 Dec 2021 14:58:42 -0500 Subject: [PATCH 012/614] Add some comments to emphasize hard coding --- tools/mksurfdata_map/mksurfdata.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_map/mksurfdata.pl b/tools/mksurfdata_map/mksurfdata.pl index 3caa4eb009..64dbaed738 100755 --- a/tools/mksurfdata_map/mksurfdata.pl +++ b/tools/mksurfdata_map/mksurfdata.pl @@ -286,8 +286,8 @@ sub write_transient_timeseries_file { printf $fh_landuse_timeseries $dynpft_format, $hrvtypyr, $yr; my $urbanyr = "/glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_".$yr."_new_NoAdjust.nc"; chomp( $urbanyr); - printf $fh_landuse_timeseries $dynpft_format, $urbanyr, $yr; # Keer: I don't quiet understand the 'pft_override' option so I made no change to the "landuse_timeseries_override_$desc.txt" - if ( $yr % 100 == 0 ) { + printf $fh_landuse_timeseries $dynpft_format, $urbanyr, $yr; # I hard coded this part just to generate a txt file with urban raw data file locations + if ( $yr % 100 == 0 ) { # And note that I made no change to the "landuse_timeseries_override_$desc.txt" because I am not sure how to deal with the the 'pft_override' option print "year: $yr\n"; } } From b3d654a187cf93d9bb79ac6468bcf1309d0485bc Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Thu, 16 Dec 2021 15:16:58 -0500 Subject: [PATCH 013/614] Change the pcturb_max threshold for HASURBAN --- tools/mksurfdata_map/src/mksurfdat.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index 81dc4d9914..a753298f44 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -1222,9 +1222,9 @@ program mksurfdat call check_ret(nf_sync(ncid), subname) end do ! end of read loop - do n = 1,ns_o + do n = 1, ns_o do k =1, numurbl - if (pcturb_max(n,k) > 1.e-6_r8) then + if (pcturb_max(n,k) > 1.e-3_r8) then hasurban(n,k) = 1 else hasurban(n,k) = 0 From 6f87e1cfde54be72453731c5c7c786a55babf993 Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Tue, 21 Dec 2021 09:51:35 -0500 Subject: [PATCH 014/614] Delete HASURBAN --- tools/mksurfdata_map/src/mkfileMod.F90 | 4 ++-- tools/mksurfdata_map/src/mksurfdat.F90 | 17 +++-------------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/tools/mksurfdata_map/src/mkfileMod.F90 b/tools/mksurfdata_map/src/mkfileMod.F90 index 084848f5d8..2a453b056a 100644 --- a/tools/mksurfdata_map/src/mkfileMod.F90 +++ b/tools/mksurfdata_map/src/mkfileMod.F90 @@ -544,9 +544,9 @@ subroutine mkfile(domain, fname, harvdata, dynlanduse) lev1name='numurbl', lev2name='time', & long_name='percent urban for each density type', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='HASURBAN', xtype=nf_int, & + call ncd_def_spatial_var(ncid=ncid, varname='PCT_URBAN_MAX', xtype=xtype, & lev1name='numurbl', & - long_name='whether the grid ever has urban during the considered time period', units='unitless') + long_name='maximum percent urban for each density type', units='unitless') call harvdata%getFieldsIdx( ind1D, ind2D ) do j = 1, harvdata%num1Dfields() diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index a753298f44..ee9dff6831 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -110,7 +110,6 @@ program mksurfdat real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland real(r8), allocatable :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) real(r8), allocatable :: pcturb_max(:,:) ! maximum percent cover of each urban class, as % of grid cell - integer , allocatable :: hasurban(:,:) ! whether the urban class should be active in transient urban simulations real(r8), allocatable :: urbn_classes(:,:) ! percent cover of each urban class, as % of total urban area real(r8), allocatable :: urbn_classes_g(:,:)! percent cover of each urban class, as % of grid cell real(r8), allocatable :: elev(:) ! glc elevation (m) @@ -450,7 +449,6 @@ program mksurfdat pctwet(ns_o) , & pcturb(ns_o) , & pcturb_max(ns_o,numurbl) , & - hasurban(ns_o,numurbl) , & urban_region(ns_o) , & urbn_classes(ns_o,numurbl) , & urbn_classes_g(ns_o,numurbl) , & @@ -480,7 +478,6 @@ program mksurfdat pctlak(:) = spval pctwet(:) = spval pcturb(:) = spval - hasurban(:,:) = 0 urban_region(:) = -999 urbn_classes(:,:) = spval urbn_classes_g(:,:) = spval @@ -1222,23 +1219,15 @@ program mksurfdat call check_ret(nf_sync(ncid), subname) end do ! end of read loop - do n = 1, ns_o - do k =1, numurbl - if (pcturb_max(n,k) > 1.e-3_r8) then - hasurban(n,k) = 1 - else - hasurban(n,k) = 0 - end if - end do - end do + call check_ret(nf_inq_varid(ncid, 'PCT_NAT_PFT_MAX', varid), subname) call check_ret(nf_put_var_double(ncid, varid, get_pct_p2l_array(pctnatpft_max)), subname) call check_ret(nf_inq_varid(ncid, 'PCT_CROP_MAX', varid), subname) call check_ret(nf_put_var_double(ncid, varid, get_pct_l2g_array(pctcft_max)), subname) - call check_ret(nf_inq_varid(ncid, 'HASURBAN', varid), subname) - call check_ret(nf_put_var_int(ncid, varid, hasurban), subname) + call check_ret(nf_inq_varid(ncid, 'PCT_URBAN_MAX', varid), subname) + call check_ret(nf_put_var_double(ncid, varid, pcturb_max), subname) if (num_cft > 0) then call check_ret(nf_inq_varid(ncid, 'PCT_CFT_MAX', varid), subname) From b51b3b93a244ef2de942d62e3ea39eb16db60239 Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Tue, 21 Dec 2021 09:54:36 -0500 Subject: [PATCH 015/614] Delete pcturb_orig --- tools/mksurfdata_map/src/mksurfdat.F90 | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index ee9dff6831..c74e524e50 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -138,7 +138,6 @@ program mksurfdat real(r8), allocatable :: lakedepth(:) ! lake depth (m) real(r8), allocatable :: pctlak_orig(:) ! percent lake of gridcell before dynamic land use adjustments real(r8), allocatable :: pctwet_orig(:) ! percent wetland of gridcell before dynamic land use adjustments - real(r8), allocatable :: pcturb_orig(:) ! percent urban of gridcell before dynamic land use adjustments real(r8), allocatable :: pctgla_orig(:) ! percent glacier of gridcell before dynamic land use adjustments real(r8) :: std_elev = -999.99_r8 ! Standard deviation of elevation (m) to use for entire grid @@ -469,7 +468,6 @@ program mksurfdat glacier_region(ns_o) , & pctlak_orig(ns_o) , & pctwet_orig(ns_o) , & - pcturb_orig(ns_o) , & pctgla_orig(ns_o) ) landfrac_pft(:) = spval pctlnd_pft(:) = spval @@ -658,7 +656,6 @@ program mksurfdat ! Save special land unit areas of surface dataset pctlak_orig(:) = pctlak(:) pctwet_orig(:) = pctwet(:) - pcturb_orig(:) = pcturb(:) pctgla_orig(:) = pctgla(:) ! Make elevation [elev] from [ftopo, ffrac] dataset From 09b35c5fa6e995d546966889ce43bcd95b7747f2 Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Wed, 22 Dec 2021 11:11:10 -0500 Subject: [PATCH 016/614] Merge #1073 with this PR #1579(Add dynamic lake variables) --- tools/mksurfdata_map/mksurfdata.pl | 9 ++++-- tools/mksurfdata_map/src/mkfileMod.F90 | 8 ++++- tools/mksurfdata_map/src/mklanwatMod.F90 | 33 +++++++++++++++++--- tools/mksurfdata_map/src/mksurfdat.F90 | 38 +++++++++++++++++------- 4 files changed, 70 insertions(+), 18 deletions(-) diff --git a/tools/mksurfdata_map/mksurfdata.pl b/tools/mksurfdata_map/mksurfdata.pl index 64dbaed738..a73f3fdbab 100755 --- a/tools/mksurfdata_map/mksurfdata.pl +++ b/tools/mksurfdata_map/mksurfdata.pl @@ -285,9 +285,12 @@ sub write_transient_timeseries_file { chomp( $hrvtypyr ); printf $fh_landuse_timeseries $dynpft_format, $hrvtypyr, $yr; my $urbanyr = "/glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_".$yr."_new_NoAdjust.nc"; - chomp( $urbanyr); - printf $fh_landuse_timeseries $dynpft_format, $urbanyr, $yr; # I hard coded this part just to generate a txt file with urban raw data file locations - if ( $yr % 100 == 0 ) { # And note that I made no change to the "landuse_timeseries_override_$desc.txt" because I am not sure how to deal with the the 'pft_override' option + chomp( $urbanyr); # !KZ I hard coded this part just to generate a txt file with urban raw data file locations + printf $fh_landuse_timeseries $dynpft_format, $urbanyr, $yr; # And note that I made no change to the "landuse_timeseries_override_$desc.txt" because I am not sure how to deal with the the 'pft_override' option + my $lakeyr = "/glade/work/ivanderk/inputdata/rawdata/timeseries/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_2017_c20200305.nc"; + chomp( $lakeyr); + printf $fh_landuse_timeseries $dynpft_format, $lakeyr, $yr; + if ( $yr % 100 == 0 ) { print "year: $yr\n"; } } diff --git a/tools/mksurfdata_map/src/mkfileMod.F90 b/tools/mksurfdata_map/src/mkfileMod.F90 index 2a453b056a..69ff8f58d4 100644 --- a/tools/mksurfdata_map/src/mkfileMod.F90 +++ b/tools/mksurfdata_map/src/mkfileMod.F90 @@ -547,7 +547,13 @@ subroutine mkfile(domain, fname, harvdata, dynlanduse) call ncd_def_spatial_var(ncid=ncid, varname='PCT_URBAN_MAX', xtype=xtype, & lev1name='numurbl', & long_name='maximum percent urban for each density type', units='unitless') - + + call ncd_def_spatial_var(ncid=ncid, varname='PCT_LAKE', xtype=xtype, & + lev1name="time", long_name='percent lake', units='unitless') + + call ncd_def_spatial_var(ncid=ncid, varname='PCT_LAKE_MAX', xtype=xtype, & + long_name='maximum percent lake for each density type', units='unitless') + call harvdata%getFieldsIdx( ind1D, ind2D ) do j = 1, harvdata%num1Dfields() call ncd_def_spatial_var(ncid=ncid, varname=mkharvest_fieldname(ind1D(j),constant=.false.), xtype=xtype, & diff --git a/tools/mksurfdata_map/src/mklanwatMod.F90 b/tools/mksurfdata_map/src/mklanwatMod.F90 index 49a1485fa7..66159d4bd8 100644 --- a/tools/mksurfdata_map/src/mklanwatMod.F90 +++ b/tools/mksurfdata_map/src/mklanwatMod.F90 @@ -24,10 +24,10 @@ module mklanwatMod private ! !PUBLIC MEMBER FUNCTIONS: - public mklakwat ! make % lake - public mkwetlnd ! make % wetland - public mklakparams ! make lake parameters - + public mklakwat ! make % lake + public mkwetlnd ! make % wetland + public mklakparams ! make lake parameters + public update_max_array_lake ! Update the maximum lake percent !EOP !=============================================================== contains @@ -499,5 +499,30 @@ subroutine mklakparams(ldomain, mapfname, datfname, ndiag, & call shr_sys_flush(6) end subroutine mklakparams +!------------------------------------------------------------------------------ + +!----------------------------------------------------------------------- +subroutine update_max_array_lake(pct_lakmax_arr,pct_lake_arr) + ! + ! !DESCRIPTION: + ! Update the maximum lake percent for landuse.timeseries file + ! + ! !ARGUMENTS: + real(r8) , intent(inout):: pct_lakmax_arr(:) ! max lake percent + real(r8) , intent(in):: pct_lake_arr(:) ! lake percent that is used to update the old pct_lakmax_arr + ! + ! !LOCAL VARIABLES: + integer :: n,ns ! indices + + character(len=*), parameter :: subname = 'update_max_array_lake' + !----------------------------------------------------------------------- + ns = size(pct_lake_arr,1) + do n = 1, ns + if (pct_lake_arr(n) > pct_lakmax_arr(n)) then + pct_lakmax_arr(n) = pct_lake_arr(n) + end if + end do + +end subroutine update_max_array_lake end module mklanwatMod diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index c74e524e50..2e9ffaab64 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -22,7 +22,7 @@ program mksurfdat soil_color, mksoilcol, mkorganic, & soil_fmax, mkfmax use mkvocefMod , only : mkvocef - use mklanwatMod , only : mklakwat, mkwetlnd, mklakparams + use mklanwatMod , only : mklakwat, mkwetlnd, mklakparams, update_max_array_lake use mkglacierregionMod , only : mkglacierregion use mkglcmecMod , only : nglcec, mkglcmec, mkglcmecInit, mkglacier use mkharvestMod , only : mkharvest, mkharvest_init, mkharvest_fieldname @@ -81,6 +81,7 @@ program mksurfdat character(len=256) :: fname ! generic filename character(len=256) :: fhrvname ! generic harvest filename character(len=256) :: furbname ! generic transient urban land cover filename + character(len=256) :: flakname ! generic lake filename character(len=256) :: string ! string read in integer :: t1 ! timer real(r8),parameter :: p5 = 0.5_r8 ! constant @@ -107,6 +108,7 @@ program mksurfdat real(r8), allocatable :: elevclass(:) ! glacier_mec elevation classes integer, allocatable :: glacier_region(:) ! glacier region ID real(r8), allocatable :: pctlak(:) ! percent of grid cell that is lake + real(r8), allocatable :: pctlak_max(:) ! maximum percent of grid cell that is lake real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland real(r8), allocatable :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) real(r8), allocatable :: pcturb_max(:,:) ! maximum percent cover of each urban class, as % of grid cell @@ -135,8 +137,7 @@ program mksurfdat real(r8), allocatable :: vic_ws(:) ! VIC Ws parameter (unitless) real(r8), allocatable :: vic_dsmax(:) ! VIC Dsmax parameter (mm/day) real(r8), allocatable :: vic_ds(:) ! VIC Ds parameter (unitless) - real(r8), allocatable :: lakedepth(:) ! lake depth (m) - real(r8), allocatable :: pctlak_orig(:) ! percent lake of gridcell before dynamic land use adjustments + real(r8), allocatable :: lakedepth(:) ! lake depth (m) real(r8), allocatable :: pctwet_orig(:) ! percent wetland of gridcell before dynamic land use adjustments real(r8), allocatable :: pctgla_orig(:) ! percent glacier of gridcell before dynamic land use adjustments @@ -282,7 +283,7 @@ program mksurfdat ! ====================================== ! Optionally specify setting for: ! ====================================== - ! mksrf_fdynuse ----- ASCII text file that lists each year of pft and urban files to use + ! mksrf_fdynuse ----- ASCII text file that lists each year of pft, urban, and lake files to use ! mksrf_gridtype ---- Type of grid (default is 'global') ! outnc_double ------ If output should be in double precision ! outnc_large_files - If output should be in NetCDF large file format @@ -444,7 +445,8 @@ program mksurfdat pctcft(ns_o) , & pctcft_max(ns_o) , & pctgla(ns_o) , & - pctlak(ns_o) , & + pctlak(ns_o) , & + pctlak_max(ns_o) , & pctwet(ns_o) , & pcturb(ns_o) , & pcturb_max(ns_o,numurbl) , & @@ -466,7 +468,6 @@ program mksurfdat vic_ds(ns_o) , & lakedepth(ns_o) , & glacier_region(ns_o) , & - pctlak_orig(ns_o) , & pctwet_orig(ns_o) , & pctgla_orig(ns_o) ) landfrac_pft(:) = spval @@ -654,7 +655,6 @@ program mksurfdat region_o=urban_region) ! Save special land unit areas of surface dataset - pctlak_orig(:) = pctlak(:) pctwet_orig(:) = pctwet(:) pctgla_orig(:) = pctgla(:) @@ -1085,6 +1085,7 @@ program mksurfdat pctnatpft_max = pctnatpft pctcft_max = pctcft pcturb_max = urbn_classes_g + pctlak_max = pctlak ntim = 0 do @@ -1120,7 +1121,14 @@ program mksurfdat write(6,*) subname, ' error: year for urban not equal to year for PFT files' call abort() end if - write(6,*)'input urban dynamic dataset for year ', year2, ' is : ', trim(furbname) + write(6,*)'input urban dynamic dataset for year ', year2, ' is : ', trim(furbname) + read(nfdyn, '(A195,1x,I4)', iostat=ier) flakname, year2 + if ( year2 /= year ) then + write(6,*) subname, ' error: year for lake not equal to year for PFT files' + call abort() + end if + write(6,*)'input lake dynamic dataset for year ', year2, ' is : ', trim(flakname) + ntim = ntim + 1 ! Create pctpft data at model resolution @@ -1149,7 +1157,10 @@ program mksurfdat end if end do - + ! Create pctlak data at model resolution (use original mapping file from lake data) + call mklakwat (ldomain, mapfname=map_flakwat, datfname=flakname, & + ndiag=ndiag, zero_out=all_urban.or.all_veg, lake_o=pctlak) + call mkurban (ldomain, mapfname=map_furban, datfname=furbname, & ndiag=ndiag, zero_out=all_veg, urbn_o=pcturb, urbn_classes_o=urbn_classes, & region_o=urban_region) @@ -1162,7 +1173,6 @@ program mksurfdat ! For landunits NOT read each year: reset to their pre-adjustment values in preparation for redoing landunit area normalization pctwet(:) = pctwet_orig(:) - pctlak(:) = pctlak_orig(:) pctgla(:) = pctgla_orig(:) call change_landuse(ldomain, dynpft=.true.) @@ -1173,6 +1183,7 @@ program mksurfdat call update_max_array(pctnatpft_max,pctnatpft) call update_max_array(pctcft_max,pctcft) call update_max_array_urban(pcturb_max,urbn_classes_g) + call update_max_array_lake(pctlak_max,pctlak) ! Output time-varying data for current year @@ -1184,6 +1195,10 @@ program mksurfdat call check_ret(nf_inq_varid(ncid, 'PCT_URBAN', varid), subname) call ncd_put_time_slice(ncid, varid, ntim, urbn_classes_g) + + call check_ret(nf_inq_varid(ncid, 'PCT_LAKE', varid), subname) + call ncd_put_time_slice(ncid, varid, ntim, pctlak) + if (num_cft > 0) then call check_ret(nf_inq_varid(ncid, 'PCT_CFT', varid), subname) call ncd_put_time_slice(ncid, varid, ntim, get_pct_p2l_array(pctcft)) @@ -1226,6 +1241,9 @@ program mksurfdat call check_ret(nf_inq_varid(ncid, 'PCT_URBAN_MAX', varid), subname) call check_ret(nf_put_var_double(ncid, varid, pcturb_max), subname) + call check_ret(nf_inq_varid(ncid, 'PCT_LAKE_MAX', varid), subname) + call check_ret(nf_put_var_double(ncid, varid, pctlak_max), subname) + if (num_cft > 0) then call check_ret(nf_inq_varid(ncid, 'PCT_CFT_MAX', varid), subname) call check_ret(nf_put_var_double(ncid, varid, get_pct_p2l_array(pctcft_max)), subname) From fc7119da410c9f106f2239f1a4d435cff2470b54 Mon Sep 17 00:00:00 2001 From: keerzhang1 <86242752+keerzhang1@users.noreply.github.com> Date: Wed, 22 Dec 2021 14:25:17 -0500 Subject: [PATCH 017/614] Correct copy and paste error --- tools/mksurfdata_map/src/mkfileMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_map/src/mkfileMod.F90 b/tools/mksurfdata_map/src/mkfileMod.F90 index 69ff8f58d4..abba061b69 100644 --- a/tools/mksurfdata_map/src/mkfileMod.F90 +++ b/tools/mksurfdata_map/src/mkfileMod.F90 @@ -552,7 +552,7 @@ subroutine mkfile(domain, fname, harvdata, dynlanduse) lev1name="time", long_name='percent lake', units='unitless') call ncd_def_spatial_var(ncid=ncid, varname='PCT_LAKE_MAX', xtype=xtype, & - long_name='maximum percent lake for each density type', units='unitless') + long_name='maximum percent lake', units='unitless') call harvdata%getFieldsIdx( ind1D, ind2D ) do j = 1, harvdata%num1Dfields() From 4b3ef5a77bf514e66bd6c7a5b72947e1e009ca75 Mon Sep 17 00:00:00 2001 From: Keith Oleson Date: Tue, 28 Dec 2021 14:50:38 -0700 Subject: [PATCH 018/614] Incorporate changes from PR1564 into PR1579 --- tools/mksurfdata_map/src/mkpftUtilsMod.F90 | 40 ---- tools/mksurfdata_map/src/mksurfdat.F90 | 203 ++++++--------------- 2 files changed, 52 insertions(+), 191 deletions(-) diff --git a/tools/mksurfdata_map/src/mkpftUtilsMod.F90 b/tools/mksurfdata_map/src/mkpftUtilsMod.F90 index 4a9ea12f97..0faede43a1 100644 --- a/tools/mksurfdata_map/src/mkpftUtilsMod.F90 +++ b/tools/mksurfdata_map/src/mkpftUtilsMod.F90 @@ -24,7 +24,6 @@ module mkpftUtilsMod ! !PUBLIC MEMBER FUNCTIONS: ! public :: convert_from_p2g ! Convert a p2g array into pct_pft_type objects - public :: adjust_total_veg_area ! Adjust the total vegetated area (natural veg & crop) to a new specified total ! ! !PRIVATE MEMBER FUNCTIONS: @@ -213,45 +212,6 @@ function get_default_cft() result(default_cft) end function get_default_cft - - !----------------------------------------------------------------------- - subroutine adjust_total_veg_area(new_total_pct, pctnatpft, pctcft) - ! - ! !DESCRIPTION: - ! Adjust the total vegetated area on the grid cell (natural veg & crop) to a new - ! specified total. - ! - ! If the old areas are 0%, then all the new area goes into pctnatpft. - ! - ! !USES: - use mkpctPftTypeMod, only : pct_pft_type - ! - ! !ARGUMENTS: - real(r8), intent(in) :: new_total_pct ! new total % of natural veg + crop landunits - class(pct_pft_type), intent(inout) :: pctnatpft ! natural veg cover information - class(pct_pft_type), intent(inout) :: pctcft ! crop cover information - ! - ! !LOCAL VARIABLES: - real(r8) :: natpft_l2g ! grid cell % cover of nat. veg. - real(r8) :: cft_l2g ! grid cell % cover of crop - real(r8) :: old_total ! old total % cover of natural veg + crop landunits - - character(len=*), parameter :: subname = 'adjust_total_veg_area' - !----------------------------------------------------------------------- - - natpft_l2g = pctnatpft%get_pct_l2g() - cft_l2g = pctcft%get_pct_l2g() - old_total = natpft_l2g + cft_l2g - if (old_total > 0._r8) then - call pctnatpft%set_pct_l2g(natpft_l2g * new_total_pct / old_total) - call pctcft%set_pct_l2g(cft_l2g * new_total_pct / old_total) - else - call pctnatpft%set_pct_l2g(new_total_pct) - end if - - end subroutine adjust_total_veg_area - - end module mkpftUtilsMod diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index 32390a5188..ba51a4480c 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -1120,13 +1120,14 @@ program mksurfdat write(6,*) subname, ' error: year for urban not equal to year for PFT files' call abort() end if - write(6,*)'input urban dynamic dataset for year ', year2, ' is : ', trim(furbname) + write(6,*)'input urban dynamic dataset for year ', year2, ' is : ', trim(furbname) + ! Read input lake data read(nfdyn, '(A195,1x,I4)', iostat=ier) flakname, year2 if ( year2 /= year ) then write(6,*) subname, ' error: year for lake not equal to year for PFT files' call abort() end if - write(6,*)'input lake dynamic dataset for year ', year2, ' is : ', trim(flakname) + write(6,*)'input lake dynamic dataset for year ', year2, ' is : ', trim(flakname) ntim = ntim + 1 @@ -1170,7 +1171,8 @@ program mksurfdat end where end if - ! For landunits NOT read each year: reset to their pre-adjustment values in preparation for redoing landunit area normalization + ! For landunits NOT read each year: reset to their pre-adjustment values in + ! preparation for redoing landunit area normalization pctwet(:) = pctwet_orig(:) pctgla(:) = pctgla_orig(:) @@ -1344,8 +1346,6 @@ subroutine normalizencheck_landuse(ldomain) ! ! ! !USES: - use mkpftConstantsMod , only : baregroundindex - use mkpftUtilsMod , only : adjust_total_veg_area implicit none ! !ARGUMENTS: type(domain_type) :: ldomain @@ -1360,13 +1360,7 @@ subroutine normalizencheck_landuse(ldomain) integer :: nsmall ! number of small PFT values for a single check integer :: nsmall_tot ! total number of small PFT values in all grid cells real(r8) :: suma ! sum for error check - real(r8) :: suma2 ! another sum for error check - real(r8) :: new_total_veg_pct ! new % veg (% of grid cell, total of natural veg & crop) - real(r8) :: bare_pct_p2g ! % of bare soil, as % of grid cell - real(r8) :: bare_urb_diff ! difference between bare soil and urban % - real(r8) :: pcturb_excess ! excess urban % not accounted for by bare soil - real(r8) :: sum8, sum8a ! sum for error check - real(r4) :: sum4a ! sum for error check + real(r8) :: new_total_natveg_pct ! new % veg (% of grid cell, natural veg) real(r8), parameter :: tol_loose = 1.e-4_r8 ! tolerance for some 'loose' error checks real(r8), parameter :: toosmallPFT = 1.e-10_r8 ! tolerance for PFT's to ignore character(len=32) :: subname = 'normalizencheck_landuse' ! subroutine name @@ -1409,21 +1403,17 @@ subroutine normalizencheck_landuse(ldomain) pftdata_mask(n) = 1 end if - ! Make sure sum of land cover types does not exceed 100. If it does, - ! subtract excess from most dominant land cover. + ! Make sure sum of all land cover types except natural vegetation + ! does not exceed 100. If it does, subtract excess from these land cover + ! types proportionally. - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - if (suma > 250._r4) then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb and pctgla is greater than 250%' - write (6,*)'n,pctlak,pctwet,pcturb,pctgla= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n) - call abort() - else if (suma > 100._r4) then + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() + if (suma > 100._r4) then pctlak(n) = pctlak(n) * 100._r8/suma pctwet(n) = pctwet(n) * 100._r8/suma pcturb(n) = pcturb(n) * 100._r8/suma pctgla(n) = pctgla(n) * 100._r8/suma + call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8/suma) end if ! Check preconditions @@ -1447,81 +1437,33 @@ subroutine normalizencheck_landuse(ldomain) write(6,*) 'n, pctgla = ', n, pctgla(n) call abort() end if - - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - if (suma > (100._r8 + tol_loose)) then - write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla must be' - write(6,*) '<= 100% before normalizing vegetated area' - write(6,*) 'n, pctlak, pctwet, pcturb, pctgla = ', & - n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) + if ( pctcft(n)%get_pct_l2g() < 0.0_r8 )then + write(6,*) subname, ' ERROR: pctcrop is negative!' + write(6,*) 'n, pctcrop = ', n, pctcft(n)%get_pct_l2g() call abort() end if - ! ------------------------------------------------------------------------ - ! Normalize vegetated area so that vegetated + special area is 100% - ! ------------------------------------------------------------------------ - ! First normalize vegetated (natural veg + crop) cover so that the total of - ! (vegetated + (special excluding urban)) is 100%. We'll deal with urban later. - ! - ! Note that, in practice, the total area of natural veg + crop is typically 100% - ! going into this routine. However, the following code does NOT rely on this, and - ! will work properly regardless of the initial area of natural veg + crop (even if - ! that initial area is 0%). - - suma = pctlak(n)+pctwet(n)+pctgla(n) - new_total_veg_pct = 100._r8 - suma - ! correct for rounding error: - new_total_veg_pct = max(new_total_veg_pct, 0._r8) - call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) - - ! Make sure we did the above rescaling correctly - - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - if (abs(suma - 100._r8) > tol_loose) then - write(6,*) subname, ' ERROR in rescaling veg based on (special excluding urban' - write(6,*) 'suma = ', suma + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() + if (suma > (100._r8 + tol_loose)) then + write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla + pctcrop must be' + write(6,*) '<= 100% before normalizing natural vegetation area' + write(6,*) 'n, pctlak, pctwet, pcturb, pctgla, pctcrop = ', & + n, pctlak(n), pctwet(n), pcturb(n), pctgla(n), pctcft(n)%get_pct_l2g() call abort() end if - ! Now decrease the vegetated area to account for urban area. Urban needs to be - ! handled specially because we replace bare soil preferentially with urban, rather - ! than rescaling all PFTs equally. + ! Natural vegetated cover is 100% minus the sum of all other landunits - if (pcturb(n) > 0._r8) then - - ! Replace bare soil preferentially with urban - bare_pct_p2g = pctnatpft(n)%get_one_pct_p2g(baregroundindex) - bare_urb_diff = bare_pct_p2g - pcturb(n) - bare_pct_p2g = max(0._r8, bare_urb_diff) - call pctnatpft(n)%set_one_pct_p2g(baregroundindex, bare_pct_p2g) - pcturb_excess = abs(min(0._r8,bare_urb_diff)) - - ! For any urban not accounted for by bare soil, replace other PFTs - ! proportionally - if (pcturb_excess > 0._r8) then - ! Note that, in this case, we will have already reduced bare ground to 0% - - new_total_veg_pct = pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - pcturb_excess - if (new_total_veg_pct < 0._r8) then - if (abs(new_total_veg_pct) < tol_loose) then - ! only slightly less than 0; correct it - new_total_veg_pct = 0._r8 - else - write(6,*) subname, ' ERROR: trying to replace veg with urban,' - write(6,*) 'but pcturb_excess exceeds current vegetation percent' - call abort() - end if - end if - - call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) - end if - - end if ! pcturb(n) > 0 + new_total_natveg_pct = 100._r8 - suma + ! correct for rounding error: + new_total_natveg_pct = max(new_total_natveg_pct, 0._r8) + call pctnatpft(n)%set_pct_l2g(new_total_natveg_pct) + ! Confirm that we have done the rescaling correctly: now the sum of all landunits - ! should be 100% - suma = pctlak(n)+pctwet(n)+pctgla(n)+pcturb(n) - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + ! should be 100% within tol_loose + suma = pctlak(n)+pctwet(n)+pctgla(n)+pcturb(n)+pctcft(n)%get_pct_l2g() + suma = suma + pctnatpft(n)%get_pct_l2g() if (abs(suma - 100._r8) > tol_loose) then write(6,*) subname, ' ERROR: landunits do not sum to 100%' write(6,*) 'n, suma, pctlak, pctwet, pctgla, pcturb, pctnatveg, pctcrop = ' @@ -1558,30 +1500,34 @@ subroutine normalizencheck_landuse(ldomain) call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8/suma) end if - ! Roundoff error fix - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - suma2 = pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + ! This roundoff error fix is needed to handle the situation where new_total_natveg_pct + ! ends up near 0 but not exactly 0 due to roundoff issues. In this situation, we set the + ! natveg landunit area to exactly 0 and put the remainder into some other landunit. Since + ! the remainder is very small, it doesn't really matter which other landunit we add it to, + ! so we just pick some landunit that already has at least 1% cover. + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() if ( (suma < 100._r8 .and. suma > (100._r8 - 1.e-6_r8)) .or. & - (suma2 > 0.0_r8 .and. suma2 < 1.e-6_r8) ) then - write (6,*) 'Special land units near 100%, but not quite for n,suma =',n,suma - write (6,*) 'Adjusting special land units to 100%' - if (pctlak(n) >= 25._r8) then - pctlak(n) = 100._r8 - (pctwet(n) + pcturb(n) + pctgla(n)) - else if (pctwet(n) >= 25._r8) then - pctwet(n) = 100._r8 - (pctlak(n) + pcturb(n) + pctgla(n)) - else if (pcturb(n) >= 25._r8) then - pcturb(n) = 100._r8 - (pctlak(n) + pctwet(n) + pctgla(n)) - else if (pctgla(n) >= 25._r8) then - pctgla(n) = 100._r8 - (pctlak(n) + pctwet(n) + pcturb(n)) + (pctnatpft(n)%get_pct_l2g() > 0.0_r8 .and. pctnatpft(n)%get_pct_l2g() < 1.e-6_r8) ) then + write (6,*) 'Special plus crop land units near 100%, but not quite for n,suma =',n,suma + write (6,*) 'Adjusting special plus crop land units to 100%' + if (pctlak(n) >= 1.0_r8) then + pctlak(n) = 100._r8 - (pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g()) + else if (pctwet(n) >= 1.0_r8) then + pctwet(n) = 100._r8 - (pctlak(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g()) + else if (pcturb(n) >= 1.0_r8) then + pcturb(n) = 100._r8 - (pctlak(n) + pctwet(n) + pctgla(n) + pctcft(n)%get_pct_l2g()) + else if (pctgla(n) >= 1.0_r8) then + pctgla(n) = 100._r8 - (pctlak(n) + pctwet(n) + pcturb(n) + pctcft(n)%get_pct_l2g()) + else if (pctcft(n)%get_pct_l2g() >= 1.0_r8) then + call pctcft(n)%set_pct_l2g(100._r8 - (pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n))) else - write (6,*) subname, 'Error: sum of special land units nearly 100% but none is >= 25% at ', & + write (6,*) subname, 'Error: sum of special plus crop land units nearly 100% but none is >= 1.0% at ', & 'n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),pctnatveg(n),pctcrop(n),suma = ', & n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(),suma call abort() end if call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) end if if ( any(pctnatpft(n)%get_pct_p2g() > 0.0_r8 .and. pctnatpft(n)%get_pct_p2g() < toosmallPFT ) .or. & any(pctcft(n)%get_pct_p2g() > 0.0_r8 .and. pctcft(n)%get_pct_p2g() < toosmallPFT )) then @@ -1593,14 +1539,8 @@ subroutine normalizencheck_landuse(ldomain) call abort() end if - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - if (suma < 100._r8-epsilon(suma) .and. suma > (100._r8 - 4._r8*epsilon(suma))) then - write (6,*) subname, 'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& - pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() - call abort() - end if - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() + suma = suma + pctnatpft(n)%get_pct_l2g() if ( abs(suma-100._r8) > 1.e-10_r8) then write (6,*) subname, ' error: sum of pctlak, pctwet,', & 'pcturb, pctgla, pctnatveg and pctcrop is NOT equal to 100' @@ -1612,45 +1552,6 @@ subroutine normalizencheck_landuse(ldomain) end do - ! Check that when pctnatveg+pctcrop identically zero, sum of special landunits is identically 100% - - if ( .not. outnc_double )then - do n = 1,ns_o - sum8 = real(pctlak(n),r4) - sum8 = sum8 + real(pctwet(n),r4) - sum8 = sum8 + real(pcturb(n),r4) - sum8 = sum8 + real(pctgla(n),r4) - sum4a = real(pctnatpft(n)%get_pct_l2g(),r4) - sum4a = sum4a + real(pctcft(n)%get_pct_l2g(),r4) - if ( sum4a==0.0_r4 .and. sum8 < 100._r4-2._r4*epsilon(sum4a) )then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 - write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n), & - pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g() - call abort() - end if - end do - else - do n = 1,ns_o - sum8 = pctlak(n) - sum8 = sum8 + pctwet(n) - sum8 = sum8 + pcturb(n) - sum8 = sum8 + pctgla(n) - sum8a = pctnatpft(n)%get_pct_l2g() - sum8a = sum8a + pctcft(n)%get_pct_l2g() - if ( sum8a==0._r8 .and. sum8 < (100._r8-4._r8*epsilon(sum8)) )then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 - write (6,*) 'Total error, error/epsilon = ',100._r8-sum8, ((100._r8-sum8)/epsilon(sum8)) - write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,epsilon= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& - pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), epsilon(sum8) - call abort() - end if - end do - end if - ! Make sure that there is no vegetation outside the pft mask do n = 1,ns_o if (pftdata_mask(n) == 0 .and. (pctnatpft(n)%get_pct_l2g() > 0 .or. pctcft(n)%get_pct_l2g() > 0)) then From 88e5a0b170f119f8fb8417fbea770d9bd9fa6229 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 15 Jan 2022 21:04:39 -0700 Subject: [PATCH 019/614] refactored generation of mksurfdata namelist --- Externals.cfg | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Externals.cfg b/Externals.cfg index 1c2293d02f..4df74dad8c 100644 --- a/Externals.cfg +++ b/Externals.cfg @@ -1,3 +1,11 @@ +[ccs_config] +#tag = ccs_config_cesm0.0.3 +branch = main +protocol = git +repo_url = https://github.com/ESMCI/ccs_config_cesm +local_path = ccs_config +required = True + [clm] local_path = . protocol = externals_only @@ -37,7 +45,8 @@ required = True local_path = cime protocol = git repo_url = https://github.com/ESMCI/cime -tag = branch_tags/cime6.0.12_a01 +#tag = branch_tags/cime6.0.12_a01 +branch = master required = True [cmeps] From c2eebb9d9969b8d06aa49c250a8eb78ead73553c Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 19 Jan 2022 19:02:51 -0700 Subject: [PATCH 020/614] new esmf mksurfdata code --- .../gen_mksurfdata_namelist.py | 356 +++ .../gen_mksurfdata_namelist.xml | 282 +++ tools/mksurfdata_esmf/src/CMakeLists.txt | 54 + tools/mksurfdata_esmf/src/ESMF_RegridEx.F90 | 93 + tools/mksurfdata_esmf/src/Makefile | 66 + tools/mksurfdata_esmf/src/chkerrMod.F90 | 1 + tools/mksurfdata_esmf/src/fileutils.F90 | 38 + tools/mksurfdata_esmf/src/log.out | Bin 0 -> 14179 bytes tools/mksurfdata_esmf/src/mkVICparamsMod.F90 | 200 ++ .../src/mkagfirepkmonthMod.F90 | 273 ++ tools/mksurfdata_esmf/src/mkchecksMod.F90 | 159 ++ .../mksurfdata_esmf/src/mkdiagnosticsMod.F90 | 398 +++ tools/mksurfdata_esmf/src/mkesmfMod.F90 | 103 + tools/mksurfdata_esmf/src/mkfileMod.F90 | 514 ++++ tools/mksurfdata_esmf/src/mkgdpMod.F90 | 147 ++ .../src/mkglacierregionMod.F90 | 139 ++ tools/mksurfdata_esmf/src/mkglcmecMod.F90 | 794 ++++++ tools/mksurfdata_esmf/src/mkharvestMod.F90 | 1104 ++++++++ tools/mksurfdata_esmf/src/mkindexmapMod.F90 | 697 ++++++ tools/mksurfdata_esmf/src/mklaiMod.F90 | 445 ++++ tools/mksurfdata_esmf/src/mklanwatMod.F90 | 288 +++ tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 | 626 +++++ tools/mksurfdata_esmf/src/mkpeatMod.F90 | 149 ++ .../mksurfdata_esmf/src/mkpftConstantsMod.F90 | 43 + tools/mksurfdata_esmf/src/mkpftMod.F90 | 1267 ++++++++++ tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 | 257 ++ tools/mksurfdata_esmf/src/mkpioMod.F90 | 627 +++++ tools/mksurfdata_esmf/src/mksoilMod.F90 | 1238 +++++++++ tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 | 224 ++ tools/mksurfdata_esmf/src/mksoildepthMod.F90 | 172 ++ tools/mksurfdata_esmf/src/mksurfdata | Bin 0 -> 2742328 bytes tools/mksurfdata_esmf/src/mksurfdata.F90 | 1408 +++++++++++ tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 183 ++ .../src/mkurbanparCommonMod.F90 | 365 +++ tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 759 ++++++ tools/mksurfdata_esmf/src/mkutilsMod.F90 | 162 ++ tools/mksurfdata_esmf/src/mkvarctl.F90 | 416 ++++ tools/mksurfdata_esmf/src/mkvarpar.F90 | 22 + tools/mksurfdata_esmf/src/mkvocefMod.F90 | 209 ++ tools/mksurfdata_esmf/src/nanMod.F90 | 41 + tools/mksurfdata_esmf/src/run_mksurfdata | 22 + tools/mksurfdata_esmf/src/shr_const_mod.F90 | 58 + tools/mksurfdata_esmf/src/shr_kind_mod.F90 | 19 + tools/mksurfdata_esmf/src/shr_log_mod.F90 | 13 + tools/mksurfdata_esmf/src/shr_mpi_mod.F90 | 2215 +++++++++++++++++ tools/mksurfdata_esmf/src/shr_pio_mod.F90 | 748 ++++++ tools/mksurfdata_esmf/src/shr_string_mod.F90 | 142 ++ tools/mksurfdata_esmf/src/shr_sys_mod.F90 | 352 +++ 48 files changed, 17888 insertions(+) create mode 100755 tools/mksurfdata_esmf/gen_mksurfdata_namelist.py create mode 100644 tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml create mode 100644 tools/mksurfdata_esmf/src/CMakeLists.txt create mode 100644 tools/mksurfdata_esmf/src/ESMF_RegridEx.F90 create mode 100644 tools/mksurfdata_esmf/src/Makefile create mode 100644 tools/mksurfdata_esmf/src/chkerrMod.F90 create mode 100644 tools/mksurfdata_esmf/src/fileutils.F90 create mode 100644 tools/mksurfdata_esmf/src/log.out create mode 100644 tools/mksurfdata_esmf/src/mkVICparamsMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkchecksMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkesmfMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkfileMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkgdpMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkglacierregionMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkglcmecMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkharvestMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkindexmapMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mklaiMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mklanwatMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkpeatMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkpftConstantsMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkpftMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkpioMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mksoilMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mksoildepthMod.F90 create mode 100755 tools/mksurfdata_esmf/src/mksurfdata create mode 100644 tools/mksurfdata_esmf/src/mksurfdata.F90 create mode 100644 tools/mksurfdata_esmf/src/mktopostatsMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkurbanparMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkutilsMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mkvarctl.F90 create mode 100644 tools/mksurfdata_esmf/src/mkvarpar.F90 create mode 100644 tools/mksurfdata_esmf/src/mkvocefMod.F90 create mode 100644 tools/mksurfdata_esmf/src/nanMod.F90 create mode 100644 tools/mksurfdata_esmf/src/run_mksurfdata create mode 100644 tools/mksurfdata_esmf/src/shr_const_mod.F90 create mode 100644 tools/mksurfdata_esmf/src/shr_kind_mod.F90 create mode 100644 tools/mksurfdata_esmf/src/shr_log_mod.F90 create mode 100644 tools/mksurfdata_esmf/src/shr_mpi_mod.F90 create mode 100644 tools/mksurfdata_esmf/src/shr_pio_mod.F90 create mode 100644 tools/mksurfdata_esmf/src/shr_string_mod.F90 create mode 100644 tools/mksurfdata_esmf/src/shr_sys_mod.F90 diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py new file mode 100755 index 0000000000..ab4218edd5 --- /dev/null +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -0,0 +1,356 @@ +#!/usr/bin/env python3 + +import sys, os, shutil +import xml.etree.ElementTree as ET +import logging +import argparse +import subprocess +from datetime import datetime + +logger = logging.getLogger(__name__) + +# valid options for SSP scenarios and pft years: +valid_opts = {"ssp_rcp": ["hist","SSP1-2.6","SSP3-7.0","SSP5-3.4","SSP2-4.5","SSP1-1.9","SSP4-3.4","SSP4-6.0","SSP5-8.5"]} + +def get_parser(): + """ + Get parser object for this script. + """ + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + + parser.print_usage = parser.print_help + + parser.add_argument( + "--sy", + "--start-year", + help="Simulation start year. [default: %(default)s] ", + action="store", + dest="start_year", + required=True, + type=int, + ) + parser.add_argument( + "--ey", + "--end-year", + help="Simulation end year. [default: start_year] ", + action="store", + dest="end_year", + required=True, + type=int, + ) + parser.add_argument( + "--glc-nec", + help=""" + Number of glacier elevation classes to use. + [default: %(default)s] + """, + action="store", + dest="glc_nec", + type=int, + default=10, + ) + parser.add_argument( + "--rundir", + help=""" + Directory to run in. + [default: %(default)s] + """, + action="store", + dest="run_dir", + required=False, + default=os.getcwd(), + ) + parser.add_argument( + "--ssp-rcp", + help=""" + Shared Socioeconomic Pathway and Representative + Concentration Pathway Scenario name(s). + [default: %(default)s] + """, + action="store", + dest="ssp_rcp", + required=False, + choices=valid_opts["ssp_rcp"], + default="hist", + ) + parser.add_argument( + "--rawdata-dir", + help=""" + /path/of/root/of/input/data', + [default: %(default)s] + """, + action="store", + dest="input_path", + default="/glade/p/cesm/cseg/inputdata/", + ) + parser.add_argument( + "--vic", + help=""" + Flag for adding the fields required for the VIC model. + """, + action="store_true", + dest="vic_flag", + default=False, + ) + parser.add_argument( + "--glc", + help=""" + Flag for adding the optional 3D glacier fields for verification of the glacier model. + """, + action="store_true", + dest="glc_flag", + default=False, + ) + parser.add_argument( + "--hires_pft", + help=""" + If you want to use the high-resolution pft dataset rather + than the default lower resolution dataset. + (Low resolution is at quarter-degree, high resolution at 3-minute) + [Note: hires only available for 1850 and 2005.] + """, + action="store_true", + dest="hres_flag", + default=False, + ) + parser.add_argument( + "--nocrop", + help=""" + Create datasets with the extensive list of prognostic crop types. + """, + action="store_false", + dest="crop_flag", + default=True, + ) + parser.add_argument( + "-f", + "--fast", + help="Toggle fast mode which does not user the large mapping file", + action="store_true", + dest="fast_flag", + default=False, + ) + parser.add_argument( + "--potveg_flag", + help=""" + Use Potential Vegetation for pft_years + """, + action="store_false", + dest="potveg_flag", + default=False, + ) + parser.add_argument( + "-r", + "--res", + help=""" + model resolution + """, + action="store", + dest="res", + required=False, + default="4x5", + ) + return parser + +def main (): + + args = get_parser().parse_args() + + hires_pft = args.hres_flag + ssp_rcp = args.ssp_rcp + res = args.res + input_path = args.input_path + crop_flag = args.crop_flag + vic_flag = args.vic_flag + glc_flag = args.glc_flag + start_year = args.start_year + end_year = args.end_year + potveg = args.potveg_flag + glc_nec = args.glc_nec + + # determine pft_years - needed to parse xml file + if start_year == 1850 and end_year == 1850: + pft_years = "1850" + elif start_year == 2000 and end_year == 2000: + pft_years = "2005" + elif start_year >= 850 and end_year <= 1849: + pft_years = "0850-1849" + elif start_year >= 1850 and end_year <= 2005: + pft_years = "1850-2015" + elif start_year >= 2016 and end_year <=2100: + pft_years = "2016-2100" + elif potveg: + pft_years = "PtVg" + else: + raise argparse.ArgumentTypeError( + "ERROR: Simulation start and end years should be between 850 and 2105 or potential vegetation flag needs to be true " + ) + + # error check on glc_nec + if (glc_nec <= 0) or (glc_nec >= 100): + raise argparse.ArgumentTypeError("ERROR: glc_nec must be between 1 and 99.") + + # if args.debug: + # logging.basicConfig(level=logging.DEBUG) + + # create attribute list for parsing xml file + attribute_list = {'hires_pft':hires_pft, + 'pft_years':pft_years, + 'ssp_rcp':ssp_rcp, + 'mergeGIS':'of'} + + # TODO: add an argument for mergeGIS + + # create dictionary for raw data files names + rawdata_files = {} + + tree1 = ET.parse('./gen_mksurfdata_namelist.xml') + root = tree1.getroot() + root.tag + root.attrib + for child1 in root: + max_match_num = -1 + max_match_child = None + for child2 in child1: + if child2.tag == 'entry': + num_match = 0 + for attrib in attribute_list: + # Get the value of the attrib for the entry + childval = child2.get(attrib, default=None) + if childval == attribute_list[attrib]: + num_match += 1 + elif childval is not None: + num_match = -1 + break + if num_match > max_match_num: + max_match_num = num_match + max_match_child = child2 + + if max_match_child is None: + print (f"{child1.tag} has no matches") + raise "ERROR" + + for item in max_match_child: + if item.tag == 'data_filename': + rawdata_files[child1.tag] = os.path.join(input_path, item.text) + if '%y' in rawdata_files[child1.tag]: + # ERROR: keep %y here and do the replacement later + rawdata_files[child1.tag] = rawdata_files[child1.tag].replace("%y",str(start_year)) + if not os.path.isfile(rawdata_files[child1.tag]): + raise Exception (f"file {rawdata_files[child1.tag]} does not exist") + + if item.tag == 'mesh_filename': + new_key = f"{child1.tag}_mesh" + rawdata_files[new_key] = os.path.join(input_path, item.text) + if not os.path.isfile(rawdata_files[new_key]): + raise Exception (f"file {rawdata_files[new_key]} does not exist") + + tree2 = ET.parse('../../ccs_config/component_grids_nuopc.xml') + root = tree2.getroot() + model_mesh = "" + for child1 in root: # this is domain tag + for name, value in child1.attrib.items(): + if value == res: + for child2 in child1: + if child2.tag == 'mesh': + model_mesh = child2.text + rawdata_files["mksrf_fgrid_mesh"] = os.path.join(input_path,model_mesh.strip('$DIN_LOC_ROOT/')) + if child2.tag == 'nx': + rawdata_files["mksrf_fgrid_nx"] = child2.text + if child2.tag == 'ny': + rawdata_files["mksrf_fgrid_ny"] = child2.text + + if len(model_mesh) == 0: + print (f"ERROR: input res {res} is invalid") + valid_grids = [] + for child1 in root: # this is domain tag + for name, value in child1.attrib.items(): + valid_grids.append(value) + print (f"Valid values are {valid_grids}") + raise Exception ("Exiting") + + # Determine num_pft + if crop_flag: + num_pft = "78" + else: + num_pft = "16" + logger.debug(f" crop_flag = {str(crop_flag)} => num_pft = {num_pft}") + + # Create land-use txt file for a transient case. + # Determine the run type and if a transient run create output landuse txt file + if end_year > start_year: + run_type = "transient" + else: + run_type = "timeslice" + logger.info(f" run_type = {run_type}") + if run_type == 'transient': + landuse_fname = f"transient_timeseries_hist_{num_pft}pfts_simyr{start_year}-{end_year}.txt" + with open(landuse_fname, "w", encoding='utf-8') as landuse_file: + for year in range(start_year, end_year + 1): + file1 = rawdata_files["mksrf_fvegtyp"] + landuse_input_fname = file1.replace("%y",str(start_year)) + if not os.path.isfile(landuse_input_fname): + logger.warning(f"landunit_input_fname: {landuse_input_fname}") + # TODO: make the space/tab exactly the same as pl code: + landuse_line = landuse_input_fname + "\t\t\t" + str(year) + "\n" + # -- Each line is written twice in the original pl code: + landuse_file.write(landuse_line) + landuse_file.write(landuse_line) + logger.debug(f"year : {year}") + logger.debug(landuse_line) + logger.info("Successfully created land use file : {landuse_fname}.") + logger.info("-------------------------------------------------------") + else: + landuse_fname = "" + + time_stamp = datetime.today().strftime("%y%m%d") + if end_year == start_year: + nlfname = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.namelist" + fsurdat = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.nc" + fsurlog = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.log" + fdyndat = "" + else: + nlfname = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.namelist" + fsurdat = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.nc" + fsurlog = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.log" + fdyndat = f"landuse.timeseries_{res}_{ssp_rcp}_{num_pft}_CMIP6_{start_year}-{end_year}_c{time_stamp}.log" + + # TODO: make this an input argument + create_esmf_pet_files = .true. + + with open(nlfname, "w",encoding='utf-8') as nlfile: + + nlfile.write("&mksurfdata_input \n") + for key,value in rawdata_files.items(): + if key == 'mksrf_fgrid_nx' or key == 'mksrf_fgrid_ny': + nlfile.write(f" {key} = {value} \n") + elif key != "mksrf_vic": + nlfile.write(f" {key} = \'{value}\' \n") + + mksrf_hrvtyp = rawdata_files["mksrf_fvegtyp"] + nlfile.write( f" mksrf_hrvtyp = {mksrf_hrvtyp} \n") + + nlfile.write( " outnc_double = .true. \n") + nlfile.write( " all_urban = .false. \n") + nlfile.write( " no_inlandwet = .true. \n") + nlfile.write(f" numpft = {num_pft} \n") + nlfile.write( " fdyndat = \' \' \n") + nlfile.write(f" fsurdat = \'{fsurdat}\' \n") + nlfile.write(f" fsurlog = \'{fsurlog}\' \n") + + nlfile.write(f" start_year = {start_year}\n") + nlfile.write(f" end_year = {end_year}\n") + nlfile.write(f" mksrf_fdynuse = \'{landuse_fname} \' \n") + + mksrf_vic = rawdata_files["mksrf_fvic"] + nlfile.write(f" use_vic = {vic_flag} \n") + nlfile.write(f" mksrf_fvic = f{mksrf_vic} \n") + nlfile.write( " outnc_vic = .true. \n") + nlfile.write(f" use_glc = f{glc_flag} \n") + nlfile.write(f" create_esmf_pet_files = f{create_esmf_pet_files} \n") + nlfile.write("/ \n") + +if __name__ == "__main__": + main() diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml new file mode 100644 index 0000000000..38cea3e86f --- /dev/null +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -0,0 +1,282 @@ + + + + + + + + + + + + + lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.c170413.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + + + lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_lai_histclm52deg005_earthstatmirca_2005.c190119.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + + + + + + + + + + lnd/clm2/rawdata/mksrf_organic_10level_5x5min_ISRIC-WISE-NCSCD_nlev7_c120830.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc + + + + + + lnd/clm2/rawdata/mksrf_irrig_2160x4320_simyr2000.c110527.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc + + + + + + lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_soilcolor_CMIP6_simyr2005.c170623.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + + + lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_soilcolor_histclm52deg005_earthstatmirca_2005.c190116.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + + + + + + lnd/clm2/rawdata/mksrf_soitex.10level.c010119.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc + + + + + + lnd/clm2/rawdata/mksrf_fmax_0.125x0.125_c200220.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.125x0.125_nomask_c200129.nc + + + + + + + + + + lnd/clm2/rawdata/mksrf_LakePnDepth_3x3min_simyr2004_csplk_c151015.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + + + + + + lnd/clm2/rawdata/mksrf_lanwat.050425.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + + + + + + + + + + lnd/clm2/rawdata/mksrf_vocef_0.5x0.5_simyr2000.c110531.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + + + + + + + + + + lnd/clm2/rawdata/mksrf_urban_0.05x0.05_simyr2000.c120621.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + + + lnd/clm2/rawdata/mksrf_urban_0.05x0.05_zerourbanpct.c181014.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + + + + + + + lnd/clm2/rawdata/mksrf_topo.10min.c191120.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_c200129.nc + + + + + + + + + + + + + lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000.c120926.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + + + lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000_mergeGreenland.c120921.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + + + + + + lnd/clm2/rawdata/mksrf_GlacierRegion_10x10min_nomask_c191120.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_c200129.nc + + + + + + + + + + lnd/clm2/rawdata/mksrf_gdp_0.5x0.5_AVHRR_simyr2000.c130228.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + + + lnd/clm2/rawdata/mksrf_gdp_0.5x0_zerogdp.c200413.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + + + + + + lnd/clm2/rawdata/mksrf_peatf_0.5x0.5_AVHRR_simyr2000.c130228.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + + + + + + lnd/clm2/rawdata/mksf_soilthk_5x5min_ORNL-Soil_simyr1900-2015_c170630.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc + + + + + + lnd/clm2/rawdata/mksrf_abm_0.5x0.5_AVHRR_simyr2000.c130201.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + + + lnd/clm2/rawdata/mksrf_abm_0.5x0.5_missingabm.c200413.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + + + + + + + + + + lnd/clm2/rawdata/mksrf_topostats_1km-merge-10min_HYDRO1K-merge-nomask_simyr2000.c130402.nc + lnd/clm2/mappingdata/grids/UGRID_1km-merge-10min_HYDRO1K-merge-nomask_c130402.nc + + + + + + + + + + lnd/clm2/rawdata/mksrf_vic_0.9x1.25_GRDC_simyr2000.c130307.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.9x1.25_nomask_c200129.nc + + + + + + + + + + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.simyrPtVg.c181106/mksrf_landuse_potvegclm50_LUH2.c181106.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + + + + + lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_1850.c190119.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + + + lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_2005.c190119.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + + + + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_%y.c171012.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + + + + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_%y.c170629.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + + + + + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_%y.c181217.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + + + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_%y.c181217.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + + + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_%y.c181217.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + + + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_%y.c181217.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + + + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_%y.c181217.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + + + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_%y.c171005.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + + + + + diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt new file mode 100644 index 0000000000..938f868c28 --- /dev/null +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -0,0 +1,54 @@ +cmake_minimum_required(VERSION 3.10) +project(mksurfdata Fortran) + +#include(${CASEROOT}/Macros.cmake) +set (ESMFMKFILE /glade/work/oehmke/ESMF/scalable_mesh_from_file/lib/libg/Linux.intel.64.mpt.default/esmf.mk) +file(STRINGS ${ESMFMKFILE} esmf_mk_text) +foreach(line ${esmf_mk_text}) + string(REGEX REPLACE "^[ ]+" "" line ${line}) # strip leading spaces + if (line MATCHES "^ESMF_*") # process only line starting with ESMF_ + string(REGEX MATCH "^ESMF_[^=]+" esmf_name ${line}) + string(REPLACE "${esmf_name}=" "" emsf_value ${line}) + set(${esmf_name} "${emsf_value}") + endif() +endforeach() +string(REPLACE "-I" "" ESMF_F90COMPILEPATHS ${ESMF_F90COMPILEPATHS}) +string(REPLACE " " ";" ESMF_F90COMPILEPATHS ${ESMF_F90COMPILEPATHS}) +message("ESMF_F90COMPILEPATHS: ${ESMF_F90COMPILEPATHS}") + +set(SRCFILES mkvarctl.F90 + mkvarpar.F90 + mkpioMod.F90 + mkfileMod.F90 + mklanwatMod.F90 + mkesmfMod.F90 + mkutilsMod.F90 + mkchecksMod.F90 + fileutils.F90 + nanMod.F90 + shr_const_mod.F90 + shr_kind_mod.F90 + shr_log_mod.F90 + shr_string_mod.F90 + shr_sys_mod.F90 + shr_pio_mod.F90 + shr_mpi_mod.F90) + +add_library(mksurfdata ${SRCFILES}) + +add_compile_definitions(PIO2) + +message("CMAKE_CURRENT_BINARY_DIR is ${CMAKE_CURRENT_BINARY_DIR}") +message("PROJECT_BINARY_DIR is ${PROJECT_BINARY_DIR}") + +target_include_directories (mksurfdata PRIVATE ${ESMF_F90COMPILEPATHS}) +target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/include) + +#link_directories(/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/lib) +#target_link_libraries(mksurfdata piof) +#target_link_libraries(mksurfdata /glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/lib/libpiof.a) +#link_directories(/glade/p/cesmdata/cseg/PROGS/esmf/8.2.0b23/mpt/2.22/intel/19.1.1/lib/libg/Linux.intel.64.mpt.default) +#target_link_libraries(mksurfdata esmf) +#target_link_libraries(mksurfdata /glade/p/cesmdata/cseg/PROGS/esmf/8.2.0b23/mpt/2.22/intel/19.1.1/lib/libg/Linux.intel.64.mpt.default/libesmf.a) + +install(TARGETS mksurfdata) diff --git a/tools/mksurfdata_esmf/src/ESMF_RegridEx.F90 b/tools/mksurfdata_esmf/src/ESMF_RegridEx.F90 new file mode 100644 index 0000000000..2da6b6b57b --- /dev/null +++ b/tools/mksurfdata_esmf/src/ESMF_RegridEx.F90 @@ -0,0 +1,93 @@ +program ESMF_RegridEx + + !============================================================================== + ! This program shows examples of using Regrid on Field data + !----------------------------------------------------------------------------- + use ESMF + + implicit none + + ! Local variables to be used in the Regrid method calls. + ! The code creating and filling these variables is not included in the + ! example documentation because those interfaces are not specific to + ! Regrid. + type(ESMF_Field) :: field1, field2 + type(ESMF_IGrid) :: srcigrid, dstigrid + type(ESMF_RouteHandle) :: regrid_rh + type(ESMF_DELayout) :: layout1, layout2 + integer :: rc + integer :: finalrc, npets + integer :: i, j, lb(2), ub(2), halo + type(ESMF_ArraySpec) :: arrayspec + type(ESMF_VM) :: vm + real (ESMF_KIND_R8), dimension(:,:), pointer :: f90ptr1 + real (ESMF_KIND_R8), dimension(2) :: mincoords, maxcoords + + finalrc = ESMF_SUCCESS + + !------------------------------------------------------------------------- + ! ! Setup: + ! ! + ! ! Create a source and destination igrid with data on it, to use + ! ! in the Regrid calls below. + + call ESMF_Initialize(rc=rc) + call ESMF_VMGetGlobal(vm, rc=rc) + call ESMF_VMGet(vm, petCount=npets, rc=rc) + + layout1 = ESMF_DELayoutCreate(vm, (/ 1, npets /), rc=rc) + layout2 = ESMF_DELayoutCreate(vm, (/ npets, 1 /), rc=rc) + + mincoords = (/ 0.0, 0.0 /) + maxcoords = (/ 20.0, 30.0 /) + srcigrid = ESMF_IGridCreateHorzXYUni((/ 90, 180 /), mincoords, maxcoords, & + horzStagger=ESMF_IGRID_HORZ_STAGGER_A, name="srcigrid", rc=rc) + call ESMF_IGridDistribute(srcigrid, delayout=layout1, rc=rc) + + ! same igrid coordinates, but different layout + dstigrid = ESMF_IGridCreateHorzXYUni((/ 90, 180 /), mincoords, maxcoords, horzStagger=ESMF_IGRID_HORZ_STAGGER_A, name="srcigrid", rc=rc) + call ESMF_IGridDistribute(dstigrid, delayout=layout2, rc=rc) + call ESMF_ArraySpecSet(arrayspec, 2, ESMF_TYPEKIND_R8, rc) + + ! allow for a halo width of 3, let field create data space + halo = 3 + field1 = ESMF_FieldCreate(srcigrid, arrayspec, horzRelloc=ESMF_CELL_CENTER, haloWidth=3, name="src pressure", rc=rc) + + ! get a fortran pointer to the data spacd + call ESMF_FieldGetDataPointer(field1, f90ptr1, ESMF_DATACOPY_REFERENCE, rc=rc) + + lb(:) = lbound(f90ptr1) + ub(:) = ubound(f90ptr1) + + f90ptr1(:,:) = 0.0 + do j=lb(2)+halo, ub(2)-halo + do i=lb(1)+halo, ub(1)-halo + f90ptr1(i, j) = i*1000 + j + enddo + enddo + + field2 = ESMF_FieldCreate(dstigrid, arrayspec, horzRelloc=ESMF_CELL_CENTER, name="dst pressure", rc=rc) + + ! fields all ready to go + ! The user has already created an {\tt ESMF\_IGrid}, an + ! {\tt ESMF\_Array} with data, and put them together in an {\tt ESMF\_Field}. + ! An {\tt ESMF\_RouteHandle} is created by the regrid store call + ! and the data movement needed to + ! execute the regrid is stored with that handle by the store method. + ! To actually execute the operation, the source and destination data + ! objects must be supplied, along with the same {\tt ESMF\_RouteHandle}. + + call ESMF_FieldRegridStore(field1, field2, vm, routehandle=regrid_rh, regridmethod=ESMF_REGRIDMETHOD_BILINEAR, rc=rc) + call ESMF_FieldRegrid(field1, field2, regrid_rh, rc=rc) + call ESMF_FieldRegridRelease(regrid_rh, rc=rc) + + call ESMF_FieldDestroy(field1, rc=rc) + call ESMF_FieldDestroy(field2, rc=rc) + call ESMF_IGridDestroy(srcigrid, rc=rc) + call ESMF_IGridDestroy(dstigrid, rc=rc) + call ESMF_Finalize(rc=rc) + +end program ESMF_RegridEx + + + diff --git a/tools/mksurfdata_esmf/src/Makefile b/tools/mksurfdata_esmf/src/Makefile new file mode 100644 index 0000000000..ddc4bf3c69 --- /dev/null +++ b/tools/mksurfdata_esmf/src/Makefile @@ -0,0 +1,66 @@ +# GNU Makefile template for user ESMF application + +################################################################################ +################################################################################ +## This Makefile must be able to find the "esmf.mk" Makefile fragment in the ## +## 'include' line below. Following the ESMF User's Guide, a complete ESMF ## +## installation should ensure that a single environment variable "ESMFMKFILE" ## +## is made available on the system. This variable should point to the ## +## "esmf.mk" file. ## +## ## +## This example Makefile uses the "ESMFMKFILE" environment variable. ## +## ## +## If you notice that this Makefile cannot find variable ESMFMKFILE then ## +## please contact the person responsible for the ESMF installation on your ## +## system. ## +## As a work-around you can simply hardcode the path to "esmf.mk" in the ## +## include line below. However, doing so will render this Makefile a lot less ## +## flexible and non-portable. ## +################################################################################ + + +COMPILEPATH = -I/glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/bld -I/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/include +LINKPATH = -L/glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/bld -L/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/lib/ + +ESMFMKFILE=/glade/work/oehmke/ESMF/scalable_mesh_from_file/lib/libg/Linux.intel.64.mpt.default/esmf.mk +include $(ESMFMKFILE) + +################################################################################ +################################################################################ + +.SUFFIXES: .f90 .F90 .c .C + +%.o : %.f90 + $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) $(ESMF_F90COMPILEFREENOCPP) $(COMPILEPATH) $< + +%.o : %.F90 + $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) $(ESMF_F90COMPILEFREECPP) $(ESMF_F90COMPILECPPFLAGS) $(COMPILEPATH) $< + +%.o : %.c + $(ESMF_CXXCOMPILER) -c $(ESMF_CXXCOMPILEOPTS) $(ESMF_CXXCOMPILEPATHSLOCAL) $(ESMF_CXXCOMPILEPATHS) $(ESMF_CXXCOMPILECPPFLAGS) $< + +%.o : %.C + $(ESMF_CXXCOMPILER) -c $(ESMF_CXXCOMPILEOPTS) $(ESMF_CXXCOMPILEPATHSLOCAL) $(ESMF_CXXCOMPILEPATHS) $(ESMF_CXXCOMPILECPPFLAGS) $< + +# ----------------------------------------------------------------------------- +mksurfdata: mksurfdata.o + $(ESMF_F90LINKER) $(ESMF_F90LINKOPTS) $(ESMF_F90LINKPATHS) $(ESMF_F90LINKRPATHS) -o $@ $^ $(ESMF_F90ESMFLINKLIBS) $(LINKPATH) -l mksurfdata -l piof + +# ----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- +.PHONY: dust clean distclean info edit +dust: + rm -f PET*.ESMF_LogFile *.nc *.stdout +clean: + rm -f esmApp *.o *.mod +distclean: dust clean + +info: + @echo ================================================================== + @echo ESMFMKFILE=$(ESMFMKFILE) + @echo ================================================================== + @cat $(ESMFMKFILE) + @echo ================================================================== + +run: + $(ESMF_INTERNAL_MPIRUN) -np 4 ./esmApp diff --git a/tools/mksurfdata_esmf/src/chkerrMod.F90 b/tools/mksurfdata_esmf/src/chkerrMod.F90 new file mode 100644 index 0000000000..cf38ecd64a --- /dev/null +++ b/tools/mksurfdata_esmf/src/chkerrMod.F90 @@ -0,0 +1 @@ +module mkutilMod diff --git a/tools/mksurfdata_esmf/src/fileutils.F90 b/tools/mksurfdata_esmf/src/fileutils.F90 new file mode 100644 index 0000000000..2a28ac3ba9 --- /dev/null +++ b/tools/mksurfdata_esmf/src/fileutils.F90 @@ -0,0 +1,38 @@ +module fileutils + + !----------------------------------------------------------------------- + ! Module containing file I/O utilities + !----------------------------------------------------------------------- + + use shr_sys_mod, only : shr_sys_abort + + implicit none + + public :: get_filename !Returns filename given full pathname + +!----------------------------------------------------------------------- +contains +!----------------------------------------------------------------------- + + character(len=256) function get_filename (fulpath) + ! Returns filename given full pathname + + ! input/output variables + character(len=*), intent(in) :: fulpath !full pathname + + ! local variables: + integer :: i !loop index + integer :: klen !length of fulpath character string + !------------------------------------------------------------------------ + + klen = len_trim(fulpath) + do i = klen, 1, -1 + if (fulpath(i:i) == '/') go to 10 + end do + i = 0 +10 get_filename = fulpath(i+1:klen) + + return + end function get_filename + +end module fileutils diff --git a/tools/mksurfdata_esmf/src/log.out b/tools/mksurfdata_esmf/src/log.out new file mode 100644 index 0000000000000000000000000000000000000000..d60d4108cbcb7c627d9220e7f4b2af5667d02551 GIT binary patch literal 14179 zcmeHOQE%EX5Z>$f75CUmEd-CY6sZqwDN?1;R;<+?Ba@iok=V?3)^)#r=Y)i?O|;w4 z2GaQff_?Gb`Mx_Ji4O)c5iplJlnRt~FwvQc55NlNqGpY9vpwCvoI58{ zL_7u|bZ4oglRS~%1VUdqqmxQ0X!_PbU5!h69u+o=rZDk=4fT(u5s}m8xnjBl%5RyO zUS6@6DgHa47Hhf&a$C0QFH5>DYq~quCrN#j-B5_$Ie#JRll9jnJ%kU!$2xq_e(Uk^ zs`Q=q2ESB`M*Hp7{>>zumLSD%!YSd@KMOX0^WcU&iaaW$OxlBh;wi;bil=2b+@hBY zv`3Xjp(wS@FTn_>gj33;atu%|MY$B^Qe`-#Tx!)D=$Z7&di=X%I+UT5E{Wf?N3Ec6 zn~swaP6?-!N#_{YY?PvR;(k#n|5%Cqlz-ID)h`Y-(+)&C&<^ZCS|`zzOV#pMww2CoW+pLr zJQOyaw5*BheNr{9Q~p>K9#nX_yR0r37bBfvX}}8E``YghIy2GAC^VLwtI2|@bq3vb z{{rAa&6Ivp6-9AT^)4>f&vn%9utBhyxjJ2Td2+I$xq|cVG3q!xzrG2>A5_eLvZG_H z6RIrK9GnL0RqX_)ea2obULwcQA!{<$v}J{sw*b57^aD0{*FU~G0tiD-7Fx%R3sXc+ zF52&z0Oh)5r>~Z4cy|w1qtWfC2gAGT@bY#z3_sqE-uD6P+GY^I6wA__FsW1=>(a1f i%}o)25b-4O1uFig0gn0ll)e4NTRzq%uUz@0$Bpk`nf7M@ literal 0 HcmV?d00001 diff --git a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 new file mode 100644 index 0000000000..431e43cb28 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 @@ -0,0 +1,200 @@ +module mkVICparamsMod + +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mkVICparamsMod +! +! !DESCRIPTION: +! make parameters for VIC +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +!----------------------------------------------------------------------- +! +! !USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush + use mkdomainMod , only : domain_checksame + + implicit none + + private + +! !PUBLIC MEMBER FUNCTIONS: + public mkVICparams ! make VIC parameters +! +!EOP +!=============================================================== +contains +!=============================================================== + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkVICparams +! +! !INTERFACE: +subroutine mkVICparams(ldomain, mapfname, datfname, ndiag, & + binfl_o, ws_o, dsmax_o, ds_o) +! +! !DESCRIPTION: +! make VIC parameters +! +! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkncdio + use mkdiagnosticsMod, only : output_diagnostics_continuous + use mkchecksMod, only : min_bad +! +! !ARGUMENTS: + + implicit none + type(domain_type) , intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: binfl_o(:) ! output grid: VIC b parameter for the Variable Infiltration Capacity Curve (unitless) + real(r8) , intent(out):: ws_o(:) ! output grid: VIC Ws parameter for the ARNO curve (unitless) + real(r8) , intent(out):: dsmax_o(:) ! output grid: VIC Dsmax parameter for the ARNO curve (mm/day) + real(r8) , intent(out):: ds_o(:) ! output grid: VIC Ds parameter for the ARNO curve (unitless) +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +! +! !LOCAL VARIABLES: +!EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: data_i(:) ! data on input grid + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + integer :: ncid,varid ! input netCDF id's + integer :: ier ! error status + + real(r8), parameter :: min_valid_binfl = 0._r8 + real(r8), parameter :: min_valid_ws = 0._r8 + real(r8), parameter :: min_valid_dsmax = 0._r8 + real(r8), parameter :: min_valid_ds = 0._r8 + + character(len=32) :: subname = 'mkVICparams' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make VIC parameters.....' + call shr_sys_flush(6) + + ! ----------------------------------------------------------------- + ! Read domain and mapping information, check for consistency + ! ----------------------------------------------------------------- + + call domain_read(tdomain,datfname) + + call gridmap_mapread(tgridmap, mapfname ) + + ! Obtain frac_dst + allocate(frac_dst(ldomain%ns), stat=ier) + if (ier/=0) call abort() + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + allocate(mask_r8(tdomain%ns), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! ----------------------------------------------------------------- + ! Open input file, allocate memory for input data + ! ----------------------------------------------------------------- + + write(6,*)'Open VIC parameter file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + + allocate(data_i(tdomain%ns), stat=ier) + if (ier/=0) call abort() + + ! ----------------------------------------------------------------- + ! Regrid binfl + ! ----------------------------------------------------------------- + + call check_ret(nf_inq_varid (ncid, 'binfl', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + call gridmap_areaave_srcmask(tgridmap, data_i, binfl_o, nodata=0.1_r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check validity of output data + if (min_bad(binfl_o, min_valid_binfl, 'binfl')) then + call abort() + end if + + call output_diagnostics_continuous(data_i, binfl_o, tgridmap, "VIC b parameter", "unitless", ndiag, tdomain%mask, frac_dst) + + ! ----------------------------------------------------------------- + ! Regrid Ws + ! ----------------------------------------------------------------- + + call check_ret(nf_inq_varid (ncid, 'Ws', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + call gridmap_areaave_srcmask(tgridmap, data_i, ws_o, nodata=0.75_r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check validity of output data + if (min_bad(ws_o, min_valid_ws, 'Ws')) then + call abort() + end if + + call output_diagnostics_continuous(data_i, ws_o, tgridmap, "VIC Ws parameter", "unitless", ndiag, tdomain%mask, frac_dst) + + ! ----------------------------------------------------------------- + ! Regrid Dsmax + ! ----------------------------------------------------------------- + + call check_ret(nf_inq_varid (ncid, 'Dsmax', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + call gridmap_areaave_srcmask(tgridmap, data_i, dsmax_o, nodata=10._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check validity of output data + if (min_bad(dsmax_o, min_valid_dsmax, 'Dsmax')) then + call abort() + end if + + call output_diagnostics_continuous(data_i, dsmax_o, tgridmap, "VIC Dsmax parameter", "mm/day", ndiag, tdomain%mask, frac_dst) + + ! ----------------------------------------------------------------- + ! Regrid Ds + ! ----------------------------------------------------------------- + + call check_ret(nf_inq_varid (ncid, 'Ds', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + call gridmap_areaave_srcmask(tgridmap, data_i, ds_o, nodata=0.1_r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check validity of output data + if (min_bad(ds_o, min_valid_ds, 'Ds')) then + call abort() + end if + + call output_diagnostics_continuous(data_i, ds_o, tgridmap, "VIC Ds parameter", "unitless", ndiag, tdomain%mask, frac_dst) + + ! ----------------------------------------------------------------- + ! Close files and deallocate dynamic memory + ! ----------------------------------------------------------------- + + call check_ret(nf_close(ncid), subname) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (data_i) + deallocate (frac_dst) + deallocate (mask_r8) + + write (6,*) 'Successfully made VIC parameters' + write (6,*) + call shr_sys_flush(6) + +end subroutine mkVICparams + + +end module mkVICparamsMod diff --git a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 new file mode 100644 index 0000000000..7b58ddffad --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 @@ -0,0 +1,273 @@ +module mkagfirepkmonthMod +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mkagfirepkmonthMod +! +! !DESCRIPTION: +! Make agricultural fire peak month data +! +! !REVISION HISTORY: +! Author: Sam Levis and Bill Sacks +! +!----------------------------------------------------------------------- +!!USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush + use mkdomainMod , only : domain_checksame + implicit none + + SAVE + private ! By default make data private +! +! !PUBLIC MEMBER FUNCTIONS: +! + public mkagfirepkmon ! Set agricultural fire peak month +! +! !PRIVATE MEMBER FUNCTIONS: + private define_months ! define month strings +! +! !PRIVATE DATA MEMBERS: +! + integer , parameter :: min_valid_value = 1 + integer , parameter :: max_valid_value = 12 + integer , parameter :: unsetmon = 13 ! flag to indicate agricultural fire peak month NOT set +! +! !PRIVATE DATA MEMBERS: +! +!EOP +!=============================================================== +contains +!=============================================================== + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkagfirepkmon +! +! !INTERFACE: +subroutine mkagfirepkmon(ldomain, mapfname, datfname, ndiag, & + agfirepkmon_o) +! +! !DESCRIPTION: +! Make agricultural fire peak month data from higher resolution data +! +! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkindexmapMod, only : get_dominant_indices + use mkvarpar, only : re + use mkncdio + use mkchecksMod, only : min_bad, max_bad +! +! !ARGUMENTS: + implicit none + type(domain_type) , intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + integer , intent(out):: agfirepkmon_o(:) ! agricultural fire peak month +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Sam Levis and Bill Sacks +! +! +! !LOCAL VARIABLES: +!EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: gast_i(:) ! global area, by surface type + real(r8), allocatable :: gast_o(:) ! global area, by surface type + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + integer , allocatable :: agfirepkmon_i(:) ! input grid: agricultural fire peak month + integer :: nagfirepkmon ! number of peak months + character(len=35), allocatable :: month(:)! name of each month + integer :: k,ni,no,ns_i,ns_o ! indices + integer :: ncid,varid ! input netCDF id's + integer :: ier ! error status + + integer, parameter :: miss = unsetmon ! missing data indicator + integer, parameter :: min_valid = 1 ! minimum valid value + integer, parameter :: max_valid = 13 ! maximum valid value + character(len=32) :: subname = 'mkagfirepkmon' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make agricultural fire peak month data .....' + call shr_sys_flush(6) + + ! ----------------------------------------------------------------- + ! Read domain and mapping information, check for consistency + ! ----------------------------------------------------------------- + + call domain_read( tdomain,datfname ) + + call gridmap_mapread( tgridmap, mapfname ) + + ! Obtain frac_dst + ns_o = ldomain%ns + allocate(frac_dst(ns_o), stat=ier) + if (ier/=0) call abort() + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ns_i = tdomain%ns + allocate(mask_r8(ns_i), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! ----------------------------------------------------------------- + ! Open input file, allocate memory for input data + ! ----------------------------------------------------------------- + + write (6,*) 'Open agricultural fire peak month file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + + allocate(agfirepkmon_i(ns_i), stat=ier) + if (ier/=0) call abort() + + ! ----------------------------------------------------------------- + ! Regrid ag fire peak month + ! ----------------------------------------------------------------- + + call check_ret(nf_inq_varid (ncid, 'abm', varid), subname) + call check_ret(nf_get_var_int (ncid, varid, agfirepkmon_i), subname) + ! Note that any input point that is outside the range [min_valid_value,max_valid_value] + ! will be ignored; this ignores input points with value of unsetmon + call get_dominant_indices(tgridmap, agfirepkmon_i, agfirepkmon_o, & + min_valid_value, max_valid_value, miss, mask_src=tdomain%mask) + + ! Check validity of output data + if (min_bad(agfirepkmon_o, min_valid, 'agfirepkmon') .or. & + max_bad(agfirepkmon_o, max_valid, 'agfirepkmon')) then + call abort() + end if + + + ! ----------------------------------------------------------------- + ! Output diagnostics comparing global area of each peak month on input and output grids + ! + ! WJS (3-4-13): I am trying to generally put these diagnostics in mkdiagnosticsMod, but + ! so far there isn't a general diagnostics routine for categorical data + ! + ! TODO(wjs, 2016-01-22) Now there is a routine for this: output_diagnostics_index. + ! However, it currently doesn't provide the capability for named months. Either add + ! that capability or decide it's not important, then delete the below code, instead + ! calling output_diagnostics_index. + ! ----------------------------------------------------------------- + + nagfirepkmon = maxval(agfirepkmon_i) + allocate(gast_i(1:nagfirepkmon),gast_o(1:nagfirepkmon),month(1:nagfirepkmon)) + call define_months(nagfirepkmon, month) + + gast_i(:) = 0.0_r8 + do ni = 1,ns_i + k = agfirepkmon_i(ni) + gast_i(k) = gast_i(k) + tgridmap%area_src(ni)*tdomain%mask(ni)*re**2 + end do + + gast_o(:) = 0.0_r8 + do no = 1,ns_o + k = agfirepkmon_o(no) + gast_o(k) = gast_o(k) + tgridmap%area_dst(no)*frac_dst(no)*re**2 + end do + + ! area comparison + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'Agricultural fire peak month Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,1001) +1001 format (1x,'peak month',20x,' input grid area output grid area',/ & + 1x,33x,' 10**6 km**2',' 10**6 km**2') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + + do k = 1, nagfirepkmon + write (ndiag,1002) month(k),gast_i(k)*1.e-6,gast_o(k)*1.e-6 +1002 format (1x,a35,f16.3,f17.3) + end do + + ! ----------------------------------------------------------------- + ! Close files and deallocate dynamic memory + ! ----------------------------------------------------------------- + + call check_ret(nf_close(ncid), subname) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (agfirepkmon_i,gast_i,gast_o,month, frac_dst, mask_r8) + + write (6,*) 'Successfully made Agricultural fire peak month' + write (6,*) + call shr_sys_flush(6) + +end subroutine mkagfirepkmon + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: define_months +! +! !INTERFACE: +subroutine define_months(nagfirepkmon, month) +! +! !DESCRIPTION: +! Define month strings +! +! !USES: +! +! !ARGUMENTS: + implicit none + integer , intent(in) :: nagfirepkmon ! max input value (including the 'unset' special value) + character(len=*), intent(out):: month(:) ! name of each month value +! +! !CALLED FROM: +! subroutine mkagfirepkmon +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +! +! !LOCAL VARIABLES: +!EOP +!----------------------------------------------------------------------- + + if (nagfirepkmon == unsetmon) then + if (size(month) < 13) then + write(6,*) 'month array too small: ', size(month), ' < 13' + call abort() + end if + month(1) = 'January ' + month(2) = 'February ' + month(3) = 'March ' + month(4) = 'April ' + month(5) = 'May ' + month(6) = 'June ' + month(7) = 'July ' + month(8) = 'August ' + month(9) = 'September ' + month(10) = 'October ' + month(11) = 'November ' + month(12) = 'December ' + month(13) = 'no agricultural fire peak month data' + else + write(6,*)'nagfirepkmon value of ',nagfirepkmon,' not supported' + call abort() + end if + +end subroutine define_months +!----------------------------------------------------------------------- + + +end module mkagfirepkmonthMod diff --git a/tools/mksurfdata_esmf/src/mkchecksMod.F90 b/tools/mksurfdata_esmf/src/mkchecksMod.F90 new file mode 100644 index 0000000000..d78888c3bf --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkchecksMod.F90 @@ -0,0 +1,159 @@ +module mkchecksMod + + !----------------------------------------------------------------------- + ! Generic routines to check validity of output fields + !----------------------------------------------------------------------- + + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush + + implicit none + private + + public :: min_bad ! check the minimum value of a field + public :: max_bad ! check the maximum value of a field + + interface min_bad + module procedure min_bad_int + module procedure min_bad_r8 + end interface min_bad + + interface max_bad + module procedure max_bad_int + module procedure max_bad_r8 + end interface max_bad + +!=============================================================== +contains +!=============================================================== + + logical function min_bad_r8(data, min_allowed, varname) + + ! Confirm that no value of data is less than min_allowed. + ! Returns true if errors found, false otherwise. + ! Also prints offending points + + ! !ARGUMENTS: + real(r8) , intent(in) :: data(:) ! array of data to check + real(r8) , intent(in) :: min_allowed ! minimum valid value + character(len=*) , intent(in) :: varname ! name of field + + ! !LOCAL VARIABLES: + logical :: errors_found ! true if any errors have been found + integer :: n ! index + character(len=*), parameter :: subname = 'min_bad_r8' + !------------------------------------------------------------------------------ + + errors_found = .false. + + do n = 1, size(data) + if (data(n) < min_allowed) then + write(6,*) subname//' ERROR: ', trim(varname), ' = ', data(n), ' less than ',& + min_allowed, ' at ', n + errors_found = .true. + end if + end do + + call shr_sys_flush(6) + min_bad_r8 = errors_found + end function min_bad_r8 + + !=============================================================== + logical function min_bad_int(data, min_allowed, varname) + + ! !DESCRIPTION: + ! Confirm that no value of data is less than min_allowed. + ! Returns true if errors found, false otherwise. + ! Also prints offending points + + ! !ARGUMENTS: + integer , intent(in) :: data(:) ! array of data to check + integer , intent(in) :: min_allowed ! minimum valid value + character(len=*) , intent(in) :: varname ! name of field + + ! !LOCAL VARIABLES: + logical :: errors_found ! true if any errors have been found + integer :: n ! index + character(len=*), parameter :: subname = 'min_bad_int' + !------------------------------------------------------------------------------ + + errors_found = .false. + + do n = 1, size(data) + if (data(n) < min_allowed) then + write(6,*) subname//' ERROR: ', trim(varname), ' = ', data(n), ' less than ',& + min_allowed, ' at ', n + errors_found = .true. + end if + end do + + call shr_sys_flush(6) + min_bad_int = errors_found + end function min_bad_int + + !=============================================================== + logical function max_bad_r8(data, max_allowed, varname) + + ! Confirm that no value of data is greate than max_allowed. + ! Returns true if errors found, false otherwise. + ! Also prints offending points + + ! !ARGUMENTS: + real(r8) , intent(in) :: data(:) ! array of data to check + real(r8) , intent(in) :: max_allowed ! maximum valid value + character(len=*) , intent(in) :: varname ! name of field + + ! !LOCAL VARIABLES: + logical :: errors_found ! true if any errors have been found + integer :: n ! index + character(len=*), parameter :: subname = 'max_bad_r8' + !------------------------------------------------------------------------------ + + errors_found = .false. + + do n = 1, size(data) + if (data(n) > max_allowed) then + write(6,*) subname//' ERROR: ', trim(varname), ' = ', data(n), ' greater than ',& + max_allowed, ' at ', n + errors_found = .true. + end if + end do + + call shr_sys_flush(6) + max_bad_r8 = errors_found + end function max_bad_r8 + + !=============================================================== + logical function max_bad_int(data, max_allowed, varname) + + ! !DESCRIPTION: + ! Confirm that no value of data is greate than max_allowed. + ! Returns true if errors found, false otherwise. + ! Also prints offending points + + ! !ARGUMENTS: + integer , intent(in) :: data(:) ! array of data to check + integer , intent(in) :: max_allowed ! maximum valid value + character(len=*) , intent(in) :: varname ! name of field + + ! !LOCAL VARIABLES: + logical :: errors_found ! true if any errors have been found + integer :: n ! index + character(len=*), parameter :: subname = 'max_bad_int' + !------------------------------------------------------------------------------ + + errors_found = .false. + + do n = 1, size(data) + if (data(n) > max_allowed) then + write(6,*) subname//' ERROR: ', trim(varname), ' = ', data(n), ' greater than ',& + max_allowed, ' at ', n + errors_found = .true. + end if + end do + + call shr_sys_flush(6) + max_bad_int = errors_found + end function max_bad_int + +end module mkchecksMod diff --git a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 new file mode 100644 index 0000000000..4aab56e792 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 @@ -0,0 +1,398 @@ +module mkdiagnosticsMod + + !----------------------------------------------------------------------- + ! Output diagnostics to log file + !----------------------------------------------------------------------- + + use shr_kind_mod, only : r8 => shr_kind_r8 + + implicit none + private + + ! !PUBLIC MEMBER FUNCTIONS: + public :: output_diagnostics_area ! output diagnostics for field that is % of grid area + public :: output_diagnostics_continuous ! output diagnostics for a continuous (real-valued) field + public :: output_diagnostics_continuous_outonly ! output diagnostics for a continuous (real-valued) field + ! just on the output grid + public :: output_diagnostics_index ! output diagnostics for an index field + +!------------------------------------------------------------------------------ +contains +!------------------------------------------------------------------------------ + + subroutine output_diagnostics_area(data_i, data_o, gridmap, name, percent, ndiag, mask_src, frac_dst) + + ! Output diagnostics for a field that gives either fraction or percent of grid cell area + + use mkgridmapMod, only : gridmap_type + use mkvarpar, only : re + + ! !ARGUMENTS: + implicit none + real(r8) , intent(in) :: data_i(:) ! data on input grid + real(r8) , intent(in) :: data_o(:) ! data on output grid + type(gridmap_type), intent(in) :: gridmap ! mapping info + character(len=*) , intent(in) :: name ! name of field + logical , intent(in) :: percent ! is field specified as percent? (alternative is fraction) + integer , intent(in) :: ndiag ! unit number for diagnostic output + integer, intent(in) :: mask_src(:) + real(r8), intent(in) :: frac_dst(:) + + ! !LOCAL VARIABLES: + real(r8) :: gdata_i ! global sum of input data + real(r8) :: gdata_o ! global sum of output data + real(r8) :: garea_i ! global sum of input area + real(r8) :: garea_o ! global sum of output area + integer :: ns_i, ns_o ! sizes of input & output grids + integer :: ni,no,k ! indices + character(len=*), parameter :: subname = "output_diagnostics_area" + !------------------------------------------------------------------------------ + + ! Error check for array size consistencies + + ns_i = gridmap%na + ns_o = gridmap%nb + if (size(data_i) /= ns_i .or. & + size(data_o) /= ns_o) then + write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) + write(6,*) 'size(data_i) = ', size(data_i) + write(6,*) 'ns_i = ', ns_i + write(6,*) 'size(data_o) = ', size(data_o) + write(6,*) 'ns_o = ', ns_o + call abort() + end if + if (size(frac_dst) /= ns_o) then + write(6,*) subname//' ERROR: incorrect size of frac_dst' + write(6,*) 'size(frac_dst) = ', size(frac_dst) + write(6,*) 'ns_o = ', ns_o + call abort() + end if + if (size(mask_src) /= ns_i) then + write(6,*) subname//' ERROR: incorrect size of mask_src' + write(6,*) 'size(mask_src) = ', size(mask_src) + write(6,*) 'ns_i = ', ns_i + call abort() + end if + + ! Sums on input grid + + gdata_i = 0. + garea_i = 0. + do ni = 1,ns_i + garea_i = garea_i + gridmap%area_src(ni)*re**2 + gdata_i = gdata_i + data_i(ni) * gridmap%area_src(ni) * mask_src(ni) * re**2 + end do + + ! Sums on output grid + + gdata_o = 0. + garea_o = 0. + do no = 1,ns_o + garea_o = garea_o + gridmap%area_dst(no)*re**2 + gdata_o = gdata_o + data_o(no) * gridmap%area_dst(no) * frac_dst(no) * re**2 + end do + + ! Correct units + + if (percent) then + gdata_i = gdata_i / 100._r8 + gdata_o = gdata_o / 100._r8 + end if + + ! Diagnostic output + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) trim(name), ' Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,2001) +2001 format (1x,'surface type input grid area output grid area'/ & + 1x,' 10**6 km**2 10**6 km**2 ') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + write (ndiag,2002) name, gdata_i*1.e-06, gdata_o*1.e-06 + write (ndiag,2002) 'all surface', garea_i*1.e-06, garea_o*1.e-06 +2002 format (1x,a12, f14.3,f17.3) + + end subroutine output_diagnostics_area + + !------------------------------------------------------------------------------ + subroutine output_diagnostics_continuous(data_i, data_o, gridmap, name, units, ndiag, mask_src, frac_dst) + + ! Output diagnostics for a continuous field (but not area, for which there is a different routine) + + use mkgridmapMod, only : gridmap_type + use mkvarpar, only : re + + ! !ARGUMENTS: + real(r8) , intent(in) :: data_i(:) ! data on input grid + real(r8) , intent(in) :: data_o(:) ! data on output grid + type(gridmap_type), intent(in) :: gridmap ! mapping info + character(len=*) , intent(in) :: name ! name of field + character(len=*) , intent(in) :: units ! units of field + integer , intent(in) :: ndiag ! unit number for diagnostic output + integer, intent(in) :: mask_src(:) + real(r8), intent(in) :: frac_dst(:) + + ! !LOCAL VARIABLES: + real(r8) :: gdata_i ! global sum of input data + real(r8) :: gdata_o ! global sum of output data + real(r8) :: gwt_i ! global sum of input weights (area * frac) + real(r8) :: gwt_o ! global sum of output weights (area * frac) + integer :: ns_i, ns_o ! sizes of input & output grids + integer :: ni,no,k ! indices + character(len=*), parameter :: subname = "output_diagnostics_continuous" + !------------------------------------------------------------------------------ + + ! Error check for array size consistencies + + ns_i = gridmap%na + ns_o = gridmap%nb + if (size(data_i) /= ns_i .or. & + size(data_o) /= ns_o) then + write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) + write(6,*) 'size(data_i) = ', size(data_i) + write(6,*) 'ns_i = ', ns_i + write(6,*) 'size(data_o) = ', size(data_o) + write(6,*) 'ns_o = ', ns_o + call abort() + end if + if (size(frac_dst) /= ns_o) then + write(6,*) subname//' ERROR: incorrect size of frac_dst' + write(6,*) 'size(frac_dst) = ', size(frac_dst) + write(6,*) 'ns_o = ', ns_o + call abort() + end if + if (size(mask_src) /= ns_i) then + write(6,*) subname//' ERROR: incorrect size of mask_src' + write(6,*) 'size(mask_src) = ', size(mask_src) + write(6,*) 'ns_i = ', ns_i + call abort() + end if + + ! Sums on input grid + + gdata_i = 0. + gwt_i = 0. + do ni = 1,ns_i + gdata_i = gdata_i + data_i(ni) * gridmap%area_src(ni) * mask_src(ni) + gwt_i = gwt_i + gridmap%area_src(ni) * mask_src(ni) + end do + + ! Sums on output grid + + gdata_o = 0. + gwt_o = 0. + do no = 1,ns_o + gdata_o = gdata_o + data_o(no) * gridmap%area_dst(no) * frac_dst(no) + gwt_o = gwt_o + gridmap%area_dst(no) * frac_dst(no) + end do + + ! Correct units + + gdata_i = gdata_i / gwt_i + gdata_o = gdata_o / gwt_o + + ! Diagnostic output + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) trim(name), ' Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,2001) + write (ndiag,2002) units, units +2001 format (1x,' parameter input grid output grid') +2002 format (1x,' ', a24, a24) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + write (ndiag,2003) name, gdata_i, gdata_o +2003 format (1x,a12, f22.3,f17.3) + + end subroutine output_diagnostics_continuous + + !------------------------------------------------------------------------------ + subroutine output_diagnostics_continuous_outonly(data_o, gridmap, name, units, ndiag) + ! + ! !DESCRIPTION: + ! Output diagnostics for a continuous field, just on the output grid + ! This is used when the average of the field on the input grid is not of interest (e.g., + ! when the output quantity is the standard deviation of the input field) + + use mkgridmapMod, only : gridmap_type + use mkvarpar, only : re + + ! !ARGUMENTS: + real(r8) , intent(in) :: data_o(:) ! data on output grid + type(gridmap_type), intent(in) :: gridmap ! mapping info + character(len=*) , intent(in) :: name ! name of field + character(len=*) , intent(in) :: units ! units of field + integer , intent(in) :: ndiag ! unit number for diagnostic output + + ! !LOCAL VARIABLES: + real(r8) :: gdata_o ! global sum of output data + real(r8) :: gwt_o ! global sum of output weights (area * frac) + integer :: ns_o ! size of output grid + integer :: no,k ! indices + character(len=*), parameter :: subname = "output_diagnostics_continuous_outonly" + !------------------------------------------------------------------------------ + + ! Error check for array size consistencies + + ns_o = gridmap%nb + if (size(data_o) /= ns_o) then + write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) + write(6,*) 'size(data_o) = ', size(data_o) + write(6,*) 'ns_o = ', ns_o + call abort() + end if + + ! Sums on output grid + + gdata_o = 0. + gwt_o = 0. + do no = 1,ns_o + gdata_o = gdata_o + data_o(no)*gridmap%area_dst(no)*gridmap%frac_dst(no) + gwt_o = gwt_o + gridmap%area_dst(no)*gridmap%frac_dst(no) + end do + + ! Correct units + + gdata_o = gdata_o / gwt_o + + ! Diagnostic output + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) trim(name), ' Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,2001) + write (ndiag,2002) units +2001 format (1x,' parameter output grid') +2002 format (1x,' ', a24) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + write (ndiag,2003) name, gdata_o +2003 format (1x,a12, f22.3) + + end subroutine output_diagnostics_continuous_outonly + + !----------------------------------------------------------------------- + subroutine output_diagnostics_index(data_i, data_o, gridmap, name, & + minval, maxval, ndiag, mask_src, frac_dst) + ! + ! !DESCRIPTION: + ! Output diagnostics for an index field: area of each index in input and output + ! + ! !USES: + use mkvarpar, only : re + use mkgridmapMod, only : gridmap_type + ! + ! !ARGUMENTS: + integer , intent(in) :: data_i(:) ! data on input grid + integer , intent(in) :: data_o(:) ! data on output grid + type(gridmap_type) , intent(in) :: gridmap ! mapping info + character(len=*) , intent(in) :: name ! name of field + integer , intent(in) :: minval ! minimum valid value + integer , intent(in) :: maxval ! minimum valid value + integer , intent(in) :: ndiag ! unit number for diagnostic output + integer , intent(in) :: mask_src(:) + real(r8) , intent(in) :: frac_dst(:) + ! + ! !LOCAL VARIABLES: + integer :: ns_i, ns_o ! sizes of input & output grids + integer :: ni, no, k ! indices + real(r8), allocatable :: garea_i(:) ! input grid: global area of each index + real(r8), allocatable :: garea_o(:) ! output grid: global area of each index + integer :: ier ! error status + + character(len=*), parameter :: subname = 'output_diagnostics_index' + !----------------------------------------------------------------------- + + ! Error check for array size consistencies + + ns_i = gridmap%na + ns_o = gridmap%nb + if (size(data_i) /= ns_i .or. & + size(data_o) /= ns_o) then + write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) + write(6,*) 'size(data_i) = ', size(data_i) + write(6,*) 'ns_i = ', ns_i + write(6,*) 'size(data_o) = ', size(data_o) + write(6,*) 'ns_o = ', ns_o + call abort() + end if + if (size(frac_dst) /= ns_o) then + write(6,*) subname//' ERROR: incorrect size of frac_dst' + write(6,*) 'size(frac_dst) = ', size(frac_dst) + write(6,*) 'ns_o = ', ns_o + call abort() + end if + if (size(mask_src) /= ns_i) then + write(6,*) subname//' ERROR: incorrect size of mask_src' + write(6,*) 'size(mask_src) = ', size(mask_src) + write(6,*) 'ns_i = ', ns_i + call abort() + end if + + ! Sum areas on input grid + + allocate(garea_i(minval:maxval), stat=ier) + if (ier/=0) call abort() + + garea_i(:) = 0. + do ni = 1, ns_i + k = data_i(ni) + if (k >= minval .and. k <= maxval) then + garea_i(k) = garea_i(k) + gridmap%area_src(ni) * mask_src(ni) * re**2 + end if + end do + + ! Sum areas on output grid + + allocate(garea_o(minval:maxval), stat=ier) + if (ier/=0) call abort() + + garea_o(:) = 0. + do no = 1, ns_o + k = data_o(no) + if (k >= minval .and. k <= maxval) then + garea_o(k) = garea_o(k) + gridmap%area_dst(no) * frac_dst(no) * re**2 + end if + end do + + ! Write results + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) trim(name), ' Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,2001) +2001 format (1x,'index input grid area output grid area',/ & + 1x,' 10**6 km**2 10**6 km**2') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + + do k = minval, maxval + write (ndiag,2002) k, garea_i(k)*1.e-06, garea_o(k)*1.e-06 +2002 format (1x,i9,f17.3,f18.3) + end do + + ! Deallocate memory + + deallocate(garea_i, garea_o) + + end subroutine output_diagnostics_index + +end module mkdiagnosticsMod diff --git a/tools/mksurfdata_esmf/src/mkesmfMod.F90 b/tools/mksurfdata_esmf/src/mkesmfMod.F90 new file mode 100644 index 0000000000..d11584f4e3 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkesmfMod.F90 @@ -0,0 +1,103 @@ +module mkesmfMod + + use ESMF + use pio , only : file_desc_t, iosystem_desc_t, io_desc_t, var_desc_t + use pio , only : pio_openfile, pio_closefile, pio_nowrite + use pio , only : pio_double, pio_real, pio_int, pio_offset_kind, pio_get_var + use pio , only : pio_read_darray, pio_setframe, pio_fill_double, pio_get_att + use pio , only : io_desc_t, var_desc_t + use pio , only : PIO_BCAST_ERROR, PIO_RETURN_ERROR, PIO_NOERR, PIO_INTERNAL_ERROR + use pio , only : PIO_REAL, PIO_INT, PIO_DOUBLE, PIO_SHORT + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkUtilsMod , only : chkerr + + implicit none + private + + public :: regrid_data + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + +!=============================================================== +contains +!=============================================================== + + subroutine regrid_data(field_i, field_o, varname, filename, data_i, data_o, rc) + + use mkvarctl , only : ndiag, root_task + use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_ioformat, io_subsystem + + ! input/output variables + type(ESMF_Field) , intent(inout) :: field_i ! raw data field + type(ESMF_Field) , intent(inout) :: field_o ! model field + character(len=*) , intent(in) :: varname ! field name in rawdata file + character(len=*) , intent(in) :: filename ! file name of rawdata file + real(r8) , intent(inout) :: data_i(:) ! input raw data + real(r8) , intent(inout) :: data_o(:) ! mapped data + integer , intent(out) :: rc + + ! local variables + type(ESMF_Mesh) :: mesh_i + type(ESMF_RouteHandle) :: routehandle + integer :: srcMaskValue = 0 + integer :: dstMaskValue = -987987 ! spval for RH mask values + integer :: srcTermProcessing_Value = 0 + type(file_desc_t) :: pioid + type(var_desc_t) :: pio_varid + type(io_desc_t) :: pio_iodesc + integer :: pio_vartype + real(r4), allocatable :: data_real(:) + real(r8), allocatable :: data_double(:) + real(r8), pointer :: dataptr(:) + integer :: lsize + integer :: rcode + logical :: checkflag = .false. + character(len=*), parameter :: subname = 'mklakwat' + !------------------------------------------------- + + rc = ESMF_SUCCESS + + ! create route handle to map field_model to field_data + call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_DSTAREA, & + srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Get data_i - Read in varname from filename + rcode = pio_openfile(io_subsystem, pioid, pio_iotype, trim(filename), pio_nowrite) + call ESMF_FieldGet(field_i, mesh=mesh_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (pio_vartype == PIO_REAL) then + allocate(data_real(lsize)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real, rcode) + data_i(:) = real(data_real(:), kind=r8) + deallocate(data_real) + else if (pio_vartype == PIO_DOUBLE) then + allocate(data_double(lsize)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double, rcode) + data_i(:) = data_double(:) + deallocate(data_double) + else + call shr_sys_abort(subName//"ERROR: only real and double types are supported") + end if + + ! Interpolate data_i to data_o + call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) + dataptr(:) = data_i(:) + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + dataptr(:) = 0._r8 + call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, & + termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + data_o(:) = dataptr(:) + + end subroutine regrid_data + +end module mkesmfMod diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 new file mode 100644 index 0000000000..77cf7e5400 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -0,0 +1,514 @@ +module mkfileMod + + implicit none + private + + public :: mkfile + +!================================================================================= +contains +!================================================================================= + +#ifdef TODO + subroutine mkfile(vm, nx, ny, fname, harvdata, dynlanduse, pioid) +#else + subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) +#endif + + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_getenv + use fileutils , only : get_filename + use mkvarpar , only : nlevsoi, numrad, numstdpft +#ifdef TODO + use mkurbanparMod, only : numurbl, nlevurb + use mkglcmecMod , only : nglcec + use mkpftMod , only : mkpftAtt + use mksoilMod , only : mksoilAtt + use mkharvestMod , only : mkharvest_fieldname, mkharvest_numtypes, mkharvest_longname + use mkharvestMod , only : mkharvest_units, harvestDataType +#endif + use mkpioMod ! TODO: add only + use mkvarctl + + implicit none + + ! input/output variables + type(ESMF_VM) , intent(inout) :: vm + integer , intent(in) :: nx + integer , intent(in) :: ny + character(len=*) , intent(in) :: fname + logical , intent(in) :: dynlanduse +#ifdef TODO + type(harvestDataType) , intent(in) :: harvdata +#endif + + ! local variables + type(file_desc_t) :: pioid + integer :: j ! index + integer :: dimid ! temporary + integer :: values(8) ! temporary + character(len=256) :: str ! global attribute string + character(len=256) :: name ! name of attribute + character(len=256) :: unit ! units of attribute + character(len= 18) :: datetime ! temporary + character(len= 8) :: date ! temporary + character(len= 10) :: time ! temporary + character(len= 5) :: zone ! temporary + integer :: ier ! error status + integer :: omode ! netCDF output mode + integer :: xtype ! external type + integer, allocatable :: ind1D(:) ! Indices of 1D harvest variables + integer, allocatable :: ind2D(:) ! Indices of 2D harvest variables + integer :: rcode + character(len=32) :: subname = 'mkfile' ! subroutine name + !----------------------------------------------------------------------- + + !--------------------------- + ! Create and open file + !--------------------------- + + ! TODO: how to translate the following into the pio call + !call check_ret(nf_create(trim(fname), ior(nf_clobber,nf_64bit_offset), ncid), subname) + call mkpio_wopen(pioid, trim(fname), vm, clobber=.true.) + ! TODO: what about setting no fill values? + + !--------------------------- + ! Define dimensions. + !--------------------------- + + if (outnc_1d) then + rcode = pio_def_dim(pioid, 'gridcell', nx, dimid) + else + rcode = pio_def_dim(pioid, 'lsmlon', nx, dimid) + rcode = pio_def_dim(pioid, 'lsmlat', ny, dimid) + end if + + if (.not. dynlanduse) then +#ifdef TODO + rcode = pio_def_dim(pioid, 'nglcec', nglcec, dimid) + rcode = pio_def_dim(pioid, 'nglcecp1', nglcec+1, dimid) +#endif + else +#ifdef TODO + rcode = pio_def_dim(pioid, 'numurbl', numurbl, dimid) + rcode = pio_def_dim(pioid, 'nlevurb', nlevurb, dimid) +#endif + rcode = pio_def_dim(pioid, 'numrad' , numrad, dimid) + rcode = pio_def_dim(pioid, 'nchar' , 256, dimid) + end if + + !--------------------------- + ! Set global attributes. + !--------------------------- + + str = 'NCAR-CSM' + rcode = pio_put_att(pioid, pio_global, "Conventions", trim(str)) + + call date_and_time (date, time, zone, values) + datetime(1:8) = date(5:6) // '-' // date(7:8) // '-' // date(3:4) + datetime(9:) = ' ' // time(1:2) // ':' // time(3:4) // ':' // time(5:6) // ' ' + str = 'created on: ' // datetime + rcode = pio_put_att (pioid, pio_global, 'History_Log', trim(str)) + + call shr_sys_getenv ('LOGNAME', str, ier) + rcode = pio_put_att (pioid, pio_global, 'Logname', trim(str)) + + call shr_sys_getenv ('HOST', str, ier) + rcode = pio_put_att (pioid, pio_global, 'Host', trim(str)) + + str = 'Community Land Model: CLM5' + rcode = pio_put_att (pioid, pio_global, 'Source', trim(str)) + !rcode = pio_put_att (pioid, pio_global, 'Version', trim(gitdescribe), trim(gitdescribe)) +#ifdef OPT + str = 'TRUE' +#else + str = 'FALSE' +#endif + rcode = pio_put_att (pioid, pio_global, 'Compiler_Optimized', trim(str)) + + if ( all_urban )then + str = 'TRUE' + rcode = pio_put_att(pioid, pio_global, 'all_urban', trim(str)) + end if + if ( no_inlandwet )then + str = 'TRUE' + rcode = pio_put_att(pioid, pio_global, 'no_inlandwet', trim(str)) + end if + !rcode = pio_put_att_int(pioid, pio_global, 'nglcec', nglcec) + + ! Raw data file names + str = get_filename(mksrf_fgrid_mesh) + rcode = pio_put_att(pioid, pio_global, 'Input_grid_dataset', trim(str)) + str = trim(mksrf_gridtype) + rcode = pio_put_att(pioid, pio_global, 'Input_gridtype', trim(str)) + + if (.not. dynlanduse) then + str = get_filename(mksrf_fvocef) + rcode = pio_put_att(pioid, pio_global, 'VOC_EF_raw_data_file_name', trim(str)) + end if + str = get_filename(mksrf_flakwat) + rcode = pio_put_att(pioid, pio_global, 'Inland_lake_raw_data_file_name', trim(str)) + str = get_filename(mksrf_fwetlnd) + rcode = pio_put_att(pioid, pio_global, 'Inland_wetland_raw_data_file_name', trim(str)) + str = get_filename(mksrf_fglacier) + rcode = pio_put_att(pioid, pio_global, 'Glacier_raw_data_file_name', trim(str)) + str = get_filename(mksrf_fglacierregion) + rcode = pio_put_att(pioid, pio_global, 'Glacier_region_raw_data_file_name', trim(str)) + str = get_filename(mksrf_furbtopo) + rcode = pio_put_att(pioid, pio_global, 'Urban_Topography_raw_data_file_name', trim(str)) + str = get_filename(mksrf_furban) + rcode = pio_put_att(pioid, pio_global, 'Urban_raw_data_file_name', trim(str)) + if (.not. dynlanduse .and. (numpft == numstdpft) ) then + str = get_filename(mksrf_flai) + rcode = pio_put_att(pioid, pio_global, 'Lai_raw_data_file_name', trim(str)) + end if + str = get_filename(mksrf_fabm) + rcode = pio_put_att(pioid, pio_global, 'agfirepkmon_raw_data_file_name', trim(str)) + str = get_filename(mksrf_fgdp) + rcode = pio_put_att(pioid, pio_global, 'gdp_raw_data_file_name', trim(str)) + str = get_filename(mksrf_fpeat) + rcode = pio_put_att(pioid, pio_global, 'peatland_raw_data_file_name', trim(str)) + str = get_filename(mksrf_fsoildepth) + rcode = pio_put_att(pioid, pio_global, 'soildepth_raw_data_file_name', trim(str)) + str = get_filename(mksrf_ftopostats) + rcode = pio_put_att(pioid, pio_global, 'topography_stats_raw_data_file_name', trim(str)) + if ( outnc_vic )then + str = get_filename(mksrf_fvic) + rcode = pio_put_att(pioid, pio_global, 'vic_raw_data_file_name', trim(str)) + end if + + ! Mesh file names + str = get_filename(mksrf_fvegtyp_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_pft_file_name', trim(str)) + str = get_filename(mksrf_flakwat_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_lakwat_file', trim(str)) + str = get_filename(mksrf_fwetlnd_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_wetlnd_file', trim(str)) + str = get_filename(mksrf_fglacier_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_glacier_file', trim(str)) + str = get_filename(mksrf_fglacierregion_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_glacier_region_file', trim(str)) + str = get_filename(mksrf_fsoitex_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_soil_texture_file', trim(str)) + str = get_filename(mksrf_fsoicol_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_soil_color_file', trim(str)) + str = get_filename(mksrf_forganic_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_soil_organic_file', trim(str)) + str = get_filename(mksrf_furban_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_urban_file', trim(str)) + str = get_filename(mksrf_fmax_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_fmax_file', trim(str)) + str = get_filename(mksrf_fvocef_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_VOC_EF_file', trim(str)) + str = get_filename(mksrf_fhrvtyp_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_harvest_file', trim(str)) + if ( numpft == numstdpft )then + str = get_filename(mksrf_flai_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_lai_sai_file', trim(str)) + end if + str = get_filename(mksrf_furbtopo_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_urban_topography_file', trim(str)) + str = get_filename(mksrf_fabm_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_agfirepkmon_file', trim(str)) + str = get_filename(mksrf_fgdp_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_gdp_file', trim(str)) + str = get_filename(mksrf_fpeat_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_peatland_file', trim(str)) + str = get_filename(mksrf_fsoildepth_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_soildepth_file', trim(str)) + str = get_filename(mksrf_ftopostats_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_topography_stats_file', trim(str)) + if ( outnc_vic )then + str = get_filename(mksrf_fvic_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_vic_file', trim(str)) + end if + + ! ---------------------------------------------------------------------- + ! Define variables + ! ---------------------------------------------------------------------- + + if ( .not. outnc_double ) then + xtype = PIO_REAL + else + xtype = PIO_DOUBLE + end if + + !call mksoilAtt( pioid, dynlanduse, xtype ) + + !call mkpftAtt( pioid, dynlanduse, xtype ) + + call mkpio_def_spatial_var(pioid, varname='AREA' , xtype=PIO_DOUBLE, & + long_name='area', units='km^2') + + call mkpio_def_spatial_var(pioid, varname='LONGXY', xtype=PIO_DOUBLE, & + long_name='longitude', units='degrees east') + + call mkpio_def_spatial_var(pioid, varname='LATIXY', xtype=PIO_double, & + long_name='latitude', units='degrees north') + + if (.not. dynlanduse) then + call mkpio_def_spatial_var(pioid, varname='EF1_BTR', xtype=xtype, & + long_name='EF btr (isoprene)', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='EF1_FET', xtype=xtype, & + long_name='EF fet (isoprene)', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='EF1_FDT', xtype=xtype, & + long_name='EF fdt (isoprene)', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='EF1_SHR', xtype=xtype, & + long_name='EF shr (isoprene)', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='EF1_GRS', xtype=xtype, & + long_name='EF grs (isoprene)', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='EF1_CRP', xtype=xtype, & + long_name='EF crp (isoprene)', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='CANYON_HWR', xtype=xtype, & + lev1name='numurbl', & + long_name='canyon height to width ratio', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='EM_IMPROAD', xtype=xtype, & + lev1name='numurbl', & + long_name='emissivity of impervious road', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='EM_PERROAD', xtype=xtype, & + lev1name='numurbl', & + long_name='emissivity of pervious road', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='EM_ROOF', xtype=xtype, & + lev1name='numurbl', & + long_name='emissivity of roof', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='EM_WALL', xtype=xtype, & + lev1name='numurbl', & + long_name='emissivity of wall', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='HT_ROOF', xtype=xtype, & + lev1name='numurbl', & + long_name='height of roof', units='meters') + + call mkpio_def_spatial_var(pioid, varname='THICK_ROOF', xtype=xtype, & + lev1name='numurbl', & + long_name='thickness of roof', units='meters') + + call mkpio_def_spatial_var(pioid, varname='THICK_WALL', xtype=xtype, & + lev1name='numurbl', & + long_name='thickness of wall', units='meters') + + call mkpio_def_spatial_var(pioid, varname='T_BUILDING_MIN', xtype=xtype, & + lev1name='numurbl', & + long_name='minimum interior building temperature', units='K') + + call mkpio_def_spatial_var(pioid, varname='WIND_HGT_CANYON', xtype=xtype, & + lev1name='numurbl', & + long_name='height of wind in canyon', units='meters') + + call mkpio_def_spatial_var(pioid, varname='WTLUNIT_ROOF', xtype=xtype, & + lev1name='numurbl', & + long_name='fraction of roof', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='WTROAD_PERV', xtype=xtype, & + lev1name='numurbl', & + long_name='fraction of pervious road', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='ALB_IMPROAD_DIR', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='direct albedo of impervious road', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='ALB_IMPROAD_DIF', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='diffuse albedo of impervious road', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='ALB_PERROAD_DIR', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='direct albedo of pervious road', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='ALB_PERROAD_DIF', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='diffuse albedo of pervious road', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='ALB_ROOF_DIR', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='direct albedo of roof', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='ALB_ROOF_DIF', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='diffuse albedo of roof', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='ALB_WALL_DIR', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='direct albedo of wall', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='ALB_WALL_DIF', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='diffuse albedo of wall', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='TK_ROOF', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='thermal conductivity of roof', units='W/m*K') + + call mkpio_def_spatial_var(pioid, varname='TK_WALL', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='thermal conductivity of wall', units='W/m*K') + + call mkpio_def_spatial_var(pioid, varname='TK_IMPROAD', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='thermal conductivity of impervious road', units='W/m*K') + + call mkpio_def_spatial_var(pioid, varname='CV_ROOF', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='volumetric heat capacity of roof', units='J/m^3*K') + + call mkpio_def_spatial_var(pioid, varname='CV_WALL', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='volumetric heat capacity of wall', units='J/m^3*K') + + call mkpio_def_spatial_var(pioid, varname='CV_IMPROAD', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='volumetric heat capacity of impervious road', units='J/m^3*K') + + call mkpio_def_spatial_var(pioid, varname='NLEV_IMPROAD', xtype=PIO_INT, & + lev1name='numurbl', & + long_name='number of impervious road layers', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='peatf', xtype=xtype, & + long_name='peatland fraction', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='zbedrock', xtype=xtype, & + long_name='soil depth', units='m') + + call mkpio_def_spatial_var(pioid, varname='abm', xtype=PIO_INT, & + long_name='agricultural fire peak month', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='gdp', xtype=xtype, & + long_name='gdp', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='SLOPE', xtype=xtype, & + long_name='mean topographic slope', units='degrees') + + call mkpio_def_spatial_var(pioid, varname='STD_ELEV', xtype=xtype, & + long_name='standard deviation of elevation', units='m') + + if ( outnc_vic )then + call mkpio_def_spatial_var(pioid, varname='binfl', xtype=xtype, & + long_name='VIC b parameter for the Variable Infiltration Capacity Curve', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='Ws', xtype=xtype, & + long_name='VIC Ws parameter for the ARNO curve', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='Dsmax', xtype=xtype, & + long_name='VIC Dsmax parameter for the ARNO curve', units='mm/day') + + call mkpio_def_spatial_var(pioid, varname='Ds', xtype=xtype, & + long_name='VIC Ds parameter for the ARNO curve', units='unitless') + + end if + call mkpio_def_spatial_var(pioid, varname='LAKEDEPTH', xtype=xtype, & + long_name='lake depth', units='m') + + call mkpio_def_spatial_var(pioid, varname='PCT_WETLAND', xtype=xtype, & + long_name='percent wetland', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='PCT_LAKE', xtype=xtype, & + long_name='percent lake', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='PCT_GLACIER', xtype=xtype, & + long_name='percent glacier', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='GLACIER_REGION', xtype=PIO_INT, & + long_name='glacier region ID', units='unitless') + + call mkpio_defvar(pioid, varname='GLC_MEC', xtype=xtype, & + dim1name='nglcecp1', long_name='Glacier elevation class', units='m') + + call mkpio_def_spatial_var(pioid, varname='PCT_GLC_MEC', xtype=xtype, & + lev1name='nglcec', & + long_name='percent glacier for each glacier elevation class (% of landunit)', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='TOPO_GLC_MEC', xtype=xtype, & + lev1name='nglcec', & + long_name='mean elevation on glacier elevation classes', units='m') + + if ( outnc_3dglc ) then + call mkpio_def_spatial_var(pioid, varname='PCT_GLC_MEC_GIC', xtype=xtype, & + lev1name='nglcec', & + long_name='percent smaller glaciers and ice caps for each glacier elevation class (% of landunit)', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='PCT_GLC_MEC_ICESHEET', xtype=xtype, & + lev1name='nglcec', & + long_name='percent ice sheet for each glacier elevation class (% of landunit)', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='PCT_GLC_GIC', xtype=xtype, & + long_name='percent ice caps/glaciers (% of landunit)', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='PCT_GLC_ICESHEET', xtype=xtype, & + long_name='percent ice sheet (% of landunit)', units='unitless') + + end if + + if ( outnc_3dglc ) then + call mkpio_def_spatial_var(pioid, varname='PCT_GLC_MEC_GIC', xtype=xtype, & + lev1name='nglcec', & + long_name='percent smaller glaciers and ice caps for each glacier elevation class (% of landunit)', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='PCT_GLC_MEC_ICESHEET', xtype=xtype, & + lev1name='nglcec', & + long_name='percent ice sheet for each glacier elevation class (% of landunit)', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='PCT_GLC_GIC', xtype=xtype, & + long_name='percent ice caps/glaciers (% of landunit)', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='PCT_GLC_ICESHEET', xtype=xtype, & + long_name='percent ice sheet (% of landunit)', units='unitless') + + end if + + call mkpio_def_spatial_var(pioid, varname='PCT_URBAN', xtype=xtype, & + lev1name='numurbl', & + long_name='percent urban for each density type', units='unitless') + + call mkpio_def_spatial_var(pioid, varname='URBAN_REGION_ID', xtype=PIO_INT, & + long_name='urban region ID', units='unitless') + + ! call harvdata%getFieldsIdx( ind1D, ind2D ) + ! do j = 1, harvdata%num1Dfields() + ! call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind1D(j),constant=.true.), xtype=xtype, & + ! long_name=mkharvest_longname(ind1D(j)), units=mkharvest_units(ind1D(j)) ) + ! end do + ! do j = 1, harvdata%num2Dfields() + ! call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind2D(j),constant=.true.), xtype=xtype, & + ! lev1name=harvdata%getFieldsDim(ind2D(j)), & + ! long_name=mkharvest_longname(ind2D(j)), units=mkharvest_units(ind2D(j)) ) + ! end do + ! deallocate(ind1D, ind2D) + + else + + ! call harvdata%getFieldsIdx( ind1D, ind2D ) + ! do j = 1, harvdata%num1Dfields() + ! call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind1D(j),constant=.false.), xtype=xtype, & + ! lev1name='time', & + ! long_name=mkharvest_longname(ind1D(j)), units=mkharvest_units(ind1D(j)) ) + ! end do + ! do j = 1, harvdata%num2Dfields() + ! call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind2D(j),constant=.false.), xtype=xtype, & + ! lev1name=harvdata%getFieldsDim(ind2D(j)), lev2name="time", & + ! long_name=mkharvest_longname(ind2D(j)), units=mkharvest_units(ind2D(j)) ) + ! end do + ! deallocate(ind1D, ind2D) + + end if ! .not. dynlanduse + + ! End of define mode + + call mkpio_enddef(pioid) + + call pio_closefile(pioid) + + end subroutine mkfile + +end module mkfileMod diff --git a/tools/mksurfdata_esmf/src/mkgdpMod.F90 b/tools/mksurfdata_esmf/src/mkgdpMod.F90 new file mode 100644 index 0000000000..138ddf1805 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkgdpMod.F90 @@ -0,0 +1,147 @@ +module mkgdpMod + +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mkgdpMod +! +! !DESCRIPTION: +! make GDP from input GDP data +! +! !REVISION HISTORY: +! Author: Sam Levis and Bill Sacks +! +!----------------------------------------------------------------------- +! +! !USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush + use mkdomainMod , only : domain_checksame + + implicit none + + private + +! !PUBLIC MEMBER FUNCTIONS: + public mkgdp ! regrid gdp data +! +!EOP +!=============================================================== +contains +!=============================================================== + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkgdp +! +! !INTERFACE: +subroutine mkgdp(ldomain, mapfname, datfname, ndiag, gdp_o) +! +! !DESCRIPTION: +! make GDP from input GDP data +! +! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkncdio + use mkdiagnosticsMod, only : output_diagnostics_continuous + use mkchecksMod, only : min_bad +! +! !ARGUMENTS: + + implicit none + type(domain_type) , intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: gdp_o(:) ! output grid: GDP (x1000 1995 US$ per capita) +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Sam Levis and Bill Sacks +! +! +! !LOCAL VARIABLES: +!EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: data_i(:) ! data on input grid + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + integer :: ncid,varid ! input netCDF id's + integer :: ier ! error status + + real(r8), parameter :: min_valid = 0._r8 ! minimum valid value + + character(len=32) :: subname = 'mkgdp' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make GDP.....' + call shr_sys_flush(6) + + ! ----------------------------------------------------------------- + ! Read domain and mapping information, check for consistency + ! ----------------------------------------------------------------- + + call domain_read(tdomain,datfname) + + call gridmap_mapread(tgridmap, mapfname ) + + ! Obtain frac_dst + allocate(frac_dst(ldomain%ns), stat=ier) + if (ier/=0) call abort() + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + allocate(mask_r8(tdomain%ns), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! ----------------------------------------------------------------- + ! Open input file, allocate memory for input data + ! ----------------------------------------------------------------- + + write(6,*)'Open GDP file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + + allocate(data_i(tdomain%ns), stat=ier) + if (ier/=0) call abort() + + ! ----------------------------------------------------------------- + ! Regrid gdp + ! ----------------------------------------------------------------- + + call check_ret(nf_inq_varid (ncid, 'gdp', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + call gridmap_areaave_srcmask(tgridmap, data_i, gdp_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check validity of output data + if (min_bad(gdp_o, min_valid, 'gdp')) then + call abort() + end if + + call output_diagnostics_continuous(data_i, gdp_o, tgridmap, "GDP", "x1000 US$ per capita", ndiag, tdomain%mask, frac_dst) + + ! ----------------------------------------------------------------- + ! Close files and deallocate dynamic memory + ! ----------------------------------------------------------------- + + call check_ret(nf_close(ncid), subname) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (data_i) + deallocate (frac_dst) + deallocate (mask_r8) + + write (6,*) 'Successfully made GDP' + write (6,*) + call shr_sys_flush(6) + +end subroutine mkgdp + +end module mkgdpMod diff --git a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 new file mode 100644 index 0000000000..e644129ed3 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 @@ -0,0 +1,139 @@ +module mkglacierregionMod + + !----------------------------------------------------------------------- + !BOP + ! + ! !MODULE: mkglacierregionMod + ! + ! !DESCRIPTION: + ! make glacier region ID + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! + !----------------------------------------------------------------------- + ! + ! !USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush + implicit none + + private + + ! !PUBLIC MEMBER FUNCTIONS: + public mkglacierregion ! make glacier region ID + ! + !EOP + +contains + + !----------------------------------------------------------------------- + subroutine mkglacierregion(ldomain, mapfname, datfname, ndiag, & + glacier_region_o) + ! + ! !DESCRIPTION: + ! Make glacier region ID + ! + ! Regridding is done by finding the max index that overlaps each destination cell, + ! without regard to the weight of overlap or dominance of each overlapping index. + ! + ! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read, domain_checksame + use mkgridmapMod + use mkncdio + use mkindexmapMod, only : get_max_indices + use mkdiagnosticsMod, only : output_diagnostics_index + use mkchecksMod, only : min_bad + ! + ! !ARGUMENTS: + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + integer , intent(out) :: glacier_region_o(:) ! glacier region + ! + ! !LOCAL VARIABLES: + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + integer, allocatable :: glacier_region_i(:) ! glacier region on input grid + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + integer :: ncid,varid ! input netCDF id's + integer :: ier ! error status + integer :: max_region ! max region ID + + character(len=*), parameter :: subname = 'mkglacierregion' + !----------------------------------------------------------------------- + + write (6,*) 'Attempting to make glacier region .....' + call shr_sys_flush(6) + + ! ------------------------------------------------------------------------ + ! Read domain and mapping information, check for consistency + ! ------------------------------------------------------------------------ + + call domain_read(tdomain, datfname) + + call gridmap_mapread(tgridmap, mapfname) + + ! Obtain frac_dst + allocate(frac_dst(ldomain%ns), stat=ier) + if (ier/=0) call abort() + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + allocate(mask_r8(tdomain%ns), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check(tgridmap, mask_r8, frac_dst, subname) + + call domain_checksame(tdomain, ldomain, tgridmap) + + ! ------------------------------------------------------------------------ + ! Open input file, allocate memory for input data + ! ------------------------------------------------------------------------ + + write (6,*) 'Open glacier region raw data file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + + allocate(glacier_region_i(tdomain%ns), stat=ier) + if (ier/=0) call abort() + + ! ------------------------------------------------------------------------ + ! Regrid glacier_region + ! ------------------------------------------------------------------------ + + call check_ret(nf_inq_varid(ncid, 'GLACIER_REGION', varid), subname) + call check_ret(nf_get_var_int(ncid, varid, glacier_region_i), subname) + if (min_bad(glacier_region_i, 0, 'GLACIER_REGION')) then + call abort() + end if + + call get_max_indices( & + gridmap = tgridmap, & + src_array = glacier_region_i, & + dst_array = glacier_region_o, & + nodata = 0, & + mask_src = tdomain%mask) + + max_region = maxval(glacier_region_i) + call output_diagnostics_index(glacier_region_i, glacier_region_o, tgridmap, & + 'Glacier Region ID', 0, max_region, ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! ------------------------------------------------------------------------ + ! Deallocate dynamic memory & other clean up + ! ------------------------------------------------------------------------ + + call check_ret(nf_close(ncid), subname) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate(glacier_region_i) + deallocate(frac_dst) + deallocate(mask_r8) + + write (6,*) 'Successfully made glacier region' + write (6,*) + call shr_sys_flush(6) + + end subroutine mkglacierregion + +end module mkglacierregionMod diff --git a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 new file mode 100644 index 0000000000..9fbad66689 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 @@ -0,0 +1,794 @@ +module mkglcmecMod +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mkglcmecMod +! +! !DESCRIPTION: +! Make glacier multi-elevation class data +! +! !REVISION HISTORY: +! Author: Erik Kluzek, Mariana Vertenstein +! +!----------------------------------------------------------------------- +!!USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush + use mkdomainMod , only : domain_checksame + implicit none + + private ! By default make data private +! +! !PUBLIC MEMBER FUNCTIONS: +! + public mkglcmecInit ! Initialization + public mkglcmec ! Set glacier multi-elevation class + public mkglacier ! Set percent glacier +! +! !PUBLIC DATA MEMBERS: +! + integer, public :: nglcec = 10 ! number of elevation classes for glaciers + real(r8), pointer :: elevclass(:) ! elevation classes +! +! !PRIVATE MEMBER FUNCTIONS: + private get_elevclass ! get elevation class index + private mean_elevation_vc ! get the elevation of a virtual column +!EOP +!=============================================================== +contains +!=============================================================== + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkglcmecInit +! +! !INTERFACE: +subroutine mkglcmecInit( elevclass_o ) +! +! !DESCRIPTION: +! Initialize of Make glacier multi-elevation class data +! !USES: +! +! !ARGUMENTS: + implicit none + real(r8), intent(OUT) :: elevclass_o(:) ! elevation classes +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: +!EOP + character(len=32) :: subname = 'mkglcmecInit:: ' +!----------------------------------------------------------------------- + allocate( elevclass(nglcec+1) ) + + ! ----------------------------------------------------------------- + ! Define elevation classes, represents lower boundary of each class + ! ----------------------------------------------------------------- + + if ( nglcec == 36 )then + elevclass(:) = (/ 0., 200., 400., 600., 800., & + 1000., 1200., 1400., 1600., 1800., & + 2000., 2200., 2400., 2600., 2800., & + 3000., 3200., 3400., 3600., 3800., & + 4000., 4200., 4400., 4600., 4800., & + 5000., 5200., 5400., 5600., 5800., & + 6000., 6200., 6400., 6600., 6800., & + 7000., 10000./) + else if ( nglcec == 10 )then + elevclass(1) = 0. + elevclass(2) = 200. + elevclass(3) = 400. + elevclass(4) = 700. + elevclass(5) = 1000. + elevclass(6) = 1300. + elevclass(7) = 1600. + elevclass(8) = 2000. + elevclass(9) = 2500. + elevclass(10) = 3000. + elevclass(11) = 10000. + else if ( nglcec == 5 )then + elevclass(1) = 0. + elevclass(2) = 500. + elevclass(3) = 1000. + elevclass(4) = 1500. + elevclass(5) = 2000. + elevclass(6) = 10000. + else if ( nglcec == 3 )then + elevclass(1) = 0. + elevclass(2) = 1000. + elevclass(3) = 2000. + elevclass(4) = 10000. + else if ( nglcec == 1 )then + elevclass(1) = 0. + elevclass(2) = 10000. + else + write(6,*) subname//"ERROR:: nglcec must be 1, 3, 5, 10 or 36",& + " to work with CLM: " + call abort() + end if + + elevclass_o(:) = elevclass(:) + +end subroutine mkglcmecInit + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkglcmec +! +! !INTERFACE: +subroutine mkglcmec(ldomain, mapfname, & + datfname_fglacier, ndiag, & + pctglcmec_o, topoglcmec_o, & + pctglcmec_gic_o, pctglcmec_icesheet_o, & + pctglc_gic_o, pctglc_icesheet_o) +! +! !DESCRIPTION: +! make percent glacier on multiple elevation classes, mean elevation for each +! elevation class, and associated fields +! +! Note that the raw glacier data are specified by level, and thus implicitly include the +! necessary topo data for breaking pct glacier into elevation classes. Each level in the +! input data is assigned to an elevation (given by BIN_CENTERS in the input data). Thus, +! all of the input glacier in level 1 is treated as being at the same elevation, and +! likewise for each other level. These elevations are then used in assigning pct_glacier +! to the appropriate elevation class in the output data, as well as determining the mean +! topographic height of each elevation class in the output data. +! +! Note that the various percentages computed here are given as % of the glc_mec landunit. +! If the input glacier area is 0 for a given grid cell, this requires setting these % +! variables in an arbitrary way. +! +! !USES: + use shr_sys_mod, only : shr_sys_abort + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkutilsMod, only : slightly_below, slightly_above + use mkncdio + use mkvarctl , only : outnc_3dglc +! +! !ARGUMENTS: + implicit none + type(domain_type) , intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname_fglacier ! raw glacier data + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: pctglcmec_o (:,:) ! % for each elevation class on output glacier grid (% of landunit) + real(r8) , intent(out):: topoglcmec_o(:,:) ! mean elevation for each elevation classs on output glacier grid + real(r8), optional, intent(out):: pctglcmec_gic_o(:,:) ! % glc gic on output grid, by elevation class (% of landunit) + real(r8), optional, intent(out):: pctglcmec_icesheet_o(:,:) ! % glc ice sheet on output grid, by elevation class (% of landunit) + real(r8), optional, intent(out):: pctglc_gic_o(:) ! % glc gic on output grid, summed across elevation classes (% of landunit) + real(r8), optional, intent(out):: pctglc_icesheet_o(:) ! % glc ice sheet on output grid, summed across elevation classes (% of landunit) +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: David Lawrence +! 7/12/11: Bill Sacks: substantial rewrite to use input topo and % glacier at same resolution +! 9/25/12: Bill Sacks: substantial rewrite to use new format of fglacier, which provides +! percent by elevation bin (thus the separate topo dataset is no longer needed +! in this routine) +! +! +! !LOCAL VARIABLES: +!EOP + type(domain_type) :: tdomain ! local domain + type(gridmap_type) :: tgridmap ! local gridmap + real(r8), allocatable :: pctglc_gic_i(:) ! input GIC percentage for a single level + real(r8), allocatable :: pctglc_icesheet_i(:) ! input icesheet percentage for a single level + real(r8), allocatable :: topoglcmec_unnorm_o(:,:) ! same as topoglcmec_o, but unnormalized + real(r8), allocatable :: pctglc_tot_o(:) ! total glacier cover for the grid cell + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8) :: topoice_i ! topographic height of this level + real(r8) :: pctglc_i ! input total pct glacier for a single level & single point + real(r8) :: wt, frac ! weighting factors for remapping + integer :: ndims ! number of dimensions in input variables + integer :: dim_lengths(nf_max_var_dims) ! lengths of dimensions in input variables + integer, allocatable :: starts(:), counts(:) ! start indices & counts for reading variable slices + integer :: ni,no,ns_o,nst,lev ! indices + integer :: n,m ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: nlev ! number of levels in input file + real(r8) :: glc_sum ! temporary + integer :: ier ! error status + logical :: errors ! error status + + real(r8), parameter :: eps = 2.e-5_r8 ! epsilon for error checks (note that we use a large-ish value + ! because data are stored as single-precision floats in the + ! raw dataset) + real(r8), parameter :: eps_small = 1.e-12_r8 ! epsilon for error checks that expect close match + character(len=32) :: subname = 'mkglcmec' +!----------------------------------------------------------------------- + + ! Initialize all output fields to zero + + pctglcmec_o(:,:) = 0. + topoglcmec_o(:,:) = 0. + if ( outnc_3dglc )then + if ( (.not. present(pctglcmec_gic_o)) .or. (.not. present(pctglcmec_icesheet_o)) .or. & + (.not. present(pctglc_gic_o) ) .or. (.not. present(pctglc_icesheet_o) ) )then + call shr_sys_abort( subname//' ERROR: 3D glacier fields were NOT sent in and they are required' ) + end if + pctglcmec_gic_o(:,:) = 0. + pctglcmec_icesheet_o(:,:) = 0. + pctglc_gic_o(:) = 0. + pctglc_icesheet_o(:) = 0. + end if + + ! Set number of output points + + ns_o = ldomain%ns + + write (6,*) 'Attempting to make percent elevation class ',& + 'and mean elevation for glaciers .....' + call shr_sys_flush(6) + + ! ----------------------------------------------------------------- + ! Read domain and dimension information from glacier raw data file + ! ----------------------------------------------------------------- + + call domain_read(tdomain,datfname_fglacier) + nst = tdomain%ns + + ! Read z dimension size + write (6,*) 'Open glacier file: ', trim(datfname_fglacier) + call check_ret(nf_open(datfname_fglacier, 0, ncid), subname) + ier = nf_inq_dimid (ncid, 'z', dimid) + if (ier /= NF_NOERR) then + write (6,*) trim(subname), ' ERROR: z dimension not found on glacier file:' + write (6,*) trim(datfname_fglacier) + write (6,*) 'Perhaps you are trying to use an old-format glacier file?' + write (6,*) '(prior to Sept., 2012)' + call abort() + end if + call check_ret(nf_inq_dimlen (ncid, dimid, nlev), subname) + + ! ----------------------------------------------------------------- + ! Read mapping data, check for consistency with domains + ! ----------------------------------------------------------------- + + ! Mapping for raw glacier -> model output grid + call gridmap_mapread(tgridmap, mapfname ) + + ! Error checks for domain and map consistencies + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! ----------------------------------------------------------------- + ! Determine dimension lengths and create start & count arrays + ! for later reading one level at a time + ! ----------------------------------------------------------------- + + call get_dim_lengths(ncid, 'PCT_GLC_GIC', ndims, dim_lengths) + + allocate(starts(ndims), counts(ndims), stat=ier) + if (ier/=0) call abort() + + starts(1:ndims) = 1 + + ! We assume that the last dimension is the level dimension + counts(1:ndims-1) = dim_lengths(1:ndims-1) + counts(ndims) = 1 + + ! -------------------------------------------------------------------- + ! Compute fields on the output grid + ! -------------------------------------------------------------------- + + allocate(pctglc_gic_i(nst), pctglc_icesheet_i(nst), stat=ier) + if (ier/=0) call abort() + + allocate(topoglcmec_unnorm_o(ns_o,nglcec), stat=ier) + if (ier/=0) call abort() + + allocate(frac_dst(ns_o), stat=ier) + if (ier/=0) call abort() + + topoglcmec_unnorm_o(:,:) = 0. + + write(6,'(a,i4,a)',advance='no') 'Level (out of ', nlev, '): ' + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + do lev = 1, nlev + write(6,'(i4)',advance='no') lev + flush(6) + + ! Read this level's data + ! We assume that the last dimension is the level dimension + starts(ndims) = lev + call check_ret(nf_inq_varid (ncid, 'BIN_CENTERS', varid), subname) + call check_ret(nf_get_vara_double (ncid, varid, (/lev/), (/1/), topoice_i), subname) + call check_ret(nf_inq_varid (ncid, 'PCT_GLC_GIC', varid), subname) + call check_ret(nf_get_vara_double (ncid, varid, starts, counts, pctglc_gic_i), subname) + call check_ret(nf_inq_varid (ncid, 'PCT_GLC_ICESHEET', varid), subname) + call check_ret(nf_get_vara_double (ncid, varid, starts, counts, pctglc_icesheet_i), subname) + + ! Determine elevation class + m = get_elevclass(topoice_i) + if (m < 1 .or. m > nglcec) then + call abort() + end if + + do n = 1,tgridmap%ns + ni = tgridmap%src_indx(n) + no = tgridmap%dst_indx(n) + wt = tgridmap%wovr(n) * tdomain%mask(ni) + + ! fraction of this destination cell that is covered by source cells that are within the source landmask + frac = frac_dst(no) + + ! If frac == 0, then we can't do this, to avoid divide by 0. In this case, the + ! outputs remain equal to 0 (their initialized value). + if (frac > 0) then + pctglc_i = pctglc_gic_i(ni) + pctglc_icesheet_i(ni) + pctglcmec_o(no,m) = pctglcmec_o(no,m) + wt*pctglc_i / frac + if ( outnc_3dglc )then + pctglcmec_gic_o(no,m) = pctglcmec_gic_o(no,m) + wt*pctglc_gic_i(ni) / frac + pctglcmec_icesheet_o(no,m) = pctglcmec_icesheet_o(no,m) + wt*pctglc_icesheet_i(ni) / frac + end if + + ! note that, by weighting the following by pctglc_i, we are getting something + ! like the average topographic height over glaciated areas - NOT the average + ! topographic height of the entire grid cell + topoglcmec_unnorm_o(no,m) = topoglcmec_unnorm_o(no,m) + wt*pctglc_i*topoice_i / frac + end if + end do + end do + + ! Note: at this point, the various percentages are given as % of grid cell; below, we + ! renormalize these to be given as % of landunit. + + ! advance to next line (needed because of 'advance=no' writes above) + write(6,*) ' ' + + ! Close glacier input file + call check_ret(nf_close(ncid), subname) + + ! Normalize topoglcmec_o. To do this, note that pctglcmec_o(n,m) is equal to the sum of + ! the weights used in doing the weighted average of topoice_i (weight = + ! wt*pctglc_i/frac); hence pctglcmec_o(n,m) is the correct normalization factor + do no = 1,ns_o + do m = 1,nglcec + if (pctglcmec_o(no,m) > 0) then + topoglcmec_o(no,m) = topoglcmec_unnorm_o(no,m) / pctglcmec_o(no,m) + else + topoglcmec_o(no,m) = mean_elevation_vc(m) + end if + + ! Correct for rounding errors that put topoglcmec_o(no,m) slightly outside the + ! allowed bounds for this elevation class + if (slightly_below(topoglcmec_o(no,m), elevclass(m))) then + write(6,*) 'Warning: topoglcmec_o was slightly lower than lower bound; setting equal& + & to lower bound; for: ', no, m, topoglcmec_o(no,m), elevclass(m) + write(6,*) '(this is informational only, and probably just indicates rounding error)' + topoglcmec_o(no,m) = elevclass(m) + else if (slightly_above(topoglcmec_o(no,m), elevclass(m+1))) then + write(6,*) 'Warning: topoglcmec_o was slightly higher than upper bound; setting equal& + & to upper bound; for: ', no, m, topoglcmec_o(no,m), elevclass(m+1) + write(6,*) '(this is informational only, and probably just indicates rounding error)' + topoglcmec_o(no,m) = elevclass(m+1) + end if + end do + end do + + ! Renormalize percentages to be given as % of landunit rather than % of grid cell. + + allocate(pctglc_tot_o(ns_o), stat=ier) + if (ier/=0) call abort() + + do no = 1,ns_o + pctglc_tot_o(no) = sum(pctglcmec_o(no,:)) + + if (pctglc_tot_o(no) > 0._r8) then + pctglcmec_o(no,:) = pctglcmec_o(no,:) / pctglc_tot_o(no) * 100._r8 + if ( outnc_3dglc )then + pctglcmec_gic_o(no,:) = pctglcmec_gic_o(no,:) / pctglc_tot_o(no) * 100._r8 + pctglcmec_icesheet_o(no,:) = pctglcmec_icesheet_o(no,:) / pctglc_tot_o(no) * 100._r8 + end if + + else + ! Division of landunit is ambiguous. Apply the rule that all area is assigned to + ! the lowest elevation class, and all GIC. + pctglcmec_o(no,1) = 100._r8 + if ( outnc_3dglc )then + pctglcmec_gic_o(no,1) = 100._r8 + end if + end if + end do + + ! Set pctglc_gic_o to sum of pctglcmec_gic_o across elevation classes, and similarly for pctglc_icesheet_o + if ( outnc_3dglc )then + pctglc_gic_o = sum(pctglcmec_gic_o, dim=2) + pctglc_icesheet_o = sum(pctglcmec_icesheet_o, dim=2) + end if + + ! -------------------------------------------------------------------- + ! Perform various sanity checks + ! -------------------------------------------------------------------- + + errors = .false. + + ! Confirm that the sum over pctglcmec_o (from 1 to nglcec) is 100% + do no = 1,ns_o + glc_sum = sum(pctglcmec_o(no,:)) + if (abs(glc_sum - 100._r8) > eps_small) then + write(6,*)'glc_sum differs from 100% at no,pctglc= ',no,glc_sum + errors = .true. + end if + end do + + ! Confirm that GIC + ICESHEET = 100% + if ( outnc_3dglc )then + do no = 1,ns_o + if (abs((pctglc_gic_o(no) + pctglc_icesheet_o(no)) - 100._r8) > eps) then + write(6,*)'GIC + ICESHEET differs from 100% at no,pctglc_gic,pctglc_icesheet,lon,lat=', & + no,pctglc_gic_o(no),pctglc_icesheet_o(no),& + tgridmap%xc_dst(no),tgridmap%yc_dst(no) + errors = .true. + end if + end do + + ! Check that GIC + ICESHEET = total glacier at each elevation class + do m = 1, nglcec + do no = 1,ns_o + if (abs((pctglcmec_gic_o(no,m) + pctglcmec_icesheet_o(no,m)) - & + pctglcmec_o(no,m)) > eps) then + write(6,*)'GIC + ICESHEET differs from total GLC ' + write(6,*)'at no,m,pctglcmec,pctglcmec_gic,pctglcmec_icesheet = ' + write(6,*) no,m,pctglcmec_o(no,m),pctglcmec_gic_o(no,m),pctglcmec_icesheet_o(no,m) + errors = .true. + end if + end do + end do + end if + + + ! Error check: are all elevations within elevation class range + do no = 1,ns_o + do m = 1,nglcec + if (topoglcmec_o(no,m) < elevclass(m) .or. topoglcmec_o(no,m) > elevclass(m+1)) then + write(6,*) 'Error: mean elevation does not fall within elevation class ' + write(6,*) elevclass(m),elevclass(m+1),topoglcmec_o(no,m),m,no + errors = .true. + endif + end do + end do + + if (errors) then + call abort() + end if + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate(pctglc_gic_i, pctglc_icesheet_i) + deallocate(topoglcmec_unnorm_o) + deallocate(pctglc_tot_o) + deallocate(frac_dst) + deallocate(starts, counts) + + write (6,*) 'Successfully made percent elevation class and mean elevation for glaciers' + write (6,*) + call shr_sys_flush(6) + +end subroutine mkglcmec + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkglacier +! +! !INTERFACE: +subroutine mkglacier(ldomain, mapfname, datfname, ndiag, zero_out, glac_o) +! +! !DESCRIPTION: +! make percent glacier +! +! In contrast to mkglcmec, this uses a "flat" PCT_GLACIER field (not separated by +! elevation class, and not separated into icesheet vs GIC). +! +! This simpler routine is sufficient for cases when we run without multiple elevation +! classes. This routine is also used when running with multiple elevation classes: we +! first regrid the flat PCT_GLACIER field, then later create the multiple elevation class +! data. This multi-step process makes it easier to do corrections on the total +! PCT_GLACIER, and make sure these corrections apply appropriately to the multi-level +! output. The assumption is that PCT_GLACIER is the sum of both PCT_GLC_GIC and +! PCT_GLC_ICESHEET across all elevation bins. +! +! !USES: + use mkdomainMod , only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio +! +! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + logical , intent(in) :: zero_out ! if should zero glacier out + real(r8) , intent(out):: glac_o(:) ! output grid: %glacier +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Mariana Vertenstein +! +! +! !LOCAL VARIABLES: +!EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: glac_i(:) ! input grid: percent glac + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: gglac_i ! input grid: global glac + real(r8) :: garea_i ! input grid: global area + real(r8) :: gglac_o ! output grid: global glac + real(r8) :: garea_o ! output grid: global area + integer :: ni,no,k,n,m,ns, ns_o ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ier ! error status + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + character(len=32) :: subname = 'mkglacier' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make %glacier .....' + call shr_sys_flush(6) + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + ns = tdomain%ns + ns_o = ldomain%ns + allocate(glac_i(ns), & + frac_dst(ns_o), & + stat=ier) + if (ier/=0) call abort() + + write (6,*) 'Open glacier file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + call check_ret(nf_inq_varid (ncid, 'PCT_GLACIER', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, glac_i), subname) + call check_ret(nf_close(ncid), subname) + + ! Area-average percent cover on input grid to output grid + ! and correct according to land landmask + ! Note that percent cover is in terms of total grid area. + + if ( zero_out )then + + do no = 1, ns_o + glac_o(no) = 0. + enddo + + else + + call gridmap_mapread(tgridmap, mapfname ) + + ! Error checks for domain and map consistencies + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Determine glac_o on output grid + + call gridmap_areaave_srcmask(tgridmap, glac_i, glac_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + do no = 1, ns_o + if (glac_o(no) < 1.) glac_o(no) = 0. + enddo + end if + + ! Check for conservation + + do no = 1, ns_o + if ((glac_o(no)) > 100.000001_r8) then + write (6,*) 'MKGLACIER error: glacier = ',glac_o(no), & + ' greater than 100.000001 for column, row = ',no + call shr_sys_flush(6) + call abort() + end if + enddo + + ! Some error checking and writing of global values before and after the regrid + + if ( .not. zero_out )then + + ! Global sum of output field -- must multiply by fraction of + ! output grid that is land as determined by input grid + + allocate(mask_r8(ns), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global areas on input and output grids + ! ----------------------------------------------------------------- + + ! Input grid + + gglac_i = 0. + garea_i = 0. + do ni = 1, ns + garea_i = garea_i + tgridmap%area_src(ni)*re**2 + gglac_i = gglac_i + glac_i(ni)*(tgridmap%area_src(ni)/100.)*& + tdomain%mask(ni)*re**2 + end do + + ! Output grid + + gglac_o = 0. + garea_o = 0. + do no = 1, ns_o + garea_o = garea_o + tgridmap%area_dst(no)*re**2 + gglac_o = gglac_o + glac_o(no)*(tgridmap%area_dst(no)/100.)*& + frac_dst(no)*re**2 + end do + + ! Diagnostic output + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'Glacier Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,2001) +2001 format (1x,'surface type input grid area output grid area'/ & + 1x,' 10**6 km**2 10**6 km**2 ') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + write (ndiag,2002) gglac_i*1.e-06,gglac_o*1.e-06 + write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 +2002 format (1x,'glaciers ',f14.3,f17.3) +2004 format (1x,'all surface ',f14.3,f17.3) + + end if + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + if ( .not. zero_out )then + call gridmap_clean(tgridmap) + deallocate (glac_i, frac_dst, mask_r8) + end if + + write (6,*) 'Successfully made %glacier' + write (6,*) + call shr_sys_flush(6) + +end subroutine mkglacier + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: get_elevclass +! +! !INTERFACE: +integer function get_elevclass(topo, writewarn) +! +! !DESCRIPTION: +! Returns elevation class index (1..nglcec) given the topographic height. +! If topo is lower than the lowest elevation class, returns 0. +! If topo is higher than the highest elevation class, returns (nglcec+1). +! In either of the two latter cases, the function also writes a warning message, unless +! writewarn is present and false. +! +! !ARGUMENTS: + implicit none + real(r8), intent(in) :: topo ! topographic height (m) + logical, intent(in), optional :: writewarn ! should warning messages be written? (default: true) +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +! !LOCAL VARIABLES: +!EOP + integer :: m + logical :: my_writewarn + character(len=32) :: subname = 'get_elevclass' +!----------------------------------------------------------------------- + + if (present(writewarn)) then + my_writewarn = writewarn + else + my_writewarn = .true. + end if + + if (topo < elevclass(1)) then + if (my_writewarn) then + write(6,*) 'WARNING in ', trim(subname) + write(6,*) 'topo out of bounds' + write(6,*) 'topo = ', topo + write(6,*) 'elevclass(1) = ', elevclass(1) + end if + get_elevclass = 0 + return + end if + + do m = 1, nglcec + if (topo < elevclass(m+1)) then + ! note that we already know that topo >= elevclass(m), otherwise we would have + ! returned earlier + get_elevclass = m + return + end if + end do + + if (my_writewarn) then + write(6,*) 'WARNING in ', trim(subname) + write(6,*) 'topo out of bounds' + write(6,*) 'topo = ', topo + write(6,*) 'elevclass(nglcec+1) = ', elevclass(nglcec+1) + end if + get_elevclass = nglcec+1 + +end function get_elevclass + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mean_elevation_vc +! +! !INTERFACE: +real(r8) function mean_elevation_vc(class) +! +! !DESCRIPTION: +! For a virtual column (thus, a column that has no true elevation data), return the +! "mean" elevation of the given elevation class. +! +! !ARGUMENTS: + implicit none + integer, intent(in) :: class ! elevation class +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +! !LOCAL VARIABLES: +!EOP + character(len=32) :: subname = 'mean_elevation_vc' +!----------------------------------------------------------------------- + + if (class < nglcec) then + mean_elevation_vc = 0.5_r8 * (elevclass(class) + elevclass(class+1)) + else if (class == nglcec) then + ! In the top elevation class; in this case, assignment of a "mean" elevation is + ! somewhat arbitrary + + if (nglcec > 1) then + mean_elevation_vc = 2.0_r8*elevclass(class) - elevclass(class-1) + else + ! entirely arbitrary + mean_elevation_vc = 1000._r8 + end if + else + write(6,*) 'ERROR in ', trim(subname), ': class out of bounds= ', class + call abort() + end if + +end function mean_elevation_vc + +end module mkglcmecMod diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 new file mode 100644 index 0000000000..0dc107729b --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -0,0 +1,1104 @@ +module mkharvestMod +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mkharvest +! +! !DESCRIPTION: +! Make harvest and grazing data to add to the dynamic PFT file. +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +!----------------------------------------------------------------------- +! !USES: + use shr_kind_mod , only : r8 => shr_kind_r8, CL => shr_kind_CL + use shr_sys_mod , only : shr_sys_flush + use mkdomainMod , only : domain_checksame + + implicit none + + private + +! !PUBLIC DATA MEMBERS: + + public :: harvestDataType + integer, private, parameter :: numharv = 9 ! number of harvest and grazing fields + + type :: harvestDataType + private + real(r8), pointer :: data1D(:,:) ! Input 1D data + real(r8), pointer :: data2DCFT(:,:,:) ! Input 2D data with CFT's + real(r8), pointer :: data2DPFT(:,:,:) ! Input 2D data with PFT's + real(r8), pointer :: OutData1D(:,:) ! Output 1D data + real(r8), pointer :: OutData2DCFT(:,:,:) ! Output 2D data with CFT's + real(r8), pointer :: OutData2DPFT(:,:,:) ! Output 2D data with natural PFT's + integer :: dims2nd(numharv) ! 2nd dimension size + integer :: CFTdimsize ! Size of CFT dimension + integer :: PFTdimsize ! Size of PFT dimension + integer :: indices1D(numharv) ! Field indices for CFT variables + integer :: indicesCFT(numharv) ! Field indices for CFT variables + integer :: indicesPFT(numharv) ! Field indices for PFT variables + contains + procedure :: init ! Initialization + procedure :: get1DFieldPtr ! Get a pointer to a 1D field + procedure :: get2DFieldPtr ! Get a pointer to a 2D field + procedure :: getFieldsIdx ! Get field indexes to 1D and 2D fields + procedure :: getFieldsDim ! Get dimension names for this field + procedure :: isField1D ! Return true if field is a 1D field + procedure :: isField2D ! Return true if field is a 2D field + procedure :: num1DFields ! Return the number of 1D fields + procedure :: num2DFields ! Return the number of 2D fields + procedure :: clean ! Clean and deallocate everything + end type harvestDataType + +! !PUBLIC MEMBER FUNCTIONS: + public mkharvest_init ! Initialization + public mkharvest ! Calculate the harvest values on output grid + public mkharvest_fieldname ! Field name for harvest fields on landuse.timeseries + public mkharvest_longname ! Long name + public mkharvest_units ! units + public mkharvest_numtypes ! Number of harvest types + public mkharvest_parse_oride ! Parse the over-ride string + +! !PRIVATE MEMBER FUNCTIONS: (but public because unit test uses them) + public mkharvest_fieldInBounds ! Check that field index is within bounds + +! !PRIVATE DATA MEMBERS: + + integer, parameter :: harlen = 25 ! length of strings for harvest fieldnames + character(len=harlen), parameter :: harvest_fieldnames(numharv) = (/ & + 'HARVEST_VH1 ', & + 'HARVEST_VH2 ', & + 'HARVEST_SH1 ', & + 'HARVEST_SH2 ', & + 'HARVEST_SH3 ', & + 'GRAZING ', & + 'FERTNITRO_CFT ', & + 'UNREPRESENTED_PFT_LULCC', & + 'UNREPRESENTED_CFT_LULCC' & + /) + character(len=harlen), parameter :: harvest_const_fieldnames(numharv) = (/ & + 'CONST_HARVEST_VH1 ', & + 'CONST_HARVEST_VH2 ', & + 'CONST_HARVEST_SH1 ', & + 'CONST_HARVEST_SH2 ', & + 'CONST_HARVEST_SH3 ', & + 'CONST_GRAZING ', & + 'CONST_FERTNITRO_CFT ', & + 'UNREPRESENTED_PFT_LULCC', & + 'UNREPRESENTED_CFT_LULCC' & + /) + character(len=CL), parameter :: string_undef = 'UNSET' + real(r8), parameter :: real_undef = -999.99 + character(len=CL), save :: harvest_longnames(numharv) = string_undef + character(len=CL), save :: harvest_units(numharv) = string_undef + real(r8), pointer :: oride_harv(:) ! array that can override harvesting + logical , save :: initialized = .false. + +!EOP +!----------------------------------------------------------------------- +contains +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: init +! +! !INTERFACE: + subroutine init( this, dims2nd, ns_i, ns_o, init_value ) +! +! !DESCRIPTION: +! Initialization of the harvestData object +! +! !USES: + implicit none +! +! !ARGUMENTS: + class(harvestDataType), intent(INOUT) :: this ! harvestData object + integer, intent(IN) :: dims2nd(:) ! 2nd Dimension sizes + integer, intent(IN) :: ns_i ! Input dimension size + integer, intent(IN) :: ns_o ! Output dimension size + real(r8), intent(IN) :: init_value ! Initial value +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! !LOCAL VARIABLES: + character(len=*), parameter :: subname = 'harvestData::init' + integer :: num2nd ! number of non 1D variables + integer :: numCFT, numPFT ! number of CFT and PFT variables respectively + integer :: num1D ! number of 1D variables + integer :: n ! index +!EOP +!----------------------------------------------------------------------- + if ( size(dims2nd) /= numharv )then + write(*,*) subname//':ERROR:: dims2nd given to init is not the right size' + call abort() + end if + this%CFTdimsize = 64 + this%PFTdimsize = 15 + this%dims2nd = dims2nd + num2nd = 0 + numCFT = 0 + numPFT = 0 + num1D = 0 + this%indices1D = -1 + this%indicesPFT = -1 + this%indicesCFT = -1 + do n = 1, numharv + if ( dims2nd(n) == 0 )then + num1D = num1D + 1 + this%indices1D(n) = num1D + else + num2nd = num2nd + 1 + if ( dims2nd(n) == this%CFTdimsize )then + numCFT = numCFT + 1 + this%indicesCFT(n) = numCFT + else if ( dims2nd(n) == this%PFTdimsize )then + numPFT = numPFT + 1 + this%indicesPFT(n) = numPFT + else + write(*,*) 'ERROR:: dims2nd is not the right size (should be 0, 15, or 64) = ', dims2nd(n) + call abort() + end if + end if + end do + + allocate( this%data1D(ns_i,num1D) ) + allocate( this%OutData1D(ns_o,num1D) ) + + this%OutData1D(:,:) = init_value + + if ( num2nd > 0 ) then + allocate( this%data2DCFT (ns_i,this%CFTdimsize,numCFT) ) + allocate( this%OutData2DCFT(ns_o,this%CFTdimsize,numCFT) ) + + this%OutData2DCFT(:,:,:) = init_value + + allocate( this%data2DPFT (ns_i,this%PFTdimsize,numPFT) ) + allocate( this%OutData2DPFT(ns_o,this%PFTdimsize,numPFT) ) + + this%OutData2DPFT(:,:,:) = init_value + end if + + end subroutine init + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: get1DFieldPtr +! +! !INTERFACE: + function get1DFieldPtr( this, nfield, output ) result(ptr1D) +! +! !DESCRIPTION: +! Returns 2D pointer to field data for this index +! +! !USES: + implicit none +! +! !ARGUMENTS: + class(harvestDataType), intent(IN) :: this ! harvestData object + integer, intent(in) :: nfield ! field index + real(r8), pointer :: ptr1D(:) ! Pointer to 1D data + logical, optional, intent(in) :: output ! Flag if this is the output pointer or not (input) +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! !LOCAL VARIABLES: + character(len=*), parameter :: subname = 'harvestData::get1DFieldPtr' + logical :: loutput ! Local output flag +!EOP +!----------------------------------------------------------------------- + loutput = .false. + if ( present(output) ) loutput = output + if ( mkharvest_fieldInBounds( nfield ) .and. this%isField1D(nfield) )then + if ( .not. loutput ) then + ptr1D => this%data1D(:,this%indices1D(nfield)) + else + ptr1D => this%OutData1D(:,this%indices1D(nfield)) + end if + else + call abort() + end if + end function get1DFieldPtr + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: get2DFieldPtr +! +! !INTERFACE: + function get2DFieldPtr( this, nfield, output ) result(ptr2D) +! +! !DESCRIPTION: +! Returns 2D pointer to field data for this index +! +! !USES: + implicit none +! +! !ARGUMENTS: + class(harvestDataType), intent(IN) :: this ! harvestData object + integer, intent(in) :: nfield ! field index + real(r8), pointer :: ptr2D(:,:) ! Pointer to 2D data + logical, optional, intent(in) :: output ! Flag if this is the output pointer or not (input) +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! !LOCAL VARIABLES: + character(len=*), parameter :: subname = 'harvestData::get2DFieldPtr' + logical :: loutput ! Local output flag +!EOP +!----------------------------------------------------------------------- + loutput = .false. + if ( present(output) ) loutput = output + if ( mkharvest_fieldInBounds( nfield ) .and. this%isField2D(nfield) )then + if ( .not. loutput ) then + if ( this%dims2nd(nfield) == this%CFTdimsize )then + ptr2D => this%data2DCFT(:,:,this%indicesCFT(nfield)) + else + ptr2D => this%data2DPFT(:,:,this%indicesPFT(nfield)) + end if + else + if ( this%dims2nd(nfield) == this%CFTdimsize )then + ptr2D => this%OutData2DCFT(:,:,this%indicesCFT(nfield)) + else + ptr2D => this%OutData2DPFT(:,:,this%indicesPFT(nfield)) + end if + end if + else + call abort() + end if + end function get2DFieldPtr + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: getFieldsIdx +! +! !INTERFACE: + subroutine getFieldsIdx( this, indices1D, indices2D ) +! +! !DESCRIPTION: +! Returns list of 1D and 2D fields indices +! +! !USES: + implicit none +! +! !ARGUMENTS: + class(harvestDataType), intent(IN) :: this ! harvestData object + integer, allocatable :: indices1D(:) ! List of 1D indices + integer, allocatable :: indices2D(:) ! List of 2D indices +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! !LOCAL VARIABLES: + character(len=*), parameter :: subname = 'harvestData::getFieldsIdx' + integer :: ifld, n1, n2 ! field index and field index +!EOP +!----------------------------------------------------------------------- + allocate( indices1D(max(1,this%num1DFields()) ) ) + allocate( indices2D(max(1,this%num2DFields()) ) ) + indices1D = -1 + indices2D = -1 + n1 = 0 + n2 = 0 + do ifld = 1, mkharvest_numtypes() + if ( this%isField1D(ifld) )then + n1 = n1 + 1 + indices1D(n1) = ifld + else if ( this%isField2D(ifld) )then + n2 = n2 + 1 + indices2D(n2) = ifld + end if + end do + end subroutine getFieldsIdx + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: getFieldsDim +! +! !INTERFACE: + function getFieldsDim( this, nfield ) result(dimname) +! +! !DESCRIPTION: +! Returns list of 1D and 2D fields indices +! +! !USES: + implicit none +! +! !ARGUMENTS: + class(harvestDataType), intent(IN) :: this ! harvestData object + integer, intent(in) :: nfield ! field index + character(len=10) :: dimname ! Dimension names +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! !LOCAL VARIABLES: + character(len=*), parameter :: subname = 'harvestData::getFieldsDim' +!EOP +!----------------------------------------------------------------------- + if ( this%dims2nd(nfield) == this%CFTdimsize )then + dimname = "cft" + else if ( this%dims2nd(nfield) == this%PFTdimsize )then + dimname = "natpft" + else + dimname = "none" + end if + end function getFieldsDim + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: isField1D +! +! !INTERFACE: + logical function isField1D( this, nfield ) +! +! !DESCRIPTION: +! Returns true if this field index is a 1D field +! +! !USES: + implicit none +! +! !ARGUMENTS: + class(harvestDataType), intent(IN) :: this ! harvestData object + integer, intent(in) :: nfield ! field index +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! !LOCAL VARIABLES: + character(len=*), parameter :: subname = 'harvestData::isField1D' +!EOP +!----------------------------------------------------------------------- + isField1D = .false. + if ( mkharvest_fieldInBounds( nfield ) )then + if ( this%dims2nd(nfield) == 0 ) isField1D = .true. + else + call abort() + end if + end function isField1D + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: isField2D +! +! !INTERFACE: + logical function isField2D( this, nfield ) +! +! !DESCRIPTION: +! Returns true if this field index is a 2D field +! +! !USES: + implicit none +! +! !ARGUMENTS: + class(harvestDataType), intent(IN) :: this ! harvestData object + integer, intent(in) :: nfield ! field index +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! !LOCAL VARIABLES: + character(len=*), parameter :: subname = 'harvestData::isField2D' +!EOP +!----------------------------------------------------------------------- + isField2D = .false. + if ( mkharvest_fieldInBounds( nfield ) )then + if ( this%dims2nd(nfield) /= 0 ) isField2D = .true. + else + call abort() + end if + end function isField2D + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: num1DFields +! +! !INTERFACE: + integer function num1DFields( this ) +! +! !DESCRIPTION: +! Returns the number of 1D fields +! +! !USES: + implicit none +! +! !ARGUMENTS: + class(harvestDataType), intent(IN) :: this ! harvestData object +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! !LOCAL VARIABLES: + character(len=*), parameter :: subname = 'harvestData::num1DFields' +!EOP +!----------------------------------------------------------------------- + num1DFields = count( this%dims2nd == 0) + end function num1DFields + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: num2DFields +! +! !INTERFACE: + integer function num2DFields( this ) +! +! !DESCRIPTION: +! Returns the number of 2D fields +! +! !USES: + implicit none +! +! !ARGUMENTS: + class(harvestDataType), intent(IN) :: this ! harvestData object +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! !LOCAL VARIABLES: + character(len=*), parameter :: subname = 'harvestData::num2DFields' +!EOP +!----------------------------------------------------------------------- + num2DFields = count( this%dims2nd /= 0) + end function num2DFields + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkharvest_init +! +! !INTERFACE: + subroutine mkharvest_init( ns_o, init_val, harvdata, fharvest, constant ) +! +! !DESCRIPTION: +! Initialization of mkharvest module. +! +! !USES: + use mkncdio + implicit none +! +! !ARGUMENTS: + integer , intent(in) :: ns_o ! clm output grid resolution + real(r8) , intent(in) :: init_val ! initial value to set to + type(harvestDataType), intent(INOUT) :: harvdata ! Harvest data + character(len=*) , intent(in) :: fharvest ! input harvest dataset file name + logical, intent(in), optional :: constant ! Flag if variables are CONST_ version for surface dataset + ! rather than landuse.timeseries +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: + character(len=*), parameter :: subname = 'mkharvest_init' + character(len=CL) :: lunits ! local units read in + integer :: ncid,varid ! input netCDF id's + integer :: ifld ! indices + integer :: ret ! return code + logical :: lconstant ! local version of constant flag + logical :: varexists ! If variable exists on file + integer :: dim_lengths(3) ! Dimension lengths on file + integer :: dims2nd(numharv) ! Dimension lengths of 3rd dimension for each variable on file + integer :: ndims ! Number of dimensions on file + integer :: ns_i ! clm input grid resolution (nlat*nlon) +!EOP +!----------------------------------------------------------------------- + lconstant = .false. + if ( present(constant) ) lconstant = constant + + initialized = .true. + call check_ret(nf_open(fharvest, 0, ncid), subname) + dims2nd(:) = 0 + ns_i = 0 + do ifld = 1, numharv + call check_ret(nf_inq_varid ( ncid, mkharvest_fieldname(ifld, constant=lconstant), varid), subname, varexists=varexists) + if ( .not. varexists )then + write(*,*) "SKIP: "//mkharvest_fieldname(ifld, constant=lconstant) + harvest_longnames(ifld) = trim(mkharvest_fieldname(ifld, constant=lconstant)) // " (zeroed out)" + harvest_units(ifld) = "not_read_in" + else + call check_ret(nf_get_att_text( ncid, varid, 'long_name', harvest_longnames(ifld)), subname ) + ret = nf_get_att_text( ncid, varid, 'units', harvest_units(ifld)) + if ( ret == nf_enotatt )then + harvest_units(ifld) = "unitless" + else if ( ret == nf_noerr )then + else + write(*,*) 'ERROR:: bad return code from NetCDF get attribute= '// nf_strerror(ret) + call abort() + end if + call get_dim_lengths(ncid, mkharvest_fieldname(ifld, constant=lconstant), ndims, dim_lengths) + if ( ns_i == 0 )then + ns_i = dim_lengths(1)*dim_lengths(2) + else if ( ns_i /= dim_lengths(1)*dim_lengths(2) )then + write(*,*) 'ERROR:: bad dimension sizes for variable = ', mkharvest_fieldname(ifld, constant=lconstant) + call abort() + end if + if ( ndims == 2 )then + dims2nd(ifld) = 0 + else if ( ndims == 3 )then + dims2nd(ifld) = dim_lengths(3) + else + write(*,*) 'ERROR:: bad dimensionality for variable = ', mkharvest_fieldname(ifld, constant=lconstant) + call abort() + end if + + end if + end do + call harvdata%init( dims2nd, ns_i, ns_o, init_val ) + + call check_ret(nf_close(ncid), subname) + + allocate( oride_harv(numharv) ) + oride_harv(:) = real_undef + + end subroutine mkharvest_init + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkharvest_fieldInBounds +! +! !INTERFACE: + logical function mkharvest_fieldInBounds( nfield ) +! +! !DESCRIPTION: +! Return true if field index is in bounds and initialization done +! +! !USES: + implicit none +! +! !ARGUMENTS: + integer, intent(in) :: nfield ! field index +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! !LOCAL VARIABLES: + character(len=*), parameter :: subname = 'mkharvest_fieldInBounds' +!EOP +!----------------------------------------------------------------------- + if ( nfield < 1 )then + write(6,*) subname, ' ERROR nfield < 1' + mkharvest_fieldInBounds = .false. + else if ( nfield > numharv )then + write(6,*) subname, ' ERROR nfield > max fields' + mkharvest_fieldInBounds = .false. + else if ( .not. initialized ) then + write(6,*) subname, ' ERROR mkharvest NOT initialized yet!' + mkharvest_fieldInBounds = .false. + else + mkharvest_fieldInBounds = .true. + end if + + end function mkharvest_fieldInBounds + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkharvest_fieldname +! +! !INTERFACE: + character(len=harlen) function mkharvest_fieldname( nfield, constant ) +! +! !DESCRIPTION: +! Return harvest fieldname of input field number. +! +! !USES: + implicit none +! +! !ARGUMENTS: + integer, intent(in) :: nfield + logical, intent(in), optional :: constant +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! !LOCAL VARIABLES: + character(len=*), parameter :: subname = 'mkharvest_fieldname' + logical :: lconstant ! local version of constant flag +!EOP +!----------------------------------------------------------------------- + lconstant = .false. + if ( present(constant) ) lconstant = constant + + if ( mkharvest_fieldInBounds( nfield ) )then + if ( .not. lconstant )then + mkharvest_fieldname = harvest_fieldnames(nfield) + else + mkharvest_fieldname = harvest_const_fieldnames(nfield) + end if + else + call abort() + end if + + end function mkharvest_fieldname + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkharvest_units +! +! !INTERFACE: + character(len=CL) function mkharvest_units( nfield ) +! +! !DESCRIPTION: +! Return units description of harvest fields +! +! !USES: + implicit none +! +! !ARGUMENTS: + integer, intent(in) :: nfield +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: + character(len=*), parameter :: subname = 'mkharvest_units' +!EOP +!----------------------------------------------------------------------- + + if ( mkharvest_fieldInBounds( nfield ) )then + mkharvest_units = harvest_units(nfield) + else + call abort() + end if + + end function mkharvest_units + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkharvest_longname +! +! !INTERFACE: + character(len=CL) function mkharvest_longname( nfield ) +! +! !DESCRIPTION: +! Return longname description of given input field number. +! +! !USES: + implicit none +! +! !ARGUMENTS: + integer, intent(in) :: nfield +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: + character(len=*), parameter :: subname = 'mkharvest_longname' +!EOP +!----------------------------------------------------------------------- + + if ( mkharvest_fieldInBounds( nfield ) )then + mkharvest_longname = harvest_longnames(nfield) + else + call abort() + end if + + end function mkharvest_longname + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkharvest_numtypes +! +! !INTERFACE: + integer function mkharvest_numtypes( ) +! +! !DESCRIPTION: +! Return number of different harvest field types. +! +! !USES: + implicit none +! +! !ARGUMENTS: + character(len=*), parameter :: subname = 'mkharvest_numtypes' +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: +!EOP +!----------------------------------------------------------------------- + mkharvest_numtypes = numharv + + end function mkharvest_numtypes + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: clean +! +! !INTERFACE: + subroutine clean( this ) +! +! !DESCRIPTION: +! Clean and deallocate the harvestData object +! +! !USES: + implicit none +! +! !ARGUMENTS: + class(harvestDataType), intent(INOUT) :: this ! harvestData object +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! !LOCAL VARIABLES: + character(len=*), parameter :: subname = 'harvestData::clean' +!EOP +!----------------------------------------------------------------------- + this%CFTdimsize = -1 + this%PFTdimsize = -1 + + if ( associated(this%data1D) ) deallocate( this%data1D ) + if ( associated(this%Outdata1D) ) deallocate( this%OutData1D ) + + if ( associated(this%data2DCFT) ) deallocate( this%data2DCFT ) + if ( associated(this%OutData2DCFT)) deallocate( this%OutData2DCFT ) + if ( associated(this%data2DPFT ) ) deallocate( this%data2DPFT ) + if ( associated(this%OutData2DPFT)) deallocate( this%OutData2DPFT ) + this%data2DCFT => null() + this%OutData2DCFT => null() + this%data2DPFT => null() + this%OutData2DPFT => null() + + end subroutine clean + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkharvest +! +! !INTERFACE: +subroutine mkharvest(ldomain, mapfname, datfname, ndiag, harvdata) +! +! !DESCRIPTION: +! Make harvest data for the dynamic PFT dataset. +! This dataset consists of the normalized harvest or grazing fraction (0-1) of +! the model. +! +! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio +! +! !ARGUMENTS: + implicit none + type(domain_type) , intent(in) :: ldomain ! + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + type(harvestDataType), intent(INOUT) :: harvdata ! Harvest data +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: +!EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8) :: gharv_o(numharv) ! output grid: global area harvesting + real(r8) :: garea_o ! output grid: global area + real(r8) :: gharv_i(numharv) ! input grid: global area harvesting + real(r8) :: garea_i ! input grid: global area + integer :: ifld ! indices + integer :: k,n,m,ni,no,ns_i,ns_o ! indices + integer :: ncid,varid ! input netCDF id's + logical :: varexists ! If variable exists or not + integer :: ier ! error status + integer, allocatable :: ind1D(:) ! Index of 1D harvest fields + integer, allocatable :: ind2D(:) ! Index of 2D harvest fields + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), pointer :: data1D_i(:) ! 1D input data + real(r8), pointer :: data2D_i(:,:) ! 2D output data + real(r8), pointer :: data1D_o(:) ! 1D output data + real(r8), pointer :: data2D_o(:,:) ! 2D output data + + character(len=*), parameter :: unit = '10**6 km**2' ! Output units + real(r8), parameter :: fac = 1.e-06_r8 ! Output factor + real(r8), parameter :: rat = fac/100._r8 ! Output factor divided by 100% + character(len=*), parameter :: subname = 'mkharvest' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make harvest fields .....' + call shr_sys_flush(6) + + ! ----------------------------------------------------------------- + ! Normally read in the harvesting file, and then regrid to output grid + ! ----------------------------------------------------------------- + call harvdata%getFieldsIdx( ind1D, ind2D ) + + if ( all(oride_harv == real_undef ) )then + + ! ----------------------------------------------------------------- + ! Read input harvesting file + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read HARVEST_VH1, HARVEST_VH2, ... GRAZING etc. + + call domain_read(tdomain,datfname) + ns_i = tdomain%ns + ns_o = ldomain%ns + allocate(frac_dst(ns_o), stat=ier) + if (ier /= 0) call abort() + + write (6,*) 'Open harvest file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + do k = 1, harvdata%num1Dfields() + ifld = ind1D(k) + call check_ret( nf_inq_varid(ncid, mkharvest_fieldname(ifld), varid), subname, varexists=varexists ) + data1D_i => harvdata%get1DFieldPtr( ifld ) + if ( .not. varexists )then + write(*,*) "SKIP: "//mkharvest_fieldname(ifld) + data1D_i(:) = 0.0_r8 + else + call check_ret(nf_get_var_double (ncid, varid, data1D_i), subname) + end if + end do + do k = 1, harvdata%num2Dfields() + ifld = ind2D(k) + call check_ret( nf_inq_varid(ncid, mkharvest_fieldname(ifld), varid), subname, varexists=varexists ) + data2D_i => harvdata%get2DFieldPtr( ifld ) + if ( .not. varexists )then + write(*,*) "SKIP: "//mkharvest_fieldname(ifld) + data2D_i(:,:) = 0.0_r8 + else + call check_ret(nf_get_var_double (ncid, varid, data2D_i), subname) + end if + end do + call check_ret(nf_close(ncid), subname) + + ! Area-average normalized harvest on input grid [data*_i] to output grid [data*_o] + + call gridmap_mapread(tgridmap, mapfname ) + + ! Error checks for domain and map consistencies + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Determine data* on output grid + + do k = 1, harvdata%num1Dfields() + ifld = ind1D(k) + data1D_i => harvdata%get1DFieldPtr( ifld ) + data1D_o => harvdata%get1DFieldPtr( ifld, output=.true. ) + call gridmap_areaave_srcmask(tgridmap, data1D_i, data1D_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + end do + do k = 1, harvdata%num2Dfields() + ifld = ind2D(k) + data2D_i => harvdata%get2DFieldPtr( ifld ) + data2D_o => harvdata%get2DFieldPtr( ifld, output=.true. ) + do m = lbound(data2D_i(:,:),dim=2), ubound(data2D_i(:,:),dim=2) + call gridmap_areaave_srcmask(tgridmap, data2D_i(:,m), data2D_o(:,m), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + end do + end do + + ! ----------------------------------------------------------------- + ! Error check + ! Compare global areas on input and output grids + ! ----------------------------------------------------------------- + + gharv_i(:) = 0. + garea_i = 0. + do ni = 1, ns_i + garea_i = garea_i + tgridmap%area_src(ni)*re**2 + do k = 1, harvdata%num1Dfields() + m = ind1D(k) + data1D_i => harvdata%get1DFieldPtr( m ) + gharv_i(m) = gharv_i(m) + data1D_i(ni)*tgridmap%area_src(ni)* & + tdomain%mask(ni)*re**2 + end do + end do + + gharv_o(:) = 0. + garea_o = 0. + do no = 1,ns_o + garea_o = garea_o + tgridmap%area_dst(no)*re**2 + do k = 1, harvdata%num1Dfields() + m = ind1D(k) + data1D_o => harvdata%get1DFieldPtr( m, output=.true. ) + gharv_o(m) = gharv_o(m) + data1D_o(no)*tgridmap%area_dst(no)* & + frac_dst(no)*re**2 + end do + end do + + ! Write out to diagnostic output file + ! + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'Harvesting Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,1001) unit, unit +1001 format (1x,'harvest type ',20x,' input grid area',' output grid area',/ & + 1x,33x,' ',A,' ',A) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + do k = 1, harvdata%num1Dfields() + m = ind1D(k) + write (ndiag,1002) mkharvest_fieldname(m), gharv_i(m)*rat,gharv_o(m)*rat + end do +1002 format (1x,a35,f16.3,f17.3) + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + + else + + ! ----------------------------------------------------------------- + ! Otherwise override the harvesting with the input harvest values + ! ----------------------------------------------------------------- + + if ( any(oride_harv == real_undef ) )then + write(6,*) subname, ' error some override harvesting fields set ', & + 'and others are not = ', oride_harv + call abort() + end if + do k = 1, harvdata%num1Dfields() + m = ind1D(k) + if ( oride_harv(m) < 0.0_r8 .or. oride_harv(m) > 100.0_r8 )then + write(6,*) subname, ' error override harvesting field out of range', & + oride_harv(m), ' field = ', mkharvest_fieldname(m) + call abort() + end if + end do + do no = 1,ns_o + do k = 1, harvdata%num1Dfields() + m = ind1D(k) + data1D_o => harvdata%get1DFieldPtr( m, output=.true. ) + data1D_o(no) = oride_harv(m) + end do + end do + + end if + + deallocate( ind1D, ind2D ) + write (6,*) 'Successfully made harvest and grazing' + write (6,*) + +end subroutine mkharvest + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkharvest_parse_oride +! +! !INTERFACE: +subroutine mkharvest_parse_oride( string ) +! +! !DESCRIPTION: +! Parse the string with harvest and grazing information on it, to override +! the file with this information rather than reading from a file. +! +! !USES: + use shr_string_mod, only: shr_string_betweenTags +! !ARGUMENTS: + character(len=256), intent(IN) :: string ! String to parse with harvest and grazing data +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: +!EOP + integer :: rc ! error return code + character(len=256) :: substring ! substring between tags + character(len=*), parameter :: harv_start = "" + character(len=*), parameter :: harv_end = "" + character(len=*), parameter :: graz_start = "" + character(len=*), parameter :: graz_end = "" + character(len=*), parameter :: subname = 'mkharvest_parse_oride' +!----------------------------------------------------------------------- + call shr_string_betweenTags( string, harv_start, harv_end, substring, rc ) + if ( rc /= 0 )then + write(6,*) subname//'Trouble finding harvest start end tags' + call abort() + end if + read(substring,*) oride_harv(1:numharv-1) + call shr_string_betweenTags( string, graz_start, graz_end, substring, rc ) + if ( rc /= 0 )then + write(6,*) subname//'Trouble finding grazing start end tags' + call abort() + end if + read(substring,*) oride_harv(numharv) + if ( harvest_fieldnames(numharv) /= 'GRAZING' )then + write(6,*) subname, ' grazing is NOT last field as was expected' + call abort() + end if + +!----------------------------------------------------------------------- + +end subroutine mkharvest_parse_oride + +!----------------------------------------------------------------------- + +end module mkharvestMod diff --git a/tools/mksurfdata_esmf/src/mkindexmapMod.F90 b/tools/mksurfdata_esmf/src/mkindexmapMod.F90 new file mode 100644 index 0000000000..5f8e74af2b --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkindexmapMod.F90 @@ -0,0 +1,697 @@ +module mkindexmapMod +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mkindexmapMod +! +! !DESCRIPTION: +! Module containing subroutines for making maps of index data. +! +! This includes a routine for making a map using the dominant type among the input grid +! cells making up a given output cell, as well as routines for using an index map as +! indices into a lookup table, to essentially paint-by-number some other field, and some +! other related routines +! +! WJS (2-1-12): There is a lookup_2d subroutine, but not a lookup_1d (or any other +! dimensionality). That is simply because I needed lookup_2d, but have not yet needed a +! routine of other dimensionalities. In the future, it would probably be helpful to at +! least have lookup_1d and lookup_1d_netcdf. If this is done, see my notes under the +! lookup_2d_netcdf routine for some thoughts on avoiding duplication. +! +! +! !USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use mkncdio, only : nf_max_name + use mkgridmapMod, only : gridmap_type + + implicit none + private + +! !PUBLIC TYPES: +! + ! dim_slice_type: stores information about dimensions that we use for slicing a multi- + ! dimensional variable + type dim_slice_type + character(len=nf_max_name) :: name ! name of this dimension + integer :: val ! index to use for the slice + end type dim_slice_type + public :: dim_slice_type +! +! !PUBLIC MEMBER FUNCTIONS: + public :: get_dominant_indices ! make output map based on dominant type in each grid cell + public :: get_max_indices ! make output map based on maximum type in each grid cell + public :: lookup_2d ! create map based on a 2-d lookup table + public :: lookup_2d_netcdf ! wrapper to lookup_2d; first read table from netcdf file + public :: which_max ! get index of the maximum value in an array +! +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +!EOP +!------------------------------------------------------------------------------ +contains + +!------------------------------------------------------------------------------ +!BOP +! +! !IROUTINE: get_dominant_indices +! +! !INTERFACE: +subroutine get_dominant_indices(gridmap, src_array, dst_array, minval, maxval, nodata, filter, mask_src) +! +! !DESCRIPTION: +! Fills an output array on the destination grid (dst_array) whose values are equal to the +! (weighted) dominant value in the source grid cells overlapping a given destination grid +! cell +! +! Ignores all values in src_array that are less than minval or greater than maxval (treats +! those values the same as if they had wt=0). (Note: for memory-use efficiency, it is +! best if the indices are designed such that most values between minval and maxval are +! actually used, since an array is allocated of size (maxval - minval + 1)*gridmap%nb.) +! +! The filter argument can be used to exclude certain overlaps -- if provided, we only +! consider overlaps where filter is .true. If not provided, filter is treated as being +! .true. everywhere. +! +! Output grid cells with no contributing valid source points are given the nodata value +! +! !ARGUMENTS: + implicit none + type(gridmap_type), intent(in) :: gridmap ! provides mapping from src -> dst + integer , intent(in) :: src_array(:) ! input values; length gridmap%na + integer , intent(out):: dst_array(:) ! output values; length gridmap%nb + integer , intent(in) :: minval ! minimum valid value in src_array + integer , intent(in) :: maxval ! maximum valid value in src_array + integer , intent(in) :: nodata ! value to assign to dst_array where there are no valid source points + integer , intent(in) :: mask_src(:) + + logical, intent(in), optional :: filter(:) ! only consider overlaps where filter is .true.; length gridmap%ns +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +! +! !LOCAL VARIABLES: +!EOP + logical, allocatable :: lfilter(:) ! local version of filter + logical, allocatable :: hasdata(:) ! true if an output cell has any valid data; + real(r8), allocatable :: weights(:,:) ! summed weight of each index value for each output cell + + integer :: n, ni, no + integer :: k + integer :: maxindex + real(r8) :: wt + real(r8) :: maxwt + + character(len=*), parameter :: subname = "get_dominant_indices" +!----------------------------------------------------------------------- + + ! Error-check inputs and initialize local variables + + if (size(src_array) /= gridmap%na .or. & + size(dst_array) /= gridmap%nb) then + write(6,*) subname//' ERROR: incorrect sizes of src_array or dst_array' + write(6,*) 'size(src_array) = ', size(src_array) + write(6,*) 'gridmap%na = ', gridmap%na + write(6,*) 'size(dst_array) = ', size(dst_array) + write(6,*) 'gridmap%nb = ', gridmap%nb + call abort() + end if + if (size(mask_src) /= size(src_array)) then + write(6,*) subname//' ERROR: incorrect size of mask_src' + write(6,*) 'size(mask_src) = ', size(mask_src) + write(6,*) 'size(src_array) = ', size(src_array) + call abort() + end if + + allocate(lfilter(gridmap%ns)) + + if (present(filter)) then + if (size(filter) /= gridmap%ns) then + write(6,*) subname//' ERROR: incorrect size of filter' + write(6,*) 'size(filter) = ', size(filter) + write(6,*) 'gridmap%ns = ', gridmap%ns + call abort() + end if + + lfilter(:) = filter(:) + else + lfilter(:) = .true. + end if + + allocate(hasdata(gridmap%nb)) + hasdata(:) = .false. + allocate(weights(minval:maxval, gridmap%nb)) + weights(minval:maxval,:) = 0. + + ! Determine weight of each index value for each output (destination) cell + + do n = 1, gridmap%ns + if (lfilter(n)) then + ni = gridmap%src_indx(n) + no = gridmap%dst_indx(n) + wt = gridmap%wovr(n) * mask_src(ni) + k = src_array(ni) + if (k >= minval .and. k <= maxval) then + ! Note: if we were doing something like weighted sums, I think we would + ! want to divide wt by gridmap%frac_dst(no), as is done in + ! gridmap_areaave_default. But since all we care about is the relative + ! values of weights for a given destination cell, this is unnecessary + weights(k,no) = weights(k,no) + wt + hasdata(no) = .true. + end if + end if + end do + + ! Determine output values + ! Note: if a given destination cell has no contributing source points (thus + ! hasdata(no) = false), or the max weight of any index overlapping this destination + ! cell is <= 0, then the output value there will be nodata. + ! (I don't think this latter condition -- weight <= 0 -- is possible, but we handle + ! it anyway) + + dst_array(:) = nodata + do no = 1, gridmap%nb + if (hasdata(no)) then + call which_max(weights(:,no), maxwt, maxindex, lbound=minval) + if (maxwt > 0.) then + dst_array(no) = maxindex + end if + end if + end do + + deallocate(lfilter, weights, hasdata) + +end subroutine get_dominant_indices +!------------------------------------------------------------------------------ + +!----------------------------------------------------------------------- +subroutine get_max_indices(gridmap, src_array, dst_array, nodata, mask_src) + ! + ! !DESCRIPTION: + ! Fills an output array on the destination grid (dst_array) whose values are equal to + ! the maximum value in the source grid cells overlapping a given destination grid cell. + ! + ! The frequency of occurrence of the source values is irrelevant. For example, if the + ! value 1 appears in 99% of source cells overlapping a given destination cell and the + ! value 2 appears in just 1%, we'll put 2 in the destination cell because it is the + ! maximum value. + ! + ! Output grid cells with no contributing valid source points are given the nodata value + ! + ! !ARGUMENTS: + type(gridmap_type) , intent(in) :: gridmap ! provides mapping from src -> dst + integer , intent(in) :: src_array(:) ! input values; length gridmap%na + integer , intent(out) :: dst_array(:) ! output values; length gridmap%nb + integer , intent(in) :: nodata ! value to assign to dst_array where there are no valid source points + integer , intent(in) :: mask_src(:) ! mask at the source resolution + ! + ! !LOCAL VARIABLES: + logical, allocatable :: hasdata(:) ! true if an output cell has any valid data; + integer :: n, ni, no + real(r8) :: wt + integer :: src_val + + character(len=*), parameter :: subname = 'get_max_indices' + !----------------------------------------------------------------------- + + ! Error-check inputs + + if (size(src_array) /= gridmap%na .or. & + size(dst_array) /= gridmap%nb) then + write(6,*) subname//' ERROR: incorrect sizes of src_array or dst_array' + write(6,*) 'size(src_array) = ', size(src_array) + write(6,*) 'gridmap%na = ', gridmap%na + write(6,*) 'size(dst_array) = ', size(dst_array) + write(6,*) 'gridmap%nb = ', gridmap%nb + call abort() + end if + if (size(mask_src) /= size(src_array)) then + write(6,*) subname//' ERROR: incorrect size of mask_src' + write(6,*) 'size(mask_src) = ', size(mask_src) + write(6,*) 'size(src_array) = ', size(src_array) + call abort() + end if + + ! Initialize local variables + allocate(hasdata(gridmap%nb)) + hasdata(:) = .false. + + do n = 1, gridmap%ns + ni = gridmap%src_indx(n) + wt = gridmap%wovr(n) * mask_src(ni) + if (wt > 0._r8) then + no = gridmap%dst_indx(n) + src_val = src_array(ni) + if (.not. hasdata(no)) then + hasdata(no) = .true. + dst_array(no) = src_val + else if (src_val > dst_array(no)) then + dst_array(no) = src_val + end if + end if + end do + + do no = 1, gridmap%nb + if (.not. hasdata(no)) then + dst_array(no) = nodata + end if + end do + +end subroutine get_max_indices + + +!------------------------------------------------------------------------------ +!BOP +! +! !IROUTINE: lookup_2d +! +! !INTERFACE: +subroutine lookup_2d(index1, index2, lookup_table, fill_val, data, ierr, & + nodata, valid_entries, invalid_okay) +! +! !DESCRIPTION: +! Creates a data array using a paint-by-number approach according to a lookup table +! +! This routine operates on a 2-d lookup table. There are therefore two index arrays +! (index1 and index2); these index arrays are on the same grid as the desired data array +! (thus, index1, index2 and data must all have the same length). Each output point, n, is +! then generally determined as: +! +! data(n) = lookup_table(index1(n), index2(n)) +! +! fill_val: value to put in data array where either: +! (a) index1 or index2 are equal to nodata (if nodata is given) +! Note that this condition does NOT result in ierr being set +! (b) valid_entries(index1(n), index2(n)) is false (if valid_entries is given) +! Note that this condition also results in ierr being set, unless invalid_okay is +! present and .true. +! (If valid_entries is not given, it is treated as being .true. everywhere) +! (c) index1 or index2 out of range +! Note that this condition also results in ierr being set +! +! ierr: error return code (if non-0, indicates first error encountered): +! 0: no error +! 1: attempt to assign values from the lookup table that are invalid according +! to valid_entries (note: this is not considered an error if invalid_okay is +! present and .true.) +! 2: attempt to access an out-of-range index in lookup table +! WJS (2-2-12): My main reason for using ierr rather than aborting in case of error +! is to facilitate unit testing +! +! !ARGUMENTS: + implicit none + integer , intent(in) :: index1(:) ! index into dim 1 of lookup_table + integer , intent(in) :: index2(:) ! index into dim 2 of lookup_table + real(r8), intent(in) :: lookup_table(:,:) + real(r8), intent(in) :: fill_val ! value to put in data where we don't have a valid value (see above for details) + real(r8), intent(out):: data(:) ! output arary + integer , intent(out):: ierr ! error return code (0 = no error) + + ! nodata flag in index1 and index2 (see above for details): + integer, intent(in), optional :: nodata + + ! which entries are considered valid (see above for details): + logical, intent(in), optional :: valid_entries(:,:) + + ! invalid_okay: if true, then assigning fill_val because valid_entries is false does + ! NOT raise an error flag (invalid_okay defaults to false, meaning an error is + ! raised in this case): + logical, intent(in), optional :: invalid_okay +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +! +! !LOCAL VARIABLES: +!EOP + integer :: n + integer :: i1, i2 + integer :: data_size ! size of index1, index2 and data arrays + integer :: table_n1 ! size of dimension 1 of lookup table + integer :: table_n2 ! size of dimension 2 of lookup table + logical :: linvalid_okay ! local version of invalid_okay + logical, allocatable :: lvalid_entries(:,:) ! local version of valid_entries + + character(len=*), parameter :: subname = 'lookup_2d' +!----------------------------------------------------------------------- + + ierr = 0 + + ! Error-check array sizes + + data_size = size(data) + if (size(index1) /= data_size .or. size(index2) /= data_size) then + write(6,*) subname//' ERROR: data array sizes do not match' + write(6,*) 'size(data) = ', data_size + write(6,*) 'size(index1) = ', size(index1) + write(6,*) 'size(index2) = ', size(index2) + call abort() + end if + + table_n1 = size(lookup_table,1) + table_n2 = size(lookup_table,2) + if (present(valid_entries)) then + if (size(valid_entries,1) /= table_n1 .or. size(valid_entries,2) /= table_n2) then + write(6,*) subname//' ERROR: size of valid_entries does not match lookup_table' + write(6,*) 'size(lookup_table) = ', table_n1, table_n2 + write(6,*) 'size(valid_entries) = ', size(valid_entries,1), & + size(valid_entries,2) + call abort() + end if + end if + + ! Set local version of invalid_okay & valid_entries + + if (present(invalid_okay)) then + linvalid_okay = invalid_okay + else + linvalid_okay = .false. + end if + + allocate(lvalid_entries(table_n1, table_n2)) + if (present(valid_entries)) then + lvalid_entries(:,:) = valid_entries(:,:) + else + lvalid_entries(:,:) = .true. + end if + + ! Do the lookups + + do n = 1, data_size + i1 = index1(n) + i2 = index2(n) + + ! First handle special cases: + + ! index is nodata flag (this is NOT an error) + if (present(nodata)) then + if (i1 == nodata .or. i2 == nodata) then + data(n) = fill_val + cycle + end if + end if + + ! index out of range + if (i1 <= 0 .or. i1 > table_n1 .or. & + i2 <= 0 .or. i2 > table_n2) then + data(n) = fill_val + if (ierr == 0) ierr = 2 + cycle + end if + + ! lookup table entry is invalid + if (.not. lvalid_entries(i1, i2)) then + data(n) = fill_val + if (.not. linvalid_okay) then + if (ierr == 0) ierr = 1 + end if + cycle + end if + + ! Finally, the "normal" case, if none of the special cases were triggered: + data(n) = lookup_table(i1, i2) + end do + + deallocate(lvalid_entries) + +end subroutine lookup_2d +!------------------------------------------------------------------------------ + +!------------------------------------------------------------------------------ +!BOP +! +! !IROUTINE: lookup_2d_netcdf +! +! !INTERFACE: +subroutine lookup_2d_netcdf(ncid, tablename, lookup_has_invalid, & + dimname1, dimname2, n_extra_dims, & + index1, index2, fill_val, data, ierr, & + extra_dims, nodata, invalid_okay) +! +! !DESCRIPTION: +! Wrapper to lookup_2d that first reads the lookup table from a netcdf file +! +! If lookup_has_invalid is false, then we treat all lookup table entries as valid data +! (i.e., all valid_entries are true in the call to lookup_2d). If lookup_has_invalid is +! true, then we read the _FillValue attribute for the lookup table variable, and consider +! any table entry with value _FillValue to be an invalid entry, thus putting fill_val in +! these data locations (and raising an error flag unless invalid_okay is present and +! true). +! +! The dimension given by dimname1 -- with the associated indices given by index1 -- is the +! fastest-varying dimension in the lookup table. Dimension dimname2 (associated with +! index2) is the second-fastest-varying dimension. Similarly, extra_dims should be ordered +! from faster-varying to slowest-varying dimension. (The first dimension in extra_dims is +! the third-fastest-varying dimension in the lookup table.) +! +! n_extra_dims gives the number of extra dimensions (in addition to the first two) in the +! lookup table. We take a single 2-d slice of the lookup table, by using a single value of +! each of these other dimensions. If n_extra_dims > 0, then extra_dims must be present, +! with at least n_extra_dims entries. Each entry in extra_dims gives the name of a +! dimension and the dimension index to use for the slice. +! +! If size(extra_dims) > n_extra_dims, then we use the first n_extra_dims entries in +! extra_dims. If n_extra_dims = 0, then extra_dims is ignored. +! +! Note that we ignore any coordinate variables associated with the dimensions of the +! lookup table; we simply treat the lookup table indices as 1,2,3,... +! +! See the lookup_2d documentation for documentation of some other arguments +! +! WJS (2-1-12): Some thoughts on avoiding duplication if we eventually want similar +! routines, lookup_1d_netcdf, lookup_3d_netcdf, etc.: +! +! Much of the code in lookup_2d_netcdf could then be pulled out to a shared subroutine +! (e.g., much of the error-checking code). +! +! Or, maybe better: we could try to make a single lookup_netcdf subroutine that handles +! 1-d, 2-d and any other dimensionality. To do that, we would (1) make a generic interface +! (of which lookup_1d and lookup_2d would be implementations); (2) change the repeated +! arguments in lookup_2d_netcdf (*1 and *2) to arrays -- maybe using an array of a derived +! type containing these arguments; (3) if possible, initially read the lookup table into a +! 1-d array (if the netcdf call allows reading a n-d array into a 1-d array) (if netcdf +! doesn't allow this, then I think we could achieve the same thing by reading 1-d slices +! of the lookup table in a loop, building the full lookup table as a long 1-d array); (4) +! in the call to the generic 'lookup' function, reshape the 1-d lookup table +! appropriately. (Note: I think it would be challenging to combine lookup_1d and lookup_2d +! (etc.) into a single routine using a similar method.) +! +! !USES: + use mkncdio +! !ARGUMENTS: + implicit none + integer , intent(in) :: ncid ! ID of an open netcdf file + character(len=*), intent(in) :: tablename ! name of the lookup table variable + logical , intent(in) :: lookup_has_invalid ! should we use _FillValue? (see above) + character(len=*), intent(in) :: dimname1 ! name of the first (fastest-varying) dimension of the lookup table + character(len=*), intent(in) :: dimname2 ! name of the second dimension of the lookup table + integer , intent(in) :: n_extra_dims ! number of extra dimensions in the lookup table + ! The following arguments are passed directly to lookup_2d: + integer , intent(in) :: index1(:) ! index into dim 1 of lookup table + integer , intent(in) :: index2(:) ! index into dim 2 of lookup table + real(r8) , intent(in) :: fill_val ! value to put in data where we don't have a valid value + real(r8) , intent(out):: data(:) ! output array + integer , intent(out):: ierr ! error return code from the call to lookup_2d + + ! slice to use if lookup table variable has more than 2 dimensions: + type(dim_slice_type), intent(in), optional :: extra_dims(:) + + ! nodata flag in index1 and index2, passed directly to lookup_2d: + integer , intent(in), optional :: nodata + + ! flag for whether trying to use a lookup table value that is equal to the _FillValue + ! should raise an error flag + ! (irrelevant if lookup_has_invalid is .false.) + ! (passed directly to lookup_2d - see the documentation there for more details) + logical , intent(in), optional :: invalid_okay +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +! +! !LOCAL VARIABLES: +!EOP + integer :: varid ! netcdf variable id of the lookup table + integer :: ndims ! total number of dimensions of lookup table + integer :: ndims_expected ! value we expect for ndims, for error checking + integer :: i + real(r8) :: table_fillval ! value of the _FillValue attribute for the lookup table + character(len=nf_max_name), allocatable :: dimnames(:) ! dimension names + integer , allocatable :: dimids(:) ! dimension ids + integer , allocatable :: dimlens(:) ! dimension lengths + integer , allocatable :: starts(:) ! starting indices for reading lookup table + integer , allocatable :: counts(:) ! dimension counts for reading lookup table + real(r8), allocatable :: lookup_table(:,:) + logical , allocatable :: valid_entries(:,:) ! which entries of the lookup table are considered valid + + character(len=*), parameter :: subname = 'lookup_2d_netcdf' +!----------------------------------------------------------------------- + + ! Error-check extra_dims + + if (n_extra_dims > 0) then + if (.not. present(extra_dims)) then + write(6,*) subname//' ERROR: extra_dims must be present for n_extra_dims > 0' + call abort() + end if + + if (size(extra_dims) < n_extra_dims) then + write(6,*) subname//' ERROR: not enough extra dimensions given' + write(6,*) 'n_extra_dims = ', n_extra_dims + write(6,*) 'size(extra_dims) = ', size(extra_dims) + call abort() + end if + end if + + ! Determine number of expected dimensions in the table, and actual number of + ! dimensions in the netcdf file + + ndims_expected = 2 + n_extra_dims + + call check_ret(nf_inq_varid (ncid, tablename, varid), subname) + call check_ret(nf_inq_varndims (ncid, varid, ndims), subname) + if (ndims /= ndims_expected) then + write(6,*) subname//' ERROR: unexpected number of dimensions in ', & + trim(tablename) + write(6,*) 'ndims = ', ndims + write(6,*) 'expected (based on n_extra_dims): ', ndims_expected + call abort() + end if + + ! Get dimension names & sizes, and error-check them + + allocate(dimids(ndims), dimlens(ndims), dimnames(ndims)) + call check_ret(nf_inq_vardimid (ncid, varid, dimids), subname) + do i = 1, ndims + call check_ret(nf_inq_dimname (ncid, dimids(i), dimnames(i)), subname) + call check_ret(nf_inq_dimlen (ncid, dimids(i), dimlens(i)), subname) + end do + + call check_dimname(dimnames(1), dimname1, 1) + call check_dimname(dimnames(2), dimname2, 2) + do i = 1, n_extra_dims + call check_dimname(dimnames(2+i), extra_dims(i)%name, 2+i) + call check_dimsize(dimlens(2+i), extra_dims(i)%val, 2+i) + end do + + ! Read the lookup table; if the given variable has more than 2 dimensions, we read + ! a single 2-d slice + + allocate(starts(ndims), counts(ndims)) + allocate(lookup_table(dimlens(1), dimlens(2))) + starts(1:2) = 1 + counts(1:2) = dimlens(1:2) + do i = 1, n_extra_dims + starts(2+i) = extra_dims(i)%val + counts(2+i) = 1 + end do + call check_ret(nf_get_vara_double (ncid, varid, starts, counts, lookup_table), subname) + + ! Determine which entries are valid + + allocate(valid_entries(size(lookup_table, 1), size(lookup_table, 2))) + valid_entries(:,:) = .true. + if (lookup_has_invalid) then + call check_ret(nf_get_att_double (ncid, varid, '_FillValue', table_fillval), subname) + where (lookup_table == table_fillval) + valid_entries = .false. + end where + end if + + ! Do the lookups + + call lookup_2d(index1, index2, lookup_table, fill_val, data, ierr, nodata=nodata, & + valid_entries=valid_entries, invalid_okay=invalid_okay) + + deallocate(valid_entries) + deallocate(lookup_table) + deallocate(starts, counts) + deallocate(dimids, dimlens, dimnames) + +contains +!------------------------------------------------------------------------------ + subroutine check_dimname(actual, expected, i) + ! Make sure names are equal; if not, stop with an error message + + character(len=*), intent(in) :: actual, expected + integer , intent(in) :: i ! dimension number, for output purposes + + if (actual /= expected) then + write(6,*) subname//' ERROR: unexpected dimension name in ', trim(tablename) + write(6,*) 'dimension #', i + write(6,*) 'actual: ', trim(actual) + write(6,*) 'expected: ', trim(expected) + call abort() + end if + end subroutine check_dimname + +!------------------------------------------------------------------------------ + subroutine check_dimsize(length, index, i) + ! Make sure dimension length is long enough; if not, stop with an error message + + integer, intent(in) :: length, index + integer, intent(in) :: i ! dimension number, for output purposes + + if (index > length) then + write(6,*) subname//' ERROR: desired index exceeds dimension length in ', & + trim(tablename) + write(6,*) 'dimension #', i + write(6,*) 'index: ', index + write(6,*) 'length: ', length + call abort() + end if + end subroutine check_dimsize + +end subroutine lookup_2d_netcdf +!------------------------------------------------------------------------------ + +!------------------------------------------------------------------------------ +!BOP +! +! !IROUTINE: which_max +! +! !INTERFACE: +subroutine which_max(arr, maxval, maxindex, lbound) +! +! !DESCRIPTION: +! Returns maximum value in arr along with the index of the maximum value +! +! If multiple values are tied, returns index of the first maximum +! +! !ARGUMENTS: + implicit none + real(r8), intent(in) :: arr(:) + real(r8), intent(out):: maxval ! maximum value in arr(:) + integer , intent(out):: maxindex ! first index of maxval + + ! lower bound of indices of arr; if not supplied, assumed to be 1: + integer , intent(in), optional :: lbound +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +! +! !LOCAL VARIABLES: +!EOP + integer :: i +!----------------------------------------------------------------------- + + maxindex = 1 + maxval = arr(1) + + do i = 2, size(arr) + if (arr(i) > maxval) then + maxindex = i + maxval = arr(i) + end if + end do + + if (present(lbound)) then + maxindex = maxindex + (lbound - 1) + end if +end subroutine which_max +!------------------------------------------------------------------------------ + +end module mkindexmapMod diff --git a/tools/mksurfdata_esmf/src/mklaiMod.F90 b/tools/mksurfdata_esmf/src/mklaiMod.F90 new file mode 100644 index 0000000000..e4b6d9bfa1 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mklaiMod.F90 @@ -0,0 +1,445 @@ +module mklaiMod +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mklai +! +! !DESCRIPTION: +! Make LAI/SAI/height data +! +! !REVISION HISTORY: +! Author: Sam Levis +! +!EOP +!----------------------------------------------------------------------- + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush + use mkdomainMod , only : domain_checksame + use mkvarctl + + implicit none + + private + + public :: mklai + private :: pft_laicheck + +contains + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mklai +! +! !INTERFACE: +subroutine mklai(ldomain, mapfname, datfname, ndiag, ncido) +! +! !DESCRIPTION: +! Make LAI/SAI/height data +! Portions of this code could be moved out of the month loop +! for improved efficiency +! +! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar , only : re + use mkvarctl + use mkncdio + use mkpftConstantsMod, only : c3cropindex, c3irrcropindex +! +! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + integer , intent(in) :: ncido ! output netcdf file id +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Mariana Vertenstein +! +! +! !LOCAL VARIABLES: +!EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + integer :: numpft_i ! number of plant types on input + real(r8) :: glai_o(0:numpft) ! output grid: global area pfts + real(r8) :: gsai_o(0:numpft) ! output grid: global area pfts + real(r8) :: ghgtt_o(0:numpft) ! output grid: global area pfts + real(r8) :: ghgtb_o(0:numpft) ! output grid: global area pfts + real(r8) :: glai_i(0:numpft) ! input grid: global area pfts + real(r8) :: gsai_i(0:numpft) ! input grid: global area pfts + real(r8) :: ghgtt_i(0:numpft) ! input grid: global area pfts + real(r8) :: ghgtb_i(0:numpft) ! input grid: global area pfts + + real(r8), allocatable :: mlai_o(:,:) ! monthly lai + real(r8), allocatable :: msai_o(:,:) ! monthly sai + real(r8), allocatable :: mhgtt_o(:,:) ! monthly height (top) + real(r8), allocatable :: mhgtb_o(:,:) ! monthly height (bottom) + real(r8), allocatable :: mlai_max(:,:) ! monthly lai + real(r8), allocatable :: msai_max(:,:) ! monthly sai + real(r8), allocatable :: mhgtt_max(:,:) ! monthly height (top) + real(r8), allocatable :: mhgtb_max(:,:) ! monthly height (bottom) + real(r8), allocatable :: mlai_i(:,:) ! monthly lai in + real(r8), allocatable :: msai_i(:,:) ! monthly sai in + real(r8), allocatable :: mhgtt_i(:,:) ! monthly height (top) in + real(r8), allocatable :: mhgtb_i(:,:) ! monthly height (bottom) in + real(r8), allocatable :: frac_dst(:) ! output fractions: same as frac_dst + integer, pointer :: laimask(:,:) ! lai+sai output mask for each plant function type + real(r8) :: garea_i ! input grid: global area + real(r8) :: garea_o ! output grid: global area + integer :: mwts ! number of weights + integer :: ni,no,ns_i,ns_o ! indices + integer :: k,l,n,m ! indices + integer :: ncidi,dimid,varid ! input netCDF id's + integer :: ndimsi,ndimso ! netCDF dimension sizes + integer :: dimids(4) ! netCDF dimension ids + integer :: bego(4),leno(4) ! netCDF bounds + integer :: begi(4),leni(4) ! netCDF bounds + integer :: ntim ! number of input time samples + integer :: ier ! error status + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + character(len=256) :: name ! name of attribute + character(len=256) :: unit ! units of attribute + character(len= 32) :: subname = 'mklai' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make LAIs/SAIs/heights .....' + call shr_sys_flush(6) + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read local fields + + ns_o = ldomain%ns + + call domain_read(tdomain,datfname) + ns_i = tdomain%ns + + write (6,*) 'Open LAI file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncidi), subname) + call check_ret(nf_inq_dimid(ncidi, 'pft', dimid), subname) + call check_ret(nf_inq_dimlen(ncidi, dimid, numpft_i), subname) + call check_ret(nf_inq_dimid(ncidi, 'time', dimid), subname) + call check_ret(nf_inq_dimlen(ncidi, dimid, ntim), subname) + + if (numpft_i /= numpft+1) then + write(6,*) 'WARNING: ' // trim(subname) // '(): parameter numpft+1 = ', numpft+1, & + 'does not equal input dataset numpft = ', numpft_i + write(6,*)'This inconsistency used to stop the program. Now we allow it ' + write(6,*)'because crop pfts 17-last are assumed to never use satellite lai data.' +! stop + if (numpft_i > numpft + 1) then + ! NOTE(bja, 2015-01) If this error check is determined to be + ! invalid, all the loop bounds over output data in this + ! routine will need to be double checked! + write(6, *) "ERROR:" // trim(subname) // "(): input numpft must be less than or equal to output numpft+1." + call abort() + end if + endif + if (ntim /= 12) then + write(6,*)'MKLAI: must have 12 time samples on input data' + call abort() + endif + + ! NOTE - close data set at bottom of routine + + ! Dynamic allocation of variables + + allocate(mlai_i(ns_i,0:numpft_i), & + msai_i(ns_i,0:numpft_i), & + mhgtt_i(ns_i,0:numpft_i), & + mhgtb_i(ns_i,0:numpft_i), & + frac_dst(ns_o), & + mlai_o(ns_o,0:numpft), & + msai_o(ns_o,0:numpft), & + mhgtt_o(ns_o,0:numpft), & + mhgtb_o(ns_o,0:numpft), & + laimask(ns_i,0:numpft), stat=ier ) + if (ier /= 0) then + write(6,*)'mklai allocation error'; call abort() + end if + + ! Determine mapping weights and map + + call gridmap_mapread(tgridmap, mapfname) + + ! Error checks for domain and map consistencies + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Determine number of dimensions in input by querying MONTHLY_LAI + + call check_ret(nf_inq_varid(ncidi, 'MONTHLY_LAI', varid), subname) + call check_ret(nf_inq_vardimid(ncidi, varid, dimids), subname) + call check_ret(nf_inq_varndims(ncidi, varid, ndimsi), subname) + if (ndimsi ==4) then + begi(1) = 1 + begi(2) = 1 + begi(3) = 1 + leni(4) = 1 + call check_ret(nf_inq_dimlen(ncidi, dimids(1), leni(1)), subname) + call check_ret(nf_inq_dimlen(ncidi, dimids(2), leni(2)), subname) + call check_ret(nf_inq_dimlen(ncidi, dimids(3), leni(3)), subname) + else if (ndimsi== 3) then + begi(1) = 1 + begi(2) = 1 + leni(3) = 1 + call check_ret(nf_inq_dimlen(ncidi, dimids(1), leni(1)), subname) + call check_ret(nf_inq_dimlen(ncidi, dimids(2), leni(2)), subname) + end if + + ! Determine number of dimensions in output by querying MONTHLY_LAI + + call check_ret(nf_inq_varid(ncido, 'MONTHLY_LAI', varid), subname) + call check_ret(nf_inq_varndims(ncido, varid, ndimso), subname) + call check_ret(nf_inq_vardimid(ncido, varid, dimids), subname) + if (ndimso ==4) then + bego(1) = 1 + bego(2) = 1 + bego(3) = 1 + leno(4) = 1 + call check_ret(nf_inq_dimlen(ncido, dimids(1), leno(1)), subname) + call check_ret(nf_inq_dimlen(ncido, dimids(2), leno(2)), subname) + call check_ret(nf_inq_dimlen(ncido, dimids(3), leno(3)), subname) + else if (ndimso== 3) then + bego(1) = 1 + bego(2) = 1 + leno(3) = 1 + call check_ret(nf_inq_dimlen(ncido, dimids(1), leno(1)), subname) + call check_ret(nf_inq_dimlen(ncido, dimids(2), leno(2)), subname) + end if + + ! Loop over months + + do m = 1, ntim + + if (ndimsi == 4) begi(4)=m + if (ndimsi == 3) begi(3)=m + + call check_ret(nf_inq_varid (ncidi, 'MONTHLY_LAI', varid), subname) + call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & + mlai_i), subname) + + call check_ret(nf_inq_varid (ncidi, 'MONTHLY_SAI', varid), subname) + call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & + msai_i), subname) + + call check_ret(nf_inq_varid (ncidi, 'MONTHLY_HEIGHT_TOP', varid), subname) + call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & + mhgtt_i), subname) + + call check_ret(nf_inq_varid (ncidi, 'MONTHLY_HEIGHT_BOT', varid), subname) + call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & + mhgtb_i), subname) + + mlai_o(:,:) = 0. + msai_o(:,:) = 0. + mhgtt_o(:,:) = 0. + mhgtb_o(:,:) = 0. + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Loop over pft types to do mapping + do l = 0, numpft_i - 1 + call gridmap_areaave_srcmask(tgridmap, mlai_i(:,l) , mlai_o(:,l) , nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, msai_i(:,l) , msai_o(:,l) , nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, mhgtt_i(:,l), mhgtt_o(:,l), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, mhgtb_i(:,l), mhgtb_o(:,l), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + enddo + + ! Determine laimask + + laimask(:,:) = 0 + + ! copy LAI, SAI, & heights from the C3 crop (pft15) + ! to the irrigated (pft16) whether crop is on or off + mlai_o(:,c3irrcropindex) = mlai_o(:,c3cropindex) + msai_o(:,c3irrcropindex) = msai_o(:,c3cropindex) + mhgtt_o(:,c3irrcropindex) = mhgtt_o(:,c3cropindex) + mhgtb_o(:,c3irrcropindex) = mhgtb_o(:,c3cropindex) + + ! ----------------------------------------------------------------- + ! Output model resolution LAI/SAI/HEIGHT data + ! ----------------------------------------------------------------- + + ! Now write out all variables + + if (ndimso == 4) bego(4)=m + if (ndimso == 3) bego(3)=m + + call check_ret(nf_inq_varid(ncido, 'MONTHLY_LAI', varid), subname) + call check_ret(nf_put_vara_double(ncido, varid, bego, leno, mlai_o), subname) + + call check_ret(nf_inq_varid(ncido, 'MONTHLY_SAI', varid), subname) + call check_ret(nf_put_vara_double(ncido, varid, bego, leno, msai_o), subname) + + call check_ret(nf_inq_varid(ncido, 'MONTHLY_HEIGHT_TOP', varid), subname) + call check_ret(nf_put_vara_double(ncido, varid, bego, leno, mhgtt_o), subname) + + call check_ret(nf_inq_varid(ncido, 'MONTHLY_HEIGHT_BOT', varid), subname) + call check_ret(nf_put_vara_double(ncido, varid, bego, leno, mhgtb_o), subname) + + call check_ret(nf_inq_varid(ncido, 'time', varid), subname) + call check_ret(nf_put_vara_int(ncido, varid, bego(ndimso), leno(ndimso), m), subname) + + call check_ret(nf_sync(ncido), subname) + + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global areas on input and output grids + ! ----------------------------------------------------------------- + + ! Input grid global area + + garea_i = 0. + do ni = 1,ns_i + garea_i = garea_i + tgridmap%area_src(ni) + end do + + glai_i(:) = 0. + gsai_i(:) = 0. + ghgtt_i(:) = 0. + ghgtb_i(:) = 0. + do l = 0, numpft_i - 1 + do ni = 1, ns_i + glai_i(l) = glai_i(l) + mlai_i(ni,l) *tgridmap%area_src(ni)*& + tdomain%mask(ni)*re**2 + gsai_i(l) = gsai_i(l) + msai_i(ni,l) *tgridmap%area_src(ni)*& + tdomain%mask(ni)*re**2 + ghgtt_i(l) = ghgtt_i(l)+ mhgtt_i(ni,l)*tgridmap%area_src(ni)*& + tdomain%mask(ni)*re**2 + ghgtb_i(l) = ghgtb_i(l)+ mhgtb_i(ni,l)*tgridmap%area_src(ni)*& + tdomain%mask(ni)*re**2 + end do + end do + + ! Output grid global area + + garea_o = 0. + do no = 1,ns_o + garea_o = garea_o + tgridmap%area_dst(no) + end do + + glai_o(:) = 0. + gsai_o(:) = 0. + ghgtt_o(:) = 0. + ghgtb_o(:) = 0. + do l = 0, numpft_i - 1 + do no = 1,ns_o + glai_o(l) = glai_o(l) + mlai_o(no,l)*tgridmap%area_dst(no)* & + frac_dst(no)*re**2 + gsai_o(l) = gsai_o(l) + msai_o(no,l)*tgridmap%area_dst(no)* & + frac_dst(no)*re**2 + ghgtt_o(l) = ghgtt_o(l)+ mhgtt_o(no,l)*tgridmap%area_dst(no)* & + frac_dst(no)*re**2 + ghgtb_o(l) = ghgtb_o(l)+ mhgtb_o(no,l)*tgridmap%area_dst(no)* & + frac_dst(no)*re**2 + end do + end do + + ! Comparison + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'LAI Output for month ',m + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,1001) +1001 format (1x,'PFT input grid area output grid area',/ & + 1x,3x,' 10**6 km**2',' 10**6 km**2') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + do l = 0, numpft + write (ndiag,1002) l, glai_i(l)*1.e-06*1.e-02,glai_o(l)*1.e-06*1.e-02 +1002 format (1x,i3,f16.3,f17.3) + end do + + write (6,*) 'Successfully made LAIs/SAIs/heights for month ', m + call shr_sys_flush(6) + + enddo + write (6,*) + + ! Close input file + call check_ret(nf_close(ncidi), subname) + + ! consistency check that PFT and LAI+SAI make sense + !call pft_laicheck( ni_s, pft_i, laimask ) + + ! Deallocate dynamic memory + deallocate(mlai_i) + deallocate(msai_i) + deallocate(mhgtt_i) + deallocate(mhgtb_i) + deallocate(mlai_o) + deallocate(msai_o) + deallocate(mhgtt_o) + deallocate(mhgtb_o) + deallocate(laimask) + deallocate(frac_dst) + + call gridmap_clean(tgridmap) + call domain_clean(tdomain) + +end subroutine mklai + +!----------------------------------------------------------------------- +!BOP +! +! !INTERFACE: +subroutine pft_laicheck( ni_s, pctpft_i, laimask ) + +! !USES: +! +! !DESCRIPTION: +! +! consistency check that PFT and LAI+SAI make sense +! +! !ARGUMENTS: + implicit none + integer , intent(in) :: ni_s ! input PFT grid resolution + real(r8), pointer :: pctpft_i(:,:) ! % plant function types + integer, pointer :: laimask(:,:) ! mask where LAI+SAI > 0 +!EOP + + character(len=*), parameter :: subName="pft_laicheck" + integer :: ni,l,n,nc ! Indices +!----------------------------------------------------------------------- + + do l = 0, numpft + n = 0 + nc = 0 + do ni = 1,ni_s + if ( pctpft_i(ni,l) > 0.0_r8 ) nc = nc + 1 + if ( (pctpft_i(ni,l) > 0.0_r8) .and. (laimask(ni,l) /= 1) )then + write (6,*) subName//' :: warning: pft and LAI+SAI mask not consistent!' + write (6,*) 'ni,l = ', ni, l + write (6,*) 'pctpft_i = ',pctpft_i(ni,l) + write (6,*) 'laimask = ', laimask(ni,l) + n = n + 1 + end if + end do + if ( n > max(4,nc/4) ) then + write (6,*) subName//' :: pft/LAI+SAI inconsistency over more than 25% land-cover' + write (6,*) '# inconsistent points, total PFT pts, total LAI+SAI pts = ', & + n, nc, sum(laimask(:,l)) + call abort() + end if + end do + +end subroutine pft_laicheck + +!----------------------------------------------------------------------- + +end module mklaiMod diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 new file mode 100644 index 0000000000..8f7c59056c --- /dev/null +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -0,0 +1,288 @@ +module mklanwatMod + + !----------------------------------------------------------------------- + ! make %lake and %wetland from input lake / wetland data + ! also make lake parameters + !----------------------------------------------------------------------- + + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkvarpar , only : re + use mkesmfMod , only : regrid_data + use mkutilsMod , only : chkerr + use mkvarctl , only : root_task, ndiag + + implicit none + private + + public mklakwat ! make % lake + public mkwetlnd ! make % wetland + public mklakparams ! make lake parameters + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + +!=============================================================== +contains +!=============================================================== + + subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, zero_out, lake_o, rc) + + ! ------------------- + ! make %lake + ! ------------------- + + ! input/output variables + type(ESMF_Mesh) , intent(in) :: mesh_o + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + logical , intent(in) :: zero_out ! if should zero glacier out + real(r8) , intent(out) :: lake_o(:) ! output grid: %lake + integer , intent(out) :: rc + + ! local variables + type(ESMF_Mesh) :: mesh_i + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + real(r8), allocatable :: lake_i(:) ! input grid: percent lake + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: glake_i ! input grid: global lake + real(r8) :: garea_i ! input grid: global area + real(r8) :: glake_o ! output grid: global lake + real(r8) :: garea_o ! output grid: global area + integer :: ni,no,ns_i,ns_o,k ! indices + integer :: rcode ! error status + character(len=32) :: subname = 'mklakwat' + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (root_task) then + write (ndiag,*) 'Attempting to make %lake .....' + end if + + ! Initialize lake_o to 0 + ns_o = size(lake_o) + do no = 1,ns_o + lake_o(no) = 0. + enddo + + if ( .not. zero_out ) then + + ! create field on input mesh (first read in input mesh) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(lake_i(ns_i), stat=rcode) + if (rcode/=0) call shr_sys_abort() + + ! create field on model mesh + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! regrid lake_i to lake_o - this also returns lake_i to be used in the global sums below + call regrid_data(field_i, field_o, 'PCT_LAKE', trim(file_data_i), lake_i, lake_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do no = 1,size(lake_o) + if (lake_o(no) < 1.) lake_o(no) = 0. + enddo + + ! ----------------------------------------------------------------- + ! Error check prep + ! Global sum of output field -- must multiply by fraction of + ! output grid that is land as determined by input grid + ! ----------------------------------------------------------------- + ! TODO: not sure if we still want this with the ESMF regridding + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global areas on input and output grids + ! ----------------------------------------------------------------- + ! TODO: implement this + ! ! Input grid + + deallocate (lake_i) + ! TODO: destroy route handle and created field + end if + + if (root_task) then + write (ndiag,*) 'Successfully made %lake' + write (ndiag,*) + end if + + end subroutine mklakwat + + !=============================================================== + subroutine mkwetlnd(file_mesh_i, file_data_i, mesh_o, zero_out, swmp_o, rc) + + ! ------------------- + ! make %wetland + ! ------------------- + + ! input/output variables + type(ESMF_Mesh) , intent(in) :: mesh_o + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + logical , intent(in) :: zero_out ! if should zero glacier out + real(r8) , intent(out) :: swmp_o(:) ! output grid: %lake + integer , intent(out) :: rc + + ! local variables + type(ESMF_Mesh) :: mesh_i + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + real(r8), allocatable :: swmp_i(:) ! input grid: percent lake + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: glake_i ! input grid: global lake + real(r8) :: garea_i ! input grid: global area + real(r8) :: glake_o ! output grid: global lake + real(r8) :: garea_o ! output grid: global area + integer :: ni,no,ns_i,ns_o,k ! indices + integer :: rcode ! error status + character(len=32) :: subname = 'mkwtlnd' + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (root_task) then + write (ndiag,*) 'Attempting to make %wetland .....' + end if + + ! Initialize swmp_o to 0 + ns_o = size(swmp_o) + do no = 1,ns_o + swmp_o(no) = 0. + enddo + + if ( .not. zero_out ) then + + ! create field on input mesh (first read in input mesh) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(swmp_i(ns_i), stat=rcode) + if (rcode/=0) call shr_sys_abort() + + ! create field on model mesh + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! regrid swmp_i to swmp_o - this also returns swmp_i to be used in the global sums below + call regrid_data(field_i, field_o, 'PCT_WETLAND', trim(file_data_i), swmp_i, swmp_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do no = 1,ns_o + if (swmp_o(no) < 1.) swmp_o(no) = 0. + enddo + + ! ----------------------------------------------------------------- + ! Error check prep + ! Global sum of output field -- must multiply by fraction of + ! output grid that is land as determined by input grid + ! ----------------------------------------------------------------- + ! TODO: not sure if we still want this with the ESMF regridding + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global areas on input and output grids + ! ----------------------------------------------------------------- + ! TODO: implememt this + + deallocate (swmp_i) + ! TODO: destroy route handle and created field + + end if + + if (root_task) then + write (ndiag,*) 'Successfully made %wetland' + write (ndiag,*) + end if + + end subroutine mkwetlnd + + !=============================================================== + + subroutine mklakparams(file_mesh_i, file_data_i, mesh_o, lakedepth_o, rc) + + ! ------------------- + ! make lake parameters (currently just lake depth) + ! ------------------- + + !use mkdiagnosticsMod , only : output_diagnostics_continuous + use mkchecksMod , only : min_bad + + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o + real(r8) , intent(out) :: lakedepth_o(:) ! output grid: lake depth (m) + integer , intent(out) :: rc + + ! local variables + type(ESMF_Mesh) :: mesh_i + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + real(r8), allocatable :: lakedepth_i(:) ! input raw data + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: glake_i ! input grid: global lake + real(r8) :: garea_i ! input grid: global area + real(r8) :: glake_o ! output grid: global lake + real(r8) :: garea_o ! output grid: global area + integer :: ni,no,ns_i,ns_o,k ! indices + integer :: rcode ! error status + real(r8), parameter :: min_valid_lakedepth = 0._r8 + character(len=32) :: subname = 'mklakparams' + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (root_task) then + write (ndiag,*) 'Attempting to make lake parameters.....' + end if + + ! create field on input mesh (first read in input mesh) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(lakedepth_i(ns_i), stat=rcode) + if (rcode/=0) call shr_sys_abort() + + ! create field on model mesh + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! regrid lakedepth_i to lakedepth_o - this also returns lakedepth_i to be used in the global sums below + call regrid_data(field_i, field_o, 'LAKEDEPTH', trim(file_data_i), lakedepth_i, lakedepth_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Check validity of output data + if (min_bad(lakedepth_o, min_valid_lakedepth, 'lakedepth')) then + call shr_sys_abort() + end if + + ! TODO: implement the following + !call output_diagnostics_continuous(data_i, lakedepth_o, tgridmap, "Lake Depth", "m", ndiag, tdomain%mask, frac_dst) + + deallocate (lakedepth_i) + + if (root_task) then + write (ndiag,*) 'Successfully made lake parameters' + write (ndiag,*) + end if + + end subroutine mklakparams + +end module mklanwatMod diff --git a/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 b/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 new file mode 100644 index 0000000000..8c2c9b7c53 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 @@ -0,0 +1,626 @@ +module mkpctPftTypeMod + + !----------------------------------------------------------------------- + !BOP + ! + ! !MODULE: mkpctPftType + ! + ! !DESCRIPTION: + ! Derived type and associated methods for operating on pct_pft data + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! + !----------------------------------------------------------------------- + + !!USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + + implicit none + private + + ! !PUBLIC TYPES + public :: pct_pft_type + + type :: pct_pft_type + private + real(r8), allocatable :: pct_p2l(:) ! pct of each pft on the landunit + real(r8) :: pct_l2g ! pct of landunit on the grid cell + contains + ! Public routines: + ! Query routines: + procedure :: get_pct_p2l ! get an array holding % of each pft on the landunit + procedure :: get_pct_p2g ! get an array holding % of each pft on the gridcell + procedure :: get_pct_l2g ! get % of landunit on the grid cell + procedure :: get_first_pft_index ! get index of the first pft (lower bound of arrays) + procedure :: get_one_pct_p2g ! get % of gridcell for a single pft + ! Routines that modify the data: + procedure :: set_pct_l2g ! set % of landunit on the grid cell + procedure :: set_one_pct_p2g ! set % pft for a single pft + procedure :: merge_pfts ! merge all area from one PFT into another PFT + procedure :: remove_small_cover ! set % cover to 0 for any PFT whose grid cell coverage is less than a threshold + + ! Private routines: + procedure, private :: convert_from_p2g ! convert a p2g array into p2l and l2g + procedure, private :: check_vals ! perform a sanity check after setting values + end type pct_pft_type + + ! !PUBLIC MEMBER FUNCTIONS + public :: update_max_array ! given an array of pct_pft_type variables update the max_p2l values from pct_p2l + public :: get_pct_p2l_array ! given an array of pct_pft_type variables, return a 2-d array of pct_p2l + public :: get_pct_l2g_array ! given an array of pct_pft_type variables, return an array of pct_l2g + + interface pct_pft_type + module procedure constructor ! initialize a new pct_pft_type object + module procedure constructor_pong ! initialize a new pct_pft_type object with all PFT's on the gridcell + module procedure constructor_empty ! initialize a new pct_pft_type object for an empty landunit + end interface pct_pft_type + + ! !PRIVATE TYPES: + real(r8), parameter :: tol = 1.e-12_r8 ! tolerance for checking equality + + !EOP + +contains + + ! ======================================================================== + ! Constructors + ! ======================================================================== + + !----------------------------------------------------------------------- + function constructor_pong(pct_p2g, first_pft_index, default_pct_p2l) result(this) + ! + ! !DESCRIPTION: + ! Given the % of each pft on the grid cell, create a pct_pft_type object. + ! + ! Note that pct_p2g should just contain the pfts in this landunit. + ! + ! If all PFTs have 0 weight on the grid cell, we arbitrarily set % of each pft on the + ! landunit based on default_pct_p2l. Note that: + ! (1) size of default_pct_p2l must match size of pct_p2g + ! (2) default_pct_p2l must sum to 100% + ! + ! !ARGUMENTS: + type(pct_pft_type) :: this ! function result + + real(r8), intent(in) :: pct_p2g(:) ! % of each pft on the grid cell + integer , intent(in) :: first_pft_index ! index of the first pft (lower bound of arrays) + real(r8), intent(in) :: default_pct_p2l(:) ! default % of each pft on the landunit, used if total landunit area is 0% + ! + ! !LOCAL VARIABLES: + integer :: last_pft_index + + character(len=*), parameter :: subname = 'constructor_pong' + !----------------------------------------------------------------------- + + if (size(default_pct_p2l) /= size(pct_p2g)) then + write(6,*) subname//' ERROR: size of default_pct_p2l must match size of pct_p2g' + call abort() + end if + + last_pft_index = first_pft_index + size(pct_p2g) - 1 + allocate(this%pct_p2l(first_pft_index : last_pft_index)) + call this%convert_from_p2g(pct_p2g, default_pct_p2l) + + end function constructor_pong + + !----------------------------------------------------------------------- + function constructor(pct_p2l, pct_l2g, first_pft_index) result(this) + ! + ! !DESCRIPTION: + ! Given the % of each pft on the land cell and % of land unit on grid cell, + ! create a pct_pft_type object. + ! + ! Note that pct_p2g should just contain the pfts in this landunit. + ! + ! !ARGUMENTS: + type(pct_pft_type) :: this ! function result + + real(r8), intent(in) :: pct_p2l(:) ! % of each pft on the landunit + real(r8), intent(in) :: pct_l2g ! % of the landunit on the grid cell + integer , intent(in) :: first_pft_index ! index of the first pft (lower bound of arrays) + ! + ! !LOCAL VARIABLES: + integer :: last_pft_index + + character(len=*), parameter :: subname = 'constructor' + !----------------------------------------------------------------------- + + last_pft_index = first_pft_index + size(pct_p2l) - 1 + allocate(this%pct_p2l(first_pft_index : last_pft_index)) + this%pct_p2l = pct_p2l + this%pct_l2g = pct_l2g + + end function constructor + + !----------------------------------------------------------------------- + function constructor_empty() result(this) + ! + ! !DESCRIPTION: + ! Initialize a new pct_pft_type object for an empty landunit - that is, one that has + ! no PFTs on it, and never can (e.g., the crop landunit when we're running without + ! prognostic crops, so that the landunit is always empty). + ! + ! !ARGUMENTS: + type(pct_pft_type) :: this ! function result + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'constructor_empty' + !----------------------------------------------------------------------- + + this%pct_l2g = 0._r8 + allocate(this%pct_p2l(0)) + + end function constructor_empty + + + + ! ======================================================================== + ! Public member functions + ! ======================================================================== + + !----------------------------------------------------------------------- + function get_pct_p2l(this) result(pct_p2l) + ! + ! !DESCRIPTION: + ! Get an array holding % of each pft on the landunit + ! + ! !ARGUMENTS: + class(pct_pft_type), intent(in) :: this + real(r8) :: pct_p2l(size(this%pct_p2l)) ! function result + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'get_pct_p2l' + !----------------------------------------------------------------------- + + pct_p2l = this%pct_p2l + + end function get_pct_p2l + + !----------------------------------------------------------------------- + function get_pct_p2g(this) result(pct_p2g) + ! + ! !DESCRIPTION: + ! Get an array holding % of each pft on the gridcell + ! + ! !ARGUMENTS: + class(pct_pft_type), intent(in) :: this + real(r8) :: pct_p2g(size(this%pct_p2l)) ! function result + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'get_pct_p2g' + !----------------------------------------------------------------------- + + pct_p2g(:) = this%pct_p2l(:) * this%pct_l2g / 100._r8 + + end function get_pct_p2g + + !----------------------------------------------------------------------- + function get_pct_l2g(this) result(pct_l2g) + ! + ! !DESCRIPTION: + ! Get % of landunit on the grid cell + ! + ! !ARGUMENTS: + real(r8) :: pct_l2g ! function result + class(pct_pft_type), intent(in) :: this + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'get_pct_l2g' + !----------------------------------------------------------------------- + + pct_l2g = this%pct_l2g + + end function get_pct_l2g + + !----------------------------------------------------------------------- + function get_first_pft_index(this) result(first_pft_index) + ! + ! !DESCRIPTION: + ! Get index of the first pft (lower bound of arrays) + ! + ! !ARGUMENTS: + integer :: first_pft_index ! function result + class(pct_pft_type), intent(in) :: this + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'get_first_pft_index' + !----------------------------------------------------------------------- + + first_pft_index = lbound(this%pct_p2l, 1) + + end function get_first_pft_index + + !----------------------------------------------------------------------- + function get_one_pct_p2g(this, pft_index) result(pct_p2g) + ! + ! !DESCRIPTION: + ! Get % of gridcell for a single pft + ! + ! !ARGUMENTS: + real(r8) :: pct_p2g ! function result + class(pct_pft_type), intent(in) :: this + integer :: pft_index + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'get_one_pct_p2g' + !----------------------------------------------------------------------- + + pct_p2g = this%pct_p2l(pft_index) * this%pct_l2g / 100._r8 + + end function get_one_pct_p2g + + !----------------------------------------------------------------------- + subroutine set_pct_l2g(this, pct_l2g_new) + ! + ! !DESCRIPTION: + ! Set percent of landunit on the grid cell. Keep pct_p2l the same as before. + ! + ! !ARGUMENTS: + class(pct_pft_type), intent(inout) :: this + real(r8), intent(in) :: pct_l2g_new ! new percent of this landunit with respect to grid cell + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'set_pct_l2g' + !----------------------------------------------------------------------- + + if (pct_l2g_new < 0._r8 .or. pct_l2g_new > (100._r8 + tol)) then + write(6,*) subname//' ERROR: pct_l2g_new must be between 0 and 100%' + write(6,*) 'pct_l2g_new = ', pct_l2g_new + call abort() + end if + + this%pct_l2g = pct_l2g_new + + end subroutine set_pct_l2g + + !----------------------------------------------------------------------- + subroutine set_one_pct_p2g(this, pft_index, pct_p2g_new) + ! + ! !DESCRIPTION: + ! Set percent pft for a single pft, given its weight on the grid cell. + ! + ! The landunit percent is adjusted appropriately. In addition, the coverage of other + ! PFTs are adjusted proportionally so that the total pct_pft adds to 100%. + ! + ! If the resulting total weight on the grid cell is reduced to 0, then pct_p2l + ! remains as it was before this subroutine call. + ! + ! Note about pft_index: Note that the first element of the array has index given by + ! the first_pft_index value given to the constructor. + ! + ! !ARGUMENTS: + class(pct_pft_type), intent(inout) :: this + integer , intent(in) :: pft_index ! index of the pft to change + real(r8), intent(in) :: pct_p2g_new ! new percent of this pft, with respect to grid cell + ! + ! !LOCAL VARIABLES: + real(r8), allocatable :: pct_p2g(:) ! % of each pft on the grid cell + + character(len=*), parameter :: subname = 'set_pct_p2g' + !----------------------------------------------------------------------- + + if (pct_p2g_new < 0._r8 .or. pct_p2g_new > (100._r8 + tol)) then + write(6,*) subname//' ERROR: pct_p2g_new must be between 0 and 100%' + write(6,*) 'pct_p2g_new = ', pct_p2g_new + call abort() + end if + + allocate(pct_p2g(lbound(this%pct_p2l, 1) : ubound(this%pct_p2l, 1))) + pct_p2g(:) = this%get_pct_p2g() + pct_p2g(pft_index) = pct_p2g_new + + ! Note that by using this%pct_p2l as the default_pct_pl2 argument, we ensure that, if + ! the new p2g value brings the total % on the grid cell to 0, then we keep the + ! previous values for pct_p2l + call this%convert_from_p2g(pct_p2g, this%pct_p2l) + + deallocate(pct_p2g) + + end subroutine set_one_pct_p2g + + !----------------------------------------------------------------------- + subroutine merge_pfts(this, source, dest) + ! + ! !DESCRIPTION: + ! Merge all area from one PFT into another PFT + ! + ! !ARGUMENTS: + class(pct_pft_type), intent(inout) :: this + integer, intent(in) :: source ! index of source PFT + integer, intent(in) :: dest ! index of dest PFT + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'merge_pfts' + !----------------------------------------------------------------------- + + this%pct_p2l(dest) = this%pct_p2l(dest) + this%pct_p2l(source) + this%pct_p2l(source) = 0._r8 + + call this%check_vals(subname) + + end subroutine merge_pfts + + !----------------------------------------------------------------------- + subroutine remove_small_cover(this, too_small, nsmall) + ! + ! !DESCRIPTION: + ! Remove any small PFTs, defined as those whose grid cell coverage is below some + ! threshold. Also returns the number of small PFTs found. + ! + ! !USES: + ! + ! !ARGUMENTS: + class(pct_pft_type), intent(inout) :: this + real(r8), intent(in) :: too_small ! threshold for considering a PFT too small (% of grid cell) + integer , intent(out) :: nsmall ! number of small (but non-zero) PFTs found + ! + ! !LOCAL VARIABLES: + integer :: pft_lbound + integer :: pft_ubound + integer :: pft_index + real(r8), allocatable :: pct_p2g(:) ! % of each pft on the grid cell + logical , allocatable :: is_small(:) ! whether each PFT is considered too small (but not 0) + logical , allocatable :: is_zero(:) ! whether each PFT is exactly 0 + + character(len=*), parameter :: subname = 'remove_small_cover' + !----------------------------------------------------------------------- + + pft_lbound = lbound(this%pct_p2l, 1) + pft_ubound = ubound(this%pct_p2l, 1) + allocate(pct_p2g (pft_lbound : pft_ubound)) + allocate(is_small(pft_lbound : pft_ubound)) + allocate(is_zero (pft_lbound : pft_ubound)) + + pct_p2g(:) = this%get_pct_p2g() + is_zero(:) = (pct_p2g == 0._r8) + is_small(:) = (pct_p2g < too_small .and. .not. is_zero(:)) + + nsmall = count(is_small(:)) + + if (nsmall > 0) then + + if (all(is_zero(:) .or. is_small(:))) then + ! If all PFTs are either 0 or small, then set pct_l2g to 0, but don't touch + ! pct_p2l(:) (We do NOT set pct_p2l to all 0 in this case, because we need to + ! maintain sum(pct_p2l) = 100%) + this%pct_l2g = 0._r8 + + else + ! If there are some big PFTs, then we need to adjust pct_p2l as well as pct_l2g + ! (setting pct_p2l to 0 for the small elements and renormalizing the others) + do pft_index = pft_lbound, pft_ubound + if (is_small(pft_index)) then + call this%set_one_pct_p2g(pft_index, 0._r8) + end if + end do + end if + + call this%check_vals(subname) + end if + + deallocate(pct_p2g, is_small, is_zero) + end subroutine remove_small_cover + + ! ======================================================================== + ! Private member functions + ! ======================================================================== + + !----------------------------------------------------------------------- + subroutine convert_from_p2g(this, pct_p2g, default_pct_p2l) + ! + ! !DESCRIPTION: + ! Given a p2g array, compute the p2l array and l2g + ! + ! !ARGUMENTS: + class(pct_pft_type), intent(inout) :: this + real(r8), intent(in) :: pct_p2g(:) ! % of each pft on the grid cell + real(r8), intent(in) :: default_pct_p2l(:) ! default % of each pft on the landunit, used if total landunit area is 0% + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'convert_from_p2g' + !----------------------------------------------------------------------- + + ! Check pre-conditions + + if (size(pct_p2g) /= size(this%pct_p2l) .or. size(default_pct_p2l) /= size(this%pct_p2l)) then + write(6,*) subname//' ERROR: array size mismatch: ' + write(6,*) size(pct_p2g), size(default_pct_p2l), size(this%pct_p2l) + call abort() + end if + + if (abs(sum(default_pct_p2l) - 100._r8) > tol) then + write(6,*) subname//' ERROR: default_pct_p2l must sum to 100' + call abort() + end if + + if (any(pct_p2g < 0._r8)) then + write(6,*) subname//' ERROR: negative values found in pct_p2g array' + write(6,*) pct_p2g + call abort() + end if + + if (sum(pct_p2g) < 0._r8 .or. sum(pct_p2g) > (100._r8 + tol)) then + write(6,*) subname//' ERROR: pct_p2g must be between 0 and 100' + write(6,*) 'sum(pct_p2g) = ', sum(pct_p2g) + call abort() + end if + + ! Done checking pre-conditions + + this%pct_l2g = sum(pct_p2g) + if (this%pct_l2g > 0._r8) then + this%pct_p2l = pct_p2g / this%pct_l2g * 100._r8 + else + this%pct_p2l = default_pct_p2l + end if + + ! Check post-conditions + + call this%check_vals(subname) + + end subroutine convert_from_p2g + + + !----------------------------------------------------------------------- + subroutine check_vals(this, caller) + ! + ! !DESCRIPTION: + ! Perform a sanity check after setting values + ! + ! !ARGUMENTS: + class(pct_pft_type), intent(in) :: this + character(len=*), intent(in) :: caller ! name of the calling subroutine + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'check_vals' + !----------------------------------------------------------------------- + + if (abs(sum(this%pct_p2l) - 100._r8) > tol) then + write(6,*) subname//' ERROR from ', caller, ': pct_p2l does not sum to 100' + write(6,*) 'sum(this%pct_p2l) = ', sum(this%pct_p2l) + call abort() + end if + + if (any(this%pct_p2l < 0._r8)) then + write(6,*) subname//' ERROR from ', caller, ': negative values found in pct_p2l' + write(6,*) this%pct_p2l + call abort() + end if + + if (this%pct_l2g < 0._r8 .or. this%pct_l2g > (100._r8 + tol)) then + write(6,*) subname//' ERROR from ', caller, ': pct_l2g must be between 0 and 100' + write(6,*) 'pct_l2g = ', this%pct_l2g + call abort() + end if + + end subroutine check_vals + + ! ======================================================================== + ! Module-level routines (not member functions) + ! ======================================================================== + + !----------------------------------------------------------------------- + subroutine update_max_array(pct_pft_max_arr,pct_pft_arr) + ! + ! !DESCRIPTION: + ! Given an array of pct_pft_type variables, update all the max_p2l variables. + ! + ! Assumes that all elements of pct_pft_max_arr and pct_pft_arr have the same + ! size and lower bound for their pct_p2l array. + ! + ! !ARGUMENTS: + ! workaround for gfortran bug (58043): declare this 'type' rather than 'class': + type(pct_pft_type), intent(inout) :: pct_pft_max_arr(:) + type(pct_pft_type), intent(in) :: pct_pft_arr(:) + ! + ! !LOCAL VARIABLES: + integer :: pft_lbound + integer :: pft_ubound + integer :: arr_index + integer :: pft_index + + character(len=*), parameter :: subname = 'update_max_array' + !----------------------------------------------------------------------- + + + pft_lbound = lbound(pct_pft_arr(1)%pct_p2l, 1) + pft_ubound = ubound(pct_pft_arr(1)%pct_p2l, 1) + + do arr_index = 1, size(pct_pft_arr) + if (lbound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_lbound .or. & + ubound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_ubound) then + write(6,*) subname//' ERROR: all elements of pct_pft_arr must have' + write(6,*) 'the same size and lower bound for their pct_p2l array' + call abort() + end if + + if (pct_pft_arr(arr_index)%pct_l2g > pct_pft_max_arr(arr_index)%pct_l2g) then + pct_pft_max_arr(arr_index)%pct_l2g = pct_pft_arr(arr_index)%pct_l2g + end if + + do pft_index = pft_lbound, pft_ubound + if (pct_pft_arr(arr_index)%pct_p2l(pft_index) > pct_pft_max_arr(arr_index)%pct_p2l(pft_index)) then + pct_pft_max_arr(arr_index)%pct_p2l(pft_index) = pct_pft_arr(arr_index)%pct_p2l(pft_index) + end if + end do + end do + + end subroutine update_max_array + + !----------------------------------------------------------------------- + function get_pct_p2l_array(pct_pft_arr) result(pct_p2l) + ! + ! !DESCRIPTION: + ! Given an array of pct_pft_type variables, return a 2-d array of pct_p2l. + ! + ! Assumes that all elements of pct_pft_arr have the same size and lower bound for + ! their pct_p2l array. + ! + ! !ARGUMENTS: + real(r8), allocatable :: pct_p2l(:,:) ! function result (n_elements, n_pfts) + ! workaround for gfortran bug (58043): declare this 'type' rather than 'class': + type(pct_pft_type), intent(in) :: pct_pft_arr(:) + ! + ! !LOCAL VARIABLES: + integer :: pft_lbound + integer :: pft_ubound + integer :: arr_index + integer :: pft_index + + character(len=*), parameter :: subname = 'get_pct_p2l_array' + !----------------------------------------------------------------------- + + pft_lbound = lbound(pct_pft_arr(1)%pct_p2l, 1) + pft_ubound = ubound(pct_pft_arr(1)%pct_p2l, 1) + + allocate(pct_p2l(size(pct_pft_arr), pft_lbound:pft_ubound)) + + do arr_index = 1, size(pct_pft_arr) + if (lbound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_lbound .or. & + ubound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_ubound) then + write(6,*) subname//' ERROR: all elements of pct_pft_arr must have' + write(6,*) 'the same size and lower bound for their pct_p2l array' + call abort() + end if + + do pft_index = pft_lbound, pft_ubound + pct_p2l(arr_index, pft_index) = pct_pft_arr(arr_index)%pct_p2l(pft_index) + end do + end do + + end function get_pct_p2l_array + + !----------------------------------------------------------------------- + function get_pct_l2g_array(pct_pft_arr) result(pct_l2g) + ! + ! !DESCRIPTION: + ! Given an array of pct_pft_type variables, return an array of pct_l2g. + ! + ! !ARGUMENTS: + real(r8), allocatable :: pct_l2g(:) ! function result + class(pct_pft_type), intent(in) :: pct_pft_arr(:) + ! + ! !LOCAL VARIABLES: + integer :: arr_index + + character(len=*), parameter :: subname = 'get_pct_l2g_array' + !----------------------------------------------------------------------- + + allocate(pct_l2g(size(pct_pft_arr))) + pct_l2g = pct_pft_arr(:)%pct_l2g + + end function get_pct_l2g_array + + +end module mkpctPftTypeMod diff --git a/tools/mksurfdata_esmf/src/mkpeatMod.F90 b/tools/mksurfdata_esmf/src/mkpeatMod.F90 new file mode 100644 index 0000000000..8e47f5032d --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkpeatMod.F90 @@ -0,0 +1,149 @@ +module mkpeatMod + +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mkpeatMod +! +! !DESCRIPTION: +! make fraction peat from input peat data +! +! !REVISION HISTORY: +! Author: Sam Levis and Bill Sacks +! +!----------------------------------------------------------------------- +! +! !USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush + use mkdomainMod , only : domain_checksame + + implicit none + + private + +! !PUBLIC MEMBER FUNCTIONS: + public mkpeat ! regrid peat data +! +!EOP +!=============================================================== +contains +!=============================================================== + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkpeat +! +! !INTERFACE: +subroutine mkpeat(ldomain, mapfname, datfname, ndiag, peat_o) +! +! !DESCRIPTION: +! make peat +! +! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkncdio + use mkdiagnosticsMod, only : output_diagnostics_area + use mkchecksMod, only : min_bad, max_bad +! +! !ARGUMENTS: + + implicit none + type(domain_type) , intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: peat_o(:) ! output grid: fraction peat +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Sam Levis and Bill Sacks +! +! +! !LOCAL VARIABLES: +!EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: data_i(:) ! data on input grid + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + integer :: ncid,varid ! input netCDF id's + integer :: ier ! error status + + real(r8), parameter :: min_valid = 0._r8 ! minimum valid value + real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value + character(len=32) :: subname = 'mkpeat' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make peat .....' + call shr_sys_flush(6) + + ! ----------------------------------------------------------------- + ! Read domain and mapping information, check for consistency + ! ----------------------------------------------------------------- + + call domain_read( tdomain, datfname ) + + call gridmap_mapread( tgridmap, mapfname ) + + ! Obtain frac_dst + allocate(frac_dst(ldomain%ns), stat=ier) + if (ier/=0) call abort() + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + allocate(mask_r8(tdomain%ns), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! ----------------------------------------------------------------- + ! Open input file, allocate memory for input data + ! ----------------------------------------------------------------- + + write(6,*)'Open peat file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + + allocate(data_i(tdomain%ns), stat=ier) + if (ier/=0) call abort() + + ! ----------------------------------------------------------------- + ! Regrid peat + ! ----------------------------------------------------------------- + + call check_ret(nf_inq_varid (ncid, 'peatf', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + call gridmap_areaave_srcmask(tgridmap, data_i, peat_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check validity of output data + if (min_bad(peat_o, min_valid, 'peat') .or. & + max_bad(peat_o, max_valid, 'peat')) then + call abort() + end if + + call output_diagnostics_area(data_i, peat_o, tgridmap, "Peat", percent=.false., ndiag=ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! ----------------------------------------------------------------- + ! Close files and deallocate dynamic memory + ! ----------------------------------------------------------------- + + call check_ret(nf_close(ncid), subname) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (data_i) + deallocate (frac_dst) + deallocate (mask_r8) + + write (6,*) 'Successfully made peat' + write (6,*) + call shr_sys_flush(6) + +end subroutine mkpeat + + +end module mkpeatMod diff --git a/tools/mksurfdata_esmf/src/mkpftConstantsMod.F90 b/tools/mksurfdata_esmf/src/mkpftConstantsMod.F90 new file mode 100644 index 0000000000..241873c339 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkpftConstantsMod.F90 @@ -0,0 +1,43 @@ +module mkpftConstantsMod + !----------------------------------------------------------------------- + !BOP + ! + ! !MODULE: mkpftConstants + ! + ! !DESCRIPTION: + ! Constants used by mkpft and related code + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! + !----------------------------------------------------------------------- + !!USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + + implicit none + private + + ! + ! !PUBLIC DATA MEMBERS: + ! + + integer, parameter, public :: maxpft = 78 ! maximum # of PFT + + integer, public :: num_natpft = -1 ! number of PFTs on the natural vegetation + ! landunit, NOT including bare ground + ! (includes generic crops for runs with + ! create_crop_landunit=false) + + integer, public :: num_cft ! number of CFTs on the crop landunit + integer, public :: natpft_lb ! lower bound for natural pft arrays + integer, public :: natpft_ub ! upper bound for natural pft arrays + integer, public :: cft_lb ! lower bound for cft arrays + integer, public :: cft_ub ! upper bound for cft arrays + + integer, parameter, public :: baregroundindex = 0 ! index of bare ground in a natural pft array + + ! The following is NOT set as a parameter so that it can be overridden in unit tests + integer, public :: c3cropindex = 15 + integer, public :: c3irrcropindex = 16 + +end module mkpftConstantsMod diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 new file mode 100644 index 0000000000..f454a6e580 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -0,0 +1,1267 @@ +module mkpftMod + +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mkpft +! +! !DESCRIPTION: +! Make PFT data +! +! !REVISION HISTORY: +! Author: Mariana Vertenstein +! +!----------------------------------------------------------------------- +!!USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush + use mkvarpar , only : noveg + use mkvarctl , only : numpft + use mkdomainMod , only : domain_checksame + use mkpftConstantsMod + + implicit none + + private ! By default make data private +! +! !PUBLIC MEMBER FUNCTIONS: +! + public mkpftInit ! Initialization + public mkpft ! Set PFT + public mkpft_parse_oride ! Parse the string with PFT fraction/index info to override + public mkpftAtt ! Write out attributes to output file on pft +! +! !PUBLIC DATA MEMBERS: +! + + ! + ! When pft_idx and pft_frc are set, they must be set together, and they will cause the + ! entire area to be covered with vegetation and zero out other landunits. + ! The sum of pft_frc must = 100%, and each pft_idx point in the array corresponds to + ! the fraction in pft_frc. Only the first few points are used until pft_frc = 0.0. + ! + integer :: m ! index + integer, public :: pft_idx(0:maxpft) = & ! PFT vegetation index to override with + (/ ( -1, m = 0, maxpft ) /) + real(r8), public :: pft_frc(0:maxpft) = & ! PFT vegetation fraction to override with + (/ ( 0.0_r8, m = 0, maxpft ) /) +! +! !PRIVATE DATA MEMBERS: +! + logical, public, protected :: use_input_pft = .false. ! Flag to override PFT with input values + logical, public, protected :: presc_cover = .false. ! Flag to prescribe vegetation coverage + integer, private :: nzero ! index of first zero fraction + + type, public :: pft_oride ! Public only for unit testing + real(r8) :: crop ! Percent covered by crops + real(r8) :: natveg ! Percent covered by natural vegetation + real(r8), allocatable :: natpft(:) ! Percent of each natural PFT within the natural veg landunit + real(r8), allocatable :: cft(:) ! Percent of each crop CFT within the crop landunit + contains + procedure, public :: InitZeroOut ! Initialize the PFT override object to zero out all vegetation + procedure, public :: InitAllPFTIndex ! Initialize the PFT override object with PFT indeces for all veg and crop types + procedure, public :: Clean ! Clean up a PFT Override object + end type pft_oride + + interface pft_oride + module procedure :: constructor ! PFT Overide object constructor + end interface pft_oride + + type(pft_oride), private :: pft_override ! Module instance of PFT override object + ! Used for both zeroing out PFT's as well + ! as setting specified PFT's over the gridcell +! +! !PRIVATE MEMBER FUNCTIONS: +! + private :: mkpft_check_oride ! Check the pft_frc and pft_idx values for correctness +!EOP +!=============================================================== +contains +!=============================================================== + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkpftInit +! +! !INTERFACE: +subroutine mkpftInit( zero_out_l, all_veg_l ) +! +! !DESCRIPTION: +! Initialize of Make PFT data +! !USES: + use mkvarpar, only : numstdpft, numstdcft +! +! !ARGUMENTS: + implicit none + logical, intent(IN) :: zero_out_l ! If veg should be zero'ed out + logical, intent(IN) :: all_veg_l ! If should zero out other fractions so that + ! all land-cover is vegetation +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: +!EOP + real(r8), parameter :: hndrd = 100.0_r8 ! A hundred percent + character(len=32) :: subname = 'mkpftMod::mkpftInit() ' + logical :: error_happened ! If an error was triggered so should return +!----------------------------------------------------------------------- + write (6, '(a, a, a)') "In ", trim(subname), "..." + if ( maxpft < numpft ) then + write(6,*) subname//'number PFT is > max allowed!' + call abort() + return + end if + nzero = -1 + call mkpft_check_oride( error_happened ) + if ( error_happened )then + write(6,*) subname//'Problem setting pft override settings' + return + end if + if ( zero_out_l .and. use_input_pft )then + write(6,*) subname//"trying to both zero out all PFT's as well as set them to specific values" + call abort() + return + end if + ! If zeroing out, set use_input_pft to true so the pft_override will be used + if( zero_out_l )then + nzero = 0 + pft_frc(0) = 0.0_r8 + pft_idx(0) = noveg + use_input_pft = .true. + end if + if ( use_input_pft ) then + write(6,*) 'Set PFT fraction to : ', pft_frc(0:nzero) + write(6,*) 'With PFT index : ', pft_idx(0:nzero) + end if + if ( all_veg_l .and. .not. use_input_pft )then + write(6,*) subname//'if all_veg is set to true then specified PFT indices must be provided (i.e. pft_frc and pft_idx)' + call abort() + return + end if + + if ( zero_out_l .and. all_veg_l )then + write(6,*) subname//'zeroing out vegetation and setting vegetation to 100% is a contradiction!' + call abort() + return + end if + + ! Determine number of PFTs on the natural vegetation landunit, and number of CFTs on + ! the crop landunit. + ! + ! For the sake of dynamic PFTs and dynamic landunits, it helps for the structure of the + ! surface dataset to reflect the subgrid structure that will be used by CLM. Currently + ! generic crops will always go on the crop landunit, regardless of whether or not we're + ! using the extra specific crops (so we always run CLM with create_crop_landunit=.true.). + ! When we create a surface dataset WITH the extra specific crops, all crops + ! (including the generic crops) again go on the crop landunit. + + num_natpft = numstdpft - numstdcft + num_cft = numpft - num_natpft + + ! Determine array bounds for arrays of just natural pfts and just crops. Note that + ! these are set up so that they always span 0:numpft, so that there is a 1:1 + ! correspondence between an element in a full 0:numpft array and an element with the + ! same index in either a natpft array or a cft array. + natpft_lb = noveg + natpft_ub = num_natpft + cft_lb = num_natpft+1 + cft_ub = cft_lb + num_cft - 1 + + ! Make sure the array indices have been set up properly, to ensure the 1:1 + ! correspondence mentioned above + if (cft_ub /= numpft) then + write(6,*) 'CFT_UB set up incorrectly: cft_ub, numpft = ', cft_ub, numpft + call abort() + return + end if + ! + ! Set the PFT override values if applicable + ! + pft_override = pft_oride() + presc_cover = .false. + if( zero_out_l )then + call pft_override%InitZeroOut() + presc_cover = .true. + else if ( use_input_pft ) then + call pft_override%InitAllPFTIndex() + if ( .not. all_veg_l )then + if ( pft_override%crop <= 0.0 )then + write(6,*) "Warning: PFT/CFT's are being overridden, but no crop type is being asked for" + end if + if ( pft_override%natveg <= 0.0 )then + write(6,*) "Warning: PFT/CFT's are being overridden, but no natural vegetation type is being asked for" + end if + presc_cover = .false. + else + presc_cover = .true. + end if + end if + +end subroutine mkpftInit + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkpft +! +! !INTERFACE: +subroutine mkpft(ldomain, mapfname, fpft, ndiag, & + pctlnd_o, pctnatpft_o, pctcft_o) +! +! !DESCRIPTION: +! Make PFT data +! +! This dataset consists of the %cover of the [numpft]+1 PFTs used by +! the model. The input %cover pertains to the "vegetated" portion of the +! grid cell and sums to 100. The real portion of each grid cell +! covered by each PFT is the PFT cover times the fraction of the +! grid cell that is land. This is the quantity preserved when +! area-averaging from the input (1/2 degree) grid to the models grid. +! +! Upon return from this routine, the % cover of the natural veg + crop landunits is +! generally 100% everywhere; this will be normalized later to account for special landunits. +! +! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio + use mkpctPftTypeMod, only : pct_pft_type + use mkpftConstantsMod, only : natpft_lb, natpft_ub, num_cft, cft_lb, cft_ub +! +! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: fpft ! input pft dataset file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: pctlnd_o(:) ! output grid:%land/gridcell + type(pct_pft_type), intent(out):: pctnatpft_o(:) ! natural PFT cover + type(pct_pft_type), intent(out):: pctcft_o(:) ! crop (CFT) cover +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Mariana Vertenstein +! +! +! !LOCAL VARIABLES: +!EOP + type(pct_pft_type), allocatable:: pctnatpft_i(:) ! input grid: natural PFT cover + type(pct_pft_type), allocatable:: pctcft_i(:) ! input grid: crop (CFT) cover + type(domain_type) :: tdomain ! local domain + type(gridmap_type) :: tgridmap ! local gridmap + real(r8), allocatable :: pctpft_i(:,:) ! input grid: PFT percent + real(r8), allocatable :: pctpft_o(:,:) ! output grid: PFT percent (% of grid cell) + real(r8), allocatable :: pctnatveg_i(:) ! input grid: natural veg percent (% of grid cell) + real(r8), allocatable :: pctnatveg_o(:) ! output grid: natural veg percent (% of grid cell) + real(r8), allocatable :: pctcrop_i(:) ! input grid: all crop percent (% of grid cell) + real(r8), allocatable :: pctcrop_o(:) ! output grid: all crop percent (% of grid cell) + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: pct_cft_i(:,:) ! input grid: CFT (Crop Functional Type) percent (% of landunit cell) + real(r8), allocatable :: temp_i(:,:) ! input grid: temporary 2D variable to read in + real(r8), allocatable :: pct_cft_o(:,:) ! output grid: CFT (Crop Functional Type) percent (% of landunit cell) + real(r8), allocatable :: pct_nat_pft_i(:,:) ! input grid: natural PFT percent (% of landunit cell) + real(r8), allocatable :: pct_nat_pft_o(:,:) ! output grid: natural PFT percent (% of landunit cell) + integer :: numpft_i ! num of plant types input data + integer :: natpft_i ! num of natural plant types input data + integer :: ncft_i ! num of crop types input data + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: wst_sum ! sum of %pft + real(r8), allocatable :: gpft_o(:) ! output grid: global area pfts + real(r8) :: garea_o ! output grid: global area + real(r8), allocatable :: gpft_i(:) ! input grid: global area pfts + real(r8) :: garea_i ! input grid: global area + integer :: k,n,m,ni,no,ns_i,ns_o ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ndims ! number of dimensions for a variable on the file + integer :: dimlens(3) ! dimension lengths for a variable on the file + integer :: ier ! error status + real(r8) :: relerr = 0.0001_r8 ! max error: sum overlap wts ne 1 + logical :: oldformat ! if input file is in the old format or not (based on what variables exist) + logical :: error_happened ! If an error was triggered so should return + + character(len=35) veg(0:maxpft) ! vegetation types + character(len=32) :: subname = 'mkpftMod::mkpft()' +!----------------------------------------------------------------------- + + write (6,*) + write (6, '(a, a, a)') "In ", trim(subname), "..." + write (6,*) 'Attempting to make PFTs .....' + call shr_sys_flush(6) + + ! ----------------------------------------------------------------- + ! Set the vegetation types + ! ----------------------------------------------------------------- + if ( numpft >= numstdpft )then + veg(0:maxpft) = (/ & + 'not vegetated ', & + 'needleleaf evergreen temperate tree', & + 'needleleaf evergreen boreal tree ', & + 'needleleaf deciduous boreal tree ', & + 'broadleaf evergreen tropical tree ', & + 'broadleaf evergreen temperate tree ', & + 'broadleaf deciduous tropical tree ', & + 'broadleaf deciduous temperate tree ', & + 'broadleaf deciduous boreal tree ', & + 'broadleaf evergreen shrub ', & + 'broadleaf deciduous temperate shrub', & + 'broadleaf deciduous boreal shrub ', & + 'c3 arctic grass ', & + 'c3 non-arctic grass ', & + 'c4 grass ', & + 'c3_crop ', & + 'c3_irrigated ', & + 'temperate_corn ', & + 'irrigated_temperate_corn ', & + 'spring_wheat ', & + 'irrigated_spring_wheat ', & + 'winter_wheat ', & + 'irrigated_winter_wheat ', & + 'temperate_soybean ', & + 'irrigated_temperate_soybean ', & + 'barley ', & + 'irrigated_barley ', & + 'winter_barley ', & + 'irrigated_winter_barley ', & + 'rye ', & + 'irrigated_rye ', & + 'winter_rye ', & + 'irrigated_winter_rye ', & + 'cassava ', & + 'irrigated_cassava ', & + 'citrus ', & + 'irrigated citrus ', & + 'cocoa ', & + 'irrigated_cocoa ', & + 'coffee ', & + 'irrigated_coffee ', & + 'cotton ', & + 'irrigated_cotton ', & + 'datepalm ', & + 'irrigated_datepalm ', & + 'foddergrass ', & + 'irrigated_foddergrass ', & + 'grapes ', & + 'irrigated_grapes ', & + 'groundnuts ', & + 'irrigated_groundnuts ', & + 'millet ', & + 'irrigated_millet ', & + 'oilpalm ', & + 'irrigated_oilpalm ', & + 'potatoes ', & + 'irrigated_potatoes ', & + 'pulses ', & + 'irrigated_pulses ', & + 'rapeseed ', & + 'irrigated_rapeseed ', & + 'rice ', & + 'irrigated_rice ', & + 'sorghum ', & + 'irrigated_sorghum ', & + 'sugarbeet ', & + 'irrigated_sugarbeet ', & + 'sugarcane ', & + 'irrigated_sugarcane ', & + 'sunflower ', & + 'irrigated_sunflower ', & + 'miscanthus ', & + 'irrigated_miscanthus ', & + 'switchgrass ', & + 'irrigated_switchgrass ', & + 'tropical_corn ', & + 'irrigated_tropical_corn ', & + 'tropical_soybean ', & + 'irrigated_tropical_soybean ' /) + end if + if ( numpft == numstdpft )then + write(6,*)'Creating surface datasets with the standard # of PFTs =', numpft + else if ( numpft > numstdpft )then + write(6,*)'Creating surface datasets with extra types for crops; total pfts =', numpft + else + write(6,*) subname//': parameter numpft is NOT set to a known value (should be 16 or more) =',numpft + call abort() + return + end if + + ns_o = ldomain%ns + + ! ----------------------------------------------------------------- + ! Read input PFT file + ! ----------------------------------------------------------------- + if ( .not. presc_cover ) then + ! Obtain input grid info, read PCT_PFT + + call domain_read(tdomain,fpft) + ns_i = tdomain%ns + + write (6,*) 'Open PFT file: ', trim(fpft) + call check_ret(nf_open(fpft, 0, ncid), subname) + + ! Check what variables exist to determine what format the file is in + call check_ret(nf_inq_varid (ncid, 'PCT_PFT', varid), subname, varexists=oldformat) + + if ( oldformat ) then + write(6,*) subname//' ERROR: PCT_PFT field on the the file so it is in the old format, which is no longer supported' + call abort() + return + end if + call check_ret(nf_inq_dimid (ncid, 'natpft', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, natpft_i), subname) + call check_ret(nf_inq_dimid (ncid, 'cft', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, ncft_i), subname) + numpft_i = natpft_i + ncft_i + + ! Check if the number of pfts on the input matches the expected number. A mismatch + ! is okay if the input raw dataset has prognostic crops and the output does not. + if (numpft_i .ne. numpft+1) then + if (numpft_i .eq. numstdpft+1) then + write(6,*) subname//' ERROR: trying to use non-crop input file' + write(6,*) 'for a surface dataset with crops.' + call abort() + return + else if (numpft_i > numstdpft+1 .and. numpft_i == maxpft+1) then + write(6,*) subname//' WARNING: using a crop input raw dataset for a non-crop output surface dataset' + else + write(6,*) subname//': parameter numpft+1= ',numpft+1, & + 'does not equal input dataset numpft= ',numpft_i + call abort() + return + end if + endif + + ! TODO: create a route handle + ! for starts just do everything on one processor to make sure it works + + ! TODO: determine local number of points and allocate memory only for the local number + ! the local number can be determined from the mesh + ! TODO: initialize pio and set global decomposition + + ! If file is in the new format, expect the following variables: + ! PCT_NATVEG, PCT_CROP, PCT_NAT_PFT, PCT_CFT + allocate(pctnatveg_i(ns_i), & + pctnatveg_o(ns_o), & + pctcrop_i(ns_i), & + pctcrop_o(ns_o), & + frac_dst(ns_o), & + pct_cft_i(ns_i,1:num_cft), & + pct_cft_o(ns_o,1:num_cft), & + pct_nat_pft_i(ns_i,0:num_natpft), & + pct_nat_pft_o(ns_o,0:num_natpft), & + stat=ier) + if (ier/=0)then + call abort() + return + end if + + call check_ret(nf_inq_varid (ncid, 'PCT_NATVEG', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, pctnatveg_i), subname) + call check_ret(nf_inq_varid (ncid, 'PCT_CROP', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, pctcrop_i), subname) + if ( .not. use_input_pft )then + call check_ret(nf_inq_varid (ncid, 'PCT_CFT', varid), subname) + call get_dim_lengths(ncid, 'PCT_CFT', ndims, dimlens(:) ) + if ( ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) == num_cft )then + call check_ret(nf_get_var_double (ncid, varid, pct_cft_i), subname) + else if ( ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) > num_cft )then + ! Read in the whole array: then sum the rainfed and irrigated + ! seperately + allocate( temp_i(ns_i,dimlens(3)) ) + call check_ret(nf_get_var_double (ncid, varid, temp_i), subname) + do n = 1, num_cft + pct_cft_i(:,n) = 0.0_r8 + do m = n, dimlens(3), 2 + pct_cft_i(:,n) = pct_cft_i(:,n) + temp_i(:,m) + end do + end do + deallocate( temp_i ) + else + write(6,*) subname//': ERROR: dimensions for PCT_CROP are NOT what is expected' + call abort() + return + end if + call check_ret(nf_inq_varid (ncid, 'PCT_NAT_PFT', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, pct_nat_pft_i), subname) + end if + + call check_ret(nf_close(ncid), subname) + + ! ----------------------------------------------------------------- + ! Otherwise if vegetation is prescribed everywhere + ! ----------------------------------------------------------------- + else + ns_i = 1 + numpft_i = numpft+1 + allocate(pctnatveg_i(ns_i), & + pctnatveg_o(ns_o), & + pctcrop_i(ns_i), & + pctcrop_o(ns_o), & + pct_cft_i(ns_i,1:num_cft), & + pct_cft_o(ns_o,1:num_cft), & + pct_nat_pft_i(ns_i,0:num_natpft), & + pct_nat_pft_o(ns_o,0:num_natpft), & + stat=ier) + if (ier/=0)then + call abort() + return + end if + end if + allocate(pctpft_i(ns_i,0:(numpft_i-1)), & + pctpft_o(ns_o,0:(numpft_i-1)), & + pctnatpft_i(ns_i), & + pctcft_i(ns_i), & + stat=ier) + if (ier/=0)then + call abort() + return + end if + + ! Determine pctpft_o on output grid + + ! If total vegetation cover is prescribed from input... + if ( use_input_pft .and. presc_cover ) then + + do no = 1,ns_o + pctlnd_o(no) = 100._r8 + pctnatveg_o(no) = pft_override%natveg + pctcrop_o(no) = pft_override%crop + end do + + ! otherewise if total cover isn't prescribed read it from the datasets + else + + ! Compute pctlnd_o, pctpft_o + + ! TODO: create a route handle here + call gridmap_mapread(tgridmap, mapfname) + + ! Error checks for domain and map consistencies + ! TODO: remove this check + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Area-average percent cover on input grid [pctpft_i] to output grid + ! [pctpft_o] and correct [pctpft_o] according to land landmask + ! Note that percent cover is in terms of total grid area. + pctlnd_o(:) = frac_dst(:) * 100._r8 + + ! New format with extra variables on input + call gridmap_areaave_srcmask(tgridmap, pctnatveg_i, pctnatveg_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, pctcrop_i, pctcrop_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! + ! If specific PFT/CFT's are NOT prescribed set them from the input file + ! + if ( .not. use_input_pft )then + do m = 0, num_natpft + call gridmap_areaave_scs(tgridmap, pct_nat_pft_i(:,m), & + pct_nat_pft_o(:,m), nodata=0._r8, & + src_wt=pctnatveg_i*0.01_r8*tdomain%mask, & + dst_wt=pctnatveg_o*0.01_r8, frac_dst=frac_dst) + do no = 1,ns_o + if (pctlnd_o(no) < 1.0e-6 .or. pctnatveg_o(no) < 1.0e-6) then + if (m == 0) then + pct_nat_pft_o(no,m) = 100._r8 + else + pct_nat_pft_o(no,m) = 0._r8 + endif + end if + enddo + end do + do m = 1, num_cft + call gridmap_areaave_scs(tgridmap, pct_cft_i(:,m), pct_cft_o(:,m), & + nodata=0._r8, src_wt=pctcrop_i*0.01_r8*tdomain%mask, & + dst_wt=pctcrop_o*0.01_r8, frac_dst=frac_dst) + do no = 1,ns_o + if (pctlnd_o(no) < 1.0e-6 .or. pctcrop_o(no) < 1.0e-6) then + if (m == 1) then + pct_cft_o(no,m) = 100._r8 + else + pct_cft_o(no,m) = 0._r8 + endif + end if + enddo + end do + ! Otherwise do some error checking to make sure specific veg types are given where nat-veg and crop is assigned + else + do no = 1,ns_o + if (pctlnd_o(no) > 1.0e-6 .and. pctnatveg_o(no) > 1.0e-6) then + if ( pft_override%natveg <= 0.0_r8 )then + write(6,*) subname//': ERROR: no natural vegetation PFTs are being prescribed but there are natural '// & + 'vegetation areas: provide at least one natural veg PFT' + call abort() + return + end if + end if + if (pctlnd_o(no) > 1.0e-6 .and. pctcrop_o(no) > 1.0e-6) then + if ( pft_override%crop <= 0.0_r8 )then + write(6,*) subname//': ERROR: no crop CFTs are being prescribed but there are crop areas: provide at least one CFT' + call abort() + return + end if + end if + end do + end if + end if + + ! + ! If specific PFT/CFT's are prescribed set them directly + ! + if ( use_input_pft )then + do no = 1,ns_o + if (pctlnd_o(no) > 1.0e-6 .and. pctnatveg_o(no) > 1.0e-6) then + pct_nat_pft_o(no,noveg:num_natpft) = pft_override%natpft(noveg:num_natpft) + else + pct_nat_pft_o(no,noveg) = 100._r8 + pct_nat_pft_o(no,noveg+1:) = 0._r8 + end if + if (pctlnd_o(no) > 1.0e-6 .and. pctcrop_o(no) > 1.0e-6) then + pct_cft_o(no,1:num_cft) = pft_override%cft(1:num_cft) + else + pct_cft_o(no,1) = 100._r8 + pct_cft_o(no,2:) = 0._r8 + end if + pctpft_o(no,natpft_lb:natpft_ub) = pct_nat_pft_o(no,0:num_natpft) + pctpft_o(no,cft_lb:cft_ub) = pct_cft_o(no,1:num_cft) + end do + end if + + + ! Error check: percents should sum to 100 for land grid cells, within roundoff + ! Also correct sums so that if they differ slightly from 100, they are corrected to + ! equal 100 more exactly. + + do no = 1,ns_o + wst_sum = 0. + do m = 0, num_natpft + wst_sum = wst_sum + pct_nat_pft_o(no,m) + enddo + if (abs(wst_sum-100._r8) > relerr) then + write (6,*) subname//'error: nat pft = ', & + (pct_nat_pft_o(no,m), m = 0, num_natpft), & + ' do not sum to 100. at no = ',no,' but to ', wst_sum + call abort() + end if + + ! Correct sum so that if it differs slightly from 100, it is corrected to equal + ! 100 more exactly + do m = 1, num_natpft + pct_nat_pft_o(no,m) = pct_nat_pft_o(no,m) * 100._r8 / wst_sum + end do + + wst_sum = 0. + do m = 1, num_cft + wst_sum = wst_sum + pct_cft_o(no,m) + enddo + if (abs(wst_sum-100._r8) > relerr) then + write (6,*) subname//'error: crop cft = ', & + (pct_cft_o(no,m), m = 1, num_cft), & + ' do not sum to 100. at no = ',no,' but to ', wst_sum + call abort() + end if + + ! Correct sum so that if it differs slightly from 100, it is corrected to equal + ! 100 more exactly + do m = 1, num_cft + pct_cft_o(no,m) = pct_cft_o(no,m) * 100._r8 / wst_sum + end do + + end do + + ! Convert % pft as % of grid cell to % pft on the landunit and % of landunit on the + ! grid cell + do no = 1,ns_o + pctnatpft_o(no) = pct_pft_type( pct_nat_pft_o(no,:), pctnatveg_o(no), first_pft_index=natpft_lb ) + pctcft_o(no) = pct_pft_type( pct_cft_o(no,:), pctcrop_o(no), first_pft_index=cft_lb ) + end do + + ! ----------------------------------------------------------------- + ! Error check + ! Compare global areas on input and output grids + ! Only when you aren't prescribing the vegetation coverage everywhere + ! If use_input_pft is set this will compare the global coverage of + ! the prescribed vegetation to the coverage of PFT/CFT's on the input + ! datasets. + ! ----------------------------------------------------------------- + + if ( .not. presc_cover ) then + + ! Convert to pctpft over grid if using new format + do ni = 1, ns_i + pctnatpft_i(ni) = pct_pft_type( pct_nat_pft_i(ni,:), pctnatveg_i(ni), first_pft_index=natpft_lb ) + pctcft_i(ni) = pct_pft_type( pct_cft_i(ni,:), pctcrop_i(ni), first_pft_index=cft_lb ) + end do + + do no = 1,ns_o + pctpft_o(no,natpft_lb:natpft_ub) = pctnatpft_o(no)%get_pct_p2g() + pctpft_o(no,cft_lb:cft_ub) = pctcft_o(no)%get_pct_p2g() + end do + allocate(gpft_i(0:numpft_i-1)) + allocate(gpft_o(0:numpft_i-1)) + + ! input grid + + gpft_i(:) = 0. + garea_i = 0. + do ni = 1,ns_i + garea_i = garea_i + tgridmap%area_src(ni)*re**2 + do m = 0, numpft_i - 1 + gpft_i(m) = gpft_i(m) + pctpft_i(ni,m)*tgridmap%area_src(ni)*& + tdomain%mask(ni)*re**2 + end do + end do + if ( allocated(pctpft_i) ) deallocate (pctpft_i) + + ! output grid + + gpft_o(:) = 0. + garea_o = 0. + do no = 1,ns_o + garea_o = garea_o + tgridmap%area_dst(no)*re**2 + do m = 0, numpft_i - 1 + gpft_o(m) = gpft_o(m) + pctpft_o(no,m)*tgridmap%area_dst(no)*& + frac_dst(no)*re**2 + end do + end do + + ! comparison + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'PFTs Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,1001) +1001 format (1x,'plant type ',20x,' input grid area',' output grid area',/ & + 1x,33x,' 10**6 km**2',' 10**6 km**2') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + do m = 0, numpft_i - 1 + write (ndiag,1002) veg(m), gpft_i(m)*1.e-06/100.,gpft_o(m)*1.e-06/100. + end do +1002 format (1x,a35,f16.3,f17.3) + call shr_sys_flush(ndiag) + + deallocate(gpft_i, gpft_o, frac_dst) + + end if + deallocate( pctnatpft_i ) + deallocate( pctcft_i ) + deallocate(pctpft_o) + + + ! Deallocate dynamic memory + + deallocate(pctnatveg_i) + deallocate(pctnatveg_o) + deallocate(pctcrop_i) + deallocate(pctcrop_o) + deallocate(pct_cft_i) + deallocate(pct_cft_o) + deallocate(pct_nat_pft_i) + deallocate(pct_nat_pft_o) + if ( .not. presc_cover ) then + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + end if + + write (6,*) 'Successfully made PFTs' + write (6,*) + + +end subroutine mkpft + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkpft_parse_oride +! +! !INTERFACE: +subroutine mkpft_parse_oride( string ) +! +! !DESCRIPTION: +! Parse the string with pft fraction and index information on it, to override +! the file with this information rather than reading from a file. +! +! !USES: + use shr_string_mod, only: shr_string_betweenTags, shr_string_countChar +! !ARGUMENTS: + character(len=256), intent(IN) :: string ! String to parse with PFT fraction + ! and index data +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: +!EOP + integer :: rc ! error return code + integer :: num_elms ! number of elements + character(len=256) :: substring ! string between tags + character(len=*), parameter :: frc_start = "" + character(len=*), parameter :: frc_end = "" + character(len=*), parameter :: idx_start = "" + character(len=*), parameter :: idx_end = "" + character(len=*), parameter :: subname = 'mkpft_parse_oride' + !----------------------------------------------------------------------- + + ! NOTE(bja, 2015-02) pft_frc and pft_index can be reset multiple + ! times by calls to this function. If the number of elements being + ! set is different each time, then we are working with out of date + ! information, and the sums may not sum to 100%. + pft_frc = 0.0_r8 + pft_idx = -1 + + call shr_string_betweenTags( string, frc_start, frc_end, substring, rc ) + if ( rc /= 0 )then + write(6,*) subname//'Trouble finding pft_frac start end tags' + call abort() + return + end if + num_elms = shr_string_countChar( substring, ",", rc ) + read(substring,*) pft_frc(0:num_elms) + call shr_string_betweenTags( string, idx_start, idx_end, substring, rc ) + if ( rc /= 0 )then + write(6,*) subname//'Trouble finding pft_index start end tags' + call abort() + return + end if + if ( num_elms /= shr_string_countChar( substring, ",", rc ) )then + write(6,*) subname//'number of elements different between frc and idx fields' + call abort() + return + end if + read(substring,*) pft_idx(0:num_elms) +!----------------------------------------------------------------------- + +end subroutine mkpft_parse_oride + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkpft_check_oride +! +! !INTERFACE: +subroutine mkpft_check_oride( error_happened ) +! +! !DESCRIPTION: +! Check that the pft override values are valid +! !USES: + implicit none +! !ARGUMENTS: + logical, intent(out) :: error_happened ! Result, true if there was a problem +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: +!EOP + integer :: i, j ! indices + real(r8) :: sumpft ! Sum of pft_frc + real(r8), parameter :: hndrd = 100.0_r8 ! A hundred percent + character(len=32) :: subname = 'mkpftMod::mkpft_check_oride() ' +!----------------------------------------------------------------------- + + error_happened = .false. + sumpft = sum(pft_frc) + if ( sumpft == 0.0 )then + ! PFT fraction is NOT used + use_input_pft = .false. + else if ( abs(sumpft - hndrd) > 1.e-6 )then + write(6, '(a, a, f15.12)') trim(subname), 'Sum of PFT fraction is NOT equal to 100% =', sumpft + write(6,*) 'Set PFT fraction to : ', pft_frc(0:nzero) + write(6,*) 'With PFT index : ', pft_idx(0:nzero) + error_happened = .true. + call abort() + return + else + use_input_pft = .true. + nzero = numpft + do i = 0, numpft + if ( pft_frc(i) == 0.0_r8 )then + nzero = i-1 + exit + end if + end do + ! PFT fraction IS used, and sum is OK, now check details + do i = 0, nzero + if ( pft_frc(i) < 0.0_r8 .or. pft_frc(i) > hndrd )then + write(6,*) subname//'PFT fraction is out of range: pft_frc=', pft_frc(i) + error_happened = .true. + call abort() + return + else if ( pft_frc(i) > 0.0_r8 .and. pft_idx(i) == -1 )then + write(6,*) subname//'PFT fraction > zero, but index NOT set: pft_idx=', pft_idx(i) + error_happened = .true. + call abort() + return + end if + ! PFT index out of range + if ( pft_idx(i) < 0 .or. pft_idx(i) > numpft )then + write(6,*) subname//'PFT index is out of range: ', pft_idx(i) + error_happened = .true. + call abort() + return + end if + ! Make sure index values NOT used twice + do j = 0, i-1 + if ( pft_idx(i) == pft_idx(j) )then + write(6,*) subname//'Same PFT index is used twice: ', pft_idx(i) + error_happened = .true. + call abort() + return + end if + end do + end do + ! Make sure the rest of the fraction is zero and index are not set as well + do i = nzero+1, numpft + if ( pft_frc(i) /= 0.0_r8 .or. pft_idx(i) /= -1 )then + write(6,*) subname//'After PFT fraction is zeroed out, fraction is non zero, or index set' + error_happened = .true. + call abort() + return + end if + end do + end if + +end subroutine mkpft_check_oride + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkpftAtt +! +! !INTERFACE: +subroutine mkpftAtt( ncid, dynlanduse, xtype ) +! +! !DESCRIPTION: +! make PFT attributes on the output file +! + use mkncdio , only : check_ret, ncd_defvar, ncd_def_spatial_var + use fileutils , only : get_filename + use mkvarctl , only : mksrf_fvegtyp, mksrf_flai + use mkvarpar + +! !ARGUMENTS: + implicit none + include 'netcdf.inc' + integer, intent(in) :: ncid ! NetCDF file ID to write out to + logical, intent(in) :: dynlanduse ! if dynamic land-use file + integer, intent(in) :: xtype ! external type to output real data as +! +! !CALLED FROM: +! subroutine mkfile in module mkfileMod +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: +!EOP + integer :: pftsize ! size of lsmpft dimension + integer :: natpftsize ! size of natpft dimension + integer :: dimid ! input netCDF id's + character(len=256) :: str ! global attribute string + character(len=32) :: subname = 'mkpftAtt' + + ! Define dimensions + call check_ret(nf_def_dim (ncid, 'time' , nf_unlimited, dimid), subname) + + if (.not. dynlanduse) then + pftsize = numpft + 1 + call check_ret(nf_def_dim (ncid, 'lsmpft' , pftsize , dimid), subname) + end if + + natpftsize = num_natpft + 1 + call check_ret(nf_def_dim (ncid, 'natpft' , natpftsize , dimid), subname) + + ! zero-size dimensions can cause problems, so we only include the cft dimension if num_cft > 0 + ! Note that this implies that we can only include PCT_CFT on the dataset if num_cft > 0 + if (num_cft > 0) then + call check_ret(nf_def_dim (ncid, 'cft' , num_cft , dimid), subname) + end if + + ! Add global attributes + + if (.not. dynlanduse) then + str = get_filename(mksrf_flai) + call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & + 'Lai_raw_data_file_name', len_trim(str), trim(str)), subname) + end if + + if ( use_input_pft ) then + str = 'TRUE' + call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & + 'pft_override', len_trim(str), trim(str)), subname) + else + str = get_filename(mksrf_fvegtyp) + call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & + 'Vegetation_type_raw_data_filename', len_trim(str), trim(str)), subname) + end if + + ! Define variables + + ! Coordinate variable for indices of natural PFTs + call ncd_defvar(ncid=ncid, varname='natpft', xtype=nf_int, & + dim1name='natpft', long_name='indices of natural PFTs', units='index') + + ! Coordinate variable for indices of CFTs + if (num_cft > 0) then + call ncd_defvar(ncid=ncid, varname='cft', xtype=nf_int, & + dim1name='cft', long_name='indices of CFTs', units='index') + end if + + call ncd_def_spatial_var(ncid=ncid, varname='LANDFRAC_PFT', xtype=nf_double, & + long_name='land fraction from pft dataset', units='unitless') + + call ncd_def_spatial_var(ncid=ncid, varname='PFTDATA_MASK', xtype=nf_int, & + long_name='land mask from pft dataset, indicative of real/fake points', units='unitless') + + if (.not. dynlanduse) then + call ncd_def_spatial_var(ncid=ncid, varname='PCT_NATVEG', xtype=xtype, & + long_name='total percent natural vegetation landunit', units='unitless') + end if + + ! PCT_CROP + if (.not. dynlanduse) then + call ncd_def_spatial_var(ncid=ncid, varname='PCT_CROP', xtype=xtype, & + long_name='total percent crop landunit', units='unitless') + else + call ncd_def_spatial_var(ncid=ncid, varname='PCT_CROP', xtype=xtype, & + lev1name='time', & + long_name='total percent crop landunit', units='unitless') + call ncd_def_spatial_var(ncid=ncid, varname='PCT_CROP_MAX', xtype=xtype, & + long_name='maximum total percent crop landunit during time period', units='unitless') + end if + + ! PCT_NAT_PFT + if (.not. dynlanduse) then + call ncd_def_spatial_var(ncid=ncid, varname='PCT_NAT_PFT', xtype=xtype, & + lev1name='natpft', & + long_name='percent plant functional type on the natural veg landunit (% of landunit)', units='unitless') + else + call ncd_def_spatial_var(ncid=ncid, varname='PCT_NAT_PFT', xtype=xtype, & + lev1name='natpft', lev2name='time', & + long_name='percent plant functional type on the natural veg landunit (% of landunit)', units='unitless') + call ncd_def_spatial_var(ncid=ncid, varname='PCT_NAT_PFT_MAX', xtype=xtype, & + lev1name='natpft', & + long_name='maximum percent plant functional type during time period (% of landunit)', units='unitless') + end if + + ! PCT_CFT + if (num_cft > 0) then + if (.not. dynlanduse) then + call ncd_def_spatial_var(ncid=ncid, varname='PCT_CFT', xtype=xtype, & + lev1name='cft', & + long_name='percent crop functional type on the crop landunit (% of landunit)', units='unitless') + else + call ncd_def_spatial_var(ncid=ncid, varname='PCT_CFT', xtype=xtype, & + lev1name='cft', lev2name='time', & + long_name='percent crop functional type on the crop landunit (% of landunit)', units='unitless') + call ncd_def_spatial_var(ncid=ncid, varname='PCT_CFT_MAX', xtype=xtype, & + lev1name='cft', & + long_name='maximum percent crop functional type during time period (% of landunit)', units='unitless') + end if + end if + + ! LAI,SAI,HTOP,HBOT + if (.not. dynlanduse) then + call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_LAI', xtype=xtype, & + lev1name='lsmpft', lev2name='time', & + long_name='monthly leaf area index', units='unitless') + + call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_SAI', xtype=xtype, & + lev1name='lsmpft', lev2name='time', & + long_name='monthly stem area index', units='unitless') + + call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_HEIGHT_TOP', xtype=xtype, & + lev1name='lsmpft', lev2name='time', & + long_name='monthly height top', units='meters') + + call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_HEIGHT_BOT', xtype=xtype, & + lev1name='lsmpft', lev2name='time', & + long_name='monthly height bottom', units='meters') + end if + + ! OTHER + if (dynlanduse) then + call ncd_defvar(ncid=ncid, varname='YEAR', xtype=nf_int, & + dim1name='time', & + long_name='Year of PFT data', units='unitless') + call ncd_defvar(ncid=ncid, varname='time', xtype=nf_int, & + dim1name='time', & + long_name='year', units='unitless') + call ncd_defvar(ncid=ncid, varname='input_pftdata_filename', xtype=nf_char, & + dim1name='nchar', & + dim2name='time', & + long_name='Input filepath for PFT values for this year', units='unitless') + else + call ncd_defvar(ncid=ncid, varname='time', xtype=nf_int, & + dim1name='time', & + long_name='Calendar month', units='month') + end if + +end subroutine mkpftAtt + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: constructor +! +! !INTERFACE: +function constructor( ) result(this) +! +! !DESCRIPTION: +! Construct a new PFT override object +! +! !ARGUMENTS: + implicit none + type(pft_oride) :: this +!EOP + character(len=32) :: subname = 'mkpftMod::constructor() ' + + this%crop = -1.0_r8 + this%natveg = -1.0_r8 + if ( num_natpft < 0 )then + write(6,*) subname//'num_natpft is NOT set = ', num_natpft + call abort() + return + end if + if ( num_cft < 0 )then + write(6,*) subname//'num_cft is NOT set = ', num_cft + call abort() + return + end if + allocate( this%natpft(noveg:num_natpft) ) + allocate( this%cft(1:num_cft) ) + this%natpft(:) = -1.0_r8 + this%cft(:) = -1.0_r8 + call this%InitZeroOut() +end function constructor + + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: InitZeroOut +! +! !INTERFACE: +subroutine InitZeroOut( this ) +! +! !DESCRIPTION: +! Initialize a pft_oride object with vegetation that's zeroed out +! +! !ARGUMENTS: + implicit none + class(pft_oride), intent(inout) :: this +!EOP + this%crop = 0.0_r8 + this%natveg = 0.0_r8 + + this%natpft = 0.0_r8 + this%natpft(noveg) = 100.0_r8 + this%cft = 0.0_r8 + this%cft(1) = 100.0_r8 +end subroutine InitZeroOut + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: InitZeroOut +! +! !INTERFACE: +subroutine InitAllPFTIndex( this ) +! +! !DESCRIPTION: +! Initialize a pft_oride object with vegetation that's zeroed out +! +! !ARGUMENTS: + implicit none + class(pft_oride), intent(inout) :: this +!EOP + integer :: m, i ! Indices + real(r8) :: croptot ! Total of crop + real(r8) :: natvegtot ! Total of natural vegetation + character(len=32) :: subname = 'mkpftMod::coInitAllPFTIndex() ' + + croptot = 0.0_r8 + natvegtot = 0.0_r8 + this%natpft = 0.0_r8 + this%cft = 0.0_r8 + do m = noveg, nzero + i = pft_idx(m) + if ( (i < noveg) .or. (i > numpft) )then + write(6,*) subname//'PFT index is out of valid range' + call abort() + return + else if ( i <= num_natpft )then + this%natpft(i) = pft_frc(m) + natvegtot = natvegtot + pft_frc(m) + else + this%cft(i-num_natpft) = pft_frc(m) + croptot = croptot + pft_frc(m) + end if + end do + this%crop = croptot + this%natveg = natvegtot + ! Renormalize + if ( natvegtot > 0.0_r8 )then + this%natpft = 100.0_r8 * this%natpft / natvegtot + else + this%natpft(noveg) = 100.0_r8 + end if + if (croptot > 0.0_r8 )then + this%cft = 100.0_r8 * this%cft / croptot + else + this%cft(1) = 100.0_r8 + end if + +end subroutine InitAllPFTIndex + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: clean +! +! !INTERFACE: +subroutine Clean( this ) +! +! !DESCRIPTION: +! Clean up a PFT Oride object +! +! !ARGUMENTS: + implicit none + class(pft_oride), intent(inout) :: this +!EOP + this%crop = -1.0_r8 + this%natveg = -1.0_r8 + deallocate( this%natpft ) + deallocate( this%cft ) + +end subroutine Clean + +!----------------------------------------------------------------------- + +end module mkpftMod diff --git a/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 b/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 new file mode 100644 index 0000000000..4a9ea12f97 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 @@ -0,0 +1,257 @@ +module mkpftUtilsMod + + !----------------------------------------------------------------------- + !BOP + ! + ! !MODULE: mkpftUtils + ! + ! !DESCRIPTION: + ! Lower-level utilities used in making PFT data. + ! + ! These are separated out from mkpftMod mainly as an aid to testing. + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! + !----------------------------------------------------------------------- + !!USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + + implicit none + private + + ! + ! !PUBLIC MEMBER FUNCTIONS: + ! + public :: convert_from_p2g ! Convert a p2g array into pct_pft_type objects + public :: adjust_total_veg_area ! Adjust the total vegetated area (natural veg & crop) to a new specified total + + ! + ! !PRIVATE MEMBER FUNCTIONS: + ! + + private :: get_default_natpft ! Get the default natural pft breakdown, for a 0-area natural veg. landunit + private :: get_default_cft ! Get the default cft breakdown, for a 0-area crop landunit + + interface convert_from_p2g + module procedure convert_from_p2g_default + module procedure convert_from_p2g_missing_crops + end interface convert_from_p2g + + !EOP + !=============================================================== +contains + !=============================================================== + + !----------------------------------------------------------------------- + subroutine convert_from_p2g_default(pct_p2g, pctnatpft, pctcft) + ! + ! !DESCRIPTION: + ! Given the % of each pft on the grid cell, create pct_pft_type objects that give % of + ! each pft on the landunit and % of each landunit on the grid cell. + ! + ! !USES: + use mkpctPftTypeMod , only : pct_pft_type + use mkpftConstantsMod, only : natpft_lb, natpft_ub, num_cft, cft_lb, cft_ub + ! + ! !ARGUMENTS: + real(r8), intent(in) :: pct_p2g(natpft_lb:) ! % of each pft on the grid cell (includes crops as well as natural veg types) + type(pct_pft_type), intent(out) :: pctnatpft ! natural PFT cover + type(pct_pft_type), intent(out) :: pctcft ! crop (CFT) COVER + ! + ! !LOCAL VARIABLES: + real(r8), allocatable :: default_natpft(:) ! default p2l for natural PFTs, for grid cells where the current size of the natural veg landunit is 0 + real(r8), allocatable :: default_cft(:) ! default p2l for CFTs, for grid cells where the current size of the crop landunit is 0 + + character(len=*), parameter :: subname = 'convert_from_p2g_default' + !----------------------------------------------------------------------- + + if (ubound(pct_p2g, 1) /= cft_ub) then + write(6,*) subname, ' ERROR: upper bound of pct_p2g should be cft_ub' + write(6,*) 'ubound(pct_p2g), cft_ub = ', ubound(pct_p2g), cft_ub + call abort() + end if + + allocate(default_natpft(natpft_lb:natpft_ub)) + default_natpft = get_default_natpft() + pctnatpft = pct_pft_type(pct_p2g(natpft_lb:natpft_ub), natpft_lb, default_natpft) + deallocate(default_natpft) + + if (num_cft > 0) then + allocate(default_cft(cft_lb:cft_ub)) + default_cft = get_default_cft() + pctcft = pct_pft_type(pct_p2g(cft_lb:cft_ub), cft_lb, default_cft) + deallocate(default_cft) + else + ! create an empty placeholder, with 0 area on the grid cell + pctcft = pct_pft_type() + end if + + end subroutine convert_from_p2g_default + + !----------------------------------------------------------------------- + subroutine convert_from_p2g_missing_crops(pct_p2g, pctcft_saved, pctnatpft, pctcft) + ! + ! !DESCRIPTION: + ! Given the % of each pft on the grid cell, create pct_pft_type objects that give % + ! of each pft on the landunit and % of each landunit on the grid cell. + ! + ! This version of the routine assumes that pct_p2g only includes the standard PFTs - + ! not prognostic crops. It takes the relative crop cover from pctcft_saved, and uses + ! the % cover of the generic c3 crop in pct_p2g to specify the total crop landunit + ! area. + ! + ! Typically, pct_p2g will have an upper bound of numstdpft; however, this is not + ! assumed. Any upper bound is fine as long as the upper bound is greater than + ! natpft_ub and includes c3cropindex. + ! + ! Assumptions: + ! - We are running with prognostic crops (i.e., NOT an empty crop landunit - although + ! it's fine for the crop landunit area to be 0%) + ! - In pct_p2g, the only non-zero areas should be: + ! - Areas of PFTs on the natural veg landunit + ! - The area of the generic c3 crop + ! + ! !USES: + use mkpctPftTypeMod , only : pct_pft_type + use mkpftConstantsMod , only : c3cropindex, natpft_lb, natpft_ub, num_cft + ! + ! !ARGUMENTS: + real(r8), intent(in) :: pct_p2g(natpft_lb:) ! % of each pft on the grid cell (includes crops as well as natural veg types) + type(pct_pft_type), intent(in) :: pctcft_saved ! saved crop cover information, used to specify the relative cover of each crop + type(pct_pft_type), intent(out) :: pctnatpft ! natural PFT cover + type(pct_pft_type), intent(out) :: pctcft ! crop (CFT) COVER + ! + ! !LOCAL VARIABLES: + real(r8), allocatable :: default_natpft(:) ! default p2l for natural PFTs, for grid cells where the current size of the natural veg landunit is 0 + integer :: pft_index + real(r8) :: crop_area ! area of the crop landunit on the grid cell + + character(len=*), parameter :: subname = 'convert_from_p2g_missing_crops' + !----------------------------------------------------------------------- + + ! Error checking on inputs + + if (num_cft == 0) then + write(6,*) subname, ' ERROR: this routine should only be called when running with prognostic crops' + write(6,*) '(i.e., with num_cft > 0)' + call abort() + end if + + do pft_index = natpft_ub + 1, ubound(pct_p2g, 1) + if (pft_index /= c3cropindex .and. pct_p2g(pft_index) > 0._r8) then + write(6,*) subname, ' ERROR: in pct_p2g, the only non-zero areas should be:' + write(6,*) ' - areas of PFTs on the natural veg landunit' + write(6,*) ' - the area of the generic c3 crop' + write(6,*) '(we do not currently handle the case where the transient input dataset' + write(6,*) 'has non-zero areas for both pft 15 and pft 16)' + write(6,*) 'pft_index, area = ', pft_index, pct_p2g(pft_index) + call abort() + end if + end do + + ! Done error checking on inputs + + allocate(default_natpft(natpft_lb:natpft_ub)) + default_natpft = get_default_natpft() + pctnatpft = pct_pft_type(pct_p2g(natpft_lb:natpft_ub), natpft_lb, default_natpft) + deallocate(default_natpft) + + pctcft = pctcft_saved + crop_area = pct_p2g(c3cropindex) + call pctcft%set_pct_l2g(crop_area) + + end subroutine convert_from_p2g_missing_crops + + !----------------------------------------------------------------------- + function get_default_natpft() result(default_natpft) + ! + ! !DESCRIPTION: + ! Get the default natural pft breakdown, for a 0-area natural veg. landunit. + ! + ! Currently we use the same default everywhere. In the future, we could change this + ! to compute default_natpft based on some function of location (e.g., different + ! values for high latitudes than low latitudes, etc.). + ! + ! !USES: + use mkpftConstantsMod, only : baregroundindex, natpft_lb, natpft_ub + ! + ! !ARGUMENTS: + real(r8), allocatable :: default_natpft(:) ! function result + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'get_default_natpft' + !----------------------------------------------------------------------- + + allocate(default_natpft(natpft_lb:natpft_ub)) + default_natpft(:) = 0._r8 + default_natpft(baregroundindex) = 100._r8 + + end function get_default_natpft + + !----------------------------------------------------------------------- + function get_default_cft() result(default_cft) + ! + ! !DESCRIPTION: + ! Get the default cft breakdown, for a 0-area crop landunit. + ! + ! !USES: + use mkpftConstantsMod, only : c3cropindex, cft_lb, cft_ub + ! + ! !ARGUMENTS: + real(r8), allocatable :: default_cft(:) ! function result + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'get_default_cft' + !----------------------------------------------------------------------- + + allocate(default_cft(cft_lb:cft_ub)) + default_cft(:) = 0._r8 + default_cft(c3cropindex) = 100._r8 + + end function get_default_cft + + + !----------------------------------------------------------------------- + subroutine adjust_total_veg_area(new_total_pct, pctnatpft, pctcft) + ! + ! !DESCRIPTION: + ! Adjust the total vegetated area on the grid cell (natural veg & crop) to a new + ! specified total. + ! + ! If the old areas are 0%, then all the new area goes into pctnatpft. + ! + ! !USES: + use mkpctPftTypeMod, only : pct_pft_type + ! + ! !ARGUMENTS: + real(r8), intent(in) :: new_total_pct ! new total % of natural veg + crop landunits + class(pct_pft_type), intent(inout) :: pctnatpft ! natural veg cover information + class(pct_pft_type), intent(inout) :: pctcft ! crop cover information + ! + ! !LOCAL VARIABLES: + real(r8) :: natpft_l2g ! grid cell % cover of nat. veg. + real(r8) :: cft_l2g ! grid cell % cover of crop + real(r8) :: old_total ! old total % cover of natural veg + crop landunits + + character(len=*), parameter :: subname = 'adjust_total_veg_area' + !----------------------------------------------------------------------- + + natpft_l2g = pctnatpft%get_pct_l2g() + cft_l2g = pctcft%get_pct_l2g() + old_total = natpft_l2g + cft_l2g + if (old_total > 0._r8) then + call pctnatpft%set_pct_l2g(natpft_l2g * new_total_pct / old_total) + call pctcft%set_pct_l2g(cft_l2g * new_total_pct / old_total) + else + call pctnatpft%set_pct_l2g(new_total_pct) + end if + + end subroutine adjust_total_veg_area + + +end module mkpftUtilsMod + + diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 new file mode 100644 index 0000000000..89fe454c89 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -0,0 +1,627 @@ +module mkpioMod + + use ESMF ! TODO: put in only statements + use pio ! TODO: put in only statements + use shr_kind_mod , only : r8 => shr_kind_r8, cl => shr_kind_cl, cs => shr_kind_cs + use shr_sys_mod , only : shr_sys_abort + use mkutilsMod , only : chkerr + use mkvarctl , only : root_task, ndiag + + implicit none + private + + public :: mkpio_iodesc_rawdata + public :: mkpio_iodesc_output + public :: mkpio_wopen + public :: mkpio_close + public :: mkpio_redef + public :: mkpio_enddef + public :: mkpio_defvar + public :: mkpio_def_spatial_var + public :: mkpio_get_dim_lengths + public :: mkpio_put_time_slice + + interface mkpio_def_spatial_var + module procedure mkpio_def_spatial_var_0lev + module procedure mkpio_def_spatial_var_1lev + module procedure mkpio_def_spatial_var_2lev + end interface mkpio_def_spatial_var + + interface mkpio_put_time_slice + module procedure mkpio_put_time_slice_1d + module procedure mkpio_put_time_slice_2d + end interface mkpio_put_time_slice + + integer, public :: pio_iotype + integer, public :: pio_ioformat + type(iosystem_desc_t), pointer, public :: io_subsystem + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + +!=============================================================== +contains +!=============================================================== + + subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, pio_iodesc, rc) + + ! Determine pio io descriptor for variable on rawdata file + + ! input/output variables + type(ESMF_Mesh) , intent(in) :: mesh + character(len=*) , intent(in) :: varname + type(file_desc_t) , intent(inout) :: pioid + type(var_desc_t) , intent(out) :: pio_varid + integer , intent(out) :: pio_vartype + type(io_desc_t) , intent(inout) :: pio_iodesc + integer , intent(out) :: rc + + ! local variables + type(ESMF_DistGrid) :: distGrid + integer :: n, ndims + integer, pointer :: compdof(:) + integer, allocatable :: dimids(:) + integer, allocatable :: dimlens(:) + integer :: lsize + integer :: rCode ! pio return code (only used when pio error handling is PIO_BCAST_ERROR) + character(*), parameter :: subname = '(shr_strdata_set_stream_iodesc) ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (root_task) then + write(ndiag,'(a,i8, i8)') 'setting iodesc for : '//trim(varname)// & + ' with dimlens(1), dimlens2 = ',dimlens(1),dimlens(2) + end if + + call ESMF_MeshGet(mesh, elementdistGrid=distGrid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_DistGridGet(distGrid, localDe=0, elementCount=lsize, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(compdof(lsize)) + call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=compdof, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! get pio variable id, type and number of dimensions + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + rcode = pio_inq_vartype(pioid, pio_varid, pio_vartype) + rcode = pio_inq_varndims(pioid, pio_varid, ndims) + + ! get variable dimension sizes + allocate(dimids(ndims)) + allocate(dimlens(ndims)) + rcode = pio_inq_vardimid(pioid, pio_varid, dimids(1:ndims)) + do n = 1, ndims + rcode = pio_inq_dimlen(pioid, dimids(n), dimlens(n)) + end do + + ! determine io descriptor for this variable + if (ndims == 1) then + call pio_initdecomp(io_subsystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) + else if (ndims == 2) then + call pio_initdecomp(io_subsystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + else + call shr_sys_abort('rawdata input must have ndims either 1 or 2') + end if + + ! deallocate memory + deallocate(compdof) + + end subroutine mkpio_iodesc_rawdata + + !=============================================================================== + logical function mkpio_file_exists(vm, filename) + + !--------------- + ! inquire if i/o file exists + !--------------- + + ! input/output variables + type(ESMF_VM) , intent(in) :: vm + character(len=*) , intent(in) :: filename + + ! local variables + integer :: tmp(1) + integer :: rc + !------------------------------------------------------------------------------- + + tmp(1) = 0 + + mkpio_file_exists = .false. + if (root_task) then + inquire(file=trim(filename), exist=mkpio_file_exists) + if (mkpio_file_exists) tmp(1) = 1 + end if + call ESMF_VMBroadCast(vm, tmp, 1, 0, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if(tmp(1) == 1) mkpio_file_exists = .true. + + end function mkpio_file_exists + + !=============================================================================== + subroutine mkpio_wopen(pioid, filename, vm, clobber) + + !--------------- + ! open netcdf file + !--------------- + + use pio , only : PIO_IOTYPE_PNETCDF, PIO_IOTYPE_NETCDF, PIO_BCAST_ERROR, PIO_INTERNAL_ERROR + use pio , only : pio_openfile, pio_createfile, PIO_GLOBAL, pio_enddef + use pio , only : pio_put_att, pio_redef, pio_get_att + use pio , only : pio_seterrorhandling, pio_file_is_open, pio_clobber, pio_write, pio_noclobber + + ! input/output arguments + type(file_desc_t) , intent(inout) :: pioid + character(len=*) , intent(in) :: filename + type(ESMF_VM) , intent(in) :: vm + logical , intent(in) :: clobber + + ! local variables + integer :: rcode + integer :: nmode + integer :: rc + character(len=CL) :: wfilename + character(*),parameter :: subName = '(mkpio_wopen) ' + !------------------------------------------------------------------------------- + + ! filename not open + wfilename = trim(filename) + + if (mkpio_file_exists(vm, filename)) then + if (clobber) then + nmode = pio_clobber + ! only applies to classic NETCDF files. + if(pio_iotype == PIO_IOTYPE_NETCDF .or. pio_iotype == PIO_IOTYPE_PNETCDF) then + nmode = ior(nmode,pio_ioformat) + endif + rcode = pio_createfile(io_subsystem, pioid, pio_iotype, trim(filename), nmode) + if (root_task) write(ndiag,'(a)') trim(subname)//' creating file '//trim(filename) + else + rcode = pio_openfile(io_subsystem, pioid, pio_iotype, trim(filename), pio_write) + if (root_task) write(ndiag,'(a)') trim(subname)//' opening file '//trim(filename) + call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) + endif + else + nmode = pio_noclobber + ! only applies to classic NETCDF files. + if(pio_iotype == PIO_IOTYPE_NETCDF .or. pio_iotype == PIO_IOTYPE_PNETCDF) then + nmode = ior(nmode,pio_ioformat) + endif + rcode = pio_createfile(io_subsystem, pioid, pio_iotype, trim(filename), nmode) + if (root_task) write(ndiag,'(a)') trim(subname) //' creating file '// trim(filename) + endif + + end subroutine mkpio_wopen + + !=============================================================================== + subroutine mkpio_close(pioid, filename, rc) + + !--------------- + ! close netcdf file + !--------------- + + use pio, only: pio_file_is_open, pio_closefile + + ! input/output variables + type(file_desc_t) , intent(in) :: pioid + character(*) , intent(in) :: filename + integer , intent(out) :: rc + + ! local variables + character(len=CL) :: wfilename + character(*),parameter :: subName = '(mkpio_close) ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (.not. pio_file_is_open(pioid)) then + ! filename not open, just return + elseif (trim(wfilename) == trim(filename)) then + ! filename matches, close it + call pio_closefile(pioid) + else + ! different filename is open, abort + if (root_task) then + write(ndiag,'(a)') trim(subname)//' different wfilename and filename currently open, aborting ' + write(ndiag,'(a)') 'filename = ',trim(filename) + write(ndiag,'(a)') 'wfilename = ',trim(wfilename) + end if + call ESMF_LogWrite(subname//'different file currently open, aborting '//trim(filename), ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) then + call ESMF_Finalize(endflag=ESMF_END_ABORT) + end if + endif + + end subroutine mkpio_close + + !=============================================================================== + subroutine mkpio_redef(pioid) + + use pio, only : pio_redef + + ! input/output variables + type(file_desc_t), intent(inout) :: pioid + + ! local variables + integer :: rcode + !------------------------------------------------------------------------------- + + rcode = pio_redef(pioid) + + end subroutine mkpio_redef + + !=============================================================================== + subroutine mkpio_enddef(pioid) + + use pio, only : pio_enddef + + ! input/output variables + type(file_desc_t), intent(inout) :: pioid + + ! local variables + integer :: rcode + !------------------------------------------------------------------------------- + + rcode = pio_enddef(pioid) + + end subroutine mkpio_enddef + + !=============================================================================== + subroutine mkpio_defvar(pioid, varname, xtype, & + dim1name, dim2name, dim3name, dim4name, dim5name, & + long_name, units, missing_value, fill_value, imissing_value, ifill_value) + + ! Define a pio variable + + ! input/output variables + type(file_desc_t) , intent(in) :: pioid + character(len=*) , intent(in) :: varname ! variable name + integer , intent(in) :: xtype ! external type + character(len=*) , intent(in), optional :: dim1name ! dimension name + character(len=*) , intent(in), optional :: dim2name ! dimension name + character(len=*) , intent(in), optional :: dim3name ! dimension name + character(len=*) , intent(in), optional :: dim4name ! dimension name + character(len=*) , intent(in), optional :: dim5name ! dimension name + character(len=*) , intent(in), optional :: long_name ! attribute + character(len=*) , intent(in), optional :: units ! attribute + real(r8) , intent(in), optional :: missing_value ! attribute for real + real(r8) , intent(in), optional :: fill_value ! attribute for real + integer , intent(in), optional :: imissing_value ! attribute for int + integer , intent(in), optional :: ifill_value ! attribute for int + + ! !LOCAL VARIABLES: + integer :: n ! indices + integer :: ndims ! dimension counter + integer :: dimid(5) ! dimension ids + type(var_desc_t) :: pio_varid ! variable id + integer :: itmp ! temporary + character(len=CS) :: str ! temporary + integer :: rcode + character(*), parameter :: subname='mkpio_defvar_real' ! subroutine name + !----------------------------------------------------------------------- + + ! Determine dimension ids for variable + + dimid(:) = 0 + + if (present(dim1name)) then + rcode = pio_inq_dimid(pioid, dim1name, dimid(1)) + end if + if (present(dim2name)) then + rcode = pio_inq_dimid(pioid, dim2name, dimid(2)) + end if + if (present(dim3name)) then + rcode = pio_inq_dimid(pioid, dim3name, dimid(3)) + end if + if (present(dim4name)) then + rcode = pio_inq_dimid(pioid, dim4name, dimid(4)) + end if + if (present(dim5name)) then + rcode = pio_inq_dimid(pioid, dim5name, dimid(5)) + end if + + ! Define variable + if (present(dim1name)) then + ndims = 0 + do n = 1, size(dimid) + if (dimid(n) /= 0) ndims = ndims + 1 + end do + rcode = pio_def_var(pioid, trim(varname), xtype, dimid(1:ndims), pio_varid) + else + rcode = pio_def_var(pioid, trim(varname), xtype, pio_varid) + end if + + ! Add attributes to variable + if (present(long_name)) then + rcode = pio_put_att(pioid, pio_varid, 'long_name', trim(long_name)) + end if + if (present(units)) then + rcode = pio_put_att(pioid, pio_varid, 'units', trim(units)) + end if + if (present(fill_value)) then + rcode = pio_put_att(pioid, pio_varid, '_FillValue', fill_value) + end if + if (present(missing_value)) then + rcode = pio_put_att(pioid, pio_varid, 'missing_value', missing_value) + end if + if (present(ifill_value)) then + rcode = pio_put_att(pioid, pio_varid, '_FillValue', ifill_value) + end if + if (present(imissing_value)) then + rcode = pio_put_att(pioid, pio_varid, 'missing_value', imissing_value) + end if + + end subroutine mkpio_defvar + + ! ======================================================================== + ! mkpio_def_spatial_var routines: define a spatial pio variable + ! (convenience wrapper to mkpio_defvar) + ! ======================================================================== + + subroutine mkpio_def_spatial_var_0lev(pioid, varname, xtype, long_name, units) + + ! Define a spatial netCDF variable (convenience wrapper to mkpio_defvar) + ! The variable in question has ONLY spatial dimensions (no level or time dimensions) + + use mkvarctl, only : outnc_1d + + ! !ARGUMENTS: + type(file_desc_t) , intent(in) :: pioid + character(len=*) , intent(in) :: varname ! variable name + integer , intent(in) :: xtype ! external type + character(len=*) , intent(in) :: long_name ! attribute + character(len=*) , intent(in) :: units ! attribute + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'mkpio_def_spatial_var_0lev' + !----------------------------------------------------------------------- + + if (outnc_1d) then + call mkpio_defvar(pioid=pioid, varname=varname, xtype=xtype, & + dim1name='gridcell', long_name=long_name, units=units) + else + call mkpio_defvar(pioid=pioid, varname=varname, xtype=xtype, & + dim1name='lsmlon', dim2name='lsmlat', long_name=long_name, units=units) + end if + + end subroutine mkpio_def_spatial_var_0lev + + !----------------------------------------------------------------------- + subroutine mkpio_def_spatial_var_1lev(pioid, varname, xtype, lev1name, long_name, units) + ! + ! !DESCRIPTION: + ! Define a spatial netCDF variable (convenience wrapper to mkpio_defvar) + ! + ! The variable in question has one level (or time) dimension in addition to its + ! spatial dimensions + ! + ! !USES: + use mkvarctl, only : outnc_1d + ! + ! !ARGUMENTS: + type(file_desc_t) , intent(in) :: pioid + character(len=*) , intent(in) :: varname ! variable name + integer , intent(in) :: xtype ! external type + character(len=*) , intent(in) :: lev1name ! name of level (or time) dimension + character(len=*) , intent(in) :: long_name ! attribute + character(len=*) , intent(in) :: units ! attribute + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'mkpio_def_spatial_var_1lev' + !----------------------------------------------------------------------- + + if (outnc_1d) then + call mkpio_defvar(pioid, varname=varname, xtype=xtype, & + dim1name='gridcell', dim2name=lev1name, & + long_name=long_name, units=units) + else + call mkpio_defvar(pioid, varname=varname, xtype=xtype, & + dim1name='lsmlon', dim2name='lsmlat',dim3name=lev1name, & + long_name=long_name, units=units) + end if + + end subroutine mkpio_def_spatial_var_1lev + + !----------------------------------------------------------------------- + subroutine mkpio_def_spatial_var_2lev(pioid, varname, xtype, lev1name, lev2name, long_name, units) + ! + ! !DESCRIPTION: + ! Define a spatial netCDF variable (convenience wrapper to mkpio_defvar) + ! + ! The variable in question has two level (or time) dimensions in addition to its + ! spatial dimensions + ! + ! !USES: + use mkvarctl, only : outnc_1d + ! + ! !ARGUMENTS: + type(file_desc_t) , intent(in) :: pioid + character(len=*) , intent(in) :: varname ! variable name + integer , intent(in) :: xtype ! external type + character(len=*) , intent(in) :: lev1name ! name of first level (or time) dimension + character(len=*) , intent(in) :: lev2name ! name of second level (or time) dimension + character(len=*) , intent(in) :: long_name ! attribute + character(len=*) , intent(in) :: units ! attribute + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'mkpio_def_spatial_var_2lev' + !----------------------------------------------------------------------- + + if (outnc_1d) then + call mkpio_defvar(pioid=pioid, varname=varname, xtype=xtype, & + dim1name='gridcell', dim2name=lev1name, dim3name=lev2name, & + long_name=long_name, units=units) + else + call mkpio_defvar(pioid=pioid, varname=varname, xtype=xtype, & + dim1name='lsmlon', dim2name='lsmlat', dim3name=lev1name, dim4name=lev2name, & + long_name=long_name, units=units) + end if + + end subroutine mkpio_def_spatial_var_2lev + + ! ======================================================================== + subroutine mkpio_put_time_slice_1d(pioid, pio_varid, pio_iodesc, time_index, data) + + ! Write a single time slice of a 1-d variable + + ! input/output variables + type(file_desc_t) , intent(inout) :: pioid + type(var_desc_t) , intent(inout) :: pio_varid + type(io_desc_t) , intent(inout) :: pio_iodesc + integer , intent(in) :: time_index ! time index in file + real(r8) , intent(in) :: data(:) ! data to write (a single time slice) + ! + ! local variables: + integer :: rcode + character(len=*), parameter :: subname = 'mkpio_put_time_slice_1d' + !----------------------------------------------------------------------- + + call pio_setframe(pioid, pio_varid, int(time_index, kind=Pio_Offset_Kind)) + call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) + + end subroutine mkpio_put_time_slice_1d + + !----------------------------------------------------------------------- + subroutine mkpio_put_time_slice_2d(pioid, pio_varid, pio_iodesc, time_index, data) + + ! Write a single time slice of a 2-d variable + + ! input/output variables + type(file_desc_t) , intent(inout) :: pioid + type(var_desc_t) , intent(inout) :: pio_varid + type(io_desc_t) , intent(inout) :: pio_iodesc + integer , intent(in) :: time_index ! time index in file + real(r8) , intent(in) :: data(:,:) ! data to write (a single time slice) + ! + ! local variables: + integer :: rcode + character(len=*), parameter :: subname = 'mkpio_put_time_slice_2d' + !----------------------------------------------------------------------- + + call pio_setframe(pioid, pio_varid, int(time_index, kind=Pio_Offset_Kind)) + call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) + + end subroutine mkpio_put_time_slice_2d + + !=============================================================== + subroutine mkpio_get_dim_lengths(pioid, varname, ndims, dim_lengths) + + ! Returns the number of dimensions and an array containing the dimension lengths of a + ! variable in an open netcdf file. + ! Entries 1:ndims in the returned dim_lengths array contain the dimension lengths; the + ! remaining entries in that vector are meaningless. The dim_lengths array must be large + ! enough to hold all ndims values; if not, the code aborts (this can be ensured by passing + ! in an array of length nf_max_var_dims). + ! + ! input/otuput variables + type(file_desc_t) , intent(in) :: pioid + character(len=*) , intent(in) :: varname ! name of variable of interest + integer , intent(out) :: ndims ! number of dimensions of variable + integer , intent(out) :: dim_lengths(:) ! lengths of dimensions of variable + ! + ! local variables + type(var_desc_t) :: pio_varid + integer :: dimids(size(dim_lengths)) + integer :: i + integer :: rcode + character(len=*), parameter :: subname = 'get_dim_lengths' + !------------------------------------------------------------------------------ + + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + rcode = pio_inq_varndims(pioid, pio_varid, ndims) + + if (ndims > size(dim_lengths)) then + call shr_sys_abort(trim(subname)//' ERROR: dim_lengths too small') + end if + + dim_lengths(:) = 0 ! pre-fill with 0 so we won't have garbage in elements past ndims + do i = 1, ndims + rcode = pio_inq_dimlen(pioid, dimids(i), dim_lengths(i)) + end do + + end subroutine mkpio_get_dim_lengths + + !=============================================================== + subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) + + ! Write variable varname to output file + + ! input/output variables + type(file_desc_t) , intent(inout) :: pioid + character(len=*) , intent(in) :: varname + type(ESMF_Mesh) , intent(in) :: mesh + type(io_desc_t) , intent(inout) :: pio_iodesc + + integer , intent(out) :: rc + + ! local variables + type(ESMF_DistGrid) :: distGrid + integer :: n, ndims + integer, pointer :: compdof(:) + integer, allocatable :: dimids(:) + integer, allocatable :: dimlens(:) + integer :: lsize + type(var_desc_t) :: pio_varid + integer :: pio_vartype + character(len=cs) :: dimname + integer :: rCode ! pio return code (only used when pio error handling is PIO_BCAST_ERROR) + character(*), parameter :: subname = '(shr_strdata_set_stream_iodesc) ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (root_task) then + write(ndiag,'(a,i8, i8)') 'setting iodesc for : '//trim(varname)// & + ' with dimlens(1), dimlens2 = ',dimlens(1),dimlens(2) + end if + + call ESMF_MeshGet(mesh, elementdistGrid=distGrid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_DistGridGet(distGrid, localDe=0, elementCount=lsize, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(compdof(lsize)) + call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=compdof, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! get pio variable id, type and number of dimensions + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + rcode = pio_inq_vartype(pioid, pio_varid, pio_vartype) + rcode = pio_inq_varndims(pioid, pio_varid, ndims) + + ! get variable dimension sizes + allocate(dimids(ndims)) + allocate(dimlens(ndims)) + rcode = pio_inq_vardimid(pioid, pio_varid, dimids(1:ndims)) + do n = 1, ndims + rcode = pio_inq_dimlen(pioid, dimids(n), dimlens(n)) + end do + + ! determine io descriptor for this variable + if (ndims == 1) then + call pio_initdecomp(io_subsystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) + else if (ndims == 2) then + if (trim(dimname) == 'time' .or. trim(dimname) == 'nt') then + call pio_initdecomp(io_subsystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) + else + call pio_initdecomp(io_subsystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + end if + else if (ndims == 3) then + if (trim(dimname) == 'time' .or. trim(dimname) == 'nt') then + call pio_initdecomp(io_subsystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + else + call pio_initdecomp(io_subsystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof, pio_iodesc) + end if + else if (ndims == 4) then + end if + + ! deallocate memory + deallocate(compdof) + + end subroutine mkpio_iodesc_output + +end module mkpioMod diff --git a/tools/mksurfdata_esmf/src/mksoilMod.F90 b/tools/mksurfdata_esmf/src/mksoilMod.F90 new file mode 100644 index 0000000000..e5c117edb6 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mksoilMod.F90 @@ -0,0 +1,1238 @@ +module mksoilMod +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mksoilMod +! +! !DESCRIPTION: +! Make soil data (texture, color and organic) +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +!----------------------------------------------------------------------- +!!USES: + use shr_kind_mod, only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_flush + use mkdomainMod , only : domain_checksame + use mksoilUtilsMod, only : mkrank, dominant_soil_color + implicit none + + SAVE + private ! By default make data private +! +! !PUBLIC MEMBER FUNCTIONS: +! + public mksoilInit ! Soil Initialization + + public mksoilAtt ! Add attributes to output file + + public mksoiltex ! Set soil texture + public mkorganic ! Set organic soil + public mksoilcol ! Set soil color + public mkfmax ! Make percent fmax +! +! !PUBLIC DATA MEMBERS: +! + real(r8), public, parameter :: unset = -999.99_r8 ! Flag to signify soil texture override not set + real(r8), public :: soil_sand = unset ! soil texture sand % to override with + real(r8), public :: soil_clay = unset ! soil texture clay % to override with + real(r8), public :: soil_fmax = unset ! soil max saturation frac to override with + integer , parameter :: unsetcol = -999 ! flag to indicate soil color NOT set + integer , public :: soil_color= unsetcol ! soil color to override with +! +! !PRIVATE DATA MEMBERS: +! +! !PRIVATE MEMBER FUNCTIONS: + private :: mksoiltexInit ! Soil texture Initialization + private :: mksoilcolInit ! Soil color Initialization + private :: mksoilfmaxInit ! Soil fmax Initialization + +!EOP +!=============================================================== +contains +!=============================================================== + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mksoilInit +! +! !INTERFACE: +subroutine mksoilInit( ) +! +! !DESCRIPTION: +! Initialize the different soil types +! !USES: +! +! !ARGUMENTS: + implicit none +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: +!EOP + character(len=32) :: subname = 'mksoilInit' +!----------------------------------------------------------------------- + call mksoiltexInit() + call mksoilcolInit() + call mksoilfmaxInit() + +end subroutine mksoilInit + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mksoiltexInit +! +! !INTERFACE: +subroutine mksoiltexInit( ) +! +! !DESCRIPTION: +! Initialize of make soil texture +! !USES: +! +! !ARGUMENTS: + implicit none +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: +!EOP + real(r8) :: sumtex + character(len=32) :: subname = 'mksoiltexInit' +!----------------------------------------------------------------------- + if ( soil_clay /= unset )then + write(6,*) 'Replace soil clay % for all points with: ', soil_clay + if ( soil_sand == unset )then + write (6,*) subname//':error: soil_clay set, but NOT soil_sand' + call abort() + end if + end if + if ( soil_sand /= unset )then + write(6,*) 'Replace soil sand % for all points with: ', soil_sand + if ( soil_clay == unset )then + write (6,*) subname//':error: soil_sand set, but NOT soil_clay' + call abort() + end if + sumtex = soil_sand + soil_clay + if ( sumtex < 0.0_r8 .or. sumtex > 100.0_r8 )then + write (6,*) subname//':error: soil_sand and soil_clay out of bounds: sand, clay = ', & + soil_sand, soil_clay + call abort() + end if + end if + +end subroutine mksoiltexInit + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mksoiltex +! +! !INTERFACE: +subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) +! +! !DESCRIPTION: +! make %sand and %clay from IGBP soil data, which includes +! igbp soil 'mapunits' and their corresponding textures +! +! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio +! +! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: sand_o(:,:) ! % sand (output grid) + real(r8) , intent(out):: clay_o(:,:) ! % clay (output grid) +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Mariana Vertenstein +! +! +! !LOCAL VARIABLES: +!EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + character(len=38) :: typ ! soil texture based on ... + integer :: nlay ! number of soil layers + integer :: mapunitmax ! max value of igbp soil mapunits + integer :: mapunittemp ! temporary igbp soil mapunit + integer :: maxovr + integer , allocatable :: novr(:) + integer , allocatable :: kmap(:,:) + real(r8), allocatable :: kwgt(:,:) + integer , allocatable :: kmax(:) + real(r8), allocatable :: wst(:) + real(r8), allocatable :: sand_i(:,:) ! input grid: percent sand + real(r8), allocatable :: clay_i(:,:) ! input grid: percent clay + real(r8), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + integer, parameter :: num=2 ! set soil mapunit number + integer :: wsti(num) ! index to 1st and 2nd largest wst + integer, parameter :: nlsm=4 ! number of soil textures + character(len=38) :: soil(0:nlsm) ! name of each soil texture + real(r8) :: gast_i(0:nlsm) ! global area, by texture type + real(r8) :: gast_o(0:nlsm) ! global area, by texture type + real(r8) :: wt ! map overlap weight + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + integer :: l,k,n,m,ni,no,ns_i,ns_o ! indices + integer :: k1,k2 ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ier ! error status + integer :: miss = 99999 ! missing data indicator + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + logical :: found ! temporary + integer :: kmap_max ! maximum overlap weights + integer, parameter :: kmap_max_min = 90 ! kmap_max mininum value + integer, parameter :: km_mx_ns_prod = 160000 ! product of kmap_max*ns_o to keep constant + character(len=32) :: subname = 'mksoiltex' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make %sand and %clay .....' + call shr_sys_flush(6) + + ! ----------------------------------------------------------------- + ! Define the model surface types: 0 to nlsm + ! ----------------------------------------------------------------- + + soil(0) = 'no soil: ocean, glacier, lake, no data' + soil(1) = 'clays ' + soil(2) = 'sands ' + soil(3) = 'loams ' + soil(4) = 'silts ' + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + ns_i = tdomain%ns + ns_o = ldomain%ns + + write (6,*) 'Open soil texture file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + call check_ret(nf_inq_dimid (ncid, 'number_of_layers', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, nlay), subname) + + call check_ret(nf_inq_dimid (ncid, 'max_value_mapunit', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, mapunitmax), subname) + + allocate(sand_i(mapunitmax,nlay), & + clay_i(mapunitmax,nlay), & + mapunit_i(ns_i), stat=ier) + if (ier/=0) call abort() + + call check_ret(nf_inq_varid (ncid, 'MAPUNITS', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, mapunit_i), subname) + + call check_ret(nf_inq_varid (ncid, 'PCT_SAND', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, sand_i), subname) + + call check_ret(nf_inq_varid (ncid, 'PCT_CLAY', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, clay_i), subname) + + call check_ret(nf_close(ncid), subname) + + ! Compute local fields _o + if (soil_sand==unset .and. soil_clay==unset) then + + call gridmap_mapread(tgridmap, mapfname) + + ! Error checks for domain and map consistencies + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + allocate(frac_dst(ns_o), stat=ier) + if (ier/=0) call abort() + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! kmap_max are the maximum number of mapunits that will consider on + ! any output gridcell - this is set currently above and can be changed + ! kmap(:) are the mapunit values on the input grid + ! kwgt(:) are the weights on the input grid + + allocate(novr(ns_o)) + novr(:) = 0 + do n = 1,tgridmap%ns + ni = tgridmap%src_indx(n) + if (tdomain%mask(ni) > 0) then + no = tgridmap%dst_indx(n) + novr(no) = novr(no) + 1 + end if + end do + maxovr = maxval(novr(:)) + kmap_max = min(maxovr,max(kmap_max_min,km_mx_ns_prod/ns_o)) + deallocate(novr) + + write(6,*)'kmap_max= ',kmap_max,' maxovr= ',maxovr,' ns_o= ',ns_o,' size= ',(kmap_max+1)*ns_o + + allocate(kmap(0:kmap_max,ns_o), stat=ier) + if (ier/=0) call abort() + allocate(kwgt(0:kmap_max,ns_o), stat=ier) + if (ier/=0) call abort() + allocate(kmax(ns_o), stat=ier) + if (ier/=0) call abort() + allocate(wst(0:kmap_max), stat=ier) + if (ier/=0) call abort() + + kwgt(:,:) = 0. + kmap(:,:) = 0 + kmax(:) = 0 + + do n = 1,tgridmap%ns + ni = tgridmap%src_indx(n) + no = tgridmap%dst_indx(n) + wt = tgridmap%wovr(n) * tdomain%mask(ni) + if (wt > 0._r8) then + k = mapunit_i(ni) + found = .false. + do l = 0,kmax(no) + if (k == kmap(l,no)) then + kwgt(l,no) = kwgt(l,no) + wt + found = .true. + exit + end if + end do + if (.not. found) then + kmax(no) = kmax(no) + 1 + if (kmax(no) > kmap_max) then + write(6,*)'kmax is > kmap_max= ',kmax(no), 'kmap_max = ', & + kmap_max,' for no = ',no + write(6,*)'reset kmap_max in mksoilMod to a greater value' + call abort() + end if + kmap(kmax(no),no) = k + kwgt(kmax(no),no) = wt + end if + end if + enddo + + end if + + do no = 1,ns_o + + if (soil_sand==unset .and. soil_clay==unset) then + wst(:) = 0. + wst(0:kmax(no)) = kwgt(0:kmax(no),no) + + ! Rank non-zero weights by soil mapunit. + ! k1 is the most extensive mapunit. + ! k2 is the second most extensive mapunit. + + if (maxval(wst(:)) > 0) then + call mkrank (kmax(no)+1, wst(0:kmax(no)), miss, wsti, num) + k1 = kmap(wsti(1),no) + if (wsti(2) == miss) then + k2 = miss + else + k2 = kmap(wsti(2),no) + end if + else + k1 = 0 + k2 = 0 + end if + + end if + + ! Set soil texture as follows: + ! a. Use dominant igbp soil mapunit based on area of overlap unless + ! 'no data' is dominant + ! b. In this case use second most dominant mapunit if it has data + ! c. If this has no data or if there isn't a second most dominant + ! mapunit, use loam for soil texture + + if (soil_sand/=unset .and. soil_clay/=unset) then !---soil texture is input + do l = 1, nlay + sand_o(no,l) = soil_sand + clay_o(no,l) = soil_clay + end do + else if (k1 /= 0) then !---not 'no data' + do l = 1, nlay + sand_o(no,l) = sand_i(k1,l) + clay_o(no,l) = clay_i(k1,l) + end do + else !---if (k1 == 0) then + if (k2 == 0 .or. k2 == miss) then !---no data + do l = 1, nlay + sand_o(no,l) = 43. !---use loam + clay_o(no,l) = 18. + end do + else !---if (k2 /= 0 and /= miss) + do l = 1, nlay + sand_o(no,l) = sand_i(k2,l) + clay_o(no,l) = clay_i(k2,l) + end do + end if !---end of k2 if-block + end if !---end of k1 if-block + + enddo + + if (soil_sand==unset .and. soil_clay==unset) then + + ! Global sum of output field + + allocate(mask_r8(ns_i), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global area of each soil type on input and output grids + ! ----------------------------------------------------------------- + + ! input grid: global areas by texture class + + gast_i(:) = 0. + do l = 1, nlay + do ni = 1,ns_i + mapunittemp = nint(mapunit_i(ni)) + if (mapunittemp==0) then + typ = 'no soil: ocean, glacier, lake, no data' + else if (clay_i(mapunittemp,l) >= 40.) then + typ = 'clays' + else if (sand_i(mapunittemp,l) >= 50.) then + typ = 'sands' + else if (clay_i(mapunittemp,l)+sand_i(mapunittemp,l) < 50.) then + if (tdomain%mask(ni) /= 0.) then + typ = 'silts' + else !if (tdomain%mask(ni) == 0.) then no data + typ = 'no soil: ocean, glacier, lake, no data' + end if + else + typ = 'loams' + end if + do m = 0, nlsm + if (typ == soil(m)) go to 101 + end do + write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunittemp,l), & + ' clay = ',clay_i(mapunittemp,l), & + ' not assigned to soil type for input grid lon,lat,layer = ',ni,l + call abort() +101 continue + gast_i(m) = gast_i(m) + tgridmap%area_src(ni)*tdomain%mask(ni)*re**2 + end do + end do + + ! output grid: global areas by texture class + + gast_o(:) = 0. + do l = 1, nlay + do no = 1,ns_o + if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then + typ = 'no soil: ocean, glacier, lake, no data' + else if (clay_o(no,l) >= 40.) then + typ = 'clays' + else if (sand_o(no,l) >= 50.) then + typ = 'sands' + else if (clay_o(no,l)+sand_o(no,l) < 50.) then + typ = 'silts' + else + typ = 'loams' + end if + do m = 0, nlsm + if (typ == soil(m)) go to 102 + end do + write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & + ' clay = ',clay_o(no,l), & + ' not assigned to soil type for output grid lon,lat,layer = ',no,l + call abort() +102 continue + gast_o(m) = gast_o(m) + tgridmap%area_dst(no)*frac_dst(no)*re**2 + end do + end do + + ! Diagnostic output + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',l=1,70) + write (ndiag,*) 'Soil Texture Output' + write (ndiag,'(1x,70a1)') ('=',l=1,70) + write (ndiag,*) + + write (ndiag,*) 'The following table of soil texture classes is for comparison only.' + write (ndiag,*) 'The actual data is continuous %sand, %silt and %clay not textural classes' + write (ndiag,*) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',l=1,70) + write (ndiag,1001) +1001 format (1x,'soil texture class',17x,' input grid area output grid area',/ & + 1x,33x,' 10**6 km**2',' 10**6 km**2') + write (ndiag,'(1x,70a1)') ('.',l=1,70) + write (ndiag,*) + + do l = 0, nlsm + write (ndiag,1002) soil(l),gast_i(l)*1.e-6,gast_o(l)*1.e-6 +1002 format (1x,a38,f16.3,f17.3) + end do + + end if + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + if (soil_sand==unset .and. soil_clay==unset) then + call gridmap_clean(tgridmap) + deallocate (kmap, kwgt, kmax, wst) + deallocate (sand_i,clay_i,mapunit_i) + deallocate (frac_dst) + deallocate (mask_r8) + end if + + + write (6,*) 'Successfully made %sand and %clay' + write (6,*) + call shr_sys_flush(6) + +end subroutine mksoiltex + +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mksoilcolInit +! +! !INTERFACE: +subroutine mksoilcolInit( ) +! +! !DESCRIPTION: +! Initialize of make soil color +! !USES: +! +! !ARGUMENTS: + implicit none +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: +!EOP + real(r8) :: sumtex + character(len=32) :: subname = 'mksoilcolInit' +!----------------------------------------------------------------------- + + ! Error check soil_color if it is set + if ( soil_color /= unsetcol )then + if ( soil_color < 0 .or. soil_color > 20 )then + write(6,*)'soil_color is out of range = ', soil_color + call abort() + end if + write(6,*) 'Replace soil color for all points with: ', soil_color + end if +end subroutine mksoilcolInit + + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mksoilcol +! +! !INTERFACE: +subroutine mksoilcol(ldomain, mapfname, datfname, ndiag, & + soil_color_o, nsoicol) +! +! !DESCRIPTION: +! make %sand and %clay from IGBP soil data, which includes +! igbp soil 'mapunits' and their corresponding textures +! +! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio +! +! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + integer , intent(out):: soil_color_o(:) ! soil color classes + integer , intent(out):: nsoicol ! number of soil colors +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Mariana Vertenstein +! +! +! !LOCAL VARIABLES: +!EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: gast_i(:) ! global area, by surface type + real(r8), allocatable :: gast_o(:) ! global area, by surface type + integer , allocatable :: soil_color_i(:) ! input grid: BATS soil color + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + character(len=35), allocatable :: col(:) ! name of each color + integer :: k,l,m,ni,no,ns_i,ns_o ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ier ! error status + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + character(len=32) :: subname = 'mksoilcol' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make soil color classes .....' + call shr_sys_flush(6) + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ns_o = ldomain%ns + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + ns_i = tdomain%ns + allocate(soil_color_i(ns_i), stat=ier) + if (ier/=0) call abort() + allocate(frac_dst(ns_o), stat=ier) + if (ier/=0) call abort() + + write (6,*) 'Open soil color file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + call check_ret(nf_inq_varid (ncid, 'SOIL_COLOR', varid), subname) + call check_ret(nf_get_var_int (ncid, varid, soil_color_i), subname) + call check_ret(nf_close(ncid), subname) + + nsoicol = maxval(soil_color_i) + write(6,*)'nsoicol = ',nsoicol + + allocate(gast_i(0:nsoicol),gast_o(0:nsoicol),col(0:nsoicol)) + + ! ----------------------------------------------------------------- + ! Define the model color classes: 0 to nsoicol + ! ----------------------------------------------------------------- + + if (nsoicol == 20) then + col(0) = 'no soil ' + col(1) = 'class 1: light ' + col(2) = 'class 2: ' + col(3) = 'class 3: ' + col(4) = 'class 4: ' + col(5) = 'class 5: ' + col(6) = 'class 6: ' + col(7) = 'class 7: ' + col(8) = 'class 8: ' + col(9) = 'class 9: ' + col(10) = 'class 10: ' + col(11) = 'class 11: ' + col(12) = 'class 12: ' + col(13) = 'class 13: ' + col(14) = 'class 14: ' + col(15) = 'class 15: ' + col(16) = 'class 16: ' + col(17) = 'class 17: ' + col(18) = 'class 18: ' + col(19) = 'class 19: ' + col(20) = 'class 20: dark ' + else if (nsoicol == 8) then + col(0) = 'no soil ' + col(1) = 'class 1: light ' + col(2) = 'class 2: ' + col(3) = 'class 3: ' + col(4) = 'class 4: ' + col(5) = 'class 5: ' + col(6) = 'class 6: ' + col(7) = 'class 7: ' + col(8) = 'class 8: dark ' + else + write(6,*)'nsoicol value of ',nsoicol,' is not currently supported' + call abort() + end if + + ! Error check soil_color if it is set + if ( soil_color /= unsetcol )then + + if ( soil_color > nsoicol )then + write(6,*)'soil_color is out of range = ', soil_color + call abort() + end if + + do no = 1,ns_o + soil_color_o(no) = soil_color + end do + + else + + call gridmap_mapread(tgridmap, mapfname) + + ! Error checks for domain and map consistencies + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Determine dominant soil color for each output cell + + call dominant_soil_color( & + tgridmap = tgridmap, & + mask_i = tdomain%mask, & + soil_color_i = soil_color_i, & + nsoicol = nsoicol, & + soil_color_o = soil_color_o) + + ! Global sum of output field + + allocate(mask_r8(ns_i), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global area of each soil color on input and output grids + ! ----------------------------------------------------------------- + + gast_i(:) = 0. + do ni = 1,ns_i + k = soil_color_i(ni) + gast_i(k) = gast_i(k) + tgridmap%area_src(ni)*tdomain%mask(ni)*re**2 + end do + + gast_o(:) = 0. + do no = 1,ns_o + k = soil_color_o(no) + gast_o(k) = gast_o(k) + tgridmap%area_dst(no)*frac_dst(no)*re**2 + end do + + ! area comparison + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'Soil Color Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,1001) +1001 format (1x,'soil color type',20x,' input grid area output grid area',/ & + 1x,33x,' 10**6 km**2',' 10**6 km**2') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + + do k = 0, nsoicol + write (ndiag,1002) col(k),gast_i(k)*1.e-6,gast_o(k)*1.e-6 +1002 format (1x,a35,f16.3,f17.3) + end do + + end if + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + if ( soil_color == unsetcol )then + call gridmap_clean(tgridmap) + end if + deallocate (soil_color_i,gast_i,gast_o,col, frac_dst, mask_r8) + + write (6,*) 'Successfully made soil color classes' + write (6,*) + call shr_sys_flush(6) + +end subroutine mksoilcol + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkorganic +! +! !INTERFACE: +subroutine mkorganic(ldomain, mapfname, datfname, ndiag, organic_o) +! +! !DESCRIPTION: +! make organic matter dataset +! +! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio +! +! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: organic_o(:,:) ! output grid: +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! +! Author: David Lawrence +! +! +! !LOCAL VARIABLES: +!EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: organic_i(:,:) ! input grid: total column organic matter + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: gomlev_i ! input grid: global organic on lev + real(r8) :: garea_i ! input grid: global area + real(r8) :: gomlev_o ! output grid: global organic on lev + real(r8) :: garea_o ! output grid: global area + integer :: k,n,m,ni,no,ns_i ! indices + integer :: lev ! level index + integer :: nlay ! number of soil layers + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ier ! error status + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + character(len=32) :: subname = 'mkorganic' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make organic matter dataset .....' + call shr_sys_flush(6) + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + ns_i = tdomain%ns + + write (6,*) 'Open soil organic file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + + call check_ret(nf_inq_dimid (ncid, 'number_of_layers', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, nlay), subname) + + allocate(organic_i(ns_i,nlay),stat=ier) + if (ier/=0) call abort() + allocate(frac_dst(ldomain%ns),stat=ier) + if (ier/=0) call abort() + + if (nlay /= nlevsoi) then + write(6,*)'nlay, nlevsoi= ',nlay,nlevsoi,' do not match' + call abort() + end if + + call check_ret(nf_inq_varid (ncid, 'ORGANIC', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, organic_i), subname) + + call check_ret(nf_close(ncid), subname) + + ! Area-average percent cover on input grid to output grid + ! and correct according to land landmask + ! Note that percent cover is in terms of total grid area. + + call gridmap_mapread(tgridmap, mapfname ) + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + do lev = 1,nlay + call gridmap_areaave_srcmask(tgridmap, organic_i(:,lev), organic_o(:,lev), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + end do + + do lev = 1,nlevsoi + + ! Check for conservation + + do no = 1,ldomain%ns + if ((organic_o(no,lev)) > 130.000001_r8) then + write (6,*) 'MKORGANIC error: organic = ',organic_o(no,lev), & + ' greater than 130.000001 for column, row = ',no + call shr_sys_flush(6) + call abort() + end if + enddo + +! ! Diagnostic output + + ! TODO: there is nothing being written out here currently - all zeroes + ! So for now these are commented out +!!$ write (ndiag,*) +!!$ write (ndiag,'(1x,70a1)') ('.',k=1,70) +!!$ write (ndiag,2001) +!!$2001 format (1x,'surface type input grid area output grid area'/ & +!!$ 1x,' 10**6 km**2 10**6 km**2 ') +!!$ write (ndiag,'(1x,70a1)') ('.',k=1,70) +!!$ write (ndiag,*) +!!$ write (ndiag,2002) gomlev_i*1.e-06,gomlev_o*1.e-06 +!!$ write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 +!!$2002 format (1x,'organic ',f14.3,f17.3) +!!$2004 format (1x,'all surface ',f14.3,f17.3) +!!$ + call shr_sys_flush(ndiag) + + write (6,*) 'Successfully made organic matter, level = ', lev + call shr_sys_flush(6) + + end do ! lev + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (organic_i) + deallocate (frac_dst) + + write (6,*) 'Successfully made organic matter' + call shr_sys_flush(6) + write(6,*) + +end subroutine mkorganic + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mksoilfmaxInit +! +! !INTERFACE: +subroutine mksoilfmaxInit( ) +! +! !DESCRIPTION: +! Initialize of make soil fmax +! !USES: +! +! !ARGUMENTS: + implicit none +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: +!EOP + real(r8) :: sumtex + character(len=32) :: subname = 'mksoilfmaxInit' +!----------------------------------------------------------------------- + + ! Error check soil_fmax if it is set + if ( soil_fmax /= unset )then + if ( soil_fmax < 0.0 .or. soil_fmax > 1.0 )then + write(6,*)'soil_fmax is out of range = ', soil_fmax + call abort() + end if + write(6,*) 'Replace soil fmax for all points with: ', soil_fmax + end if + +end subroutine mksoilfmaxInit + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkfmax +! +! !INTERFACE: +subroutine mkfmax(ldomain, mapfname, datfname, ndiag, fmax_o) +! +! !DESCRIPTION: +! make percent fmax +! +! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio +! +! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: fmax_o(:) ! output grid: %fmax +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Revised: Nan Rosenbloom - used mkglacier.F90 as template. +! Original Author: Mariana Vertenstein +! +! +! !LOCAL VARIABLES: +!EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: fmax_i(:) ! input grid: percent fmax + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: gfmax_i ! input grid: global fmax + real(r8) :: garea_i ! input grid: global area + real(r8) :: gfmax_o ! output grid: global fmax + real(r8) :: garea_o ! output grid: global area + integer :: k,n,m,ni,no,ns_i,ns_o ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ier ! error status + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + character(len=32) :: subname = 'mkfmax' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make %fmax .....' + call shr_sys_flush(6) + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + ns_i = tdomain%ns + ns_o = ldomain%ns + allocate(fmax_i(ns_i), stat=ier) + if (ier/=0) call abort() + allocate(frac_dst(ns_o), stat=ier) + if (ier/=0) call abort() + + write (6,*) 'Open soil fmax file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + call check_ret(nf_inq_varid (ncid, 'FMAX', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, fmax_i), subname) + call check_ret(nf_close(ncid), subname) + + ! Area-average percent cover on input grid to output grid + ! and correct according to land landmask + ! Note that percent cover is in terms of total grid area. + + call gridmap_mapread(tgridmap, mapfname ) + + ! Error checks for domain and map consistencies + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Determine fmax_o on output grid + + ! In points with no data, use globalAvg + ! (WJS (3-11-13): use real(.365783,r8) rather than .365783_r8 to maintain bfb results + ! with old code) + call gridmap_areaave_srcmask(tgridmap, fmax_i, fmax_o, nodata=real(.365783,r8), mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check for conservation + + do no = 1, ns_o + if ((fmax_o(no)) > 1.000001_r8) then + write (6,*) 'MKFMAX error: fmax = ',fmax_o(no), & + ' greater than 1.000001 for column, row = ',no + call shr_sys_flush(6) + call abort() + end if + enddo + + ! Global sum of output field -- must multiply by fraction of + ! output grid that is land as determined by input grid + + allocate(mask_r8(ns_i), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global areas on input and output grids + ! ----------------------------------------------------------------- + + gfmax_i = 0. + garea_i = 0. + do ni = 1,ns_i + garea_i = garea_i + tgridmap%area_src(ni)*re**2 + gfmax_i = gfmax_i + fmax_i(ni)*(tgridmap%area_src(ni)/100.)* & + tdomain%mask(ni)*re**2 + end do + + gfmax_o = 0. + garea_o = 0. + do no = 1,ns_o + garea_o = garea_o + tgridmap%area_dst(no)*re**2 + gfmax_o = gfmax_o + fmax_o(no)*(tgridmap%area_dst(no)/100.) * & + frac_dst(no)*re**2 + if ((frac_dst(no) < 0.0) .or. (frac_dst(no) > 1.0001)) then + write(6,*) "ERROR:: frac_dst out of range: ", frac_dst(no),no + call abort() + end if + end do + + ! Diagnostic output + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'Maximum Fractional Saturated Area Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,2001) +2001 format (1x,'surface type input grid area output grid area'/ & + 1x,' 10**6 km**2 10**6 km**2 ') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + write (ndiag,2002) gfmax_i*1.e-06,gfmax_o*1.e-06 + write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 +2002 format (1x,'fmax ',f14.3,f17.3) +2004 format (1x,'all surface ',f14.3,f17.3) + + write (6,*) 'Successfully made %fmax' + write (6,*) + call shr_sys_flush(6) + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (fmax_i) + deallocate (frac_dst) + deallocate (mask_r8) + +end subroutine mkfmax + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mksoilAtt +! +! !INTERFACE: +subroutine mksoilAtt( ncid, dynlanduse, xtype ) +! +! !DESCRIPTION: +! add atttributes to output file regarding the soil module +! +! !USES: + use fileutils , only : get_filename + use mkncdio , only : check_ret, ncd_defvar, ncd_def_spatial_var + use mkvarpar + use mkvarctl + +! !ARGUMENTS: + implicit none + include 'netcdf.inc' + integer, intent(in) :: ncid ! NetCDF file ID to write out to + logical, intent(in) :: dynlanduse ! if dynamic land-use file + integer, intent(in) :: xtype ! external type to output real data as +! +! !CALLED FROM: +! subroutine mkfile in module mkfileMod +! +! !REVISION HISTORY: +! Original Author: Erik Kluzek +! +! +! !LOCAL VARIABLES: +!EOP + integer :: dimid ! temporary + character(len=256) :: str ! global attribute string + character(len=32) :: subname = 'mksoilAtt' +!----------------------------------------------------------------------- + + if (.not. dynlanduse) then + + ! Define dimensions unique to soil + + call check_ret(nf_def_dim (ncid, 'nlevsoi', & + nlevsoi , dimid), subname) + + ! Add global attributes to file + + if ( soil_clay /= unset .and. soil_sand /= unset )then + str = 'TRUE' + call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & + 'soil_clay_override', len_trim(str), trim(str)), subname) + str = 'TRUE' + call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & + 'soil_sand_override', len_trim(str), trim(str)), subname) + else + str = get_filename(mksrf_fsoitex) + call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & + 'Soil_texture_raw_data_file_name', len_trim(str), trim(str)), subname) + end if + if ( soil_color /= unsetcol )then + str = 'TRUE' + call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & + 'soil_color_override', len_trim(str), trim(str)), subname) + else + str = get_filename(mksrf_fsoicol) + call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & + 'Soil_color_raw_data_file_name', len_trim(str), trim(str)), subname) + end if + if ( soil_fmax /= unset )then + str = 'TRUE' + call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & + 'soil_fmax_override', len_trim(str), trim(str)), subname) + else + str = get_filename(mksrf_fmax) + call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & + 'Fmax_raw_data_file_name', len_trim(str), trim(str)), subname) + end if + str = get_filename(mksrf_forganic) + call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & + 'Organic_matter_raw_data_file_name', len_trim(str), trim(str)), subname) + + ! Define variables + + call ncd_defvar(ncid=ncid, varname='mxsoil_color', xtype=nf_int, & + long_name='maximum numbers of soil colors', units='unitless') + + call ncd_def_spatial_var(ncid=ncid, varname='SOIL_COLOR', xtype=nf_int, & + long_name='soil color', units='unitless') + + call ncd_def_spatial_var(ncid=ncid, varname='PCT_SAND', xtype=xtype, & + lev1name='nlevsoi', & + long_name='percent sand', units='unitless') + + call ncd_def_spatial_var(ncid=ncid, varname='PCT_CLAY', xtype=xtype, & + lev1name='nlevsoi', & + long_name='percent clay', units='unitless') + + call ncd_def_spatial_var(ncid=ncid, varname='ORGANIC', xtype=xtype, & + lev1name='nlevsoi', & + long_name='organic matter density at soil levels', & + units='kg/m3 (assumed carbon content 0.58 gC per gOM)') + + call ncd_def_spatial_var(ncid=ncid, varname='FMAX', xtype=xtype, & + long_name='maximum fractional saturated area', units='unitless') + + end if + +end subroutine mksoilAtt + +!----------------------------------------------------------------------- + +end module mksoilMod diff --git a/tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 b/tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 new file mode 100644 index 0000000000..122cfd45d5 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 @@ -0,0 +1,224 @@ +module mksoilUtilsMod + + !----------------------------------------------------------------------- + !BOP + ! + ! !MODULE: mksoilUtils + ! + ! !DESCRIPTION: + ! Lower-level utilities used in making soil data. + ! + ! These are separated out from mksoilMod mainly as an aid to testing. + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! + !----------------------------------------------------------------------- + !!USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use mkgridmapMod, only : gridmap_type + + implicit none + private + + ! + ! !PUBLIC MEMBER FUNCTIONS: + ! + public :: dominant_soil_color + public :: mkrank + + ! + ! !PRIVATE MEMBER FUNCTIONS: + ! + + !EOP + !=============================================================== +contains + !=============================================================== + + !----------------------------------------------------------------------- + subroutine dominant_soil_color(tgridmap, mask_i, soil_color_i, nsoicol, soil_color_o) + ! + ! !DESCRIPTION: + ! Determine the dominant soil color in each output cell + ! + ! !ARGUMENTS: + type(gridmap_type) , intent(in) :: tgridmap + integer , intent(in) :: mask_i(:) ! input grid: land mask (1 = land, 0 = ocean) + integer , intent(in) :: soil_color_i(:) ! input grid: BATS soil color + integer , intent(in) :: nsoicol ! number of soil colors + integer , intent(out) :: soil_color_o(:) ! output grid: soil color classes + ! + ! !LOCAL VARIABLES: + integer, parameter :: num = 2 ! set soil mapunit number + integer :: wsti(num) ! index to 1st and 2nd largest wst + integer :: k, n, ni, no, ns_i, ns_o + real(r8) :: wt ! map overlap weight + real(r8), allocatable :: wst(:,:) ! overlap weights, by surface type + logical :: has_color ! whether this grid cell has non-zero color + integer, parameter :: miss = 99999 ! missing data indicator + + character(len=*), parameter :: subname = 'dominant_soil_color' + !----------------------------------------------------------------------- + + ns_i = size(mask_i) + if (size(soil_color_i) /= ns_i) then + write(6,*) subname, ' ERROR: size of soil_color_i should match size of mask_i' + write(6,*) 'size(mask_i), size(soil_color_i) = ', & + size(mask_i), size(soil_color_i) + call abort() + end if + + ! find area of overlap for each soil color for each no + + ns_o = size(soil_color_o) + allocate(wst(0:nsoicol,ns_o)) + wst(0:nsoicol,:) = 0 + + ! TODO: need to do a loop to determine + ! the maximum number of over lap cells throughout the grid + ! first get an array that is novr(ns_o) and fill this in - then set + ! maxovr - to max(novr) - then allocate the array wst to be size of + ! maxovr,ns_o or 0:nsoilcol,ns_o + + do n = 1,tgridmap%ns + ni = tgridmap%src_indx(n) + no = tgridmap%dst_indx(n) + wt = tgridmap%wovr(n) * mask_i(ni) + k = soil_color_i(ni) * mask_i(ni) + wst(k,no) = wst(k,no) + wt + enddo + + soil_color_o(:) = 0 + do no = 1,ns_o + + ! If the output cell has any non-zero-colored inputs, then set the weight of + ! zero-colored inputs to 0, to ensure that the zero-color is NOT dominant. + if (any(wst(1:nsoicol,no) > 0.)) then + has_color = .true. + wst(0,no) = 0.0 + else + has_color = .false. + end if + + ! Rank non-zero weights by color type. wsti(1) is the most extensive + ! color type. + + if (has_color) then + call mkrank (nsoicol, wst(0:nsoicol,no), miss, wsti, num) + soil_color_o(no) = wsti(1) + end if + + ! If land but no color, set color to 15 (in older dataset generic + ! soil color 4) + + if (nsoicol == 8) then + if (soil_color_o(no)==0) then + soil_color_o(no) = 4 + end if + else if (nsoicol == 20) then + if (soil_color_o(no)==0) then + soil_color_o(no) = 15 + end if + else + write(6,*) 'MKSOILCOL error: unhandled nsoicol: ', nsoicol + call abort() + end if + + ! Error checks + + if (soil_color_o(no) < 0 .or. soil_color_o(no) > nsoicol) then + write (6,*) 'MKSOILCOL error: land model soil color = ', & + soil_color_o(no),' is not valid for lon,lat = ',no + call abort() + end if + + end do + + deallocate (wst) + + end subroutine dominant_soil_color + + + !----------------------------------------------------------------------- + !BOP + ! + ! !ROUTINE: mkrank + ! + ! !INTERFACE: + subroutine mkrank (n, a, miss, iv, num) + ! + ! !DESCRIPTION: + ! Return indices of largest [num] values in array [a]. + ! + ! !ARGUMENTS: + integer , intent(in) :: n !array length + real(r8), intent(in) :: a(0:n) !array to be ranked + integer , intent(in) :: miss !missing data value + integer , intent(in) :: num !number of largest values requested + integer , intent(out):: iv(num) !index to [num] largest values in array [a] + ! + ! !REVISION HISTORY: + ! Author: Gordon Bonan + ! + ! !LOCAL VARIABLES: + !EOP + real(r8) a_max !maximum value in array + integer i !array index + real(r8) delmax !tolerance for finding if larger value + integer m !do loop index + integer k !do loop index + logical exclude !true if data value has already been chosen + !----------------------------------------------------------------------- + + delmax = 1.e-06 + + ! Find index of largest non-zero number + + iv(1) = miss + a_max = -9999. + + do i = 0, n + if (a(i)>0. .and. (a(i)-a_max)>delmax) then + a_max = a(i) + iv(1) = i + end if + end do + + ! iv(1) = miss indicates no values > 0. this is an error + + if (iv(1) == miss) then + write (6,*) 'MKRANK error: iv(1) = missing' + call abort() + end if + + ! Find indices of the next [num]-1 largest non-zero number. + ! iv(m) = miss if there are no more values > 0 + + do m = 2, num + iv(m) = miss + a_max = -9999. + do i = 0, n + + ! exclude if data value has already been chosen + + exclude = .false. + do k = 1, m-1 + if (i == iv(k)) exclude = .true. + end do + + ! if not already chosen, see if it is the largest of + ! the remaining values + + if (.not. exclude) then + if (a(i)>0. .and. (a(i)-a_max)>delmax) then + a_max = a(i) + iv(m) = i + end if + end if + end do + end do + + end subroutine mkrank + +end module mksoilUtilsMod diff --git a/tools/mksurfdata_esmf/src/mksoildepthMod.F90 b/tools/mksurfdata_esmf/src/mksoildepthMod.F90 new file mode 100644 index 0000000000..c69cf375a4 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mksoildepthMod.F90 @@ -0,0 +1,172 @@ +module mksoildepthMod + +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mksoildepthMod +! +! !DESCRIPTION: +! make fraction soildepth from input soildepth data +! +! !REVISION HISTORY: +! Author: Sam Levis and Bill Sacks +! +!----------------------------------------------------------------------- +! +! !USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush + use mkdomainMod , only : domain_checksame + + implicit none + + private + +! !PUBLIC MEMBER FUNCTIONS: + public mksoildepth ! regrid soildepth data +! +!EOP +!=============================================================== +contains +!=============================================================== + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mksoildepth +! +! !INTERFACE: +subroutine mksoildepth(ldomain, mapfname, datfname, ndiag, soildepth_o) +! +! !DESCRIPTION: +! make soildepth +! +! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkncdio + use mkdiagnosticsMod, only : output_diagnostics_area + use mkchecksMod, only : min_bad, max_bad +! +! !ARGUMENTS: + + implicit none + type(domain_type) , intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: soildepth_o(:) ! output grid: fraction soildepth +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Sam Levis and Bill Sacks +! +! +! !LOCAL VARIABLES: +!EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: data_i(:) ! data on input grid + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + integer :: ncid,varid ! input netCDF id's + integer :: ier ! error status + + real(r8), parameter :: min_valid = 0._r8 ! minimum valid value + real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value + character(len=32) :: subname = 'mksoildepth' + character(len=32) :: varname + integer :: varnum +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make soildepth .....' + call shr_sys_flush(6) + + ! ----------------------------------------------------------------- + ! Read domain and mapping information, check for consistency + ! ----------------------------------------------------------------- + + call domain_read( tdomain, datfname ) + + call gridmap_mapread( tgridmap, mapfname ) + + ! Obtain frac_dst + allocate(frac_dst(ldomain%ns), stat=ier) + if (ier/=0) call abort() + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + allocate(mask_r8(tdomain%ns), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! ----------------------------------------------------------------- + ! Open input file, allocate memory for input data + ! ----------------------------------------------------------------- + + write(6,*)'Open soildepth file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + + allocate(data_i(tdomain%ns), stat=ier) + if (ier/=0) call abort() + + ! ----------------------------------------------------------------- + ! Regrid soildepth + ! ----------------------------------------------------------------- + + varnum = 1 + select case (varnum) + case(1) + varname = 'Avg_Depth_Median' + case(2) + varname = 'Avg_Depth_Mean' + case(3) + varname = 'Upland_Valley_Depth_Median' + case(4) + varname = 'Upland_Valley_Depth_Mean' + case(5) + varname = 'Upland_Hillslope_Depth_Median' + case(6) + varname = 'Upland_Hillslope_Depth_Mean' + case(7) + varname = 'Lowland_Depth_Mean' + case(8) + varname = 'Lowland_Depth_Mean' + end select + +! call check_ret(nf_inq_varid (ncid, 'Avg_Depth_Median', varid), subname) + call check_ret(nf_inq_varid (ncid, varname, varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + call gridmap_areaave_srcmask(tgridmap, data_i, soildepth_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check validity of output data + if (min_bad(soildepth_o, min_valid, 'soildepth') .or. & + max_bad(soildepth_o, max_valid, 'soildepth')) then + call abort() + end if + + call output_diagnostics_area(data_i, soildepth_o, tgridmap, "Soildepth", percent=.false., ndiag=ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! ----------------------------------------------------------------- + ! Close files and deallocate dynamic memory + ! ----------------------------------------------------------------- + + call check_ret(nf_close(ncid), subname) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (data_i) + deallocate (frac_dst) + deallocate (mask_r8) + + write (6,*) 'Successfully made soildepth' + write (6,*) + call shr_sys_flush(6) + +end subroutine mksoildepth + + +end module mksoildepthMod diff --git a/tools/mksurfdata_esmf/src/mksurfdata b/tools/mksurfdata_esmf/src/mksurfdata new file mode 100755 index 0000000000000000000000000000000000000000..97d19adffe5fb999a31acbd81e91d8abfde3a72a GIT binary patch literal 2742328 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�aC%G!@kx%1dJtp~b;v97iV9i_>Vl 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

e|@;k;rc5BHJ_ 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⩰KOt8Wip?EqtyO=G}V4B1&@T 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�B|icHjprSfVyo2GbmOf-9W{h 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ℑHaBA@J35DQlOxbv<_K1rO8{myZg_4i_f6wDLP|B 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�>3#S`OKc#i_G{;D#6O-lpvT@2 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 z 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 z%0DJQ?7s{xTpx2T)j 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

9NQrB`9s?Th3fa(IZ7Pf?Ks(g^J*lTgihF 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

hOs_623<`eY>zh3Ez6=i~oWA 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≫4LrA^2Ds#;TfRZTTTnEwL($b=Z99$06D05Yl=` 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

;!yYYadZL@HrQ&eVX`wFz{+?oh54U->6?20RJT6 z-0z00esme=@3!7YaTD-{uQbo;haT<$-t&rjB$NLS0DlAXV0(l9KftTg+V2|Bj$Z&D z#Qq$^f5cO&pYJZ5E*#du|LhDrFh$F40RKtAcg6X4<2Mch{`A?Z|Awvffkxnwzp8$E z(Jo7Xe|X0sLijAoJ)dy4hlc4I-;E!>L2zpKkG$>v5c45_=-lu1+pjTBaiqk0-_FKQ zE8ah(@}zfCImZH@o>0Htg8nr@a8%y)Q33iPjBAd=y}7_kZm$z0f_|3*{^B!ghmXPm zok%#>x4%y7OT$(9JLGwmv+(ac@JVBT)Ghld&85Htr>h?N@#s|sH|xm2A2N7E`*k<^ z^~(l7L;3W8eh_&2in4xecBseE@1wYhnV*apju8Z=o1gj)_RT7I}ZU5;`fVt@xb2&$A#--O%eQK z!nu7vN1hzSGhcvz!=CD4Oxzhs3j{1@+RB&46YggZrGk%k9^6Ik>dalWfJ1=4IsXs= zQn16tzz4E(1ka5NfCtuV`}UxHuMiwUyFP9My>kiT<`#PMVc@6#ceVg#{Phm-E&8Si z{*vMKckPeijJLhE1>S3|Cx!(#59dGYL4TSx?-2)nl9dnt26%UHsxY|}tj+=+c|$$V z0Pw4TH+-W0xf*`;Uc={-gM~7(wLb6?@P9q1{$vsOyaPOLt!sQuILC|C);xcJ1Yke* zz*=p`>%nI#@V;-n?G+OoM6Qnv=wHJ7U0Wgl1;Agk^0DiHr?LO48}#=B|MC=#7e~WR zo&`Sih3d!T=dS}FYt5ew0S{t)0XFo)2(9n_8*9Hd=L;qPFR|WhS57$VZM_v|8$rKn zXO;7O`120IU5dfilR=+8P3`t%&|eGulwDOGqyHy>_rXsZzc)~X|60%wtX2K=qTG*x zM}BvxAZA^Do99#yOEDk2Gy3lyzz23w`XJ=20)F%NTHgcFUIzm|^mN4^1|9_-I7sa$ zFiHhl34HlJ+Alr@{kg!?)_Z1d1|FHJ`Z43F=LnZ^$Kun3@oLof4Z$gnzpzpfH2ie)4YM2MLY~*T=y{@F@7qez``d z&ww7%z|;60>Td8l-r&}IHqHY+uw{PtVbPRzcJ8sH7f)K2

hJ(CD!}!Cks88x;|>bXP{l{wFmOp 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 CuFe$z literal 0 HcmV?d00001 diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 new file mode 100644 index 0000000000..567b49af2b --- /dev/null +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -0,0 +1,1408 @@ +program mksurfdata + + !----------------------------------------------------------------------- + ! mksurfdata creates land model surface dataset from original "raw" + ! data files. Surface dataset contains model grid, pfts, inland + ! water, glacier, soil texture, soil color, LAI and SAI, urban + ! fraction, and urban parameters. + ! ----------------------------------------------------------------------- + + ! ====================================================================== + ! Summary of input namelist + ! ====================================== + ! Must specify settings for the output grid: + ! ====================================== + ! mksrf_fgrid_mesh -- mesh for output grid + ! ====================================== + ! Must specify settings for input high resolution datafiles + ! ====================================== + ! mksrf_fglacier - Glacier dataset + ! mksrf_fglacierregion - Glacier region ID dataset + ! mksrf_flai ----- Leaf Area Index dataset + ! mksrf_flakwat -- Lake water dataset + ! mksrf_fwetlnd -- Wetland water dataset + ! mksrf_forganic - Organic soil carbon dataset + ! mksrf_fmax ----- Max fractional saturated area dataset + ! mksrf_fsoicol -- Soil color dataset + ! mksrf_fsoitex -- Soil texture dataset + ! mksrf_furbtopo-- Topography dataset (for limiting urban areas) + ! mksrf_furban --- Urban dataset + ! mksrf_fvegtyp -- PFT vegetation type dataset + ! mksrf_fhrvtyp -- harvest type dataset + ! mksrf_fvocef -- Volatile Organic Compund Emission Factor dataset + ! mksrf_fgdp ----- GDP dataset + ! mksrf_fpeat ---- Peatland dataset + ! mksrf_fsoildepth Soil depth dataset + ! mksrf_fabm ----- Agricultural fire peak month dataset + ! mksrf_ftopostats Topography statistics dataset + ! mksrf_fvic ----- VIC parameters dataset + ! ====================================== + ! Must specify meshes for input high resolutin datasets + ! ====================================== + ! mksrf_fpft_mesh -------- Mesh for mksrf_fvegtyp + ! mksrf_flakwat_mesh ----- Mesh for mksrf_flakwat + ! mksrf_fwetlnd_mesh ----- Mesh for mksrf_fwetlnd + ! mksrf_fglacier_mesh ---- Mesh for mksrf_fglacier + ! mksrf_fglacierregion_mesh Mesh for mksrf_fglacierregion + ! mksrf_fsoitex_mesh ----- Mesh for mksrf_fsoitex + ! mksrf_fsoicol_mesh ----- Mesh for mksrf_fsoicol + ! mksrf_furban_mesh ------ Mesh for mksrf_furban + ! mksrf_furbtopo_mesh ---- Mesh for mksrf_furbtopo + ! mksrf_fmax_mesh -------- Mesh for mksrf_fmax + ! mksrf_forganic_mesh ---- Mesh for mksrf_forganic + ! mksrf_fvocef_mesh ------ Mesh for mksrf_fvocef + ! mksrf_flai_mesh -------- Mesh for mksrf_flai + ! mksrf_fhrv_mesh -------- Mesh for mksrf_flai harvesting + ! mksrf_fgdp_mesh -------- Mesh for mksrf_fgdp + ! mksrf_fpeat_mesh ------- Mesh for mksrf_fpeat + ! mksrf_fsoildepth_mesh -- Mesh for mksrf_fsoildepth + ! mksrf_fabm_mesh -------- Mesh for mksrf_fabm + ! mksrf_ftopostats_mesh -- Mesh for mksrf_ftopostats + ! mksrf_fvic_mesh -------- Mesh for mksrf_fvic + ! ====================================== + ! Optionally specify setting for: + ! ====================================== + ! mksrf_fdynuse ----- ASCII text file that lists each year of pft files to use + ! mksrf_gridtype ---- Type of grid (default is 'global') + ! outnc_double ------ If output should be in double precision + ! outnc_large_files - If output should be in NetCDF large file format + ! outnc_vic --------- Output fields needed for VIC + ! outnc_3dglc ------- Output 3D glacier fields (normally only needed for comparasion) + ! nglcec ------------ If you want to change the number of Glacier elevation classes + ! gitdescribe ------- Description of this version from git + ! ====================================== + ! Optional settings to change values for entire area + ! ====================================== + ! all_urban --------- If entire area is urban + ! all_veg ----------- If entire area is to be vegetated (pft_idx and pft_frc then required) + ! no_inlandwet ------ If wetland should be set to 0% over land + ! pft_idx ----------- If you want to change to 100% veg covered with given PFT indices + ! pft_frc ----------- Fractions that correspond to the pft_idx above + ! ================== + ! numpft (if different than default of 16) + ! ====================================== + ! Optional settings to work around urban bug? + ! ====================================== + ! urban_skip_abort_on_invalid_data_check + ! ====================================================================== + + ! !USES: + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs + use shr_pio_mod , only : shr_pio_getiosys, shr_pio_getiotype, shr_pio_getioformat + use shr_pio_mod , only : shr_pio_init1, shr_pio_init2 + use shr_sys_mod , only : shr_sys_abort + ! use mklaiMod , only : mklai + ! use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array + ! use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft + ! use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride + ! use mksoilMod , only : soil_sand, soil_clay, mksoiltex, mksoilInit + ! use mksoilMod , only : soil_color, mksoilcol, mkorganic + ! use mksoilMod , only : soil_fmax, mkfmax + ! use mkvocefMod , only : mkvocef + use mklanwatMod , only : mklakwat, mkwetlnd, mklakparams + ! use mkglacierregionMod , only : mkglacierregion + ! use mkglcmecMod , only : nglcec, mkglcmec, mkglcmecInit, mkglacier + ! use mkharvestMod , only : mkharvest, mkharvest_init, mkharvest_fieldname + ! use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride + ! use mkharvestMod , only : harvestDataType + ! use mkurbanparCommonMod, only : mkelev + ! use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, numurbl + ! use mkgdpMod , only : mkgdp + ! use mkpeatMod , only : mkpeat + ! use mksoildepthMod , only : mksoildepth + ! use mkagfirepkmonthMod , only : mkagfirepkmon + ! use mktopostatsMod , only : mktopostats + ! use mkVICparamsMod , only : mkVICparams + use mkutilsMod , only : normalize_classes_by_gcell, chkerr + use mkfileMod , only : mkfile + use mkvarpar , only : nlevsoi, elev_thresh, numstdpft + use nanMod , only : nan, bigint + use mkpioMod , only : pio_iotype, pio_ioformat, io_subsystem + use mkpioMod , only : mkpio_put_time_slice, mkpio_iodesc_output + use mkvarctl + + implicit none + + ! local variables + type(ESMF_Mesh) :: mesh_model + integer :: nsoicol ! number of model color classes + integer :: k,m,n ! indices + integer :: ni,nj,ns_o ! indices + integer :: lsize_o + integer :: ier ! error status + integer :: nfdyn ! unit numbers + integer :: omode ! netCDF output mode + integer :: ret ! netCDF return status + integer :: ntim ! time sample for dynamic land use + integer :: year ! year for dynamic land use + integer :: year2 ! year for dynamic land use for harvest file + real(r8) :: suma ! sum for error check + character(len=256) :: string ! string read in + integer :: rcode + + ! pio variables + type(file_desc_t) :: pioid + type(var_desc_t) :: pio_varid + type(io_desc_t) :: pio_iodesc + + ! data arrays + real(r8), pointer :: landfrac_pft(:) ! PFT data: % land per gridcell + real(r8), pointer :: pctlnd_pft(:) ! PFT data: % of gridcell for PFTs + real(r8), pointer :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs + integer , pointer :: pftdata_mask(:) ! mask indicating real or fake land type +#ifdef TODO + type(pct_pft_type), pointer :: pctnatpft(:) ! % of grid cell that is nat veg, and breakdown into PFTs + type(pct_pft_type), pointer :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series + type(pct_pft_type), pointer :: pctcft(:) ! % of grid cell that is crop, and breakdown into CFTs + type(pct_pft_type), pointer :: pctcft_max(:) ! % of grid cell maximum CFTs of the time series +#endif + real(r8) :: harvest_initval ! initial value for harvest variables + real(r8), pointer :: harvest1D(:) ! harvest 1D data: normalized harvesting + real(r8), pointer :: harvest2D(:,:) ! harvest 1D data: normalized harvesting + real(r8), pointer :: pctgla(:) ! percent of grid cell that is glacier + real(r8), pointer :: pctglc_gic(:) ! percent of grid cell that is gic (% of glc landunit) + real(r8), pointer :: pctglc_icesheet(:) ! percent of grid cell that is ice sheet (% of glc landunit) + real(r8), pointer :: pctglcmec(:,:) ! glacier_mec pct coverage in each class (% of landunit) + real(r8), pointer :: topoglcmec(:,:) ! glacier_mec sfc elevation in each gridcell and class + real(r8), pointer :: pctglcmec_gic(:,:) ! GIC pct coverage in each class (% of landunit) + real(r8), pointer :: pctglcmec_icesheet(:,:) ! icesheet pct coverage in each class (% of landunit) + real(r8), pointer :: elevclass(:) ! glacier_mec elevation classes + integer, pointer :: glacier_region(:) ! glacier region ID + real(r8), pointer :: pctlak(:) ! percent of grid cell that is lake + real(r8), pointer :: pctwet(:) ! percent of grid cell that is wetland + real(r8), pointer :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) + real(r8), pointer :: urbn_classes(:,:) ! percent cover of each urban class, as % of total urban area + real(r8), pointer :: urbn_classes_g(:,:) ! percent cover of each urban class, as % of grid cell + real(r8), pointer :: elev(:) ! glc elevation (m) + real(r8), pointer :: fmax(:) ! fractional saturated area + integer , pointer :: soicol(:) ! soil color + real(r8), pointer :: pctsand(:,:) ! soil texture: percent sand + real(r8), pointer :: pctclay(:,:) ! soil texture: percent clay + real(r8), pointer :: ef1_btr(:) ! Isoprene emission factor for broadleaf + real(r8), pointer :: ef1_fet(:) ! Isoprene emission factor for fine/everg + real(r8), pointer :: ef1_fdt(:) ! Isoprene emission factor for fine/dec + real(r8), pointer :: ef1_shr(:) ! Isoprene emission factor for shrubs + real(r8), pointer :: ef1_grs(:) ! Isoprene emission factor for grasses + real(r8), pointer :: ef1_crp(:) ! Isoprene emission factor for crops + real(r8), pointer :: organic(:,:) ! organic matter density (kg/m3) + real(r8), pointer :: gdp(:) ! GDP (x1000 1995 US$/capita) + real(r8), pointer :: fpeat(:) ! peatland fraction of gridcell + real(r8), pointer :: soildepth(:) ! soil depth (m) + integer , pointer :: agfirepkmon(:) ! agricultural fire peak month + integer , pointer :: urban_region(:) ! urban region ID + real(r8), pointer :: topo_stddev(:) ! standard deviation of elevation (m) + real(r8), pointer :: slope(:) ! topographic slope (degrees) + real(r8), pointer :: vic_binfl(:) ! VIC b + + ! parameters (unitless) + real(r8), pointer :: vic_ws(:) ! VIC Ws parameter (unitless) + real(r8), pointer :: vic_dsmax(:) ! VIC Dsmax parameter (mm/day) + real(r8), pointer :: vic_ds(:) ! VIC Ds parameter (unitless) + real(r8), pointer :: lakedepth(:) ! lake depth (m) + integer , pointer :: harvind1D(:) ! Indices of 1D harvest fields + integer , pointer :: harvind2D(:) ! Indices of 2D harvest fields + logical :: zero_out ! if should zero glacier out +#ifdef TODO + type(harvestDataType) :: harvdata +#endif + + ! esmf variables + integer :: rc + type(ESMF_LogKind_Flag) :: logkindflag + type(ESMF_VM) :: vm + character(len=CS) :: varname + character(len=32) :: subname = 'mksrfdata' ! program name + + ! NOTE(bja, 2015-01) added to work around a ?bug? causing 1x1_urbanc_alpha to abort. See + !/glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 + logical :: urban_skip_abort_on_invalid_data_check + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + ! ------------------------------------------------------------ + + ! ------------------ + ! Initialize MPI + ! ------------------ + + call MPI_init(rc) + mpicom = mpi_comm_world + + ! ------------------ + ! Initialize PIO + ! ------------------ + + ! First phase - reads the pio default settings from file pio_in, namelist pio_default_inparm + ! It then returns the new compute comm in Global_Comm and sets module variable io_comm. + call shr_pio_init1("pio_in", mpicom) + + ! Determine my rank + call mpi_comm_rank(mpicom, iam, ier) + + ! Initialize PIO - second phase + call shr_pio_init2((/mpicom/), (/mpicom/)) + io_subsystem => shr_pio_getiosys() + pio_iotype = shr_pio_getiotype() + pio_ioformat = shr_pio_getioformat() + + ! ------------------ + ! Read input namelist on root_task and broadcast to all pes + ! ------------------ + + ! root_task is a module variable in mkvarctl + root_task = (iam == 0) + call read_namelist_input() + + ! ------------------ + ! Initialize ESMF and get mpicom from ESMF + ! ------------------ + + if (create_esmf_pet_files) then + logkindflag = ESMF_LOGKIND_MULTI + else + logkindflag = ESMF_LOGKIND_MULTI_ON_ERROR + end if + call ESMF_Initialize(mpiCommunicator=MPICOM, logkindflag=logkindflag, logappendflag=.false., & + ioUnitLBound=5001, ioUnitUBound=5101, vm=vm, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMGetGlobal(vm, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMGet(vm, mpicommunicator=mpicom, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_LogSet(flush=.true.) + call ESMF_LogWrite("mksurfdata starting", ESMF_LOGMSG_INFO) + + ! ------------------ + ! open output ndiag file + ! ------------------ + + if (fsurlog == ' ') then + call shr_sys_abort(' ERROR: must specify fsurlog in namelist') + else + open (newunit=ndiag, file=trim(fsurlog), iostat=ier) + if (ier /= 0) then + call shr_sys_abort(' failed to open ndiag file '//trim(fsurlog)) + else + if (root_task) then + write(ndiag,*)' successfully opened ndiag file ',trim(fsurlog) + end if + end if + end if + + ! ------------------ + ! ------------------ + + if (root_task) then + write (ndiag,*) 'Attempting to create surface boundary data .....' + write (ndiag,'(72a1)') ("-",n=1,60) + end if + + call check_namelist_input() + + ! ------------------ + ! Write out namelist input to ndiag + ! ------------------ + + call write_namelist_input() + + ! ---------------------------------------------------------------------- + ! Call module initialization routines + ! ---------------------------------------------------------------------- + + ! call mksoilInit( ) + ! call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) + ! allocate ( elevclass(nglcec+1) ) + ! call mkglcmecInit (elevclass) + ! call mkurbanInit (mksrf_furban) + + ! ---------------------------------------------------------------------- + ! Allocate and initialize dynamic memory for local variables + ! ---------------------------------------------------------------------- + + ! Read in model mesh to determine the number of local points + mesh_model = ESMF_MeshCreate(filename=trim(mksrf_fgrid_mesh), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + ! Get the number of local destination points on my processor (lsize_o) + call ESMF_MeshGet(mesh_model, numOwnedElements=lsize_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + allocate ( landfrac_pft(lsize_o)) ; landfrac_pft(:) = spval + allocate ( pctlnd_pft(lsize_o)) ; pctlnd_pft(:) = spval + allocate ( pftdata_mask(lsize_o)) ; pftdata_mask(:) = -999 + !allocate ( pctnatpft(lsize_o)) ; + !allocate ( pctnatpft_max(lsize_o)) ; + !allocate ( pctcft(lsize_o)) ; + !allocate ( pctcft_max(lsize_o)) ; + allocate ( pctgla(lsize_o)) ; pctgla(:) = spval + allocate ( pctlak(lsize_o)) ; pctlak(:) = spval + allocate ( pctwet(lsize_o)) ; pctwet(:) = spval + allocate ( pcturb(lsize_o)) ; pcturb(:) = spval + allocate ( urban_region(lsize_o)) ; urban_region(:) = -999 + !allocate ( urbn_classes(lsize_o,numurbl)) ; urbn_classes(:,:) = spval + !allocate ( urbn_classes_g(lsize_o,numurbl)) ; urbn_classes_g(:,:) = spval + allocate ( pctsand(lsize_o,nlevsoi)) ; pctsand(:,:) = spval + allocate ( pctclay(lsize_o,nlevsoi)) ; pctclay(:,:) = spval + allocate ( soicol(lsize_o)) ; soicol(:) = -999 + allocate ( gdp(lsize_o)) ; gdp(:) = spval + allocate ( fpeat(lsize_o)) ; fpeat(:) = spval + allocate ( soildepth(lsize_o)) ; soildepth(:) = spval + allocate ( agfirepkmon(lsize_o)) ; agfirepkmon(:) = -999 + allocate ( topo_stddev(lsize_o)) ; topo_stddev(:) = spval + allocate ( slope(lsize_o)) ; slope(:) = spval + allocate ( vic_binfl(lsize_o)) ; vic_binfl(:) = spval + allocate ( vic_ws(lsize_o)) ; vic_ws(:) = spval + allocate ( vic_dsmax(lsize_o)) ; vic_dsmax(:) = spval + allocate ( vic_ds(lsize_o)) ; vic_ds(:) = spval + allocate ( lakedepth(lsize_o)) ; lakedepth(:) = spval + allocate ( glacier_region(lsize_o)) ; glacier_region(:) = -999 + + ! ---------------------------------------------------------------------- + ! Read in and interpolate surface data set fields + ! ---------------------------------------------------------------------- + + ! ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] + ! call mkpft( mapfname=map_fpft, fpft=mksrf_fvegtyp, ndiag=ndiag, pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft) + + ! ! Create harvesting data at model resolution + ! if (all_veg) then + ! ! In this case, we don't call mkharvest, so we want the harvest variables to be + ! ! initialized reasonably. + ! harvest_initval = 0._r8 + ! else + ! harvest_initval = spval + ! end if + ! call mkharvest_init( lsize_o, harvest_initval, harvdata, mksrf_fhrvtyp ) + ! if ( .not. all_veg )then + ! call mkharvest( mapfname=map_fharvest, datfname=mksrf_fhrvtyp, ndiag=ndiag, harvdata=harvdata ) + ! end if + + ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] + zero_out = all_urban .or. all_veg + call mklakwat(mksrf_flakwat, mksrf_flakwat_mesh, mesh_model, zero_out, pctlak, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') + + zero_out = all_urban .or. all_veg .or. no_inlandwet + call mkwetlnd(mksrf_flakwat, mksrf_flakwat_mesh, mesh_model, zero_out, pctwet, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkwetlnd') + + call mklakparams(mksrf_flakwat, mksrf_flakwat_mesh, mesh_model, lakedepth, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkwetlnd') + + ! ! Make glacier fraction [pctgla] from [fglacier] dataset + ! call mkglacier ( mapfname=map_fglacier, datfname=mksrf_fglacier, ndiag=ndiag, zero_out=all_urban.or.all_veg, glac_o=pctgla) + + ! ! Make glacier region ID [glacier_region] from [fglacierregion] dataset + ! call mkglacierregion ( mapfname=map_fglacierregion, & + ! datfname=mksrf_fglacierregion, ndiag=ndiag, glacier_region_o = glacier_region) + + ! ! Make soil texture [pctsand, pctclay] [fsoitex] + ! call mksoiltex ( mapfname=map_fsoitex, datfname=mksrf_fsoitex, ndiag=ndiag, sand_o=pctsand, clay_o=pctclay) + + ! ! Make soil color classes [soicol] [fsoicol] + ! call mksoicol ( mapfname=map_fsoicol, datfname=mksrf_fsoicol, ndiag=ndiag, soil_color_o=soicol, nsoicol=nsoicol) + + ! ! Make fmax [fmax] from [fmax] dataset + ! allocate(fmax(lsize_o)); fmax(:) = spval + ! call mkfmax ( mapfname=map_fmax, datfname=mksrf_fmax, ndiag=ndiag, fmax_o=fmax) + + ! ! Make GDP data [gdp] from [gdp] + ! call mkgdp ( mapfname=map_fgdp, datfname=mksrf_fgdp, ndiag=ndiag, gdp_o=gdp) + + ! ! Make peat data [fpeat] from [peatf] + ! call mkpeat ( mapfname=map_fpeat, datfname=mksrf_fpeat, ndiag=ndiag, peat_o=fpeat) + + ! ! Make soil depth data [soildepth] from [soildepthf] + ! call mksoildepth ( mapfname=map_fsoildepth, datfname=mksrf_fsoildepth, ndiag=ndiag, soildepth_o=soildepth) + + ! ! Make agricultural fire peak month data [abm] from [abm] + ! call mkagfirepkmon ( mapfname=map_fabm, datfname=mksrf_fabm, ndiag=ndiag, agfirepkmon_o=agfirepkmon) + + ! ! Make urban fraction [pcturb] from [furban] dataset + ! call mkurban ( mapfname=map_furban, datfname=mksrf_furban, & + ! ndiag=ndiag, zero_out=all_veg, urbn_o=pcturb, urbn_classes_o=urbn_classes, region_o=urban_region) + + ! ! Make elevation [elev] from [ftopo, ffrac] dataset + ! ! Used only to screen pcturb, screen pcturb by elevation threshold from elev dataset + ! if ( .not. all_urban .and. .not. all_veg )then + ! allocate(elev(lsize_o)) + ! elev(:) = spval + ! ! NOTE(wjs, 2016-01-15) This uses the 'TOPO_ICE' variable for historical reasons + ! ! (this same dataset used to be used for glacier-related purposes as well). + ! ! TODO(wjs, 2016-01-15) A better solution for this urban screening would probably + ! ! be to modify the raw urban data; in that case, I believe we could remove furbtopo. + ! call mkelev ( mapfname=map_furbtopo, datfname=mksrf_furbtopo, varname='TOPO_ICE', ndiag=ndiag, elev_o=elev) + ! where (elev .gt. elev_thresh) + ! pcturb = 0._r8 + ! end where + ! deallocate(elev) + ! end if + + ! ! Compute topography statistics [topo_stddev, slope] from [ftopostats] + ! call mktopostats ( mapfname=map_ftopostats, datfname=mksrf_ftopostats, & + ! ndiag=ndiag, topo_stddev_o=topo_stddev, slope_o=slope, std_elev=std_elev) + + ! ! Make VIC parameters [binfl, ws, dsmax, ds] from [fvic] + ! if ( outnc_vic )then + ! call mkVICparams ( mapfname=map_fvic, datfname=mksrf_fvic, ndiag=ndiag, & + ! binfl_o=vic_binfl, ws_o=vic_ws, dsmax_o=vic_dsmax, ds_o=vic_ds) + ! end if + + ! ! Make organic matter density [organic] [forganic] + ! allocate (organic(lsize_o,nlevsoi)) + ! organic(:,:) = spval + ! call mkorganic ( mapfname=map_forganic, datfname=mksrf_forganic, ndiag=ndiag, organic_o=organic) + + ! ! Make VOC emission factors for isoprene & + ! ! [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] + ! allocate ( ef1_btr(lsize_o) , & + ! ef1_fet(lsize_o) , & + ! ef1_fdt(lsize_o) , & + ! ef1_shr(lsize_o) , & + ! ef1_grs(lsize_o) , & + ! ef1_crp(lsize_o) ) + ! ef1_btr(:) = 0._r8 + ! ef1_fet(:) = 0._r8 + ! ef1_fdt(:) = 0._r8 + ! ef1_shr(:) = 0._r8 + ! ef1_grs(:) = 0._r8 + ! ef1_crp(:) = 0._r8 + + ! call mkvocef ( mapfname=map_fvocef, datfname=mksrf_fvocef, ndiag=ndiag, & + ! ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & + ! ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp) + + ! ! Do landuse changes such as for the poles, etc. + ! call change_landuse( dynpft=.false. ) + + ! ---------------------------------------------------------------------- + ! Modify interpolated fields based on additional constrants + ! ---------------------------------------------------------------------- + + do n = 1,lsize_o + ! Truncate all percentage fields on output grid. This is needed to + ! insure that wt is zero (not a very small number such as + ! 1e-16) where it really should be zero + + do k = 1,nlevsoi + pctsand(n,k) = float(nint(pctsand(n,k))) + pctclay(n,k) = float(nint(pctclay(n,k))) + end do + pctlak(n) = float(nint(pctlak(n))) + pctwet(n) = float(nint(pctwet(n))) + pctgla(n) = float(nint(pctgla(n))) + + ! Assume wetland, glacier and/or lake when dataset landmask implies ocean + ! (assume medium soil color (15) and loamy texture). + ! Also set pftdata_mask here + + if (pctlnd_pft(n) < 1.e-6_r8) then + pftdata_mask(n) = 0 + soicol(n) = 15 + if (pctgla(n) < 1.e-6_r8) then + pctwet(n) = 100._r8 - pctlak(n) + pctgla(n) = 0._r8 + else + pctwet(n) = max(100._r8 - pctgla(n) - pctlak(n), 0.0_r8) + end if + pcturb(n) = 0._r8 + !call pctnatpft(n)%set_pct_l2g(0._r8) + !call pctcft(n)%set_pct_l2g(0._r8) + pctsand(n,:) = 43._r8 + pctclay(n,:) = 18._r8 + organic(n,:) = 0._r8 + else + pftdata_mask(n) = 1 + end if + + ! Make sure sum of land cover types does not exceed 100. If it does, + ! subtract excess from most dominant land cover. + + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + if (suma > 250._r4) then + write (6,*) subname, ' error: sum of pctlak, pctwet,', & + 'pcturb and pctgla is greater than 250%' + write (6,*)'n,pctlak,pctwet,pcturb,pctgla= ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n) + call abort() + else if (suma > 100._r4) then + pctlak(n) = pctlak(n) * 100._r8/suma + pctwet(n) = pctwet(n) * 100._r8/suma + pcturb(n) = pcturb(n) * 100._r8/suma + pctgla(n) = pctgla(n) * 100._r8/suma + end if + + end do + + ! call normalizencheck_landuse() + + ! Write out sum of PFT's + + ! do k = natpft_lb,natpft_ub + ! suma = 0._r8 + ! do n = 1,lsize_o + ! suma = suma + pctnatpft(n)%get_one_pct_p2g(k) + ! enddo + ! write(6,*) 'sum over domain of pft ',k,suma + ! enddo + ! write(6,*) + + ! do k = cft_lb,cft_ub + ! suma = 0._r8 + ! do n = 1,lsize_o + ! suma = suma + pctcft(n)%get_one_pct_p2g(k) + ! enddo + ! write(6,*) 'sum over domain of cft ',k,suma + ! enddo + ! write(6,*) + + ! ! Make final values of percent urban by class + ! ! This call needs to occur after all corrections are made to pcturb + + ! call normalize_classes_by_gcell(urbn_classes, pcturb, urbn_classes_g) + + ! ! Make glacier multiple elevation classes [pctglcmec,topoglcmec] from [fglacier] dataset + ! ! This call needs to occur after pctgla has been adjusted for the final time + + ! allocate (pctglcmec(lsize_o,nglcec), & + ! topoglcmec(lsize_o,nglcec) ) + ! if ( outnc_3dglc )then + ! allocate( & + ! pctglcmec_gic(lsize_o,nglcec), & + ! pctglcmec_icesheet(lsize_o,nglcec)) + ! allocate (pctglc_gic(lsize_o)) + ! allocate (pctglc_icesheet(lsize_o)) + ! end if + + ! pctglcmec(:,:) = spval + ! topoglcmec(:,:) = spval + + ! if ( outnc_3dglc )then + ! call mkglcmec ( mapfname=map_fglacier, & + ! datfname_fglacier=mksrf_fglacier, ndiag=ndiag, & + ! pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, & + ! pctglcmec_gic_o=pctglcmec_gic, pctglcmec_icesheet_o=pctglcmec_icesheet, & + ! pctglc_gic_o=pctglc_gic, pctglc_icesheet_o=pctglc_icesheet) + ! else + ! call mkglcmec ( mapfname=map_fglacier, & + ! datfname_fglacier=mksrf_fglacier, ndiag=ndiag, & + ! pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec ) + ! end if + + ! ! Determine fractional land from pft dataset + + ! do n = 1,lsize_o + ! landfrac_pft(n) = pctlnd_pft(n)/100._r8 + ! end do + + ! ---------------------------------------------------------------------- + ! Create surface dataset + ! ---------------------------------------------------------------------- + + ! Create netCDF surface dataset. + + ! If fsurdat is blank, then we do not write a surface dataset - but we may still + ! write a dynamic landuse file. This is useful if we are creating many datasets at + ! once, and don't want duplicate surface datasets. + ! + ! TODO(wjs, 2016-01-26) Ideally, we would also avoid doing the processing of + ! variables that are just needed by the surface dataset (not by the dynamic landuse + ! file). However, this would require some analysis of the above code, to determine + ! which processing is needed (directly or indirectly) in order to create a dynamic + ! landuse file. + + if (fsurdat /= ' ') then + + ! The following variables need to be output as int + ! nf_put_var_int(ncid, varid, (/(n,n=natpft_lb,natpft_ub)/)) + ! nf_put_var_int(ncid, varid, (/(n,n=cft_lb,cft_ub)/)) + ! nf_put_var_int(ncid, varid, pftdata_mask) ! derived in mksurfdata + ! nf_put_var_int(ncid, varid, nsoicol) ! set in mksoicol + ! nf_put_var_int(ncid, varid, soicol) ! set in mksoicol + ! nf_put_var_int(ncid, varid, glacier_region) + ! nf_put_var_int(ncid, varid, agfirepkmon) + ! nf_put_var_int(ncid, varid, urban_region) + + !call mkfile( vm, nx, ny, trim(fsurdat), harvdata, dynlanduse = .false., pioid=pioid) + call mkfile( vm, mksrf_fgrid_mesh_nx, mksrf_fgrid_mesh_ny, trim(fsurdat), dynlanduse=.false., pioid=pioid) + + ! write area, longxy and latixy + ! TODO: fill this in + ! call check_ret(nf_open(trim(fname), nf_write, ncid), subname) + ! File will be in define mode. Set fill mode to "no fill" to optimize performance + ! call check_ret(nf_set_fill (ncid, nf_nofill, omode), subname) + ! call check_ret(nf_inq_varid(ncid, 'AREA', varid), subname) + ! call check_ret(nf_put_var_double(ncid, varid, domain%area), subname) + ! call check_ret(nf_inq_varid(ncid, 'LONGXY', varid), subname) + ! call check_ret(nf_put_var_double(ncid, varid, domain%lonc), subname) + ! call check_ret(nf_inq_varid(ncid, 'LATIXY', varid), subname) + ! call check_ret(nf_put_var_double(ncid, varid, domain%latc), subname) + + ! Synchronize the disk copy of a netCDF dataset with in-memory buffers + !call check_ret(nf_sync(ncid), subname) + + ! Close grid data dataset + !call check_ret(nf_close(ncid), subname) + + ! Write fields OTHER THAN lai, sai, heights, and urban parameters to netcdf surface dataset + + ! rcode = pio_inq_varid(pioid, 'natpft', pio_varid) + ! rcode = pio_put_var_int(pioid, pio_varid, (/(n,n=natpft_lb,natpft_ub)/))) + + ! if (num_cft > 0) then + ! rcode = pio_inq_varid(pioid, 'cft', pio_varid)) + ! rcode = pio_put_var_int(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/))) + ! end if + + varname = 'PFTDATA_MASK' + call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + call pio_write_darray(pioid, pio_varid, pio_iodesc, pftdata_mask, rcode) + !call pio_write_darray(io_file(lfile_ind), varid, iodesc, fldptr2(:,n), rcode, fillval=lfillvalue) + call pio_freedecomp(pioid, pio_iodesc) + + varname = 'LANDFRAC_PFT' + call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + call pio_write_darray(pioid, pio_varid, pio_iodesc, landfrac_pft, rcode) + call pio_freedecomp(pioid, pio_iodesc) + + varname = 'mxsoil_color' + ! TODO: output this as an integer - not calling darray + !call pio_write_darray(pioid, pio_varid, pio_iodesc, nsoicol, rcode) + + varname = 'SOIL_COLOR' + call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + call pio_write_darray(pioid, pio_varid, pio_iodesc, soicol, rcode) + call pio_freedecomp(pioid, pio_iodesc) + + varname = 'PCT_SAND' + call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + call pio_write_darray(pioid, pio_varid, pio_iodesc, pctsand, rcode) + call pio_freedecomp(pioid, pio_iodesc) + + varname = 'PCT_CLAY' + call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + call pio_write_darray(pioid, pio_varid, pio_iodesc, pctclay, rcode) + call pio_freedecomp(pioid, pio_iodesc) + + varname = 'PCT_WETLAND' + call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + call pio_write_darray(pioid, pio_varid, pio_iodesc, pctwet, rcode) + call pio_freedecomp(pioid, pio_iodesc) + + varname = 'PCT_LAKE' + call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + call pio_write_darray(pioid, pio_varid, pio_iodesc, pctlak, rcode) + call pio_freedecomp(pioid, pio_iodesc) + + varname = 'PCT_GLACIER' + call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + call pio_write_darray(pioid, pio_varid, pio_iodesc, pctgla, rcode) + call pio_freedecomp(pioid, pio_iodesc) + + varname = 'GLACIER_REGION' + call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + call pio_write_darray(pioid, pio_varid, pio_iodesc, glacier_region, rcode) + call pio_freedecomp(pioid, pio_iodesc) + + varname = 'PCT_GLC_MEC' + call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + call pio_write_darray(pioid, pio_varid, pio_iodesc, pctglcmec, rcode) + call pio_freedecomp(pioid, pio_iodesc) + + varname = 'GLC_MEC' + call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + call pio_write_darray(pioid, pio_varid, pio_iodesc, elevclass, rcode) + call pio_freedecomp(pioid, pio_iodesc) + + if ( outnc_3dglc )then + !'TOPO_GLC_MEC', topoglcmec + ! 'PCT_GLC_MEC_ICESHEET', pctglcmec_icesheet + ! 'PCT_GLC_GIC', pctglc_gic + ! 'PCT_GLC_ICESHEET', pctglc_icesheet + end if + + !'PCT_URBAN', ut_urbn_classes_g + !'PCT_NATVEG', get_pct_l2g_array(pctnatpft) + + ! rcode = pio_inq_varid(pioid, 'PCT_CROP', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_l2g_array(pctcft))) + + ! rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_p2l_array(pctnatpft))) + + ! if (num_cft > 0) then + ! rcode = pio_inq_varid(pioid, 'PCT_CFT', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_p2l_array(pctcft))) + ! end if + + ! call harvdata%getFieldsIdx( harvind1D, harvind2D ) + ! do k = 1, harvdata%num1Dfields() + ! rcode = pio_inq_varid(pioid, trim(mkharvest_fieldname(harvind1D(k),constant=.true.)), pio_varid)) + ! harvest1D => harvdata%get1DFieldPtr( harvind1D(k), output=.true. ) + ! rcode = pio_put_var_double(pioid, pio_varid, harvest1D)) + ! end do + ! do k = 1, harvdata%num2Dfields() + ! rcode = pio_inq_varid(pioid, trim(mkharvest_fieldname(harvind2D(k),constant=.true.)), pio_varid)) + ! harvest2D => harvdata%get2DFieldPtr( harvind2D(k), output=.true. ) + ! rcode = pio_put_var_double(pioid, pio_varid, harvest2D)) + ! end do + ! deallocate( harvind1D, harvind2D ) + + ! rcode = pio_inq_varid(pioid, 'FMAX', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, fmax)) + + ! rcode = pio_inq_varid(pioid, 'gdp', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, gdp)) + + ! rcode = pio_inq_varid(pioid, 'peatf', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, fpeat)) + + + ! ! rcode = pio_inq_varid(pioid, 'Avg_Depth_Median', pio_varid)) + ! rcode = pio_inq_pio_varid(pioid, 'zbedrock', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, soildepth)) + + ! rcode = pio_inq_varid(pioid, 'abm', pio_varid)) + ! rcode = pio_put_var_int(pioid, pio_varid, agfirepkmon)) + + ! rcode = pio_inq_pio_varid(pioid, 'SLOPE', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, slope)) + + ! rcode = pio_inq_varid(pioid, 'STD_ELEV', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, topo_stddev)) + + ! if ( outnc_vic )then + ! rcode = pio_inq_varid(pioid, 'binfl', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, vic_binfl)) + + ! rcode = pio_inq_varid(pioid, 'Ws', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, vic_ws)) + + ! rcode = pio_inq_varid(pioid, 'Dsmax', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, vic_dsmax)) + + ! rcode = pio_inq_varid(pioid, 'Ds', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, vic_ds)) + ! end if + + ! rcode = pio_inq_varid(pioid, 'LAKEDEPTH', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, lakedepth)) + + ! rcode = pio_inq_varid(pioid, 'EF1_BTR', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, ef1_btr)) + + ! rcode = pio_inq_varid(pioid, 'EF1_FET', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, ef1_fet)) + + ! rcode = pio_inq_varid(pioid, 'EF1_FDT', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, ef1_fdt)) + + ! rcode = pio_inq_varid(pioid, 'EF1_SHR', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, ef1_shr)) + + ! rcode = pio_inq_varid(pioid, 'EF1_GRS', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, ef1_grs)) + + ! rcode = pio_inq_varid(pioid, 'EF1_CRP', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, ef1_crp)) + + ! rcode = pio_inq_varid(pioid, 'ORGANIC', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, organic)) + + ! rcode = pio_inq_varid(pioid, 'URBAN_REGION_ID', pio_varid)) + ! rcode = pio_put_var_int(pioid, pio_varid, urban_region)) + + ! ! Synchronize the disk copy of a netCDF dataset with in-memory buffers + + ! rcode = pio_sync(pioid)) + + ! ---------------------------------------------------------------------- + ! Make Urban Parameters from raw input data and write to surface dataset + ! Write to netcdf file is done inside mkurbanpar routine + ! ---------------------------------------------------------------------- + + ! write(6,*)'calling mkurbanpar' + ! call mkurbanpar(datfname=mksrf_furban, pioido=pioid, region_o=urban_region, & + ! urbn_classes_gcell_o=urbn_classes_g, & + ! urban_skip_abort_on_invalid_data_check=urban_skip_abort_on_invalid_data_check) + + ! ---------------------------------------------------------------------- + ! Make LAI and SAI from 1/2 degree data and write to surface dataset + ! Write to netcdf file is done inside mklai routine + ! ---------------------------------------------------------------------- + + ! write(6,*)'calling mklai' + ! call mklai( mapfname=map_flai, datfname=mksrf_flai, ndiag=ndiag, pioido=pioid ) + + ! Close surface dataset + + call pio_closefile(pioid) + + write (6,'(72a1)') ("-",n=1,60) + write (6,*)' land model surface data set successfully created for ', & + 'grid of size ',lsize_o + + else ! fsurdat == ' ' + + write (6,*) 'fsurdat is blank: skipping writing surface dataset' + + end if ! if (fsurdat /= ' ') + + ! Deallocate arrays NOT needed for dynamic-pft section of code + + deallocate ( organic ) + deallocate ( ef1_btr, ef1_fet, ef1_fdt, ef1_shr, ef1_grs, ef1_crp ) + deallocate ( pctglcmec, topoglcmec) + if ( outnc_3dglc ) deallocate ( pctglc_gic, pctglc_icesheet) + deallocate ( elevclass ) + deallocate ( fmax ) + deallocate ( pctsand, pctclay ) + deallocate ( soicol ) + deallocate ( gdp, fpeat, agfirepkmon ) + deallocate ( soildepth ) + deallocate ( topo_stddev, slope ) + deallocate ( vic_binfl, vic_ws, vic_dsmax, vic_ds ) + deallocate ( lakedepth ) + deallocate ( glacier_region ) + +#ifdef TODO + call harvdata%clean() +#endif + + ! ---------------------------------------------------------------------- + ! Create dynamic land use dataset if appropriate + ! ---------------------------------------------------------------------- + + if (mksrf_fdynuse /= ' ') then + + ! write(6,*)'creating dynamic land use dataset' + + ! allocate(pctlnd_pft_dyn(lsize_o)) + ! call mkharvest_init( lsize_o, spval, harvdata, mksrf_fhrvtyp ) + + ! if (fdyndat == ' ') then + ! write(6,*)' must specify fdyndat in namelist if mksrf_fdynuse is not blank' + ! call abort() + ! end if + + ! ! Define dimensions and global attributes + + ! call mkfile( fdyndat, harvdata, dynlanduse=.true., pioid) + + ! ! Write fields other pft to dynamic land use dataset + + ! call domain_write( fdyndat) + + ! rcode = pio_open(trim(fdyndat), nf_write, pioid)) + ! rcode = pio_set_fill (pioid, nf_nofill, omode)) + + ! rcode = pio_inq_varid(pioid, 'natpft', pio_varid)) + ! rcode = pio_put_var_int(pioid, pio_varid, (/(n,n=natpft_lb,natpft_ub)/)) + + ! if (num_cft > 0) then + ! rcode = pio_inq_varid(pioid, 'cft', pio_varid)) + ! rcode = pio_put_var_int(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/) + ! end if + + ! rcode = pio_inq_varid(pioid, 'PFTDATA_MASK', pio_varid)) + ! rcode = pio_put_var_int(pioid, pio_varid, pftdata_mask)) + + ! rcode = pio_inq_varid(pioid, 'LANDFRAC_PFT', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, landfrac_pft)) + + ! ! Synchronize the disk copy of a netCDF dataset with in-memory buffers + + ! rcode = pio_sync(pioid)) + + ! ! Read in each dynamic pft landuse dataset + + ! call opnfil (newunit=nfdyn, mksrf_fdynuse, nfdyn, 'f') + + ! pctnatpft_max = pctnatpft + ! pctcft_max = pctcft + + ! ntim = 0 + ! do + ! ! Read input pft data + + ! read(nfdyn, '(A195,1x,I4)', iostat=ier) string, year + ! if (ier /= 0) exit + ! ! + ! ! If pft fraction override is set, than intrepret string as PFT and harvesting override values + ! ! + ! if ( all_veg )then + ! fname = ' ' + ! fhrvname = ' ' + ! call mkpft_parse_oride(string) + ! call mkharvest_parse_oride(string) + ! write(6, '(a, i4, a)') 'PFT and harvesting values for year ', year, ' :' + ! write(6, '(a, a)') ' ', trim(string) + ! ! + ! ! Otherwise intrepret string as a filename with PFT and harvesting values in it + ! ! + ! else + ! fname = string + ! write(6,*)'input pft dynamic dataset for year ', year, ' is : ', trim(fname) + ! read(nfdyn, '(A195,1x,I4)', iostat=ier) fhrvname, year2 + ! if ( year2 /= year ) then + ! write(6,*) subname, ' error: year for harvest not equal to year for PFT files' + ! call abort() + ! end if + ! end if + ! ntim = ntim + 1 + + ! ! Create pctpft data at model resolution + + ! call mkpft( mapfname=map_fpft, fpft=fname, & + ! ndiag=ndiag, pctlnd_o=pctlnd_pft_dyn, pctnatpft_o=pctnatpft, pctcft_o=pctcft ) + + ! ! Create harvesting data at model resolution + + ! call mkharvest( mapfname=map_fharvest, datfname=fhrvname, & + ! ndiag=ndiag, harvdata=harvdata ) + + ! ! Consistency check on input land fraction + + ! do n = 1,lsize_o + ! if (pctlnd_pft_dyn(n) /= pctlnd_pft(n)) then + ! write(6,*) subname,' error: pctlnd_pft for dynamics data = ',& + ! pctlnd_pft_dyn(n), ' not equal to pctlnd_pft for surface data = ',& + ! pctlnd_pft(n),' at n= ',n + ! if ( trim(fname) == ' ' )then + ! write(6,*) ' PFT string = ', string + ! else + ! write(6,*) ' PFT file = ', fname + ! end if + ! call abort() + ! end if + ! end do + + ! call change_landuse( dynpft=.true.) + + ! call normalizencheck_landuse(ldomain) + + ! call update_max_array(pctnatpft_max,pctnatpft) + ! call update_max_array(pctcft_max,pctcft) + + ! ! Output time-varying data for current year + + ! rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT', pio_varid)) + ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_p2l_array(pctnatpft)) + + ! rcode = pio_inq_varid(pioid, 'PCT_CROP', pio_varid)) + ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_l2g_array(pctcft)) + + ! if (num_cft > 0) then + ! rcode = pio_inq_varid(pioid, 'PCT_CFT', pio_varid)) + ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_p2l_array(pctcft)) + ! end if + + ! call harvdata%getFieldsIdx( harvind1D, harvind2D ) + ! do k = 1, harvdata%num1Dfields() + ! rcode = pio_inq_varid(pioid, trim(mkharvest_fieldname(harvind1D(k),constant=.false.)), pio_varid)) + ! harvest1D => harvdata%get1DFieldPtr( harvind1D(k), output=.true. ) + ! call mkpio_put_time_slice(pioid, pio_varid, ntim, harvest1D) + ! end do + ! do k = 1, harvdata%num2Dfields() + ! rcode = pio_inq_varid(pioid, trim(mkharvest_fieldname(harvind2D(k),constant=.false.)), pio_varid)) + ! harvest2D => harvdata%get2DFieldPtr( harvind2D(k), output=.true. ) + ! call mkpio_put_time_slice(pioid, pio_varid, ntim, harvest2D) + ! end do + ! deallocate( harvind1D, harvind2D ) + + ! rcode = pio_inq_varid(pioid, 'YEAR', pio_varid)) + ! rcode = pio_put_vara_int(pioid, pio_varid, ntim, 1, year)) + + ! rcode = pio_inq_varid(pioid, 'time', pio_varid)) + ! rcode = pio_put_vara_int(pioid, pio_varid, ntim, 1, year)) + + ! rcode = pio_inq_varid(pioid, 'input_pftdata_filename', pio_varid)) + ! rcode = pio_put_vara_text(pioid, pio_varid, (/ 1, ntim /), (/ len_trim(string), 1 /), trim(string) )) + + ! ! Synchronize the disk copy of a netCDF dataset with in-memory buffers + + ! rcode = pio_sync(pioid)) + + ! end do ! end of read loop + + ! rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT_MAX', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_p2l_array(pctnatpft_max))) + + ! rcode = pio_inq_varid(pioid, 'PCT_CROP_MAX', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_l2g_array(pctcft_max))) + + ! if (num_cft > 0) then + ! rcode = pio_inq_varid(pioid, 'PCT_CFT_MAX', pio_varid)) + ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_p2l_array(pctcft_max))) + ! end if + + ! rcode = pio_closefile(pioid)) + + end if ! end of if-create dynamic landust dataset + + ! ---------------------------------------------------------------------- + ! Close diagnostic dataset + ! ---------------------------------------------------------------------- + + close (ndiag) + write (6,*) + write (6,*) 'Surface data output file = ',trim(fsurdat) + write (6,*) ' This file contains the land model surface data' + write (6,*) 'Diagnostic log file = ',trim(fsurlog) + write (6,*) ' See this file for a summary of the dataset' + write (6,*) + + write (6,*) 'Successfully created surface dataset' + +!----------------------------------------------------------------------- +contains +!----------------------------------------------------------------------- + +#ifdef TODO + subroutine change_landuse( dynpft, lsize_o, mesh_o) + + ! Do landuse changes such as for the poles, etc. + ! If have pole points on grid - set south pole to glacier + ! north pole is assumed as non-land + + ! input/output variables + logical, intent(in) :: dynpft ! if part of the dynpft section of code + + ! !LOCAL VARIABLES: + integer :: n,lsize_o ! indices + character(len=32) :: subname = 'change_landuse' ! subroutine name + !----------------------------------------------------------------------- + + ! + + do n = 1,lsize_o + ! TODO: define latc + if (abs(latc(n) - 90._r8) < 1.e-6_r8) then + pctlak(n) = 0._r8 + pctwet(n) = 0._r8 + pcturb(n) = 0._r8 + pctgla(n) = 100._r8 + call pctnatpft(n)%set_pct_l2g(0._r8) + call pctcft(n)%set_pct_l2g(0._r8) + if ( .not. dynpft )then + organic(n,:) = 0._r8 + ef1_btr(n) = 0._r8 + ef1_fet(n) = 0._r8 + ef1_fdt(n) = 0._r8 + ef1_shr(n) = 0._r8 + ef1_grs(n) = 0._r8 + ef1_crp(n) = 0._r8 + end if + end if + + end do + end subroutine change_landuse +#endif + +#ifdef TODO + !----------------------------------------------------------------------- + subroutine normalizencheck_landuse(ldomain) + ! + ! Normalize land use and make sure things add up to 100% as well as + ! checking that things are as they should be. + ! + ! Precondition: pctlak + pctwet + pcturb + pctgla <= 100 (within roundoff) + ! + ! !USES: + use mkpftConstantsMod , only : baregroundindex + use mkpftUtilsMod , only : adjust_total_veg_area + implicit none + + ! !ARGUMENTS: + type(domain_type) :: ldomain + ! + ! !LOCAL VARIABLES: + integer :: m,k,n,ns_o ! indices + integer :: nsmall ! number of small PFT values for a single check + integer :: nsmall_tot ! total number of small PFT values in all grid cells + real(r8) :: suma ! sum for error check + real(r8) :: suma2 ! another sum for error check + real(r8) :: new_total_veg_pct ! new % veg (% of grid cell, total of natural veg & crop) + real(r8) :: bare_pct_p2g ! % of bare soil, as % of grid cell + real(r8) :: bare_urb_diff ! difference between bare soil and urban % + real(r8) :: pcturb_excess ! excess urban % not accounted for by bare soil + real(r8) :: sum8, sum8a ! sum for error check + real(r4) :: sum4a ! sum for error check + real(r8), parameter :: tol_loose = 1.e-4_r8 ! tolerance for some 'loose' error checks + real(r8), parameter :: toosmallPFT = 1.e-10_r8 ! tolerance for PFT's to ignore + character(len=32) :: subname = 'normalizencheck_landuse' ! subroutine name + !----------------------------------------------------------------------- + + ! ------------------------------------------------------------------------ + ! Normalize vegetated area so that vegetated + special area is 100% + ! ------------------------------------------------------------------------ + + ns_o = ldomain%ns + do n = 1,ns_o + + ! Check preconditions + if ( pctlak(n) < 0.0_r8 )then + write(6,*) subname, ' ERROR: pctlak is negative!' + write(6,*) 'n, pctlak = ', n, pctlak(n) + call abort() + end if + if ( pctwet(n) < 0.0_r8 )then + write(6,*) subname, ' ERROR: pctwet is negative!' + write(6,*) 'n, pctwet = ', n, pctwet(n) + call abort() + end if + if ( pcturb(n) < 0.0_r8 )then + write(6,*) subname, ' ERROR: pcturb is negative!' + write(6,*) 'n, pcturb = ', n, pcturb(n) + call abort() + end if + if ( pctgla(n) < 0.0_r8 )then + write(6,*) subname, ' ERROR: pctgla is negative!' + write(6,*) 'n, pctgla = ', n, pctgla(n) + call abort() + end if + + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + if (suma > (100._r8 + tol_loose)) then + write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla must be' + write(6,*) '<= 100% before calling this subroutine' + write(6,*) 'n, pctlak, pctwet, pcturb, pctgla = ', & + n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) + call abort() + end if + + ! First normalize vegetated (natural veg + crop) cover so that the total of + ! (vegetated + (special excluding urban)) is 100%. We'll deal with urban later. + ! + ! Note that, in practice, the total area of natural veg + crop is typically 100% + ! going into this routine. However, the following code does NOT rely on this, and + ! will work properly regardless of the initial area of natural veg + crop (even if + ! that initial area is 0%). + + suma = pctlak(n)+pctwet(n)+pctgla(n) + new_total_veg_pct = 100._r8 - suma + ! correct for rounding error: + new_total_veg_pct = max(new_total_veg_pct, 0._r8) + + call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) + + ! Make sure we did the above rescaling correctly + + suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + if (abs(suma - 100._r8) > tol_loose) then + write(6,*) subname, ' ERROR in rescaling veg based on (special excluding urban' + write(6,*) 'suma = ', suma + call abort() + end if + + ! Now decrease the vegetated area to account for urban area. Urban needs to be + ! handled specially because we replace bare soil preferentially with urban, rather + ! than rescaling all PFTs equally. + + if (pcturb(n) > 0._r8) then + + ! Replace bare soil preferentially with urban + bare_pct_p2g = pctnatpft(n)%get_one_pct_p2g(baregroundindex) + bare_urb_diff = bare_pct_p2g - pcturb(n) + bare_pct_p2g = max(0._r8, bare_urb_diff) + call pctnatpft(n)%set_one_pct_p2g(baregroundindex, bare_pct_p2g) + pcturb_excess = abs(min(0._r8,bare_urb_diff)) + + ! For any urban not accounted for by bare soil, replace other PFTs + ! proportionally + if (pcturb_excess > 0._r8) then + ! Note that, in this case, we will have already reduced bare ground to 0% + + new_total_veg_pct = pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - pcturb_excess + if (new_total_veg_pct < 0._r8) then + if (abs(new_total_veg_pct) < tol_loose) then + ! only slightly less than 0; correct it + new_total_veg_pct = 0._r8 + else + write(6,*) subname, ' ERROR: trying to replace veg with urban,' + write(6,*) 'but pcturb_excess exceeds current vegetation percent' + call abort() + end if + end if + + call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) + end if + + end if ! pcturb(n) > 0 + + ! Confirm that we have done the rescaling correctly: now the sum of all landunits + ! should be 100% + suma = pctlak(n)+pctwet(n)+pctgla(n)+pcturb(n) + suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + if (abs(suma - 100._r8) > tol_loose) then + write(6,*) subname, ' ERROR: landunits do not sum to 100%' + write(6,*) 'n, suma, pctlak, pctwet, pctgla, pcturb, pctnatveg, pctcrop = ' + write(6,*) n, suma, pctlak(n), pctwet(n), pctgla(n), pcturb(n), & + pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() + call abort() + end if + + end do + + ! ------------------------------------------------------------------------ + ! Do other corrections and error checks + ! ------------------------------------------------------------------------ + + nsmall_tot = 0 + + do n = 1,ns_o + + ! If the coverage of any PFT or CFT is too small at the gridcell level, set its + ! % cover to 0, then renormalize everything else as needed + call pctnatpft(n)%remove_small_cover(toosmallPFT, nsmall) + nsmall_tot = nsmall_tot + nsmall + call pctcft(n)%remove_small_cover(toosmallPFT, nsmall) + nsmall_tot = nsmall_tot + nsmall + + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + if ( abs(suma - 100.0_r8) > 2.0*epsilon(suma) )then + pctlak(n) = pctlak(n) * 100._r8/suma + pctwet(n) = pctwet(n) * 100._r8/suma + pcturb(n) = pcturb(n) * 100._r8/suma + pctgla(n) = pctgla(n) * 100._r8/suma + call pctnatpft(n)%set_pct_l2g(pctnatpft(n)%get_pct_l2g() * 100._r8/suma) + call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8/suma) + end if + + ! Roundoff error fix + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + suma2 = pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + if ( (suma < 100._r8 .and. suma > (100._r8 - 1.e-6_r8)) .or. & + (suma2 > 0.0_r8 .and. suma2 < 1.e-6_r8) ) then + write (6,*) 'Special land units near 100%, but not quite for n,suma =',n,suma + write (6,*) 'Adjusting special land units to 100%' + if (pctlak(n) >= 25._r8) then + pctlak(n) = 100._r8 - (pctwet(n) + pcturb(n) + pctgla(n)) + else if (pctwet(n) >= 25._r8) then + pctwet(n) = 100._r8 - (pctlak(n) + pcturb(n) + pctgla(n)) + else if (pcturb(n) >= 25._r8) then + pcturb(n) = 100._r8 - (pctlak(n) + pctwet(n) + pctgla(n)) + else if (pctgla(n) >= 25._r8) then + pctgla(n) = 100._r8 - (pctlak(n) + pctwet(n) + pcturb(n)) + else + write (6,*) subname, 'Error: sum of special land units nearly 100% but none is >= 25% at ', & + 'n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),pctnatveg(n),pctcrop(n),suma = ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& + pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(),suma + call abort() + end if + call pctnatpft(n)%set_pct_l2g(0._r8) + call pctcft(n)%set_pct_l2g(0._r8) + end if + if ( any(pctnatpft(n)%get_pct_p2g() > 0.0_r8 .and. pctnatpft(n)%get_pct_p2g() < toosmallPFT ) .or. & + any(pctcft(n)%get_pct_p2g() > 0.0_r8 .and. pctcft(n)%get_pct_p2g() < toosmallPFT )) then + write (6,*) 'pctnatpft or pctcft is small at n=', n + write (6,*) 'pctnatpft%pct_p2l = ', pctnatpft(n)%get_pct_p2l() + write (6,*) 'pctcft%pct_p2l = ', pctcft(n)%get_pct_p2l() + write (6,*) 'pctnatpft%pct_l2g = ', pctnatpft(n)%get_pct_l2g() + write (6,*) 'pctcft%pct_l2g = ', pctcft(n)%get_pct_l2g() + call abort() + end if + + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + if (suma < 100._r8-epsilon(suma) .and. suma > (100._r8 - 4._r8*epsilon(suma))) then + write (6,*) subname, 'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& + pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() + call abort() + end if + suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + if ( abs(suma-100._r8) > 1.e-10_r8) then + write (6,*) subname, ' error: sum of pctlak, pctwet,', & + 'pcturb, pctgla, pctnatveg and pctcrop is NOT equal to 100' + write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,sum= ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& + pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), suma + call abort() + end if + + end do + + ! Check that when pctnatveg+pctcrop identically zero, sum of special landunits is identically 100% + + if ( .not. outnc_double )then + do n = 1,ns_o + sum8 = real(pctlak(n),r4) + sum8 = sum8 + real(pctwet(n),r4) + sum8 = sum8 + real(pcturb(n),r4) + sum8 = sum8 + real(pctgla(n),r4) + sum4a = real(pctnatpft(n)%get_pct_l2g(),r4) + sum4a = sum4a + real(pctcft(n)%get_pct_l2g(),r4) + if ( sum4a==0.0_r4 .and. sum8 < 100._r4-2._r4*epsilon(sum4a) )then + write (6,*) subname, ' error: sum of pctlak, pctwet,', & + 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 + write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n), & + pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g() + call abort() + end if + end do + else + do n = 1,ns_o + sum8 = pctlak(n) + sum8 = sum8 + pctwet(n) + sum8 = sum8 + pcturb(n) + sum8 = sum8 + pctgla(n) + sum8a = pctnatpft(n)%get_pct_l2g() + sum8a = sum8a + pctcft(n)%get_pct_l2g() + if ( sum8a==0._r8 .and. sum8 < (100._r8-4._r8*epsilon(sum8)) )then + write (6,*) subname, ' error: sum of pctlak, pctwet,', & + 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 + write (6,*) 'Total error, error/epsilon = ',100._r8-sum8, ((100._r8-sum8)/epsilon(sum8)) + write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,epsilon= ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& + pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), epsilon(sum8) + call abort() + end if + end do + end if + + ! Make sure that there is no vegetation outside the pft mask + do n = 1,ns_o + if (pftdata_mask(n) == 0 .and. (pctnatpft(n)%get_pct_l2g() > 0 .or. pctcft(n)%get_pct_l2g() > 0)) then + write (6,*)'vegetation found outside the pft mask at n=',n + write (6,*)'pctnatveg,pctcrop=', pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() + call abort() + end if + end do + + ! Make sure that sums at the landunit level all add to 100% + ! (Note that we don't check pctglcmec here, because it isn't computed at the point + ! that this subroutine is called -- but the check of sum(pctglcmec) is done in + ! mkglcmecMod) + ! (Also note that we don't need to check pctnatpft or pctcft, because a similar check + ! is done internally by the pct_pft_type routines.) + do n = 1,ns_o + if (abs(sum(urbn_classes(n,:)) - 100._r8) > 1.e-12_r8) then + write(6,*) 'sum(urbn_classes(n,:)) != 100: ', n, sum(urbn_classes(n,:)) + call abort() + end if + end do + + if ( nsmall_tot > 0 )then + write (6,*)'number of small pft = ', nsmall_tot + end if + + end subroutine normalizencheck_landuse +#endif + +end program mksurfdata diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 new file mode 100644 index 0000000000..7e102d9bcf --- /dev/null +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -0,0 +1,183 @@ +module mktopostatsMod + +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mktopostatsMod +! +! !DESCRIPTION: +! make various topography statistics +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +!----------------------------------------------------------------------- +! +! !USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush + use mkdomainMod , only : domain_checksame + + implicit none + + private + +! !PUBLIC MEMBER FUNCTIONS: + public mktopostats ! make topo stddev & mean slope +! +!EOP +!=============================================================== +contains +!=============================================================== + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mktopostats +! +! !INTERFACE: +subroutine mktopostats(ldomain, mapfname, datfname, ndiag, topo_stddev_o, slope_o, std_elev) +! +! !DESCRIPTION: +! make various topography statistics +! +! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkncdio + use mkdiagnosticsMod, only : output_diagnostics_continuous, output_diagnostics_continuous_outonly + use mkchecksMod, only : min_bad, max_bad +! +! !ARGUMENTS: + + implicit none + type(domain_type) , intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(in) :: std_elev ! standard deviation of elevation (m) to use when not using input file + real(r8) , intent(out):: topo_stddev_o(:) ! output grid: standard deviation of elevation (m) + real(r8) , intent(out):: slope_o(:) ! output grid: slope (degrees) +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +! +! !LOCAL VARIABLES: +!EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: data_i(:) ! data on input grid + integer :: ncid,varid ! input netCDF id's + integer :: ier ! error status + logical :: bypass_reading ! If should bypass reading dataset and just use a global value + + real(r8), parameter :: min_valid_topo_stddev = 0._r8 + + real(r8), parameter :: min_valid_slope = 0._r8 + real(r8), parameter :: max_valid_slope = 90._r8 + + character(len=32) :: subname = 'mktopostats' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make Topography statistics.....' + if ( std_elev >= 0.0_r8 )then + bypass_reading = .true. + write (6,*) ' By pass the reading and just use global values' + else + bypass_reading = .false. + end if + call shr_sys_flush(6) + + ! ----------------------------------------------------------------- + ! Read domain and mapping information, check for consistency + ! ----------------------------------------------------------------- + + if ( .not. bypass_reading )then + call domain_read(tdomain,datfname) + + call gridmap_mapread(tgridmap, mapfname ) + + call gridmap_check( tgridmap, tgridmap%frac_src, tgridmap%frac_dst, subname ) + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! ----------------------------------------------------------------- + ! Open input file, allocate memory for input data + ! ----------------------------------------------------------------- + + write(6,*)'Open Topography file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + + allocate(data_i(tdomain%ns), stat=ier) + if (ier/=0) call abort() + + ! ----------------------------------------------------------------- + ! Make topography standard deviation + ! ----------------------------------------------------------------- + + call check_ret(nf_inq_varid (ncid, 'ELEVATION', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + call gridmap_areastddev(tgridmap, data_i, topo_stddev_o, nodata=0._r8) + + call output_diagnostics_continuous_outonly(topo_stddev_o, tgridmap, "Topo Std Dev", "m", ndiag) + else + write (6,*) ' Set std deviation of topography to ', std_elev + topo_stddev_o = std_elev + end if + + ! Check validity of output data + if (min_bad(topo_stddev_o, min_valid_topo_stddev, 'topo_stddev')) then + call abort() + end if + + + ! ----------------------------------------------------------------- + ! Regrid slope + ! ----------------------------------------------------------------- + + if ( .not. bypass_reading )then + call check_ret(nf_inq_varid (ncid, 'SLOPE', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + + ! Subr. gridmap_areaave_no_srcmask should NOT be used in general. We have + ! kept it to support the rare raw data files for which we have masking on + ! the mapping file and, therefore, we do not explicitly pass the src_mask + ! as an argument. In general, users are advised to use subroutine + ! gridmap_areaave_srcmask. + call gridmap_areaave_no_srcmask(tgridmap, data_i, slope_o, nodata=0._r8) + + call output_diagnostics_continuous(data_i, slope_o, tgridmap, "Slope", "degrees", ndiag, tdomain%mask, tgridmap%frac_dst) + else + write (6,*) ' Set slope of topography to ', 0.0_r8 + slope_o = 0.0_r8 + end if + ! Check validity of output data + if (min_bad(slope_o, min_valid_slope, 'slope') .or. & + max_bad(slope_o, max_valid_slope, 'slope')) then + call abort() + end if + + + ! ----------------------------------------------------------------- + ! Close files and deallocate dynamic memory + ! ----------------------------------------------------------------- + + if ( .not. bypass_reading )then + call check_ret(nf_close(ncid), subname) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (data_i) + end if + + write (6,*) 'Successfully made Topography statistics' + write (6,*) + call shr_sys_flush(6) + +end subroutine mktopostats + + +end module mktopostatsMod diff --git a/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 new file mode 100644 index 0000000000..ab738ea03c --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 @@ -0,0 +1,365 @@ +module mkurbanparCommonMod +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mkurbanparCommon +! +! !DESCRIPTION: +! Common routines for making urban parameter data, independent of the method used for +! making the urban parameters (e.g., averages, dominant type, etc.) +! +! (WJS 4-18-12: In the past, this contained routines shared between mkurbanparDomMod and +! mkurbanparAvgMod; now there is just a single module, mkurbanparMod, but I am keeping the +! separate mkurbanparCommonMod in case a similar split comes back in the future. However, +! if such a split seems unlikely in the future, these routines could be moved back into +! mkurbanparMod.) +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +!----------------------------------------------------------------------- +! !USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush + implicit none + + private + +! !PUBLIC MEMBER FUNCTIONS: + public :: mkurban_pct ! Make output urban %, given input urban % + public :: mkurban_pct_diagnostics ! print diagnostics related to pct urban + public :: mkelev ! Get elevation to reduce urban for high elevation areas +! +! !PUBLIC DATA MEMBERS: +! + real(r8), parameter :: MIN_DENS = 0.1_r8 ! minimum urban density (% of grid cell) - below this value, urban % is set to 0 + + public :: MIN_DENS +! +!EOP + +contains + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkurban_pct +! +! !INTERFACE: +subroutine mkurban_pct(ldomain, tdomain, tgridmap, urbn_i, urbn_o, frac_dst) +! +! !DESCRIPTION: +! make percent urban on output grid, given percent urban on input grid +! +! This assumes that we're neither using all_urban or zero_out +! +! +! !USES: + use mkdomainMod , only : domain_type, domain_checksame + use mkgridmapMod + use mkvarctl , only : mksrf_gridtype +! +! !ARGUMENTS: + implicit none + type(domain_type) , intent(in) :: ldomain + type(domain_type) , intent(in) :: tdomain ! local domain + type(gridmap_type), intent(in) :: tgridmap ! local gridmap + real(r8) , intent(in) :: urbn_i(:) ! input grid: percent urban + real(r8) , intent(in) :: frac_dst(:) ! output fractions + real(r8) , intent(out):: urbn_o(:) ! output grid: percent urban +! +! !REVISION HISTORY: +! Author: Bill Sacks +! (Moved from mkurbanparMod Feb, 2012) +! +! +! !LOCAL VARIABLES: +!EOP + integer :: ier ! error status + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + integer :: ni,no ! indices + real(r8) :: relerr = 0.00001_r8 ! max error: sum overlap wts ne 1 + character(len=*), parameter :: subname = 'mkurban_pct' +!----------------------------------------------------------------------- + + ! Error checks for array size consistencies + + if (size(urbn_i) /= tdomain%ns .or. & + size(urbn_o) /= ldomain%ns) then + write(6,*) subname//' ERROR: array size inconsistencies' + write(6,*) 'size(urbn_i) = ', size(urbn_i) + write(6,*) 'tdomain%ns = ', tdomain%ns + write(6,*) 'size(urbn_o) = ', size(urbn_o) + write(6,*) 'ldomain%ns = ', ldomain%ns + call abort() + end if + if (size(frac_dst) /= ldomain%ns) then + write(6,*) subname//' ERROR: array size inconsistencies' + write(6,*) 'size(frac_dst) = ', size(frac_dst) + write(6,*) 'ldomain%ns = ', ldomain%ns + call abort() + end if + + ! Error checks for domain and map consistencies + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Determine urbn_o on ouput grid: + ! Area-average percent cover on input grid to output grid + ! and correct according to land landmask + ! Note that percent cover is in terms of total grid area. + + call gridmap_areaave_srcmask(tgridmap, urbn_i, urbn_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check for conservation + + do no = 1, ldomain%ns + if ((urbn_o(no)) > 100.000001_r8) then + write (6,*) 'MKURBAN error: urban = ',urbn_o(no), & + ' greater than 100.000001 for column, row = ',no + call abort() + end if + enddo + + ! Global sum of output field -- must multiply by fraction of + ! output grid that is land as determined by input grid + + allocate(mask_r8(tdomain%ns), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + ! (Error check2 in mkurban_pct_diagnostics, which should be called separately) + + deallocate (mask_r8) + +end subroutine mkurban_pct +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkurban_pct_diagnostics +! +! !INTERFACE: +subroutine mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, urbn_i, urbn_o, ndiag, dens_class, frac_dst) +! +! !DESCRIPTION: +! print diagnostics related to pct urban +! +! This is intended to be called after mkurban_pct, but is split out into a separate +! routine so that modifications to urbn_o can be made in between the two calls (e.g., +! setting urbn_o to 0 wherever it is less than a certain threshold; the rules for doing +! this can't always be applied inline in mkurban_pct). +! +! !USES: + use mkdomainMod , only : domain_type + use mkgridmapMod, only : gridmap_type + use mkvarpar +! +! !ARGUMENTS: + implicit none + type(domain_type) , intent(in) :: ldomain + type(domain_type) , intent(in) :: tdomain ! local domain + type(gridmap_type), intent(in) :: tgridmap ! local gridmap + real(r8) , intent(in) :: urbn_i(:) ! input grid: percent urban + real(r8) , intent(in) :: urbn_o(:) ! output grid: percent urban + real(r8) , intent(in) :: frac_dst(:) ! output fractions + integer , intent(in) :: ndiag ! unit number for diag out + + integer , intent(in), optional :: dens_class ! density class +! +! !REVISION HISTORY: +! Author: Bill Sacks +! (Moved from mkurbanparMod Feb, 2012) +! +! +! !LOCAL VARIABLES: +!EOP + real(r8) :: gurbn_i ! input grid: global urbn + real(r8) :: garea_i ! input grid: global area + real(r8) :: gurbn_o ! output grid: global urbn + real(r8) :: garea_o ! output grid: global area + integer :: ni,no,k ! indices + character(len=*), parameter :: subname = 'mkurban_pct_diagnostics' +!----------------------------------------------------------------------- + + ! Error check inputs + if (size(frac_dst) /= ldomain%ns) then + write(6,*) subname//' ERROR: array size inconsistencies' + write(6,*) 'size(frac_dst) = ', size(frac_dst) + write(6,*) 'ldomain%ns = ', ldomain%ns + call abort() + end if + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global areas on input and output grids + ! ----------------------------------------------------------------- + + ! Input grid + + gurbn_i = 0._r8 + garea_i = 0._r8 + + do ni = 1, tdomain%ns + garea_i = garea_i + tgridmap%area_src(ni)*re**2 + gurbn_i = gurbn_i + urbn_i(ni)*(tgridmap%area_src(ni)/100._r8)*& + tdomain%mask(ni)*re**2 + end do + + ! Output grid + + gurbn_o = 0._r8 + garea_o = 0._r8 + + do no = 1, ldomain%ns + garea_o = garea_o + tgridmap%area_dst(no)*re**2 + gurbn_o = gurbn_o + urbn_o(no)* (tgridmap%area_dst(no)/100._r8)*& + frac_dst(no)*re**2 + end do + + ! Diagnostic output + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + if (present(dens_class)) then + write (ndiag,'(1x,a,i0)') 'Urban Output -- class ', dens_class + else + write (ndiag,'(1x,a)') 'Urban Output' + end if + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,2001) +2001 format (1x,'surface type input grid area output grid area'/ & + 1x,' 10**6 km**2 10**6 km**2 ') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + write (ndiag,2003) gurbn_i*1.e-06,gurbn_o*1.e-06 + write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 +2002 format (1x,'urban ',f14.3,f17.3) +2003 format (1x,'urban ',f14.3,f22.8) +2004 format (1x,'all surface ',f14.3,f17.3) + +end subroutine mkurban_pct_diagnostics +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkelev +! +! !INTERFACE: +subroutine mkelev(ldomain, mapfname, datfname, varname, ndiag, elev_o) +! +! !DESCRIPTION: +! Make elevation data +! +! !USES: + use mkdomainMod , only : domain_type, domain_clean, domain_read, domain_checksame + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio + use mkdiagnosticsMod, only : output_diagnostics_continuous +! +! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + character(len=*) , intent(in) :: varname ! topo variable name + real(r8) , intent(out):: elev_o(:) ! output elevation data +! +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Keith Oleson +! +! +! !LOCAL VARIABLES: +!EOP + type(domain_type) :: tdomain ! local domain + type(gridmap_type) :: tgridmap ! local gridmap + + real(r8), allocatable :: elev_i(:) ! canyon_height to width ratio in + real(r8), allocatable :: frac_dst(:) ! output fractions + integer :: ns_i,ns_o ! indices + integer :: k,l,n,m,ni ! indices + integer :: ncidi,dimid,varid ! input netCDF id's + integer :: ier ! error status + character(len=256) :: name ! name of attribute + character(len=256) :: unit ! units of attribute + character(len= 32) :: subname = 'mkelev' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make elevation .....' + call shr_sys_flush(6) + + ns_o = ldomain%ns + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + + ns_i = tdomain%ns + allocate(elev_i(ns_i), stat=ier) + allocate(frac_dst(ns_o), stat=ier) + if (ier /= 0) then + write(6,*)'mkelev allocation error'; call abort() + end if + + write (6,*) 'Open elevation file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncidi), subname) + call check_ret(nf_inq_varid (ncidi, trim(varname), varid), subname) + call check_ret(nf_get_var_double (ncidi, varid, elev_i), subname) + call check_ret(nf_close(ncidi), subname) + + ! Read topo elev dataset with unit mask everywhere + + call gridmap_mapread(tgridmap, mapfname) + + ! Error checks for domain and map consistencies + ! Note that the topo dataset has no landmask - so a unit landmask is assumed + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Determine elev_o on output grid + + elev_o(:) = 0. + + call gridmap_areaave_srcmask(tgridmap, elev_i, elev_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + call output_diagnostics_continuous(elev_i, elev_o, tgridmap, "Urban elev variable", "m", ndiag, tdomain%mask, frac_dst) + + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (elev_i) + deallocate (frac_dst) + + write (6,*) 'Successfully made elevation' + write (6,*) + call shr_sys_flush(6) + +end subroutine mkelev + +!----------------------------------------------------------------------- + +end module mkurbanparCommonMod diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 new file mode 100644 index 0000000000..49ce95dd07 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -0,0 +1,759 @@ +module mkurbanparMod +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mkurbanpar +! +! !DESCRIPTION: +! Make Urban Parameter data +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +!----------------------------------------------------------------------- +! !USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush + use mkvarctl, only : ispval + implicit none + + private + +! !PUBLIC MEMBER FUNCTIONS: + public :: mkurbanInit + public :: mkurban + public :: mkurbanpar + + ! The following could be private, but because there are associated test routines in a + ! separate module, it needs to be public + public :: normalize_urbn_by_tot + +! !PUBLIC DATA MEMBERS: + integer :: numurbl ! number of urban classes + integer :: nlevurb = ispval ! number of urban layers + + public :: numurbl + public :: nlevurb + +! !PRIVATE DATA MEMBERS: + ! flag to indicate nodata for index variables in output file: + integer, parameter :: index_nodata = 0 + character(len=*), parameter :: modname = 'mkurbanparMod' + + private :: index_nodata + private :: modname + +!EOP + +contains + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkurbanInit +! +! !INTERFACE: +subroutine mkurbanInit(datfname) +! +! !DESCRIPTION: +! Initialize variables needed for urban +! +! !USES: + use mkncdio +! +! !ARGUMENTS: + implicit none + character(len=*), intent(in) :: datfname ! input data file name (same as file used in mkurban) +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +! +! !LOCAL VARIABLES: + integer :: ncid,dimid ! input netCDF id's + + character(len=*), parameter :: subname = 'mkurbanInit' +!EOP +!----------------------------------------------------------------------- + + ! Set numurbl + call check_ret(nf_open(datfname, 0, ncid), subname) + call check_ret(nf_inq_dimid (ncid, 'density_class', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, numurbl), subname) + call check_ret(nf_inq_dimid (ncid, 'nlevurb', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, nlevurb), subname) + call check_ret(nf_close(ncid), subname) + +end subroutine mkurbanInit +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkurban +! +! !INTERFACE: +subroutine mkurban(ldomain, mapfname, datfname, ndiag, zero_out, & + urbn_o, urbn_classes_o, region_o) +! +! !DESCRIPTION: +! make total percent urban, breakdown into urban classes, and region ID on the output grid +! +! urbn_classes_o(n, i) gives the percent of the urban area in grid cell n that is in class #i. +! This is normalized so that sum(urbn_classes_o(n,:)) = 100 for all n, even for grid +! cells where urbn_o(n) = 0 (in the case where urbn_o(n) = 0, we come up with an +! arbitrary assignment of urban into the different classes). +! +! See comments under the normalize_urbn_by_tot subroutine for how urbn_classes_o is +! determined when the total % urban is 0, according to the input data. Note that this +! also applies when all_urban=.true., for points that have 0 urban according to the input +! data. +! +! TODO (WJS 6-12-14): I think this could be rewritten slightly to take advantage of the +! new mkpctPftTypeMod (which should then be renamed to something more general; or maybe +! better, in terms of maintaining helpful abstractions, there could be a new type to +! handle urban, and both that and pct_pft_type could be build on a single set of shared +! code - either as a single base class or through a "has-a" mechanism). This would allow +! us to combine urbn_o and urbn_classes_o into a single derived type variable. I think +! this would also replace the use of normalize_classes_by_gcell, and maybe some other +! urban-specific code. +! +! !USES: + use mkdomainMod , only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkindexmapMod, only : get_dominant_indices + use mkurbanparCommonMod, only : mkurban_pct, mkurban_pct_diagnostics, MIN_DENS + use mkutilsMod , only : normalize_classes_by_gcell + use mkvarctl , only : all_urban + use mkvarpar + use mkncdio + use mkdiagnosticsMod, only : output_diagnostics_index +! +! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + logical , intent(in) :: zero_out ! if should zero urban out + real(r8) , intent(out):: urbn_o(:) ! output grid: total % urban + real(r8) , intent(out):: urbn_classes_o(:,:) ! output grid: breakdown of total urban into each class + ! (dimensions: (ldomain%ns, numurbl)) + integer , intent(out):: region_o(:) ! output grid: region ID +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +! +! !LOCAL VARIABLES: +!EOP + type(domain_type) :: tdomain ! local domain + type(gridmap_type) :: tgridmap ! local gridmap + real(r8), allocatable :: urbn_classes_gcell_i(:,:) ! input grid: percent urban in each density class + ! (% of total grid cell area) + real(r8), allocatable :: urbn_classes_gcell_o(:,:) ! output grid: percent urban in each density class + real(r8), allocatable :: frac_dst(:) ! output fractions + ! (% of total grid cell area) + integer , allocatable :: region_i(:) ! input grid: region ID + integer :: ni,no,ns,k ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: dimlen ! netCDF dimension length + integer :: max_region ! maximum region index + integer :: ier ! error status + + character(len=*), parameter :: subname = 'mkurban' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make %urban .....' + + ! Obtain input grid info, read local fields + + call gridmap_mapread(tgridmap, mapfname) + call domain_read(tdomain, datfname) + + ns = tdomain%ns + + allocate(urbn_classes_gcell_i(ns, numurbl), & + urbn_classes_gcell_o(ldomain%ns, numurbl), & + frac_dst(ldomain%ns), & + stat=ier) + if (ier/=0) call abort() + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + write (6,*) 'Open urban file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + call check_ret(nf_inq_varid (ncid, 'PCT_URBAN', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, urbn_classes_gcell_i), subname) + + ! Determine % urban by density class on the output grid + do k = 1, numurbl + call mkurban_pct(ldomain, tdomain, tgridmap, urbn_classes_gcell_i(:,k), urbn_classes_gcell_o(:,k), frac_dst) + end do + + ! Determine total % urban + do no = 1, ldomain%ns + urbn_o(no) = sum(urbn_classes_gcell_o(no,:)) + end do + + call normalize_urbn_by_tot(urbn_classes_gcell_o, urbn_o, urbn_classes_o) + + ! Handle special cases + + ! Note that, for all these adjustments of total urban %, we do not change anything + ! about the breakdown into the different urban classes. In particular: when urbn_o is + ! set to 0 for a point, the breakdown into the different urban classes is maintained + ! as it was before. + if (all_urban) then + urbn_o(:) = 100._r8 + else if (zero_out) then + urbn_o(:) = 0._r8 + else + ! Set points to 0% if they fall below a given threshold + do no = 1, ldomain%ns + if (urbn_o(no) < MIN_DENS) then + urbn_o(no) = 0._r8 + end if + end do + end if + + ! Print diagnostics + ! First, recompute urbn_classes_gcell_o, based on any changes we have made to urbn_o + ! while handling special cases + call normalize_classes_by_gcell(urbn_classes_o, urbn_o, urbn_classes_gcell_o) + do k = 1, numurbl + call mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, & + urbn_classes_gcell_i(:,k), urbn_classes_gcell_o(:,k), & + ndiag, dens_class=k, frac_dst=frac_dst) + end do + + write (6,*) 'Successfully made %urban' + + + write(6,*) 'Attempting to make urban region .....' + + ! Read in region field + ! Note: we do this here, rather than with the rest of the reads above, because we + ! expect the input urban fields to be large, so we're just reading the fields as + ! they're needed to try to avoid unnecessary memory paging + + allocate(region_i(ns), stat=ier) + if (ier/=0) call abort() + call check_ret(nf_inq_varid (ncid, 'REGION_ID', varid), subname) + call check_ret(nf_get_var_int (ncid, varid, region_i), subname) + + ! Determine max region value, and make sure it doesn't exceed bounds of the lookup tables. + ! + ! (Note: this check assumes that region_i=1 refers to region(1), region_i=2 refers to + ! region(2), etc. The alternative would be to use a coordinate variable associated with + ! the region dimension of the lookup table, which could result in an arbitrary mapping + ! between region values and the indices of the lookup table; however, this use of + ! coordinate variables currently isn't supported by lookup_2d_netcdf [as of 2-8-12].) + + max_region = maxval(region_i) + call check_ret(nf_inq_dimid (ncid, 'region', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, dimlen), subname) + if (max_region > dimlen) then + write(6,*) modname//':'//subname// & + ' ERROR: max region value exceeds length of region dimension' + write(6,*) 'max region value : ', max_region + write(6,*) 'length of region dimension: ', dimlen + call abort() + end if + + ! Determine dominant region for each output cell + + call get_dominant_indices(tgridmap, region_i, region_o, 1, max_region, index_nodata, mask_src=tdomain%mask) + + write (6,*) 'Successfully made urban region' + write (6,*) + + ! Output diagnostics + + call output_diagnostics_index(region_i, region_o, tgridmap, 'Urban Region ID', & + 1, max_region, ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Deallocate dynamic memory & other clean up + + call check_ret(nf_close(ncid), subname) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (urbn_classes_gcell_i, urbn_classes_gcell_o, region_i, frac_dst) + +end subroutine mkurban +!----------------------------------------------------------------------- + +!------------------------------------------------------------------------------ +!BOP +! +! !IROUTINE: normalize_urbn_by_tot +! +! !INTERFACE: +subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) +! +! !DESCRIPTION: +! Normalizes urban class areas to produce % cover of each class, as % of total urban area +! +! Specifically: Given (1) an array specifying the % cover of each urban class, as a % of +! the total grid cell area ('classes_pct_gcell'), and (2) a vector giving the total urban +! area in each grid cell, expressed as % of the grid cell area: Returns an array +! ('classes_pct_tot') of the same dimensionality as classes_pct_gcell, where the values +! now give % cover of each class as a % of the total urban area. +! +! Assumes that sums(n) = sum(classes_pct_gcell(n,:)) +! +! When sums(n) = 0, the creation of classes_pct_tot(n,:) is ambiguous. Here we use the +! rule that all area is assigned to the medium-density class, defined by parameter MD. +! +! The returned array satisfies sum(classes_pct_tot(n,:))==100 for all n (within rounding error) +! +! !USES: +! +! !ARGUMENTS: + implicit none + real(r8), intent(in) :: classes_pct_gcell(:,:) ! % cover of classes as % of grid cell + real(r8), intent(in) :: sums(:) ! totals, as % of grid cell + real(r8), intent(out):: classes_pct_tot(:,:) ! % cover of classes as % of total +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +! +! !LOCAL VARIABLES: +!EOP + integer :: n ! index + integer :: n_max ! number of points + integer :: nclasses ! number of classes + real(r8) :: suma ! sum for error check + + ! index of medium-density class, which is where we assign urban areas when the total + ! urban area is 0 + integer, parameter :: MD = 3 + + ! relative error tolerance for error check + real(r8), parameter :: relerr = 1.e-10_r8 + + character(len=*), parameter :: subname = 'normalize_urbn_by_tot' +!----------------------------------------------------------------------- + + ! Error-check inputs + + n_max = size(sums) + if (size(classes_pct_tot, 1) /= n_max .or. & + size(classes_pct_gcell, 1) /= n_max) then + write(6,*) subname//' ERROR: array size mismatch' + write(6,*) 'size(sums) = ', n_max + write(6,*) 'size(classes_pct_tot, 1) = ', size(classes_pct_tot, 1) + write(6,*) 'size(classes_pct_gcell, 1) = ', size(classes_pct_gcell, 1) + call abort() + end if + + if (size(classes_pct_tot, 2) /= size(classes_pct_gcell, 2)) then + write(6,*) subname//' ERROR: array size mismatch' + write(6,*) 'size(classes_pct_tot, 2) = ', size(classes_pct_tot, 2) + write(6,*) 'size(classes_pct_gcell, 2) = ', size(classes_pct_gcell, 2) + call abort() + end if + + nclasses = size(classes_pct_gcell, 2) + if (MD > nclasses) then + write(6,*) subname//' ERROR: MD exceeds nclasses' + write(6,*) 'MD = ', MD + write(6,*) 'nclasses = ', nclasses + call abort() + end if + + ! Do the work + + do n = 1, n_max + if (sums(n) > 0._r8) then + classes_pct_tot(n,:) = classes_pct_gcell(n,:)/sums(n) * 100._r8 + else + ! Creation of classes_pct_tot is ambiguous. Apply the rule that all area is + ! assigned to the medium-density class. + classes_pct_tot(n,:) = 0._r8 + classes_pct_tot(n,MD) = 100._r8 + end if + end do + + ! Error-check output: Make sure sum(classes_pct_tot(n,:)) = 100 for all n + + do n = 1, n_max + suma = sum(classes_pct_tot(n,:)) + if (abs(suma/100._r8 - 1._r8) > relerr) then + write(6,*) subname//' ERROR: sum does not equal 100 at point ', n + write(6,*) 'suma = ', suma + call abort() + end if + end do + +end subroutine normalize_urbn_by_tot +!----------------------------------------------------------------------- + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkurbanpar +! +! !INTERFACE: +subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_skip_abort_on_invalid_data_check) +! +! !DESCRIPTION: +! Make Urban Parameter data +! +! Note that, in a grid cell with region_o==r, parameter values are filled from region r +! for ALL density classes. Thus, the parameter variables have a numurbl dimension along +! with their other dimensions. +! +! Note that we will have a 'nodata' value (given by the fill_val value associated with +! each parameter) wherever (1) we have a nodata value for region_o, or (2) the parameter +! has nodata for the given region/density combination in the input lookup table. +! +! !USES: + use mkdomainMod , only : domain_type, domain_clean, domain_read + use mkindexmapMod, only : dim_slice_type, lookup_2d_netcdf + use mkvarpar + use mkncdio +! +! !ARGUMENTS: + implicit none + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ncido ! output netcdf file id + integer , intent(in) :: region_o(:) ! output grid: region ID (length: ns_o) + real(r8) , intent(in) :: urbn_classes_gcell_o(:,:) ! output grid: percent urban in each density class + ! (% of total grid cell area) (dimensions: ns_o, numurbl) + logical , intent(in) :: urban_skip_abort_on_invalid_data_check + +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +! +! !LOCAL VARIABLES: +!EOP + ! Type to store information about each urban parameter + type param + character(len=32) :: name ! name in input & output files + real(r8) :: fill_val ! value to put where we have no data in output + logical :: check_invalid ! should we check whether there are any invalid data in the output? + end type param + + real(r8), allocatable :: data_scalar_o(:,:) ! output array for parameters with no extra dimensions + real(r8), allocatable :: data_rad_o(:,:,:,:) ! output array for parameters dimensioned by numrad & numsolar + real(r8), allocatable :: data_levurb_o(:,:,:) ! output array for parameters dimensioned by nlevurb + integer , allocatable :: unity_dens_o(:,:) ! artificial density indices + integer :: nlevurb_i ! input grid: number of urban vertical levels + integer :: numsolar_i ! input grid: number of solar type (DIR/DIF) + integer :: numrad_i ! input grid: number of solar bands (VIS/NIR) + integer :: m,n,no,ns_o,p,k ! indices + integer :: ncidi,dimid,varid ! netCDF id's + integer :: ier ! error status + character(len=nf_max_name) :: varname ! variable name + + ! information on extra dimensions for lookup tables greater than 2-d: + type(dim_slice_type), allocatable :: extra_dims(:) + + ! suffix for variables dimensioned by numsolar, for each value of numsolar: + character(len=8), parameter :: solar_suffix(numsolar) = (/'_DIR', '_DIF'/) + + ! value to put where we have no data in output variables, for real-valued parameters + real(r8), parameter :: fill_val_real = 0._r8 + + ! To add a new urban parameter, simply add an element to one of the below lists + ! (params_scalar, params_rad or params_levurb) + + ! Urban parameters with no extra dimensions + type(param), parameter :: params_scalar(13) = & + (/ param('CANYON_HWR', fill_val_real, .true.), & + param('EM_IMPROAD', fill_val_real, .true.), & + param('EM_PERROAD', fill_val_real, .true.), & + param('EM_ROOF', fill_val_real, .true.), & + param('EM_WALL', fill_val_real, .true.), & + param('HT_ROOF', fill_val_real, .true.), & + param('THICK_ROOF', fill_val_real, .true.), & + param('THICK_WALL', fill_val_real, .true.), & + param('T_BUILDING_MIN', fill_val_real, .true.), & + param('WIND_HGT_CANYON', fill_val_real, .true.), & + param('WTLUNIT_ROOF', fill_val_real, .true.), & + param('WTROAD_PERV', fill_val_real, .true.), & + + ! Note that NLEV_IMPROAD is written as an integer, meaning that type conversion occurs + ! by truncation. Thus we expect the values in the NLEV_IMPROAD lookup table to be exact; + ! e.g., if a value were 1.99999 rather than 2.0000, it would be written as 1 instead of 2 + ! Also note: we use fill_val=-1 rather than 0, because 0 appears in the lookup table + param('NLEV_IMPROAD', -1, .true.) /) + + ! Urban parameters dimensioned by numrad & numsolar + type(param), parameter :: params_rad(4) = & + (/ param('ALB_IMPROAD', fill_val_real, .true.), & + param('ALB_PERROAD', fill_val_real, .true.), & + param('ALB_ROOF', fill_val_real, .true.), & + param('ALB_WALL', fill_val_real, .true.) /) + + ! Urban parameters dimensioned by nlevurb + type(param), parameter :: params_levurb(6) = & + (/ param('TK_ROOF', fill_val_real, .true.), & + param('TK_WALL', fill_val_real, .true.), & + param('CV_ROOF', fill_val_real, .true.), & + param('CV_WALL', fill_val_real, .true.), & + + ! Impervious road thermal conductivity and heat capacity have varying levels of + ! data. Thus, we expect to find some missing values in the lookup table -- we + ! do not want to treat that as an error -- thus, we set check_invalid=.false. + param('CV_IMPROAD', fill_val_real, .false.), & + param('TK_IMPROAD', fill_val_real, .false.) /) + + + character(len=*), parameter :: subname = 'mkurbanpar' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make Urban Parameters .....' + call shr_sys_flush(6) + + ! Determine & error-check array sizes + ns_o = size(region_o) + if (size(urbn_classes_gcell_o, 1) /= ns_o) then + write(6,*) modname//':'//subname//' ERROR: array size mismatch' + write(6,*) 'size(region_o) = ', size(region_o) + write(6,*) 'size(urbn_classes_gcell_o, 1) = ', size(urbn_classes_gcell_o, 1) + call abort() + end if + if (size(urbn_classes_gcell_o, 2) /= numurbl) then + write(6,*) modname//':'//subname//' ERROR: array size mismatch' + write(6,*) 'size(urbn_classes_gcell_o, 2) = ', size(urbn_classes_gcell_o, 2) + write(6,*) 'numurbl = ', numurbl + end if + + + ! Read dimensions from input file + + write (6,*) 'Open urban parameter file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncidi), subname) + call check_ret(nf_inq_dimid(ncidi, 'nlevurb', dimid), subname) + call check_ret(nf_inq_dimlen(ncidi, dimid, nlevurb_i), subname) + call check_ret(nf_inq_dimid(ncidi, 'numsolar', dimid), subname) + call check_ret(nf_inq_dimlen(ncidi, dimid, numsolar_i), subname) + call check_ret(nf_inq_dimid(ncidi, 'numrad', dimid), subname) + call check_ret(nf_inq_dimlen(ncidi, dimid, numrad_i), subname) + + if (nlevurb_i /= nlevurb) then + write(6,*)'MKURBANPAR: parameter nlevurb= ',nlevurb, & + 'does not equal input dataset nlevurb= ',nlevurb_i + call abort() + endif + if (numsolar_i /= numsolar) then + write(6,*)'MKURBANPAR: parameter numsolar= ',numsolar, & + 'does not equal input dataset numsolar= ',numsolar_i + call abort() + endif + if (numrad_i /= numrad) then + write(6,*)'MKURBANPAR: parameter numrad= ',numrad, & + 'does not equal input dataset numrad= ',numrad_i + call abort() + endif + + ! Create an array that will hold the density indices + ! In a given grid cell, we output parameter values for all density classes, for the + ! region of that grid cell. In order to do this while still using the lookup_2d + ! routine, we create a dummy unity_dens_o array that contains the density values + ! passed to the lookup routine. + + allocate(unity_dens_o(ns_o, numurbl)) + do k = 1, numurbl + unity_dens_o(:,k) = k + end do + + ! Handle urban parameters with no extra dimensions + + allocate(data_scalar_o(ns_o, numurbl), stat=ier) + if (ier /= 0) then + write(6,*)'mkurbanpar allocation error'; call abort() + end if + + do p = 1, size(params_scalar) + call lookup_and_check_err(params_scalar(p)%name, params_scalar(p)%fill_val, & + params_scalar(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & + data_scalar_o, 0) + + call check_ret(nf_inq_varid(ncido, params_scalar(p)%name, varid), subname) + ! In the following, note that type conversion occurs if we're writing to a variable of type + ! other than double; e.g., for an integer, conversion occurs by truncation! + call check_ret(nf_put_var_double(ncido, varid, data_scalar_o), subname) + end do + + deallocate(data_scalar_o) + + ! Handle urban parameters dimensioned by numrad & numsolar + + allocate(data_rad_o(ns_o, numurbl, numrad, numsolar), stat=ier) + if (ier /= 0) then + write(6,*)'mkurbanpar allocation error'; call abort() + end if + + allocate(extra_dims(2)) + extra_dims(1)%name = 'numrad' + extra_dims(2)%name = 'numsolar' + + do p = 1, size(params_rad) + do m = 1,numsolar + extra_dims(2)%val = m + do n = 1,numrad + extra_dims(1)%val = n + + call lookup_and_check_err(params_rad(p)%name, params_rad(p)%fill_val, & + params_rad(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & + data_rad_o(:,:,n,m), & + 2, extra_dims) + end do + end do + + ! Special handling of numsolar: rather than outputting variables with a numsolar + ! dimension, we output separate variables for each value of numsolar + do m = 1,numsolar + if (len_trim(params_rad(p)%name) + len_trim(solar_suffix(m)) > len(varname)) then + write(6,*) 'variable name exceeds length of varname' + write(6,*) trim(params_rad(p)%name)//trim(solar_suffix(m)) + call abort() + end if + varname = trim(params_rad(p)%name)//trim(solar_suffix(m)) + call check_ret(nf_inq_varid(ncido, varname, varid), subname) + ! In the following, note that type conversion occurs if we're writing to a variable of type + ! other than double; e.g., for an integer, conversion occurs by truncation! + call check_ret(nf_put_var_double(ncido, varid, data_rad_o(:,:,:,m)), subname) + end do + end do + + deallocate(data_rad_o) + deallocate(extra_dims) + + ! Handle urban parameters dimensioned by nlevurb + + allocate(data_levurb_o(ns_o, numurbl, nlevurb), stat=ier) + if (ier /= 0) then + write(6,*)'mkurbanpar allocation error'; call abort() + end if + + allocate(extra_dims(1)) + extra_dims(1)%name = 'nlevurb' + + do p = 1, size(params_levurb) + do n = 1,nlevurb + extra_dims(1)%val = n + + call lookup_and_check_err(params_levurb(p)%name, params_levurb(p)%fill_val, & + params_levurb(p)%check_invalid, & + urban_skip_abort_on_invalid_data_check, data_levurb_o(:,:,n), & + 1, extra_dims) + end do + + call check_ret(nf_inq_varid(ncido, params_levurb(p)%name, varid), subname) + ! In the following, note that type conversion occurs if we're writing to a variable of type + ! other than double; e.g., for an integer, conversion occurs by truncation! + call check_ret(nf_put_var_double(ncido, varid, data_levurb_o), subname) + end do + + deallocate(data_levurb_o) + deallocate(extra_dims) + + + call check_ret(nf_close(ncidi), subname) + call check_ret(nf_sync(ncido), subname) + + write (6,*) 'Successfully made Urban Parameters' + write (6,*) + call shr_sys_flush(6) + + deallocate(unity_dens_o) + +contains +!------------------------------------------------------------------------------ + subroutine lookup_and_check_err(varname, fill_val, check_invalid, & + urban_skip_abort_on_invalid_data_check, data, n_extra_dims, extra_dims) + + ! Wrapper to lookup_2d_netcdf: Loops over each density class, calling lookup_2d_netcdf + ! with that density class and filling the appropriate slice of the data array. Also + ! checks for any errors, aborting if there were any. + ! + ! Note that the lookup_2d_netcdf routine is designed to work with a single value of + ! each of the indices. However, we want to fill parameter values for ALL density + ! classes. This is why we loop over density class in this routine. + ! + ! Note: inherits a number of variables from the parent routine + + use mkindexmapMod, only : lookup_2d_netcdf + + implicit none + character(len=*), intent(in) :: varname ! name of lookup table + real(r8) , intent(in) :: fill_val ! value to put where we have no data in output variables + logical , intent(in) :: check_invalid ! should we check whether there are any invalid data in the output? + logical , intent(in) :: urban_skip_abort_on_invalid_data_check + + real(r8) , intent(out):: data(:,:) ! output from lookup_2d_netcdf + integer , intent(in) :: n_extra_dims ! number of extra dimensions in the lookup table + + ! slice to use if lookup table variable has more than 2 dimensions: + type(dim_slice_type), intent(in), optional :: extra_dims(:) + + ! Local variables: + + integer :: k,n ! indices + integer :: ierr ! error return code + + + do k = 1, numurbl + ! In the following, note that unity_dens_o(:,k) has been constructed so that + ! unity_dens_o(:,k)==k everywhere. Thus, we fill data(:,k) with the parameter + ! values corresponding to density class k. + ! Also note: We use invalid_okay=.true. because we fill all density classes, + ! some of which may have invalid entries. Because doing so disables some error + ! checking, we do our own error checking after the call. + call lookup_2d_netcdf(ncidi, varname, .true., & + 'density_class', 'region', n_extra_dims, & + unity_dens_o(:,k), region_o, fill_val, data(:,k), ierr, & + extra_dims=extra_dims, nodata=index_nodata, & + invalid_okay=.true.) + + if (ierr /= 0) then + write(6,*) modname//':'//subname//' ERROR in lookup_2d_netcdf for ', & + trim(varname), ' class', k, ': err=', ierr + call abort() + end if + + if (check_invalid) then + ! Make sure we have valid parameter values wherever we have non-zero urban cover + do n = 1, ns_o + ! This check assumes that fill_val doesn't appear in any of the valid entries + ! of the lookup table + if (urbn_classes_gcell_o(n,k) > 0. .and. data(n,k) == fill_val) then + write(6,*) modname//':'//subname//' ERROR: fill value found in output where urban cover > 0' + write(6,*) 'var: ', trim(varname) + write(6,*) 'class: ', k + write(6,*) 'n: ', n + write(6,*) 'region: ', region_o(n) + write(6,*) 'urbn_classes_gcell_o(n,k): ', urbn_classes_gcell_o(n,k) + if (.not. urban_skip_abort_on_invalid_data_check) then + ! NOTE(bja, 2015-01) added to work around a ?bug? noted in + ! /glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 + call abort() + end if + end if + end do + end if + + end do + + end subroutine lookup_and_check_err + +end subroutine mkurbanpar +!------------------------------------------------------------------------------ + +end module mkurbanparMod diff --git a/tools/mksurfdata_esmf/src/mkutilsMod.F90 b/tools/mksurfdata_esmf/src/mkutilsMod.F90 new file mode 100644 index 0000000000..653535aec9 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkutilsMod.F90 @@ -0,0 +1,162 @@ +module mkutilsMod + + + ! General-purpose utilities + use ESMF + use shr_kind_mod, only : r8 => shr_kind_r8 + + implicit none + private + + ! PUBLIC MEMBER FUNCTIONS: + public :: normalize_classes_by_gcell ! renormalize array so values are given as % of total grid cell area + public :: slightly_below + public :: slightly_above + public :: chkerr + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + +!=============================================================== +contains +!=============================================================== + + subroutine normalize_classes_by_gcell(classes_pct_tot, sums, classes_pct_gcell) + ! + ! !DESCRIPTION: + ! Renormalizes an array (gcell x class) so that values are given as % of total grid cell area + ! + ! Specifically: Given (1) an array specifying the % cover of different classes, as a % of + ! some total ('classes_pct_tot'), and (2) a vector giving these totals ('sums'), expressed + ! as % of grid cell area: Returns an array ('classes_pct_gcell') of the same + ! dimensionality as classes_pct_tot, where the values now give the % cover of each class + ! as a % of total grid cell area. + ! + ! The size of 'sums' should match the size of the first dimension in 'classes_pct_tot' and + ! 'classes_pct_gcell' + ! + ! For example, if classes_pct_tot(n,i) gives the % of the urban area in grid cell n that is + ! in urban class #i, and sums(n) gives the % of grid cell n that is urban, then + ! classes_pct_gcell(n,i) will give the % of the total area of grid cell n that is in urban + ! class #i. + ! + ! !USES: + ! + ! !ARGUMENTS: + implicit none + real(r8), intent(in) :: classes_pct_tot(:,:) ! % cover of classes as % of total + real(r8), intent(in) :: sums(:) ! totals, as % of grid cell + real(r8), intent(out):: classes_pct_gcell(:,:) ! % cover of classes as % of grid cell + ! + ! !LOCAL VARIABLES: + integer :: n, n_max + character(len=*), parameter :: subname = "normalize_classes_by_gcell" + !------------------------------------------------------------------------------ + + ! Error-check inputs + + n_max = size(sums) + if (size(classes_pct_tot, 1) /= n_max .or. & + size(classes_pct_gcell, 1) /= n_max) then + write(6,*) subname//' ERROR: array size mismatch' + write(6,*) 'size(sums) = ', n_max + write(6,*) 'size(classes_pct_tot, 1) = ', size(classes_pct_tot, 1) + write(6,*) 'size(classes_pct_gcell, 1) = ', size(classes_pct_gcell, 1) + call abort() + end if + + if (size(classes_pct_tot, 2) /= size(classes_pct_gcell, 2)) then + write(6,*) subname//' ERROR: array size mismatch' + write(6,*) 'size(classes_pct_tot, 2) = ', size(classes_pct_tot, 2) + write(6,*) 'size(classes_pct_gcell, 2) = ', size(classes_pct_gcell, 2) + call abort() + end if + + ! Do the work + + do n = 1, n_max + classes_pct_gcell(n,:) = classes_pct_tot(n,:) * (sums(n)/100._r8) + end do + end subroutine normalize_classes_by_gcell + + !=============================================================== + logical function slightly_below(a, b, eps) + + ! Returns true if a is slightly below b; false if a is significantly below b or if a is + ! greater than or equal to b + ! if provided, eps gives the relative error allowed for checking the "slightly" + ! condition; if not provided, the tolerance defaults to the value given by eps_default + + ! !ARGUMENTS: + real(r8), intent(in) :: a + real(r8), intent(in) :: b + real(r8), intent(in), optional :: eps + + ! !LOCAL VARIABLES: + real(r8) :: l_eps + real(r8), parameter :: eps_default = 1.e-15_r8 ! default relative error tolerance + !------------------------------------------------------------------------------ + + if (present(eps)) then + l_eps = eps + else + l_eps = eps_default + end if + + if (a < b .and. (b - a)/b < l_eps) then + slightly_below = .true. + else + slightly_below = .false. + end if + + end function slightly_below + + !=============================================================== + logical function slightly_above(a, b, eps) + + ! !DESCRIPTION: + ! Returns true if a is slightly above b; false if a is significantly above b or if a is + ! less than or equal to b + + ! !ARGUMENTS: + ! if provided, eps gives the relative error allowed for checking the "slightly" + ! condition; if not provided, the tolerance defaults to the value given by eps_default + real(r8), intent(in) :: a + real(r8), intent(in) :: b + real(r8), intent(in), optional :: eps + + ! !LOCAL VARIABLES: + real(r8) :: l_eps + real(r8), parameter :: eps_default = 1.e-15_r8 ! default relative error tolerance + !------------------------------------------------------------------------------ + + if (present(eps)) then + l_eps = eps + else + l_eps = eps_default + end if + + if (a > b .and. (a - b)/b < l_eps) then + slightly_above = .true. + else + slightly_above = .false. + end if + + end function slightly_above + + !=============================================================== + logical function chkerr(rc, line, file) + integer , intent(in) :: rc + integer , intent(in) :: line + character(len=*) , intent(in) :: file + + ! local variables + integer :: lrc + chkerr = .false. + lrc = rc + if (ESMF_LogFoundError(rcToCheck=lrc, msg=ESMF_LOGERR_PASSTHRU, line=line, file=file)) then + chkerr = .true. + endif + end function chkerr + +end module mkutilsMod diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 new file mode 100644 index 0000000000..714b46ec76 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -0,0 +1,416 @@ +module mkvarctl + + !----------------------------------------------------------------------- + ! Module containing control variables + !----------------------------------------------------------------------- + + use ESMF + use shr_kind_mod, only: r8 => shr_kind_r8 + + implicit none + private + +#include + + ! --------------------- + ! routines + ! --------------------- + + public :: read_namelist_input + public :: check_namelist_input + public :: write_namelist_input + + ! --------------------- + ! variables + ! --------------------- + + integer, public :: ndiag ! output log unit + logical, public :: root_task ! proc 0 logical for printing msgs + integer, public :: iam ! processor number + integer, public :: npes ! number of processors + integer, public :: mpicom ! communicator group + logical, public :: create_esmf_pet_files + + ! Values from mpif.h that will be used + public :: MPI_INTEGER + public :: MPI_REAL8 + public :: MPI_LOGICAL + public :: MPI_CHARACTER + public :: MPI_COMM_WORLD + + real(r8), public, parameter :: spval = 1.e36 ! special value + integer, public, parameter :: ispval = -9999 ! special value + + character(len=256) , public :: fgrddat ! grid data file + character(len=256) , public :: fsurdat ! output surface data file name (if blank, do not output a surface dataset) + character(len=256) , public :: fsurlog ! output surface log file name + character(len=256) , public :: fdyndat ! dynamic landuse data file name + character(len=256) , public :: fhrvname ! generic harvest filename + logical , public :: all_veg ! if gridcell will be 100% vegetated land-cover + real(r8) , public :: std_elev = -999.99_r8 ! Standard deviation of elevation (m) to use for ent + + ! NOTE(bja, 2015-01) added to work around a ?bug? causing 1x1_urbanc_alpha to abort. See + !/glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 + logical :: urban_skip_abort_on_invalid_data_check + + logical, public :: outnc_large_files ! output files in 64-bit format for large files + logical, public :: outnc_double ! output ALL data in files as 64-bit + integer, public :: outnc_dims = 2 ! only applicable to lat/lon grids + logical, public :: outnc_1d ! true => output file is 1d + logical, public :: outnc_vic ! true => output VIC fields + logical, public :: outnc_3dglc ! true => output 3D glacier fields + + character(len= 32), public :: mksrf_gridnm = ' ' ! name of grid to use on output file + character(len=512), public :: mksrf_gridtype = ' ' ! land gridtype, global or reg + character(len=512), public :: mksrf_fgrid_mesh = ' ' ! land grid file name to use + integer , public :: mksrf_fgrid_mesh_nx + integer , public :: mksrf_fgrid_mesh_ny + + character(len=512), public :: mksrf_fvegtyp = ' ' ! vegetation data file name + character(len=512), public :: mksrf_fhrvtyp = ' ' ! harvest data file name + character(len=512), public :: mksrf_fsoitex = ' ' ! soil texture data file name + character(len=512), public :: mksrf_forganic = ' ' ! organic matter data file name + character(len=512), public :: mksrf_fsoicol = ' ' ! soil color data file name + character(len=512), public :: mksrf_fabm = ' ' ! ag fire peak month and + character(len=512), public :: mksrf_fpeat = ' ' ! peatlands and + character(len=512), public :: mksrf_fsoildepth = ' ' ! soil depth file name + character(len=512), public :: mksrf_fgdp = ' ' ! gdp data file names + character(len=512), public :: mksrf_flakwat = ' ' ! inland lake data file name + character(len=512), public :: mksrf_fwetlnd = ' ' ! inland wetlands data file name + character(len=512), public :: mksrf_furban = ' ' ! urban data file name + character(len=512), public :: mksrf_fglacier = ' ' ! glacier data file name + character(len=512), public :: mksrf_fglacierregion = ' ' ! glacier region data file name + character(len=512), public :: mksrf_furbtopo = ' ' ! urban topography data file name + character(len=512), public :: mksrf_fmax = ' ' ! fmax data file name + character(len=512), public :: mksrf_flai = ' ' ! lai data filename + character(len=512), public :: mksrf_fdynuse = ' ' ! ascii file containing names of dynamic land use files + character(len=512), public :: mksrf_fvocef = ' ' ! VOC Emission Factor data file name + character(len=512), public :: mksrf_ftopostats = ' ' ! topography statistics data file name + character(len=512), public :: mksrf_fvic = ' ' ! VIC parameters data file name + + character(len=512), public :: mksrf_fvegtyp_mesh = ' ' ! vegetation mesh file name + character(len=512), public :: mksrf_fhrvtyp_mesh = ' ' ! harvest mesh file name + character(len=512), public :: mksrf_fsoitex_mesh = ' ' ! soil texture mesh file name + character(len=512), public :: mksrf_forganic_mesh = ' ' ! organic matter mesh file name + character(len=512), public :: mksrf_fsoicol_mesh = ' ' ! soil color mesh file name + character(len=512), public :: mksrf_fabm_mesh = ' ' ! ag fire peak month and + character(len=512), public :: mksrf_fpeat_mesh = ' ' ! peatlands and + character(len=512), public :: mksrf_fsoildepth_mesh = ' ' ! soil depth file name + character(len=512), public :: mksrf_fgdp_mesh = ' ' ! gdp mesh file names + character(len=512), public :: mksrf_flakwat_mesh = ' ' ! inland lake mesh file name + character(len=512), public :: mksrf_fwetlnd_mesh = ' ' ! inland wetlands mesh file name + character(len=512), public :: mksrf_furban_mesh = ' ' ! urban mesh file name + character(len=512), public :: mksrf_fglacier_mesh = ' ' ! glacier mesh file name + character(len=512), public :: mksrf_fglacierregion_mesh = ' ' ! glacier region mesh file name + character(len=512), public :: mksrf_furbtopo_mesh = ' ' ! urban topography mesh file name + character(len=512), public :: mksrf_fmax_mesh = ' ' ! fmax mesh file name + character(len=512), public :: mksrf_flai_mesh = ' ' ! lai mesh filename + character(len=512), public :: mksrf_fhrv_mesh = ' ' ! harvest mesh filename + character(len=512), public :: mksrf_fdynuse_mesh_mesh_mesh = ' ' ! ascii file containing names of dynamic land use files + character(len=512), public :: mksrf_fvocef_mesh = ' ' ! VOC Emission Factor mesh file name + character(len=512), public :: mksrf_ftopostats_mesh = ' ' ! topography statistics mesh file name + character(len=512), public :: mksrf_fvic_mesh = ' ' ! VIC parameters mesh file name + + integer , public :: numpft = 16 ! number of plant types + ! + ! Variables to override data read in with + ! (all_urban is mostly for single-point mode, but could be used for sensitivity studies) + ! + logical, public :: all_urban ! output ALL data as 100% covered in urban + logical, public :: no_inlandwet ! set wetland to 0% over land; wetland will only be used for ocean points + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + +!=============================================================== +contains +!=============================================================== + + subroutine read_namelist_input() + + ! local variables + integer :: ier + integer :: fileunit + ! ------------------------------------------------------------ + + namelist /mksurfdata_input/ & + mksrf_fvegtyp, & + mksrf_fhrvtyp, & + mksrf_fsoitex, & + mksrf_forganic, & + mksrf_fsoicol, & + mksrf_fvocef, & + mksrf_flakwat, & + mksrf_fwetlnd, & + mksrf_fglacier, & + mksrf_fglacierregion, & + mksrf_furbtopo, & + mksrf_fmax, & + mksrf_furban, & + mksrf_flai, & + mksrf_fdynuse, & + mksrf_fgdp, & + mksrf_fpeat, & + mksrf_fsoildepth, & + mksrf_fabm, & + mksrf_ftopostats, & + mksrf_fvic, & + mksrf_flai_mesh, & + mksrf_fhrv_mesh, & + mksrf_forganic_mesh, & + mksrf_fsoicol_mesh, & + mksrf_fsoitex_mesh, & + mksrf_fmax_mesh, & + mksrf_flakwat_mesh, & + mksrf_fwetlnd_mesh, & + mksrf_fvocef_mesh, & + mksrf_furban_mesh, & + mksrf_furbtopo_mesh, & + mksrf_fglacier_mesh, & + mksrf_fglacierregion_mesh, & + mksrf_fgdp_mesh, & + mksrf_fpeat_mesh, & + mksrf_fsoildepth_mesh, & + mksrf_fabm_mesh, & + mksrf_ftopostats_mesh, & + mksrf_fvic_mesh, & + mksrf_fvegtyp_mesh, & + mksrf_fgrid_mesh, & + mksrf_fgrid_mesh_nx, & + mksrf_fgrid_mesh_ny, & + !nglcec, & + numpft, & + !pft_idx, & + all_veg, & + !pft_frc, & + all_urban, & + no_inlandwet, & + !gitdescribe, & + outnc_large_files, & + outnc_double, & + outnc_dims, & + outnc_vic, & + outnc_3dglc, & + fsurdat, & + fdyndat, & + fsurlog, & + std_elev, & + urban_skip_abort_on_invalid_data_check, & + create_esmf_pet_files + + ! Set default namelist values - make these the defaults in gen_mksurfdata_namelist.py + mksrf_gridtype = 'global' + outnc_large_files = .false. + outnc_double = .true. + outnc_vic = .false. + outnc_3dglc = .false. + all_urban = .false. + all_veg = .false. + no_inlandwet = .true. + urban_skip_abort_on_invalid_data_check = .false. ! default value for bug work around + + if (root_task) then + write(6,*) 'Attempting to initialize control settings .....' + end if + + if (root_task) then + open(newunit=fileunit, status="old", file="mksurfdata_in") + read(fileunit, nml=mksurfdata_input, iostat=ier) + if (ier > 0) then + call ESMF_LogWrite('error reading in mksurfdata_input namelist from mksurfdata_in', & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + call ESMF_Finalize(endflag=ESMF_END_ABORT) + end if + close(fileunit) + end if + + call mpi_bcast (mksrf_fgrid_mesh, len(mksrf_fgrid_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fvegtyp, len(mksrf_fvegtyp), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fhrvtyp, len(mksrf_fhrvtyp), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fsoitex, len(mksrf_fsoitex), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_forganic, len(mksrf_forganic), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fsoicol, len(mksrf_fsoicol), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fabm, len(mksrf_fabm), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fpeat, len(mksrf_fpeat), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fsoildepth, len(mksrf_fsoildepth), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fgdp, len(mksrf_fgdp), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_flakwat, len(mksrf_flakwat), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fwetlnd, len(mksrf_fwetlnd), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_furban, len(mksrf_furban), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fglacier, len(mksrf_fglacier), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fglacierregion, len(mksrf_fglacierregion), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_furbtopo, len(mksrf_furbtopo), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fmax, len(mksrf_fmax), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_flai, len(mksrf_flai), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fdynuse, len(mksrf_fdynuse), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fvocef, len(mksrf_fvocef), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_ftopostats, len(mksrf_ftopostats), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fvic, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fvegtyp_mesh, len(mksrf_fvegtyp_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fhrvtyp_mesh, len(mksrf_fhrvtyp_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fsoitex_mesh, len(mksrf_fsoitex_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_forganic_mesh, len(mksrf_forganic_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fsoicol_mesh, len(mksrf_fsoicol_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fabm_mesh, len(mksrf_fabm_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fpeat_mesh, len(mksrf_fpeat_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fsoildepth_mesh, len(mksrf_fsoildepth_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fgdp_mesh, len(mksrf_fgdp_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_flakwat_mesh, len(mksrf_flakwat_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fwetlnd_mesh, len(mksrf_fwetlnd_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_furban_mesh, len(mksrf_furban_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fglacier_mesh, len(mksrf_fglacier_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fglacierregion_mesh, len(mksrf_fglacierregion_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_furbtopo_mesh, len(mksrf_furbtopo_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fmax_mesh, len(mksrf_fmax_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_flai_mesh, len(mksrf_flai_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fdynuse_mesh_mesh_mesh, len(mksrf_fdynuse_mesh_mesh_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fvocef, len(mksrf_fvocef), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_ftopostats, len(mksrf_ftopostats), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fvic, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (create_esmf_pet_files, 1, MPI_LOGICAL, 0, MPICOM, ier) + + end subroutine read_namelist_input + + !=============================================================== + subroutine check_namelist_input() + ! error check on namelist input + + if (root_task) then + if (urban_skip_abort_on_invalid_data_check) then + write(ndiag, *) "WARNING: aborting on invalid data check in urban has been disabled!" + write(ndiag, *) "WARNING: urban data may be invalid!" + end if + end if + + if (mksrf_fgrid_mesh /= ' ')then + fgrddat = mksrf_fgrid_mesh + if (root_task) write(ndiag,*)'mksrf_fgrid_mesh = ',trim(mksrf_fgrid_mesh) + else + call ESMF_LogWrite(" must specify mksrf_fgrid_mesh", ESMF_LOGMSG_ERROR) + call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + + if (trim(mksrf_gridtype) == 'global' .or. trim(mksrf_gridtype) == 'regional') then + write(ndiag,*)'mksrf_gridtype = ',trim(mksrf_gridtype) + else + call ESMF_LogWrite(" mksrf_gridtype "//trim(mksrf_gridtype)//" is not supported", ESMF_LOGMSG_ERROR) + call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + + if (root_task) then + if ( outnc_large_files )then + write(ndiag,'(a)')'Output file in NetCDF 64-bit large_files format' + end if + if ( outnc_double )then + write(ndiag,'(a)')'Output ALL data in file as 64-bit' + end if + if ( outnc_vic )then + write(ndiag,'(a)')'Output VIC fields' + end if + if ( outnc_3dglc )then + write(ndiag,'(a)')'Output optional 3D glacier fields (mostly used for verification of the glacier model)' + end if + if ( outnc_3dglc )then + write(ndiag,'(a)')'Output optional 3D glacier fields (mostly used for verification of the glacier model)' + end if + if ( all_urban )then + write(ndiag,'(a)') 'Output ALL data in file as 100% urban' + end if + if ( no_inlandwet )then + write(ndiag,'(a)') 'Set wetland to 0% over land' + end if + end if + + ! if (nglcec <= 0) then + ! call shr_sys_abort('nglcec must be at least 1') + ! end if + + if (root_task) then + if (all_veg) then + write(ndiag,'(a)') 'Output ALL data in file as 100% vegetated' + end if + end if + + if (mksrf_fgrid_mesh_ny == 1) then + if (root_task) then + write(ndiag,*)'fsurdat is 2d lat/lon grid' + write(ndiag,*)'nlon= ',mksrf_fgrid_mesh_nx + write(ndiag,*)'nlat= ',mksrf_fgrid_mesh_ny + if (outnc_dims == 1) then + write(ndiag,*)' writing output file in 1d gridcell format' + end if + end if + else + if (root_task) then + write(ndiag,*)'fsurdat is 1d gridcell grid' + outnc_dims = 1 + end if + end if + + outnc_1d = .true. + if (root_task) then + write(ndiag,*)'output file will be 1d' + else + outnc_1d = .false. + if (mksrf_fgrid_mesh_ny == 1) then + outnc_1d = .true. + end if + end if + + end subroutine check_namelist_input + + !=============================================================== + subroutine write_namelist_input() + + ! Note - need to call this after ndiag has been set + + if (root_task) then + write(ndiag,*) 'PFTs from: ',trim(mksrf_fvegtyp) + write(ndiag,*) 'harvest from: ',trim(mksrf_fhrvtyp) + write(ndiag,*) 'fmax from: ',trim(mksrf_fmax) + write(ndiag,*) 'glaciers from: ',trim(mksrf_fglacier) + !write(ndiag,*) ' with: ', nglcec, ' glacier elevation classes' + write(ndiag,*) 'glacier region ID from: ',trim(mksrf_fglacierregion) + write(ndiag,*) 'urban topography from: ',trim(mksrf_furbtopo) + write(ndiag,*) 'urban from: ',trim(mksrf_furban) + write(ndiag,*) 'inland lake from: ',trim(mksrf_flakwat) + write(ndiag,*) 'inland wetland from: ',trim(mksrf_fwetlnd) + write(ndiag,*) 'soil texture from: ',trim(mksrf_fsoitex) + write(ndiag,*) 'soil organic from: ',trim(mksrf_forganic) + write(ndiag,*) 'soil color from: ',trim(mksrf_fsoicol) + write(ndiag,*) 'VOC emission factors from: ',trim(mksrf_fvocef) + write(ndiag,*) 'gdp from: ',trim(mksrf_fgdp) + write(ndiag,*) 'peat from: ',trim(mksrf_fpeat) + write(ndiag,*) 'soil depth from: ',trim(mksrf_fsoildepth) + write(ndiag,*) 'abm from: ',trim(mksrf_fabm) + write(ndiag,*) 'topography statistics from: ',trim(mksrf_ftopostats) + write(ndiag,*) 'VIC parameters from: ',trim(mksrf_fvic) + write(ndiag,*)' mesh for pft ',trim(mksrf_fvegtyp_mesh) + write(ndiag,*)' mesh for lake water ',trim(mksrf_flakwat_mesh) + write(ndiag,*)' mesh for wetland ',trim(mksrf_fwetlnd_mesh) + write(ndiag,*)' mesh for glacier ',trim(mksrf_fglacier_mesh) + write(ndiag,*)' mesh for glacier region ',trim(mksrf_fglacierregion_mesh) + write(ndiag,*)' mesh for soil texture ',trim(mksrf_fsoitex_mesh) + write(ndiag,*)' mesh for soil color ',trim(mksrf_fsoicol_mesh) + write(ndiag,*)' mesh for soil organic ',trim(mksrf_forganic_mesh) + write(ndiag,*)' mesh for urban ',trim(mksrf_furban_mesh) + write(ndiag,*)' mesh for fmax ',trim(mksrf_fmax_mesh) + write(ndiag,*)' mesh for VOC pct emis ',trim(mksrf_fvocef_mesh) + write(ndiag,*)' mesh for harvest ',trim(mksrf_fhrv_mesh) + write(ndiag,*)' mesh for lai/sai ',trim(mksrf_flai_mesh) + write(ndiag,*)' mesh for urb topography ',trim(mksrf_furbtopo_mesh) + write(ndiag,*)' mesh for GDP ',trim(mksrf_fgdp_mesh) + write(ndiag,*)' mesh for peatlands ',trim(mksrf_fpeat_mesh) + write(ndiag,*)' mesh for soil depth ',trim(mksrf_fsoildepth_mesh) + write(ndiag,*)' mesh for ag fire pk month ',trim(mksrf_fabm_mesh) + write(ndiag,*)' mesh for topography stats ',trim(mksrf_ftopostats_mesh) + write(ndiag,*)' mesh for VIC parameters ',trim(mksrf_fvic_mesh) + + if (mksrf_fdynuse /= ' ') then + write(ndiag,*)'mksrf_fdynuse = ',trim(mksrf_fdynuse) + end if + end if + + end subroutine write_namelist_input + +end module mkvarctl diff --git a/tools/mksurfdata_esmf/src/mkvarpar.F90 b/tools/mksurfdata_esmf/src/mkvarpar.F90 new file mode 100644 index 0000000000..28487babba --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkvarpar.F90 @@ -0,0 +1,22 @@ +module mkvarpar + +!----------------------------------------------------------------------- +! Module containing CLM parameters +!----------------------------------------------------------------------- + + use shr_kind_mod, only: r8 => shr_kind_r8 + use shr_const_mod, only: SHR_CONST_REARTH + + implicit none + public + + integer, parameter :: nlevsoi = 10 ! number of soil layers + integer, parameter :: numstdpft = 16 ! number of standard PFT types + integer, parameter :: numstdcft = 2 ! of the number of standard PFT types, how many are crop (CFT) + integer, parameter :: noveg = 0 ! value for non-vegetated pft + integer, parameter :: numsolar = 2 ! number of solar types (Direct,Diffuse) + integer, parameter :: numrad = 2 ! number of solar bands (VIS,NIR) + real(r8),parameter :: elev_thresh = 2600._r8 ! elevation threshold for screening urban areas + real(r8),parameter :: re = SHR_CONST_REARTH*0.001 + +end module mkvarpar diff --git a/tools/mksurfdata_esmf/src/mkvocefMod.F90 b/tools/mksurfdata_esmf/src/mkvocefMod.F90 new file mode 100644 index 0000000000..03d9dddd3f --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkvocefMod.F90 @@ -0,0 +1,209 @@ +module mkvocefMod +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mkvocMod +! +! !DESCRIPTION: +! Make VOC percentage emissions for surface dataset +! +! !REVISION HISTORY: +! Author: Erik Kluzek +! +!----------------------------------------------------------------------- +! !USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush + use mkdomainMod , only : domain_checksame + + implicit none + private + +! !PUBLIC MEMBER FUNCTIONS: + public :: mkvocef ! Get the percentage emissions for VOC for different + ! land cover types +!EOP + +contains + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: mkvocef +! +! !INTERFACE: +subroutine mkvocef(ldomain, mapfname, datfname, ndiag, & + ef_btr_o, ef_fet_o, ef_fdt_o, ef_shr_o, ef_grs_o, ef_crp_o) +! +! !DESCRIPTION: +! make volatile organic coumpunds (VOC) emission factors. +! +! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio +! +! !ARGUMENTS: + implicit none + type(domain_type) , intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diagnostic output + real(r8) , intent(out):: ef_btr_o(:) ! output grid: EFs for broadleaf trees + real(r8) , intent(out):: ef_fet_o(:) ! output grid: EFs for fineleaf evergreen + real(r8) , intent(out):: ef_fdt_o(:) ! output grid: EFs for fineleaf deciduous + real(r8) , intent(out):: ef_shr_o(:) ! output grid: EFs for shrubs + real(r8) , intent(out):: ef_grs_o(:) ! output grid: EFs for grasses + real(r8) , intent(out):: ef_crp_o(:) ! output grid: EFs for crops +! +! !CALLED FROM: +! subroutine mksrfdat in module mksrfdatMod +! +! !REVISION HISTORY: +! Author: Colette L. Heald +! 17 Jul 2007 F Vitt -- updated to pftintdat06_clm3_5_05 and corrected indexing of ef_*_i arrarys +! +!EOP +! +! !LOCAL VARIABLES: + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: ef_btr_i(:) ! input grid: EFs for broadleaf trees + real(r8), allocatable :: ef_fet_i(:) ! input grid: EFs for fineleaf evergreen + real(r8), allocatable :: ef_fdt_i(:) ! input grid: EFs for fineleaf deciduous + real(r8), allocatable :: ef_shr_i(:) ! input grid: EFs for shrubs + real(r8), allocatable :: ef_grs_i(:) ! input grid: EFs for grasses + real(r8), allocatable :: ef_crp_i(:) ! input grid: EFs for crops + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + real(r8) :: sum_fldo ! global sum of dummy input fld + real(r8) :: sum_fldi ! global sum of dummy input fld + integer :: k,n,no,ni,ns_o,ns_i ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ier ! error status + real(r8) :: relerr = 0.00001_r8 ! max error: sum overlap wts ne 1 + character(len=32) :: subname = 'mkvocef' +!----------------------------------------------------------------------- + + write (6,*) 'Attempting to make VOC emission factors .....' + call shr_sys_flush(6) + + ns_o = ldomain%ns + + ! ----------------------------------------------------------------- + ! Read input Emission Factors + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + ns_i = tdomain%ns + allocate(ef_btr_i(ns_i), ef_fet_i(ns_i), ef_fdt_i(ns_i), & + ef_shr_i(ns_i), ef_grs_i(ns_i), ef_crp_i(ns_i), & + frac_dst(ns_o), stat=ier) + if (ier/=0) call abort() + + write (6,*) 'Open VOC file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + call check_ret(nf_inq_varid (ncid, 'ef_btr', varid), subname) + call check_ret(nf_get_var_double(ncid, varid, ef_btr_i), subname) + call check_ret(nf_inq_varid (ncid, 'ef_fet', varid), subname) + call check_ret(nf_get_var_double(ncid, varid, ef_fet_i), subname) + call check_ret(nf_inq_varid (ncid, 'ef_fdt', varid), subname) + call check_ret(nf_get_var_double(ncid, varid, ef_fdt_i), subname) + call check_ret(nf_inq_varid (ncid, 'ef_shr', varid), subname) + call check_ret(nf_get_var_double(ncid, varid, ef_shr_i), subname) + call check_ret(nf_inq_varid (ncid, 'ef_grs', varid), subname) + call check_ret(nf_get_var_double(ncid, varid, ef_grs_i), subname) + call check_ret(nf_inq_varid (ncid, 'ef_crp', varid), subname) + call check_ret(nf_get_var_double(ncid, varid, ef_crp_i), subname) + call check_ret(nf_close(ncid), subname) + + ! Area-average percent cover on input grid to output grid + ! and correct according to land landmask + ! Note that percent cover is in terms of total grid area. + + call gridmap_mapread(tgridmap, mapfname ) + + ! Error checks for domain and map consistencies + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Do mapping from input to output grid + + call gridmap_areaave_srcmask(tgridmap, ef_btr_i, ef_btr_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, ef_fet_i, ef_fet_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, ef_fdt_i, ef_fdt_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, ef_shr_i, ef_shr_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, ef_grs_i, ef_grs_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, ef_crp_i, ef_crp_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check for conservation + + do no = 1, ns_o + if ( ef_btr_o(no) < 0._r8 ) then + write (6,*) 'MKVOCEF error: EF btr = ',ef_btr_o(no), & + ' is negative for no = ',no + call abort() + end if + if ( ef_fet_o(no) < 0._r8 ) then + write (6,*) 'MKVOCEF error: EF fet = ',ef_fet_o(no), & + ' is negative for no = ',no + call abort() + end if + if ( ef_fdt_o(no) < 0._r8 ) then + write (6,*) 'MKVOCEF error: EF fdt = ',ef_fdt_o(no), & + ' is negative for no = ',no + call abort() + end if + if ( ef_shr_o(no) < 0._r8 ) then + write (6,*) 'MKVOCEF error: EF shr = ',ef_shr_o(no), & + ' is negative for no = ',no + call abort() + end if + if ( ef_grs_o(no) < 0._r8 ) then + write (6,*) 'MKVOCEF error: EF grs = ',ef_grs_o(no), & + ' is negative for no = ',no + call abort() + end if + if ( ef_crp_o(no) < 0._r8 ) then + write (6,*) 'MKVOCEF error: EF crp = ',ef_crp_o(no), & + ' is negative for no = ',no + call abort() + end if + enddo + + ! ----------------------------------------------------------------- + ! Error check1 + ! Compare global sum fld_o to global sum fld_i. + ! ----------------------------------------------------------------- + + ! Global sum of output field -- must multiply by fraction of + ! output grid that is land as determined by input grid + + allocate(mask_r8(ns_i), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + write (6,*) 'Successfully made VOC Emission Factors' + write (6,*) + call shr_sys_flush(6) + + ! Deallocate dynamic memory + + deallocate ( ef_btr_i, ef_fet_i, ef_fdt_i, & + ef_shr_i, ef_grs_i, ef_crp_i, frac_dst, mask_r8 ) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + +end subroutine mkvocef + +!----------------------------------------------------------------------- + +end module mkvocefMod diff --git a/tools/mksurfdata_esmf/src/nanMod.F90 b/tools/mksurfdata_esmf/src/nanMod.F90 new file mode 100644 index 0000000000..0cbeeea112 --- /dev/null +++ b/tools/mksurfdata_esmf/src/nanMod.F90 @@ -0,0 +1,41 @@ +module nanMod + +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: nanMod +! +! !DESCRIPTION: +! Set parameters for the floating point flags "inf" Infinity +! and "nan" not-a-number. As well as "bigint" the point +! at which integers start to overflow. These values are used +! to initialize arrays with as a way to detect if arrays +! are being used before being set. +! Note that bigint is the largest possible 32-bit integer. +! +! !USES: + use shr_kind_mod, only: r8 => shr_kind_r8 +! +! !PUBLIC TYPES: + implicit none + save +#ifdef __PGI +! quiet nan for portland group compilers + real(r8), parameter :: inf = O'0777600000000000000000' + real(r8), parameter :: nan = O'0777700000000000000000' + integer, parameter :: bigint = O'17777777777' +#else +! signaling nan otherwise + real(r8), parameter :: inf = O'0777600000000000000000' + real(r8), parameter :: nan = O'0777610000000000000000' + integer, parameter :: bigint = O'17777777777' +#endif +! +! !REVISION HISTORY: +! Created by Mariana Vertenstein based on cam module created by +! CCM core group +! +!EOP +!----------------------------------------------------------------------- + +end module nanMod diff --git a/tools/mksurfdata_esmf/src/run_mksurfdata b/tools/mksurfdata_esmf/src/run_mksurfdata new file mode 100644 index 0000000000..58b9c6c703 --- /dev/null +++ b/tools/mksurfdata_esmf/src/run_mksurfdata @@ -0,0 +1,22 @@ +#!/bin/bash +#PBS -A P93300606 +#PBS -N job_name +#PBS -j oe +#PBS -q premium +#PBS -l walltime=45:00 +#PBS -l select=2:ncpus=36:mpiprocs=36 +##PBS -l select=16:ncpus=36:mpiprocs=9 +#PBS -o log.out + +# note for -l input above +# -l select={num_nodes}:ncpus={max_tasks_per_node}:mpiprocs={tasks_per_node} + +export TMPDIR=/glade/scratch/$USER/temp +mkdir -p $TMPDIR + +#module rm netcdf +#module load netcdf-mpi pnetcdf pio/2.5.5 +#make + +# -np {total_tasks} +mpiexec_mpt -np 72 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata diff --git a/tools/mksurfdata_esmf/src/shr_const_mod.F90 b/tools/mksurfdata_esmf/src/shr_const_mod.F90 new file mode 100644 index 0000000000..07d194e71e --- /dev/null +++ b/tools/mksurfdata_esmf/src/shr_const_mod.F90 @@ -0,0 +1,58 @@ +!=============================================================================== + +MODULE shr_const_mod + + use shr_kind_mod + + integer(SHR_KIND_IN),parameter,private :: R8 = SHR_KIND_R8 ! rename for local readability only + + !---------------------------------------------------------------------------- + ! physical constants (all data public) + !---------------------------------------------------------------------------- + public + + real(R8),parameter :: SHR_CONST_PI = 3.14159265358979323846_R8 ! pi + real(R8),parameter :: SHR_CONST_CDAY = 86400.0_R8 ! sec in calendar day ~ sec + real(R8),parameter :: SHR_CONST_SDAY = 86164.0_R8 ! sec in siderial day ~ sec + real(R8),parameter :: SHR_CONST_OMEGA = 2.0_R8*SHR_CONST_PI/SHR_CONST_SDAY ! earth rot ~ rad/sec + real(R8),parameter :: SHR_CONST_REARTH = 6.37122e6_R8 ! radius of earth ~ m + real(R8),parameter :: SHR_CONST_G = 9.80616_R8 ! acceleration of gravity ~ m/s^2 + + real(R8),parameter :: SHR_CONST_STEBOL = 5.67e-8_R8 ! Stefan-Boltzmann constant ~ W/m^2/K^4 + real(R8),parameter :: SHR_CONST_BOLTZ = 1.38065e-23_R8 ! Boltzmann's constant ~ J/K/molecule + real(R8),parameter :: SHR_CONST_AVOGAD = 6.02214e26_R8 ! Avogadro's number ~ molecules/kmole + real(R8),parameter :: SHR_CONST_RGAS = SHR_CONST_AVOGAD*SHR_CONST_BOLTZ ! Universal gas constant ~ J/K/kmole + real(R8),parameter :: SHR_CONST_MWDAIR = 28.966_R8 ! molecular weight dry air ~ kg/kmole + real(R8),parameter :: SHR_CONST_MWWV = 18.016_R8 ! molecular weight water vapor + real(R8),parameter :: SHR_CONST_RDAIR = SHR_CONST_RGAS/SHR_CONST_MWDAIR ! Dry air gas constant ~ J/K/kg + real(R8),parameter :: SHR_CONST_RWV = SHR_CONST_RGAS/SHR_CONST_MWWV ! Water vapor gas constant ~ J/K/kg + real(R8),parameter :: SHR_CONST_ZVIR = (SHR_CONST_RWV/SHR_CONST_RDAIR)-1.0_R8 ! RWV/RDAIR - 1.0 + real(R8),parameter :: SHR_CONST_KARMAN = 0.4_R8 ! Von Karman constant + real(R8),parameter :: SHR_CONST_PSTD = 101325.0_R8 ! standard pressure ~ pascals + real(R8),parameter :: SHR_CONST_PDB = 0.0112372_R8 ! ratio of 13C/12C in Pee Dee Belemnite (C isotope standard) + + real(R8),parameter :: SHR_CONST_TKTRIP = 273.16_R8 ! triple point of fresh water ~ K + real(R8),parameter :: SHR_CONST_TKFRZ = 273.15_R8 ! freezing T of fresh water ~ K + real(R8),parameter :: SHR_CONST_TKFRZSW = SHR_CONST_TKFRZ - 1.8_R8 ! freezing T of salt water ~ K + + real(R8),parameter :: SHR_CONST_RHODAIR = & ! density of dry air at STP ~ kg/m^3 + SHR_CONST_PSTD/(SHR_CONST_RDAIR*SHR_CONST_TKFRZ) + real(R8),parameter :: SHR_CONST_RHOFW = 1.000e3_R8 ! density of fresh water ~ kg/m^3 + real(R8),parameter :: SHR_CONST_RHOSW = 1.026e3_R8 ! density of sea water ~ kg/m^3 + real(R8),parameter :: SHR_CONST_RHOICE = 0.917e3_R8 ! density of ice ~ kg/m^3 + real(R8),parameter :: SHR_CONST_CPDAIR = 1.00464e3_R8 ! specific heat of dry air ~ J/kg/K + real(R8),parameter :: SHR_CONST_CPWV = 1.810e3_R8 ! specific heat of water vap ~ J/kg/K + real(R8),parameter :: SHR_CONST_CPVIR = (SHR_CONST_CPWV/SHR_CONST_CPDAIR)-1.0_R8 ! CPWV/CPDAIR - 1.0 + real(R8),parameter :: SHR_CONST_CPFW = 4.188e3_R8 ! specific heat of fresh h2o ~ J/kg/K + real(R8),parameter :: SHR_CONST_CPSW = 3.996e3_R8 ! specific heat of sea h2o ~ J/kg/K + real(R8),parameter :: SHR_CONST_CPICE = 2.11727e3_R8 ! specific heat of fresh ice ~ J/kg/K + real(R8),parameter :: SHR_CONST_LATICE = 3.337e5_R8 ! latent heat of fusion ~ J/kg + real(R8),parameter :: SHR_CONST_LATVAP = 2.501e6_R8 ! latent heat of evaporation ~ J/kg + real(R8),parameter :: SHR_CONST_LATSUB = & ! latent heat of sublimation ~ J/kg + SHR_CONST_LATICE + SHR_CONST_LATVAP + real(R8),parameter :: SHR_CONST_OCN_REF_SAL = 34.7_R8 ! ocn ref salinity (psu) + real(R8),parameter :: SHR_CONST_ICE_REF_SAL = 4.0_R8 ! ice ref salinity (psu) + + real(R8),parameter :: SHR_CONST_SPVAL = 1.0e30_R8 ! special missing value + +END MODULE shr_const_mod diff --git a/tools/mksurfdata_esmf/src/shr_kind_mod.F90 b/tools/mksurfdata_esmf/src/shr_kind_mod.F90 new file mode 100644 index 0000000000..d1219223da --- /dev/null +++ b/tools/mksurfdata_esmf/src/shr_kind_mod.F90 @@ -0,0 +1,19 @@ +!=============================================================================== + +MODULE shr_kind_mod + + !---------------------------------------------------------------------------- + ! precision/kind constants add data public + !---------------------------------------------------------------------------- + public + integer,parameter :: SHR_KIND_R8 = selected_real_kind(12) ! 8 byte real + integer,parameter :: SHR_KIND_R4 = selected_real_kind( 6) ! 4 byte real + integer,parameter :: SHR_KIND_RN = kind(1.0) ! native real + integer,parameter :: SHR_KIND_I8 = selected_int_kind (13) ! 8 byte integer + integer,parameter :: SHR_KIND_I4 = selected_int_kind ( 6) ! 4 byte integer + integer,parameter :: SHR_KIND_IN = kind(1) ! native integer + integer,parameter :: SHR_KIND_CS = 80 ! short char + integer,parameter :: SHR_KIND_CL = 256 ! long char + integer,parameter :: SHR_KIND_CX = 512 ! extra-long char + +END MODULE shr_kind_mod diff --git a/tools/mksurfdata_esmf/src/shr_log_mod.F90 b/tools/mksurfdata_esmf/src/shr_log_mod.F90 new file mode 100644 index 0000000000..244314a8de --- /dev/null +++ b/tools/mksurfdata_esmf/src/shr_log_mod.F90 @@ -0,0 +1,13 @@ +MODULE shr_log_mod + + use shr_kind_mod + + !---------------------------------------------------------------------------- + ! low-level shared variables for logging, these may not be parameters + !---------------------------------------------------------------------------- + public + + integer(SHR_KIND_IN) :: shr_log_Level = 1 + integer(SHR_KIND_IN) :: shr_log_Unit = 6 + +END MODULE shr_log_mod diff --git a/tools/mksurfdata_esmf/src/shr_mpi_mod.F90 b/tools/mksurfdata_esmf/src/shr_mpi_mod.F90 new file mode 100644 index 0000000000..346b954fb9 --- /dev/null +++ b/tools/mksurfdata_esmf/src/shr_mpi_mod.F90 @@ -0,0 +1,2215 @@ +Module shr_mpi_mod + + !------------------------------------------------------------------------------- + ! PURPOSE: general layer on MPI functions + !------------------------------------------------------------------------------- + + use shr_kind_mod + + implicit none + private + + ! PUBLIC: Public interfaces + + public :: shr_mpi_chkerr + public :: shr_mpi_send + public :: shr_mpi_recv + public :: shr_mpi_bcast + public :: shr_mpi_gathScatVInit + public :: shr_mpi_gatherV + public :: shr_mpi_scatterV + public :: shr_mpi_sum + public :: shr_mpi_min + public :: shr_mpi_max + public :: shr_mpi_commsize + public :: shr_mpi_commrank + public :: shr_mpi_initialized + public :: shr_mpi_abort + public :: shr_mpi_barrier + public :: shr_mpi_init + public :: shr_mpi_finalize + + interface shr_mpi_send ; module procedure & + shr_mpi_sendi0, & + shr_mpi_sendi1, & + shr_mpi_sendr0, & + shr_mpi_sendr1, & + shr_mpi_sendr3 + end interface shr_mpi_send + interface shr_mpi_recv ; module procedure & + shr_mpi_recvi0, & + shr_mpi_recvi1, & + shr_mpi_recvr0, & + shr_mpi_recvr1, & + shr_mpi_recvr3 + end interface shr_mpi_recv + interface shr_mpi_bcast ; module procedure & + shr_mpi_bcastc0, & + shr_mpi_bcastc1, & + shr_mpi_bcastl0, & + shr_mpi_bcastl1, & + shr_mpi_bcasti0, & + shr_mpi_bcasti1, & + shr_mpi_bcasti80, & + shr_mpi_bcasti81, & + shr_mpi_bcasti2, & + shr_mpi_bcastr0, & + shr_mpi_bcastr1, & + shr_mpi_bcastr2, & + shr_mpi_bcastr3 + end interface shr_mpi_bcast + interface shr_mpi_gathScatVInit ; module procedure & + shr_mpi_gathScatVInitr1 + end interface shr_mpi_gathScatVInit + interface shr_mpi_gatherv ; module procedure & + shr_mpi_gatherVr1 + end interface shr_mpi_gatherv + interface shr_mpi_scatterv ; module procedure & + shr_mpi_scatterVr1 + end interface shr_mpi_scatterv + interface shr_mpi_sum ; module procedure & + shr_mpi_sumi0, & + shr_mpi_sumi1, & + shr_mpi_sumb0, & + shr_mpi_sumb1, & + shr_mpi_sumr0, & + shr_mpi_sumr1, & + shr_mpi_sumr2, & + shr_mpi_sumr3 + end interface shr_mpi_sum + interface shr_mpi_min ; module procedure & + shr_mpi_mini0, & + shr_mpi_mini1, & + shr_mpi_minr0, & + shr_mpi_minr1 + end interface shr_mpi_min + interface shr_mpi_max ; module procedure & + shr_mpi_maxi0, & + shr_mpi_maxi1, & + shr_mpi_maxr0, & + shr_mpi_maxr1 + end interface shr_mpi_max + +#include ! mpi library include file + + !=============================================================================== +CONTAINS + !=============================================================================== + + SUBROUTINE shr_mpi_chkerr(rcode,string) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_IN), intent(in) :: rcode ! input MPI error code + character(*), intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_chkerr) ' + character(MPI_MAX_ERROR_STRING) :: lstring + integer(SHR_KIND_IN) :: len + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: layer on MPI error checking + !------------------------------------------------------------------------------- + + if (rcode /= MPI_SUCCESS) then + call MPI_ERROR_STRING(rcode,lstring,len,ierr) + write(6,*) trim(subName),":",lstring(1:len) + call shr_mpi_abort(string,rcode) + endif + + END SUBROUTINE shr_mpi_chkerr + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_sendi0(lvec,pid,tag,comm,string) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_IN), intent(in) :: lvec ! send value + integer(SHR_KIND_IN), intent(in) :: pid ! pid to send to + integer(SHR_KIND_IN), intent(in) :: tag ! tag + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_sendi0) ' + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Send a single integer + !------------------------------------------------------------------------------- + + lsize = 1 + + call MPI_SEND(lvec,lsize,MPI_INTEGER,pid,tag,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_sendi0 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_sendi1(lvec,pid,tag,comm,string) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_IN), intent(in) :: lvec(:) ! in/out local values + integer(SHR_KIND_IN), intent(in) :: pid ! pid to send to + integer(SHR_KIND_IN), intent(in) :: tag ! tag + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_sendi1) ' + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Send a vector of integers + !------------------------------------------------------------------------------- + + lsize = size(lvec) + + call MPI_SEND(lvec,lsize,MPI_INTEGER,pid,tag,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_sendi1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_sendr0(lvec,pid,tag,comm,string) + + IMPLICIT none + + !----- arguments --- + real(SHR_KIND_R8), intent(in) :: lvec ! in/out local values + integer(SHR_KIND_IN), intent(in) :: pid ! pid to send to + integer(SHR_KIND_IN), intent(in) :: tag ! tag + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_sendr0) ' + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Send a real scalar + !------------------------------------------------------------------------------- + + lsize = 1 + + call MPI_SEND(lvec,lsize,MPI_REAL8,pid,tag,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_sendr0 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_sendr1(lvec,pid,tag,comm,string) + + IMPLICIT none + + !----- arguments --- + real(SHR_KIND_R8), intent(in) :: lvec(:) ! in/out local values + integer(SHR_KIND_IN), intent(in) :: pid ! pid to send to + integer(SHR_KIND_IN), intent(in) :: tag ! tag + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_sendr1) ' + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Send a vector of reals + !------------------------------------------------------------------------------- + + lsize = size(lvec) + + call MPI_SEND(lvec,lsize,MPI_REAL8,pid,tag,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_sendr1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_sendr3(array,pid,tag,comm,string) + + IMPLICIT none + + !----- arguments --- + real (SHR_KIND_R8), intent(in) :: array(:,:,:) ! in/out local values + integer(SHR_KIND_IN), intent(in) :: pid ! pid to send to + integer(SHR_KIND_IN), intent(in) :: tag ! tag + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_sendr3) ' + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Send a vector of reals + !------------------------------------------------------------------------------- + + lsize = size(array) + + call MPI_SEND(array,lsize,MPI_REAL8,pid,tag,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_sendr3 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_recvi0(lvec,pid,tag,comm,string) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_IN), intent(out):: lvec ! in/out local values + integer(SHR_KIND_IN), intent(in) :: pid ! pid to recv from + integer(SHR_KIND_IN), intent(in) :: tag ! tag + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_recvi0) ' + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: status(MPI_STATUS_SIZE) ! mpi status info + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Recv a vector of reals + !------------------------------------------------------------------------------- + + lsize = 1 + + call MPI_RECV(lvec,lsize,MPI_INTEGER,pid,tag,comm,status,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_recvi0 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_recvi1(lvec,pid,tag,comm,string) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_IN), intent(out):: lvec(:) ! in/out local values + integer(SHR_KIND_IN), intent(in) :: pid ! pid to recv from + integer(SHR_KIND_IN), intent(in) :: tag ! tag + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_recvi1) ' + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: status(MPI_STATUS_SIZE) ! mpi status info + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Recv a vector of reals + !------------------------------------------------------------------------------- + + lsize = size(lvec) + + call MPI_RECV(lvec,lsize,MPI_INTEGER,pid,tag,comm,status,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_recvi1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_recvr0(lvec,pid,tag,comm,string) + + IMPLICIT none + + !----- arguments --- + real(SHR_KIND_R8), intent(out):: lvec ! in/out local values + integer(SHR_KIND_IN), intent(in) :: pid ! pid to recv from + integer(SHR_KIND_IN), intent(in) :: tag ! tag + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_recvr0) ' + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: status(MPI_STATUS_SIZE) ! mpi status info + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Recv a vector of reals + !------------------------------------------------------------------------------- + + lsize = 1 + + call MPI_RECV(lvec,lsize,MPI_REAL8,pid,tag,comm,status,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_recvr0 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_recvr1(lvec,pid,tag,comm,string) + + IMPLICIT none + + !----- arguments --- + real(SHR_KIND_R8), intent(out):: lvec(:) ! in/out local values + integer(SHR_KIND_IN), intent(in) :: pid ! pid to recv from + integer(SHR_KIND_IN), intent(in) :: tag ! tag + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_recvr1) ' + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: status(MPI_STATUS_SIZE) ! mpi status info + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Recv a vector of reals + !------------------------------------------------------------------------------- + + lsize = size(lvec) + + call MPI_RECV(lvec,lsize,MPI_REAL8,pid,tag,comm,status,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_recvr1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_recvr3(array,pid,tag,comm,string) + + IMPLICIT none + + !----- arguments --- + real (SHR_KIND_R8), intent(out):: array(:,:,:) ! in/out local values + integer(SHR_KIND_IN), intent(in) :: pid ! pid to recv from + integer(SHR_KIND_IN), intent(in) :: tag ! tag + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_recvr3) ' + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: status(MPI_STATUS_SIZE) ! mpi status info + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Recv a vector of reals + !------------------------------------------------------------------------------- + + lsize = size(array) + + call MPI_RECV(array,lsize,MPI_REAL8,pid,tag,comm,status,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_recvr3 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_bcasti0(vec,comm,string,pebcast) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_IN), intent(inout):: vec ! vector of 1 + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_bcasti0) ' + integer(SHR_KIND_IN) :: ierr + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: lpebcast + + !------------------------------------------------------------------------------- + ! PURPOSE: Broadcast an integer + !------------------------------------------------------------------------------- + + lsize = 1 + lpebcast = 0 + if (present(pebcast)) lpebcast = pebcast + + call MPI_BCAST(vec,lsize,MPI_INTEGER,lpebcast,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_bcasti0 + + SUBROUTINE shr_mpi_bcasti80(vec,comm,string,pebcast) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_I8), intent(inout):: vec ! vector of 1 + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_bcasti0) ' + integer(SHR_KIND_IN) :: ierr + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: lpebcast + + !------------------------------------------------------------------------------- + ! PURPOSE: Broadcast an integer + !------------------------------------------------------------------------------- + + lsize = 1 + lpebcast = 0 + if (present(pebcast)) lpebcast = pebcast + + call MPI_BCAST(vec,lsize,MPI_INTEGER8,lpebcast,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_bcasti80 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_bcastl0(vec,comm,string,pebcast) + + IMPLICIT none + + !----- arguments --- + logical, intent(inout):: vec ! vector of 1 + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_bcastl0) ' + integer(SHR_KIND_IN) :: ierr + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: lpebcast + + !------------------------------------------------------------------------------- + ! PURPOSE: Broadcast a logical + !------------------------------------------------------------------------------- + + lsize = 1 + lpebcast = 0 + if (present(pebcast)) lpebcast = pebcast + + call MPI_BCAST(vec,lsize,MPI_LOGICAL,lpebcast,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_bcastl0 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_bcastc0(vec,comm,string,pebcast) + + IMPLICIT none + + !----- arguments --- + character(len=*), intent(inout) :: vec ! vector of 1 + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_bcastc0) ' + integer(SHR_KIND_IN) :: ierr + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: lpebcast + + !------------------------------------------------------------------------------- + ! PURPOSE: Broadcast a character string + !------------------------------------------------------------------------------- + + lsize = len(vec) + lpebcast = 0 + if (present(pebcast)) lpebcast = pebcast + + call MPI_BCAST(vec,lsize,MPI_CHARACTER,lpebcast,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_bcastc0 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_bcastc1(vec,comm,string,pebcast) + + IMPLICIT none + + !----- arguments --- + character(len=*), intent(inout) :: vec(:) ! 1D vector + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_bcastc1) ' + integer(SHR_KIND_IN) :: ierr + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: lpebcast + + !------------------------------------------------------------------------------- + ! PURPOSE: Broadcast a character string + !------------------------------------------------------------------------------- + + lsize = size(vec)*len(vec) + lpebcast = 0 + if (present(pebcast)) lpebcast = pebcast + + call MPI_BCAST(vec,lsize,MPI_CHARACTER,lpebcast,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_bcastc1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_bcastr0(vec,comm,string,pebcast) + + IMPLICIT none + + !----- arguments --- + real(SHR_KIND_R8), intent(inout):: vec ! vector of 1 + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_bcastr0) ' + integer(SHR_KIND_IN) :: ierr + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: lpebcast + + !------------------------------------------------------------------------------- + ! PURPOSE: Broadcast a real + !------------------------------------------------------------------------------- + + lsize = 1 + lpebcast = 0 + if (present(pebcast)) lpebcast = pebcast + + call MPI_BCAST(vec,lsize,MPI_REAL8,lpebcast,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_bcastr0 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_bcasti1(vec,comm,string,pebcast) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_IN), intent(inout):: vec(:) ! vector + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_bcasti1) ' + integer(SHR_KIND_IN) :: ierr + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: lpebcast + + !------------------------------------------------------------------------------- + ! PURPOSE: Broadcast a vector of integers + !------------------------------------------------------------------------------- + + lsize = size(vec) + lpebcast = 0 + if (present(pebcast)) lpebcast = pebcast + + call MPI_BCAST(vec,lsize,MPI_INTEGER,lpebcast,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_bcasti1 + + SUBROUTINE shr_mpi_bcasti81(vec,comm,string,pebcast) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_I8), intent(inout):: vec(:) ! vector + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_bcasti1) ' + integer(SHR_KIND_IN) :: ierr + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: lpebcast + + !------------------------------------------------------------------------------- + ! PURPOSE: Broadcast a vector of integers + !------------------------------------------------------------------------------- + + lsize = size(vec) + lpebcast = 0 + if (present(pebcast)) lpebcast = pebcast + + call MPI_BCAST(vec,lsize,MPI_INTEGER8,lpebcast,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_bcasti81 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_bcastl1(vec,comm,string,pebcast) + + IMPLICIT none + + !----- arguments --- + logical, intent(inout):: vec(:) ! vector of 1 + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_bcastl1) ' + integer(SHR_KIND_IN) :: ierr + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: lpebcast + + !------------------------------------------------------------------------------- + ! PURPOSE: Broadcast a logical + !------------------------------------------------------------------------------- + + lsize = size(vec) + lpebcast = 0 + if (present(pebcast)) lpebcast = pebcast + + call MPI_BCAST(vec,lsize,MPI_LOGICAL,lpebcast,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_bcastl1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_bcastr1(vec,comm,string,pebcast) + + IMPLICIT none + + !----- arguments --- + real(SHR_KIND_R8), intent(inout):: vec(:) ! vector + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_bcastr1) ' + integer(SHR_KIND_IN) :: ierr + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: lpebcast + + !------------------------------------------------------------------------------- + ! PURPOSE: Broadcast a vector of reals + !------------------------------------------------------------------------------- + + lsize = size(vec) + lpebcast = 0 + if (present(pebcast)) lpebcast = pebcast + + call MPI_BCAST(vec,lsize,MPI_REAL8,lpebcast,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_bcastr1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_bcastr2(arr,comm,string,pebcast) + + IMPLICIT none + + !----- arguments ----- + real(SHR_KIND_R8), intent(inout):: arr(:,:) ! array, 2d + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) + + !----- local ----- + integer(SHR_KIND_IN) :: ierr + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: lpebcast + + !----- formats ----- + character(*),parameter :: subName = '(shr_mpi_bcastr2) ' + + !------------------------------------------------------------------------------- + ! PURPOSE: Broadcast a 2d array of reals + !------------------------------------------------------------------------------- + + lsize = size(arr) + lpebcast = 0 + if (present(pebcast)) lpebcast = pebcast + + call MPI_BCAST(arr,lsize,MPI_REAL8,lpebcast,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_bcastr2 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_bcasti2(arr,comm,string,pebcast) + + IMPLICIT none + + !----- arguments ----- + integer, intent(inout):: arr(:,:) ! array, 2d + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) + + !----- local ----- + integer(SHR_KIND_IN) :: ierr + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: lpebcast + + !----- formats ----- + character(*),parameter :: subName = '(shr_mpi_bcasti2) ' + + !------------------------------------------------------------------------------- + ! PURPOSE: Broadcast a 2d array of integers + !------------------------------------------------------------------------------- + + lsize = size(arr) + lpebcast = 0 + if (present(pebcast)) lpebcast = pebcast + + call MPI_BCAST(arr,lsize,MPI_INTEGER,lpebcast,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_bcasti2 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_bcastr3(arr,comm,string,pebcast) + + IMPLICIT none + + !----- arguments ----- + real(SHR_KIND_R8), intent(inout):: arr(:,:,:) ! array, 3d + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) + + !----- local ----- + integer(SHR_KIND_IN) :: ierr + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: lpebcast + + !----- formats ----- + character(*),parameter :: subName = '(shr_mpi_bcastr3) ' + + !------------------------------------------------------------------------------- + ! PURPOSE: Broadcast a 3d array of reals + !------------------------------------------------------------------------------- + + lsize = size(arr) + lpebcast = 0 + if (present(pebcast)) lpebcast = pebcast + + call MPI_BCAST(arr,lsize,MPI_REAL8,lpebcast,comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_bcastr3 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_gathScatvInitr1(comm, rootid, locArr, glob1DArr, globSize, & + displs, string ) + + IMPLICIT none + + !----- arguments ----- + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + integer(SHR_KIND_IN), intent(in) :: rootid ! MPI task to gather/scatter on + real(SHR_KIND_R8), intent(in) :: locArr(:) ! Local array of distributed data + real(SHR_KIND_R8), pointer :: glob1DArr(:) ! Global 1D array of gathered data + integer(SHR_KIND_IN), pointer :: globSize(:) ! Size of each distributed piece + integer(SHR_KIND_IN), pointer :: displs(:) ! Displacements for receive + character(*),optional,intent(in) :: string ! message + + !----- local ----- + integer(SHR_KIND_IN) :: npes ! Number of MPI tasks + integer(SHR_KIND_IN) :: locSize ! Size of local distributed data + integer(SHR_KIND_IN), pointer :: sendSize(:) ! Size to send for initial gather + integer(SHR_KIND_IN) :: i ! Index + integer(SHR_KIND_IN) :: rank ! Rank of this MPI task + integer(SHR_KIND_IN) :: nSize ! Maximum size to send + integer(SHR_KIND_IN) :: ierr ! Error code + integer(SHR_KIND_IN) :: nSiz1D ! Size of 1D global array + integer(SHR_KIND_IN) :: maxSize ! Maximum size + + !----- formats ----- + character(*),parameter :: subName = '(shr_mpi_gathScatvInitr1) ' + + !------------------------------------------------------------------------------- + ! PURPOSE: Setup arrays for a gatherv/scatterv operation + !------------------------------------------------------------------------------- + + locSize = size(locarr) + call shr_mpi_commsize( comm, npes ) + call shr_mpi_commrank( comm, rank ) + allocate( globSize(npes) ) + ! + ! --- Gather the send global sizes from each MPI task ----------------------- + ! + allocate( sendSize(npes) ) + sendSize(:) = 1 + globSize(:) = 1 + call MPI_GATHER( locSize, 1, MPI_INTEGER, globSize, sendSize, & + MPI_INTEGER, rootid, comm, ierr ) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + deallocate( sendSize ) + ! + ! --- Prepare the displacement and allocate arrays ------------------------- + ! + allocate( displs(npes) ) + displs(1) = 0 + if ( rootid /= rank )then + maxSize = 1 + globSize = 1 + else + maxSize = maxval(globSize) + end if + nsiz1D = min(maxSize,globSize(1)) + do i = 2, npes + nSize = min(maxSize,globSize(i-1)) + displs(i) = displs(i-1) + nSize + nsiz1D = nsiz1D + min(maxSize,globSize(i)) + end do + allocate( glob1DArr(nsiz1D) ) + !----- Do some error checking for the root task arrays computed ---- + if ( rootid == rank )then + if ( nsiz1D /= sum(globSize) ) & + call shr_mpi_abort( subName//" : Error, size of global array not right" ) + if ( any(displs < 0) .or. any(displs >= nsiz1D) ) & + call shr_mpi_abort( subName//" : Error, displacement array not right" ) + if ( (displs(npes)+globSize(npes)) /= nsiz1D ) & + call shr_mpi_abort( subName//" : Error, displacement array values too big" ) + end if + + END SUBROUTINE shr_mpi_gathScatvInitr1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_gathervr1(locarr, locSize, glob1DArr, globSize, displs, rootid, & + comm, string ) + + IMPLICIT none + + !----- arguments ----- + real(SHR_KIND_R8), intent(in) :: locArr(:) ! Local array + real(SHR_KIND_R8), intent(inout):: glob1DArr(:) ! Global 1D array to receive in on + integer(SHR_KIND_IN), intent(in) :: locSize ! Number to send this PE + integer(SHR_KIND_IN), intent(in) :: globSize(:) ! Number to receive each PE + integer(SHR_KIND_IN), intent(in) :: displs(:) ! Displacements for receive + integer(SHR_KIND_IN), intent(in) :: rootid ! MPI task to gather on + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + + !----- local ----- + integer(SHR_KIND_IN) :: ierr ! Error code + + !----- formats ----- + character(*),parameter :: subName = '(shr_mpi_gathervr1) ' + + !------------------------------------------------------------------------------- + ! PURPOSE: Gather a 1D array of reals + !------------------------------------------------------------------------------- + + call MPI_GATHERV( locarr, locSize, MPI_REAL8, glob1Darr, globSize, displs, & + MPI_REAL8, rootid, comm, ierr ) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_gathervr1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_scattervr1(locarr, locSize, glob1Darr, globSize, displs, rootid, & + comm, string ) + + IMPLICIT none + + !----- arguments ----- + real(SHR_KIND_R8), intent(out) :: locarr(:) ! Local array + real(SHR_KIND_R8), intent(in) :: glob1Darr(:) ! Global 1D array to send from + integer(SHR_KIND_IN), intent(in) :: locSize ! Number to receive this PE + integer(SHR_KIND_IN), intent(in) :: globSize(:) ! Number to send to each PE + integer(SHR_KIND_IN), intent(in) :: displs(:) ! Displacements for send + integer(SHR_KIND_IN), intent(in) :: rootid ! MPI task to scatter on + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + + !----- local ----- + integer(SHR_KIND_IN) :: ierr ! Error code + + !----- formats ----- + character(*),parameter :: subName = '(shr_mpi_scattervr1) ' + + !------------------------------------------------------------------------------- + ! PURPOSE: Scatter a 1D array of reals + !------------------------------------------------------------------------------- + + + call MPI_SCATTERV( glob1Darr, globSize, displs, MPI_REAL8, locarr, locSize, & + MPI_REAL8, rootid, comm, ierr ) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_scattervr1 + + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_sumi0(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_IN), intent(in) :: lvec ! in/out local values + integer(SHR_KIND_IN), intent(out):: gvec ! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_sumi0) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds sum of a distributed vector of values, assume local sum + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_SUM + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = 1 + gsize = 1 + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_sumi0 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_sumi1(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_IN), intent(in) :: lvec(:) ! in/out local values + integer(SHR_KIND_IN), intent(out):: gvec(:) ! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_sumi1) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds sum of a distributed vector of values, assume local sum + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_SUM + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = size(lvec) + gsize = size(gvec) + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_sumi1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_sumb0(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_I8), intent(in) :: lvec ! in/out local values + integer(SHR_KIND_I8), intent(out):: gvec ! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_sumb0) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds sum of a distributed vector of values, assume local sum + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_SUM + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = 1 + gsize = 1 + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER8,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER8,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_sumb0 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_sumb1(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_I8), intent(in) :: lvec(:) ! in/out local values + integer(SHR_KIND_I8), intent(out):: gvec(:) ! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_sumb1) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds sum of a distributed vector of values, assume local sum + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_SUM + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = size(lvec) + gsize = size(gvec) + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER8,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER8,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_sumb1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_sumr0(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + real(SHR_KIND_R8), intent(in) :: lvec ! in/out local values + real(SHR_KIND_R8), intent(out):: gvec ! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_sumr0) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds sum of a distributed vector of values, assume local sum + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_SUM + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = 1 + gsize = 1 + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_sumr0 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_sumr1(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + real(SHR_KIND_R8), intent(in) :: lvec(:) ! in/out local values + real(SHR_KIND_R8), intent(out):: gvec(:) ! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_sumr1) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds sum of a distributed vector of values, assume local sum + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_SUM + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = size(lvec) + gsize = size(gvec) + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_sumr1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_sumr2(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + real(SHR_KIND_R8), intent(in) :: lvec(:,:)! in/out local values + real(SHR_KIND_R8), intent(out):: gvec(:,:)! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_sumr2) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds sum of a distributed vector of values, assume local sum + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_SUM + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = size(lvec) + gsize = size(gvec) + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_sumr2 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_sumr3(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + real(SHR_KIND_R8), intent(in) :: lvec(:,:,:) ! in/out local values + real(SHR_KIND_R8), intent(out):: gvec(:,:,:) ! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_sumr3) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds sum of a distributed vector of values, assume local sum + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_SUM + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = size(lvec) + gsize = size(gvec) + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_sumr3 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_mini0(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_IN), intent(in) :: lvec ! in/out local values + integer(SHR_KIND_IN), intent(out):: gvec ! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_mini0) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds min of a distributed vector of values, assume local min + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_MIN + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = 1 + gsize = 1 + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_mini0 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_mini1(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_IN), intent(in) :: lvec(:) ! in/out local values + integer(SHR_KIND_IN), intent(out):: gvec(:) ! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_mini1) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds min of a distributed vector of values, assume local min + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_MIN + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = size(lvec) + gsize = size(gvec) + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_mini1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_minr0(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + real(SHR_KIND_R8), intent(in) :: lvec ! in/out local values + real(SHR_KIND_R8), intent(out):: gvec ! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_minr0) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds min of a distributed vector of values, assume local min + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_MIN + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = 1 + gsize = 1 + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_minr0 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_minr1(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + real(SHR_KIND_R8), intent(in) :: lvec(:) ! in/out local values + real(SHR_KIND_R8), intent(out):: gvec(:) ! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_minr1) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds min of a distributed vector of values, assume local min + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_MIN + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = size(lvec) + gsize = size(gvec) + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_minr1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_maxi0(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_IN), intent(in) :: lvec ! in/out local values + integer(SHR_KIND_IN), intent(out):: gvec ! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_maxi0) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds max of a distributed vector of values, assume local max + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_MAX + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = 1 + gsize = 1 + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_maxi0 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_maxi1(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + integer(SHR_KIND_IN), intent(in) :: lvec(:) ! in/out local values + integer(SHR_KIND_IN), intent(out):: gvec(:) ! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_maxi1) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds max of a distributed vector of values, assume local max + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_MAX + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = size(lvec) + gsize = size(gvec) + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_maxi1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_maxr0(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + real(SHR_KIND_R8), intent(in) :: lvec ! in/out local values + real(SHR_KIND_R8), intent(out):: gvec ! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_maxr0) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds max of a distributed vector of values, assume local max + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_MAX + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = 1 + gsize = 1 + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_maxr0 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_maxr1(lvec,gvec,comm,string,all) + + IMPLICIT none + + !----- arguments --- + real(SHR_KIND_R8), intent(in) :: lvec(:) ! in/out local values + real(SHR_KIND_R8), intent(out):: gvec(:) ! in/out global values + integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator + character(*),optional,intent(in) :: string ! message + logical, optional,intent(in) :: all ! allreduce if true + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_maxr1) ' + logical :: lall + character(SHR_KIND_CL) :: lstring + integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type + integer(SHR_KIND_IN) :: lsize + integer(SHR_KIND_IN) :: gsize + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: Finds max of a distributed vector of values, assume local max + ! already computed + !------------------------------------------------------------------------------- + + reduce_type = MPI_MAX + if (present(all)) then + lall = all + else + lall = .false. + endif + if (present(string)) then + lstring = trim(subName)//":"//trim(string) + else + lstring = trim(subName) + endif + + lsize = size(lvec) + gsize = size(gvec) + + if (lsize /= gsize) then + call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) + endif + + if (lall) then + call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") + else + call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) + call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") + endif + + END SUBROUTINE shr_mpi_maxr1 + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_commsize(comm,size,string) + + IMPLICIT none + + !----- arguments --- + integer,intent(in) :: comm + integer,intent(out) :: size + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_commsize) ' + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: MPI commsize + !------------------------------------------------------------------------------- + + call MPI_COMM_SIZE(comm,size,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_commsize + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_commrank(comm,rank,string) + + IMPLICIT none + + !----- arguments --- + integer,intent(in) :: comm + integer,intent(out) :: rank + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_commrank) ' + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: MPI commrank + !------------------------------------------------------------------------------- + + call MPI_COMM_RANK(comm,rank,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_commrank + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_initialized(flag,string) + + IMPLICIT none + + !----- arguments --- + logical,intent(out) :: flag + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_initialized) ' + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: MPI initialized + !------------------------------------------------------------------------------- + + call MPI_INITIALIZED(flag,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_initialized + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_abort(string,rcode) + + IMPLICIT none + + !----- arguments --- + character(*),optional,intent(in) :: string ! message + integer,optional,intent(in) :: rcode ! optional code + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_abort) ' + integer(SHR_KIND_IN) :: ierr + integer :: rc ! return code + + !------------------------------------------------------------------------------- + ! PURPOSE: MPI abort + !------------------------------------------------------------------------------- + + if ( present(string) .and. present(rcode) ) then + write(6,*) trim(subName),":",trim(string),rcode + endif + if ( present(rcode) )then + rc = rcode + else + rc = 1001 + end if + call MPI_ABORT(MPI_COMM_WORLD,rc,ierr) + + END SUBROUTINE shr_mpi_abort + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_barrier(comm,string) + + IMPLICIT none + + !----- arguments --- + integer,intent(in) :: comm + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_barrier) ' + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: MPI barrier + !------------------------------------------------------------------------------- + + call MPI_BARRIER(comm,ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_barrier + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_init(string) + + IMPLICIT none + + !----- arguments --- + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_init) ' + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: MPI init + !------------------------------------------------------------------------------- + + call MPI_INIT(ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_init + + !=============================================================================== + !=============================================================================== + + SUBROUTINE shr_mpi_finalize(string) + + IMPLICIT none + + !----- arguments --- + character(*),optional,intent(in) :: string ! message + + !----- local --- + character(*),parameter :: subName = '(shr_mpi_finalize) ' + integer(SHR_KIND_IN) :: ierr + + !------------------------------------------------------------------------------- + ! PURPOSE: MPI finalize + !------------------------------------------------------------------------------- + + call MPI_BARRIER(MPI_COMM_WORLD,ierr) + call MPI_FINALIZE(ierr) + if (present(string)) then + call shr_mpi_chkerr(ierr,subName//trim(string)) + else + call shr_mpi_chkerr(ierr,subName) + endif + + END SUBROUTINE shr_mpi_finalize + + !=============================================================================== + !=============================================================================== + +END MODULE shr_mpi_mod diff --git a/tools/mksurfdata_esmf/src/shr_pio_mod.F90 b/tools/mksurfdata_esmf/src/shr_pio_mod.F90 new file mode 100644 index 0000000000..106cdfc0ea --- /dev/null +++ b/tools/mksurfdata_esmf/src/shr_pio_mod.F90 @@ -0,0 +1,748 @@ +module shr_pio_mod + + use pio + use shr_kind_mod, only : shr_kind_CS, shr_kind_cl, shr_kind_in + use shr_mpi_mod, only : shr_mpi_bcast, shr_mpi_chkerr + use shr_sys_mod, only : shr_sys_abort + + implicit none + private + +#include + + public :: shr_pio_init1 + public :: shr_pio_init2 + public :: shr_pio_getiosys + public :: shr_pio_getiotype + public :: shr_pio_getioroot + public :: shr_pio_finalize + public :: shr_pio_getioformat + public :: shr_pio_getrearranger + + type pio_comp_t + integer :: compid + integer :: pio_root + integer :: pio_stride + integer :: pio_numiotasks + integer :: pio_iotype + integer :: pio_rearranger + integer :: pio_netcdf_ioformat + end type pio_comp_t + + type(pio_comp_t), allocatable :: pio_comp_settings(:) + type (iosystem_desc_t), allocatable, target :: iosystems(:) + integer :: io_comm + logical :: pio_async_interface + integer :: pio_debug_level=0, pio_blocksize=0 + integer(kind=pio_offset_kind) :: pio_buffer_size_limit=-1 + integer :: pio_rearr_opt_comm_type, pio_rearr_opt_fcd + logical :: pio_rearr_opt_c2i_enable_hs, pio_rearr_opt_c2i_enable_isend + integer :: pio_rearr_opt_c2i_max_pend_req + logical :: pio_rearr_opt_i2c_enable_hs, pio_rearr_opt_i2c_enable_isend + integer :: pio_rearr_opt_i2c_max_pend_req + integer :: total_comps = 1 + integer :: shr_log_unit = 6 + +#define DEBUGI 1 + +#ifdef DEBUGI + integer :: drank +#endif + +!=============================================================== +contains +!=============================================================== + + subroutine shr_pio_init1(nlfilename, Global_Comm) + + ! Should be the first routine called after mpi_init. + ! It reads the pio default settings from file drv_in, namelist pio_default_inparm + ! It then returns the new compute comm in Global_Comm and sets module variable io_comm. + + character(len=*) , intent(in) :: nlfilename + integer , intent(inout) :: Global_Comm + + integer :: ncomps + integer :: i, pio_root, pio_stride, pio_numiotasks, pio_iotype, pio_rearranger, pio_netcdf_ioformat + integer :: mpigrp_world, mpigrp, ierr, mpicom + integer :: pelist(3,1) + integer, allocatable :: comp_comm(:) + type(iosystem_desc_t), allocatable :: iosystems(:) + character(*),parameter :: subName = '(shr_pio_init1) ' + !----------------------------------------------------------------------- + + ncomps = 1 + + call shr_pio_read_default_namelist(nlfilename, Global_Comm, pio_stride, pio_root, pio_numiotasks, & + pio_iotype, pio_async_interface, pio_rearranger) + + pio_netcdf_ioformat = PIO_64BIT_OFFSET + call MPI_comm_rank(Global_Comm, drank, ierr) + + io_comm = MPI_COMM_NULL + allocate(pio_comp_settings(ncomps)) + do i=1,ncomps + pio_comp_settings(i)%pio_root = pio_root + pio_comp_settings(i)%pio_stride = pio_stride + pio_comp_settings(i)%pio_numiotasks = pio_numiotasks + pio_comp_settings(i)%pio_iotype = pio_iotype + pio_comp_settings(i)%pio_rearranger = pio_rearranger + pio_comp_settings(i)%pio_netcdf_ioformat = pio_netcdf_ioformat + end do + + if(pio_debug_level>0) then + if(drank==0) then + write(shr_log_unit,*) 'Setting pio_debuglevel : ',pio_debug_level + end if + call pio_setdebuglevel(pio_debug_level) + endif + total_comps = ncomps + + end subroutine shr_pio_init1 + + !=============================================================== + subroutine shr_pio_init2(comp_comm, comp_comm_iam) + + ! If pio_async_interface is false each component namelist + ! pio_inparm is read from compname_modelio.nml Then a subset of + ! each components compute tasks are Identified as IO tasks using + ! the root, stride and count variables to select the tasks. + + integer , intent(in) :: comp_comm(:), comp_comm_iam(:) + + integer :: i + character(len=shr_kind_cl) :: nlfilename, cname + integer :: ret + character(*), parameter :: subName = '(shr_pio_init2) ' + + ! 0 is a valid value of pio_buffer_size_limit + if (pio_buffer_size_limit>=0) then + if(comp_comm_iam(1)==0) then + write(shr_log_unit,*) 'Setting pio_buffer_size_limit : ',pio_buffer_size_limit + end if + call pio_set_buffer_size_limit(pio_buffer_size_limit) + endif + if (pio_blocksize>0) then + if(comp_comm_iam(1)==0) then + write(shr_log_unit,*) 'Setting pio_blocksize : ',pio_blocksize + end if + call pio_set_blocksize(pio_blocksize) + endif + ! Correct the total_comps value which may be lower in nuopc + total_comps = 1 + allocate(iosystems(total_comps)) + + i = 1 + call shr_pio_read_component_namelist(nlfilename , comp_comm(i), pio_comp_settings(i)%pio_stride, & + pio_comp_settings(i)%pio_root, pio_comp_settings(i)%pio_numiotasks, & + pio_comp_settings(i)%pio_iotype, pio_comp_settings(i)%pio_rearranger, & + pio_comp_settings(i)%pio_netcdf_ioformat) + + call pio_init(comp_comm_iam(i), comp_comm(i), pio_comp_settings(i)%pio_numiotasks, 0, & + pio_comp_settings(i)%pio_stride, & + pio_comp_settings(i)%pio_rearranger, iosystems(i), & + base=pio_comp_settings(i)%pio_root) + + ret = pio_set_rearr_opts(iosystems(i), pio_rearr_opt_comm_type,& + pio_rearr_opt_fcd,& + pio_rearr_opt_c2i_enable_hs, pio_rearr_opt_c2i_enable_isend,& + pio_rearr_opt_c2i_max_pend_req,& + pio_rearr_opt_i2c_enable_hs, pio_rearr_opt_i2c_enable_isend,& + pio_rearr_opt_i2c_max_pend_req) + if(ret /= PIO_NOERR) then + write(shr_log_unit,*) "ERROR: Setting rearranger options failed" + end if + + i = 1 + write(shr_log_unit,*) ' : pio_numiotasks = ',pio_comp_settings(i)%pio_numiotasks + write(shr_log_unit,*) ' : pio_stride = ',pio_comp_settings(i)%pio_stride + write(shr_log_unit,*) ' : pio_rearranger = ',pio_comp_settings(i)%pio_rearranger + write(shr_log_unit,*) ' : pio_root = ',pio_comp_settings(i)%pio_root + write(shr_log_unit,*) ' : pio_iotype = ',pio_comp_settings(i)%pio_iotype + + end subroutine shr_pio_init2 + + !=============================================================================== + subroutine shr_pio_finalize( ) + integer :: ierr + call pio_finalize(iosystems(1), ierr) + end subroutine shr_pio_finalize + + !=============================================================================== + function shr_pio_getiotype() result(io_type) + integer :: io_type + io_type = pio_comp_settings(1)%pio_iotype + end function shr_pio_getiotype + + !=============================================================================== + function shr_pio_getrearranger() result(io_type) + integer :: io_type + io_type = pio_comp_settings(1)%pio_rearranger + end function shr_pio_getrearranger + + !=============================================================================== + function shr_pio_getioformat() result(io_format) + integer :: io_format + io_format = pio_comp_settings(1)%pio_netcdf_ioformat + end function shr_pio_getioformat + + !=============================================================================== + function shr_pio_getioroot() result(io_root) + integer :: io_root + io_root = pio_comp_settings(1)%pio_root + end function shr_pio_getioroot + + !=============================================================================== + function shr_pio_getiosys() result(iosystem) + type(iosystem_desc_t), pointer :: iosystem + iosystem => iosystems(1) + end function shr_pio_getiosys + + !=============================================================================== + subroutine shr_pio_read_default_namelist(nlfilename, Comm, pio_stride, pio_root, pio_numiotasks, & + pio_iotype, pio_async_interface, pio_rearranger) + + character(len=*), intent(in) :: nlfilename + integer, intent(in) :: Comm + logical, intent(out) :: pio_async_interface + integer, intent(out) :: pio_stride, pio_root, pio_numiotasks, pio_iotype, pio_rearranger + + character(len=shr_kind_cs) :: pio_typename + character(len=shr_kind_cs) :: pio_rearr_comm_type, pio_rearr_comm_fcd + integer :: pio_netcdf_ioformat + integer :: pio_rearr_comm_max_pend_req_comp2io + logical :: pio_rearr_comm_enable_hs_comp2io, pio_rearr_comm_enable_isend_comp2io + integer :: pio_rearr_comm_max_pend_req_io2comp + logical :: pio_rearr_comm_enable_hs_io2comp, pio_rearr_comm_enable_isend_io2comp + character(*),parameter :: subName = '(shr_pio_read_default_namelist) ' + + integer :: iam, ierr, npes, unitn + logical :: iamroot + namelist /pio_default_inparm/ & + pio_async_interface, pio_debug_level, pio_blocksize, & + pio_buffer_size_limit, pio_root, pio_numiotasks, pio_stride, & + pio_rearr_comm_type, pio_rearr_comm_fcd, & + pio_rearr_comm_max_pend_req_comp2io, pio_rearr_comm_enable_hs_comp2io, & + pio_rearr_comm_enable_isend_comp2io, & + pio_rearr_comm_max_pend_req_io2comp, pio_rearr_comm_enable_hs_io2comp, & + pio_rearr_comm_enable_isend_io2comp + + call mpi_comm_rank(Comm, iam , ierr) + call mpi_comm_size(Comm, npes, ierr) + + if(iam==0) then + iamroot=.true. + else + iamroot=.false. + end if + + !-------------------------------------------------------------------------- + ! read io nml parameters + !-------------------------------------------------------------------------- + + pio_stride = -99 ! set based on pio_numiotasks value when initialized < 0 + pio_numiotasks = -99 ! set based on pio_stride value when initialized < 0 + pio_root = -99 + pio_typename = 'nothing' + pio_blocksize= -99 ! io blocking size set internally in pio when < 0 + pio_buffer_size_limit = -99 ! io task memory buffer maximum set internally in pio when < 0 + pio_debug_level = 0 ! no debug info by default + pio_async_interface = .false. ! pio tasks are a subset of component tasks + pio_rearranger = PIO_REARR_SUBSET + pio_netcdf_ioformat = PIO_64BIT_OFFSET + pio_rearr_comm_type = 'p2p' + pio_rearr_comm_fcd = '2denable' + pio_rearr_comm_max_pend_req_comp2io = 0 + pio_rearr_comm_enable_hs_comp2io = .true. + pio_rearr_comm_enable_isend_comp2io = .false. + pio_rearr_comm_max_pend_req_io2comp = 0 + pio_rearr_comm_enable_hs_io2comp = .true. + pio_rearr_comm_enable_isend_io2comp = .false. + + if(iamroot) then + open( newunit = unitn, file=trim(nlfilename), status='old' , iostat=ierr) + if(ierr/=0) then + write(shr_log_unit,*) 'File ',trim(nlfilename),' not found, setting default values.' + else + ierr = 1 + do while( ierr /= 0 ) + read(unitn,nml=pio_default_inparm,iostat=ierr) + if (ierr < 0) then + call shr_sys_abort( subname//':: namelist read returns an'// & + ' end of file or end of record condition '//trim(nlfilename) ) + end if + end do + close(unitn) + call shr_pio_getiotypefromname(pio_typename, pio_iotype, pio_iotype_netcdf) + end if + end if + + call shr_pio_namelist_set(npes, Comm, pio_stride, pio_root, pio_numiotasks, pio_iotype, & + iamroot, pio_rearranger, pio_netcdf_ioformat) + + call shr_mpi_bcast(pio_debug_level, Comm) + call shr_mpi_bcast(pio_root, Comm) + call shr_mpi_bcast(pio_numiotasks, Comm) + call shr_mpi_bcast(pio_blocksize, Comm) + call shr_mpi_bcast(pio_buffer_size_limit, Comm) + call shr_mpi_bcast(pio_async_interface, Comm) + call shr_mpi_bcast(pio_rearranger, Comm) + call shr_mpi_bcast(pio_stride, Comm) + + if (npes == 1) then + pio_rearr_comm_max_pend_req_comp2io = 0 + pio_rearr_comm_max_pend_req_io2comp = 0 + endif + + call shr_pio_rearr_opts_set(Comm, pio_rearr_comm_type, pio_rearr_comm_fcd, & + pio_rearr_comm_max_pend_req_comp2io, pio_rearr_comm_enable_hs_comp2io, & + pio_rearr_comm_enable_isend_comp2io, & + pio_rearr_comm_max_pend_req_io2comp, pio_rearr_comm_enable_hs_io2comp, & + pio_rearr_comm_enable_isend_io2comp, pio_numiotasks) + + end subroutine shr_pio_read_default_namelist + + !=============================================================== + subroutine shr_pio_read_component_namelist(nlfilename, Comm, pio_stride, pio_root, & + pio_numiotasks, pio_iotype, pio_rearranger, pio_netcdf_ioformat) + + character(len=*) , intent(in) :: nlfilename + integer , intent(in) :: Comm + integer , intent(inout) :: pio_stride, pio_root, pio_numiotasks + integer , intent(inout) :: pio_iotype, pio_rearranger, pio_netcdf_ioformat + + character(len=SHR_KIND_CS) :: pio_typename + character(len=SHR_KIND_CS) :: pio_netcdf_format + integer :: unitn + integer :: iam, ierr, npes + logical :: iamroot + integer :: pio_default_stride, pio_default_root, pio_default_numiotasks, pio_default_iotype + integer :: pio_default_rearranger, pio_default_netcdf_ioformat + character(*),parameter :: subName = '(shr_pio_read_component_namelist) ' + + namelist /pio_inparm/ pio_stride, pio_root, pio_numiotasks, & + pio_typename, pio_rearranger, pio_netcdf_format + + call mpi_comm_rank(Comm, iam , ierr) + call mpi_comm_size(Comm, npes, ierr) + + if(iam==0) then + iamroot=.true. + else + iamroot=.false. + end if + + pio_default_stride = pio_stride + pio_default_root = pio_root + pio_default_numiotasks = pio_numiotasks + pio_default_iotype = pio_iotype + pio_default_rearranger = pio_rearranger + pio_default_netcdf_ioformat = PIO_64BIT_DATA + + !-------------------------------------------------------------------------- + ! read io nml parameters + !-------------------------------------------------------------------------- + + pio_stride = -99 ! set based on pio_numiotasks value when initialized < 0 + pio_numiotasks = -99 ! set based on pio_stride value when initialized < 0 + pio_root = -99 + pio_typename = 'nothing' + pio_rearranger = -99 + pio_netcdf_format = '64bit_offset' + + if(iamroot) then + open( newunit=unitn, file=trim(nlfilename), status='old' , iostat=ierr) + if( ierr /= 0) then + write(shr_log_unit,*) 'No ',trim(nlfilename),' found, using defaults for pio settings' + pio_stride = pio_default_stride + pio_root = pio_default_root + pio_numiotasks = pio_default_numiotasks + pio_iotype = pio_default_iotype + pio_rearranger = pio_default_rearranger + pio_netcdf_ioformat = pio_default_netcdf_ioformat + else + ierr = 1 + do while( ierr /= 0 ) + read(unitn,nml=pio_inparm,iostat=ierr) + if (ierr < 0) then + call shr_sys_abort( subname//':: namelist read returns an'// & + ' end of file or end of record condition' ) + end if + end do + close(unitn) + call shr_pio_getiotypefromname(pio_typename, pio_iotype, pio_default_iotype) + call shr_pio_getioformatfromname(pio_netcdf_format, pio_netcdf_ioformat, pio_default_netcdf_ioformat) + end if + if(pio_stride== -99) then + if (pio_numiotasks > 0) then + pio_stride = npes/pio_numiotasks + else + pio_stride = pio_default_stride + endif + endif + if(pio_root == -99) pio_root = pio_default_root + if(pio_rearranger == -99) pio_rearranger = pio_default_rearranger + if(pio_numiotasks == -99) then + pio_numiotasks = npes/pio_stride + endif + endif + + call shr_pio_namelist_set(npes, Comm, pio_stride, pio_root, pio_numiotasks, pio_iotype, & + iamroot, pio_rearranger, pio_netcdf_ioformat) + + end subroutine shr_pio_read_component_namelist + + !=============================================================================== + subroutine shr_pio_getioformatfromname(pio_netcdf_format, pio_netcdf_ioformat, pio_default_netcdf_ioformat) + + character(len=*), intent(inout) :: pio_netcdf_format + integer, intent(out) :: pio_netcdf_ioformat + integer, intent(in) :: pio_default_netcdf_ioformat + + pio_netcdf_format = shr_pio_string_toupper(pio_netcdf_format) + if ( pio_netcdf_format .eq. 'CLASSIC' ) then + pio_netcdf_ioformat = 0 + elseif ( pio_netcdf_format .eq. '64BIT_OFFSET' ) then + pio_netcdf_ioformat = PIO_64BIT_OFFSET + elseif ( pio_netcdf_format .eq. '64BIT_DATA' ) then + pio_netcdf_ioformat = PIO_64BIT_DATA + else + pio_netcdf_ioformat = pio_default_netcdf_ioformat + endif + + end subroutine shr_pio_getioformatfromname + + !=============================================================================== + subroutine shr_pio_getiotypefromname(typename, iotype, defaulttype) + + character(len=*), intent(inout) :: typename + integer, intent(out) :: iotype + integer, intent(in) :: defaulttype + + typename = shr_pio_string_toupper(typename) + if ( typename .eq. 'NETCDF' ) then + iotype = pio_iotype_netcdf + else if ( typename .eq. 'PNETCDF') then + iotype = pio_iotype_pnetcdf + else if ( typename .eq. 'NETCDF4P') then + iotype = pio_iotype_netcdf4p + else if ( typename .eq. 'NETCDF4C') then + iotype = pio_iotype_netcdf4c + else if ( typename .eq. 'NOTHING') then + iotype = defaulttype + else if ( typename .eq. 'DEFAULT') then + iotype = defaulttype + else + write(shr_log_unit,*) 'shr_pio_mod: WARNING Bad io_type argument - using iotype_netcdf' + iotype=pio_iotype_netcdf + end if + + end subroutine shr_pio_getiotypefromname + + !=============================================================================== + subroutine shr_pio_namelist_set(npes,mycomm, pio_stride, pio_root, pio_numiotasks, & + pio_iotype, iamroot, pio_rearranger, pio_netcdf_ioformat) + + integer, intent(in) :: npes, mycomm + integer, intent(inout) :: pio_stride, pio_root, pio_numiotasks + integer, intent(inout) :: pio_iotype, pio_rearranger, pio_netcdf_ioformat + logical, intent(in) :: iamroot + character(*),parameter :: subName = '(shr_pio_namelist_set) ' + + integer :: ierr + + call mpi_bcast(pio_iotype , 1, MPI_INT, 0, myComm, ierr) + call mpi_bcast(pio_stride , 1, MPI_INT, 0, myComm, ierr) + call mpi_bcast(pio_root , 1, MPI_INT, 0, myComm, ierr) + call mpi_bcast(pio_numiotasks , 1, MPI_INT, 0, myComm, ierr) + call mpi_bcast(pio_rearranger , 1, MPI_INT, 0, myComm, ierr) + call mpi_bcast(pio_netcdf_ioformat , 1, MPI_INT, 0, myComm, ierr) + + if (pio_root<0) then + pio_root = 1 + endif + if(.not. pio_async_interface) then + pio_root = min(pio_root,npes-1) + ! If you are asking for parallel IO then you should use at least two io pes + if(npes > 1 .and. pio_numiotasks == 1 .and. & + (pio_iotype .eq. PIO_IOTYPE_PNETCDF .or. & + pio_iotype .eq. PIO_IOTYPE_NETCDF4P)) then + pio_numiotasks = 2 + pio_stride = min(pio_stride, npes/2) + endif + endif + + !-------------------------------------------------------------------------- + ! check/set/correct io pio parameters + !-------------------------------------------------------------------------- + if (pio_stride>0.and.pio_numiotasks<0) then + pio_numiotasks = max(1,npes/pio_stride) + else if(pio_numiotasks>0 .and. pio_stride<0) then + pio_stride = max(1,npes/pio_numiotasks) + else if(pio_numiotasks<0 .and. pio_stride<0) then + pio_stride = max(1,npes/4) + pio_numiotasks = max(1,npes/pio_stride) + end if + if(pio_stride == 1 .and. .not. pio_async_interface) then + pio_root = 0 + endif + if(pio_rearranger .ne. PIO_REARR_SUBSET .and. pio_rearranger .ne. PIO_REARR_BOX) then + write(shr_log_unit,*) 'pio_rearranger value, ',pio_rearranger,& + ', not supported - using PIO_REARR_BOX' + pio_rearranger = PIO_REARR_BOX + + endif + + + if (.not. pio_async_interface .and. & + pio_root + (pio_stride)*(pio_numiotasks-1) >= npes .or. & + pio_stride<=0 .or. pio_numiotasks<=0 .or. pio_root < 0 .or. & + pio_root > npes-1 ) then + if(npes<100) then + pio_stride = max(1,npes/4) + else if(npes<1000) then + pio_stride = max(1,npes/8) + else + pio_stride = max(1,npes/16) + end if + if(pio_stride>1) then + pio_numiotasks = npes/pio_stride + pio_root = min(1,npes-1) + else + pio_numiotasks = npes + pio_root = 0 + end if + if( iamroot) then + write(shr_log_unit,*) 'pio_stride, iotasks or root out of bounds - resetting to defaults: ',& + pio_stride,pio_numiotasks, pio_root + end if + end if + + end subroutine shr_pio_namelist_set + + !=============================================================================== + subroutine shr_pio_rearr_opts_set(comm, pio_rearr_comm_type, pio_rearr_comm_fcd, & + pio_rearr_comm_max_pend_req_comp2io, pio_rearr_comm_enable_hs_comp2io, & + pio_rearr_comm_enable_isend_comp2io, & + pio_rearr_comm_max_pend_req_io2comp, pio_rearr_comm_enable_hs_io2comp, & + pio_rearr_comm_enable_isend_io2comp, & + pio_numiotasks) + + ! This subroutine sets the global PIO rearranger options + ! The input args that represent the rearranger options are valid only + ! on the root proc of comm + ! The rearranger options are passed to PIO_Init() in shr_pio_init2() + + integer(SHR_KIND_IN), intent(in) :: comm + character(len=shr_kind_cs), intent(in) :: pio_rearr_comm_type, pio_rearr_comm_fcd + integer, intent(in) :: pio_rearr_comm_max_pend_req_comp2io + logical, intent(in) :: pio_rearr_comm_enable_hs_comp2io + logical, intent(in) :: pio_rearr_comm_enable_isend_comp2io + integer, intent(in) :: pio_rearr_comm_max_pend_req_io2comp + logical, intent(in) :: pio_rearr_comm_enable_hs_io2comp + logical, intent(in) :: pio_rearr_comm_enable_isend_io2comp + integer, intent(in) :: pio_numiotasks + + character(*), parameter :: subname = '(shr_pio_rearr_opts_set) ' + integer, parameter :: NUM_REARR_COMM_OPTS = 8 + integer, parameter :: PIO_REARR_COMM_DEF_MAX_PEND_REQ = 64 + ! Automatically reset if the number of maximum pending requests is set to 0 + integer, parameter :: REARR_COMM_DEF_MAX_PEND_REQ_RESET = 0 + integer(SHR_KIND_IN), dimension(NUM_REARR_COMM_OPTS) :: buf + integer :: rank, ierr + + call mpi_comm_rank(comm, rank, ierr) + call shr_mpi_chkerr(ierr,subname//' mpi_comm_rank comm_world') + + buf = 0 + ! buf(1) = comm_type + ! buf(2) = comm_fcd + ! buf(3) = max_pend_req_comp2io + ! buf(4) = enable_hs_comp2io + ! buf(5) = enable_isend_comp2io + ! buf(6) = max_pend_req_io2comp + ! buf(7) = enable_hs_io2comp + ! buf(8) = enable_isend_io2comp + if(rank == 0) then + ! buf(1) = comm_type + select case(pio_rearr_comm_type) + case ("p2p") + case ("default") + buf(1) = pio_rearr_comm_p2p + case ("coll") + buf(1) = pio_rearr_comm_coll + case default + write(shr_log_unit,*) "Invalid PIO rearranger comm type, ", pio_rearr_comm_type + write(shr_log_unit,*) "Resetting PIO rearrange comm type to p2p" + buf(1) = pio_rearr_comm_p2p + end select + + ! buf(2) = comm_fcd + select case(pio_rearr_comm_fcd) + case ("2denable") + case ("default") + buf(2) = pio_rearr_comm_fc_2d_enable + case ("io2comp") + buf(2) = pio_rearr_comm_fc_1d_io2comp + case ("comp2io") + buf(2) = pio_rearr_comm_fc_1d_comp2io + case ("disable") + buf(2) = pio_rearr_comm_fc_2d_disable + case default + write(shr_log_unit,*) "Invalid PIO rearranger comm flow control direction, ", pio_rearr_comm_fcd + write(shr_log_unit,*) "Resetting PIO rearrange comm flow control direction to 2denable" + buf(2) = pio_rearr_comm_fc_2d_enable + end select + + ! buf(3) = max_pend_req_comp2io + if((pio_rearr_comm_max_pend_req_comp2io <= 0) .and. & + (pio_rearr_comm_max_pend_req_comp2io /= PIO_REARR_COMM_UNLIMITED_PEND_REQ)) then + + if(pio_rearr_comm_max_pend_req_comp2io /= REARR_COMM_DEF_MAX_PEND_REQ_RESET) then + write(shr_log_unit, *) "Invalid PIO rearranger comm max pend req (comp2io), ",& + pio_rearr_comm_max_pend_req_comp2io + else + write(shr_log_unit, *) "User-specified PIO rearranger comm max pend req (comp2io), ",& + pio_rearr_comm_max_pend_req_comp2io, " (value will be reset as requested) " + end if + + ! Small multiple of pio_numiotasks has proven to perform + ! well empirically, and we do not want to allow maximum for + ! very large process count runs. Can improve this by + ! communicating between iotasks first, and then non-iotasks + ! to iotasks (TO DO) + write(shr_log_unit, *) "Resetting PIO rearranger comm max pend req (comp2io) to ", & + max(PIO_REARR_COMM_DEF_MAX_PEND_REQ, 2 * pio_numiotasks) + buf(3) = max(PIO_REARR_COMM_DEF_MAX_PEND_REQ, 2 * pio_numiotasks) + else + buf(3) = pio_rearr_comm_max_pend_req_comp2io + end if + + ! buf(4) = enable_hs_comp2io + if(pio_rearr_comm_enable_hs_comp2io) then + buf(4) = 1 + else + buf(4) = 0 + end if + + ! buf(5) = enable_isend_comp2io + if(pio_rearr_comm_enable_isend_comp2io) then + buf(5) = 1 + else + buf(5) = 0 + end if + + ! buf(6) = max_pend_req_io2comp + if((pio_rearr_comm_max_pend_req_io2comp <= 0) .and. & + (pio_rearr_comm_max_pend_req_io2comp /= PIO_REARR_COMM_UNLIMITED_PEND_REQ)) then + + if(pio_rearr_comm_max_pend_req_io2comp /= REARR_COMM_DEF_MAX_PEND_REQ_RESET) then + write(shr_log_unit, *) "Invalid PIO rearranger comm max pend req (io2comp), ",& + pio_rearr_comm_max_pend_req_io2comp + else + write(shr_log_unit, *) "User-specified PIO rearranger comm max pend req (io2comp), ",& + pio_rearr_comm_max_pend_req_io2comp, " (value will be reset as requested) " + end if + + write(shr_log_unit, *) "Resetting PIO rearranger comm max pend req (io2comp) to ", PIO_REARR_COMM_DEF_MAX_PEND_REQ + buf(6) = PIO_REARR_COMM_DEF_MAX_PEND_REQ + else + buf(6) = pio_rearr_comm_max_pend_req_io2comp + end if + + ! buf(7) = enable_hs_io2comp + if(pio_rearr_comm_enable_hs_io2comp) then + buf(7) = 1 + else + buf(7) = 0 + end if + + ! buf(8) = enable_isend_io2comp + if(pio_rearr_comm_enable_isend_io2comp) then + buf(8) = 1 + else + buf(8) = 0 + end if + + end if + + call shr_mpi_bcast(buf, comm) + + ! buf(1) = comm_type + ! buf(2) = comm_fcd + ! buf(3) = max_pend_req_comp2io + ! buf(4) = enable_hs_comp2io + ! buf(5) = enable_isend_comp2io + ! buf(6) = max_pend_req_io2comp + ! buf(7) = enable_hs_io2comp + ! buf(8) = enable_isend_io2comp + pio_rearr_opt_comm_type = buf(1) + pio_rearr_opt_fcd = buf(2) + pio_rearr_opt_c2i_max_pend_req = buf(3) + if(buf(4) == 0) then + pio_rearr_opt_c2i_enable_hs = .false. + else + pio_rearr_opt_c2i_enable_hs = .true. + end if + if(buf(5) == 0) then + pio_rearr_opt_c2i_enable_isend = .false. + else + pio_rearr_opt_c2i_enable_isend = .true. + end if + pio_rearr_opt_i2c_max_pend_req = buf(6) + if(buf(7) == 0) then + pio_rearr_opt_i2c_enable_hs = .false. + else + pio_rearr_opt_i2c_enable_hs = .true. + end if + if(buf(8) == 0) then + pio_rearr_opt_i2c_enable_isend = .false. + else + pio_rearr_opt_i2c_enable_isend = .true. + end if + + if(rank == 0) then + ! Log the rearranger options + write(shr_log_unit, *) "PIO rearranger options:" + write(shr_log_unit, *) " comm type = ", trim(pio_rearr_comm_type) + write(shr_log_unit, *) " comm fcd = ", trim(pio_rearr_comm_fcd) + if(pio_rearr_opt_c2i_max_pend_req == PIO_REARR_COMM_UNLIMITED_PEND_REQ) then + write(shr_log_unit, *) " max pend req (comp2io) = PIO_REARR_COMM_UNLIMITED_PEND_REQ (-1)" + else + write(shr_log_unit, *) " max pend req (comp2io) = ", pio_rearr_opt_c2i_max_pend_req + end if + write(shr_log_unit, *) " enable_hs (comp2io) = ", pio_rearr_opt_c2i_enable_hs + write(shr_log_unit, *) " enable_isend (comp2io) = ", pio_rearr_opt_c2i_enable_isend + if(pio_rearr_opt_i2c_max_pend_req == PIO_REARR_COMM_UNLIMITED_PEND_REQ) then + write(shr_log_unit, *) " max pend req (io2comp) = PIO_REARR_COMM_UNLIMITED_PEND_REQ (-1)" + else + write(shr_log_unit, *) " max pend req (io2comp) = ", pio_rearr_opt_i2c_max_pend_req + end if + write(shr_log_unit, *) " enable_hs (io2comp) = ", pio_rearr_opt_i2c_enable_hs + write(shr_log_unit, *) " enable_isend (io2comp) = ", pio_rearr_opt_i2c_enable_isend + end if + end subroutine shr_pio_rearr_opts_set + + !=============================================================================== + function shr_pio_string_toUpper(str) + + character(len=*), intent(in) :: str ! String to convert to upper case + character(len=len(str)) :: shr_pio_string_toUpper + + integer :: i ! Index + integer :: aseq ! ascii collating sequence + integer :: LowerToUpper ! integer to convert case + character(len=1) :: ctmp ! Character temporary + !------------------------------------------------------------------------------- + + LowerToUpper = iachar("A") - iachar("a") + do i = 1, len(str) + ctmp = str(i:i) + aseq = iachar(ctmp) + if ( aseq >= iachar("a") .and. aseq <= iachar("z") ) & + ctmp = achar(aseq + LowertoUpper) + shr_pio_string_toUpper(i:i) = ctmp + end do + end function shr_pio_string_toUpper + +end module shr_pio_mod diff --git a/tools/mksurfdata_esmf/src/shr_string_mod.F90 b/tools/mksurfdata_esmf/src/shr_string_mod.F90 new file mode 100644 index 0000000000..089eb21a19 --- /dev/null +++ b/tools/mksurfdata_esmf/src/shr_string_mod.F90 @@ -0,0 +1,142 @@ +module shr_string_mod + + implicit none + private + + public :: shr_string_countChar ! Count number of char in string, fn + public :: shr_string_endIndex ! Index of end of substr in str + public :: shr_string_betweenTags ! get the substring between the two tags + +!=============================================================================== +contains +!=============================================================================== + + integer function shr_string_countChar(str,char,rc) + + ! count number of occurances of a single character in a string + + ! !INPUT/OUTPUT PARAMETERS: + character(len=*) ,intent(in) :: str ! string to search + character(1) ,intent(in) :: char ! char to search for + integer,intent(out),optional :: rc ! return code + + !----- local ----- + integer :: count ! counts occurances of char + integer :: n ! generic index + integer :: t01 = 0 ! timer + + !----- formats ----- + character(*),parameter :: subName = "(shr_string_countChar) " + character(*),parameter :: F00 = "('(shr_string_countChar) ',4a)" + + !------------------------------------------------------------------------------- + ! Notes: + !------------------------------------------------------------------------------- + + count = 0 + do n = 1, len_trim(str) + if (str(n:n) == char) count = count + 1 + end do + shr_string_countChar = count + + if (present(rc)) rc = 0 + + end function shr_string_countChar + + !=============================================================================== + subroutine shr_string_betweenTags(string,startTag,endTag,substr,rc) + + ! Get the substring found between the start and end tags. + + ! !INPUT/OUTPUT PARAMETERS: + character(*) ,intent(in) :: string ! string to search + character(*) ,intent(in) :: startTag ! start tag + character(*) ,intent(in) :: endTag ! end tag + character(*) ,intent(out) :: substr ! sub-string between tags + integer,intent(out),optional :: rc ! retrun code + + !--- local --- + integer :: iStart ! substring start index + integer :: iEnd ! substring end index + integer :: rCode ! return code + integer :: t01 = 0 ! timer + character(*),parameter :: F00 = "('(shr_string_betweenTags) ',4a)" + + !------------------------------------------------------------------------------- + ! Notes: + ! * assumes the leading/trailing white space is not part of start & end tags + !------------------------------------------------------------------------------- + + iStart = shr_string_endIndex(string,trim(adjustL(startTag))) ! end of start tag + iEnd = index(string,trim(adjustL(endTag ))) ! start of end tag + + rCode = 0 + substr = "" + + if (iStart < 1) then + write(6,F00) "ERROR: can't find start tag in string" + write(6,F00) "ERROR: start tag = ",trim(startTag) + write(6,F00) "ERROR: string = ",trim(string) + rCode = 1 + else if (iEnd < 1) then + write(6,F00) "ERROR: can't find end tag in string" + write(6,F00) "ERROR: end tag = ",trim( endTag) + write(6,F00) "ERROR: string = ",trim(string) + rCode = 2 + else if ( iEnd <= iStart) then + write(6,F00) "ERROR: start tag not before end tag" + write(6,F00) "ERROR: start tag = ",trim(startTag) + write(6,F00) "ERROR: end tag = ",trim( endTag) + write(6,F00) "ERROR: string = ",trim(string) + rCode = 3 + else if ( iStart+1 == iEnd ) then + substr = "" + write(6,F00) "WARNING: zero-length substring found in ",trim(string) + else + substr = string(iStart+1:iEnd-1) + if (len_trim(substr) == 0 ) then + write(6,F00) "WARNING: white-space substring found in ",trim(string) + end if + end if + + if (present(rc)) rc = rCode + + end subroutine shr_string_betweenTags + + !=============================================================================== + integer function shr_string_endIndex(string,substr,rc) + + ! Get the ending index of substr within string + + ! !INPUT/OUTPUT PARAMETERS: + character(len=*) ,intent(in) :: string ! string to search + character(len=*) ,intent(in) :: substr ! sub-string to search for + integer ,intent(out),optional :: rc ! return code + + !--- local --- + integer :: i ! generic index + !------------------------------------------------------------------------------- + ! Notes: + ! * returns zero if substring not found, uses len_trim() intrinsic + ! * very similar to: i = index(str,substr,back=.true.) + ! * do we need this function? + !------------------------------------------------------------------------------- + + i = index(trim(string),trim(substr)) + if ( i == 0 ) then + shr_string_endIndex = 0 ! substr is not in string + else + shr_string_endIndex = i + len_trim(substr) - 1 + end if + + ! ------------------------------------------------------------------- + ! i = index(trim(string),trim(substr),back=.true.) + ! if (i == len(string)+1) i = 0 + ! shr_string_endIndex = i + ! ------------------------------------------------------------------- + + if (present(rc)) rc = 0 + + end function shr_string_endIndex + +end module shr_string_mod diff --git a/tools/mksurfdata_esmf/src/shr_sys_mod.F90 b/tools/mksurfdata_esmf/src/shr_sys_mod.F90 new file mode 100644 index 0000000000..8c51b711cc --- /dev/null +++ b/tools/mksurfdata_esmf/src/shr_sys_mod.F90 @@ -0,0 +1,352 @@ +!=============================================================================== + +MODULE shr_sys_mod + + use shr_kind_mod ! defines real & integer kinds + use shr_log_mod, only: s_loglev => shr_log_Level + use shr_log_mod, only: s_logunit => shr_log_Unit + + implicit none + +! PUBLIC: Public interfaces + + private + + public :: shr_sys_system ! make a system call + public :: shr_sys_chdir ! change current working dir + public :: shr_sys_getenv ! get an environment variable + public :: shr_sys_abort ! abort a program + public :: shr_sys_irtc ! returns real-time clock tick + public :: shr_sys_sleep ! have program sleep for a while + public :: shr_sys_flush ! flush an i/o buffer + +!=============================================================================== +CONTAINS +!=============================================================================== + +!=============================================================================== +!=============================================================================== + +SUBROUTINE shr_sys_system(str,rcode) + + IMPLICIT none + + !----- arguments --- + character(*) ,intent(in) :: str ! system/shell command string + integer(SHR_KIND_IN),intent(out) :: rcode ! function return error code + + !----- functions ----- +#if (defined CRAY) || (defined UNICOSMP) + integer(SHR_KIND_IN),external :: ishell ! function to envoke shell command +#endif +#if (defined OSF1 || defined SUNOS || (defined LINUX && !defined __GFORTRAN__ && !defined CATAMOUNT)) + integer(SHR_KIND_IN),external :: system ! function to envoke shell command +#endif + + !----- local ----- +#if (defined CATAMOUNT) + character(2*SHR_KIND_CL) :: file1 ! one or two filenames + character( SHR_KIND_CL) :: file2 ! 2nd file name + integer(SHR_KIND_IN) :: iloc ! index/location within a string +#endif + + !----- formats ----- + character(*),parameter :: subName = '(shr_sys_system) ' + character(*),parameter :: F00 = "('(shr_sys_system) ',4a)" + +!------------------------------------------------------------------------------- +! PURPOSE: an architecture independant system call +! NOTE: +! - for Catamount (Cray, pheonix at ORNL) there is no system call -- workarounds +! exist only for simple "rm" and "cp" commands +!------------------------------------------------------------------------------- + + +#if (defined CRAY) || (defined UNICOSMP) + + rcode=ishell(str) + +#elif (defined IRIX64 || defined NEC_SX) + + rcode = 0 + call system(str) + +#elif (defined AIX) + + call system(str,rcode) + +#elif (defined OSF1 || defined SUNOS || defined __GFORTRAN__ || (defined LINUX && !defined CATAMOUNT)) + + rcode = system(str) + +#elif (defined CATAMOUNT) + if (str(1:3) == 'rm ') then + call unlink(str(4:)) + if (s_loglev > 0) write(s_logunit,F00) 'CATAMOUNT unlink ',trim(str(4:)) + rcode = 0 + elseif (str(1:3) == 'mv ') then + file1 = str(4:) + iloc = index(file1,' ') + 3 + if (iloc < 6) then + if (s_loglev > 0) write(s_logunit,*) 'CATAMOUNT mv error ',trim(str),iloc + rcode = -1 + else + file1 = str(4:iloc) + file2 = str(iloc+1:) + call rename(trim(file1),trim(file2)) + if (s_loglev > 0) write(s_logunit,F00) 'CATAMOUNT rename ',trim(file1)," ",trim(file2) + rcode = 0 + endif + else + rcode = -1 + endif + +#else + + write(s_logunit,F00) 'ERROR: no implementation of system call for this architecture' + call shr_sys_abort(subName//'no implementation of system call for this architecture') + +#endif + +END SUBROUTINE shr_sys_system + +!=============================================================================== +!=============================================================================== + +SUBROUTINE shr_sys_chdir(path, rcode) + + IMPLICIT none + + !----- arguments ----- + character(*) ,intent(in) :: path ! chdir to this dir + integer(SHR_KIND_IN),intent(out) :: rcode ! return code + + !----- local ----- + integer(SHR_KIND_IN) :: lenpath ! length of path +#if (defined AIX || defined OSF1 || defined SUNOS || (defined LINUX && !defined __GFORTRAN__) || defined NEC_SX) + integer(SHR_KIND_IN),external :: chdir ! AIX system call +#endif + + !----- formats ----- + character(*),parameter :: subName = '(shr_sys_chdir) ' + character(*),parameter :: F00 = "('(shr_sys_chdir) ',4a)" + +!------------------------------------------------------------------------------- +! PURPOSE: an architecture independant system call +!------------------------------------------------------------------------------- + + lenpath=len_trim(path) + +#if (defined IRIX64 || defined CRAY || defined UNICOSMP) + + call pxfchdir(path, lenpath, rcode) + +#elif (defined AIX) + + rcode = chdir(%ref(path(1:lenpath)//'\0')) + +#elif (defined OSF1 || defined SUNOS || defined LINUX || defined NEC_SX) + + rcode=chdir(path(1:lenpath)) + +#else + + write(s_logunit,F00) 'ERROR: no implementation of chdir for this architecture' + call shr_sys_abort(subname//'no implementation of chdir for this machine') + +#endif + +END SUBROUTINE shr_sys_chdir + +!=============================================================================== +!=============================================================================== + +SUBROUTINE shr_sys_getenv(name, val, rcode) + + IMPLICIT none + + !----- arguments ----- + character(*) ,intent(in) :: name ! env var name + character(*) ,intent(out) :: val ! env var value + integer(SHR_KIND_IN),intent(out) :: rcode ! return code + + !----- local ----- + integer(SHR_KIND_IN) :: lenname ! length of env var name + integer(SHR_KIND_IN) :: lenval ! length of env var value + character(SHR_KIND_CL) :: tmpval ! temporary env var value + + !----- formats ----- + character(*),parameter :: subName = '(shr_sys_getenv) ' + character(*),parameter :: F00 = "('(shr_sys_getenv) ',4a)" + +!------------------------------------------------------------------------------- +! PURPOSE: an architecture independant system call +!------------------------------------------------------------------------------- + + lenname=len_trim(name) + +#if (defined IRIX64 || defined CRAY || defined UNICOSMP) + + call pxfgetenv(name, lenname, val, lenval, rcode) + +#elif (defined AIX || defined OSF1 || defined SUNOS || defined LINUX || defined NEC_SX) + + call getenv(trim(name),tmpval) + val=trim(tmpval) + rcode = 0 + if (len_trim(val) == 0 ) rcode = 1 + if (len_trim(val) > SHR_KIND_CL) rcode = 2 + +#else + + write(s_logunit,F00) 'ERROR: no implementation of getenv for this architecture' + call shr_sys_abort(subname//'no implementation of getenv for this machine') + +#endif + +END SUBROUTINE shr_sys_getenv + +!=============================================================================== +!=============================================================================== + +SUBROUTINE shr_sys_abort(string,rc) + + IMPLICIT none + + character(*) ,optional :: string ! error message string + integer(SHR_KIND_IN),optional :: rc ! error code + + !----- formats ----- + character(*),parameter :: subName = '(shr_sys_abort) ' + character(*),parameter :: F00 = "('(shr_sys_abort) ',4a)" + +!------------------------------------------------------------------------------- +! PURPOSE: consistent stopping mechanism +!------------------------------------------------------------------------------- + + call shr_sys_flush(s_logunit) + if (len_trim(string) > 0) write(s_logunit,F00) 'ERROR: '//trim(string) + write(s_logunit,F00) 'WARNING: stopping' + call shr_sys_flush(s_logunit) + call abort() + stop + +END SUBROUTINE shr_sys_abort + +!=============================================================================== +!=============================================================================== + +integer(SHR_KIND_I8) FUNCTION shr_sys_irtc( rate ) + + IMPLICIT none + + !----- arguments ----- + integer(SHR_KIND_I8), optional :: rate + + !----- local ----- + integer(SHR_KIND_IN) :: count + integer(SHR_KIND_IN) :: count_rate + integer(SHR_KIND_IN) :: count_max + integer(SHR_KIND_IN),save :: last_count = -1 + integer(SHR_KIND_I8),save :: count_offset = 0 + + !----- formats ----- + character(*),parameter :: subName = '(shr_sys_irtc) ' + character(*),parameter :: F00 = "('(shr_sys_irtc) ',4a)" + +!------------------------------------------------------------------------------- +! emulates Cray/SGI irtc function (returns clock tick since last reboot) +!------------------------------------------------------------------------------- + + call system_clock(count=count,count_rate=count_rate, count_max=count_max) + if ( present(rate) ) rate = count_rate + shr_sys_irtc = count + + !--- adjust for clock wrap-around --- + if ( last_count /= -1 ) then + if ( count < last_count ) count_offset = count_offset + count_max + end if + shr_sys_irtc = shr_sys_irtc + count_offset + last_count = count + +END FUNCTION shr_sys_irtc + +!=============================================================================== +!=============================================================================== + +SUBROUTINE shr_sys_sleep(sec) + + IMPLICIT none + + !----- arguments ----- + real (SHR_KIND_R8),intent(in) :: sec ! number of seconds to sleep + + !----- local ----- + integer(SHR_KIND_IN) :: isec ! integer number of seconds + integer(SHR_KIND_IN) :: rcode ! return code + character(90) :: str ! system call string + + !----- formats ----- + character(*),parameter :: subName = '(shr_sys_sleep) ' + character(*),parameter :: F00 = "('(shr_sys_sleep) ',4a)" + character(*),parameter :: F10 = "('sleep ',i8 )" + +!------------------------------------------------------------------------------- +! PURPOSE: Sleep for approximately sec seconds +!------------------------------------------------------------------------------- + + isec = nint(sec) + + if (isec < 0) then + if (s_loglev > 0) write(s_logunit,F00) 'ERROR: seconds must be > 0, sec=',sec + else if (isec == 0) then + ! Don't consider this an error and don't call system sleep + else +#if defined(CATAMOUNT) + call sleep(isec) +#else + write(str,FMT=F10) isec + call shr_sys_system( str, rcode ) +#endif + endif + +END SUBROUTINE shr_sys_sleep + +!=============================================================================== +!=============================================================================== + +SUBROUTINE shr_sys_flush(unit) + + IMPLICIT none + + !----- arguments ----- + integer(SHR_KIND_IN) :: unit ! flush output buffer for this unit + + !----- formats ----- + character(*),parameter :: subName = '(shr_sys_flush) ' + character(*),parameter :: F00 = "('(shr_sys_flush) ',4a)" + +!------------------------------------------------------------------------------- +! PURPOSE: an architecture independant system call +!------------------------------------------------------------------------------- + +#if (defined IRIX64 || defined CRAY || defined OSF1 || defined SUNOS || defined LINUX || defined NEC_SX || defined UNICOSMP) + + call flush(unit) + +#elif (defined AIX) + + call flush_(unit) + +#else + + if (s_loglev > 0) write(s_logunit,F00) 'WARNING: no implementation of flush for this architecture' + +#endif + +END SUBROUTINE shr_sys_flush + +!=============================================================================== +!=============================================================================== + +END MODULE shr_sys_mod From 6a9ac01188590f81e95911460ecbc2983bd5190c Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 20 Jan 2022 15:18:51 -0700 Subject: [PATCH 021/614] more cleanup --- .../gen_mksurfdata_namelist.py | 19 +- .../gen_mksurfdata_namelist.xml | 2 +- tools/mksurfdata_esmf/src/CMakeLists.txt | 9 +- tools/mksurfdata_esmf/src/Makefile | 6 +- tools/mksurfdata_esmf/src/log.out | Bin 14179 -> 0 bytes tools/mksurfdata_esmf/src/mkVICparamsMod.F90 | 3 - .../src/mkagfirepkmonthMod.F90 | 3 - tools/mksurfdata_esmf/src/mkchecksMod.F90 | 5 - tools/mksurfdata_esmf/src/mkesmfMod.F90 | 78 +- tools/mksurfdata_esmf/src/mkfileMod.F90 | 4 +- tools/mksurfdata_esmf/src/mkgdpMod.F90 | 3 - .../src/mkglacierregionMod.F90 | 3 - tools/mksurfdata_esmf/src/mkglcmecMod.F90 | 7 - tools/mksurfdata_esmf/src/mkharvestMod.F90 | 2 - tools/mksurfdata_esmf/src/mklaiMod.F90 | 721 +++-- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 308 +-- tools/mksurfdata_esmf/src/mkpeatMod.F90 | 216 +- tools/mksurfdata_esmf/src/mkpftMod.F90 | 2387 ++++++++--------- tools/mksurfdata_esmf/src/mkpioMod.F90 | 135 +- tools/mksurfdata_esmf/src/mksoilMod.F90 | 2344 ++++++++-------- tools/mksurfdata_esmf/src/mksoildepthMod.F90 | 3 - tools/mksurfdata_esmf/src/mksurfdata | Bin 2742328 -> 4027320 bytes tools/mksurfdata_esmf/src/mksurfdata.F90 | 277 +- tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 335 ++- .../src/mkurbanparCommonMod.F90 | 707 +++-- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 1383 +++++----- tools/mksurfdata_esmf/src/mkvarctl.F90 | 120 +- tools/mksurfdata_esmf/src/mkvocefMod.F90 | 387 ++- tools/mksurfdata_esmf/src/run_mksurfdata | 6 +- tools/mksurfdata_esmf/src/shr_mpi_mod.F90 | 2215 --------------- tools/mksurfdata_esmf/src/shr_pio_mod.F90 | 748 ------ tools/mksurfdata_esmf/src/shr_sys_mod.F90 | 368 +-- 32 files changed, 4723 insertions(+), 8081 deletions(-) delete mode 100644 tools/mksurfdata_esmf/src/log.out delete mode 100644 tools/mksurfdata_esmf/src/shr_mpi_mod.F90 delete mode 100644 tools/mksurfdata_esmf/src/shr_pio_mod.F90 diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index ab4218edd5..d30b41b2d9 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -318,7 +318,7 @@ def main (): fdyndat = f"landuse.timeseries_{res}_{ssp_rcp}_{num_pft}_CMIP6_{start_year}-{end_year}_c{time_stamp}.log" # TODO: make this an input argument - create_esmf_pet_files = .true. + create_esmf_pet_files = True with open(nlfname, "w",encoding='utf-8') as nlfile: @@ -326,11 +326,13 @@ def main (): for key,value in rawdata_files.items(): if key == 'mksrf_fgrid_nx' or key == 'mksrf_fgrid_ny': nlfile.write(f" {key} = {value} \n") - elif key != "mksrf_vic": + elif key != "mksrf_fvic" and key != "mksrf_fvic_mesh": nlfile.write(f" {key} = \'{value}\' \n") mksrf_hrvtyp = rawdata_files["mksrf_fvegtyp"] - nlfile.write( f" mksrf_hrvtyp = {mksrf_hrvtyp} \n") + nlfile.write( f" mksrf_fhrvtyp = \'{mksrf_hrvtyp}\' \n") + mksrf_hrvtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] + nlfile.write( f" mksrf_fhrvtyp_mesh = \'{mksrf_hrvtyp_mesh}\' \n") nlfile.write( " outnc_double = .true. \n") nlfile.write( " all_urban = .false. \n") @@ -340,16 +342,15 @@ def main (): nlfile.write(f" fsurdat = \'{fsurdat}\' \n") nlfile.write(f" fsurlog = \'{fsurlog}\' \n") - nlfile.write(f" start_year = {start_year}\n") - nlfile.write(f" end_year = {end_year}\n") + #nlfile.write(f" start_year = {start_year}\n") + #nlfile.write(f" end_year = {end_year}\n") nlfile.write(f" mksrf_fdynuse = \'{landuse_fname} \' \n") mksrf_vic = rawdata_files["mksrf_fvic"] - nlfile.write(f" use_vic = {vic_flag} \n") - nlfile.write(f" mksrf_fvic = f{mksrf_vic} \n") + nlfile.write(f" use_vic = .{vic_flag}. \n") nlfile.write( " outnc_vic = .true. \n") - nlfile.write(f" use_glc = f{glc_flag} \n") - nlfile.write(f" create_esmf_pet_files = f{create_esmf_pet_files} \n") + nlfile.write(f" use_glc = .{glc_flag}. \n") + nlfile.write(f" create_esmf_pet_files = .{create_esmf_pet_files}. \n") nlfile.write("/ \n") if __name__ == "__main__": diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 38cea3e86f..ae61df294e 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -223,7 +223,7 @@ version of the raw dataset will probably go away. lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - + lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_1850.c190119.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 938f868c28..de7574c0e3 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -30,9 +30,7 @@ set(SRCFILES mkvarctl.F90 shr_kind_mod.F90 shr_log_mod.F90 shr_string_mod.F90 - shr_sys_mod.F90 - shr_pio_mod.F90 - shr_mpi_mod.F90) + shr_sys_mod.F90) add_library(mksurfdata ${SRCFILES}) @@ -42,7 +40,10 @@ message("CMAKE_CURRENT_BINARY_DIR is ${CMAKE_CURRENT_BINARY_DIR}") message("PROJECT_BINARY_DIR is ${PROJECT_BINARY_DIR}") target_include_directories (mksurfdata PRIVATE ${ESMF_F90COMPILEPATHS}) -target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/include) +target_include_directories (mksurfdata PRIVATE /glade/work/jedwards/tools/pio/2.5.5/intel/19.1.1/mpt/2.22/include) +#target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/include) # non debug version +target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/pnetcdf/1.12.2/mpt/2.22/intel/19.1.1//include) +target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/netcdf-mpi/4.8.0/mpt/2.22/intel/19.1.1//include) #link_directories(/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/lib) #target_link_libraries(mksurfdata piof) diff --git a/tools/mksurfdata_esmf/src/Makefile b/tools/mksurfdata_esmf/src/Makefile index ddc4bf3c69..d978d88020 100644 --- a/tools/mksurfdata_esmf/src/Makefile +++ b/tools/mksurfdata_esmf/src/Makefile @@ -20,7 +20,9 @@ COMPILEPATH = -I/glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/bld -I/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/include -LINKPATH = -L/glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/bld -L/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/lib/ +#LINKPATH = -L/glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/bld -L/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/lib/ +LINKPATH = -L/glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/bld +PIO_LINKPATH = -L/glade/work/jedwards/tools/pio/2.5.5/intel/19.1.1/mpt/2.22/lib -L/glade/u/apps/ch/opt/pnetcdf/1.12.2/mpt/2.22/intel/19.1.1//lib -L/glade/u/apps/ch/opt/netcdf/4.7.3/intel/19.0.5/lib ESMFMKFILE=/glade/work/oehmke/ESMF/scalable_mesh_from_file/lib/libg/Linux.intel.64.mpt.default/esmf.mk include $(ESMFMKFILE) @@ -44,7 +46,7 @@ include $(ESMFMKFILE) # ----------------------------------------------------------------------------- mksurfdata: mksurfdata.o - $(ESMF_F90LINKER) $(ESMF_F90LINKOPTS) $(ESMF_F90LINKPATHS) $(ESMF_F90LINKRPATHS) -o $@ $^ $(ESMF_F90ESMFLINKLIBS) $(LINKPATH) -l mksurfdata -l piof + $(ESMF_F90LINKER) $(LINKPATH) $(PIO_LINKPATH) $(ESMF_F90LINKOPTS) $(ESMF_F90LINKPATHS) $(ESMF_F90LINKRPATHS) -o $@ $^ $(ESMF_F90ESMFLINKLIBS) -l mksurfdata -l piof -l pnetcdf -lnetcdf # ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------- diff --git a/tools/mksurfdata_esmf/src/log.out b/tools/mksurfdata_esmf/src/log.out deleted file mode 100644 index d60d4108cbcb7c627d9220e7f4b2af5667d02551..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14179 zcmeHOQE%EX5Z>$f75CUmEd-CY6sZqwDN?1;R;<+?Ba@iok=V?3)^)#r=Y)i?O|;w4 z2GaQff_?Gb`Mx_Ji4O)c5iplJlnRt~FwvQc55NlNqGpY9vpwCvoI58{ zL_7u|bZ4oglRS~%1VUdqqmxQ0X!_PbU5!h69u+o=rZDk=4fT(u5s}m8xnjBl%5RyO zUS6@6DgHa47Hhf&a$C0QFH5>DYq~quCrN#j-B5_$Ie#JRll9jnJ%kU!$2xq_e(Uk^ zs`Q=q2ESB`M*Hp7{>>zumLSD%!YSd@KMOX0^WcU&iaaW$OxlBh;wi;bil=2b+@hBY zv`3Xjp(wS@FTn_>gj33;atu%|MY$B^Qe`-#Tx!)D=$Z7&di=X%I+UT5E{Wf?N3Ec6 zn~swaP6?-!N#_{YY?PvR;(k#n|5%Cqlz-ID)h`Y-(+)&C&<^ZCS|`zzOV#pMww2CoW+pLr zJQOyaw5*BheNr{9Q~p>K9#nX_yR0r37bBfvX}}8E``YghIy2GAC^VLwtI2|@bq3vb z{{rAa&6Ivp6-9AT^)4>f&vn%9utBhyxjJ2Td2+I$xq|cVG3q!xzrG2>A5_eLvZG_H z6RIrK9GnL0RqX_)ea2obULwcQA!{<$v}J{sw*b57^aD0{*FU~G0tiD-7Fx%R3sXc+ zF52&z0Oh)5r>~Z4cy|w1qtWfC2gAGT@bY#z3_sqE-uD6P+GY^I6wA__FsW1=>(a1f i%}o)25b-4O1uFig0gn0ll)e4NTRzq%uUz@0$Bpk`nf7M@ diff --git a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 index 431e43cb28..9b43bd9274 100644 --- a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 @@ -15,7 +15,6 @@ module mkVICparamsMod ! ! !USES: use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush use mkdomainMod , only : domain_checksame implicit none @@ -87,7 +86,6 @@ subroutine mkVICparams(ldomain, mapfname, datfname, ndiag, & !----------------------------------------------------------------------- write (6,*) 'Attempting to make VIC parameters.....' - call shr_sys_flush(6) ! ----------------------------------------------------------------- ! Read domain and mapping information, check for consistency @@ -192,7 +190,6 @@ subroutine mkVICparams(ldomain, mapfname, datfname, ndiag, & write (6,*) 'Successfully made VIC parameters' write (6,*) - call shr_sys_flush(6) end subroutine mkVICparams diff --git a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 index 7b58ddffad..2086f5dc10 100644 --- a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 +++ b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 @@ -13,7 +13,6 @@ module mkagfirepkmonthMod !----------------------------------------------------------------------- !!USES: use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush use mkdomainMod , only : domain_checksame implicit none @@ -97,7 +96,6 @@ subroutine mkagfirepkmon(ldomain, mapfname, datfname, ndiag, & !----------------------------------------------------------------------- write (6,*) 'Attempting to make agricultural fire peak month data .....' - call shr_sys_flush(6) ! ----------------------------------------------------------------- ! Read domain and mapping information, check for consistency @@ -208,7 +206,6 @@ subroutine mkagfirepkmon(ldomain, mapfname, datfname, ndiag, & write (6,*) 'Successfully made Agricultural fire peak month' write (6,*) - call shr_sys_flush(6) end subroutine mkagfirepkmon diff --git a/tools/mksurfdata_esmf/src/mkchecksMod.F90 b/tools/mksurfdata_esmf/src/mkchecksMod.F90 index d78888c3bf..e385165564 100644 --- a/tools/mksurfdata_esmf/src/mkchecksMod.F90 +++ b/tools/mksurfdata_esmf/src/mkchecksMod.F90 @@ -5,7 +5,6 @@ module mkchecksMod !----------------------------------------------------------------------- use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush implicit none private @@ -54,7 +53,6 @@ logical function min_bad_r8(data, min_allowed, varname) end if end do - call shr_sys_flush(6) min_bad_r8 = errors_found end function min_bad_r8 @@ -87,7 +85,6 @@ logical function min_bad_int(data, min_allowed, varname) end if end do - call shr_sys_flush(6) min_bad_int = errors_found end function min_bad_int @@ -119,7 +116,6 @@ logical function max_bad_r8(data, max_allowed, varname) end if end do - call shr_sys_flush(6) max_bad_r8 = errors_found end function max_bad_r8 @@ -152,7 +148,6 @@ logical function max_bad_int(data, max_allowed, varname) end if end do - call shr_sys_flush(6) max_bad_int = errors_found end function max_bad_int diff --git a/tools/mksurfdata_esmf/src/mkesmfMod.F90 b/tools/mksurfdata_esmf/src/mkesmfMod.F90 index d11584f4e3..665cbf81c1 100644 --- a/tools/mksurfdata_esmf/src/mkesmfMod.F90 +++ b/tools/mksurfdata_esmf/src/mkesmfMod.F90 @@ -1,13 +1,6 @@ module mkesmfMod use ESMF - use pio , only : file_desc_t, iosystem_desc_t, io_desc_t, var_desc_t - use pio , only : pio_openfile, pio_closefile, pio_nowrite - use pio , only : pio_double, pio_real, pio_int, pio_offset_kind, pio_get_var - use pio , only : pio_read_darray, pio_setframe, pio_fill_double, pio_get_att - use pio , only : io_desc_t, var_desc_t - use pio , only : PIO_BCAST_ERROR, PIO_RETURN_ERROR, PIO_NOERR, PIO_INTERNAL_ERROR - use pio , only : PIO_REAL, PIO_INT, PIO_DOUBLE, PIO_SHORT use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 use shr_sys_mod , only : shr_sys_abort use mkUtilsMod , only : chkerr @@ -15,7 +8,7 @@ module mkesmfMod implicit none private - public :: regrid_data + public :: regrid_rawdata character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -24,69 +17,23 @@ module mkesmfMod contains !=============================================================== - subroutine regrid_data(field_i, field_o, varname, filename, data_i, data_o, rc) - - use mkvarctl , only : ndiag, root_task - use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_ioformat, io_subsystem + subroutine regrid_rawdata(field_i, field_o, routehandle, data_i, data_o, rc) ! input/output variables - type(ESMF_Field) , intent(inout) :: field_i ! raw data field - type(ESMF_Field) , intent(inout) :: field_o ! model field - character(len=*) , intent(in) :: varname ! field name in rawdata file - character(len=*) , intent(in) :: filename ! file name of rawdata file - real(r8) , intent(inout) :: data_i(:) ! input raw data - real(r8) , intent(inout) :: data_o(:) ! mapped data - integer , intent(out) :: rc + type(ESMF_Field) , intent(in) :: field_i + type(ESMF_Field) , intent(inout) :: field_o + type(ESMF_RouteHandle) , intent(inout) :: routehandle + real(r8) , intent(in) :: data_i(:) + real(r8) , intent(inout) :: data_o(:) + integer , intent(out) :: rc ! local variables - type(ESMF_Mesh) :: mesh_i - type(ESMF_RouteHandle) :: routehandle - integer :: srcMaskValue = 0 - integer :: dstMaskValue = -987987 ! spval for RH mask values - integer :: srcTermProcessing_Value = 0 - type(file_desc_t) :: pioid - type(var_desc_t) :: pio_varid - type(io_desc_t) :: pio_iodesc - integer :: pio_vartype - real(r4), allocatable :: data_real(:) - real(r8), allocatable :: data_double(:) - real(r8), pointer :: dataptr(:) - integer :: lsize - integer :: rcode - logical :: checkflag = .false. - character(len=*), parameter :: subname = 'mklakwat' - !------------------------------------------------- + logical :: checkflag = .false. + real(r8), pointer :: dataptr(:) + ! -------------------------------------------- rc = ESMF_SUCCESS - ! create route handle to map field_model to field_data - call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & - srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_DSTAREA, & - srcTermProcessing=srcTermProcessing_Value, & - ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Get data_i - Read in varname from filename - rcode = pio_openfile(io_subsystem, pioid, pio_iotype, trim(filename), pio_nowrite) - call ESMF_FieldGet(field_i, mesh=mesh_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (pio_vartype == PIO_REAL) then - allocate(data_real(lsize)) - call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real, rcode) - data_i(:) = real(data_real(:), kind=r8) - deallocate(data_real) - else if (pio_vartype == PIO_DOUBLE) then - allocate(data_double(lsize)) - call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double, rcode) - data_i(:) = data_double(:) - deallocate(data_double) - else - call shr_sys_abort(subName//"ERROR: only real and double types are supported") - end if - ! Interpolate data_i to data_o call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) dataptr(:) = data_i(:) @@ -97,7 +44,8 @@ subroutine regrid_data(field_i, field_o, varname, filename, data_i, data_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) data_o(:) = dataptr(:) + call ESMF_VMLogMemInfo("After field regrid in regrid_data") - end subroutine regrid_data + end subroutine regrid_rawdata end module mkesmfMod diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 77cf7e5400..fe68f560f6 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -71,7 +71,7 @@ subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) ! TODO: how to translate the following into the pio call !call check_ret(nf_create(trim(fname), ior(nf_clobber,nf_64bit_offset), ncid), subname) - call mkpio_wopen(pioid, trim(fname), vm, clobber=.true.) + call mkpio_wopen(pioid, trim(fname), clobber=.true.) ! TODO: what about setting no fill values? !--------------------------- @@ -112,11 +112,13 @@ subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) str = 'created on: ' // datetime rcode = pio_put_att (pioid, pio_global, 'History_Log', trim(str)) +#ifdef TODO call shr_sys_getenv ('LOGNAME', str, ier) rcode = pio_put_att (pioid, pio_global, 'Logname', trim(str)) call shr_sys_getenv ('HOST', str, ier) rcode = pio_put_att (pioid, pio_global, 'Host', trim(str)) +#endif str = 'Community Land Model: CLM5' rcode = pio_put_att (pioid, pio_global, 'Source', trim(str)) diff --git a/tools/mksurfdata_esmf/src/mkgdpMod.F90 b/tools/mksurfdata_esmf/src/mkgdpMod.F90 index 138ddf1805..1babb411bf 100644 --- a/tools/mksurfdata_esmf/src/mkgdpMod.F90 +++ b/tools/mksurfdata_esmf/src/mkgdpMod.F90 @@ -15,7 +15,6 @@ module mkgdpMod ! ! !USES: use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush use mkdomainMod , only : domain_checksame implicit none @@ -80,7 +79,6 @@ subroutine mkgdp(ldomain, mapfname, datfname, ndiag, gdp_o) !----------------------------------------------------------------------- write (6,*) 'Attempting to make GDP.....' - call shr_sys_flush(6) ! ----------------------------------------------------------------- ! Read domain and mapping information, check for consistency @@ -140,7 +138,6 @@ subroutine mkgdp(ldomain, mapfname, datfname, ndiag, gdp_o) write (6,*) 'Successfully made GDP' write (6,*) - call shr_sys_flush(6) end subroutine mkgdp diff --git a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 index e644129ed3..d2056c29ca 100644 --- a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 @@ -15,7 +15,6 @@ module mkglacierregionMod ! ! !USES: use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush implicit none private @@ -66,7 +65,6 @@ subroutine mkglacierregion(ldomain, mapfname, datfname, ndiag, & !----------------------------------------------------------------------- write (6,*) 'Attempting to make glacier region .....' - call shr_sys_flush(6) ! ------------------------------------------------------------------------ ! Read domain and mapping information, check for consistency @@ -132,7 +130,6 @@ subroutine mkglacierregion(ldomain, mapfname, datfname, ndiag, & write (6,*) 'Successfully made glacier region' write (6,*) - call shr_sys_flush(6) end subroutine mkglacierregion diff --git a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 index 9fbad66689..1f9164afe9 100644 --- a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 @@ -13,7 +13,6 @@ module mkglcmecMod !----------------------------------------------------------------------- !!USES: use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush use mkdomainMod , only : domain_checksame implicit none @@ -229,7 +228,6 @@ subroutine mkglcmec(ldomain, mapfname, & write (6,*) 'Attempting to make percent elevation class ',& 'and mean elevation for glaciers .....' - call shr_sys_flush(6) ! ----------------------------------------------------------------- ! Read domain and dimension information from glacier raw data file @@ -299,7 +297,6 @@ subroutine mkglcmec(ldomain, mapfname, & do lev = 1, nlev write(6,'(i4)',advance='no') lev - flush(6) ! Read this level's data ! We assume that the last dimension is the level dimension @@ -478,7 +475,6 @@ subroutine mkglcmec(ldomain, mapfname, & write (6,*) 'Successfully made percent elevation class and mean elevation for glaciers' write (6,*) - call shr_sys_flush(6) end subroutine mkglcmec @@ -548,7 +544,6 @@ subroutine mkglacier(ldomain, mapfname, datfname, ndiag, zero_out, glac_o) !----------------------------------------------------------------------- write (6,*) 'Attempting to make %glacier .....' - call shr_sys_flush(6) ! ----------------------------------------------------------------- ! Read input file @@ -605,7 +600,6 @@ subroutine mkglacier(ldomain, mapfname, datfname, ndiag, zero_out, glac_o) if ((glac_o(no)) > 100.000001_r8) then write (6,*) 'MKGLACIER error: glacier = ',glac_o(no), & ' greater than 100.000001 for column, row = ',no - call shr_sys_flush(6) call abort() end if enddo @@ -678,7 +672,6 @@ subroutine mkglacier(ldomain, mapfname, datfname, ndiag, zero_out, glac_o) write (6,*) 'Successfully made %glacier' write (6,*) - call shr_sys_flush(6) end subroutine mkglacier diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index 0dc107729b..9459a1bfc6 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -13,7 +13,6 @@ module mkharvestMod !----------------------------------------------------------------------- ! !USES: use shr_kind_mod , only : r8 => shr_kind_r8, CL => shr_kind_CL - use shr_sys_mod , only : shr_sys_flush use mkdomainMod , only : domain_checksame implicit none @@ -879,7 +878,6 @@ subroutine mkharvest(ldomain, mapfname, datfname, ndiag, harvdata) !----------------------------------------------------------------------- write (6,*) 'Attempting to make harvest fields .....' - call shr_sys_flush(6) ! ----------------------------------------------------------------- ! Normally read in the harvesting file, and then regrid to output grid diff --git a/tools/mksurfdata_esmf/src/mklaiMod.F90 b/tools/mksurfdata_esmf/src/mklaiMod.F90 index e4b6d9bfa1..6e544c66f7 100644 --- a/tools/mksurfdata_esmf/src/mklaiMod.F90 +++ b/tools/mksurfdata_esmf/src/mklaiMod.F90 @@ -13,7 +13,6 @@ module mklaiMod !EOP !----------------------------------------------------------------------- use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush use mkdomainMod , only : domain_checksame use mkvarctl @@ -32,367 +31,365 @@ module mklaiMod ! !IROUTINE: mklai ! ! !INTERFACE: -subroutine mklai(ldomain, mapfname, datfname, ndiag, ncido) -! -! !DESCRIPTION: -! Make LAI/SAI/height data -! Portions of this code could be moved out of the month loop -! for improved efficiency -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar , only : re - use mkvarctl - use mkncdio - use mkpftConstantsMod, only : c3cropindex, c3irrcropindex -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - integer , intent(in) :: ncido ! output netcdf file id -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - integer :: numpft_i ! number of plant types on input - real(r8) :: glai_o(0:numpft) ! output grid: global area pfts - real(r8) :: gsai_o(0:numpft) ! output grid: global area pfts - real(r8) :: ghgtt_o(0:numpft) ! output grid: global area pfts - real(r8) :: ghgtb_o(0:numpft) ! output grid: global area pfts - real(r8) :: glai_i(0:numpft) ! input grid: global area pfts - real(r8) :: gsai_i(0:numpft) ! input grid: global area pfts - real(r8) :: ghgtt_i(0:numpft) ! input grid: global area pfts - real(r8) :: ghgtb_i(0:numpft) ! input grid: global area pfts - - real(r8), allocatable :: mlai_o(:,:) ! monthly lai - real(r8), allocatable :: msai_o(:,:) ! monthly sai - real(r8), allocatable :: mhgtt_o(:,:) ! monthly height (top) - real(r8), allocatable :: mhgtb_o(:,:) ! monthly height (bottom) - real(r8), allocatable :: mlai_max(:,:) ! monthly lai - real(r8), allocatable :: msai_max(:,:) ! monthly sai - real(r8), allocatable :: mhgtt_max(:,:) ! monthly height (top) - real(r8), allocatable :: mhgtb_max(:,:) ! monthly height (bottom) - real(r8), allocatable :: mlai_i(:,:) ! monthly lai in - real(r8), allocatable :: msai_i(:,:) ! monthly sai in - real(r8), allocatable :: mhgtt_i(:,:) ! monthly height (top) in - real(r8), allocatable :: mhgtb_i(:,:) ! monthly height (bottom) in - real(r8), allocatable :: frac_dst(:) ! output fractions: same as frac_dst - integer, pointer :: laimask(:,:) ! lai+sai output mask for each plant function type - real(r8) :: garea_i ! input grid: global area - real(r8) :: garea_o ! output grid: global area - integer :: mwts ! number of weights - integer :: ni,no,ns_i,ns_o ! indices - integer :: k,l,n,m ! indices - integer :: ncidi,dimid,varid ! input netCDF id's - integer :: ndimsi,ndimso ! netCDF dimension sizes - integer :: dimids(4) ! netCDF dimension ids - integer :: bego(4),leno(4) ! netCDF bounds - integer :: begi(4),leni(4) ! netCDF bounds - integer :: ntim ! number of input time samples - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=256) :: name ! name of attribute - character(len=256) :: unit ! units of attribute - character(len= 32) :: subname = 'mklai' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make LAIs/SAIs/heights .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - ns_o = ldomain%ns - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - - write (6,*) 'Open LAI file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncidi), subname) - call check_ret(nf_inq_dimid(ncidi, 'pft', dimid), subname) - call check_ret(nf_inq_dimlen(ncidi, dimid, numpft_i), subname) - call check_ret(nf_inq_dimid(ncidi, 'time', dimid), subname) - call check_ret(nf_inq_dimlen(ncidi, dimid, ntim), subname) - - if (numpft_i /= numpft+1) then - write(6,*) 'WARNING: ' // trim(subname) // '(): parameter numpft+1 = ', numpft+1, & - 'does not equal input dataset numpft = ', numpft_i - write(6,*)'This inconsistency used to stop the program. Now we allow it ' - write(6,*)'because crop pfts 17-last are assumed to never use satellite lai data.' -! stop - if (numpft_i > numpft + 1) then - ! NOTE(bja, 2015-01) If this error check is determined to be - ! invalid, all the loop bounds over output data in this - ! routine will need to be double checked! - write(6, *) "ERROR:" // trim(subname) // "(): input numpft must be less than or equal to output numpft+1." - call abort() - end if - endif - if (ntim /= 12) then - write(6,*)'MKLAI: must have 12 time samples on input data' - call abort() - endif - - ! NOTE - close data set at bottom of routine - - ! Dynamic allocation of variables - - allocate(mlai_i(ns_i,0:numpft_i), & - msai_i(ns_i,0:numpft_i), & - mhgtt_i(ns_i,0:numpft_i), & - mhgtb_i(ns_i,0:numpft_i), & - frac_dst(ns_o), & - mlai_o(ns_o,0:numpft), & - msai_o(ns_o,0:numpft), & - mhgtt_o(ns_o,0:numpft), & - mhgtb_o(ns_o,0:numpft), & - laimask(ns_i,0:numpft), stat=ier ) - if (ier /= 0) then - write(6,*)'mklai allocation error'; call abort() - end if - - ! Determine mapping weights and map - - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Determine number of dimensions in input by querying MONTHLY_LAI - - call check_ret(nf_inq_varid(ncidi, 'MONTHLY_LAI', varid), subname) - call check_ret(nf_inq_vardimid(ncidi, varid, dimids), subname) - call check_ret(nf_inq_varndims(ncidi, varid, ndimsi), subname) - if (ndimsi ==4) then - begi(1) = 1 - begi(2) = 1 - begi(3) = 1 - leni(4) = 1 - call check_ret(nf_inq_dimlen(ncidi, dimids(1), leni(1)), subname) - call check_ret(nf_inq_dimlen(ncidi, dimids(2), leni(2)), subname) - call check_ret(nf_inq_dimlen(ncidi, dimids(3), leni(3)), subname) - else if (ndimsi== 3) then - begi(1) = 1 - begi(2) = 1 - leni(3) = 1 - call check_ret(nf_inq_dimlen(ncidi, dimids(1), leni(1)), subname) - call check_ret(nf_inq_dimlen(ncidi, dimids(2), leni(2)), subname) - end if - - ! Determine number of dimensions in output by querying MONTHLY_LAI - - call check_ret(nf_inq_varid(ncido, 'MONTHLY_LAI', varid), subname) - call check_ret(nf_inq_varndims(ncido, varid, ndimso), subname) - call check_ret(nf_inq_vardimid(ncido, varid, dimids), subname) - if (ndimso ==4) then - bego(1) = 1 - bego(2) = 1 - bego(3) = 1 - leno(4) = 1 - call check_ret(nf_inq_dimlen(ncido, dimids(1), leno(1)), subname) - call check_ret(nf_inq_dimlen(ncido, dimids(2), leno(2)), subname) - call check_ret(nf_inq_dimlen(ncido, dimids(3), leno(3)), subname) - else if (ndimso== 3) then - bego(1) = 1 - bego(2) = 1 - leno(3) = 1 - call check_ret(nf_inq_dimlen(ncido, dimids(1), leno(1)), subname) - call check_ret(nf_inq_dimlen(ncido, dimids(2), leno(2)), subname) - end if - - ! Loop over months - - do m = 1, ntim - - if (ndimsi == 4) begi(4)=m - if (ndimsi == 3) begi(3)=m - - call check_ret(nf_inq_varid (ncidi, 'MONTHLY_LAI', varid), subname) - call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & - mlai_i), subname) - - call check_ret(nf_inq_varid (ncidi, 'MONTHLY_SAI', varid), subname) - call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & - msai_i), subname) - - call check_ret(nf_inq_varid (ncidi, 'MONTHLY_HEIGHT_TOP', varid), subname) - call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & - mhgtt_i), subname) - - call check_ret(nf_inq_varid (ncidi, 'MONTHLY_HEIGHT_BOT', varid), subname) - call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & - mhgtb_i), subname) - - mlai_o(:,:) = 0. - msai_o(:,:) = 0. - mhgtt_o(:,:) = 0. - mhgtb_o(:,:) = 0. - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Loop over pft types to do mapping - do l = 0, numpft_i - 1 - call gridmap_areaave_srcmask(tgridmap, mlai_i(:,l) , mlai_o(:,l) , nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, msai_i(:,l) , msai_o(:,l) , nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, mhgtt_i(:,l), mhgtt_o(:,l), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, mhgtb_i(:,l), mhgtb_o(:,l), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - enddo - - ! Determine laimask - - laimask(:,:) = 0 - - ! copy LAI, SAI, & heights from the C3 crop (pft15) - ! to the irrigated (pft16) whether crop is on or off - mlai_o(:,c3irrcropindex) = mlai_o(:,c3cropindex) - msai_o(:,c3irrcropindex) = msai_o(:,c3cropindex) - mhgtt_o(:,c3irrcropindex) = mhgtt_o(:,c3cropindex) - mhgtb_o(:,c3irrcropindex) = mhgtb_o(:,c3cropindex) - - ! ----------------------------------------------------------------- - ! Output model resolution LAI/SAI/HEIGHT data - ! ----------------------------------------------------------------- - - ! Now write out all variables - - if (ndimso == 4) bego(4)=m - if (ndimso == 3) bego(3)=m - - call check_ret(nf_inq_varid(ncido, 'MONTHLY_LAI', varid), subname) - call check_ret(nf_put_vara_double(ncido, varid, bego, leno, mlai_o), subname) - - call check_ret(nf_inq_varid(ncido, 'MONTHLY_SAI', varid), subname) - call check_ret(nf_put_vara_double(ncido, varid, bego, leno, msai_o), subname) - - call check_ret(nf_inq_varid(ncido, 'MONTHLY_HEIGHT_TOP', varid), subname) - call check_ret(nf_put_vara_double(ncido, varid, bego, leno, mhgtt_o), subname) - - call check_ret(nf_inq_varid(ncido, 'MONTHLY_HEIGHT_BOT', varid), subname) - call check_ret(nf_put_vara_double(ncido, varid, bego, leno, mhgtb_o), subname) - - call check_ret(nf_inq_varid(ncido, 'time', varid), subname) - call check_ret(nf_put_vara_int(ncido, varid, bego(ndimso), leno(ndimso), m), subname) - - call check_ret(nf_sync(ncido), subname) - - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - - ! Input grid global area - - garea_i = 0. - do ni = 1,ns_i - garea_i = garea_i + tgridmap%area_src(ni) - end do - - glai_i(:) = 0. - gsai_i(:) = 0. - ghgtt_i(:) = 0. - ghgtb_i(:) = 0. - do l = 0, numpft_i - 1 - do ni = 1, ns_i - glai_i(l) = glai_i(l) + mlai_i(ni,l) *tgridmap%area_src(ni)*& - tdomain%mask(ni)*re**2 - gsai_i(l) = gsai_i(l) + msai_i(ni,l) *tgridmap%area_src(ni)*& - tdomain%mask(ni)*re**2 - ghgtt_i(l) = ghgtt_i(l)+ mhgtt_i(ni,l)*tgridmap%area_src(ni)*& - tdomain%mask(ni)*re**2 - ghgtb_i(l) = ghgtb_i(l)+ mhgtb_i(ni,l)*tgridmap%area_src(ni)*& - tdomain%mask(ni)*re**2 - end do - end do - - ! Output grid global area - - garea_o = 0. - do no = 1,ns_o - garea_o = garea_o + tgridmap%area_dst(no) - end do - - glai_o(:) = 0. - gsai_o(:) = 0. - ghgtt_o(:) = 0. - ghgtb_o(:) = 0. - do l = 0, numpft_i - 1 - do no = 1,ns_o - glai_o(l) = glai_o(l) + mlai_o(no,l)*tgridmap%area_dst(no)* & - frac_dst(no)*re**2 - gsai_o(l) = gsai_o(l) + msai_o(no,l)*tgridmap%area_dst(no)* & - frac_dst(no)*re**2 - ghgtt_o(l) = ghgtt_o(l)+ mhgtt_o(no,l)*tgridmap%area_dst(no)* & - frac_dst(no)*re**2 - ghgtb_o(l) = ghgtb_o(l)+ mhgtb_o(no,l)*tgridmap%area_dst(no)* & - frac_dst(no)*re**2 - end do - end do - - ! Comparison - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'LAI Output for month ',m - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,1001) -1001 format (1x,'PFT input grid area output grid area',/ & - 1x,3x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - do l = 0, numpft - write (ndiag,1002) l, glai_i(l)*1.e-06*1.e-02,glai_o(l)*1.e-06*1.e-02 -1002 format (1x,i3,f16.3,f17.3) - end do - - write (6,*) 'Successfully made LAIs/SAIs/heights for month ', m - call shr_sys_flush(6) - - enddo - write (6,*) - - ! Close input file - call check_ret(nf_close(ncidi), subname) - - ! consistency check that PFT and LAI+SAI make sense - !call pft_laicheck( ni_s, pft_i, laimask ) - - ! Deallocate dynamic memory - deallocate(mlai_i) - deallocate(msai_i) - deallocate(mhgtt_i) - deallocate(mhgtb_i) - deallocate(mlai_o) - deallocate(msai_o) - deallocate(mhgtt_o) - deallocate(mhgtb_o) - deallocate(laimask) - deallocate(frac_dst) - - call gridmap_clean(tgridmap) - call domain_clean(tdomain) - -end subroutine mklai + subroutine mklai(ldomain, mapfname, datfname, ndiag, ncido) + ! + ! !DESCRIPTION: + ! Make LAI/SAI/height data + ! Portions of this code could be moved out of the month loop + ! for improved efficiency + ! + ! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar , only : re + use mkvarctl + use mkncdio + use mkpftConstantsMod, only : c3cropindex, c3irrcropindex + ! + ! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + integer , intent(in) :: ncido ! output netcdf file id + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: Mariana Vertenstein + ! + ! + ! !LOCAL VARIABLES: + !EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + integer :: numpft_i ! number of plant types on input + real(r8) :: glai_o(0:numpft) ! output grid: global area pfts + real(r8) :: gsai_o(0:numpft) ! output grid: global area pfts + real(r8) :: ghgtt_o(0:numpft) ! output grid: global area pfts + real(r8) :: ghgtb_o(0:numpft) ! output grid: global area pfts + real(r8) :: glai_i(0:numpft) ! input grid: global area pfts + real(r8) :: gsai_i(0:numpft) ! input grid: global area pfts + real(r8) :: ghgtt_i(0:numpft) ! input grid: global area pfts + real(r8) :: ghgtb_i(0:numpft) ! input grid: global area pfts + + real(r8), allocatable :: mlai_o(:,:) ! monthly lai + real(r8), allocatable :: msai_o(:,:) ! monthly sai + real(r8), allocatable :: mhgtt_o(:,:) ! monthly height (top) + real(r8), allocatable :: mhgtb_o(:,:) ! monthly height (bottom) + real(r8), allocatable :: mlai_max(:,:) ! monthly lai + real(r8), allocatable :: msai_max(:,:) ! monthly sai + real(r8), allocatable :: mhgtt_max(:,:) ! monthly height (top) + real(r8), allocatable :: mhgtb_max(:,:) ! monthly height (bottom) + real(r8), allocatable :: mlai_i(:,:) ! monthly lai in + real(r8), allocatable :: msai_i(:,:) ! monthly sai in + real(r8), allocatable :: mhgtt_i(:,:) ! monthly height (top) in + real(r8), allocatable :: mhgtb_i(:,:) ! monthly height (bottom) in + real(r8), allocatable :: frac_dst(:) ! output fractions: same as frac_dst + integer, pointer :: laimask(:,:) ! lai+sai output mask for each plant function type + real(r8) :: garea_i ! input grid: global area + real(r8) :: garea_o ! output grid: global area + integer :: mwts ! number of weights + integer :: ni,no,ns_i,ns_o ! indices + integer :: k,l,n,m ! indices + integer :: ncidi,dimid,varid ! input netCDF id's + integer :: ndimsi,ndimso ! netCDF dimension sizes + integer :: dimids(4) ! netCDF dimension ids + integer :: bego(4),leno(4) ! netCDF bounds + integer :: begi(4),leni(4) ! netCDF bounds + integer :: ntim ! number of input time samples + integer :: ier ! error status + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + character(len=256) :: name ! name of attribute + character(len=256) :: unit ! units of attribute + character(len= 32) :: subname = 'mklai' + !----------------------------------------------------------------------- + + write (6,*) 'Attempting to make LAIs/SAIs/heights .....' + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read local fields + + ns_o = ldomain%ns + + call domain_read(tdomain,datfname) + ns_i = tdomain%ns + + write (6,*) 'Open LAI file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncidi), subname) + call check_ret(nf_inq_dimid(ncidi, 'pft', dimid), subname) + call check_ret(nf_inq_dimlen(ncidi, dimid, numpft_i), subname) + call check_ret(nf_inq_dimid(ncidi, 'time', dimid), subname) + call check_ret(nf_inq_dimlen(ncidi, dimid, ntim), subname) + + if (numpft_i /= numpft+1) then + write(6,*) 'WARNING: ' // trim(subname) // '(): parameter numpft+1 = ', numpft+1, & + 'does not equal input dataset numpft = ', numpft_i + write(6,*)'This inconsistency used to stop the program. Now we allow it ' + write(6,*)'because crop pfts 17-last are assumed to never use satellite lai data.' + ! stop + if (numpft_i > numpft + 1) then + ! NOTE(bja, 2015-01) If this error check is determined to be + ! invalid, all the loop bounds over output data in this + ! routine will need to be double checked! + write(6, *) "ERROR:" // trim(subname) // "(): input numpft must be less than or equal to output numpft+1." + call abort() + end if + endif + if (ntim /= 12) then + write(6,*)'MKLAI: must have 12 time samples on input data' + call abort() + endif + + ! NOTE - close data set at bottom of routine + + ! Dynamic allocation of variables + + allocate(mlai_i(ns_i,0:numpft_i), & + msai_i(ns_i,0:numpft_i), & + mhgtt_i(ns_i,0:numpft_i), & + mhgtb_i(ns_i,0:numpft_i), & + frac_dst(ns_o), & + mlai_o(ns_o,0:numpft), & + msai_o(ns_o,0:numpft), & + mhgtt_o(ns_o,0:numpft), & + mhgtb_o(ns_o,0:numpft), & + laimask(ns_i,0:numpft), stat=ier ) + if (ier /= 0) then + write(6,*)'mklai allocation error'; call abort() + end if + + ! Determine mapping weights and map + + call gridmap_mapread(tgridmap, mapfname) + + ! Error checks for domain and map consistencies + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Determine number of dimensions in input by querying MONTHLY_LAI + + call check_ret(nf_inq_varid(ncidi, 'MONTHLY_LAI', varid), subname) + call check_ret(nf_inq_vardimid(ncidi, varid, dimids), subname) + call check_ret(nf_inq_varndims(ncidi, varid, ndimsi), subname) + if (ndimsi ==4) then + begi(1) = 1 + begi(2) = 1 + begi(3) = 1 + leni(4) = 1 + call check_ret(nf_inq_dimlen(ncidi, dimids(1), leni(1)), subname) + call check_ret(nf_inq_dimlen(ncidi, dimids(2), leni(2)), subname) + call check_ret(nf_inq_dimlen(ncidi, dimids(3), leni(3)), subname) + else if (ndimsi== 3) then + begi(1) = 1 + begi(2) = 1 + leni(3) = 1 + call check_ret(nf_inq_dimlen(ncidi, dimids(1), leni(1)), subname) + call check_ret(nf_inq_dimlen(ncidi, dimids(2), leni(2)), subname) + end if + + ! Determine number of dimensions in output by querying MONTHLY_LAI + + call check_ret(nf_inq_varid(ncido, 'MONTHLY_LAI', varid), subname) + call check_ret(nf_inq_varndims(ncido, varid, ndimso), subname) + call check_ret(nf_inq_vardimid(ncido, varid, dimids), subname) + if (ndimso ==4) then + bego(1) = 1 + bego(2) = 1 + bego(3) = 1 + leno(4) = 1 + call check_ret(nf_inq_dimlen(ncido, dimids(1), leno(1)), subname) + call check_ret(nf_inq_dimlen(ncido, dimids(2), leno(2)), subname) + call check_ret(nf_inq_dimlen(ncido, dimids(3), leno(3)), subname) + else if (ndimso== 3) then + bego(1) = 1 + bego(2) = 1 + leno(3) = 1 + call check_ret(nf_inq_dimlen(ncido, dimids(1), leno(1)), subname) + call check_ret(nf_inq_dimlen(ncido, dimids(2), leno(2)), subname) + end if + + ! Loop over months + + do m = 1, ntim + + if (ndimsi == 4) begi(4)=m + if (ndimsi == 3) begi(3)=m + + call check_ret(nf_inq_varid (ncidi, 'MONTHLY_LAI', varid), subname) + call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & + mlai_i), subname) + + call check_ret(nf_inq_varid (ncidi, 'MONTHLY_SAI', varid), subname) + call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & + msai_i), subname) + + call check_ret(nf_inq_varid (ncidi, 'MONTHLY_HEIGHT_TOP', varid), subname) + call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & + mhgtt_i), subname) + + call check_ret(nf_inq_varid (ncidi, 'MONTHLY_HEIGHT_BOT', varid), subname) + call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & + mhgtb_i), subname) + + mlai_o(:,:) = 0. + msai_o(:,:) = 0. + mhgtt_o(:,:) = 0. + mhgtb_o(:,:) = 0. + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Loop over pft types to do mapping + do l = 0, numpft_i - 1 + call gridmap_areaave_srcmask(tgridmap, mlai_i(:,l) , mlai_o(:,l) , nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, msai_i(:,l) , msai_o(:,l) , nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, mhgtt_i(:,l), mhgtt_o(:,l), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, mhgtb_i(:,l), mhgtb_o(:,l), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + enddo + + ! Determine laimask + + laimask(:,:) = 0 + + ! copy LAI, SAI, & heights from the C3 crop (pft15) + ! to the irrigated (pft16) whether crop is on or off + mlai_o(:,c3irrcropindex) = mlai_o(:,c3cropindex) + msai_o(:,c3irrcropindex) = msai_o(:,c3cropindex) + mhgtt_o(:,c3irrcropindex) = mhgtt_o(:,c3cropindex) + mhgtb_o(:,c3irrcropindex) = mhgtb_o(:,c3cropindex) + + ! ----------------------------------------------------------------- + ! Output model resolution LAI/SAI/HEIGHT data + ! ----------------------------------------------------------------- + + ! Now write out all variables + + if (ndimso == 4) bego(4)=m + if (ndimso == 3) bego(3)=m + + call check_ret(nf_inq_varid(ncido, 'MONTHLY_LAI', varid), subname) + call check_ret(nf_put_vara_double(ncido, varid, bego, leno, mlai_o), subname) + + call check_ret(nf_inq_varid(ncido, 'MONTHLY_SAI', varid), subname) + call check_ret(nf_put_vara_double(ncido, varid, bego, leno, msai_o), subname) + + call check_ret(nf_inq_varid(ncido, 'MONTHLY_HEIGHT_TOP', varid), subname) + call check_ret(nf_put_vara_double(ncido, varid, bego, leno, mhgtt_o), subname) + + call check_ret(nf_inq_varid(ncido, 'MONTHLY_HEIGHT_BOT', varid), subname) + call check_ret(nf_put_vara_double(ncido, varid, bego, leno, mhgtb_o), subname) + + call check_ret(nf_inq_varid(ncido, 'time', varid), subname) + call check_ret(nf_put_vara_int(ncido, varid, bego(ndimso), leno(ndimso), m), subname) + + call check_ret(nf_sync(ncido), subname) + + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global areas on input and output grids + ! ----------------------------------------------------------------- + + ! Input grid global area + + garea_i = 0. + do ni = 1,ns_i + garea_i = garea_i + tgridmap%area_src(ni) + end do + + glai_i(:) = 0. + gsai_i(:) = 0. + ghgtt_i(:) = 0. + ghgtb_i(:) = 0. + do l = 0, numpft_i - 1 + do ni = 1, ns_i + glai_i(l) = glai_i(l) + mlai_i(ni,l) *tgridmap%area_src(ni)*& + tdomain%mask(ni)*re**2 + gsai_i(l) = gsai_i(l) + msai_i(ni,l) *tgridmap%area_src(ni)*& + tdomain%mask(ni)*re**2 + ghgtt_i(l) = ghgtt_i(l)+ mhgtt_i(ni,l)*tgridmap%area_src(ni)*& + tdomain%mask(ni)*re**2 + ghgtb_i(l) = ghgtb_i(l)+ mhgtb_i(ni,l)*tgridmap%area_src(ni)*& + tdomain%mask(ni)*re**2 + end do + end do + + ! Output grid global area + + garea_o = 0. + do no = 1,ns_o + garea_o = garea_o + tgridmap%area_dst(no) + end do + + glai_o(:) = 0. + gsai_o(:) = 0. + ghgtt_o(:) = 0. + ghgtb_o(:) = 0. + do l = 0, numpft_i - 1 + do no = 1,ns_o + glai_o(l) = glai_o(l) + mlai_o(no,l)*tgridmap%area_dst(no)* & + frac_dst(no)*re**2 + gsai_o(l) = gsai_o(l) + msai_o(no,l)*tgridmap%area_dst(no)* & + frac_dst(no)*re**2 + ghgtt_o(l) = ghgtt_o(l)+ mhgtt_o(no,l)*tgridmap%area_dst(no)* & + frac_dst(no)*re**2 + ghgtb_o(l) = ghgtb_o(l)+ mhgtb_o(no,l)*tgridmap%area_dst(no)* & + frac_dst(no)*re**2 + end do + end do + + ! Comparison + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'LAI Output for month ',m + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,1001) +1001 format (1x,'PFT input grid area output grid area',/ & + 1x,3x,' 10**6 km**2',' 10**6 km**2') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + do l = 0, numpft + write (ndiag,1002) l, glai_i(l)*1.e-06*1.e-02,glai_o(l)*1.e-06*1.e-02 +1002 format (1x,i3,f16.3,f17.3) + end do + + write (6,*) 'Successfully made LAIs/SAIs/heights for month ', m + + enddo + write (6,*) + + ! Close input file + call check_ret(nf_close(ncidi), subname) + + ! consistency check that PFT and LAI+SAI make sense + !call pft_laicheck( ni_s, pft_i, laimask ) + + ! Deallocate dynamic memory + deallocate(mlai_i) + deallocate(msai_i) + deallocate(mhgtt_i) + deallocate(mhgtb_i) + deallocate(mlai_o) + deallocate(msai_o) + deallocate(mhgtt_o) + deallocate(mhgtb_o) + deallocate(laimask) + deallocate(frac_dst) + + call gridmap_clean(tgridmap) + call domain_clean(tdomain) + + end subroutine mklai !----------------------------------------------------------------------- !BOP diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 8f7c59056c..b455a1ee00 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -10,16 +10,15 @@ module mklanwatMod use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 use shr_sys_mod , only : shr_sys_abort use mkvarpar , only : re - use mkesmfMod , only : regrid_data + use mkpioMod , only : mkpio_get_rawdata + use mkesmfMod , only : regrid_rawdata use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag implicit none private - public mklakwat ! make % lake - public mkwetlnd ! make % wetland - public mklakparams ! make lake parameters + public :: mklakwat ! make % lake, % wetland and lake parameters character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -28,244 +27,167 @@ module mklanwatMod contains !=============================================================== - subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, zero_out, lake_o, rc) + subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & + zero_out_lake, zero_out_wetland, lake_o, swmp_o, lakedepth_o, rc) + +#ifdef TODO + use mkdiagnosticsMod , only : output_diagnostics_continuous +#endif + use mkchecksMod , only : min_bad ! ------------------- - ! make %lake + ! make %lake, %wetland and lake parameters ! ------------------- ! input/output variables type(ESMF_Mesh) , intent(in) :: mesh_o - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - logical , intent(in) :: zero_out ! if should zero glacier out - real(r8) , intent(out) :: lake_o(:) ! output grid: %lake + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + logical , intent(in) :: zero_out_lake ! if should zero glacier out + logical , intent(in) :: zero_out_wetland ! if should zero glacier out + real(r8) , intent(out) :: lake_o(:) ! output grid: %lake + real(r8) , intent(out) :: swmp_o(:) ! output grid: %lake + real(r8) , intent(out) :: lakedepth_o(:) ! output grid: lake depth (m) integer , intent(out) :: rc ! local variables - type(ESMF_Mesh) :: mesh_i - type(ESMF_Field) :: field_i - type(ESMF_Field) :: field_o - real(r8), allocatable :: lake_i(:) ! input grid: percent lake - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: glake_i ! input grid: global lake - real(r8) :: garea_i ! input grid: global area - real(r8) :: glake_o ! output grid: global lake - real(r8) :: garea_o ! output grid: global area - integer :: ni,no,ns_i,ns_o,k ! indices - integer :: rcode ! error status - character(len=32) :: subname = 'mklakwat' + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + real(r8), allocatable :: lake_i(:) ! input grid: percent lake + real(r8), allocatable :: swmp_i(:) ! input grid: percent lake + real(r8), allocatable :: lakedepth_i(:) + integer :: ni,no,ns_i,ns_o,k ! indices + integer :: rcode ! error status + integer :: srcMaskValue = 0 + integer :: dstMaskValue = -987987 ! spval for RH mask values + integer :: srcTermProcessing_Value = 0 + real(r8), parameter :: min_valid_lakedepth = 0._r8 + character(len=32) :: subname = 'mklakwat' !----------------------------------------------------------------------- rc = ESMF_SUCCESS - if (root_task) then - write (ndiag,*) 'Attempting to make %lake .....' - end if - - ! Initialize lake_o to 0 + ! Initialize lake_o and swmp_o to 0 ns_o = size(lake_o) do no = 1,ns_o lake_o(no) = 0. + swmp_o(no) = 0. enddo - if ( .not. zero_out ) then + ! create field on model mesh + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! create field on input mesh (first read in input mesh) - mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! ---------------------------------------- + ! Create route handle for rawdata mesh to model mesh + ! ---------------------------------------- + + ! create field on input mesh (first read in input mesh) + call ESMF_VMLogMemInfo("Before create mesh_i in lanwat") + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in lanwat") + + ! create route handle to map field_model to field_data + call ESMF_VMLogMemInfo("Before regridstore in regrid_data") + call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_DSTAREA, & + srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regridstore in regrid_data") + + ! ---------------------------------------- + ! Create %lake + ! ---------------------------------------- + + if (.not. zero_out_lake) then + + if (root_task) then + write (ndiag,*) 'Attempting to make %lake .....' + end if + + ! read in rawdata allocate(lake_i(ns_i), stat=rcode) if (rcode/=0) call shr_sys_abort() - - ! create field on model mesh - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + call mkpio_get_rawdata(trim(file_data_i), 'PCT_LAKE', mesh_i, lake_i, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! regrid lake_i to lake_o - this also returns lake_i to be used in the global sums below - call regrid_data(field_i, field_o, 'PCT_LAKE', trim(file_data_i), lake_i, lake_o, rc) + call ESMF_VMLogMemInfo("Before regrid_data in lanwat") + call regrid_rawdata(field_i, field_o, routehandle, lake_i, lake_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regrid_data in lanwat") do no = 1,size(lake_o) if (lake_o(no) < 1.) lake_o(no) = 0. enddo - ! ----------------------------------------------------------------- - ! Error check prep - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - ! ----------------------------------------------------------------- - ! TODO: not sure if we still want this with the ESMF regridding - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - ! TODO: implement this - ! ! Input grid - deallocate (lake_i) - ! TODO: destroy route handle and created field - end if - - if (root_task) then - write (ndiag,*) 'Successfully made %lake' - write (ndiag,*) - end if - - end subroutine mklakwat - - !=============================================================== - subroutine mkwetlnd(file_mesh_i, file_data_i, mesh_o, zero_out, swmp_o, rc) - - ! ------------------- - ! make %wetland - ! ------------------- - - ! input/output variables - type(ESMF_Mesh) , intent(in) :: mesh_o - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - logical , intent(in) :: zero_out ! if should zero glacier out - real(r8) , intent(out) :: swmp_o(:) ! output grid: %lake - integer , intent(out) :: rc - - ! local variables - type(ESMF_Mesh) :: mesh_i - type(ESMF_Field) :: field_i - type(ESMF_Field) :: field_o - real(r8), allocatable :: swmp_i(:) ! input grid: percent lake - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: glake_i ! input grid: global lake - real(r8) :: garea_i ! input grid: global area - real(r8) :: glake_o ! output grid: global lake - real(r8) :: garea_o ! output grid: global area - integer :: ni,no,ns_i,ns_o,k ! indices - integer :: rcode ! error status - character(len=32) :: subname = 'mkwtlnd' - !----------------------------------------------------------------------- - - rc = ESMF_SUCCESS - if (root_task) then - write (ndiag,*) 'Attempting to make %wetland .....' + if (root_task) then + write (ndiag,*) 'Successfully made %lake' + write (ndiag,*) + end if end if - ! Initialize swmp_o to 0 - ns_o = size(swmp_o) - do no = 1,ns_o - swmp_o(no) = 0. - enddo + ! ---------------------------------------- + ! Create %wetland + ! ---------------------------------------- - if ( .not. zero_out ) then + if (.not. zero_out_wetland) then + if (root_task) then + write (ndiag,*) 'Attempting to make %wetland .....' + end if - ! create field on input mesh (first read in input mesh) - mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! read in rawdata allocate(swmp_i(ns_i), stat=rcode) if (rcode/=0) call shr_sys_abort() - - ! create field on model mesh - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + call mkpio_get_rawdata(trim(file_data_i), 'PCT_WETLAND', mesh_i, swmp_i, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! regrid swmp_i to swmp_o - this also returns swmp_i to be used in the global sums below - call regrid_data(field_i, field_o, 'PCT_WETLAND', trim(file_data_i), swmp_i, swmp_o, rc) + call ESMF_VMLogMemInfo("Before regrid_data for wetland") + call regrid_rawdata(field_i, field_o, routehandle, swmp_i, swmp_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regrid_data for wetland") if (ChkErr(rc,__LINE__,u_FILE_u)) return do no = 1,ns_o if (swmp_o(no) < 1.) swmp_o(no) = 0. enddo - - ! ----------------------------------------------------------------- - ! Error check prep - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - ! ----------------------------------------------------------------- - ! TODO: not sure if we still want this with the ESMF regridding - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - ! TODO: implememt this - deallocate (swmp_i) - ! TODO: destroy route handle and created field + if (root_task) then + write (ndiag,*) 'Successfully made %wetland' + write (ndiag,*) + end if end if - if (root_task) then - write (ndiag,*) 'Successfully made %wetland' - write (ndiag,*) - end if - - end subroutine mkwetlnd - - !=============================================================== - - subroutine mklakparams(file_mesh_i, file_data_i, mesh_o, lakedepth_o, rc) - - ! ------------------- - ! make lake parameters (currently just lake depth) - ! ------------------- - - !use mkdiagnosticsMod , only : output_diagnostics_continuous - use mkchecksMod , only : min_bad - - ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o - real(r8) , intent(out) :: lakedepth_o(:) ! output grid: lake depth (m) - integer , intent(out) :: rc - - ! local variables - type(ESMF_Mesh) :: mesh_i - type(ESMF_Field) :: field_i - type(ESMF_Field) :: field_o - real(r8), allocatable :: lakedepth_i(:) ! input raw data - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: glake_i ! input grid: global lake - real(r8) :: garea_i ! input grid: global area - real(r8) :: glake_o ! output grid: global lake - real(r8) :: garea_o ! output grid: global area - integer :: ni,no,ns_i,ns_o,k ! indices - integer :: rcode ! error status - real(r8), parameter :: min_valid_lakedepth = 0._r8 - character(len=32) :: subname = 'mklakparams' - !----------------------------------------------------------------------- - - rc = ESMF_SUCCESS + ! ---------------------------------------- + ! Create lake parameter (lakdepth) + ! ---------------------------------------- if (root_task) then write (ndiag,*) 'Attempting to make lake parameters.....' end if - ! create field on input mesh (first read in input mesh) - mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! read in rawdata allocate(lakedepth_i(ns_i), stat=rcode) if (rcode/=0) call shr_sys_abort() - - ! create field on model mesh - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call mkpio_get_rawdata(trim(file_data_i), 'LAKEDEPTH', mesh_i, lakedepth_i, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! regrid lakedepth_i to lakedepth_o - this also returns lakedepth_i to be used in the global sums below - call regrid_data(field_i, field_o, 'LAKEDEPTH', trim(file_data_i), lakedepth_i, lakedepth_o, rc) + call ESMF_VMLogMemInfo("Before regrid_data for lakedepth") + call regrid_rawdata(field_i, field_o, routehandle, lakedepth_i, lakedepth_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regrid_data for lakedepth") if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Check validity of output data @@ -273,8 +195,9 @@ subroutine mklakparams(file_mesh_i, file_data_i, mesh_o, lakedepth_o, rc) call shr_sys_abort() end if - ! TODO: implement the following - !call output_diagnostics_continuous(data_i, lakedepth_o, tgridmap, "Lake Depth", "m", ndiag, tdomain%mask, frac_dst) +#ifdef TODO + call output_diagnostics_continuous(data_i, lakedepth_o, tgridmap, "Lake Depth", "m", ndiag, tdomain%mask, frac_dst) +#endif deallocate (lakedepth_i) @@ -283,6 +206,15 @@ subroutine mklakparams(file_mesh_i, file_data_i, mesh_o, lakedepth_o, rc) write (ndiag,*) end if - end subroutine mklakparams + ! Release memory for route handle + + call ESMF_VMLogMemInfo("Before destroy operation for lanwat ") + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operation for lanwat ") + + end subroutine mklakwat end module mklanwatMod diff --git a/tools/mksurfdata_esmf/src/mkpeatMod.F90 b/tools/mksurfdata_esmf/src/mkpeatMod.F90 index 8e47f5032d..180f2ccb75 100644 --- a/tools/mksurfdata_esmf/src/mkpeatMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpeatMod.F90 @@ -15,7 +15,6 @@ module mkpeatMod ! ! !USES: use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush use mkdomainMod , only : domain_checksame implicit none @@ -36,114 +35,111 @@ module mkpeatMod ! !IROUTINE: mkpeat ! ! !INTERFACE: -subroutine mkpeat(ldomain, mapfname, datfname, ndiag, peat_o) -! -! !DESCRIPTION: -! make peat -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_area - use mkchecksMod, only : min_bad, max_bad -! -! !ARGUMENTS: - - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: peat_o(:) ! output grid: fraction peat -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: data_i(:) ! data on input grid - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - - real(r8), parameter :: min_valid = 0._r8 ! minimum valid value - real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value - character(len=32) :: subname = 'mkpeat' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make peat .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - call domain_read( tdomain, datfname ) - - call gridmap_mapread( tgridmap, mapfname ) - - ! Obtain frac_dst - allocate(frac_dst(ldomain%ns), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write(6,*)'Open peat file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(data_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() - - ! ----------------------------------------------------------------- - ! Regrid peat - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'peatf', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, peat_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(peat_o, min_valid, 'peat') .or. & - max_bad(peat_o, max_valid, 'peat')) then - call abort() - end if - - call output_diagnostics_area(data_i, peat_o, tgridmap, "Peat", percent=.false., ndiag=ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- - - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (data_i) - deallocate (frac_dst) - deallocate (mask_r8) - - write (6,*) 'Successfully made peat' - write (6,*) - call shr_sys_flush(6) - -end subroutine mkpeat - + subroutine mkpeat(ldomain, mapfname, datfname, ndiag, peat_o) + ! + ! !DESCRIPTION: + ! make peat + ! + ! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkncdio + use mkdiagnosticsMod, only : output_diagnostics_area + use mkchecksMod, only : min_bad, max_bad + ! + ! !ARGUMENTS: + + implicit none + type(domain_type) , intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: peat_o(:) ! output grid: fraction peat + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: Sam Levis and Bill Sacks + ! + ! + ! !LOCAL VARIABLES: + !EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: data_i(:) ! data on input grid + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + integer :: ncid,varid ! input netCDF id's + integer :: ier ! error status + + real(r8), parameter :: min_valid = 0._r8 ! minimum valid value + real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value + character(len=32) :: subname = 'mkpeat' + !----------------------------------------------------------------------- + + write (6,*) 'Attempting to make peat .....' + + ! ----------------------------------------------------------------- + ! Read domain and mapping information, check for consistency + ! ----------------------------------------------------------------- + + call domain_read( tdomain, datfname ) + + call gridmap_mapread( tgridmap, mapfname ) + + ! Obtain frac_dst + allocate(frac_dst(ldomain%ns), stat=ier) + if (ier/=0) call abort() + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + allocate(mask_r8(tdomain%ns), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! ----------------------------------------------------------------- + ! Open input file, allocate memory for input data + ! ----------------------------------------------------------------- + + write(6,*)'Open peat file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + + allocate(data_i(tdomain%ns), stat=ier) + if (ier/=0) call abort() + + ! ----------------------------------------------------------------- + ! Regrid peat + ! ----------------------------------------------------------------- + + call check_ret(nf_inq_varid (ncid, 'peatf', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + call gridmap_areaave_srcmask(tgridmap, data_i, peat_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check validity of output data + if (min_bad(peat_o, min_valid, 'peat') .or. & + max_bad(peat_o, max_valid, 'peat')) then + call abort() + end if + + call output_diagnostics_area(data_i, peat_o, tgridmap, "Peat", percent=.false., ndiag=ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! ----------------------------------------------------------------- + ! Close files and deallocate dynamic memory + ! ----------------------------------------------------------------- + + call check_ret(nf_close(ncid), subname) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (data_i) + deallocate (frac_dst) + deallocate (mask_r8) + + write (6,*) 'Successfully made peat' + write (6,*) + + end subroutine mkpeat end module mkpeatMod diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index f454a6e580..d6f1b04e4a 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -1,20 +1,19 @@ module mkpftMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkpft -! -! !DESCRIPTION: -! Make PFT data -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -!----------------------------------------------------------------------- -!!USES: + !----------------------------------------------------------------------- + !BOP + ! + ! !MODULE: mkpft + ! + ! !DESCRIPTION: + ! Make PFT data + ! + ! !REVISION HISTORY: + ! Author: Mariana Vertenstein + ! + !----------------------------------------------------------------------- + !!USES: use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush use mkvarpar , only : noveg use mkvarctl , only : numpft use mkdomainMod , only : domain_checksame @@ -23,16 +22,16 @@ module mkpftMod implicit none private ! By default make data private -! -! !PUBLIC MEMBER FUNCTIONS: -! + ! + ! !PUBLIC MEMBER FUNCTIONS: + ! public mkpftInit ! Initialization public mkpft ! Set PFT public mkpft_parse_oride ! Parse the string with PFT fraction/index info to override public mkpftAtt ! Write out attributes to output file on pft -! -! !PUBLIC DATA MEMBERS: -! + ! + ! !PUBLIC DATA MEMBERS: + ! ! ! When pft_idx and pft_frc are set, they must be set together, and they will cause the @@ -42,12 +41,12 @@ module mkpftMod ! integer :: m ! index integer, public :: pft_idx(0:maxpft) = & ! PFT vegetation index to override with - (/ ( -1, m = 0, maxpft ) /) + (/ ( -1, m = 0, maxpft ) /) real(r8), public :: pft_frc(0:maxpft) = & ! PFT vegetation fraction to override with - (/ ( 0.0_r8, m = 0, maxpft ) /) -! -! !PRIVATE DATA MEMBERS: -! + (/ ( 0.0_r8, m = 0, maxpft ) /) + ! + ! !PRIVATE DATA MEMBERS: + ! logical, public, protected :: use_input_pft = .false. ! Flag to override PFT with input values logical, public, protected :: presc_cover = .false. ! Flag to prescribe vegetation coverage integer, private :: nzero ! index of first zero fraction @@ -68,1200 +67,1198 @@ module mkpftMod end interface pft_oride type(pft_oride), private :: pft_override ! Module instance of PFT override object - ! Used for both zeroing out PFT's as well - ! as setting specified PFT's over the gridcell -! -! !PRIVATE MEMBER FUNCTIONS: -! + ! Used for both zeroing out PFT's as well + ! as setting specified PFT's over the gridcell + ! + ! !PRIVATE MEMBER FUNCTIONS: + ! private :: mkpft_check_oride ! Check the pft_frc and pft_idx values for correctness -!EOP -!=============================================================== + !EOP + !=============================================================== contains -!=============================================================== - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkpftInit -! -! !INTERFACE: -subroutine mkpftInit( zero_out_l, all_veg_l ) -! -! !DESCRIPTION: -! Initialize of Make PFT data -! !USES: - use mkvarpar, only : numstdpft, numstdcft -! -! !ARGUMENTS: - implicit none - logical, intent(IN) :: zero_out_l ! If veg should be zero'ed out - logical, intent(IN) :: all_veg_l ! If should zero out other fractions so that - ! all land-cover is vegetation -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - real(r8), parameter :: hndrd = 100.0_r8 ! A hundred percent - character(len=32) :: subname = 'mkpftMod::mkpftInit() ' - logical :: error_happened ! If an error was triggered so should return -!----------------------------------------------------------------------- - write (6, '(a, a, a)') "In ", trim(subname), "..." - if ( maxpft < numpft ) then - write(6,*) subname//'number PFT is > max allowed!' - call abort() - return - end if - nzero = -1 - call mkpft_check_oride( error_happened ) - if ( error_happened )then - write(6,*) subname//'Problem setting pft override settings' - return - end if - if ( zero_out_l .and. use_input_pft )then - write(6,*) subname//"trying to both zero out all PFT's as well as set them to specific values" - call abort() - return - end if - ! If zeroing out, set use_input_pft to true so the pft_override will be used - if( zero_out_l )then - nzero = 0 - pft_frc(0) = 0.0_r8 - pft_idx(0) = noveg - use_input_pft = .true. - end if - if ( use_input_pft ) then - write(6,*) 'Set PFT fraction to : ', pft_frc(0:nzero) - write(6,*) 'With PFT index : ', pft_idx(0:nzero) - end if - if ( all_veg_l .and. .not. use_input_pft )then - write(6,*) subname//'if all_veg is set to true then specified PFT indices must be provided (i.e. pft_frc and pft_idx)' - call abort() - return - end if - - if ( zero_out_l .and. all_veg_l )then - write(6,*) subname//'zeroing out vegetation and setting vegetation to 100% is a contradiction!' - call abort() - return - end if - - ! Determine number of PFTs on the natural vegetation landunit, and number of CFTs on - ! the crop landunit. - ! - ! For the sake of dynamic PFTs and dynamic landunits, it helps for the structure of the - ! surface dataset to reflect the subgrid structure that will be used by CLM. Currently - ! generic crops will always go on the crop landunit, regardless of whether or not we're - ! using the extra specific crops (so we always run CLM with create_crop_landunit=.true.). - ! When we create a surface dataset WITH the extra specific crops, all crops - ! (including the generic crops) again go on the crop landunit. - - num_natpft = numstdpft - numstdcft - num_cft = numpft - num_natpft - - ! Determine array bounds for arrays of just natural pfts and just crops. Note that - ! these are set up so that they always span 0:numpft, so that there is a 1:1 - ! correspondence between an element in a full 0:numpft array and an element with the - ! same index in either a natpft array or a cft array. - natpft_lb = noveg - natpft_ub = num_natpft - cft_lb = num_natpft+1 - cft_ub = cft_lb + num_cft - 1 - - ! Make sure the array indices have been set up properly, to ensure the 1:1 - ! correspondence mentioned above - if (cft_ub /= numpft) then - write(6,*) 'CFT_UB set up incorrectly: cft_ub, numpft = ', cft_ub, numpft - call abort() - return - end if + !=============================================================== + + !----------------------------------------------------------------------- + !BOP ! - ! Set the PFT override values if applicable + ! !IROUTINE: mkpftInit ! - pft_override = pft_oride() - presc_cover = .false. - if( zero_out_l )then - call pft_override%InitZeroOut() - presc_cover = .true. - else if ( use_input_pft ) then - call pft_override%InitAllPFTIndex() - if ( .not. all_veg_l )then - if ( pft_override%crop <= 0.0 )then - write(6,*) "Warning: PFT/CFT's are being overridden, but no crop type is being asked for" - end if - if ( pft_override%natveg <= 0.0 )then - write(6,*) "Warning: PFT/CFT's are being overridden, but no natural vegetation type is being asked for" - end if - presc_cover = .false. - else - presc_cover = .true. - end if - end if - -end subroutine mkpftInit - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkpft -! -! !INTERFACE: -subroutine mkpft(ldomain, mapfname, fpft, ndiag, & - pctlnd_o, pctnatpft_o, pctcft_o) -! -! !DESCRIPTION: -! Make PFT data -! -! This dataset consists of the %cover of the [numpft]+1 PFTs used by -! the model. The input %cover pertains to the "vegetated" portion of the -! grid cell and sums to 100. The real portion of each grid cell -! covered by each PFT is the PFT cover times the fraction of the -! grid cell that is land. This is the quantity preserved when -! area-averaging from the input (1/2 degree) grid to the models grid. -! -! Upon return from this routine, the % cover of the natural veg + crop landunits is -! generally 100% everywhere; this will be normalized later to account for special landunits. -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio - use mkpctPftTypeMod, only : pct_pft_type - use mkpftConstantsMod, only : natpft_lb, natpft_ub, num_cft, cft_lb, cft_ub -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: fpft ! input pft dataset file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: pctlnd_o(:) ! output grid:%land/gridcell - type(pct_pft_type), intent(out):: pctnatpft_o(:) ! natural PFT cover - type(pct_pft_type), intent(out):: pctcft_o(:) ! crop (CFT) cover -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - type(pct_pft_type), allocatable:: pctnatpft_i(:) ! input grid: natural PFT cover - type(pct_pft_type), allocatable:: pctcft_i(:) ! input grid: crop (CFT) cover - type(domain_type) :: tdomain ! local domain - type(gridmap_type) :: tgridmap ! local gridmap - real(r8), allocatable :: pctpft_i(:,:) ! input grid: PFT percent - real(r8), allocatable :: pctpft_o(:,:) ! output grid: PFT percent (% of grid cell) - real(r8), allocatable :: pctnatveg_i(:) ! input grid: natural veg percent (% of grid cell) - real(r8), allocatable :: pctnatveg_o(:) ! output grid: natural veg percent (% of grid cell) - real(r8), allocatable :: pctcrop_i(:) ! input grid: all crop percent (% of grid cell) - real(r8), allocatable :: pctcrop_o(:) ! output grid: all crop percent (% of grid cell) - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: pct_cft_i(:,:) ! input grid: CFT (Crop Functional Type) percent (% of landunit cell) - real(r8), allocatable :: temp_i(:,:) ! input grid: temporary 2D variable to read in - real(r8), allocatable :: pct_cft_o(:,:) ! output grid: CFT (Crop Functional Type) percent (% of landunit cell) - real(r8), allocatable :: pct_nat_pft_i(:,:) ! input grid: natural PFT percent (% of landunit cell) - real(r8), allocatable :: pct_nat_pft_o(:,:) ! output grid: natural PFT percent (% of landunit cell) - integer :: numpft_i ! num of plant types input data - integer :: natpft_i ! num of natural plant types input data - integer :: ncft_i ! num of crop types input data - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: wst_sum ! sum of %pft - real(r8), allocatable :: gpft_o(:) ! output grid: global area pfts - real(r8) :: garea_o ! output grid: global area - real(r8), allocatable :: gpft_i(:) ! input grid: global area pfts - real(r8) :: garea_i ! input grid: global area - integer :: k,n,m,ni,no,ns_i,ns_o ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ndims ! number of dimensions for a variable on the file - integer :: dimlens(3) ! dimension lengths for a variable on the file - integer :: ier ! error status - real(r8) :: relerr = 0.0001_r8 ! max error: sum overlap wts ne 1 - logical :: oldformat ! if input file is in the old format or not (based on what variables exist) - logical :: error_happened ! If an error was triggered so should return - - character(len=35) veg(0:maxpft) ! vegetation types - character(len=32) :: subname = 'mkpftMod::mkpft()' -!----------------------------------------------------------------------- - - write (6,*) - write (6, '(a, a, a)') "In ", trim(subname), "..." - write (6,*) 'Attempting to make PFTs .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Set the vegetation types - ! ----------------------------------------------------------------- - if ( numpft >= numstdpft )then - veg(0:maxpft) = (/ & - 'not vegetated ', & - 'needleleaf evergreen temperate tree', & - 'needleleaf evergreen boreal tree ', & - 'needleleaf deciduous boreal tree ', & - 'broadleaf evergreen tropical tree ', & - 'broadleaf evergreen temperate tree ', & - 'broadleaf deciduous tropical tree ', & - 'broadleaf deciduous temperate tree ', & - 'broadleaf deciduous boreal tree ', & - 'broadleaf evergreen shrub ', & - 'broadleaf deciduous temperate shrub', & - 'broadleaf deciduous boreal shrub ', & - 'c3 arctic grass ', & - 'c3 non-arctic grass ', & - 'c4 grass ', & - 'c3_crop ', & - 'c3_irrigated ', & - 'temperate_corn ', & - 'irrigated_temperate_corn ', & - 'spring_wheat ', & - 'irrigated_spring_wheat ', & - 'winter_wheat ', & - 'irrigated_winter_wheat ', & - 'temperate_soybean ', & - 'irrigated_temperate_soybean ', & - 'barley ', & - 'irrigated_barley ', & - 'winter_barley ', & - 'irrigated_winter_barley ', & - 'rye ', & - 'irrigated_rye ', & - 'winter_rye ', & - 'irrigated_winter_rye ', & - 'cassava ', & - 'irrigated_cassava ', & - 'citrus ', & - 'irrigated citrus ', & - 'cocoa ', & - 'irrigated_cocoa ', & - 'coffee ', & - 'irrigated_coffee ', & - 'cotton ', & - 'irrigated_cotton ', & - 'datepalm ', & - 'irrigated_datepalm ', & - 'foddergrass ', & - 'irrigated_foddergrass ', & - 'grapes ', & - 'irrigated_grapes ', & - 'groundnuts ', & - 'irrigated_groundnuts ', & - 'millet ', & - 'irrigated_millet ', & - 'oilpalm ', & - 'irrigated_oilpalm ', & - 'potatoes ', & - 'irrigated_potatoes ', & - 'pulses ', & - 'irrigated_pulses ', & - 'rapeseed ', & - 'irrigated_rapeseed ', & - 'rice ', & - 'irrigated_rice ', & - 'sorghum ', & - 'irrigated_sorghum ', & - 'sugarbeet ', & - 'irrigated_sugarbeet ', & - 'sugarcane ', & - 'irrigated_sugarcane ', & - 'sunflower ', & - 'irrigated_sunflower ', & - 'miscanthus ', & - 'irrigated_miscanthus ', & - 'switchgrass ', & - 'irrigated_switchgrass ', & - 'tropical_corn ', & - 'irrigated_tropical_corn ', & - 'tropical_soybean ', & - 'irrigated_tropical_soybean ' /) - end if - if ( numpft == numstdpft )then - write(6,*)'Creating surface datasets with the standard # of PFTs =', numpft - else if ( numpft > numstdpft )then - write(6,*)'Creating surface datasets with extra types for crops; total pfts =', numpft - else - write(6,*) subname//': parameter numpft is NOT set to a known value (should be 16 or more) =',numpft - call abort() - return - end if - - ns_o = ldomain%ns - - ! ----------------------------------------------------------------- - ! Read input PFT file - ! ----------------------------------------------------------------- - if ( .not. presc_cover ) then - ! Obtain input grid info, read PCT_PFT - - call domain_read(tdomain,fpft) - ns_i = tdomain%ns - - write (6,*) 'Open PFT file: ', trim(fpft) - call check_ret(nf_open(fpft, 0, ncid), subname) - - ! Check what variables exist to determine what format the file is in - call check_ret(nf_inq_varid (ncid, 'PCT_PFT', varid), subname, varexists=oldformat) - - if ( oldformat ) then - write(6,*) subname//' ERROR: PCT_PFT field on the the file so it is in the old format, which is no longer supported' - call abort() - return - end if - call check_ret(nf_inq_dimid (ncid, 'natpft', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, natpft_i), subname) - call check_ret(nf_inq_dimid (ncid, 'cft', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, ncft_i), subname) - numpft_i = natpft_i + ncft_i - - ! Check if the number of pfts on the input matches the expected number. A mismatch - ! is okay if the input raw dataset has prognostic crops and the output does not. - if (numpft_i .ne. numpft+1) then - if (numpft_i .eq. numstdpft+1) then - write(6,*) subname//' ERROR: trying to use non-crop input file' - write(6,*) 'for a surface dataset with crops.' - call abort() - return - else if (numpft_i > numstdpft+1 .and. numpft_i == maxpft+1) then - write(6,*) subname//' WARNING: using a crop input raw dataset for a non-crop output surface dataset' - else - write(6,*) subname//': parameter numpft+1= ',numpft+1, & - 'does not equal input dataset numpft= ',numpft_i - call abort() - return - end if - endif - - ! TODO: create a route handle - ! for starts just do everything on one processor to make sure it works - - ! TODO: determine local number of points and allocate memory only for the local number - ! the local number can be determined from the mesh - ! TODO: initialize pio and set global decomposition - - ! If file is in the new format, expect the following variables: - ! PCT_NATVEG, PCT_CROP, PCT_NAT_PFT, PCT_CFT - allocate(pctnatveg_i(ns_i), & - pctnatveg_o(ns_o), & - pctcrop_i(ns_i), & - pctcrop_o(ns_o), & - frac_dst(ns_o), & - pct_cft_i(ns_i,1:num_cft), & - pct_cft_o(ns_o,1:num_cft), & - pct_nat_pft_i(ns_i,0:num_natpft), & - pct_nat_pft_o(ns_o,0:num_natpft), & - stat=ier) - if (ier/=0)then - call abort() - return - end if - - call check_ret(nf_inq_varid (ncid, 'PCT_NATVEG', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, pctnatveg_i), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_CROP', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, pctcrop_i), subname) - if ( .not. use_input_pft )then - call check_ret(nf_inq_varid (ncid, 'PCT_CFT', varid), subname) - call get_dim_lengths(ncid, 'PCT_CFT', ndims, dimlens(:) ) - if ( ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) == num_cft )then - call check_ret(nf_get_var_double (ncid, varid, pct_cft_i), subname) - else if ( ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) > num_cft )then - ! Read in the whole array: then sum the rainfed and irrigated - ! seperately - allocate( temp_i(ns_i,dimlens(3)) ) - call check_ret(nf_get_var_double (ncid, varid, temp_i), subname) - do n = 1, num_cft - pct_cft_i(:,n) = 0.0_r8 - do m = n, dimlens(3), 2 - pct_cft_i(:,n) = pct_cft_i(:,n) + temp_i(:,m) - end do - end do - deallocate( temp_i ) - else - write(6,*) subname//': ERROR: dimensions for PCT_CROP are NOT what is expected' - call abort() - return - end if - call check_ret(nf_inq_varid (ncid, 'PCT_NAT_PFT', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, pct_nat_pft_i), subname) - end if - - call check_ret(nf_close(ncid), subname) - - ! ----------------------------------------------------------------- - ! Otherwise if vegetation is prescribed everywhere - ! ----------------------------------------------------------------- - else - ns_i = 1 - numpft_i = numpft+1 - allocate(pctnatveg_i(ns_i), & - pctnatveg_o(ns_o), & - pctcrop_i(ns_i), & - pctcrop_o(ns_o), & - pct_cft_i(ns_i,1:num_cft), & - pct_cft_o(ns_o,1:num_cft), & - pct_nat_pft_i(ns_i,0:num_natpft), & - pct_nat_pft_o(ns_o,0:num_natpft), & - stat=ier) - if (ier/=0)then - call abort() - return - end if - end if - allocate(pctpft_i(ns_i,0:(numpft_i-1)), & - pctpft_o(ns_o,0:(numpft_i-1)), & - pctnatpft_i(ns_i), & - pctcft_i(ns_i), & - stat=ier) - if (ier/=0)then - call abort() - return - end if - - ! Determine pctpft_o on output grid - - ! If total vegetation cover is prescribed from input... - if ( use_input_pft .and. presc_cover ) then - - do no = 1,ns_o - pctlnd_o(no) = 100._r8 - pctnatveg_o(no) = pft_override%natveg - pctcrop_o(no) = pft_override%crop - end do - - ! otherewise if total cover isn't prescribed read it from the datasets - else - - ! Compute pctlnd_o, pctpft_o - - ! TODO: create a route handle here - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - ! TODO: remove this check - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Area-average percent cover on input grid [pctpft_i] to output grid - ! [pctpft_o] and correct [pctpft_o] according to land landmask - ! Note that percent cover is in terms of total grid area. - pctlnd_o(:) = frac_dst(:) * 100._r8 - - ! New format with extra variables on input - call gridmap_areaave_srcmask(tgridmap, pctnatveg_i, pctnatveg_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, pctcrop_i, pctcrop_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! - ! If specific PFT/CFT's are NOT prescribed set them from the input file - ! - if ( .not. use_input_pft )then - do m = 0, num_natpft - call gridmap_areaave_scs(tgridmap, pct_nat_pft_i(:,m), & - pct_nat_pft_o(:,m), nodata=0._r8, & - src_wt=pctnatveg_i*0.01_r8*tdomain%mask, & - dst_wt=pctnatveg_o*0.01_r8, frac_dst=frac_dst) - do no = 1,ns_o - if (pctlnd_o(no) < 1.0e-6 .or. pctnatveg_o(no) < 1.0e-6) then - if (m == 0) then - pct_nat_pft_o(no,m) = 100._r8 - else - pct_nat_pft_o(no,m) = 0._r8 - endif - end if - enddo - end do - do m = 1, num_cft - call gridmap_areaave_scs(tgridmap, pct_cft_i(:,m), pct_cft_o(:,m), & - nodata=0._r8, src_wt=pctcrop_i*0.01_r8*tdomain%mask, & - dst_wt=pctcrop_o*0.01_r8, frac_dst=frac_dst) - do no = 1,ns_o - if (pctlnd_o(no) < 1.0e-6 .or. pctcrop_o(no) < 1.0e-6) then - if (m == 1) then - pct_cft_o(no,m) = 100._r8 - else - pct_cft_o(no,m) = 0._r8 - endif - end if - enddo - end do - ! Otherwise do some error checking to make sure specific veg types are given where nat-veg and crop is assigned - else - do no = 1,ns_o - if (pctlnd_o(no) > 1.0e-6 .and. pctnatveg_o(no) > 1.0e-6) then - if ( pft_override%natveg <= 0.0_r8 )then - write(6,*) subname//': ERROR: no natural vegetation PFTs are being prescribed but there are natural '// & - 'vegetation areas: provide at least one natural veg PFT' - call abort() - return - end if - end if - if (pctlnd_o(no) > 1.0e-6 .and. pctcrop_o(no) > 1.0e-6) then - if ( pft_override%crop <= 0.0_r8 )then - write(6,*) subname//': ERROR: no crop CFTs are being prescribed but there are crop areas: provide at least one CFT' - call abort() - return - end if - end if - end do - end if - end if + ! !INTERFACE: + subroutine mkpftInit( zero_out_l, all_veg_l ) + ! + ! !DESCRIPTION: + ! Initialize of Make PFT data + ! !USES: + use mkvarpar, only : numstdpft, numstdcft + ! + ! !ARGUMENTS: + implicit none + logical, intent(IN) :: zero_out_l ! If veg should be zero'ed out + logical, intent(IN) :: all_veg_l ! If should zero out other fractions so that + ! all land-cover is vegetation + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: Erik Kluzek + ! + ! + ! !LOCAL VARIABLES: + !EOP + real(r8), parameter :: hndrd = 100.0_r8 ! A hundred percent + character(len=32) :: subname = 'mkpftMod::mkpftInit() ' + logical :: error_happened ! If an error was triggered so should return + !----------------------------------------------------------------------- + write (6, '(a, a, a)') "In ", trim(subname), "..." + if ( maxpft < numpft ) then + write(6,*) subname//'number PFT is > max allowed!' + call abort() + return + end if + nzero = -1 + call mkpft_check_oride( error_happened ) + if ( error_happened )then + write(6,*) subname//'Problem setting pft override settings' + return + end if + if ( zero_out_l .and. use_input_pft )then + write(6,*) subname//"trying to both zero out all PFT's as well as set them to specific values" + call abort() + return + end if + ! If zeroing out, set use_input_pft to true so the pft_override will be used + if( zero_out_l )then + nzero = 0 + pft_frc(0) = 0.0_r8 + pft_idx(0) = noveg + use_input_pft = .true. + end if + if ( use_input_pft ) then + write(6,*) 'Set PFT fraction to : ', pft_frc(0:nzero) + write(6,*) 'With PFT index : ', pft_idx(0:nzero) + end if + if ( all_veg_l .and. .not. use_input_pft )then + write(6,*) subname//'if all_veg is set to true then specified PFT indices must be provided (i.e. pft_frc and pft_idx)' + call abort() + return + end if + + if ( zero_out_l .and. all_veg_l )then + write(6,*) subname//'zeroing out vegetation and setting vegetation to 100% is a contradiction!' + call abort() + return + end if + + ! Determine number of PFTs on the natural vegetation landunit, and number of CFTs on + ! the crop landunit. + ! + ! For the sake of dynamic PFTs and dynamic landunits, it helps for the structure of the + ! surface dataset to reflect the subgrid structure that will be used by CLM. Currently + ! generic crops will always go on the crop landunit, regardless of whether or not we're + ! using the extra specific crops (so we always run CLM with create_crop_landunit=.true.). + ! When we create a surface dataset WITH the extra specific crops, all crops + ! (including the generic crops) again go on the crop landunit. + + num_natpft = numstdpft - numstdcft + num_cft = numpft - num_natpft + + ! Determine array bounds for arrays of just natural pfts and just crops. Note that + ! these are set up so that they always span 0:numpft, so that there is a 1:1 + ! correspondence between an element in a full 0:numpft array and an element with the + ! same index in either a natpft array or a cft array. + natpft_lb = noveg + natpft_ub = num_natpft + cft_lb = num_natpft+1 + cft_ub = cft_lb + num_cft - 1 + + ! Make sure the array indices have been set up properly, to ensure the 1:1 + ! correspondence mentioned above + if (cft_ub /= numpft) then + write(6,*) 'CFT_UB set up incorrectly: cft_ub, numpft = ', cft_ub, numpft + call abort() + return + end if + ! + ! Set the PFT override values if applicable + ! + pft_override = pft_oride() + presc_cover = .false. + if( zero_out_l )then + call pft_override%InitZeroOut() + presc_cover = .true. + else if ( use_input_pft ) then + call pft_override%InitAllPFTIndex() + if ( .not. all_veg_l )then + if ( pft_override%crop <= 0.0 )then + write(6,*) "Warning: PFT/CFT's are being overridden, but no crop type is being asked for" + end if + if ( pft_override%natveg <= 0.0 )then + write(6,*) "Warning: PFT/CFT's are being overridden, but no natural vegetation type is being asked for" + end if + presc_cover = .false. + else + presc_cover = .true. + end if + end if + + end subroutine mkpftInit + !----------------------------------------------------------------------- + !BOP ! - ! If specific PFT/CFT's are prescribed set them directly + ! !IROUTINE: mkpft ! - if ( use_input_pft )then - do no = 1,ns_o - if (pctlnd_o(no) > 1.0e-6 .and. pctnatveg_o(no) > 1.0e-6) then - pct_nat_pft_o(no,noveg:num_natpft) = pft_override%natpft(noveg:num_natpft) - else - pct_nat_pft_o(no,noveg) = 100._r8 - pct_nat_pft_o(no,noveg+1:) = 0._r8 - end if - if (pctlnd_o(no) > 1.0e-6 .and. pctcrop_o(no) > 1.0e-6) then - pct_cft_o(no,1:num_cft) = pft_override%cft(1:num_cft) - else - pct_cft_o(no,1) = 100._r8 - pct_cft_o(no,2:) = 0._r8 - end if - pctpft_o(no,natpft_lb:natpft_ub) = pct_nat_pft_o(no,0:num_natpft) - pctpft_o(no,cft_lb:cft_ub) = pct_cft_o(no,1:num_cft) - end do - end if - - - ! Error check: percents should sum to 100 for land grid cells, within roundoff - ! Also correct sums so that if they differ slightly from 100, they are corrected to - ! equal 100 more exactly. - - do no = 1,ns_o - wst_sum = 0. - do m = 0, num_natpft - wst_sum = wst_sum + pct_nat_pft_o(no,m) - enddo - if (abs(wst_sum-100._r8) > relerr) then - write (6,*) subname//'error: nat pft = ', & - (pct_nat_pft_o(no,m), m = 0, num_natpft), & - ' do not sum to 100. at no = ',no,' but to ', wst_sum - call abort() - end if - - ! Correct sum so that if it differs slightly from 100, it is corrected to equal - ! 100 more exactly - do m = 1, num_natpft - pct_nat_pft_o(no,m) = pct_nat_pft_o(no,m) * 100._r8 / wst_sum - end do - - wst_sum = 0. - do m = 1, num_cft - wst_sum = wst_sum + pct_cft_o(no,m) - enddo - if (abs(wst_sum-100._r8) > relerr) then - write (6,*) subname//'error: crop cft = ', & - (pct_cft_o(no,m), m = 1, num_cft), & - ' do not sum to 100. at no = ',no,' but to ', wst_sum - call abort() - end if - - ! Correct sum so that if it differs slightly from 100, it is corrected to equal - ! 100 more exactly - do m = 1, num_cft - pct_cft_o(no,m) = pct_cft_o(no,m) * 100._r8 / wst_sum - end do - - end do - - ! Convert % pft as % of grid cell to % pft on the landunit and % of landunit on the - ! grid cell - do no = 1,ns_o - pctnatpft_o(no) = pct_pft_type( pct_nat_pft_o(no,:), pctnatveg_o(no), first_pft_index=natpft_lb ) - pctcft_o(no) = pct_pft_type( pct_cft_o(no,:), pctcrop_o(no), first_pft_index=cft_lb ) - end do - - ! ----------------------------------------------------------------- - ! Error check - ! Compare global areas on input and output grids - ! Only when you aren't prescribing the vegetation coverage everywhere - ! If use_input_pft is set this will compare the global coverage of - ! the prescribed vegetation to the coverage of PFT/CFT's on the input - ! datasets. - ! ----------------------------------------------------------------- - - if ( .not. presc_cover ) then - - ! Convert to pctpft over grid if using new format - do ni = 1, ns_i - pctnatpft_i(ni) = pct_pft_type( pct_nat_pft_i(ni,:), pctnatveg_i(ni), first_pft_index=natpft_lb ) - pctcft_i(ni) = pct_pft_type( pct_cft_i(ni,:), pctcrop_i(ni), first_pft_index=cft_lb ) - end do - - do no = 1,ns_o - pctpft_o(no,natpft_lb:natpft_ub) = pctnatpft_o(no)%get_pct_p2g() - pctpft_o(no,cft_lb:cft_ub) = pctcft_o(no)%get_pct_p2g() - end do - allocate(gpft_i(0:numpft_i-1)) - allocate(gpft_o(0:numpft_i-1)) - - ! input grid - - gpft_i(:) = 0. - garea_i = 0. - do ni = 1,ns_i - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - do m = 0, numpft_i - 1 - gpft_i(m) = gpft_i(m) + pctpft_i(ni,m)*tgridmap%area_src(ni)*& - tdomain%mask(ni)*re**2 - end do - end do - if ( allocated(pctpft_i) ) deallocate (pctpft_i) - - ! output grid - - gpft_o(:) = 0. - garea_o = 0. - do no = 1,ns_o - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - do m = 0, numpft_i - 1 - gpft_o(m) = gpft_o(m) + pctpft_o(no,m)*tgridmap%area_dst(no)*& - frac_dst(no)*re**2 - end do - end do - - ! comparison - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'PFTs Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,1001) -1001 format (1x,'plant type ',20x,' input grid area',' output grid area',/ & - 1x,33x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - do m = 0, numpft_i - 1 - write (ndiag,1002) veg(m), gpft_i(m)*1.e-06/100.,gpft_o(m)*1.e-06/100. - end do -1002 format (1x,a35,f16.3,f17.3) - call shr_sys_flush(ndiag) - - deallocate(gpft_i, gpft_o, frac_dst) - - end if - deallocate( pctnatpft_i ) - deallocate( pctcft_i ) - deallocate(pctpft_o) - - - ! Deallocate dynamic memory - - deallocate(pctnatveg_i) - deallocate(pctnatveg_o) - deallocate(pctcrop_i) - deallocate(pctcrop_o) - deallocate(pct_cft_i) - deallocate(pct_cft_o) - deallocate(pct_nat_pft_i) - deallocate(pct_nat_pft_o) - if ( .not. presc_cover ) then - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - end if - - write (6,*) 'Successfully made PFTs' - write (6,*) - - -end subroutine mkpft - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkpft_parse_oride -! -! !INTERFACE: -subroutine mkpft_parse_oride( string ) -! -! !DESCRIPTION: -! Parse the string with pft fraction and index information on it, to override -! the file with this information rather than reading from a file. -! -! !USES: - use shr_string_mod, only: shr_string_betweenTags, shr_string_countChar -! !ARGUMENTS: - character(len=256), intent(IN) :: string ! String to parse with PFT fraction - ! and index data -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - integer :: rc ! error return code - integer :: num_elms ! number of elements - character(len=256) :: substring ! string between tags - character(len=*), parameter :: frc_start = "" - character(len=*), parameter :: frc_end = "" - character(len=*), parameter :: idx_start = "" - character(len=*), parameter :: idx_end = "" - character(len=*), parameter :: subname = 'mkpft_parse_oride' - !----------------------------------------------------------------------- + ! !INTERFACE: + subroutine mkpft(ldomain, mapfname, fpft, ndiag, & + pctlnd_o, pctnatpft_o, pctcft_o) + ! + ! !DESCRIPTION: + ! Make PFT data + ! + ! This dataset consists of the %cover of the [numpft]+1 PFTs used by + ! the model. The input %cover pertains to the "vegetated" portion of the + ! grid cell and sums to 100. The real portion of each grid cell + ! covered by each PFT is the PFT cover times the fraction of the + ! grid cell that is land. This is the quantity preserved when + ! area-averaging from the input (1/2 degree) grid to the models grid. + ! + ! Upon return from this routine, the % cover of the natural veg + crop landunits is + ! generally 100% everywhere; this will be normalized later to account for special landunits. + ! + ! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio + use mkpctPftTypeMod, only : pct_pft_type + use mkpftConstantsMod, only : natpft_lb, natpft_ub, num_cft, cft_lb, cft_ub + ! + ! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: fpft ! input pft dataset file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: pctlnd_o(:) ! output grid:%land/gridcell + type(pct_pft_type), intent(out):: pctnatpft_o(:) ! natural PFT cover + type(pct_pft_type), intent(out):: pctcft_o(:) ! crop (CFT) cover + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: Mariana Vertenstein + ! + ! + ! !LOCAL VARIABLES: + !EOP + type(pct_pft_type), allocatable:: pctnatpft_i(:) ! input grid: natural PFT cover + type(pct_pft_type), allocatable:: pctcft_i(:) ! input grid: crop (CFT) cover + type(domain_type) :: tdomain ! local domain + type(gridmap_type) :: tgridmap ! local gridmap + real(r8), allocatable :: pctpft_i(:,:) ! input grid: PFT percent + real(r8), allocatable :: pctpft_o(:,:) ! output grid: PFT percent (% of grid cell) + real(r8), allocatable :: pctnatveg_i(:) ! input grid: natural veg percent (% of grid cell) + real(r8), allocatable :: pctnatveg_o(:) ! output grid: natural veg percent (% of grid cell) + real(r8), allocatable :: pctcrop_i(:) ! input grid: all crop percent (% of grid cell) + real(r8), allocatable :: pctcrop_o(:) ! output grid: all crop percent (% of grid cell) + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: pct_cft_i(:,:) ! input grid: CFT (Crop Functional Type) percent (% of landunit cell) + real(r8), allocatable :: temp_i(:,:) ! input grid: temporary 2D variable to read in + real(r8), allocatable :: pct_cft_o(:,:) ! output grid: CFT (Crop Functional Type) percent (% of landunit cell) + real(r8), allocatable :: pct_nat_pft_i(:,:) ! input grid: natural PFT percent (% of landunit cell) + real(r8), allocatable :: pct_nat_pft_o(:,:) ! output grid: natural PFT percent (% of landunit cell) + integer :: numpft_i ! num of plant types input data + integer :: natpft_i ! num of natural plant types input data + integer :: ncft_i ! num of crop types input data + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: wst_sum ! sum of %pft + real(r8), allocatable :: gpft_o(:) ! output grid: global area pfts + real(r8) :: garea_o ! output grid: global area + real(r8), allocatable :: gpft_i(:) ! input grid: global area pfts + real(r8) :: garea_i ! input grid: global area + integer :: k,n,m,ni,no,ns_i,ns_o ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ndims ! number of dimensions for a variable on the file + integer :: dimlens(3) ! dimension lengths for a variable on the file + integer :: ier ! error status + real(r8) :: relerr = 0.0001_r8 ! max error: sum overlap wts ne 1 + logical :: oldformat ! if input file is in the old format or not (based on what variables exist) + logical :: error_happened ! If an error was triggered so should return + + character(len=35) veg(0:maxpft) ! vegetation types + character(len=32) :: subname = 'mkpftMod::mkpft()' + !----------------------------------------------------------------------- + + write (6,*) + write (6, '(a, a, a)') "In ", trim(subname), "..." + write (6,*) 'Attempting to make PFTs .....' + + ! ----------------------------------------------------------------- + ! Set the vegetation types + ! ----------------------------------------------------------------- + if ( numpft >= numstdpft )then + veg(0:maxpft) = (/ & + 'not vegetated ', & + 'needleleaf evergreen temperate tree', & + 'needleleaf evergreen boreal tree ', & + 'needleleaf deciduous boreal tree ', & + 'broadleaf evergreen tropical tree ', & + 'broadleaf evergreen temperate tree ', & + 'broadleaf deciduous tropical tree ', & + 'broadleaf deciduous temperate tree ', & + 'broadleaf deciduous boreal tree ', & + 'broadleaf evergreen shrub ', & + 'broadleaf deciduous temperate shrub', & + 'broadleaf deciduous boreal shrub ', & + 'c3 arctic grass ', & + 'c3 non-arctic grass ', & + 'c4 grass ', & + 'c3_crop ', & + 'c3_irrigated ', & + 'temperate_corn ', & + 'irrigated_temperate_corn ', & + 'spring_wheat ', & + 'irrigated_spring_wheat ', & + 'winter_wheat ', & + 'irrigated_winter_wheat ', & + 'temperate_soybean ', & + 'irrigated_temperate_soybean ', & + 'barley ', & + 'irrigated_barley ', & + 'winter_barley ', & + 'irrigated_winter_barley ', & + 'rye ', & + 'irrigated_rye ', & + 'winter_rye ', & + 'irrigated_winter_rye ', & + 'cassava ', & + 'irrigated_cassava ', & + 'citrus ', & + 'irrigated citrus ', & + 'cocoa ', & + 'irrigated_cocoa ', & + 'coffee ', & + 'irrigated_coffee ', & + 'cotton ', & + 'irrigated_cotton ', & + 'datepalm ', & + 'irrigated_datepalm ', & + 'foddergrass ', & + 'irrigated_foddergrass ', & + 'grapes ', & + 'irrigated_grapes ', & + 'groundnuts ', & + 'irrigated_groundnuts ', & + 'millet ', & + 'irrigated_millet ', & + 'oilpalm ', & + 'irrigated_oilpalm ', & + 'potatoes ', & + 'irrigated_potatoes ', & + 'pulses ', & + 'irrigated_pulses ', & + 'rapeseed ', & + 'irrigated_rapeseed ', & + 'rice ', & + 'irrigated_rice ', & + 'sorghum ', & + 'irrigated_sorghum ', & + 'sugarbeet ', & + 'irrigated_sugarbeet ', & + 'sugarcane ', & + 'irrigated_sugarcane ', & + 'sunflower ', & + 'irrigated_sunflower ', & + 'miscanthus ', & + 'irrigated_miscanthus ', & + 'switchgrass ', & + 'irrigated_switchgrass ', & + 'tropical_corn ', & + 'irrigated_tropical_corn ', & + 'tropical_soybean ', & + 'irrigated_tropical_soybean ' /) + end if + if ( numpft == numstdpft )then + write(6,*)'Creating surface datasets with the standard # of PFTs =', numpft + else if ( numpft > numstdpft )then + write(6,*)'Creating surface datasets with extra types for crops; total pfts =', numpft + else + write(6,*) subname//': parameter numpft is NOT set to a known value (should be 16 or more) =',numpft + call abort() + return + end if - ! NOTE(bja, 2015-02) pft_frc and pft_index can be reset multiple - ! times by calls to this function. If the number of elements being - ! set is different each time, then we are working with out of date - ! information, and the sums may not sum to 100%. - pft_frc = 0.0_r8 - pft_idx = -1 - - call shr_string_betweenTags( string, frc_start, frc_end, substring, rc ) - if ( rc /= 0 )then - write(6,*) subname//'Trouble finding pft_frac start end tags' - call abort() - return - end if - num_elms = shr_string_countChar( substring, ",", rc ) - read(substring,*) pft_frc(0:num_elms) - call shr_string_betweenTags( string, idx_start, idx_end, substring, rc ) - if ( rc /= 0 )then - write(6,*) subname//'Trouble finding pft_index start end tags' - call abort() - return - end if - if ( num_elms /= shr_string_countChar( substring, ",", rc ) )then - write(6,*) subname//'number of elements different between frc and idx fields' - call abort() - return - end if - read(substring,*) pft_idx(0:num_elms) -!----------------------------------------------------------------------- - -end subroutine mkpft_parse_oride - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkpft_check_oride -! -! !INTERFACE: -subroutine mkpft_check_oride( error_happened ) -! -! !DESCRIPTION: -! Check that the pft override values are valid -! !USES: - implicit none -! !ARGUMENTS: - logical, intent(out) :: error_happened ! Result, true if there was a problem -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - integer :: i, j ! indices - real(r8) :: sumpft ! Sum of pft_frc - real(r8), parameter :: hndrd = 100.0_r8 ! A hundred percent - character(len=32) :: subname = 'mkpftMod::mkpft_check_oride() ' -!----------------------------------------------------------------------- - - error_happened = .false. - sumpft = sum(pft_frc) - if ( sumpft == 0.0 )then - ! PFT fraction is NOT used - use_input_pft = .false. - else if ( abs(sumpft - hndrd) > 1.e-6 )then - write(6, '(a, a, f15.12)') trim(subname), 'Sum of PFT fraction is NOT equal to 100% =', sumpft - write(6,*) 'Set PFT fraction to : ', pft_frc(0:nzero) - write(6,*) 'With PFT index : ', pft_idx(0:nzero) - error_happened = .true. - call abort() - return - else - use_input_pft = .true. - nzero = numpft - do i = 0, numpft - if ( pft_frc(i) == 0.0_r8 )then - nzero = i-1 - exit + ns_o = ldomain%ns + + ! ----------------------------------------------------------------- + ! Read input PFT file + ! ----------------------------------------------------------------- + if ( .not. presc_cover ) then + ! Obtain input grid info, read PCT_PFT + + call domain_read(tdomain,fpft) + ns_i = tdomain%ns + + write (6,*) 'Open PFT file: ', trim(fpft) + call check_ret(nf_open(fpft, 0, ncid), subname) + + ! Check what variables exist to determine what format the file is in + call check_ret(nf_inq_varid (ncid, 'PCT_PFT', varid), subname, varexists=oldformat) + + if ( oldformat ) then + write(6,*) subname//' ERROR: PCT_PFT field on the the file so it is in the old format, which is no longer supported' + call abort() + return end if + call check_ret(nf_inq_dimid (ncid, 'natpft', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, natpft_i), subname) + call check_ret(nf_inq_dimid (ncid, 'cft', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, ncft_i), subname) + numpft_i = natpft_i + ncft_i + + ! Check if the number of pfts on the input matches the expected number. A mismatch + ! is okay if the input raw dataset has prognostic crops and the output does not. + if (numpft_i .ne. numpft+1) then + if (numpft_i .eq. numstdpft+1) then + write(6,*) subname//' ERROR: trying to use non-crop input file' + write(6,*) 'for a surface dataset with crops.' + call abort() + return + else if (numpft_i > numstdpft+1 .and. numpft_i == maxpft+1) then + write(6,*) subname//' WARNING: using a crop input raw dataset for a non-crop output surface dataset' + else + write(6,*) subname//': parameter numpft+1= ',numpft+1, & + 'does not equal input dataset numpft= ',numpft_i + call abort() + return + end if + endif + + ! TODO: create a route handle + ! for starts just do everything on one processor to make sure it works + + ! TODO: determine local number of points and allocate memory only for the local number + ! the local number can be determined from the mesh + ! TODO: initialize pio and set global decomposition + + ! If file is in the new format, expect the following variables: + ! PCT_NATVEG, PCT_CROP, PCT_NAT_PFT, PCT_CFT + allocate(pctnatveg_i(ns_i), & + pctnatveg_o(ns_o), & + pctcrop_i(ns_i), & + pctcrop_o(ns_o), & + frac_dst(ns_o), & + pct_cft_i(ns_i,1:num_cft), & + pct_cft_o(ns_o,1:num_cft), & + pct_nat_pft_i(ns_i,0:num_natpft), & + pct_nat_pft_o(ns_o,0:num_natpft), & + stat=ier) + if (ier/=0)then + call abort() + return + end if + + call check_ret(nf_inq_varid (ncid, 'PCT_NATVEG', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, pctnatveg_i), subname) + call check_ret(nf_inq_varid (ncid, 'PCT_CROP', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, pctcrop_i), subname) + if ( .not. use_input_pft )then + call check_ret(nf_inq_varid (ncid, 'PCT_CFT', varid), subname) + call get_dim_lengths(ncid, 'PCT_CFT', ndims, dimlens(:) ) + if ( ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) == num_cft )then + call check_ret(nf_get_var_double (ncid, varid, pct_cft_i), subname) + else if ( ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) > num_cft )then + ! Read in the whole array: then sum the rainfed and irrigated + ! seperately + allocate( temp_i(ns_i,dimlens(3)) ) + call check_ret(nf_get_var_double (ncid, varid, temp_i), subname) + do n = 1, num_cft + pct_cft_i(:,n) = 0.0_r8 + do m = n, dimlens(3), 2 + pct_cft_i(:,n) = pct_cft_i(:,n) + temp_i(:,m) + end do + end do + deallocate( temp_i ) + else + write(6,*) subname//': ERROR: dimensions for PCT_CROP are NOT what is expected' + call abort() + return + end if + call check_ret(nf_inq_varid (ncid, 'PCT_NAT_PFT', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, pct_nat_pft_i), subname) + end if + + call check_ret(nf_close(ncid), subname) + + ! ----------------------------------------------------------------- + ! Otherwise if vegetation is prescribed everywhere + ! ----------------------------------------------------------------- + else + ns_i = 1 + numpft_i = numpft+1 + allocate(pctnatveg_i(ns_i), & + pctnatveg_o(ns_o), & + pctcrop_i(ns_i), & + pctcrop_o(ns_o), & + pct_cft_i(ns_i,1:num_cft), & + pct_cft_o(ns_o,1:num_cft), & + pct_nat_pft_i(ns_i,0:num_natpft), & + pct_nat_pft_o(ns_o,0:num_natpft), & + stat=ier) + if (ier/=0)then + call abort() + return + end if + end if + allocate(pctpft_i(ns_i,0:(numpft_i-1)), & + pctpft_o(ns_o,0:(numpft_i-1)), & + pctnatpft_i(ns_i), & + pctcft_i(ns_i), & + stat=ier) + if (ier/=0)then + call abort() + return + end if + + ! Determine pctpft_o on output grid + + ! If total vegetation cover is prescribed from input... + if ( use_input_pft .and. presc_cover ) then + + do no = 1,ns_o + pctlnd_o(no) = 100._r8 + pctnatveg_o(no) = pft_override%natveg + pctcrop_o(no) = pft_override%crop + end do + + ! otherewise if total cover isn't prescribed read it from the datasets + else + + ! Compute pctlnd_o, pctpft_o + + ! TODO: create a route handle here + call gridmap_mapread(tgridmap, mapfname) + + ! Error checks for domain and map consistencies + ! TODO: remove this check + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Area-average percent cover on input grid [pctpft_i] to output grid + ! [pctpft_o] and correct [pctpft_o] according to land landmask + ! Note that percent cover is in terms of total grid area. + pctlnd_o(:) = frac_dst(:) * 100._r8 + + ! New format with extra variables on input + call gridmap_areaave_srcmask(tgridmap, pctnatveg_i, pctnatveg_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, pctcrop_i, pctcrop_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! + ! If specific PFT/CFT's are NOT prescribed set them from the input file + ! + if ( .not. use_input_pft )then + do m = 0, num_natpft + call gridmap_areaave_scs(tgridmap, pct_nat_pft_i(:,m), & + pct_nat_pft_o(:,m), nodata=0._r8, & + src_wt=pctnatveg_i*0.01_r8*tdomain%mask, & + dst_wt=pctnatveg_o*0.01_r8, frac_dst=frac_dst) + do no = 1,ns_o + if (pctlnd_o(no) < 1.0e-6 .or. pctnatveg_o(no) < 1.0e-6) then + if (m == 0) then + pct_nat_pft_o(no,m) = 100._r8 + else + pct_nat_pft_o(no,m) = 0._r8 + endif + end if + enddo + end do + do m = 1, num_cft + call gridmap_areaave_scs(tgridmap, pct_cft_i(:,m), pct_cft_o(:,m), & + nodata=0._r8, src_wt=pctcrop_i*0.01_r8*tdomain%mask, & + dst_wt=pctcrop_o*0.01_r8, frac_dst=frac_dst) + do no = 1,ns_o + if (pctlnd_o(no) < 1.0e-6 .or. pctcrop_o(no) < 1.0e-6) then + if (m == 1) then + pct_cft_o(no,m) = 100._r8 + else + pct_cft_o(no,m) = 0._r8 + endif + end if + enddo + end do + ! Otherwise do some error checking to make sure specific veg types are given where nat-veg and crop is assigned + else + do no = 1,ns_o + if (pctlnd_o(no) > 1.0e-6 .and. pctnatveg_o(no) > 1.0e-6) then + if ( pft_override%natveg <= 0.0_r8 )then + write(6,*) subname//': ERROR: no natural vegetation PFTs are being prescribed but there are natural '// & + 'vegetation areas: provide at least one natural veg PFT' + call abort() + return + end if + end if + if (pctlnd_o(no) > 1.0e-6 .and. pctcrop_o(no) > 1.0e-6) then + if ( pft_override%crop <= 0.0_r8 )then + write(6,*) subname//': ERROR: no crop CFTs are being prescribed but there are crop areas: provide at least one CFT' + call abort() + return + end if + end if + end do + end if + end if + + ! + ! If specific PFT/CFT's are prescribed set them directly + ! + if ( use_input_pft )then + do no = 1,ns_o + if (pctlnd_o(no) > 1.0e-6 .and. pctnatveg_o(no) > 1.0e-6) then + pct_nat_pft_o(no,noveg:num_natpft) = pft_override%natpft(noveg:num_natpft) + else + pct_nat_pft_o(no,noveg) = 100._r8 + pct_nat_pft_o(no,noveg+1:) = 0._r8 + end if + if (pctlnd_o(no) > 1.0e-6 .and. pctcrop_o(no) > 1.0e-6) then + pct_cft_o(no,1:num_cft) = pft_override%cft(1:num_cft) + else + pct_cft_o(no,1) = 100._r8 + pct_cft_o(no,2:) = 0._r8 + end if + pctpft_o(no,natpft_lb:natpft_ub) = pct_nat_pft_o(no,0:num_natpft) + pctpft_o(no,cft_lb:cft_ub) = pct_cft_o(no,1:num_cft) + end do + end if + + + ! Error check: percents should sum to 100 for land grid cells, within roundoff + ! Also correct sums so that if they differ slightly from 100, they are corrected to + ! equal 100 more exactly. + + do no = 1,ns_o + wst_sum = 0. + do m = 0, num_natpft + wst_sum = wst_sum + pct_nat_pft_o(no,m) + enddo + if (abs(wst_sum-100._r8) > relerr) then + write (6,*) subname//'error: nat pft = ', & + (pct_nat_pft_o(no,m), m = 0, num_natpft), & + ' do not sum to 100. at no = ',no,' but to ', wst_sum + call abort() + end if + + ! Correct sum so that if it differs slightly from 100, it is corrected to equal + ! 100 more exactly + do m = 1, num_natpft + pct_nat_pft_o(no,m) = pct_nat_pft_o(no,m) * 100._r8 / wst_sum + end do + + wst_sum = 0. + do m = 1, num_cft + wst_sum = wst_sum + pct_cft_o(no,m) + enddo + if (abs(wst_sum-100._r8) > relerr) then + write (6,*) subname//'error: crop cft = ', & + (pct_cft_o(no,m), m = 1, num_cft), & + ' do not sum to 100. at no = ',no,' but to ', wst_sum + call abort() + end if + + ! Correct sum so that if it differs slightly from 100, it is corrected to equal + ! 100 more exactly + do m = 1, num_cft + pct_cft_o(no,m) = pct_cft_o(no,m) * 100._r8 / wst_sum + end do + end do - ! PFT fraction IS used, and sum is OK, now check details - do i = 0, nzero - if ( pft_frc(i) < 0.0_r8 .or. pft_frc(i) > hndrd )then - write(6,*) subname//'PFT fraction is out of range: pft_frc=', pft_frc(i) - error_happened = .true. - call abort() - return - else if ( pft_frc(i) > 0.0_r8 .and. pft_idx(i) == -1 )then - write(6,*) subname//'PFT fraction > zero, but index NOT set: pft_idx=', pft_idx(i) - error_happened = .true. - call abort() - return - end if - ! PFT index out of range - if ( pft_idx(i) < 0 .or. pft_idx(i) > numpft )then - write(6,*) subname//'PFT index is out of range: ', pft_idx(i) - error_happened = .true. - call abort() - return - end if - ! Make sure index values NOT used twice - do j = 0, i-1 - if ( pft_idx(i) == pft_idx(j) )then - write(6,*) subname//'Same PFT index is used twice: ', pft_idx(i) - error_happened = .true. - call abort() - return - end if - end do - end do - ! Make sure the rest of the fraction is zero and index are not set as well - do i = nzero+1, numpft - if ( pft_frc(i) /= 0.0_r8 .or. pft_idx(i) /= -1 )then - write(6,*) subname//'After PFT fraction is zeroed out, fraction is non zero, or index set' - error_happened = .true. - call abort() - return - end if + + ! Convert % pft as % of grid cell to % pft on the landunit and % of landunit on the + ! grid cell + do no = 1,ns_o + pctnatpft_o(no) = pct_pft_type( pct_nat_pft_o(no,:), pctnatveg_o(no), first_pft_index=natpft_lb ) + pctcft_o(no) = pct_pft_type( pct_cft_o(no,:), pctcrop_o(no), first_pft_index=cft_lb ) end do - end if - -end subroutine mkpft_check_oride - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkpftAtt -! -! !INTERFACE: -subroutine mkpftAtt( ncid, dynlanduse, xtype ) -! -! !DESCRIPTION: -! make PFT attributes on the output file -! - use mkncdio , only : check_ret, ncd_defvar, ncd_def_spatial_var - use fileutils , only : get_filename - use mkvarctl , only : mksrf_fvegtyp, mksrf_flai - use mkvarpar - -! !ARGUMENTS: - implicit none - include 'netcdf.inc' - integer, intent(in) :: ncid ! NetCDF file ID to write out to - logical, intent(in) :: dynlanduse ! if dynamic land-use file - integer, intent(in) :: xtype ! external type to output real data as -! -! !CALLED FROM: -! subroutine mkfile in module mkfileMod -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - integer :: pftsize ! size of lsmpft dimension - integer :: natpftsize ! size of natpft dimension - integer :: dimid ! input netCDF id's - character(len=256) :: str ! global attribute string - character(len=32) :: subname = 'mkpftAtt' - - ! Define dimensions - call check_ret(nf_def_dim (ncid, 'time' , nf_unlimited, dimid), subname) - - if (.not. dynlanduse) then - pftsize = numpft + 1 - call check_ret(nf_def_dim (ncid, 'lsmpft' , pftsize , dimid), subname) - end if - - natpftsize = num_natpft + 1 - call check_ret(nf_def_dim (ncid, 'natpft' , natpftsize , dimid), subname) - - ! zero-size dimensions can cause problems, so we only include the cft dimension if num_cft > 0 - ! Note that this implies that we can only include PCT_CFT on the dataset if num_cft > 0 - if (num_cft > 0) then - call check_ret(nf_def_dim (ncid, 'cft' , num_cft , dimid), subname) - end if - - ! Add global attributes - - if (.not. dynlanduse) then - str = get_filename(mksrf_flai) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & + + ! ----------------------------------------------------------------- + ! Error check + ! Compare global areas on input and output grids + ! Only when you aren't prescribing the vegetation coverage everywhere + ! If use_input_pft is set this will compare the global coverage of + ! the prescribed vegetation to the coverage of PFT/CFT's on the input + ! datasets. + ! ----------------------------------------------------------------- + + if ( .not. presc_cover ) then + + ! Convert to pctpft over grid if using new format + do ni = 1, ns_i + pctnatpft_i(ni) = pct_pft_type( pct_nat_pft_i(ni,:), pctnatveg_i(ni), first_pft_index=natpft_lb ) + pctcft_i(ni) = pct_pft_type( pct_cft_i(ni,:), pctcrop_i(ni), first_pft_index=cft_lb ) + end do + + do no = 1,ns_o + pctpft_o(no,natpft_lb:natpft_ub) = pctnatpft_o(no)%get_pct_p2g() + pctpft_o(no,cft_lb:cft_ub) = pctcft_o(no)%get_pct_p2g() + end do + allocate(gpft_i(0:numpft_i-1)) + allocate(gpft_o(0:numpft_i-1)) + + ! input grid + + gpft_i(:) = 0. + garea_i = 0. + do ni = 1,ns_i + garea_i = garea_i + tgridmap%area_src(ni)*re**2 + do m = 0, numpft_i - 1 + gpft_i(m) = gpft_i(m) + pctpft_i(ni,m)*tgridmap%area_src(ni)*& + tdomain%mask(ni)*re**2 + end do + end do + if ( allocated(pctpft_i) ) deallocate (pctpft_i) + + ! output grid + + gpft_o(:) = 0. + garea_o = 0. + do no = 1,ns_o + garea_o = garea_o + tgridmap%area_dst(no)*re**2 + do m = 0, numpft_i - 1 + gpft_o(m) = gpft_o(m) + pctpft_o(no,m)*tgridmap%area_dst(no)*& + frac_dst(no)*re**2 + end do + end do + + ! comparison + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'PFTs Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,1001) +1001 format (1x,'plant type ',20x,' input grid area',' output grid area',/ & + 1x,33x,' 10**6 km**2',' 10**6 km**2') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + do m = 0, numpft_i - 1 + write (ndiag,1002) veg(m), gpft_i(m)*1.e-06/100.,gpft_o(m)*1.e-06/100. + end do +1002 format (1x,a35,f16.3,f17.3) + + deallocate(gpft_i, gpft_o, frac_dst) + + end if + deallocate( pctnatpft_i ) + deallocate( pctcft_i ) + deallocate(pctpft_o) + + + ! Deallocate dynamic memory + + deallocate(pctnatveg_i) + deallocate(pctnatveg_o) + deallocate(pctcrop_i) + deallocate(pctcrop_o) + deallocate(pct_cft_i) + deallocate(pct_cft_o) + deallocate(pct_nat_pft_i) + deallocate(pct_nat_pft_o) + if ( .not. presc_cover ) then + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + end if + + write (6,*) 'Successfully made PFTs' + write (6,*) + + + end subroutine mkpft + + !----------------------------------------------------------------------- + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mkpft_parse_oride + ! + ! !INTERFACE: + subroutine mkpft_parse_oride( string ) + ! + ! !DESCRIPTION: + ! Parse the string with pft fraction and index information on it, to override + ! the file with this information rather than reading from a file. + ! + ! !USES: + use shr_string_mod, only: shr_string_betweenTags, shr_string_countChar + ! !ARGUMENTS: + character(len=256), intent(IN) :: string ! String to parse with PFT fraction + ! and index data + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: Erik Kluzek + ! + ! + ! !LOCAL VARIABLES: + !EOP + integer :: rc ! error return code + integer :: num_elms ! number of elements + character(len=256) :: substring ! string between tags + character(len=*), parameter :: frc_start = "" + character(len=*), parameter :: frc_end = "" + character(len=*), parameter :: idx_start = "" + character(len=*), parameter :: idx_end = "" + character(len=*), parameter :: subname = 'mkpft_parse_oride' + !----------------------------------------------------------------------- + + ! NOTE(bja, 2015-02) pft_frc and pft_index can be reset multiple + ! times by calls to this function. If the number of elements being + ! set is different each time, then we are working with out of date + ! information, and the sums may not sum to 100%. + pft_frc = 0.0_r8 + pft_idx = -1 + + call shr_string_betweenTags( string, frc_start, frc_end, substring, rc ) + if ( rc /= 0 )then + write(6,*) subname//'Trouble finding pft_frac start end tags' + call abort() + return + end if + num_elms = shr_string_countChar( substring, ",", rc ) + read(substring,*) pft_frc(0:num_elms) + call shr_string_betweenTags( string, idx_start, idx_end, substring, rc ) + if ( rc /= 0 )then + write(6,*) subname//'Trouble finding pft_index start end tags' + call abort() + return + end if + if ( num_elms /= shr_string_countChar( substring, ",", rc ) )then + write(6,*) subname//'number of elements different between frc and idx fields' + call abort() + return + end if + read(substring,*) pft_idx(0:num_elms) + !----------------------------------------------------------------------- + + end subroutine mkpft_parse_oride + + !----------------------------------------------------------------------- + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mkpft_check_oride + ! + ! !INTERFACE: + subroutine mkpft_check_oride( error_happened ) + ! + ! !DESCRIPTION: + ! Check that the pft override values are valid + ! !USES: + implicit none + ! !ARGUMENTS: + logical, intent(out) :: error_happened ! Result, true if there was a problem + ! + ! !REVISION HISTORY: + ! Author: Erik Kluzek + ! + ! + ! !LOCAL VARIABLES: + !EOP + integer :: i, j ! indices + real(r8) :: sumpft ! Sum of pft_frc + real(r8), parameter :: hndrd = 100.0_r8 ! A hundred percent + character(len=32) :: subname = 'mkpftMod::mkpft_check_oride() ' + !----------------------------------------------------------------------- + + error_happened = .false. + sumpft = sum(pft_frc) + if ( sumpft == 0.0 )then + ! PFT fraction is NOT used + use_input_pft = .false. + else if ( abs(sumpft - hndrd) > 1.e-6 )then + write(6, '(a, a, f15.12)') trim(subname), 'Sum of PFT fraction is NOT equal to 100% =', sumpft + write(6,*) 'Set PFT fraction to : ', pft_frc(0:nzero) + write(6,*) 'With PFT index : ', pft_idx(0:nzero) + error_happened = .true. + call abort() + return + else + use_input_pft = .true. + nzero = numpft + do i = 0, numpft + if ( pft_frc(i) == 0.0_r8 )then + nzero = i-1 + exit + end if + end do + ! PFT fraction IS used, and sum is OK, now check details + do i = 0, nzero + if ( pft_frc(i) < 0.0_r8 .or. pft_frc(i) > hndrd )then + write(6,*) subname//'PFT fraction is out of range: pft_frc=', pft_frc(i) + error_happened = .true. + call abort() + return + else if ( pft_frc(i) > 0.0_r8 .and. pft_idx(i) == -1 )then + write(6,*) subname//'PFT fraction > zero, but index NOT set: pft_idx=', pft_idx(i) + error_happened = .true. + call abort() + return + end if + ! PFT index out of range + if ( pft_idx(i) < 0 .or. pft_idx(i) > numpft )then + write(6,*) subname//'PFT index is out of range: ', pft_idx(i) + error_happened = .true. + call abort() + return + end if + ! Make sure index values NOT used twice + do j = 0, i-1 + if ( pft_idx(i) == pft_idx(j) )then + write(6,*) subname//'Same PFT index is used twice: ', pft_idx(i) + error_happened = .true. + call abort() + return + end if + end do + end do + ! Make sure the rest of the fraction is zero and index are not set as well + do i = nzero+1, numpft + if ( pft_frc(i) /= 0.0_r8 .or. pft_idx(i) /= -1 )then + write(6,*) subname//'After PFT fraction is zeroed out, fraction is non zero, or index set' + error_happened = .true. + call abort() + return + end if + end do + end if + + end subroutine mkpft_check_oride + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mkpftAtt + ! + ! !INTERFACE: + subroutine mkpftAtt( ncid, dynlanduse, xtype ) + ! + ! !DESCRIPTION: + ! make PFT attributes on the output file + ! + use mkncdio , only : check_ret, ncd_defvar, ncd_def_spatial_var + use fileutils , only : get_filename + use mkvarctl , only : mksrf_fvegtyp, mksrf_flai + use mkvarpar + + ! !ARGUMENTS: + implicit none + include 'netcdf.inc' + integer, intent(in) :: ncid ! NetCDF file ID to write out to + logical, intent(in) :: dynlanduse ! if dynamic land-use file + integer, intent(in) :: xtype ! external type to output real data as + ! + ! !CALLED FROM: + ! subroutine mkfile in module mkfileMod + ! + ! !REVISION HISTORY: + ! Author: Erik Kluzek + ! + ! + ! !LOCAL VARIABLES: + !EOP + integer :: pftsize ! size of lsmpft dimension + integer :: natpftsize ! size of natpft dimension + integer :: dimid ! input netCDF id's + character(len=256) :: str ! global attribute string + character(len=32) :: subname = 'mkpftAtt' + + ! Define dimensions + call check_ret(nf_def_dim (ncid, 'time' , nf_unlimited, dimid), subname) + + if (.not. dynlanduse) then + pftsize = numpft + 1 + call check_ret(nf_def_dim (ncid, 'lsmpft' , pftsize , dimid), subname) + end if + + natpftsize = num_natpft + 1 + call check_ret(nf_def_dim (ncid, 'natpft' , natpftsize , dimid), subname) + + ! zero-size dimensions can cause problems, so we only include the cft dimension if num_cft > 0 + ! Note that this implies that we can only include PCT_CFT on the dataset if num_cft > 0 + if (num_cft > 0) then + call check_ret(nf_def_dim (ncid, 'cft' , num_cft , dimid), subname) + end if + + ! Add global attributes + + if (.not. dynlanduse) then + str = get_filename(mksrf_flai) + call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & 'Lai_raw_data_file_name', len_trim(str), trim(str)), subname) - end if - - if ( use_input_pft ) then - str = 'TRUE' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'pft_override', len_trim(str), trim(str)), subname) - else - str = get_filename(mksrf_fvegtyp) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Vegetation_type_raw_data_filename', len_trim(str), trim(str)), subname) - end if - - ! Define variables - - ! Coordinate variable for indices of natural PFTs - call ncd_defvar(ncid=ncid, varname='natpft', xtype=nf_int, & - dim1name='natpft', long_name='indices of natural PFTs', units='index') - - ! Coordinate variable for indices of CFTs - if (num_cft > 0) then - call ncd_defvar(ncid=ncid, varname='cft', xtype=nf_int, & - dim1name='cft', long_name='indices of CFTs', units='index') - end if - - call ncd_def_spatial_var(ncid=ncid, varname='LANDFRAC_PFT', xtype=nf_double, & - long_name='land fraction from pft dataset', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PFTDATA_MASK', xtype=nf_int, & - long_name='land mask from pft dataset, indicative of real/fake points', units='unitless') - - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='PCT_NATVEG', xtype=xtype, & - long_name='total percent natural vegetation landunit', units='unitless') - end if - - ! PCT_CROP - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CROP', xtype=xtype, & - long_name='total percent crop landunit', units='unitless') - else - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CROP', xtype=xtype, & - lev1name='time', & - long_name='total percent crop landunit', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CROP_MAX', xtype=xtype, & - long_name='maximum total percent crop landunit during time period', units='unitless') - end if - - ! PCT_NAT_PFT - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='PCT_NAT_PFT', xtype=xtype, & - lev1name='natpft', & - long_name='percent plant functional type on the natural veg landunit (% of landunit)', units='unitless') - else - call ncd_def_spatial_var(ncid=ncid, varname='PCT_NAT_PFT', xtype=xtype, & - lev1name='natpft', lev2name='time', & - long_name='percent plant functional type on the natural veg landunit (% of landunit)', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='PCT_NAT_PFT_MAX', xtype=xtype, & - lev1name='natpft', & - long_name='maximum percent plant functional type during time period (% of landunit)', units='unitless') - end if - - ! PCT_CFT - if (num_cft > 0) then - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CFT', xtype=xtype, & - lev1name='cft', & - long_name='percent crop functional type on the crop landunit (% of landunit)', units='unitless') - else - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CFT', xtype=xtype, & - lev1name='cft', lev2name='time', & - long_name='percent crop functional type on the crop landunit (% of landunit)', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CFT_MAX', xtype=xtype, & - lev1name='cft', & - long_name='maximum percent crop functional type during time period (% of landunit)', units='unitless') - end if - end if - - ! LAI,SAI,HTOP,HBOT - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_LAI', xtype=xtype, & - lev1name='lsmpft', lev2name='time', & - long_name='monthly leaf area index', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_SAI', xtype=xtype, & - lev1name='lsmpft', lev2name='time', & - long_name='monthly stem area index', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_HEIGHT_TOP', xtype=xtype, & - lev1name='lsmpft', lev2name='time', & - long_name='monthly height top', units='meters') - - call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_HEIGHT_BOT', xtype=xtype, & - lev1name='lsmpft', lev2name='time', & - long_name='monthly height bottom', units='meters') - end if - - ! OTHER - if (dynlanduse) then - call ncd_defvar(ncid=ncid, varname='YEAR', xtype=nf_int, & + end if + + if ( use_input_pft ) then + str = 'TRUE' + call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & + 'pft_override', len_trim(str), trim(str)), subname) + else + str = get_filename(mksrf_fvegtyp) + call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & + 'Vegetation_type_raw_data_filename', len_trim(str), trim(str)), subname) + end if + + ! Define variables + + ! Coordinate variable for indices of natural PFTs + call ncd_defvar(ncid=ncid, varname='natpft', xtype=nf_int, & + dim1name='natpft', long_name='indices of natural PFTs', units='index') + + ! Coordinate variable for indices of CFTs + if (num_cft > 0) then + call ncd_defvar(ncid=ncid, varname='cft', xtype=nf_int, & + dim1name='cft', long_name='indices of CFTs', units='index') + end if + + call ncd_def_spatial_var(ncid=ncid, varname='LANDFRAC_PFT', xtype=nf_double, & + long_name='land fraction from pft dataset', units='unitless') + + call ncd_def_spatial_var(ncid=ncid, varname='PFTDATA_MASK', xtype=nf_int, & + long_name='land mask from pft dataset, indicative of real/fake points', units='unitless') + + if (.not. dynlanduse) then + call ncd_def_spatial_var(ncid=ncid, varname='PCT_NATVEG', xtype=xtype, & + long_name='total percent natural vegetation landunit', units='unitless') + end if + + ! PCT_CROP + if (.not. dynlanduse) then + call ncd_def_spatial_var(ncid=ncid, varname='PCT_CROP', xtype=xtype, & + long_name='total percent crop landunit', units='unitless') + else + call ncd_def_spatial_var(ncid=ncid, varname='PCT_CROP', xtype=xtype, & + lev1name='time', & + long_name='total percent crop landunit', units='unitless') + call ncd_def_spatial_var(ncid=ncid, varname='PCT_CROP_MAX', xtype=xtype, & + long_name='maximum total percent crop landunit during time period', units='unitless') + end if + + ! PCT_NAT_PFT + if (.not. dynlanduse) then + call ncd_def_spatial_var(ncid=ncid, varname='PCT_NAT_PFT', xtype=xtype, & + lev1name='natpft', & + long_name='percent plant functional type on the natural veg landunit (% of landunit)', units='unitless') + else + call ncd_def_spatial_var(ncid=ncid, varname='PCT_NAT_PFT', xtype=xtype, & + lev1name='natpft', lev2name='time', & + long_name='percent plant functional type on the natural veg landunit (% of landunit)', units='unitless') + call ncd_def_spatial_var(ncid=ncid, varname='PCT_NAT_PFT_MAX', xtype=xtype, & + lev1name='natpft', & + long_name='maximum percent plant functional type during time period (% of landunit)', units='unitless') + end if + + ! PCT_CFT + if (num_cft > 0) then + if (.not. dynlanduse) then + call ncd_def_spatial_var(ncid=ncid, varname='PCT_CFT', xtype=xtype, & + lev1name='cft', & + long_name='percent crop functional type on the crop landunit (% of landunit)', units='unitless') + else + call ncd_def_spatial_var(ncid=ncid, varname='PCT_CFT', xtype=xtype, & + lev1name='cft', lev2name='time', & + long_name='percent crop functional type on the crop landunit (% of landunit)', units='unitless') + call ncd_def_spatial_var(ncid=ncid, varname='PCT_CFT_MAX', xtype=xtype, & + lev1name='cft', & + long_name='maximum percent crop functional type during time period (% of landunit)', units='unitless') + end if + end if + + ! LAI,SAI,HTOP,HBOT + if (.not. dynlanduse) then + call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_LAI', xtype=xtype, & + lev1name='lsmpft', lev2name='time', & + long_name='monthly leaf area index', units='unitless') + + call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_SAI', xtype=xtype, & + lev1name='lsmpft', lev2name='time', & + long_name='monthly stem area index', units='unitless') + + call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_HEIGHT_TOP', xtype=xtype, & + lev1name='lsmpft', lev2name='time', & + long_name='monthly height top', units='meters') + + call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_HEIGHT_BOT', xtype=xtype, & + lev1name='lsmpft', lev2name='time', & + long_name='monthly height bottom', units='meters') + end if + + ! OTHER + if (dynlanduse) then + call ncd_defvar(ncid=ncid, varname='YEAR', xtype=nf_int, & dim1name='time', & long_name='Year of PFT data', units='unitless') - call ncd_defvar(ncid=ncid, varname='time', xtype=nf_int, & + call ncd_defvar(ncid=ncid, varname='time', xtype=nf_int, & dim1name='time', & long_name='year', units='unitless') - call ncd_defvar(ncid=ncid, varname='input_pftdata_filename', xtype=nf_char, & + call ncd_defvar(ncid=ncid, varname='input_pftdata_filename', xtype=nf_char, & dim1name='nchar', & dim2name='time', & long_name='Input filepath for PFT values for this year', units='unitless') - else - call ncd_defvar(ncid=ncid, varname='time', xtype=nf_int, & + else + call ncd_defvar(ncid=ncid, varname='time', xtype=nf_int, & dim1name='time', & long_name='Calendar month', units='month') - end if - -end subroutine mkpftAtt - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: constructor -! -! !INTERFACE: -function constructor( ) result(this) -! -! !DESCRIPTION: -! Construct a new PFT override object -! -! !ARGUMENTS: - implicit none - type(pft_oride) :: this -!EOP - character(len=32) :: subname = 'mkpftMod::constructor() ' - - this%crop = -1.0_r8 - this%natveg = -1.0_r8 - if ( num_natpft < 0 )then - write(6,*) subname//'num_natpft is NOT set = ', num_natpft - call abort() - return - end if - if ( num_cft < 0 )then - write(6,*) subname//'num_cft is NOT set = ', num_cft - call abort() - return - end if - allocate( this%natpft(noveg:num_natpft) ) - allocate( this%cft(1:num_cft) ) - this%natpft(:) = -1.0_r8 - this%cft(:) = -1.0_r8 - call this%InitZeroOut() -end function constructor - - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: InitZeroOut -! -! !INTERFACE: -subroutine InitZeroOut( this ) -! -! !DESCRIPTION: -! Initialize a pft_oride object with vegetation that's zeroed out -! -! !ARGUMENTS: - implicit none - class(pft_oride), intent(inout) :: this -!EOP - this%crop = 0.0_r8 - this%natveg = 0.0_r8 - - this%natpft = 0.0_r8 - this%natpft(noveg) = 100.0_r8 - this%cft = 0.0_r8 - this%cft(1) = 100.0_r8 -end subroutine InitZeroOut - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: InitZeroOut -! -! !INTERFACE: -subroutine InitAllPFTIndex( this ) -! -! !DESCRIPTION: -! Initialize a pft_oride object with vegetation that's zeroed out -! -! !ARGUMENTS: - implicit none - class(pft_oride), intent(inout) :: this -!EOP - integer :: m, i ! Indices - real(r8) :: croptot ! Total of crop - real(r8) :: natvegtot ! Total of natural vegetation - character(len=32) :: subname = 'mkpftMod::coInitAllPFTIndex() ' - - croptot = 0.0_r8 - natvegtot = 0.0_r8 - this%natpft = 0.0_r8 - this%cft = 0.0_r8 - do m = noveg, nzero - i = pft_idx(m) - if ( (i < noveg) .or. (i > numpft) )then - write(6,*) subname//'PFT index is out of valid range' - call abort() - return - else if ( i <= num_natpft )then - this%natpft(i) = pft_frc(m) - natvegtot = natvegtot + pft_frc(m) - else - this%cft(i-num_natpft) = pft_frc(m) - croptot = croptot + pft_frc(m) end if - end do - this%crop = croptot - this%natveg = natvegtot - ! Renormalize - if ( natvegtot > 0.0_r8 )then - this%natpft = 100.0_r8 * this%natpft / natvegtot - else + + end subroutine mkpftAtt + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: constructor + ! + ! !INTERFACE: + function constructor( ) result(this) + ! + ! !DESCRIPTION: + ! Construct a new PFT override object + ! + ! !ARGUMENTS: + implicit none + type(pft_oride) :: this + !EOP + character(len=32) :: subname = 'mkpftMod::constructor() ' + + this%crop = -1.0_r8 + this%natveg = -1.0_r8 + if ( num_natpft < 0 )then + write(6,*) subname//'num_natpft is NOT set = ', num_natpft + call abort() + return + end if + if ( num_cft < 0 )then + write(6,*) subname//'num_cft is NOT set = ', num_cft + call abort() + return + end if + allocate( this%natpft(noveg:num_natpft) ) + allocate( this%cft(1:num_cft) ) + this%natpft(:) = -1.0_r8 + this%cft(:) = -1.0_r8 + call this%InitZeroOut() + end function constructor + + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: InitZeroOut + ! + ! !INTERFACE: + subroutine InitZeroOut( this ) + ! + ! !DESCRIPTION: + ! Initialize a pft_oride object with vegetation that's zeroed out + ! + ! !ARGUMENTS: + implicit none + class(pft_oride), intent(inout) :: this + !EOP + this%crop = 0.0_r8 + this%natveg = 0.0_r8 + + this%natpft = 0.0_r8 this%natpft(noveg) = 100.0_r8 - end if - if (croptot > 0.0_r8 )then - this%cft = 100.0_r8 * this%cft / croptot - else - this%cft(1) = 100.0_r8 - end if - -end subroutine InitAllPFTIndex - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: clean -! -! !INTERFACE: -subroutine Clean( this ) -! -! !DESCRIPTION: -! Clean up a PFT Oride object -! -! !ARGUMENTS: - implicit none - class(pft_oride), intent(inout) :: this -!EOP - this%crop = -1.0_r8 - this%natveg = -1.0_r8 - deallocate( this%natpft ) - deallocate( this%cft ) + this%cft = 0.0_r8 + this%cft(1) = 100.0_r8 + end subroutine InitZeroOut + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: InitZeroOut + ! + ! !INTERFACE: + subroutine InitAllPFTIndex( this ) + ! + ! !DESCRIPTION: + ! Initialize a pft_oride object with vegetation that's zeroed out + ! + ! !ARGUMENTS: + implicit none + class(pft_oride), intent(inout) :: this + !EOP + integer :: m, i ! Indices + real(r8) :: croptot ! Total of crop + real(r8) :: natvegtot ! Total of natural vegetation + character(len=32) :: subname = 'mkpftMod::coInitAllPFTIndex() ' + + croptot = 0.0_r8 + natvegtot = 0.0_r8 + this%natpft = 0.0_r8 + this%cft = 0.0_r8 + do m = noveg, nzero + i = pft_idx(m) + if ( (i < noveg) .or. (i > numpft) )then + write(6,*) subname//'PFT index is out of valid range' + call abort() + return + else if ( i <= num_natpft )then + this%natpft(i) = pft_frc(m) + natvegtot = natvegtot + pft_frc(m) + else + this%cft(i-num_natpft) = pft_frc(m) + croptot = croptot + pft_frc(m) + end if + end do + this%crop = croptot + this%natveg = natvegtot + ! Renormalize + if ( natvegtot > 0.0_r8 )then + this%natpft = 100.0_r8 * this%natpft / natvegtot + else + this%natpft(noveg) = 100.0_r8 + end if + if (croptot > 0.0_r8 )then + this%cft = 100.0_r8 * this%cft / croptot + else + this%cft(1) = 100.0_r8 + end if -end subroutine Clean + end subroutine InitAllPFTIndex -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: clean + ! + ! !INTERFACE: + subroutine Clean( this ) + ! + ! !DESCRIPTION: + ! Clean up a PFT Oride object + ! + ! !ARGUMENTS: + implicit none + class(pft_oride), intent(inout) :: this + !EOP + this%crop = -1.0_r8 + this%natveg = -1.0_r8 + deallocate( this%natpft ) + deallocate( this%cft ) + + end subroutine Clean + + !----------------------------------------------------------------------- end module mkpftMod diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 89fe454c89..79f8086b8b 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -2,14 +2,17 @@ module mkpioMod use ESMF ! TODO: put in only statements use pio ! TODO: put in only statements - use shr_kind_mod , only : r8 => shr_kind_r8, cl => shr_kind_cl, cs => shr_kind_cs + use shr_kind_mod , only : r8 => shr_kind_r8, cl => shr_kind_cl, cs => shr_kind_cs, r4 => shr_kind_r4 use shr_sys_mod , only : shr_sys_abort use mkutilsMod , only : chkerr - use mkvarctl , only : root_task, ndiag + use mkvarctl , only : root_task, ndiag, mpicom implicit none private +#include + + public :: mkpio_get_rawdata public :: mkpio_iodesc_rawdata public :: mkpio_iodesc_output public :: mkpio_wopen @@ -32,9 +35,9 @@ module mkpioMod module procedure mkpio_put_time_slice_2d end interface mkpio_put_time_slice - integer, public :: pio_iotype - integer, public :: pio_ioformat - type(iosystem_desc_t), pointer, public :: io_subsystem + integer , public :: pio_iotype + integer , public :: pio_ioformat + type(iosystem_desc_t) , public :: pio_iosystem character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -43,6 +46,59 @@ module mkpioMod contains !=============================================================== + subroutine mkpio_get_rawdata(filename, varname, mesh_i, data_i, rc) + + ! input/output variables + character(len=*) , intent(in) :: filename ! file name of rawdata file + character(len=*) , intent(in) :: varname ! field name in rawdata file + type(ESMF_Mesh) , intent(in) :: mesh_i + real(r8) , intent(inout) :: data_i(:) ! input raw data + integer , intent(out) :: rc + + ! local variables + type(file_desc_t) :: pioid + type(var_desc_t) :: pio_varid + type(io_desc_t) :: pio_iodesc + integer :: pio_vartype + real(r4), allocatable :: data_real(:) + real(r8), allocatable :: data_double(:) + real(r8), pointer :: dataptr(:) + integer :: lsize + integer :: rcode + character(len=*), parameter :: subname = 'mklakwat' + !------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Get data_i - Read in varname from filename + lsize = size(data_i) + call ESMF_VMLogMemInfo("Before pio_openfile in regrid_data for "//trim(filename)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(filename), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile in regrid_data") + call ESMF_VMLogMemInfo("After field get") + call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_iodesc in regrid_data") + if (pio_vartype == PIO_REAL) then + allocate(data_real(lsize)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real, rcode) + data_i(:) = real(data_real(:), kind=r8) + deallocate(data_real) + else if (pio_vartype == PIO_DOUBLE) then + allocate(data_double(lsize)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double, rcode) + data_i(:) = data_double(:) + deallocate(data_double) + else + call shr_sys_abort(subName//"ERROR: only real and double types are supported") + end if + call pio_closefile(pioid) + call pio_freedecomp(pioid, pio_iodesc) + call ESMF_VMLogMemInfo("After pio_read_darry in regrid_data") + + end subroutine mkpio_get_rawdata + + !=============================================================== subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, pio_iodesc, rc) ! Determine pio io descriptor for variable on rawdata file @@ -69,11 +125,12 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, rc = ESMF_SUCCESS - if (root_task) then - write(ndiag,'(a,i8, i8)') 'setting iodesc for : '//trim(varname)// & - ' with dimlens(1), dimlens2 = ',dimlens(1),dimlens(2) - end if + !if (root_task) then + !write(ndiag,'(a,i8, i8)') 'setting iodesc for : '//trim(varname)// & + !' with dimlens(1), dimlens2 = ',dimlens(1),dimlens(2) + !end if + call ESMF_VMLogMemInfo("Beginning setting compdof") call ESMF_MeshGet(mesh, elementdistGrid=distGrid, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_DistGridGet(distGrid, localDe=0, elementCount=lsize, rc=rc) @@ -81,25 +138,31 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, allocate(compdof(lsize)) call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=compdof, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("Ending setting compdof") ! get pio variable id, type and number of dimensions + call ESMF_VMLogMemInfo("Beginning getting variable id") + call PIO_seterrorhandling(pioid, PIO_BCAST_ERROR) rcode = pio_inq_varid(pioid, trim(varname), pio_varid) rcode = pio_inq_vartype(pioid, pio_varid, pio_vartype) rcode = pio_inq_varndims(pioid, pio_varid, ndims) + call ESMF_VMLogMemInfo("Ending getting variable id") ! get variable dimension sizes + call ESMF_VMLogMemInfo("Beginning getting dims") allocate(dimids(ndims)) allocate(dimlens(ndims)) rcode = pio_inq_vardimid(pioid, pio_varid, dimids(1:ndims)) do n = 1, ndims rcode = pio_inq_dimlen(pioid, dimids(n), dimlens(n)) end do + call ESMF_VMLogMemInfo("End getting dims") ! determine io descriptor for this variable if (ndims == 1) then - call pio_initdecomp(io_subsystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) else if (ndims == 2) then - call pio_initdecomp(io_subsystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) else call shr_sys_abort('rawdata input must have ndims either 1 or 2') end if @@ -110,37 +173,33 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, end subroutine mkpio_iodesc_rawdata !=============================================================================== - logical function mkpio_file_exists(vm, filename) + logical function mkpio_file_exists(filename) !--------------- ! inquire if i/o file exists !--------------- ! input/output variables - type(ESMF_VM) , intent(in) :: vm character(len=*) , intent(in) :: filename ! local variables integer :: tmp(1) - integer :: rc + integer :: ier !------------------------------------------------------------------------------- tmp(1) = 0 - mkpio_file_exists = .false. if (root_task) then inquire(file=trim(filename), exist=mkpio_file_exists) if (mkpio_file_exists) tmp(1) = 1 end if - call ESMF_VMBroadCast(vm, tmp, 1, 0, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if(tmp(1) == 1) mkpio_file_exists = .true. + call mpi_bcast(tmp(1), 1, MPI_INTEGER, 0, mpicom, ier) + if (tmp(1) == 1) mkpio_file_exists = .true. end function mkpio_file_exists !=============================================================================== - subroutine mkpio_wopen(pioid, filename, vm, clobber) + subroutine mkpio_wopen(pioid, filename, clobber) !--------------- ! open netcdf file @@ -154,43 +213,39 @@ subroutine mkpio_wopen(pioid, filename, vm, clobber) ! input/output arguments type(file_desc_t) , intent(inout) :: pioid character(len=*) , intent(in) :: filename - type(ESMF_VM) , intent(in) :: vm logical , intent(in) :: clobber ! local variables - integer :: rcode - integer :: nmode - integer :: rc - character(len=CL) :: wfilename + integer :: rcode + integer :: nmode character(*),parameter :: subName = '(mkpio_wopen) ' !------------------------------------------------------------------------------- ! filename not open - wfilename = trim(filename) + call ESMF_LogWrite("opening output file "//trim(filename), ESMF_LOGMSG_INFO) - if (mkpio_file_exists(vm, filename)) then + if (mkpio_file_exists(filename)) then if (clobber) then nmode = pio_clobber ! only applies to classic NETCDF files. if(pio_iotype == PIO_IOTYPE_NETCDF .or. pio_iotype == PIO_IOTYPE_PNETCDF) then nmode = ior(nmode,pio_ioformat) endif - rcode = pio_createfile(io_subsystem, pioid, pio_iotype, trim(filename), nmode) + rcode = pio_createfile(pio_iosystem, pioid, pio_iotype, trim(filename), nmode) if (root_task) write(ndiag,'(a)') trim(subname)//' creating file '//trim(filename) else - rcode = pio_openfile(io_subsystem, pioid, pio_iotype, trim(filename), pio_write) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(filename), pio_write) if (root_task) write(ndiag,'(a)') trim(subname)//' opening file '//trim(filename) - call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) endif else - nmode = pio_noclobber ! only applies to classic NETCDF files. - if(pio_iotype == PIO_IOTYPE_NETCDF .or. pio_iotype == PIO_IOTYPE_PNETCDF) then + if (pio_iotype == PIO_IOTYPE_NETCDF .or. pio_iotype == PIO_IOTYPE_PNETCDF) then nmode = ior(nmode,pio_ioformat) endif - rcode = pio_createfile(io_subsystem, pioid, pio_iotype, trim(filename), nmode) + rcode = pio_createfile(pio_iosystem, pioid, pio_iotype, trim(filename), nmode) if (root_task) write(ndiag,'(a)') trim(subname) //' creating file '// trim(filename) endif + call ESMF_LogWrite("successfully opened output file "//trim(filename), ESMF_LOGMSG_INFO) end subroutine mkpio_wopen @@ -576,8 +631,8 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) rc = ESMF_SUCCESS if (root_task) then - write(ndiag,'(a,i8, i8)') 'setting iodesc for : '//trim(varname)// & - ' with dimlens(1), dimlens2 = ',dimlens(1),dimlens(2) + !write(ndiag,'(a,i8, i8)') 'setting iodesc for : '//trim(varname)//' with dimlens(1), dimlens2 = ',dimlens(1),dimlens(2) + write(ndiag,'(a)') 'setting iodesc for : '//trim(varname) end if call ESMF_MeshGet(mesh, elementdistGrid=distGrid, rc=rc) @@ -603,18 +658,18 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) ! determine io descriptor for this variable if (ndims == 1) then - call pio_initdecomp(io_subsystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) else if (ndims == 2) then if (trim(dimname) == 'time' .or. trim(dimname) == 'nt') then - call pio_initdecomp(io_subsystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) else - call pio_initdecomp(io_subsystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) end if else if (ndims == 3) then if (trim(dimname) == 'time' .or. trim(dimname) == 'nt') then - call pio_initdecomp(io_subsystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) else - call pio_initdecomp(io_subsystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof, pio_iodesc) + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof, pio_iodesc) end if else if (ndims == 4) then end if diff --git a/tools/mksurfdata_esmf/src/mksoilMod.F90 b/tools/mksurfdata_esmf/src/mksoilMod.F90 index e5c117edb6..74dfb2c3bd 100644 --- a/tools/mksurfdata_esmf/src/mksoilMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilMod.F90 @@ -1,28 +1,27 @@ module mksoilMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mksoilMod -! -! !DESCRIPTION: -! Make soil data (texture, color and organic) -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -!----------------------------------------------------------------------- -!!USES: + !----------------------------------------------------------------------- + !BOP + ! + ! !MODULE: mksoilMod + ! + ! !DESCRIPTION: + ! Make soil data (texture, color and organic) + ! + ! !REVISION HISTORY: + ! Author: Erik Kluzek + ! + !----------------------------------------------------------------------- + !!USES: use shr_kind_mod, only : r8 => shr_kind_r8, r4=>shr_kind_r4 - use shr_sys_mod , only : shr_sys_flush use mkdomainMod , only : domain_checksame use mksoilUtilsMod, only : mkrank, dominant_soil_color implicit none SAVE private ! By default make data private -! -! !PUBLIC MEMBER FUNCTIONS: -! + ! + ! !PUBLIC MEMBER FUNCTIONS: + ! public mksoilInit ! Soil Initialization public mksoilAtt ! Add attributes to output file @@ -31,857 +30,851 @@ module mksoilMod public mkorganic ! Set organic soil public mksoilcol ! Set soil color public mkfmax ! Make percent fmax -! -! !PUBLIC DATA MEMBERS: -! + ! + ! !PUBLIC DATA MEMBERS: + ! real(r8), public, parameter :: unset = -999.99_r8 ! Flag to signify soil texture override not set real(r8), public :: soil_sand = unset ! soil texture sand % to override with real(r8), public :: soil_clay = unset ! soil texture clay % to override with real(r8), public :: soil_fmax = unset ! soil max saturation frac to override with integer , parameter :: unsetcol = -999 ! flag to indicate soil color NOT set integer , public :: soil_color= unsetcol ! soil color to override with -! -! !PRIVATE DATA MEMBERS: -! -! !PRIVATE MEMBER FUNCTIONS: + ! + ! !PRIVATE DATA MEMBERS: + ! + ! !PRIVATE MEMBER FUNCTIONS: private :: mksoiltexInit ! Soil texture Initialization private :: mksoilcolInit ! Soil color Initialization private :: mksoilfmaxInit ! Soil fmax Initialization -!EOP -!=============================================================== + !EOP + !=============================================================== contains -!=============================================================== - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoilInit -! -! !INTERFACE: -subroutine mksoilInit( ) -! -! !DESCRIPTION: -! Initialize the different soil types -! !USES: -! -! !ARGUMENTS: - implicit none -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - character(len=32) :: subname = 'mksoilInit' -!----------------------------------------------------------------------- - call mksoiltexInit() - call mksoilcolInit() - call mksoilfmaxInit() - -end subroutine mksoilInit - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoiltexInit -! -! !INTERFACE: -subroutine mksoiltexInit( ) -! -! !DESCRIPTION: -! Initialize of make soil texture -! !USES: -! -! !ARGUMENTS: - implicit none -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - real(r8) :: sumtex - character(len=32) :: subname = 'mksoiltexInit' -!----------------------------------------------------------------------- + !=============================================================== + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mksoilInit + ! + ! !INTERFACE: + subroutine mksoilInit( ) + ! + ! !DESCRIPTION: + ! Initialize the different soil types + ! !USES: + ! + ! !ARGUMENTS: + implicit none + ! + ! !REVISION HISTORY: + ! Author: Erik Kluzek + ! + ! + ! !LOCAL VARIABLES: + !EOP + character(len=32) :: subname = 'mksoilInit' + !----------------------------------------------------------------------- + call mksoiltexInit() + call mksoilcolInit() + call mksoilfmaxInit() + + end subroutine mksoilInit + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mksoiltexInit + ! + ! !INTERFACE: + subroutine mksoiltexInit( ) + ! + ! !DESCRIPTION: + ! Initialize of make soil texture + ! !USES: + ! + ! !ARGUMENTS: + implicit none + ! + ! !REVISION HISTORY: + ! Author: Erik Kluzek + ! + ! + ! !LOCAL VARIABLES: + !EOP + real(r8) :: sumtex + character(len=32) :: subname = 'mksoiltexInit' + !----------------------------------------------------------------------- if ( soil_clay /= unset )then write(6,*) 'Replace soil clay % for all points with: ', soil_clay if ( soil_sand == unset )then - write (6,*) subname//':error: soil_clay set, but NOT soil_sand' - call abort() + write (6,*) subname//':error: soil_clay set, but NOT soil_sand' + call abort() end if end if if ( soil_sand /= unset )then write(6,*) 'Replace soil sand % for all points with: ', soil_sand if ( soil_clay == unset )then - write (6,*) subname//':error: soil_sand set, but NOT soil_clay' - call abort() + write (6,*) subname//':error: soil_sand set, but NOT soil_clay' + call abort() end if sumtex = soil_sand + soil_clay if ( sumtex < 0.0_r8 .or. sumtex > 100.0_r8 )then - write (6,*) subname//':error: soil_sand and soil_clay out of bounds: sand, clay = ', & - soil_sand, soil_clay - call abort() + write (6,*) subname//':error: soil_sand and soil_clay out of bounds: sand, clay = ', & + soil_sand, soil_clay + call abort() end if end if -end subroutine mksoiltexInit - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoiltex -! -! !INTERFACE: -subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) -! -! !DESCRIPTION: -! make %sand and %clay from IGBP soil data, which includes -! igbp soil 'mapunits' and their corresponding textures -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: sand_o(:,:) ! % sand (output grid) - real(r8) , intent(out):: clay_o(:,:) ! % clay (output grid) -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - character(len=38) :: typ ! soil texture based on ... - integer :: nlay ! number of soil layers - integer :: mapunitmax ! max value of igbp soil mapunits - integer :: mapunittemp ! temporary igbp soil mapunit - integer :: maxovr - integer , allocatable :: novr(:) - integer , allocatable :: kmap(:,:) - real(r8), allocatable :: kwgt(:,:) - integer , allocatable :: kmax(:) - real(r8), allocatable :: wst(:) - real(r8), allocatable :: sand_i(:,:) ! input grid: percent sand - real(r8), allocatable :: clay_i(:,:) ! input grid: percent clay - real(r8), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer, parameter :: num=2 ! set soil mapunit number - integer :: wsti(num) ! index to 1st and 2nd largest wst - integer, parameter :: nlsm=4 ! number of soil textures - character(len=38) :: soil(0:nlsm) ! name of each soil texture - real(r8) :: gast_i(0:nlsm) ! global area, by texture type - real(r8) :: gast_o(0:nlsm) ! global area, by texture type - real(r8) :: wt ! map overlap weight - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - integer :: l,k,n,m,ni,no,ns_i,ns_o ! indices - integer :: k1,k2 ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - integer :: miss = 99999 ! missing data indicator - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - logical :: found ! temporary - integer :: kmap_max ! maximum overlap weights - integer, parameter :: kmap_max_min = 90 ! kmap_max mininum value - integer, parameter :: km_mx_ns_prod = 160000 ! product of kmap_max*ns_o to keep constant - character(len=32) :: subname = 'mksoiltex' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make %sand and %clay .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Define the model surface types: 0 to nlsm - ! ----------------------------------------------------------------- - - soil(0) = 'no soil: ocean, glacier, lake, no data' - soil(1) = 'clays ' - soil(2) = 'sands ' - soil(3) = 'loams ' - soil(4) = 'silts ' - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - ns_o = ldomain%ns - - write (6,*) 'Open soil texture file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_dimid (ncid, 'number_of_layers', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, nlay), subname) - - call check_ret(nf_inq_dimid (ncid, 'max_value_mapunit', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, mapunitmax), subname) - - allocate(sand_i(mapunitmax,nlay), & - clay_i(mapunitmax,nlay), & - mapunit_i(ns_i), stat=ier) - if (ier/=0) call abort() - - call check_ret(nf_inq_varid (ncid, 'MAPUNITS', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, mapunit_i), subname) - - call check_ret(nf_inq_varid (ncid, 'PCT_SAND', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, sand_i), subname) - - call check_ret(nf_inq_varid (ncid, 'PCT_CLAY', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, clay_i), subname) - - call check_ret(nf_close(ncid), subname) - - ! Compute local fields _o - if (soil_sand==unset .and. soil_clay==unset) then - - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! kmap_max are the maximum number of mapunits that will consider on - ! any output gridcell - this is set currently above and can be changed - ! kmap(:) are the mapunit values on the input grid - ! kwgt(:) are the weights on the input grid - - allocate(novr(ns_o)) - novr(:) = 0 - do n = 1,tgridmap%ns - ni = tgridmap%src_indx(n) - if (tdomain%mask(ni) > 0) then - no = tgridmap%dst_indx(n) - novr(no) = novr(no) + 1 - end if - end do - maxovr = maxval(novr(:)) - kmap_max = min(maxovr,max(kmap_max_min,km_mx_ns_prod/ns_o)) - deallocate(novr) - - write(6,*)'kmap_max= ',kmap_max,' maxovr= ',maxovr,' ns_o= ',ns_o,' size= ',(kmap_max+1)*ns_o - - allocate(kmap(0:kmap_max,ns_o), stat=ier) - if (ier/=0) call abort() - allocate(kwgt(0:kmap_max,ns_o), stat=ier) - if (ier/=0) call abort() - allocate(kmax(ns_o), stat=ier) - if (ier/=0) call abort() - allocate(wst(0:kmap_max), stat=ier) - if (ier/=0) call abort() - - kwgt(:,:) = 0. - kmap(:,:) = 0 - kmax(:) = 0 - - do n = 1,tgridmap%ns - ni = tgridmap%src_indx(n) - no = tgridmap%dst_indx(n) - wt = tgridmap%wovr(n) * tdomain%mask(ni) - if (wt > 0._r8) then - k = mapunit_i(ni) - found = .false. - do l = 0,kmax(no) - if (k == kmap(l,no)) then - kwgt(l,no) = kwgt(l,no) + wt - found = .true. - exit - end if - end do - if (.not. found) then - kmax(no) = kmax(no) + 1 - if (kmax(no) > kmap_max) then - write(6,*)'kmax is > kmap_max= ',kmax(no), 'kmap_max = ', & - kmap_max,' for no = ',no - write(6,*)'reset kmap_max in mksoilMod to a greater value' - call abort() - end if - kmap(kmax(no),no) = k - kwgt(kmax(no),no) = wt - end if - end if - enddo - - end if - - do no = 1,ns_o - - if (soil_sand==unset .and. soil_clay==unset) then - wst(:) = 0. - wst(0:kmax(no)) = kwgt(0:kmax(no),no) - - ! Rank non-zero weights by soil mapunit. - ! k1 is the most extensive mapunit. - ! k2 is the second most extensive mapunit. - - if (maxval(wst(:)) > 0) then - call mkrank (kmax(no)+1, wst(0:kmax(no)), miss, wsti, num) - k1 = kmap(wsti(1),no) - if (wsti(2) == miss) then - k2 = miss - else - k2 = kmap(wsti(2),no) - end if - else - k1 = 0 - k2 = 0 - end if - - end if - - ! Set soil texture as follows: - ! a. Use dominant igbp soil mapunit based on area of overlap unless - ! 'no data' is dominant - ! b. In this case use second most dominant mapunit if it has data - ! c. If this has no data or if there isn't a second most dominant - ! mapunit, use loam for soil texture - - if (soil_sand/=unset .and. soil_clay/=unset) then !---soil texture is input - do l = 1, nlay - sand_o(no,l) = soil_sand - clay_o(no,l) = soil_clay - end do - else if (k1 /= 0) then !---not 'no data' - do l = 1, nlay - sand_o(no,l) = sand_i(k1,l) - clay_o(no,l) = clay_i(k1,l) - end do - else !---if (k1 == 0) then - if (k2 == 0 .or. k2 == miss) then !---no data - do l = 1, nlay - sand_o(no,l) = 43. !---use loam - clay_o(no,l) = 18. - end do - else !---if (k2 /= 0 and /= miss) - do l = 1, nlay - sand_o(no,l) = sand_i(k2,l) - clay_o(no,l) = clay_i(k2,l) - end do - end if !---end of k2 if-block - end if !---end of k1 if-block - - enddo - - if (soil_sand==unset .and. soil_clay==unset) then - - ! Global sum of output field - - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global area of each soil type on input and output grids - ! ----------------------------------------------------------------- - - ! input grid: global areas by texture class - - gast_i(:) = 0. - do l = 1, nlay - do ni = 1,ns_i - mapunittemp = nint(mapunit_i(ni)) - if (mapunittemp==0) then - typ = 'no soil: ocean, glacier, lake, no data' - else if (clay_i(mapunittemp,l) >= 40.) then - typ = 'clays' - else if (sand_i(mapunittemp,l) >= 50.) then - typ = 'sands' - else if (clay_i(mapunittemp,l)+sand_i(mapunittemp,l) < 50.) then - if (tdomain%mask(ni) /= 0.) then - typ = 'silts' - else !if (tdomain%mask(ni) == 0.) then no data - typ = 'no soil: ocean, glacier, lake, no data' - end if - else - typ = 'loams' - end if - do m = 0, nlsm - if (typ == soil(m)) go to 101 - end do - write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunittemp,l), & - ' clay = ',clay_i(mapunittemp,l), & - ' not assigned to soil type for input grid lon,lat,layer = ',ni,l - call abort() -101 continue - gast_i(m) = gast_i(m) + tgridmap%area_src(ni)*tdomain%mask(ni)*re**2 - end do - end do - - ! output grid: global areas by texture class - - gast_o(:) = 0. - do l = 1, nlay - do no = 1,ns_o - if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then - typ = 'no soil: ocean, glacier, lake, no data' - else if (clay_o(no,l) >= 40.) then - typ = 'clays' - else if (sand_o(no,l) >= 50.) then - typ = 'sands' - else if (clay_o(no,l)+sand_o(no,l) < 50.) then - typ = 'silts' - else - typ = 'loams' - end if - do m = 0, nlsm - if (typ == soil(m)) go to 102 - end do - write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & - ' clay = ',clay_o(no,l), & - ' not assigned to soil type for output grid lon,lat,layer = ',no,l - call abort() -102 continue - gast_o(m) = gast_o(m) + tgridmap%area_dst(no)*frac_dst(no)*re**2 - end do - end do - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',l=1,70) - write (ndiag,*) 'Soil Texture Output' - write (ndiag,'(1x,70a1)') ('=',l=1,70) - write (ndiag,*) - - write (ndiag,*) 'The following table of soil texture classes is for comparison only.' - write (ndiag,*) 'The actual data is continuous %sand, %silt and %clay not textural classes' - write (ndiag,*) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',l=1,70) - write (ndiag,1001) -1001 format (1x,'soil texture class',17x,' input grid area output grid area',/ & - 1x,33x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',l=1,70) - write (ndiag,*) - - do l = 0, nlsm - write (ndiag,1002) soil(l),gast_i(l)*1.e-6,gast_o(l)*1.e-6 -1002 format (1x,a38,f16.3,f17.3) - end do - - end if - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - if (soil_sand==unset .and. soil_clay==unset) then - call gridmap_clean(tgridmap) - deallocate (kmap, kwgt, kmax, wst) - deallocate (sand_i,clay_i,mapunit_i) - deallocate (frac_dst) - deallocate (mask_r8) - end if - - - write (6,*) 'Successfully made %sand and %clay' - write (6,*) - call shr_sys_flush(6) - -end subroutine mksoiltex - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoilcolInit -! -! !INTERFACE: -subroutine mksoilcolInit( ) -! -! !DESCRIPTION: -! Initialize of make soil color -! !USES: -! -! !ARGUMENTS: - implicit none -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - real(r8) :: sumtex - character(len=32) :: subname = 'mksoilcolInit' -!----------------------------------------------------------------------- - - ! Error check soil_color if it is set - if ( soil_color /= unsetcol )then - if ( soil_color < 0 .or. soil_color > 20 )then - write(6,*)'soil_color is out of range = ', soil_color - call abort() - end if - write(6,*) 'Replace soil color for all points with: ', soil_color - end if -end subroutine mksoilcolInit - - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoilcol -! -! !INTERFACE: -subroutine mksoilcol(ldomain, mapfname, datfname, ndiag, & - soil_color_o, nsoicol) -! -! !DESCRIPTION: -! make %sand and %clay from IGBP soil data, which includes -! igbp soil 'mapunits' and their corresponding textures -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - integer , intent(out):: soil_color_o(:) ! soil color classes - integer , intent(out):: nsoicol ! number of soil colors -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: gast_i(:) ! global area, by surface type - real(r8), allocatable :: gast_o(:) ! global area, by surface type - integer , allocatable :: soil_color_i(:) ! input grid: BATS soil color - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - character(len=35), allocatable :: col(:) ! name of each color - integer :: k,l,m,ni,no,ns_i,ns_o ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mksoilcol' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make soil color classes .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ns_o = ldomain%ns - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - allocate(soil_color_i(ns_i), stat=ier) - if (ier/=0) call abort() - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() - - write (6,*) 'Open soil color file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'SOIL_COLOR', varid), subname) - call check_ret(nf_get_var_int (ncid, varid, soil_color_i), subname) - call check_ret(nf_close(ncid), subname) - - nsoicol = maxval(soil_color_i) - write(6,*)'nsoicol = ',nsoicol - - allocate(gast_i(0:nsoicol),gast_o(0:nsoicol),col(0:nsoicol)) - - ! ----------------------------------------------------------------- - ! Define the model color classes: 0 to nsoicol - ! ----------------------------------------------------------------- - - if (nsoicol == 20) then - col(0) = 'no soil ' - col(1) = 'class 1: light ' - col(2) = 'class 2: ' - col(3) = 'class 3: ' - col(4) = 'class 4: ' - col(5) = 'class 5: ' - col(6) = 'class 6: ' - col(7) = 'class 7: ' - col(8) = 'class 8: ' - col(9) = 'class 9: ' - col(10) = 'class 10: ' - col(11) = 'class 11: ' - col(12) = 'class 12: ' - col(13) = 'class 13: ' - col(14) = 'class 14: ' - col(15) = 'class 15: ' - col(16) = 'class 16: ' - col(17) = 'class 17: ' - col(18) = 'class 18: ' - col(19) = 'class 19: ' - col(20) = 'class 20: dark ' - else if (nsoicol == 8) then - col(0) = 'no soil ' - col(1) = 'class 1: light ' - col(2) = 'class 2: ' - col(3) = 'class 3: ' - col(4) = 'class 4: ' - col(5) = 'class 5: ' - col(6) = 'class 6: ' - col(7) = 'class 7: ' - col(8) = 'class 8: dark ' - else - write(6,*)'nsoicol value of ',nsoicol,' is not currently supported' - call abort() - end if - - ! Error check soil_color if it is set - if ( soil_color /= unsetcol )then - - if ( soil_color > nsoicol )then - write(6,*)'soil_color is out of range = ', soil_color - call abort() - end if - - do no = 1,ns_o - soil_color_o(no) = soil_color - end do - - else - - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine dominant soil color for each output cell - - call dominant_soil_color( & - tgridmap = tgridmap, & - mask_i = tdomain%mask, & - soil_color_i = soil_color_i, & - nsoicol = nsoicol, & - soil_color_o = soil_color_o) - - ! Global sum of output field - - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global area of each soil color on input and output grids - ! ----------------------------------------------------------------- - - gast_i(:) = 0. - do ni = 1,ns_i - k = soil_color_i(ni) - gast_i(k) = gast_i(k) + tgridmap%area_src(ni)*tdomain%mask(ni)*re**2 - end do - - gast_o(:) = 0. - do no = 1,ns_o - k = soil_color_o(no) - gast_o(k) = gast_o(k) + tgridmap%area_dst(no)*frac_dst(no)*re**2 - end do - - ! area comparison - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Soil Color Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,1001) -1001 format (1x,'soil color type',20x,' input grid area output grid area',/ & - 1x,33x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - - do k = 0, nsoicol - write (ndiag,1002) col(k),gast_i(k)*1.e-6,gast_o(k)*1.e-6 -1002 format (1x,a35,f16.3,f17.3) - end do - - end if - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - if ( soil_color == unsetcol )then - call gridmap_clean(tgridmap) - end if - deallocate (soil_color_i,gast_i,gast_o,col, frac_dst, mask_r8) - - write (6,*) 'Successfully made soil color classes' - write (6,*) - call shr_sys_flush(6) - -end subroutine mksoilcol - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkorganic -! -! !INTERFACE: -subroutine mkorganic(ldomain, mapfname, datfname, ndiag, organic_o) -! -! !DESCRIPTION: -! make organic matter dataset -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: organic_o(:,:) ! output grid: -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! -! Author: David Lawrence -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: organic_i(:,:) ! input grid: total column organic matter - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: gomlev_i ! input grid: global organic on lev - real(r8) :: garea_i ! input grid: global area - real(r8) :: gomlev_o ! output grid: global organic on lev - real(r8) :: garea_o ! output grid: global area - integer :: k,n,m,ni,no,ns_i ! indices - integer :: lev ! level index - integer :: nlay ! number of soil layers - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mkorganic' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make organic matter dataset .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - - write (6,*) 'Open soil organic file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - call check_ret(nf_inq_dimid (ncid, 'number_of_layers', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, nlay), subname) - - allocate(organic_i(ns_i,nlay),stat=ier) - if (ier/=0) call abort() - allocate(frac_dst(ldomain%ns),stat=ier) - if (ier/=0) call abort() - - if (nlay /= nlevsoi) then - write(6,*)'nlay, nlevsoi= ',nlay,nlevsoi,' do not match' - call abort() - end if - - call check_ret(nf_inq_varid (ncid, 'ORGANIC', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, organic_i), subname) - - call check_ret(nf_close(ncid), subname) - - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. - - call gridmap_mapread(tgridmap, mapfname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - do lev = 1,nlay - call gridmap_areaave_srcmask(tgridmap, organic_i(:,lev), organic_o(:,lev), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - end do - - do lev = 1,nlevsoi - - ! Check for conservation - - do no = 1,ldomain%ns - if ((organic_o(no,lev)) > 130.000001_r8) then - write (6,*) 'MKORGANIC error: organic = ',organic_o(no,lev), & - ' greater than 130.000001 for column, row = ',no - call shr_sys_flush(6) - call abort() - end if - enddo - -! ! Diagnostic output - - ! TODO: there is nothing being written out here currently - all zeroes - ! So for now these are commented out + end subroutine mksoiltexInit + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mksoiltex + ! + ! !INTERFACE: + subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) + ! + ! !DESCRIPTION: + ! make %sand and %clay from IGBP soil data, which includes + ! igbp soil 'mapunits' and their corresponding textures + ! + ! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio + ! + ! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: sand_o(:,:) ! % sand (output grid) + real(r8) , intent(out):: clay_o(:,:) ! % clay (output grid) + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: Mariana Vertenstein + ! + ! + ! !LOCAL VARIABLES: + !EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + character(len=38) :: typ ! soil texture based on ... + integer :: nlay ! number of soil layers + integer :: mapunitmax ! max value of igbp soil mapunits + integer :: mapunittemp ! temporary igbp soil mapunit + integer :: maxovr + integer , allocatable :: novr(:) + integer , allocatable :: kmap(:,:) + real(r8), allocatable :: kwgt(:,:) + integer , allocatable :: kmax(:) + real(r8), allocatable :: wst(:) + real(r8), allocatable :: sand_i(:,:) ! input grid: percent sand + real(r8), allocatable :: clay_i(:,:) ! input grid: percent clay + real(r8), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + integer, parameter :: num=2 ! set soil mapunit number + integer :: wsti(num) ! index to 1st and 2nd largest wst + integer, parameter :: nlsm=4 ! number of soil textures + character(len=38) :: soil(0:nlsm) ! name of each soil texture + real(r8) :: gast_i(0:nlsm) ! global area, by texture type + real(r8) :: gast_o(0:nlsm) ! global area, by texture type + real(r8) :: wt ! map overlap weight + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + integer :: l,k,n,m,ni,no,ns_i,ns_o ! indices + integer :: k1,k2 ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ier ! error status + integer :: miss = 99999 ! missing data indicator + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + logical :: found ! temporary + integer :: kmap_max ! maximum overlap weights + integer, parameter :: kmap_max_min = 90 ! kmap_max mininum value + integer, parameter :: km_mx_ns_prod = 160000 ! product of kmap_max*ns_o to keep constant + character(len=32) :: subname = 'mksoiltex' + !----------------------------------------------------------------------- + + write (6,*) 'Attempting to make %sand and %clay .....' + + ! ----------------------------------------------------------------- + ! Define the model surface types: 0 to nlsm + ! ----------------------------------------------------------------- + + soil(0) = 'no soil: ocean, glacier, lake, no data' + soil(1) = 'clays ' + soil(2) = 'sands ' + soil(3) = 'loams ' + soil(4) = 'silts ' + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + ns_i = tdomain%ns + ns_o = ldomain%ns + + write (6,*) 'Open soil texture file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + call check_ret(nf_inq_dimid (ncid, 'number_of_layers', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, nlay), subname) + + call check_ret(nf_inq_dimid (ncid, 'max_value_mapunit', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, mapunitmax), subname) + + allocate(sand_i(mapunitmax,nlay), & + clay_i(mapunitmax,nlay), & + mapunit_i(ns_i), stat=ier) + if (ier/=0) call abort() + + call check_ret(nf_inq_varid (ncid, 'MAPUNITS', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, mapunit_i), subname) + + call check_ret(nf_inq_varid (ncid, 'PCT_SAND', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, sand_i), subname) + + call check_ret(nf_inq_varid (ncid, 'PCT_CLAY', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, clay_i), subname) + + call check_ret(nf_close(ncid), subname) + + ! Compute local fields _o + if (soil_sand==unset .and. soil_clay==unset) then + + call gridmap_mapread(tgridmap, mapfname) + + ! Error checks for domain and map consistencies + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + allocate(frac_dst(ns_o), stat=ier) + if (ier/=0) call abort() + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! kmap_max are the maximum number of mapunits that will consider on + ! any output gridcell - this is set currently above and can be changed + ! kmap(:) are the mapunit values on the input grid + ! kwgt(:) are the weights on the input grid + + allocate(novr(ns_o)) + novr(:) = 0 + do n = 1,tgridmap%ns + ni = tgridmap%src_indx(n) + if (tdomain%mask(ni) > 0) then + no = tgridmap%dst_indx(n) + novr(no) = novr(no) + 1 + end if + end do + maxovr = maxval(novr(:)) + kmap_max = min(maxovr,max(kmap_max_min,km_mx_ns_prod/ns_o)) + deallocate(novr) + + write(6,*)'kmap_max= ',kmap_max,' maxovr= ',maxovr,' ns_o= ',ns_o,' size= ',(kmap_max+1)*ns_o + + allocate(kmap(0:kmap_max,ns_o), stat=ier) + if (ier/=0) call abort() + allocate(kwgt(0:kmap_max,ns_o), stat=ier) + if (ier/=0) call abort() + allocate(kmax(ns_o), stat=ier) + if (ier/=0) call abort() + allocate(wst(0:kmap_max), stat=ier) + if (ier/=0) call abort() + + kwgt(:,:) = 0. + kmap(:,:) = 0 + kmax(:) = 0 + + do n = 1,tgridmap%ns + ni = tgridmap%src_indx(n) + no = tgridmap%dst_indx(n) + wt = tgridmap%wovr(n) * tdomain%mask(ni) + if (wt > 0._r8) then + k = mapunit_i(ni) + found = .false. + do l = 0,kmax(no) + if (k == kmap(l,no)) then + kwgt(l,no) = kwgt(l,no) + wt + found = .true. + exit + end if + end do + if (.not. found) then + kmax(no) = kmax(no) + 1 + if (kmax(no) > kmap_max) then + write(6,*)'kmax is > kmap_max= ',kmax(no), 'kmap_max = ', & + kmap_max,' for no = ',no + write(6,*)'reset kmap_max in mksoilMod to a greater value' + call abort() + end if + kmap(kmax(no),no) = k + kwgt(kmax(no),no) = wt + end if + end if + enddo + + end if + + do no = 1,ns_o + + if (soil_sand==unset .and. soil_clay==unset) then + wst(:) = 0. + wst(0:kmax(no)) = kwgt(0:kmax(no),no) + + ! Rank non-zero weights by soil mapunit. + ! k1 is the most extensive mapunit. + ! k2 is the second most extensive mapunit. + + if (maxval(wst(:)) > 0) then + call mkrank (kmax(no)+1, wst(0:kmax(no)), miss, wsti, num) + k1 = kmap(wsti(1),no) + if (wsti(2) == miss) then + k2 = miss + else + k2 = kmap(wsti(2),no) + end if + else + k1 = 0 + k2 = 0 + end if + + end if + + ! Set soil texture as follows: + ! a. Use dominant igbp soil mapunit based on area of overlap unless + ! 'no data' is dominant + ! b. In this case use second most dominant mapunit if it has data + ! c. If this has no data or if there isn't a second most dominant + ! mapunit, use loam for soil texture + + if (soil_sand/=unset .and. soil_clay/=unset) then !---soil texture is input + do l = 1, nlay + sand_o(no,l) = soil_sand + clay_o(no,l) = soil_clay + end do + else if (k1 /= 0) then !---not 'no data' + do l = 1, nlay + sand_o(no,l) = sand_i(k1,l) + clay_o(no,l) = clay_i(k1,l) + end do + else !---if (k1 == 0) then + if (k2 == 0 .or. k2 == miss) then !---no data + do l = 1, nlay + sand_o(no,l) = 43. !---use loam + clay_o(no,l) = 18. + end do + else !---if (k2 /= 0 and /= miss) + do l = 1, nlay + sand_o(no,l) = sand_i(k2,l) + clay_o(no,l) = clay_i(k2,l) + end do + end if !---end of k2 if-block + end if !---end of k1 if-block + + enddo + + if (soil_sand==unset .and. soil_clay==unset) then + + ! Global sum of output field + + allocate(mask_r8(ns_i), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global area of each soil type on input and output grids + ! ----------------------------------------------------------------- + + ! input grid: global areas by texture class + + gast_i(:) = 0. + do l = 1, nlay + do ni = 1,ns_i + mapunittemp = nint(mapunit_i(ni)) + if (mapunittemp==0) then + typ = 'no soil: ocean, glacier, lake, no data' + else if (clay_i(mapunittemp,l) >= 40.) then + typ = 'clays' + else if (sand_i(mapunittemp,l) >= 50.) then + typ = 'sands' + else if (clay_i(mapunittemp,l)+sand_i(mapunittemp,l) < 50.) then + if (tdomain%mask(ni) /= 0.) then + typ = 'silts' + else !if (tdomain%mask(ni) == 0.) then no data + typ = 'no soil: ocean, glacier, lake, no data' + end if + else + typ = 'loams' + end if + do m = 0, nlsm + if (typ == soil(m)) go to 101 + end do + write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunittemp,l), & + ' clay = ',clay_i(mapunittemp,l), & + ' not assigned to soil type for input grid lon,lat,layer = ',ni,l + call abort() +101 continue + gast_i(m) = gast_i(m) + tgridmap%area_src(ni)*tdomain%mask(ni)*re**2 + end do + end do + + ! output grid: global areas by texture class + + gast_o(:) = 0. + do l = 1, nlay + do no = 1,ns_o + if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then + typ = 'no soil: ocean, glacier, lake, no data' + else if (clay_o(no,l) >= 40.) then + typ = 'clays' + else if (sand_o(no,l) >= 50.) then + typ = 'sands' + else if (clay_o(no,l)+sand_o(no,l) < 50.) then + typ = 'silts' + else + typ = 'loams' + end if + do m = 0, nlsm + if (typ == soil(m)) go to 102 + end do + write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & + ' clay = ',clay_o(no,l), & + ' not assigned to soil type for output grid lon,lat,layer = ',no,l + call abort() +102 continue + gast_o(m) = gast_o(m) + tgridmap%area_dst(no)*frac_dst(no)*re**2 + end do + end do + + ! Diagnostic output + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',l=1,70) + write (ndiag,*) 'Soil Texture Output' + write (ndiag,'(1x,70a1)') ('=',l=1,70) + write (ndiag,*) + + write (ndiag,*) 'The following table of soil texture classes is for comparison only.' + write (ndiag,*) 'The actual data is continuous %sand, %silt and %clay not textural classes' + write (ndiag,*) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',l=1,70) + write (ndiag,1001) +1001 format (1x,'soil texture class',17x,' input grid area output grid area',/ & + 1x,33x,' 10**6 km**2',' 10**6 km**2') + write (ndiag,'(1x,70a1)') ('.',l=1,70) + write (ndiag,*) + + do l = 0, nlsm + write (ndiag,1002) soil(l),gast_i(l)*1.e-6,gast_o(l)*1.e-6 +1002 format (1x,a38,f16.3,f17.3) + end do + + end if + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + if (soil_sand==unset .and. soil_clay==unset) then + call gridmap_clean(tgridmap) + deallocate (kmap, kwgt, kmax, wst) + deallocate (sand_i,clay_i,mapunit_i) + deallocate (frac_dst) + deallocate (mask_r8) + end if + + + write (6,*) 'Successfully made %sand and %clay' + write (6,*) + + end subroutine mksoiltex + + !----------------------------------------------------------------------- + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mksoilcolInit + ! + ! !INTERFACE: + subroutine mksoilcolInit( ) + ! + ! !DESCRIPTION: + ! Initialize of make soil color + ! !USES: + ! + ! !ARGUMENTS: + implicit none + ! + ! !REVISION HISTORY: + ! Author: Erik Kluzek + ! + ! + ! !LOCAL VARIABLES: + !EOP + real(r8) :: sumtex + character(len=32) :: subname = 'mksoilcolInit' + !----------------------------------------------------------------------- + + ! Error check soil_color if it is set + if ( soil_color /= unsetcol )then + if ( soil_color < 0 .or. soil_color > 20 )then + write(6,*)'soil_color is out of range = ', soil_color + call abort() + end if + write(6,*) 'Replace soil color for all points with: ', soil_color + end if + end subroutine mksoilcolInit + + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mksoilcol + ! + ! !INTERFACE: + subroutine mksoilcol(ldomain, mapfname, datfname, ndiag, & + soil_color_o, nsoicol) + ! + ! !DESCRIPTION: + ! make %sand and %clay from IGBP soil data, which includes + ! igbp soil 'mapunits' and their corresponding textures + ! + ! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio + ! + ! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + integer , intent(out):: soil_color_o(:) ! soil color classes + integer , intent(out):: nsoicol ! number of soil colors + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: Mariana Vertenstein + ! + ! + ! !LOCAL VARIABLES: + !EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: gast_i(:) ! global area, by surface type + real(r8), allocatable :: gast_o(:) ! global area, by surface type + integer , allocatable :: soil_color_i(:) ! input grid: BATS soil color + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + character(len=35), allocatable :: col(:) ! name of each color + integer :: k,l,m,ni,no,ns_i,ns_o ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ier ! error status + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + character(len=32) :: subname = 'mksoilcol' + !----------------------------------------------------------------------- + + write (6,*) 'Attempting to make soil color classes .....' + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ns_o = ldomain%ns + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + ns_i = tdomain%ns + allocate(soil_color_i(ns_i), stat=ier) + if (ier/=0) call abort() + allocate(frac_dst(ns_o), stat=ier) + if (ier/=0) call abort() + + write (6,*) 'Open soil color file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + call check_ret(nf_inq_varid (ncid, 'SOIL_COLOR', varid), subname) + call check_ret(nf_get_var_int (ncid, varid, soil_color_i), subname) + call check_ret(nf_close(ncid), subname) + + nsoicol = maxval(soil_color_i) + write(6,*)'nsoicol = ',nsoicol + + allocate(gast_i(0:nsoicol),gast_o(0:nsoicol),col(0:nsoicol)) + + ! ----------------------------------------------------------------- + ! Define the model color classes: 0 to nsoicol + ! ----------------------------------------------------------------- + + if (nsoicol == 20) then + col(0) = 'no soil ' + col(1) = 'class 1: light ' + col(2) = 'class 2: ' + col(3) = 'class 3: ' + col(4) = 'class 4: ' + col(5) = 'class 5: ' + col(6) = 'class 6: ' + col(7) = 'class 7: ' + col(8) = 'class 8: ' + col(9) = 'class 9: ' + col(10) = 'class 10: ' + col(11) = 'class 11: ' + col(12) = 'class 12: ' + col(13) = 'class 13: ' + col(14) = 'class 14: ' + col(15) = 'class 15: ' + col(16) = 'class 16: ' + col(17) = 'class 17: ' + col(18) = 'class 18: ' + col(19) = 'class 19: ' + col(20) = 'class 20: dark ' + else if (nsoicol == 8) then + col(0) = 'no soil ' + col(1) = 'class 1: light ' + col(2) = 'class 2: ' + col(3) = 'class 3: ' + col(4) = 'class 4: ' + col(5) = 'class 5: ' + col(6) = 'class 6: ' + col(7) = 'class 7: ' + col(8) = 'class 8: dark ' + else + write(6,*)'nsoicol value of ',nsoicol,' is not currently supported' + call abort() + end if + + ! Error check soil_color if it is set + if ( soil_color /= unsetcol )then + + if ( soil_color > nsoicol )then + write(6,*)'soil_color is out of range = ', soil_color + call abort() + end if + + do no = 1,ns_o + soil_color_o(no) = soil_color + end do + + else + + call gridmap_mapread(tgridmap, mapfname) + + ! Error checks for domain and map consistencies + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Determine dominant soil color for each output cell + + call dominant_soil_color( & + tgridmap = tgridmap, & + mask_i = tdomain%mask, & + soil_color_i = soil_color_i, & + nsoicol = nsoicol, & + soil_color_o = soil_color_o) + + ! Global sum of output field + + allocate(mask_r8(ns_i), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global area of each soil color on input and output grids + ! ----------------------------------------------------------------- + + gast_i(:) = 0. + do ni = 1,ns_i + k = soil_color_i(ni) + gast_i(k) = gast_i(k) + tgridmap%area_src(ni)*tdomain%mask(ni)*re**2 + end do + + gast_o(:) = 0. + do no = 1,ns_o + k = soil_color_o(no) + gast_o(k) = gast_o(k) + tgridmap%area_dst(no)*frac_dst(no)*re**2 + end do + + ! area comparison + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'Soil Color Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,1001) +1001 format (1x,'soil color type',20x,' input grid area output grid area',/ & + 1x,33x,' 10**6 km**2',' 10**6 km**2') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + + do k = 0, nsoicol + write (ndiag,1002) col(k),gast_i(k)*1.e-6,gast_o(k)*1.e-6 +1002 format (1x,a35,f16.3,f17.3) + end do + + end if + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + if ( soil_color == unsetcol )then + call gridmap_clean(tgridmap) + end if + deallocate (soil_color_i,gast_i,gast_o,col, frac_dst, mask_r8) + + write (6,*) 'Successfully made soil color classes' + write (6,*) + + end subroutine mksoilcol + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mkorganic + ! + ! !INTERFACE: + subroutine mkorganic(ldomain, mapfname, datfname, ndiag, organic_o) + ! + ! !DESCRIPTION: + ! make organic matter dataset + ! + ! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio + ! + ! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: organic_o(:,:) ! output grid: + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! + ! Author: David Lawrence + ! + ! + ! !LOCAL VARIABLES: + !EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: organic_i(:,:) ! input grid: total column organic matter + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: gomlev_i ! input grid: global organic on lev + real(r8) :: garea_i ! input grid: global area + real(r8) :: gomlev_o ! output grid: global organic on lev + real(r8) :: garea_o ! output grid: global area + integer :: k,n,m,ni,no,ns_i ! indices + integer :: lev ! level index + integer :: nlay ! number of soil layers + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ier ! error status + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + character(len=32) :: subname = 'mkorganic' + !----------------------------------------------------------------------- + + write (6,*) 'Attempting to make organic matter dataset .....' + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + ns_i = tdomain%ns + + write (6,*) 'Open soil organic file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + + call check_ret(nf_inq_dimid (ncid, 'number_of_layers', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, nlay), subname) + + allocate(organic_i(ns_i,nlay),stat=ier) + if (ier/=0) call abort() + allocate(frac_dst(ldomain%ns),stat=ier) + if (ier/=0) call abort() + + if (nlay /= nlevsoi) then + write(6,*)'nlay, nlevsoi= ',nlay,nlevsoi,' do not match' + call abort() + end if + + call check_ret(nf_inq_varid (ncid, 'ORGANIC', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, organic_i), subname) + + call check_ret(nf_close(ncid), subname) + + ! Area-average percent cover on input grid to output grid + ! and correct according to land landmask + ! Note that percent cover is in terms of total grid area. + + call gridmap_mapread(tgridmap, mapfname ) + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + do lev = 1,nlay + call gridmap_areaave_srcmask(tgridmap, organic_i(:,lev), organic_o(:,lev), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + end do + + do lev = 1,nlevsoi + + ! Check for conservation + + do no = 1,ldomain%ns + if ((organic_o(no,lev)) > 130.000001_r8) then + write (6,*) 'MKORGANIC error: organic = ',organic_o(no,lev), & + ' greater than 130.000001 for column, row = ',no + call abort() + end if + enddo + + ! ! Diagnostic output + + ! TODO: there is nothing being written out here currently - all zeroes + ! So for now these are commented out !!$ write (ndiag,*) !!$ write (ndiag,'(1x,70a1)') ('.',k=1,70) !!$ write (ndiag,2001) @@ -894,345 +887,338 @@ subroutine mkorganic(ldomain, mapfname, datfname, ndiag, organic_o) !!$2002 format (1x,'organic ',f14.3,f17.3) !!$2004 format (1x,'all surface ',f14.3,f17.3) !!$ - call shr_sys_flush(ndiag) - - write (6,*) 'Successfully made organic matter, level = ', lev - call shr_sys_flush(6) - - end do ! lev - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (organic_i) - deallocate (frac_dst) - - write (6,*) 'Successfully made organic matter' - call shr_sys_flush(6) - write(6,*) - -end subroutine mkorganic - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoilfmaxInit -! -! !INTERFACE: -subroutine mksoilfmaxInit( ) -! -! !DESCRIPTION: -! Initialize of make soil fmax -! !USES: -! -! !ARGUMENTS: - implicit none -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - real(r8) :: sumtex - character(len=32) :: subname = 'mksoilfmaxInit' -!----------------------------------------------------------------------- - - ! Error check soil_fmax if it is set - if ( soil_fmax /= unset )then - if ( soil_fmax < 0.0 .or. soil_fmax > 1.0 )then - write(6,*)'soil_fmax is out of range = ', soil_fmax - call abort() - end if - write(6,*) 'Replace soil fmax for all points with: ', soil_fmax - end if - -end subroutine mksoilfmaxInit - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkfmax -! -! !INTERFACE: -subroutine mkfmax(ldomain, mapfname, datfname, ndiag, fmax_o) -! -! !DESCRIPTION: -! make percent fmax -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: fmax_o(:) ! output grid: %fmax -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Revised: Nan Rosenbloom - used mkglacier.F90 as template. -! Original Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: fmax_i(:) ! input grid: percent fmax - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: gfmax_i ! input grid: global fmax - real(r8) :: garea_i ! input grid: global area - real(r8) :: gfmax_o ! output grid: global fmax - real(r8) :: garea_o ! output grid: global area - integer :: k,n,m,ni,no,ns_i,ns_o ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mkfmax' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make %fmax .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - ns_o = ldomain%ns - allocate(fmax_i(ns_i), stat=ier) - if (ier/=0) call abort() - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() - - write (6,*) 'Open soil fmax file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'FMAX', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, fmax_i), subname) - call check_ret(nf_close(ncid), subname) - - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. - - call gridmap_mapread(tgridmap, mapfname ) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine fmax_o on output grid - - ! In points with no data, use globalAvg - ! (WJS (3-11-13): use real(.365783,r8) rather than .365783_r8 to maintain bfb results - ! with old code) - call gridmap_areaave_srcmask(tgridmap, fmax_i, fmax_o, nodata=real(.365783,r8), mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check for conservation - - do no = 1, ns_o - if ((fmax_o(no)) > 1.000001_r8) then - write (6,*) 'MKFMAX error: fmax = ',fmax_o(no), & - ' greater than 1.000001 for column, row = ',no - call shr_sys_flush(6) - call abort() - end if - enddo - - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - - gfmax_i = 0. - garea_i = 0. - do ni = 1,ns_i - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - gfmax_i = gfmax_i + fmax_i(ni)*(tgridmap%area_src(ni)/100.)* & - tdomain%mask(ni)*re**2 - end do - - gfmax_o = 0. - garea_o = 0. - do no = 1,ns_o - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - gfmax_o = gfmax_o + fmax_o(no)*(tgridmap%area_dst(no)/100.) * & - frac_dst(no)*re**2 - if ((frac_dst(no) < 0.0) .or. (frac_dst(no) > 1.0001)) then - write(6,*) "ERROR:: frac_dst out of range: ", frac_dst(no),no - call abort() - end if - end do - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Maximum Fractional Saturated Area Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) + write (6,*) 'Successfully made organic matter, level = ', lev + + end do ! lev + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (organic_i) + deallocate (frac_dst) + + write (6,*) 'Successfully made organic matter' + write(6,*) + + end subroutine mkorganic + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mksoilfmaxInit + ! + ! !INTERFACE: + subroutine mksoilfmaxInit( ) + ! + ! !DESCRIPTION: + ! Initialize of make soil fmax + ! !USES: + ! + ! !ARGUMENTS: + implicit none + ! + ! !REVISION HISTORY: + ! Author: Erik Kluzek + ! + ! + ! !LOCAL VARIABLES: + !EOP + real(r8) :: sumtex + character(len=32) :: subname = 'mksoilfmaxInit' + !----------------------------------------------------------------------- + + ! Error check soil_fmax if it is set + if ( soil_fmax /= unset )then + if ( soil_fmax < 0.0 .or. soil_fmax > 1.0 )then + write(6,*)'soil_fmax is out of range = ', soil_fmax + call abort() + end if + write(6,*) 'Replace soil fmax for all points with: ', soil_fmax + end if + + end subroutine mksoilfmaxInit + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mkfmax + ! + ! !INTERFACE: + subroutine mkfmax(ldomain, mapfname, datfname, ndiag, fmax_o) + ! + ! !DESCRIPTION: + ! make percent fmax + ! + ! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio + ! + ! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: fmax_o(:) ! output grid: %fmax + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Revised: Nan Rosenbloom - used mkglacier.F90 as template. + ! Original Author: Mariana Vertenstein + ! + ! + ! !LOCAL VARIABLES: + !EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: fmax_i(:) ! input grid: percent fmax + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: gfmax_i ! input grid: global fmax + real(r8) :: garea_i ! input grid: global area + real(r8) :: gfmax_o ! output grid: global fmax + real(r8) :: garea_o ! output grid: global area + integer :: k,n,m,ni,no,ns_i,ns_o ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ier ! error status + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + character(len=32) :: subname = 'mkfmax' + !----------------------------------------------------------------------- + + write (6,*) 'Attempting to make %fmax .....' + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + ns_i = tdomain%ns + ns_o = ldomain%ns + allocate(fmax_i(ns_i), stat=ier) + if (ier/=0) call abort() + allocate(frac_dst(ns_o), stat=ier) + if (ier/=0) call abort() + + write (6,*) 'Open soil fmax file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + call check_ret(nf_inq_varid (ncid, 'FMAX', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, fmax_i), subname) + call check_ret(nf_close(ncid), subname) + + ! Area-average percent cover on input grid to output grid + ! and correct according to land landmask + ! Note that percent cover is in terms of total grid area. + + call gridmap_mapread(tgridmap, mapfname ) + + ! Error checks for domain and map consistencies + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Determine fmax_o on output grid + + ! In points with no data, use globalAvg + ! (WJS (3-11-13): use real(.365783,r8) rather than .365783_r8 to maintain bfb results + ! with old code) + call gridmap_areaave_srcmask(tgridmap, fmax_i, fmax_o, nodata=real(.365783,r8), mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check for conservation + + do no = 1, ns_o + if ((fmax_o(no)) > 1.000001_r8) then + write (6,*) 'MKFMAX error: fmax = ',fmax_o(no), & + ' greater than 1.000001 for column, row = ',no + call abort() + end if + enddo + + ! Global sum of output field -- must multiply by fraction of + ! output grid that is land as determined by input grid + + allocate(mask_r8(ns_i), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global areas on input and output grids + ! ----------------------------------------------------------------- + + gfmax_i = 0. + garea_i = 0. + do ni = 1,ns_i + garea_i = garea_i + tgridmap%area_src(ni)*re**2 + gfmax_i = gfmax_i + fmax_i(ni)*(tgridmap%area_src(ni)/100.)* & + tdomain%mask(ni)*re**2 + end do + + gfmax_o = 0. + garea_o = 0. + do no = 1,ns_o + garea_o = garea_o + tgridmap%area_dst(no)*re**2 + gfmax_o = gfmax_o + fmax_o(no)*(tgridmap%area_dst(no)/100.) * & + frac_dst(no)*re**2 + if ((frac_dst(no) < 0.0) .or. (frac_dst(no) > 1.0001)) then + write(6,*) "ERROR:: frac_dst out of range: ", frac_dst(no),no + call abort() + end if + end do + + ! Diagnostic output + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'Maximum Fractional Saturated Area Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,2001) 2001 format (1x,'surface type input grid area output grid area'/ & - 1x,' 10**6 km**2 10**6 km**2 ') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2002) gfmax_i*1.e-06,gfmax_o*1.e-06 - write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 + 1x,' 10**6 km**2 10**6 km**2 ') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + write (ndiag,2002) gfmax_i*1.e-06,gfmax_o*1.e-06 + write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 2002 format (1x,'fmax ',f14.3,f17.3) 2004 format (1x,'all surface ',f14.3,f17.3) - write (6,*) 'Successfully made %fmax' - write (6,*) - call shr_sys_flush(6) - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (fmax_i) - deallocate (frac_dst) - deallocate (mask_r8) - -end subroutine mkfmax - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoilAtt -! -! !INTERFACE: -subroutine mksoilAtt( ncid, dynlanduse, xtype ) -! -! !DESCRIPTION: -! add atttributes to output file regarding the soil module -! -! !USES: - use fileutils , only : get_filename - use mkncdio , only : check_ret, ncd_defvar, ncd_def_spatial_var - use mkvarpar - use mkvarctl - -! !ARGUMENTS: - implicit none - include 'netcdf.inc' - integer, intent(in) :: ncid ! NetCDF file ID to write out to - logical, intent(in) :: dynlanduse ! if dynamic land-use file - integer, intent(in) :: xtype ! external type to output real data as -! -! !CALLED FROM: -! subroutine mkfile in module mkfileMod -! -! !REVISION HISTORY: -! Original Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - integer :: dimid ! temporary - character(len=256) :: str ! global attribute string - character(len=32) :: subname = 'mksoilAtt' -!----------------------------------------------------------------------- - - if (.not. dynlanduse) then - - ! Define dimensions unique to soil - - call check_ret(nf_def_dim (ncid, 'nlevsoi', & - nlevsoi , dimid), subname) - - ! Add global attributes to file - - if ( soil_clay /= unset .and. soil_sand /= unset )then - str = 'TRUE' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'soil_clay_override', len_trim(str), trim(str)), subname) - str = 'TRUE' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'soil_sand_override', len_trim(str), trim(str)), subname) - else - str = get_filename(mksrf_fsoitex) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Soil_texture_raw_data_file_name', len_trim(str), trim(str)), subname) - end if - if ( soil_color /= unsetcol )then - str = 'TRUE' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'soil_color_override', len_trim(str), trim(str)), subname) - else - str = get_filename(mksrf_fsoicol) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Soil_color_raw_data_file_name', len_trim(str), trim(str)), subname) - end if - if ( soil_fmax /= unset )then - str = 'TRUE' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'soil_fmax_override', len_trim(str), trim(str)), subname) - else - str = get_filename(mksrf_fmax) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Fmax_raw_data_file_name', len_trim(str), trim(str)), subname) - end if - str = get_filename(mksrf_forganic) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Organic_matter_raw_data_file_name', len_trim(str), trim(str)), subname) - - ! Define variables - - call ncd_defvar(ncid=ncid, varname='mxsoil_color', xtype=nf_int, & - long_name='maximum numbers of soil colors', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='SOIL_COLOR', xtype=nf_int, & - long_name='soil color', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_SAND', xtype=xtype, & - lev1name='nlevsoi', & - long_name='percent sand', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CLAY', xtype=xtype, & - lev1name='nlevsoi', & - long_name='percent clay', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='ORGANIC', xtype=xtype, & - lev1name='nlevsoi', & - long_name='organic matter density at soil levels', & - units='kg/m3 (assumed carbon content 0.58 gC per gOM)') - - call ncd_def_spatial_var(ncid=ncid, varname='FMAX', xtype=xtype, & - long_name='maximum fractional saturated area', units='unitless') - - end if - -end subroutine mksoilAtt - -!----------------------------------------------------------------------- + write (6,*) 'Successfully made %fmax' + write (6,*) + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (fmax_i) + deallocate (frac_dst) + deallocate (mask_r8) + + end subroutine mkfmax + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mksoilAtt + ! + ! !INTERFACE: + subroutine mksoilAtt( ncid, dynlanduse, xtype ) + ! + ! !DESCRIPTION: + ! add atttributes to output file regarding the soil module + ! + ! !USES: + use fileutils , only : get_filename + use mkncdio , only : check_ret, ncd_defvar, ncd_def_spatial_var + use mkvarpar + use mkvarctl + + ! !ARGUMENTS: + implicit none + include 'netcdf.inc' + integer, intent(in) :: ncid ! NetCDF file ID to write out to + logical, intent(in) :: dynlanduse ! if dynamic land-use file + integer, intent(in) :: xtype ! external type to output real data as + ! + ! !CALLED FROM: + ! subroutine mkfile in module mkfileMod + ! + ! !REVISION HISTORY: + ! Original Author: Erik Kluzek + ! + ! + ! !LOCAL VARIABLES: + !EOP + integer :: dimid ! temporary + character(len=256) :: str ! global attribute string + character(len=32) :: subname = 'mksoilAtt' + !----------------------------------------------------------------------- + + if (.not. dynlanduse) then + + ! Define dimensions unique to soil + + call check_ret(nf_def_dim (ncid, 'nlevsoi', & + nlevsoi , dimid), subname) + + ! Add global attributes to file + + if ( soil_clay /= unset .and. soil_sand /= unset )then + str = 'TRUE' + call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & + 'soil_clay_override', len_trim(str), trim(str)), subname) + str = 'TRUE' + call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & + 'soil_sand_override', len_trim(str), trim(str)), subname) + else + str = get_filename(mksrf_fsoitex) + call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & + 'Soil_texture_raw_data_file_name', len_trim(str), trim(str)), subname) + end if + if ( soil_color /= unsetcol )then + str = 'TRUE' + call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & + 'soil_color_override', len_trim(str), trim(str)), subname) + else + str = get_filename(mksrf_fsoicol) + call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & + 'Soil_color_raw_data_file_name', len_trim(str), trim(str)), subname) + end if + if ( soil_fmax /= unset )then + str = 'TRUE' + call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & + 'soil_fmax_override', len_trim(str), trim(str)), subname) + else + str = get_filename(mksrf_fmax) + call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & + 'Fmax_raw_data_file_name', len_trim(str), trim(str)), subname) + end if + str = get_filename(mksrf_forganic) + call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & + 'Organic_matter_raw_data_file_name', len_trim(str), trim(str)), subname) + + ! Define variables + + call ncd_defvar(ncid=ncid, varname='mxsoil_color', xtype=nf_int, & + long_name='maximum numbers of soil colors', units='unitless') + + call ncd_def_spatial_var(ncid=ncid, varname='SOIL_COLOR', xtype=nf_int, & + long_name='soil color', units='unitless') + + call ncd_def_spatial_var(ncid=ncid, varname='PCT_SAND', xtype=xtype, & + lev1name='nlevsoi', & + long_name='percent sand', units='unitless') + + call ncd_def_spatial_var(ncid=ncid, varname='PCT_CLAY', xtype=xtype, & + lev1name='nlevsoi', & + long_name='percent clay', units='unitless') + + call ncd_def_spatial_var(ncid=ncid, varname='ORGANIC', xtype=xtype, & + lev1name='nlevsoi', & + long_name='organic matter density at soil levels', & + units='kg/m3 (assumed carbon content 0.58 gC per gOM)') + + call ncd_def_spatial_var(ncid=ncid, varname='FMAX', xtype=xtype, & + long_name='maximum fractional saturated area', units='unitless') + + end if + + end subroutine mksoilAtt + + !----------------------------------------------------------------------- end module mksoilMod diff --git a/tools/mksurfdata_esmf/src/mksoildepthMod.F90 b/tools/mksurfdata_esmf/src/mksoildepthMod.F90 index c69cf375a4..0a2182bb1f 100644 --- a/tools/mksurfdata_esmf/src/mksoildepthMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoildepthMod.F90 @@ -15,7 +15,6 @@ module mksoildepthMod ! ! !USES: use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush use mkdomainMod , only : domain_checksame implicit none @@ -82,7 +81,6 @@ subroutine mksoildepth(ldomain, mapfname, datfname, ndiag, soildepth_o) !----------------------------------------------------------------------- write (6,*) 'Attempting to make soildepth .....' - call shr_sys_flush(6) ! ----------------------------------------------------------------- ! Read domain and mapping information, check for consistency @@ -164,7 +162,6 @@ subroutine mksoildepth(ldomain, mapfname, datfname, ndiag, soildepth_o) write (6,*) 'Successfully made soildepth' write (6,*) - call shr_sys_flush(6) end subroutine mksoildepth diff --git a/tools/mksurfdata_esmf/src/mksurfdata b/tools/mksurfdata_esmf/src/mksurfdata index 97d19adffe5fb999a31acbd81e91d8abfde3a72a..d0ff3208aa25d77b546eb7595abcc35d87a0f2d0 100755 GIT binary patch literal 4027320 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

eb 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�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

?gywo#q76}^|EK#lBq+_0a|9m!35Wwz8&w1~Bh z$p_sj_+4r@S|=%b#E_M3ULe+{gcwcdrMOwpyl`#ZncaxdE3#b3U7=pE9OGngD5jTKRa`70MIkkvAIq{pZ6iB8xv}XQ7&VePzJ+eD8@(%3n5Ql5 zLH=r7ac}j=25aW2C3Tj4m?ad3=L~ z$GXF&p)Z3GNo)g;fVcNHpY8kTpE1aT^-PQG0Vr7r>klzs{{RfF0r0c>M_^|Sh`^}q zUj#F2KoPvG)6fs7KD`ts?&O=H(XK^hk=R-5;c>=J5n1n9O4fVIRw_NKjnIjw zuzw2q09Sd9b`$1lSThGwDQd^Sl2mtc1vIIc`a@fETYc4it+A(1kY97FT08IaQj_4t z@A3)Tif)pD)(J+j6f@IR^vGdqBbg0JB*D z&1>s!6J*UCL(R#An5GEwjd zJ|tXrS-IXdZyw2s%@^3zR3BY{&63}#jm;f#nM$9>g}ZcbNPSfxcj8r<2NWkfT2)+; zU!1_Aaj4>~U}w5XC~3JI`UxNDlQBr5j`!?=hui?InhOf_%t|xprQ0DT6+h!WK5`pn zdK*7fc}GE+rg7W^vG_|_DX{S8RmSXXf15B&k3M-wX;_ZfIHVjbJy%t)q)YH==OyCy zP6!8ofYq5nA=~ZTn$I+iNfl^$V^WqTBFdKaEHD$Mz}uoz7IPaA-tYd9F!wOcq1#XC_D6bZZ`iDP1rvH!mJtN|LyIY1yJD-0 zna-+;(|5r-;$}4BxWyN81gp5kzg8)Gc#|qGYeke>)a7!}5!yUvb4gnG)rL`1Sz^ps zJAIrJ>rbc~8bO$CN5dYZvChFuv>cS0o?HG9OMTEdxL%8u4Ykp5l@gLoN+ zP&y-6P|)E|z*?qQzt$H1fKMoVyQh?)m;)mSsdTK9(H80Hj_n-h)SlEa&Y5;{he)Ae z4xGfDE0_aowZ%Q97{@4wL15Sg*bDR7tHK%(^$p7@#v1;JPRp&`t5)%xgjVZ4*<1Fy4LtT+$pu!5&s_UYpt4*!U3PW8`kSbUBR=`i3A7##N{ z(j#^K5YBJyDs_?or~XvVZ^?5rsvyp9n1gO^lMF`m2|2$>JKSkUaCn1*Bb;t&k?vY> z2Iy&)q4}xhjDRe$I)!st&}rmx=d`+07z2AdDqTx41|+x=NSG6{9M1cd!WeiT#=tW| z&fH6(7Hj~9*K%rR5_K|+0SOUSw{s@Kg)@XPFdN3e(`q75h7E~j3K@Uq;UqaxTh6yS zvIpuR48I(x--e{(Kn-I%;mpi(W;Ud?2H9u?h;HG{F&g2ng+j7?xYM%JAOeoti9TQ| z*2xJkk`UR%d}4F9xAs|j%G zQGa!-qcR`WVdevASd*F$3n}`KU$!x0|-rc6PuB8TP4# zyue>xNcNN@=^a)KR=$12X(8}q4lp7v=F5*ml0?WpNz$oC@T=6IBuSDky^5)@oU3I@ z)nwnrWGgg>#E|~h4q?f?Vg)6^RmhQ6B1f7-maH6U-*U^!ksgq>(r}EL-#-;EQS)2C z{947+5hBU_BJ#^E#VN8ByWk)@&;CM$0VqXT_L{7?klVCEe4qyTUJerW1A;Dj(P6py zJ~BJsnDddab&S%)bK9&Szhu58+MjPg<}f8MI+FR`!+ejEfULaeT#*;;i+&cPKWe_S z@*=;FS-xr(ptFnjv*-OFNfC<{JSsEK>J&*4>s1NImfzl5% zgNmbS_>!XCa-Te#Q6xov(yK{Yacg!52h1f@PDg_0#nM8#tbsM^hwR|2Pott?SMn4K z7McB8j+OhvulQJ65_+fA3JcE91tpgJnh-gP+R5^E_vFnxW}GuPFfLjh*rY8IRDz0@ z@OLd(W!yDEi|1`@`NZrr*Ky$RdIL#TUt>dQGZ@-6q ztIdd&T49VownRGk(!Z$NWeu|+ja9;rk|a#!5~eRD+;77o`XV^3%Ion%Z02m1b_#i0 zMR`Va0}gT48Fpe$`Wxi%Io4_X$10XilXRr}L}2_W2E)*wgLFN~wBuv!@cZn&FL<{c zk_ZDz$Swqj#qp8^6U;`@50ZFS-N_6fT!D^(g1Xf6$<=KzVaRC>_Z&w_ zGNOxT^JUWJFj_BA5~T?cb$NyM)76hMDOvU)_OeWrx8m;kXb^UgNmxzPcm}+{@ooWk zFSdo)c!z|?N2`aF&bx4|V+}#$>j_gE_k>bb(3yWUmSM6T-g+U`)_t{G&aqKzNa>9y zt4wkC()_Yr@#t%FkC5Q0(hzczUotOh?KfVEwxVlk&)RJ0{f!HSm~=(Q0zfL29YF$R49a!wrz@61sz95s^Q|m`0DmH~ z^ywst+n0n;V%wlbMy)-6H0~pVSOLQ6lw2}X3R1}NP6$^<>rW`1_f_!Q3AFh|yP%Yd z8(}$x2P|#ei#{V1-UYm2M2LEHO?^RYO{TdO{|I~X>UMQ2Zd`QY38golp-OVE%NMq1 zv~%te5q4lA#RN+|H$W{{IEi>FfI&avCDlf)O)P+abjt#r| zN@IK>;3Mcx^5Y&gz0zWtv(a|J@A>}+fK`oVAbnLtQr%EwxDOWJLh%q6-o|eu+Eac{ zl>U{#lLf^ndjvdN>8*^NSu=4k2SRnls3#oP`oV=Ur>aP zv4$eZR`o#T@QyjtnfV(e#R$klI`g!~`ZZ9jTD0ST$2Zr#A`h8J2x=SLm#e0OWdN(b8L| zcF7&uqOqvQXbq?GG;7cieJ7}>>ff^{bU4zSJw`%F-%&hAvZX$O=D3-tgi}ANLsap$ zFecO$cQ4N<7}T3vaff=3T7=02t4da5!hV)xO zsgH8pKUG-Kjk8vbcKba~A%W-%-@QUuLvV#qT8RZ;h}r#$b()ma(J=(ncmirX0X3e0 z8c#rtp{akaL_Let6W@e{MAS3PbJTO{vqOwT4lqD~(ph@?J?p3VG9=m#Onb z3qX%ZI-pPr1hGj?g4m=O0aSs*Zud#$rj|SEGIn6LsDvFlcbr{)7G}|>ofSz0U*~k1 zmd@-|qW0Lig%VpNv3OwGFV;k5`VX{Hs?+V4!Ee%5sm!7~(k8*Ost+_m`Tz=_5a(_i zh@aGnAZ!!AQ$j4$VCk0(%zEAl_fiDt_uwoB=(9Il$YH0+>E!`_k9Q|d*gM`1y^vtV zQel0DQGkBAj)5xY!M5ag3;W;T}QjCVt?3678|TZ7CEke+bk z@NiI4qse@C%7ix&&p(=XNAXfVWMMoEze1WM)mOU7Ru+-p@3C(6yKsl@DefR8DliNv zvnLnVE8S{-&{gRMIuX)hX0kP5a83Psg6XpJ^8{(3qfgZe>H|#JoulBG)Bf5Lm zTR~Qx^3KFX39P0@Kbg&y=~%^HQmsbwXOEP*YOGVR(n#%w9=?{|;CQLh9rnCHwbA~n z(#V!xZc~O~FCl;^&h$sagsJUC;KZYg5{%ZP*+Sxs8igck z-sgTXJGJR1FwpRf75zj@y-WRYN!{A3_X=5SuNWH~{NDe^-nR!vQQiCJu|R-@Ngya{ zs#K$*!HNwk8q{pqz$|PKG$?Ac2pCbLU|8@Kc_nBjVJq79S9@E%y|uNsxA#_SEn-?R z2?9w}Ot2siAAqR4tRSHBQpoS~`JUO=>?S0LR@?lsGqY#ToH_G7-*di?^L>mlGIotK z3U^_?Id?(rH^PM%jPYh1@xP?Hi#!BiHLyjBZr>A}{4V3|u)cd-^@s}`FwaVc87vi9mke|F$eZ^t< ziq$S;;e!Spk>F>YD_=0LBVR!NN5;3>{u%=ALR+vJyu|Zrppy~c`k=Nrhq55>K?W65 zjFVJ&F*%#afEi7k6~<4_CjJ1y**+2d0LrmwxLO;?K>*)d0rQ{AjMWxyg}SK9oHghZ zXH9rTQnRO`)^iEh`JPnedIvmtr>ygPaq<=1cce9t;YR)wh0s7j_Oig}?lQ)~-t8uc z;b0U{L@W|PX5~~bQ@k_Apqu%=07+Rt*84&_r7!XX|TKt#Bq+D?w zB4pJJM2U;C?T;UYspy#MlGA--a)z9)J+csg#dNHGAW*&RgY2DZdhdHV_{iM3L7sG6 z^{}&{HaeSX7#O`_A#54zO+OVB_rXzcDRO14*D90H-neS_*{RT)p+Xb#02buznQeDx zZE_{Q>N50{z{$9VhG}4dF@7NI0Sb&sz$kq%l*9N-n=ABWW!Ymvjty+L?wy#ZWA-1w zSLAE?*wX?%yss}m_NT&j1H;M1H1jJVN~vrmUi))gxrIKvjT_;HQH94(-Qsh4&8Y;X)@UsbkHjunt+@g zm)VE9H0Qbk1FM_UJ{-?ppeOHk=j=xu)Rm}m5WiJmQ44b3EPaaPYwF(Mw~}23OAJep zoY!X!K)OswadQs4a>_m%$k)5Id@!~vm)9yR%fCagY%xxd0w_W!_&%AVq`>+3v%C)V zaAzm)04oQm`b9YTR!co7+g%H=+X*2TiJP|35fR>xa8(7DBqBPoY(Aa_jC2F}#XZdQ zJ+#2~1z*w89vQuTt4yGQf*llB%ng@+KEj@lB zMNlnSzZ8y6ORyM^@!FDH-Ww2ga|8`3zz4aiOGXSXsCJJSRFGV!=WyJ26ll%{GI+T_ zkIe-J9Aca!hL7<&`+&!5&~xg6A1hFA9qQG&lQ-)*Yf7I=Zq%pN(F`t^bAt;7x)MSc zl2)t_pU)Zq2XZ&5>)4#aR|dPhV~HypUEZq`vFJW{cg+{T1SFn(0uMu6-Uopv z0(ip0Vk|EKmif5J*oy;wmw3WhgfSmj^Cg~#4gk+JPe{Y%cXh+JVdwIjgFnSvya?V(DO~keQdZc zItu^Fup2N%gp|0<2^TAI5XnyzxbOt;2&w&Qe z7jy3SmF@sB=GUv#;Qv zt9pqO&%3HCU*o-uOy31psi|pec`#Pxuh_7iRrWy?06;s~fmB!Z%t@~5@z9@D*5cK^7bmFqzRl6` zmLWRnXuMawZ=}2={L;6{M3WL>6=cR~dG9B_?szYVJ0cmt(cx{&dzW9Wpf~y!fqD&3 z=12MZ+zsd!s{3cF`~P9yCzAMf&cywR>V6M(|9J*?#$Ug0-9j;9%a01ENHQGAuoPiN=-Q9xsorJL3JAD$-tKZKKSBHl}Nx+wVn z`fCEjo1TgFO`;H2k4e{8gZV-SN1TlG0Q5ahKLsIu0o`=p#!-OxW)GZ7sdD=Q%^-4j z1y~ELw@#pbD&6xBGK-t`(-lr*2R1>jMnJR4AOc(;IXhB)&mT%eyLvgp61O_E{P*yR zRPz<7zBzb>Y?N4Z`^Z8uR=(oGVK~){7EJ52Ybw5I#Yp0s()tks1pgS}GTfPi;NbE+ z0EQlJU!5o_K^k7rosl`jfsE_u1o-1mQ75QNVtnaT%HO|6Aq+Z$qnLa%Hn z6?$buhstp{IY$1?rCLwVX)1lioBlewMQx!YXYD=Lpmpe6oLMcRY=JWVkm&UeiC*uJ z==BbXUhfc;Eo^GNw7g#4vR>Y}Uf#Z5da|Cq8nNC?F*(;h+5j{pQh#71$pe=muu7RJ zdB%u8Ktp=!Am1D;6|jBbH1hE-Sr@?zVBi`(YY(kzQ^y#?KEYx@tJLyU@SRXYp)H2? z9gDRZf-u9a7-}>+7g5GPG4;OBtCs^U_!>z+=-V`!%f;+s(u_gAjETyDqjvy_eqqLS z9__h|k7ztl@qJteQOcr7E}`$}^YOLGSmw#WCiv6wylk-j34*p8V0hrBY1=Cd<^l0_{LlMJf{m(Yu36BH!aBw3<`O z6>cuz!=QgeH8GBT6kTym{ai0UlAc83$$ z$g1P_*9 ziuE79fWGc|YVlwp^YWR(i1)&S=#&h-(aT|^_-;a*#!CMhhf< zNvN4zG((PoonO8UM3Ay{CH{a@cv(H!9j!Z-$->9RoyfqIZzTDybQ#?js2KXDGvCy6;ER<@4Ww+5Ym^)nhlQ$9^Y|p=m1@>#ImsyU7)W3}&THnK|H`uIixMs{Q)4}}`Zrb~hMvf1+dg?(|Vu?v3n zX~1*7CoUtQ$ASWJ7E-RBwaUF=7*9VY>*!nC-ClWE!lr5{HFJVz48QVDUQg!$Q&de*o9=>o8e?KL4v4T+I{M zFW(Q$#%4m|TwModA6Dl9MfbOF>Id%?q|AF zx3?&Bn&WCLSR=V1a;>ZSZ_J?r%3lw?LLIi(>fK)Mz`l=-Evz75IK-lX28WZ-&t2Fe zI1{$37bo%M@Dtq!KhewSCwe)$HwXZ6?#Cw$3fvC{WmYwe1i5S`xwX71*vrx<(KlZ85SHw8F{^pe;hTZ$W-fKstFK`K0^#&7 z1lV;BMj(ryl50LNo~ow7zDvmt)@qBGsYN~3fX9GVd?^yKfDz}|3Sxv2A;kR?3sNIQ zfCol|M1X>vU1cA{e$jI79sxPE>jm4-<%w_b&A)}VE}k0|NBT1;?3XW46XWgcq-rZp zP!bC|1-~gY=X?%4zI>s2;E(EoH9Vp1Twf+``sadSRCYQ(G_L)4BRWEBV(b%3&JV~i zksIV-VxTK@V{~vBM8Yi$C8voFg=_T?_-nvKiNikKHFYB9LH+cR)x!p9HM_t`egS}w ztu7oiSf6^84eI!bsk)Ne=k~85`B=1hq=CB5P5u_tB)!jtRXx;e4+1a7O&@8bclY&m zk*=Y6y?PjOy0y;kk7T&GEpt@(Td@$Kp;49~4jKX5b%?_}aAb9QcW8k|;Z!iS9$F9+ ztLH)7g%vIyNOk4xp50$w?MTLkHy+BvYXc+js<{`_QgjfF=W=Do2Nn-Z(;*86OU`3y^%bZ#|Y^;%rY0C~|;F&2n|~Y4c{T@5?Fe33S90NOYIPN_5D?Wr}mO_@<9s`ARtad=^KX zJFH%vqF$YalkXwC)hf;vf=vv`bAx=d>`BNfjeAv_9EveX{S*!{ZBa%jc*M z7=4WZ_I93Rj@8}_z}};7o~v#am^a7!p2AHEv-hg|z102laPn2+R^VsL52!o4CrY#Z zaYy*b+i^FkC=W zmpH2%AQd=UH})WUR?oq1kOb~JV^S>O0zPl9{coJ6s5Hv3^`!X~CLUG<|5IpF`mhW= z_4UTP;Pm}7ku_jiM~P5dbdC9UX7wfIt*1zKTUmkqf8q@YQ@U>(2G9SW_#0fw{A18C zBYwx2#6|1}N7&nye>@#(aQD=0y74NlVu#8qhHyHL7oZn_OEF{q{P<=rqhtrbg8U8( z4OiZu6$*%-#mRTdWSV8vLC3Ec0vODa`~!Qq;-^Afc2?g*==?Gt|;E?i7_?zJ;E z@j=#_1gnTEYz$Ea1GIc3(7}AY7Gc$^=WQStfE}_4*v_~v)wgbEB9_b|M5r@rxlRG> zWDMjzSZDYGIC~(CSGkzan8aY$AFHeVg6O$#vcT3-$(%J)qOF zfI&wt^co+mEj|f&;OAO{M-VKcNLmekD%bW0QXR&Klfg$oeibI-kI_uTPBIbb9C(L6 zf`|Bo{6iWzhd<(7UqT=MB^ZgoN$#mT1L^R2I+-wXtzJnq1RpUl*fCjBvA9xypCcWk zH!lfns04*)%fnxOroKh1v&YEeNDhD7#7=12KmxFu#k^PCBzsRSGbOH#KpS^kiN}yDNr?=D}#Qv|4ypGw3>h$vCxCI9{ zqXnA*SLc)OY4p93v!iwYN-UEJo>OoS!2{Qt1k#r2`ymu)0QgzJBkQdm=gX}usN~8K zoSiQc5akerW3J}{RztWf_+l82U`Yb&Idz4fz~b_t0~?&+EMmol4N2 zsBLXnA)64vG_v|p?q36AXszN?JY3$|?ZH%<{8r54Kj^Vi1H*Be{R1g{1cf!&+e#=u zlI$rgKVsvdo9D{%Bi%h?%8&H$I+`+~sbsO^CbZ!+?1N^Q7VKO`63w2C=$(cN=9 zAGiq*c&;ix($jN(`H@~QS~}9(lP#UUZbdm1Xao529`eq>#_~hw%x*$j_Z9q=AL=oC zePEBe^?doEb7wcGV*Biu1DnbZb)UT~@Ftp={pY}I<%fFB{-40g@kPuz_YZKdIpl_<|~QO7y59jK}cU*_qpk6fc}{uFzmBVVr79=a0$_39I;vC&}WeWF+`!lf_Zzffu>%|6$xc_#jA zFPx~ouoe|tYwLET7EARc@c{HQ#hlw{#)NHc&?*n0F9_}@n$6Rk$xXEWYB`9ws0BuY zs|67!>`3fZlDUDB?iQFfWcm;%IdeBf9oTa<&bik#_1Fx_(Bss-Lwe}mjKon@WjDh3 zX2>b7{qKybf}_!>O3#f6qbkdAg}+C5KapjL*sf&pkpe`kfOmMwDcBdh5i${V4&TBRq~Lqn!5^Z=K+PHv#^vIVh8&`A)J z-P{U15I9M|GN+%wPHPfSU|XTSbk~aFCD#-%$uDC8w787jG_H{peC2gV$`20K9ws7# zz~+rR0SP11p>Xd8sS5Tr^{s%#8i>Z3a4bMD0^ci7BqUr1!8)>R$ zGEbbcUn5qr^&PLpX|Ey9d#8aQTAy8lHOX4`cX@W%n}FzbkUB3LRv@VSJ)CNq1sHvP zKOU&OJ&UNEo6s@%W#RGm;kSKrY+rKM$CkaeA+~IIoU-TNimf+!Q*7C<5UaongAH-o z`z%ghX2vPA!yxOr6=C>&Hdf&G4o)>p&y1y@49kM=x94^Se(CO`!OwPjV$65U9~fKq z_V;4TCdDcH2V%Wg;WB?vY}v2iOJl8f;MCYM8$7_Q_2!=xTjrKNhvE197=hmtIMv`2 z3BL)LjJ|2-bOwHh@p$|AH|+A*zHAvDTQ(vmwrts@v1P;Jlraco(c^f?Sak4xZpBThAA75vV|Wb|bY?hO1s#N+M5&ja#g?O*Na*s>CLY?%)o zvpzd5PFX^n_A;=+XMOhGg4nX(x?; z%EIvbY?NC6aH@Gi!EX&Fqwlw8b_RaSMjs7+pWPbUzwuLI%iOobmTiFHh4tHh3ca?q zYN*@!r0m2uwj+o`e7?vB&H5mFY0-}4X^z)C)WQ_U&`zo#%6ebX{K1HboFc2;cJ|4N_3@bfs; z`iE1^CklS|VKVwM&*%*NssR4>;rEY+V*8R>8C&+YH@0kGoU%e>HM4&2vrA&je)ULf z+2cQsE!$odTlTCGTUI804#RKQNVWdqR6~FIpU1c|x2Hd9RGEcTSwLmGW#DtnWAktgCRU8LhzD2XoZt9YnA? zDIO{@@fvZhqI|MPgp&`zLk5MDwZcyhxD8_yi=42HrEt>ZyL1M-2)DFgLE{aUg2$&@ z3Rd4@DcCo~Qt&~ErC{0}mV*98mV)2>$Wrj=jh2E`c_a*^Ww`>R|H7%pqk!}!aLG6Q zGyN?DfsLGF8K6QI|ZKyfQ0Sf&&j(j{W9LR6!`p>g8jhK zsBgRGeM`Y?m{~{Fc;1x%LO`GTv86`d7E8g_cPs_X(y=gn?!8>#b2CmguPFF@2wd_sZ})8^PZWO0^iw|g5RHIDR>Afn<#MHa;~MobB?9pCxa~odDhpa zonfg_D+OWrOu9_qq7HSW2{ zQezZUTv71(*#(w@OjAAzwQ;owLJ`YeKWyYhwc*IN6ik+mh2b-Nguv(fIMt+M+Xb}m z4d8;$cXFrT^Z$Tn zr=>=kwP1<7B@CZ|IRc+VoN7iW_^bdf_!>^?6ny>@_}316?l&cw(5KvIikhKHZ^2jr^&Wf?=kt5_)9h&6XN#t*^b? zT96H@Xd!+c_MSXva9`~t z?rv$=rt)+{<0JWok$l-mzIPNfG2Ry25k{TULf$yVfZ+$)^iSMi=ILO zY@}FF4`X9((PQ%PRwViHT?LI9Eqdr+hsY?tAD*rL&&Pk))c5q(SIe%0QPDeiwi*6i zv#-~u7G~PS=@2{eh3~-R^&P~9vt>G}`}$TweZ6xk27E``l_< zCR%kE-S7K7w(}zPlb6vDB(gwuM|WleMeLUyX!ii|-#_NQ?Js&nx#LsoU^zks20RX@!nn9Bo zH0FN*4r2pCO$wf7udVYT{s`g;q@RmJ;kgXGSa@!#90$sAkQ@ig5jcsQd8h!KtOrgu zF#d?`bs~r}XT?1e9Nt{m$<}6VfM1g5vhptw^s4-eWY5{4|>s-b@2i6$utHSkR zUN0<0z-M@`%pT)fZNqZR)d|M2=1K+Q3r`PpP?fi`ya(Tf70i?3FmFiD?~Q;5Z6LXw zJ08D6{3bb#w}@y(4E>>d*>jlbOygKg_iY8+!l7_t1iTXtU=6wlVLH2=yZAD2#+Q|I z&8;5l8=JPHb=i3e^pUTU0P82g)r^YahNe+&0W`U)hZhb{Q)$ zdLvPG@`wnwBmGVOb3)b3$_=0u_iS9iWKt zi8LyHMB4$(!#HEmAa#H)$#_4i#yfdfobl!>IoJ3~aWR#+1pnl6WwImhhxAY)8?3(IHC0lW%U}{mS9Ypbq zf~nI|Q*rTS0jj0r;&1`#48#TMl%;0i0_KuP#0>`vas&qu$*%N&2|fh)}7>NBx99eHUa@Ni5mT!C# z=)r^{-Y<4)Ggg1<)aJS$ z$-vD$`1y(*TIm+t{l`Cw^R+3BsP;K7X0)L0<~me3zzW+~VLgfht645L8yI8@H~-O$ z`hgZ+t%Z}Mw(xq;5OkrwSevyW1)PD6Tsh6NF5}8P9A?0e!ltucPd~I^JQN05a>bxnKz-loW-NjEQ0D z$=SR7H5{?-yM|J_=re^UF0{VKhrv#ovk5ncsGIrb&7r;rcyo=qsi~WT&6~Ntn{ZQ% z_#!Fg@`qLJt>?>o4)G-K8Oo-xKg0LDqHexp-W=-d&zsoL;mzNxo3-Z6T;INIu&qO5 ziLxwq{*^FV7M~V)TVsiZn}_E810mLKY`Ra}No zpdT#cDRl)iKeerN=p3ygO_il<736ME?-axr#Mt0!fL8H=x`F{Bw8<>%u2nRtt3Hay zMA->i1(fr=iZ*rU@l$nmqRIk;yD-7KPnD&3O7Oq0=SMgW^jwEyPtVmjp5z&Y zqvpxQv6tsk9POU-a6ET*k7eiL(ZGF?99lf4Xc-M416M5rcb5N4kj!uluSkMcVIWCfkYA*yj*jLN$T<4z zaR+RzUfoxRDxz)+g7qNmQj>lr0*)Xg=GK9F-HsG@?*=!_@D^-C8CW#`KzHvZr?#{X z7J9uK@{L}4c@G;bO`YNWFW8&X`{7HpFbF|(dLzCfEE8Wv#3Y0wX+SWuf%<~2>J>gT zztM$8T?@9b{d{d{OF{1q1-&zf-gDIZV zz|lTBg!Avh=WwdI0Fml2=j+dd6z8|miKmBHVWuKBKy?oo6{hNm8f`|G(Oc}g6`^=I z*DxoPCmToA=m^#5jcl|)H9D7#{?u%=8iWvV>l^5UcB@lx&FEEq^~4j|dhrsLre@dT zjR>TNk8v3XVM6Mvz69~c#=EE1%jmmd|G$qR$6&g@uiCa>Ye2A=z0T^Q{Wgd8YQ9ml z*9POsoIRymk`eS30dH$z3To83avEm!thPU_H98FYLbO@8EeU7HRd5_O8VKjtLV;R(^=8&y@5*aN1Uqbf7fc-?(eWl!mGGk!W11KLbx`4|GREPjY+Q6kukXS zjeD;O>W`{&dpIhS994REN9CAAN7c-3j>^)c{HjT|{L1T-9aXu>j>~DL#k^E|*)@axtZhO2nWL{7`NFlx*ZG6+r@#Uyupei|JxZ?O?7;(k% z#n9r4WS z0tIlz@daAoisPHu?)cVXh-1b#596EQs2YRu)iJ)M7~h!~-|I2HlQ6z{7~fos?--1) zj`1zU_|C-mp3HGY6^w6fJLBspoQN%cKvyl^3{Ex(yel?+@f4R&fxk7y+ZOiV-l1szBJ)fG+kwz|T5uK92vC z_j4H21UoqDCUPK#<*L9~3v!$($bnk*3O9fn_0R?gYHW`|jXr`Jz>I~_nDI!2zmnhw zV&r0e{>2u=k862l#gESk9>I^{sv_p-LuN(dM?c^Pc~foCOq2>rhcM$Nl(aED(+W5} z#~JBOaWP{va0;U3jLWV*0}?AP?1_{k_wcY4!r`oUdnvinq0QKc|1To0)l2JA}a3Wz4vj^ z%8O5N!MCW|yqd!I-Mk$)H?QK=T3m^g41CPjHtz>wLZrSKf-F!L_vM-GxSGOuZT^@7 zI3L*#$r!>nngK#X)D~eGXzR?RWX;(@nR@g4e3H2TKI(6VbYA+wX_TZ_oVF0+XRCjGaA@!S{?|RU-SGx= zx@%~^nW2>h%|&uI21`}sf_4?`7D1d$g0~sbhdt+vA;EJQ_WrnV=Yj>Pbs6sdDR9+A zSi-u}EwSs`SdhG=F@~)k>sqfc#jAw8>6j=S(Z%41z^qdlR4MZSi5!FKT!fmzWh1hKY2qUeUd4P>N@;8$}D?ndYx5vR1N6gJGm#(|OUndpMT9K>?g32Xx) zLn;IY@N2&9al&-b7-nm*rxk~ZkGps;Xndx^q(k@40RB-Puan7EZD`W%1u?ZYjf zY9HrF)nw4@ZAaGbSG5SANue+$eW}{A8rP!Hv!X|kRRC7gw()gO+%eX z;MrCqvgZz0{{8uz^|K0 zxfyThVp9GI{O5razV4xY2yf^b+HY)V|B3u(i2GFfxEm}i#f4xUPQcDd+05d6BMm8b zlc0VJmgPs3nG6Nul9QQGTDiV>7LWEWb{NphtpX3RVp%IUPFh!?C{grt0e?&p-x7Ex zesP8LH>^LL6z;F+53|v?H1_v4)m<_=!6HYv$kZWXOFgVZ?1LxqAmVa{l!&VnvGj-a zhyh1*0Xk|6JRh%cafn`6;CpkpzrwOz;;cG>`p#LgsXqauCX{)rk;TgB@QL2v`cx@sz-y;}t&SKs*>1&C0%jZI9l9<6C-N;BvQd z$d&w_UjF`<`u@$l!mjWB4G0KqLlkc0>wslu{s!L_xAskNCx3zMs>BB+h2je6`}Z>B zK6ZIp4nSd8=exWBK`+X;dve5x!w@e#KtmTGm^#`87=a?&80*ptSYh~Xcg}P4IzKdxa@a!u#`{? zW47Y>b!e-z@rG|dOS!xF8`M_sZckf13fk(rPjM`)lPOqKCsVMbZYXDBSzRvgdFsaV zpSx}{|GDdCf*er^sVzL88tYBL;a%11>mJ@hyrFA&qa=o}dwAVBYi4nN+prsDYn0un zHKno*cQsZ(tOh|EyN@*XoN=VF$k^By7a*}*4-98tsI6Bqn~tchEej#l)@e{%Bk@<5 z$U1HUnQaU#4BC$%-!@b;F5>_qBI+#&-MLn;`{Z(0@6iN!?O-4axGdqM4#vO7Ul#JWgVdRB~9cHe~37-cs$ zhet{6#%N`CW2CY>LzLYsK*`c<3*#xfE76Bx(06B4iN5>Hgn0UH#2IBM&9J^ZgZl0&s^UPR(@(}&K=T}} z@7_awcatd;#OS*-MBl9j5hi)drzw5+YaCT~lSSWMM1A*I=(`(3`tE^I`tB-N(Lh=; zhC67#0;Tsvh*L`GjR<=SXW$>c-+u+pK|}Z8e7N@5_=85GuPDpixC%=QCdV1(56)8+ zF%SMrRkZL2)hM;_2lql-5?yx>V}Sj%DgTYM|a(L91H6v<5(0y6>~6Pe$o4rZT_x*2?;=O0BwmJ zK&8J9(t_<&oX?7;1+An7R|GZZ!WgRux%z2}KL%-FSpyDfZVeP-wNQwr7*;u?J5LMg z&ZB9?k4P*0g%Q)_UzC5oCGqQKus%)bVz4aM9$z2=DT^A*`VLie)upZbS{U4tOy?&fBFYVWlNuLe9f7Fmc?=Sl7IgsBrvtKf9(ECg2*yvL8tDyG} ze^shzw$q^ZZ^Yxe(aThCBhO-l>VI{>XDPt9r3C&IudrO~S+AZ51=nHS_*AEh?Je)t4~Jcg5qlMj)CYPxD^KG`wAOdHqN(qD`buw6LQvU1NL$*k{Ls9) z{bODd=vIli;|M))3GDxoT6_)rizop{T0NIKwU>J#FUh=l-Eo}%;E6F03!?XORx-;h zukkpaoQ+@`!@0i^-QFe6>Z3Mi3xt~kBCF=myW!#=VQJ4@-3#(Dx`$&M-AjpR52pI< zwpZ|}mfGi$gCJ*GYPV{2?x&sKa!)ty{Q5a@zup$mpd%d86aqo0&w%Fe7<`EC|CM|3 zzMmf$kbrYH^W3kPFN9HRTW?GWXnUjH82YL@^+sm|{zbpL^nWAp@ahO ztu|lM7&y(~k1P3z3sE@e0eJ!3_fGkI01$AS?|m0<=Ob-S;c)o*PD}{&4>#ajiMs`f zv$;e&e&o1G)E0sk>` zJ33S|*gBZq*Z+Hbk65HG!v%I~!;U(B59Ywqe()8YH+LZPc%JT#D)J3bu%Wz-Jeb2>Mp zKQAz5Bcu$2&0yO#kKCI}4KEaCxspI+m?~$XNwh2R+zI zc@Ofh4NjG(#&qV2a;mKtB?~hs_1aue-bjCO%wTkmV;nyhGik3}#B8Q2INa zG&Kj{Ax*tlox?QsBq9jr2M{DYKgePB{Zt#W*HL*9(O1$tsSl`U$Qu)vPn8eY;rlS3 zAAlZS3{*zC9Kq$#{D#fOG4>zcy};+&NuxjAt!T7)j-=6Td_hW}@7~BS2n_)|`$At( zgl3WC$(I@b3%Fi>1^hnF`0~sr3SaJVwu>*vx}N?qxSsw!c0IinjDlKE0qxlJl)_do zb3s*HMaL_fYwDBHYw8P~SyTVtF14oKG&0VbYO){Zdi53P&3^~s!)RI-dUFdx(vaND zX#+gqsYBoa*V6I2CUkxs37ylc37k0{Bsll&RKRiM#R1M&p}+qVgva0Fz{6eL&(#h* zzy*ci0WPTHb>qPU0hbWkpyLp^^d2?Q9`~$zY;o-Rn4xck#!^LL$d%kVQP{?rLyaB&0@EpSbo15{&|C_gPnCL59 zD89l);wwBY>?{21z+HS-I9?z2vA@>$iCLD6dIx-iG3d%Sm}7oa-(U=RT;E_tc+B}3 z;UDbBwx^nJLARo)@elh4-=!*IOZD%(GUr^_Klo{sM*AQA6eaDBe4GBkH2RcD1gk5c zFt#C^dDy_i79PZ3R?Lv#x;hI^z$n9rD^K9J=?VM}F#~SI@Cg=o;0=9akz}$DWxMe^ z02?FmH;cj=U=AwWj0!ii0-e#Opu!ZO)fAxB6rkA@RG5MaQ&?dNR)~4_CgNFy@9Z@3 zoh^ayY|wSKOu5cFBfOOQLn8F=`FH&4@KorCS7{zr%3OMt;-X_-r6aYaZFrSJt_hMY zMD6Y%Xp@`EP#R-$1OL)9rFJ|1rAv?MUwV&; zFiW^z{qQTSk0EbTr*^|D*v}q9k5Z3#l$Jd@C?5s`VUNAWs*ekUIwM#IOMD(;T>I4=$PI4|vxkMmMn+dj@g`@3TsuWh06LYiJkzQOT| z@o&CURfH(bAezB33;Q?!hNY&DdZd4ImDG;wq)yd%oBqw7IZ9of8~i@HoP0HfHHTV! znG2OKbCL38o)-3H{$)@}4!y%S@;+G!1#ddyy9~5ZzRSd#qxvobY1;5zR`vqN=$~{@ z=~S?J#Z0X+7!&qSdQepa#D^nVynCGyeoS^MZVvn#f4um}o&DqL2RzoU5Ua-y71$N4mK#Jq9<| zr4~2WrJZ+kjnv17-CSvM*daGp$1&26KN3BKL;L}*+Myqsst7zUR~0Sv<4%-X=*RU^ zF)sZGYVVKk-%1-Bll_~KiL0-$BYzC)d+4r*(4o~M4y|Q%gT$4U4y|r+Xe|_n)*^9e zofbg|#*q*#{mynh!h;n{IX753@4 z7ykrXg5zh6(8WJ}HRkbK!#^FH{Mw~&=+Za9Wg{FaAg)YE_UMDlkoC)<=43_O9xO zFtR;EZqhMc&;fr;5uN=061Q}5*xopvKl#A4j{B4U4inezeCUkxk37s>vm-{U^B(FP)FDoS5X#e5g#OeR7^r~&I`{E#Oy0D51Zig$Iy?-*Y z_or8PsPjs`vG)JB@%m4%+V;8>iIOvfINY<~}?l*oX2;_NnTH z_~GX}D(!rXd5BHl?L~j3r|4c^K`(lWepq0f9pSr82Tpi|!y!KG5gveBZ)_<^=)-N? z@Lvbr9{tsiF`mG4JsB_{CZ52n&$H*-d_R%fZN(Fqjl0J^p1|`M0Su8=!3cboVY(AE zy`RHe<=gP_w79@_uD&_Ek4FygS&03z;God;4*Gg}|Drq_C#J;pY|IsZ@?-T6{&NsM z^|A1|gFdb8gD1uXwiDG&==?_{bk3~qByeUvr+_oOM_k~{$5(wN`1}RW3;w)<3k&|- zK_A!lKRCuEwiDIk!RKsx#dZ#T#{F4A=!EWZAw>PM%=TmT=N~Wr{L{$u`~|Oy;d$Ed z)(C+{L`Nle$Gj54?mA}eLKqfkN5{_M$YZn`roNyDq#82OzPZH+lkPARk0Oko&ojJW zYV9cP1^YsW*6677r_$zd0SXEiCONbwN8JvV6fQ_|&;_ctv?V{ewqR-l!X&s_8=Wv< zfU%;Mr@desqczm|Qkgx)#aDT4r79(<@>i1gXV;Q7p|T&E<5MMpJ1Cltdy@Klub?5G*+=XmB7RED*@Zg9Fm1+%EJs#u6W{g` z-#%yAPU6}={QCfP@BTc6kFj##V?O(~jsMs2uoC}g@TGVM4r|!MKGUBDD+jz|n(-NR zypp=i@I7mTjfI#f40wSnNqznf;~Ge2bd>@7AZ~Bu?OE^I@%R)bAV8X$WFqW-G5lVJKTU zzM9#}@h*aw`O3A;M^N@*bh`32yooZr=Pe#q^NII(CF#od^RJ{U-;c7un}ppom9D&A z(v{;s60HZ2a9yP<--B#C^U|AnbT+5LDtTT}^C12!X=b{Ld7kE6{+rf3p8wpEtw4(Nop}DF_L?)M2ooR8*7v# zo7u3NFnO!d1kzR;V>yG}n8930GVrj>V4U5U!F$lF_2@|+d!`#&cCAE?XS{xsaKzG& zUxw(%PV~7W^kXIKwM{>s=53)LOd1kPKZde24*eJ?wd2u`Azb)$l8E564$%+{n@VvJ zq$D5(2*h(Nlw=L3C}PHdl3>~##DTMg6Wg@7X(-n2-j5P7mh2?88v#(6bLeVvXIb(a6Il z1QE$-#$j4>Dvl-1v|{!&55=*pITs*uH;>1$uz50$MQVlCbJl4K-$0;l-J72X#$0>& zd$Kg`*0WZs6!NR(Kdg*5yNzj?yOpVN`fUYXyKl6%blUaZG4JkrO)eQC=&rZr62YUu zc;fFr@Hg{%bos7V0R5!W6x5LJ>elG&0*b-Tqq$Hc71<8)yZ-V}80+&U+ew9^_Ad{&M zF$GKi7q4ERdkYg1!Nh_8Ts7+~tN=su_!f{wT)XoUd;3B9K1ULxtMHOl=FA`+yODO) z-SGX{J25YjJSZF25baR<2@v34kUuqk^&R6+8-CfvpJJAG@u$auKXn;!r!A;XEq zN}N7fvG$muvs?8RzgDqC%1Sa1a2Z*KB?N0<;j%0#cTlQ`|Ly3ww)jarQfv&V z$==z{xAGHjEjCJOl2|SLS^pjXvxdj}EPhQ&v0=X-pVRk6W+vyK*l&7C-NL(M1Oktk z1w(4&za)nX@^=x@*7izDb*+NYY!Q6jRON|ab*q4Yg4L5suyQ}CD9G!`iMW_K2Syt9 zjoFQhYEh@;$t2BL7p#{olm_+6rjIn-8*QwF+pg9XNO%oe#ZevO9rol{ulp2;TN7Ff zKyoi3n|+n3xba*Cdbo;O7A90l8I4TC+4};0My|F!iqULcuEtbzuF}23#xR}u$kon` zHr{%Xw*rr#=El%p|0G<7`ESMFo{s?RqC?awYVk25S#CA~0FBTN&z-tal(`!pSM)>z zv}=?CpGfSz5j6BwLg3eUXslsRG$By*gh0TommI8DRx;Lbr=)}-ppp}BD*e4)jn>C_ zOP)wD!Qc|9^J2UwD0P-V>iitYy+;vkah8iu-L2Q{y253&xRQ4R1mzzd(P5*Ij2L_x_AWhFAl|IvJ0@Vl zuO-{T5CZf1;5fgm2jb3hZZR0GiHDe1dU+i(`e29~W^+-|y%UmJv z&IUYXpMc7Fei94o>#qsVw@^od?~mIX)d}fqOrKt|_GuP`b+bRx4NMwmbf*|0A_ne2 z$-0P*gjjveL?xQSh5Wed`%gmCvHBW@w~VK+2?!R%)7NzA`z3jFXZ8JaLkRly==)E_ z;$R=c34+xE3V%!xkgttOcGAp&;X_Ya>r#BHa2Ge0CF#~jbZ?{PZKm>OdP67#3I}7Vj8uaH1MgI@#qo|Uz=%bWM4uW1>eH25Z99q%o`=l@vEMz2ijccO^GtXY7b8ry0z^o>*O# z-vf|DtE(;%J|Psp>0eMD=vn?9lLz#LUGhMeJP>6cbll{D7=83AEK;%h=)2q3N7v(_ zqwAx!#ScrpxH{>l+R#Z;H6N0Epp$LzK{;HClgMhcAfMAA4pTWxwWSJkpW<8g20csTs3p^V|4)HkZUz4R>VIrd_?T zWjDuP3OHCcbcP9yn2+897Du(mUJzlA4V$MIXo4NK$A)qCQS7l@A$#mGvG&+5lNEodC=2Z>Jb5v&K z?Q`ZO&iB~!RyiL|YSqhYlLNiv8j7&mhgLVtw_bnKMC@uDm~5R9pOOwU*l33@7C*4s?T+(U7(L(iUgswTUpPU!gwLk5AR~^3_Q+ zt$!|@HSd$BSX*$`9OF~H9cWeC42qW*fQh=aZ$w5UHn zyD_iQK7UkIM&78(qWOt86z+p!nZ?UcnNSaErYd+CvfdH%3#rjjobsH zt4D0i-u#l9#jTuGb2MUgvi8C`3a68u#$ku?2{yDVOP<8!T_Ke*7wSGq8C5yr$yB9rD0L6)2JI&iLEZR^?f^#A27ZOQpJtjOjKxpH2@?Ovwr~$Icee1OVHH$6pFy&W{sKJN!Pw7|#$!tI`Uy-VwEvvz*0n3lW+QPdq&hBdTt-zbk7BhFl>xL#E z*J0+oJ8OhqoxUl1p9~P=ZbXfyf>)BUZc(kV!%De+2gx(iWGm+5m!sFkpKr2LS}8HYvQoUn6{N6#b6K$Ml52vCi#H zzX*iXmDBWKnmFKrpb8=F!~2TL#@^h`u@!RqV0bt@Cx-GC-^$Y1yv5^D+{Unc53F>? zn0#XsJR3nG(sfX_5OsYYl(pMXd?U^oNK-rmX^KH(1Nb$;+2I42{@%S6hs{3x8t?=4 zz15F1DDkay#rpu%_s04 z`Ld#r7A8En>|Ua5-$2LTgO{iAg`@I55K369D;_+*@+4SaDaKTZb1-(&fQUD+dk!Ow zcMFVOvHaui4)l*)yXs#I(|+{+3D4eU|Nb`PDE(tT6l^m_0Dk`_SR1*kdk}up$>Wd3 zHA8@kO?F20y4EM_jc)}q=;MrUC7q<1aNp7P@ zEIixq@9mTkPD2|wcjH<53w3iue>);6ME5u)y2sB71_XP2-CY9Vh#mtkgZz}@56*|Z zoNnwg4JH$?D1bjOZTx94sa06`1M-_|{}zwmJW1^40>INR97NT;%AzNLsP$4gd#%Yj zK9LZY;f(h%*n|4uQzpZyEqox%9>B=ZK_6%i#CDlXHC{R@#+V)?t(g{^6fIe;z1lcm9O<<&Z^mm|s>l z!EN))Yun_P%`uMPmtj85aS{d_MtUZ{ysRyLIZgxQmtkrd;+L0U^2PAWu$ET*a)ik= z`Q<|`M9I}fO>ha1xh6BKDyG@D|;V}(L;vg5Cg5!@)q)m@COjaN&Eq{ zip5e^l<8A?Kz{3P?vU2dwE-5jHHp0g3l38boog?Ki+_!pRNY1CyqPg4mO`h@Ic3&Q z4%P32`tF(}^*|5hFMuad*K~vUIoECxg!$<~LD)qV(yWWo@Cd!`Bk_gM6MG*~g8ST5 zS!IfiVPn)Xf{u(BlMVHm5{2Oh(LY3%Blv5kMOXT&Kav>^#=C$ivc$V+ij8+s&U&Wm zD$ea`ye&L8BUqRskY^xxZkS{wXp6YM26=7-%Z3gJ$|i&$kfdD(l5;h}&Y3YX6h{b! z%^dE#sDKx^PysJs*Q^|H8%q(#Liu=tVV>dE$#H+f5x17jrcNm(TCD=bEP1P`WvLH^TCIp&7<-TU z3c_fE0j z{;I5i>5FNJXJKRn{e?rg)JcC~iCuv}Dk^LWo5E^S=uJFtL@3$=LOHlqw1+}Od%(YfD~XNv z@D~_-1mh}1MSB<JJA}+F#KI1&kAGmjw%11{ z1yJi_2Af93@~wym6j~pdaVy^XxC_sb6;1sed6Sy)<|X37miiXSo+p?W2v;p zZE(Vuy$XkERS4;jR#G(xM^D7Md9Jx`5)SrU1qX3kQEMmRz_fO0w%`)_7MD=}|HA@i z(U#nx?2}|I4Z;)WMp-<$riNh}Z)xS-SNSG)y-jvI>Pw%GSz%9?6_%|>tg@fNKilkL z)LMHcKCO5O`0M5focvE3H;RKmE0M)J9sz?kneiE#;l)pyjsJEtK0}MP_$}1qx|tRK z_A)jjG@GsfZg`0jClN5HP6Z4afl}d(bngUspYPQcpUW=5zH+Ue<&TWd&^YHD#%CC> zfT!X!jAwiX8j#hC0a>#+&$oP6kP$@stHfYvU<`%^iNVkyF&G*o21A3yU}%sS3=I;4 zpj*<>(-y1crO6V5Vfwcx1_KC;#9TN^ z^o1)qX;t)vmRT3T>1}%3(H9i*ge@n5JfRs(ENnEjGHV%m;kx1_r16!J^A~JmC8n<# z!hyjSl2E6JF}~hU;Y~0`a`RP0P?JatNr<#i&*3P24zH?2q=lZaG`Jls_^w%}g9W$W zCNo%>Qs0)?y8#gvl!2rV+|mT$mc$nFd-%?vE#zoiL(V{yg&w#H??-jbb&0;beqi+_Y zu#mp_MN@zLVzj>57Ej;&VuZf=#b|xAvm^Ru`-`T&*-67IWmcO*$HB3tn|s+u$ww(`$%qFF%*W&VhoN@7>#PrJ>>5aA={pNsCfSN>!%TG z#~OCv`0J-nhA0wpx>4Z9_BQtKXg&qu(CcrQhyYjN#+1->w%ftxLZh+@bom>bKkDy+rZN;EX}VHzQps#rH1k zZO}eYufAB!D}(<3-)8-wRVp--gwo0>LO~9SpmKxwCN%o z4eeHlk>UNdkUv)_{=xS}i(rj^P$%$?iGRR;GkgJo6%+r!UO<>L+C+q7S1=F)ABh(T zp`DhPMTf`*0n8Uq?Jfqodih5nCpq3%~xk_$B)p;baNQ_W3;^URQjbe|~%&PHmH39X-Ad zD@RcG2r|{~vvH_XX@}zLsLlyxnq#F*-&lMdcEY4Db7JUAy!bkNpbfHelm^{%7%$uVFpuiuV#3 zj3Q^fL;?A12*>B>@m>_a935}rbu91Jcnjqyi{O_==gnJr|}-pB2j2n)O$8DSwP zP{8BVQXPwoHKs!8FHQD0Zaf83s(^R6>Ox~#UZ;a6v}6%P5y2CJ{Fmul{%4atQ!ed( zdQC)^^hHTL_?@Wa4bwA1#j9Y_`Uv=`coposRo*Zi=#{*20$MsMSR+>Q5EmNN%JQQ_ zTU&UWu)GrBDlWv8#9;!QW@zYpj61$a9GxGD(dTw*BqU>|iY8}{&1P`LYCk)~FNWev zgyj(#5HlWIJb481CHPfwxhYK`=#7p2(IsE|D#@9dRN; z9*Gxmg7OF>POuL#@`&l{PI<%;l1DlgcH)`A7#D{jky=#P33CFNLh*CK8FPWsQ1~y1 zl33(h{clFei@}}8$R#T>e$F(?F#XRl`AxSXXyF=qG4L zbSgd&(I*bSuU6eie!m0Db|k+ar-8Ot>j-{7-fA6;55&I4@cU{sIvXFT`x(}Oh+~iV zor~u;`SiBp`K?PqJiitk{te>!o%?;RVHQq46wfcbA2JcqH&qy&{A@%5_j!gC{D1bo z1UjlJ`8%N-Xd&?h4H_kCMx%p*44UA;G$a?n>gLys))MM)9D*DswWGCMq~?>FMyt8CRwD=b)@)0SJHLUBBLa<1wSg`( z@0F!ltE7f3)vAj0<8O=nBSO9s{hev6_eB)QeRBt$OPB)RQP z1)Gp%8BxoDM#>v>x>K`O0#TR`muhW7Q1hFuHzR>F0?9*-`#o2n@n)$JEmCt?nyVST zEHfUs%(gcdG$XG;vvH5D$l}~*lxCePHOTojIjXe|4*IxCijp`3%_1MSTeG>;)kv@| zmG39my@wIyQHF1_x;Dp`@CSU0QwG$^bjPU-ECBl7y41DR5Ow1+8i|;OIJC@0_B_>! z8?E@#D6N*(aP9=@GJN*2HsOz}iKiJEtbtq)Az-y)-&c61c+vWn)POgT1-p;+?eV^Z z$6N1msp~?KI3Bx0vmT&O~wz5s840x(kNBhtUh3HB!2VFp{BULy;ttLL|fOQ22b!KI$}#ao#7E5D~XX+?01*s7X3uIK9fHODB6P^QBg^LudIU+EcFXbMk zxf-m&nu(}+8WOeVAn96bZ``?%6CYL=ROGU+DR>F#0UHD}@jZwX2*(QtVkIt-R?j(Z zbcg$qMpkASYdr`odxbK`mTj9{A9kvE*CZZ+G9 z%@J%&E85 zL4!BJLYi+CC`Tgio0iG-&db7XKz|0m`^HgSaRvHxd=vh*?5}Ym`2@_88(VyErFu|GY?Anpp({XjM1bHyvtbqeI0;N5r*!nQ;iTVhjTqO>$Qhjv4$NljiLc0!ZC zho9%>xHL#ul%zN=u1p~lU!b(~G<*TbW#aY~i&HaiC4n~8L=sq&Q#~7QEx3{d==0Xu z2zl>`n?Z0)EzTo^d^d$`Cm)|Bat+fb_Mi1|i`g$tK7%FKvM}oj9~q&$(+uaA?sO#y zcL+fh5+dbhWx)?ZQbWwkP-HtOqr(U;gC|L5_C`v7{$ z>KY>F2O$rbcm2?9`>VobbH9WZV-j%IjWMAvMO`uSroO`3FOHiy&e`}JuK?l zdRTPw^{^gMc>0C`}QAw&V|MwrOD zX_q?0T}9p0t>De8vebdwK)dy$w7kvMF1|5s8`z?=-niT33DYZRTj#q?hK@YFI{RPT`-dUEgEF)0$JT4t6NyllgjrH z&!aF*Q(uAbiyYifG7e0i9z{#I6c8chGWwPU_n497M%s5vwl>&613F(#Ok?$EHM51G z(p;C?e#mQ{784uDjE}d+;KOCB)<*mYj?s{WXVs6B!92k|b z>vU7M5k^w0q}9l|S%q;Se*OYvS%$tq@ggVPzkXW%I$D0AOnI^zA-_x%@{9LS=?vW3 zWz8|O{R*KoT+pN{xbzExrJ3W`5I4D!Az@;ZiIOlc7NU*!cJxT;%d~nDS&Pt^^XvdqwVZk-T>|4J=HSq*_MGUQx|R*(>T9 z8{Xey%aNA{YrbO_(?$?Hh_3rm1f0q^X`Rj2n@bjY$1e#1mP88KKWt z@uaPD`K)Z;F|PW8WrJ=2E5`kW27R)j%)R>?;M%%S zdP%wquW3A8qy@Vf<%Q`>uLHPBsd2w-=De(8B_7v;v>EE+dXn9*Mm5|z0wV|6Q^KmR zhY?{dn>o;>$Yr@6!cCnUp2Bo3$Xa0gjNr{(=Kw8pxS0m(QN;gJx?t6`{geR<;rHv% zv9!PsG44~-gr_r2(AXpG9hgjE?jWf5(ZI>{U`>iJKr|K9hf@k8%b*r|rG_jd!YnqU zGtD@NWK!RpWZ$|_xHe%3p)W_Ihvbsu0+f?7>q4XODYXJx`7XQgWqtOu?|-JDhDIxF)QK?lZ-Ei6C>R>F1w zV>cx&9lj{2|HjfMUIl?i>JuIq6U@6gMoCLk|3s<*r1wBYi!}ckRFBdgp!Xv*BUq>S zKC?VhS9s?ny22&sC-c{=EO18$i_bZsV!&P>PR-OHw$Sg8YEu#MlfBkM=R2|Br@Kg^ z;J+gbenXcs!KZKu6TB$pNmMDm*DQ{N{=Jhxe{oP#`VWDBBog@R(OiT*FL<6El#t1% zi!uw)Ew=#8@JD(dUtLJMt}C#+5~re{9$Y{Hy6A9e0}(z1)ryMT_EkY!%oT=O1<$12 z!U->1{f_mkY&G*R=~pgo+L=PXI{CX#pu^C+p2MtUk${a0aQKqQS$H3f@!c4QN#hcC zV-Suz%$p*wmbHOfWVV7502u)uFr~#lU7+a-p$sE9Vt4V`G*aA<0b4K3VGA)O@xb++L~M;Ta(1`g~3qCb2Wwx%E37aP*v4>A%X-|2tp35Ov6tMv3=`y1{bJgGhUr?kIy zrtc%*B%S%?OL*F4epzVRz)XILeftz_@?@`c;*JFiPQ@9Aorp6QMsmh(Ct!*pefNLa z9t8`ahS0Wyp6kdlb7~-&FE;!QK1m*s8l0*#y#qzL=^f;nd4}|hx|xYc+&{3+SqTY+ zTtT`;xq{%NB~V9<^dsE<0i&ZZqzCV_iHc_n98bmt2=D+wC*2R?hf@Pb#uiL5pTMfc@6EW{WXdj>5=@anLo)Lm^GGOFQ1MUn2B^^lAIaP)- zp}re7^Rh^v7dlcRzn9fT{}PbmJS5oPeT2^|(GS68^cU*O#Ako%=^|;+x`(=XdhN%q zROeE=wI(WyX;;C&Qv4(=C(0)r0PiC&iUF{FOVRAuwJ@hr`CP0bq2&uN46^Hb6gU8_ z5taq~Z4?tc8Pm*;3|X3U4ST;d7zLPzaOZ}mf*PDGuEE*DX|PquY=u1^8e}E6*ogDP zGBI`BBDozjDJstCmVw0iyl5>5j_uAK4^7DjN0Z~^CCFe$|H^1`UceKa3yH}w2|-K_ z;|Vul3|b3(4U3p8+R<_J#U4b8niT0lRBMIf4kPL>geZliG5S}AH(EatA{k+uetr}o z--Yl0H_(*ch|%%UIl=pr(Q0u02kB=#b++wDG999!pRTUOKqnH7Sc@V0oW$!P)V@Hs zx!yai1tQJRS|HNw)KU0a2*N{VC}X~*auW5a+ck%2&Upqf2LeEv?=M3OfAa0L7zgdd zJWsnXCI`5J<%r;489Wqp z+v^JZQENCVn&*(JlaugX-BhUrj&Cq>&r{SZ_*3%?hcBDmrsItLC`CosGnux1w*h_p^-W|T7Oia zB#J*A3G!PHWljRMh4I>Jg2RD9(%L6DoHbuFKf*3*gkjb^RmgNO)zqdDuW^z?`F zn=CDPF1;6HePh2ko2-T;zkGu|LQ(hQeAjS`fB@4fmHY5G7@sp%v&QqlgX#ejCn-mfvBeN?p47!Ve5mYS@}zT`P@n+Cf@{>Ba*kz^cn zsSRwwRJ@1cr3DQD7*F7+>#WKh)>96wbXF$!aaQFG>j5)mA9y(B4(sl$%(_fN>+BxE4U%0vIM+s>WL?bF3)shEfdvMvVPh4E+N5BB8g* zJ%v9~!-MZDT3n7VxdDP7yRksfH1_YHJas*B!sB~|{7;`QEnbltTqNb92waW1VT9~| zLJbF^Bx^Vy1m%7co^W}Q^Jlz-u2{bz=KC!7D=AW=i-hE`e&Hlc8V)-_okYWdhjATi zIELXUN}d~Mz(=25fbV3w4fSLt-DVNN7@V&lJ|AFwwh4TGhtJskUB+;wLzH6`hh(%L zrsB{zSaN@k#zFCMSRgR)lNX?RoL$~2K-{Hnz|M>N*RfK_qkXqj{vN*4An(H993KSt zKm3x_ymV}nsl#Lm;R<;%CxZ4oXfMf487-}+LAGk*$Q|-uSO&+OVYV2r;@lH+DDifQ zS99TH+S1xHag{SK41g_z!3SnX!yL1la z`{RT1xMw#-nx{h9`M^LIl3iA`Iv z*J`w460uf^zXtQ^Or$Q(L>EDQ&ZYf?YqJdW7h0dpf2wzP1)fvtT9IorN*)c)uT=hf zV+GuTZX@-r$oUQFT6cn)B6O`(y!zAVT0t`KG8q_p)@qY+hU`P9+W-0(``<8ZI@ri6 z^RT5=%%kJ|F9k68SQ`ABJqs&KWv*-seR}X?SFk}|HJl$YPA1h zOT#nT|FF&B8SQ`A`tXeQKWvA1M*APONIawc58Ec5(f&8=B>UfS-v2g6?SDBvE2WWD z1=#;)0*q?`#f<=BGGMsHQk7$=9FP640Q=ue4E|b-{YDJ^T;hqSfc>u?&x1XPB$L`5 zR@u@KVHG-$+J(-7^V8~N1jstp3#T66QfpP`@hx>$Avo+m z7#}H{1ox@N=Lx?{8PXZq(oEdJ*M#)4FvQUl#2GNki0KnL!?3n83TvjOcaDiQ3<#=3uPD$gPHyP(1B4t0x-Yxxw*Kiwtq} z0LwsSru-%R!-M*00kPaRJ;aWl9fK#`zs3`^ivzqC#DGnPo(x;FP)t)HTu1gB9{YaiBdyZj>j5cxf4A6hx^yZ*FbE+Sl*ufr># zL$<&@F-+4PPCb#P%Yeq#bg5{iIW%GtIcjnvblqB^>$2SPUw!wd)psM}w_RE{sJIHp zZ{zPt|}!(slHQ zU6&CK4iy*j4X{NK&nv?*!sc@WD`f7frMlMNF>;WPI@)VoA>;_o)kuAYUfIHkqM&;q ziyk*}uUpXTGPiwm0fdy8C_9%>CR&X0o;I)-v}c6TOA3ff_)kAdgmOZff!}mA-bTd2 z8!!X3kppy{aGVAXP8KH~jx}PPwd}tvNU9516R)u2G_Ye*7(I>lobC$N=)I5wb&%#L zKXqjMY8}%W5E350I#bqMBjPY;6eolVrHPQ@IBa^d5jH(p_zrWR3RR}nU{)rV367ke zY(`E`j*Of}ETRZaiDwveofO1?|QbWx$G^)Ksj)b z1;ZJjN;E^F!{9QEXjE6AAd3uTsC;@bo;p+;Yl+wptY*j?7{g-b_Kk((WK-d=9Btrg zIp|_Z_^_{{u>co{&8wn_XN;wa1{}jYHkIs)k@QUgTD;)H>HF6~`lb+VfrwCic95Py z#Jw1zWhUj)h;vRDqaCDKipdU((Owu8qdg69M%jl>dA{&p`^pcnuY~O% zTWA50yiq8twH!6Rnxn=|(Su@>CU)LC28@GwBnN-;*vt}?IN~93#0MpgE#doXf`V7h z5CSz4u|VXwt@ExrBuA=Fm<+ZGfg=vzU6WzO5dsK=50S`bbHSD%9YzWr*zv2a*mWDm zii|VH4)9nQyxUB85q}0Jf`qGF1L`1Gbjq_68|J0SRpa31&Ze6#!JGpt&9$e7d1=B^ zL711io`Trfb(qnGHLDZM5$h)m{?ASLX9@U)U=Z$lbgongXgiJV91$~ zvmPa9<|qFy904(M3}xixCu}j{&v&t)#6QEP{Dg95PQG<+4Co{L_rl;0m#=G0A_v`r z&MC_f$Ku6;8{k4*>H`rIx~3^#pA>E_dHt#2h6tHtPBkQL4RUqY;TH0BB&7%K(QU!} zRg=gi>z0kerEiM(Bp-0)ebap{n7vXsq{7N>W;Y<;K4drGLlrZ-0jWip{02H=`(@BS zF4Q0AQ+RrVIAYVpXJmh2cCt=A(otKi9@$qTm`@>WK7TC#;=6V6=LhgF2d?8iCI8C8 z?dT@|!uKD@ztF}1ApaVTD_pAZ=LhhwEWC0`{)I|G{)O*9kbmKg|3&_V+*nNrY3(}y zf?e#C{0qULCjUbC=MUpw@M}FK|LW|2-iOq_PVqW#fw_nIpF@m-D{fT0j#6!|d&KM* z4&^R0l%>_;CSPwwT0Kt9JTp90r^~N-&a}~cp(q`=ov23)4dCBa_DOeHJ{7?_;c+_1 z7i`Aq(7-bSa&V*wt|$~&naG+Etz(f5r*xiY`0y=c0-fZT9m>ix5f|O^jM%$vHFTWa;_9FG={-)O9J%*$cq#v6} zA%xBhI`$0@>KukZRECk0z6^yT(jTJ{&pYXho)Y%DfQJUGg{JQX^yN~DIi3m!iz?Rk zT6<1~&RCVv66tASR7^xguv}5ohMM?cR1MP*Ux=k4nm!f3Fnub70dqzYJLgPQ6Ye(B zV9-}e91-p|5%RC>G=Cog*iQOkVQ~J?3s&F^2}%gc> zc_g-k(v=10^3Nxj%R%N`QdT#k>$%jN0Uy-hxddP2jGE_TvF3C2N#;}N{?t)O_XmTi zw-Q?|6BE@#R#W>#%_!76q(}s}<``=NXQ_3G2Za+;H`9n?nsWg8BS0j(#P@2zOI3x~PGue^} zYu4;@74>7bN3QcL-haotdT%C6>N0WzG%a;(BZX)0o|>+_MYY92mC)px3M#`>Fl16Y zF3s8i`#<$mgFHR6&vmP{^c+@h#k(`!-J6S$KXW3d?4)!SZT?*hRFsKUDt{c0`A8}z zbh5h2fKGT_`UwQ~x@4%faIc2VI|SXy-@+mQ=Q8!wN|V|(K8%V~R)8PPWC*GtoI#wN z_$?4X1azAVx=aVuGftJ*B{+%>sEE%cg9$={bU^#rK6apQBL{lq)1~#$X)}|`ALGY} z=?`OolxmF^xKckur zf#H29uv^p%+ui;e&J8&PUbgHd&q0J~kLBovUnyEO{m0%VHL_Wa380>)40?L-n z%ma<%Kamyi=Z>mW#+|k^o{$^jMT&vcS#!+ij*a z^m{P)s7J%`$gmH_#7})}{FFrEM_TH7CJaGzlC+2sv@{w)s7Tph3`_z+r7kI0sWXDG zzW7x9#0a_+E{}O`%A07Q2xoOb(b6A@qJqvS5*HYpAm8K(=!bGShv+9K-?cRiJ&>NH z`R_1dS4Yqf)uU9K26pJ|7=D^&ozB?7{&@=Q^v}u9^MxUYPBIb4BXUUoVEQTSjGR-^ z&r${xibeSP@;n^E4TNyY#Tf!QHfkVhaq`Vjy_2Kn)h?jM$hT?G&HoT;Lh^^f&neu) z4GLhni_Gvls^LRQ7i`hLvY@jZiY`P7?fPZJa>$jvJEDe->x^8QanI0|sCC|xXaJ7w zh#}q|7DG&C`mOsph8O{~>)rY5T^DV1Tec9z!42pFWUpkOYc||B7U4Jy>PTe17_#4+ z{;pE_6Br)(yng;s$mca|ypV2_eujBg>NyEFd*74a>vAKlEBs!KD9piV<-7%G<>cP@ za01*QU$o0**+4^Xf-@`_9c%_G$*qq~|MPjw!YlR!>+`?#7xZ5a(+B^1J`($Eb7JSS z%>n;CAMsrJ|K$0IBlr3n6!j<$L}Yc7tnPv;nXccMm>8$T4@}RfnRJsQ&vY0nBi8G< zktCpYmwH52kIC!scavP(dbLYEtXQ_o-hUsJ+gs?H+DtK^-Wn@*3|T9JZ&-G-9!N-x zb6MbT<%*vjcheNdEz2GY?|&orKRjLEgnB3HKi6@+;|9l#7&KyL+uUlqybcWcm|Ux0 ztyosd-W^9>13ElTr5$6~=%UmLv*X;pJFNO#Y7{>d%W*};vx+Z0SIE90PcK6BoBD;G z&&AmYE6p8hRd9`H>zSbj^lX&6Bu-_qV)!{3vr z_mkr8j_YObw<(Hx0JDfmk;>y?wxIlX<(pxUb7;xw zWR{tY?(|Ad;V&n60{OAs|{I$PrxklmfctRzxlYzorytEuU3WW%#5TDEPxmU$d` z$Z-S34Qb?P?fs&S>~vElPq(SkrW)@~=~G?$u%-z1p0%=NU7+t-y@tohftu=v(T%Lu z%f7x3FNPf8OYDmQ>S-7eJ*@~7^(R?9$?@Sbh%Kbg*kEx;cd2{yPXN4A-64CIr!bMp zSXkP)w1c%4&zV*6@Yyb}sqE%C9r4I`RJ1$LH~%zrscv>?GvH->mQJQ@09-+lUk>eh z_#oE@>Kq_vf*BV|x$GU%{C?akL2Y(zUt2Ux!J(1jT@F<2aj9SHFW$@1jOIXs*sD?M zvuPS&J2%JZ8}X075tu^;EkWjqWmM)%^kHG?H_g`pAAzba4|e816aCA+5#@j7mkwbX zm+(D2zQl?2Qh&UJ;s-^WTd0^$&CupBDn1RxiwSYT0gxl7p`ST&i9>-qU?w*>)B`v` zT{;*qS5M#;`r=TY8md5}`eTb|K57+}4oIc)k)Q=QrmI_I)zROn-j;+#kI#}5?vITPIj^i9hze2X?vSoMc2-%ly0kaS?m$llWaaUNU`F^M=d*njn{;+41#3%je^5c+=!3V57kdl-x`Q@K}T!Txw>zqOQ#G4*zAG2d?zPuhw5iUAN{; zw^fsb4Mg54M)M)&bF4Oeu>P-i2?$!mXio{OP#^-k?Ec~3A69kP214`) z(nFLwf*TaAq(7FrC#Cv+uHIKib-dM!`t8o6ElI1MF3LU;W#3^|95?&Fc?X2)8__1Z z+>D1yrim^WQ*yMT$l;c!!s#hm3d z{?;l1H5E;T{NlJC{Kl;=XDE&_6zdoY(pDYzcL@l|_ZEIIApeMjW7_v1w-o>c`<+O0 zB7n)nzyOSm78dmcrp)jZTd=`(1U!Af%iY?&*rxJUz;v-22Jnw)GOB$7(E7I-&}WFQ z2+$|qJ{rib*j@B9g0qJ|5vZrE;W8L(hrHaWC#R~Lof@RWG3gE3^%37MM6F zRSX3XSd~_yEAPX}ah_=$up|45)2;6V1E8zSbjM;k-*9Rg5smJ}qHw77*w_0PTy|$(Y#*!47Q3ig$+u-%YLFF5WE@ z?~b8&v*=yajCz@8aw@6=m?WpV(*+3?(W=;-i_-LQw__*TCECgqZ5_cxL99yC_q~Zl zj|Rakv(psy-jw!H);J)hsGqEE*R8)fM)YuIRBtf`z{>&X*Y~19Re;iqK(YC~KopOM zim${lurjhMzML%)u8DfMTI((D{4a5VReF+JyAS75f$`e3uj2FwsqOXro1g=z0eU+jwrwUd(#C=4H)8G6DW+0LjT)uxXu}_6>1-rq} zdKdEQQAPcpH?_5Z(cvAQ9w(KvJr`2k#ygSY8euoPx+FF32-t}?z^{OE=ZwpDUP2ez zl-!%65pQLaqAQs@%t)&``&VZbrIxSv zBqMdsuWpDh!Y#A)-CzvrR=&RI3#66o-mk{n5Dz-K8pksT<0^iagfr}p!_zqfB|$I5 zPTz>HpJB94!Q3pd2(-TPPav&ot`O-ErMH7#489Y@Pmmwt5g60CwgQ;7RY<&9v|(t^I|Cfojs;F#nn0w5Kwg4hG1%ODijPLS0E^vKBm26*=# z!^^v|+@%HNonil*c()PXap#?^8LVYE93bk!T2Pr8G3^+jZ+$gp97`mDB zLKXl(jUMLrp{DG}XLT5$nX7xCLK`tSL>f1%Wv-R&<7_2;sTrd4*4~OrM4u4kh4%z` zVS>R6F@=%La7MWfZXs1%4qgcsVTE&OFmlL91W_)W@-B^WE`OWmp3o?k4=H~$m)whe*ZWgV5_Ybt@|JzYy z83meth6+*G8Mu~AzbUfaZ7UfsYqJdr>psy+ifH9kYUL%gQhmR89w(kZhUbvVZ2FTZ zBdchNtY)JH=!cU~QPD=*9NG=w)TiUQO}!opfE!P5fSk0xaW=3Ij*FO@3J#1ESE&+yaV!}viQ z+J6Y|xO^WlR~mrt)LO+x)PM{fId`NI%03qj`Yip+eROxTRFR6BMDdERG>OU8p`ESI zoI-O1eDI7>)=rWVW@c*=?vTFt8W`MX+q`Rkx%W7~0YO__Ogr(v5009lh{|AhVm4{Xx zEPW79*pThe0GE79!|^5FjE?lvOIR};`zK~iHB`*Ey7&^Wq2fKWxj0vFt{15IHl~2Y zE2(&`DE14zaxN9$DvHmf;S+%L|rzK)CfE`N;|NiJ%uR>+fpOS7hvZa*aDdu$pH z|CKk5@Htm}6*N7_rjqWTfCxcTSq-maru7i=qu5c7!9PxDA{=1H;?mU^Majj67&$u? z+l0XoT^f8*3=!DozZpv>}hZH1LyoK+)&pnJUuKZR71vao_UDh5nmfuQ&s;#dwsxBpDroT$+7;0A6i^3XF zn1I4@npIb{S!sFzxD%BcM5U)irEh@q9BsI+Z$kxKBa`m*jSe{M&9mQnZ)*oRFY_J=6iGA{A(84_b&CSwm6x1NpEnWW0m}Jx6?Yo_|(7@fkSD0CR zilr8k*GY&;%2rndNe)M-LJ9NqWg;tQg$o-zsH}cME3o)sx}a*_J8k;!FfgKzCy6Y? z-e=Rd9^`G)lZ1`W4Ss+i)p~6H&`y@Jc5*lNdF(vv{=$?JAUFwy`uDGpdP1UmFI4c( z#)e+rdKzdNDobx|c9Nb8Ta80qp}CX1hq_7SZ76eikHt&nZ{r*34COjK3apYfuyh!l zQF^H~Zw?;PIz*q_UQCXon2fu_O)owNS!Sepe`hAs_w<)KTW4TH#tks(`WI`#eaQ}G zKB!%R2V_$)A0#crgUYZ6zqlRy_d{m!x*f*@t;k<1nj7^F%3$#jzgGMOzb2T!>gVBC zmigwfL`kQ#kMGJr#<>%PSKuMjeE$E^-t9a#J+H~=<;q?>~F z>L^$*2R@=LQD!Hj*G0kl2XK@KSkoVkf;HcbQ3hcxY6^$-j(?&o2l^J-jIj)=A*L5wI@)eH5&B z+=5XCVQt(L4y*Pi%7U;SdlA2au$IonuOO_q!3-OMb=jW{SRdNYuuj2rGOVA0CIzg6 z=X3?ud!9crtfylUM$qu?>L^(M{CE_sf4d%|48pqg({Na?`5VfDus#qmulaEM55anI z-*8wLEi_cw<2tf@g*Czf^v*4Lgr zF|0kBqhP(bCJI)oh6mxiY1CwlGB~f@w}iv`%QsLKoY(gw=JlQk8lHW2IIMe~GhltM zjbVKfATq31WBrMFodyZ+)brW^3GPJmdKv5p5i~q3nuZrg)9|Jn!(qKEV!gIR%?Ab(dTX zQLOp1Kc5))pn_9n z(3V^CYB;RxpT@7?RF}`fuiz5Cq$hp_m+(T>fOY$BhP4JDGOUkdNeWp1@NidPJ>w*> zz66KchuZoUW018eJ8an=EqKJJytp9{U5lmdFmc6+J53_w7n1jiR{AA~ zn0!tVSsFV3WB&lQM-R<8GYv|UgY4<|x^QCX z8`Af$Qe2mlJMbR5nw1kS#9xSa6VchbuG2$*5Y#&H+sl#C8 z!MO;w9vt%yB&${$6zJ(V@as>#+q_5Oi)Ogg<8;`9G2NJ^SAuS7uFcuP`B83qa_d>- zuP{wH7NB3S{P&c7fF_;xISpx0@O%f4vXLwK5hBhrj`M6M zb)PMHk905UM0G_fUUnUhm$lNhf0+)%*eL2#F%Y z)jMOIN%JnoqC=hUM4hbgI^m!q0x(^FZ4HK#fH8F{d7~C3`_O%-lD?!OG{-7Aavw^n zW0kD?`gp+qa;%bi$Rz%%SS72TMalG7C1*lb@!t@uWYQ%l8IBTWx_+`eb{hW>XqEmH zl)#(d(AUf#jxRL%!>3Q0-UR>j7_8s_EhaJ=yMK9tXW-=6eVVZQPrTh}3@|jt2<*;?Rp(F8I{bMk0d_}x$=J;TP6c+az={{x-G?25B@zE%)Q!gOS-c_f( z-FPyvJ%P77t+6|ZGdvWlWUGpjTVs{v{}v^qW0gGkIUpJstK^zj@Xi^rO1>ig-q8_b zY^^g;vMpB03+JI^IZ6a}m&B@b6LE&;Q3CAF*~!>_1UMDgeH1h)uzS`0CU!lj8;#vZ z9_<2l&xB0szbe)kHouRO)L13IC`U=RSS8tnUA;X9K3a%&SH~*(HSyhdVwK!MwEI-7 zk`c2|QWmS^CBp7hlnCtR#i}!&Xg3Qb!0tsm7`y#}Q-R&#kDJ(SzSqR=S*RP0-K!UL z0lV)K?KVR*=|sB^FG5Lmtde-z)n1NOa`v4lsftx{6VdMUSS8oJjCXE`Rr25;P%=DL zNuUTN7se_nBFdUfZjDuPW+h5S$0|{#pk!dIlKVdcL}$b*xt{oL$AK7F(1^>i>&PA{r`X50FuzSZ=#_lxWRABdyphzl}x=KC6i*6e0~;6u0e@F^^jO~W)Z6Up#-Qt+QO)g2Z9Bvukx9we(Nq1 z)qD1J#_pu5E?~EM1xE80-tNREp1=`_|H)V-Ri!AI9jhd1GD`Aem0YzR5Gk=rivNsv zei5sr+X9sIjaAZcA4-nwjWOzH&qT>ilnCr@idE_?@=N?8&h#06`Y*!|(;*`KWy5~wQfvMCYWOr8_r;Na1YD}W z$JsP_RxWrO6Qy`ROizMEA#}w@&f`{!ze?~hQ2bFx^ zmxIYWp8Vp^hmElfzr4lWl3+HOOJfKi)T!=H*}k{fUp1X9}CrS)3U`s2PpIjs{(y? zf``2S$mc!{2|v^O)BT}?$;dR+3BS6LvUe%ZTv38(hhwRh!QsHAEnS;NK3JLUPB=S` zB(J%lbT=vNo@j<51JcAvw*RzI$HM%_MJyQHiw`=q8?EhiacBi@PGAW54#QVb0zOC5 zvjYIZ;a$1|n2amQacD~)!x!c;Gbi%;DXS!Agn%Q5wuox!Z~R6NWUPmC1KDo^8I5{L z<1x4?94tz3R43yJu1A%!+t4P>Ra}WH*rq4ls$VD?)kLGY=~lE#_4G->R$*zNR{O_n zwS9~&4zyTwA^OiasK10B(6v)?w&8)E3jm#J8%LwTIXs}h^tc#WcZa&N^%L<91s=4n zqtX>0kbecg?e73Ebm1gG%V@+k!+P@{$+u!9%00hOw57sW7w}x9@4@?o)j3}Tw!;Uv zejXLkKZkmw)sF*fIOpKY@A1VX1B%YWdOhY)53(n8Ich83kDjNuJV}a=zv+Jj%Yo(i zYLqMtme4o7Sd^sGU|Vrd zIpmu4`1G)+&3Fp$8DAmsgdtP$!jj==5B%Y7eAnNR+H33sj<^`Vzl- z1f5#p_KG^TU>%|$)M-T_>eN!59do&k!5YvGVIOtsMV)7;&WEB7p-J?0rKt0gsPiDz zS%^BY)mCSUqDoP8Gd_T_hfx@|jEUcd{CC~z8i)E>wz|@xu0n_??(PyXKaTe0#3qYQ z!x!Kr&Xc@26|{_b2={RV&!;;UFy!L&RQ<(=4g}Qg? zo}bfj;QEV$pdvbYNWrKuER>uFsf0@E=?RW2mcxGutYn#SphFKuQ-ko466g6jR_a|h z@KMD4QdH7EzeDG}k82L?R@6hZRBhrVc?pFx;6@U)S&zF-r-%X^KS&j4;bmY;{cZ_7 zn6T3Kx)4QX(?@`JP%%X~=w)b|Hf{(Ya9I`&>mUDC)Tl=fOR1OY{-BK|OYjYJ^-MYM zdVj%(-lvSt5GeYA-Kl?$CIMg?DtZzXwboJZNTLw6)+_Op#GBw#e2;5Qb>fU6)!{wV z-LoElyLrAa-eJhpdZ#wt>X_3QSB6&S>ZIq=Xre4zb^UW=dJ~vAcB+9fQbmsyS=<33-O`fTuNsv zsp&GVoKgL<>ZNse;@HgkH6-qiShyeZ(wUe!5)1p44IS)3z-TjM20~S9FY#TBuvt-i zLLQD>N6gVK07uhLpUpy7_#)%Nf_qT7x43g5s7ap$itrAF)0_wU4as4dz^wm%{0LHE zN*EPBbTg_GF-zqSqt4>3ofoz#zlD#(lxKqR5y5!g1kej})Gq-qgl3NCeHP!N<9XBO zn(@3V@r~noUj|ydBA)j*fIS$``vsl{BT~cSdFh;of+cXyg>_-X^RfiKlooaM&+!Kw zbk!W5(_7HZI4u+Ly*JtPx!iuuIMsTD(*NA6Xg%QjjcA;%5l+9=f^Y^>4>T!#?-ZRJ z#)qPgwCO*i$y4icG%KR!CnV))$wy@ES_CJpFG}Ya*h_XGjIhp|IPb`c}s_bt#e)1K%qh~Ah1zaQRD7#wmQfLlT`Ie3e=3`96>0?6Dq z;x!N?ijU*b5)pQpcsmulMe(!Z?d?=ds}yf%Q}G}a8-x_3r||gEO{i;95QWzX^^1;K z>DmscR_jadcR|Tg)D;LG-2)OP#SZ?)d#cOv1(Wi9DbM_G(HmTlll0<;Nx%ndt*#Ii zJ`)w3sDQXqU7vyq6i%9-obIykn%$GTY<J@MJ7To0uU z=%7H#&-9Lmgvwk25)x!jVORjZzZm14)adU~2@zTprCdG;6=f_;7s4N9j(g}rtovmj z6Tv-4@)3tiG^Uewc}K1aT~>K5Oqc!xTVdRGuviVq0193lDoWz23oR)>0%pywn$ z-X~w^>aE;e-wV(=XzmvJ!0xWkK*w~PzD*RziQ zA@dHIuT*P@?BusQ++TO3XV}-AjwF&~o@SK5zesfVjw|%B<28E1qXyoE8 zpbZNCD7vuqHmCZX49$gSvsTe=OwyH$*=NGa;UObV7#`v@!b2__hv0%`@L;LfhelXd ztoQ)mFm#H6$Pf}Jd)eG9CUECNyeQ%y#ssF$U@serk`+sU6gQf^yz1LU?SF~dpW*`% zL`nLtBCJKi3&Mwz-0Do5=_7OwR;YgT5)QNK6VV%$DRBzE z>mMt6pn9U{dZ_4nB7Kk?t>1^fVdaWwtD018kY#UCc|fqT1C_A^d_$6IA>S1iV%Xt8 zBE;Qk@M|+ZTFxeY3OdIzjym#^I2&**?T0c1U*mbatofeD zFDO91h4^&BQdLR6(N%xZ_HO{IOM55143D!_9pM)x4@13zLlD_zQF&$4M+VS6vCm{@XI3cYNmWL9SGeTJI z4=h*TDaM}5hTFtrGs$Y6oUS()&^Ec!v6!Y-ph$4*eG$lkx}=Zb(G`KQ6E(&AXu3`O zNagJi3(ZNRNus!IUv7E|&AfU@*5>m}8I#0ev592V!t@YkX%>Om_b@ElOYxx(!pQtD zpjF01-feg^WjbTC>VpgbZer7qV_ldeI*)g&TVT_La&j5f~ZHl&IyJdJE;FrHv7 z9Gt;xp#>jHvM?;Hh5cY#{yp$rSxn0yYO=%lcgWr`=i6q&4&szy@Fl~AOZ`|#R7iM* ztR5^Xy_7_&2^zz}v;Y#r(xSJgxrFT1+p?W*wOAtoiq}1-TjP({LqQv0{ z)H#uPLymlWneq4vJVwn`sClOG==|WLlHJsh;vIfzd}$w1TKobUlgcN;LC&GpVMLsh z-bhT};;7wak;*Se;dtqdgaP>D8erqUN&Gj3|EBTZ{`_|^QVQ{xp^A6eNX5RsV1+M% zV&>!Q4Kt@WeZLMk2GjwpqF!=-t=pHoBCd6$oWBm=HXtEIH_zqX4vXg^Z->=$j<=(` zNAh;`@N{=eZ{+l+KWX$Qh5jVb9~=I-HpJ1_4y1W3LaK!)(v#2`Vnj#Es-?agkv46? zJstINGzcgrbC%Qmge_T+?#S?ZDCGullY@`GSBq=_edQvi(8uWmoCd~Ztc>5^52F~C z2t7$7>{gR{%6_hW&lWG-iVyuB)T25RmHg7Q>aS2ouKmUWy5HyFR_#=2G*_x8s!+6< zgCR;y@pdFg3vPgWqMW}LNiF5tFD$MBD?vIgd!0jit`5=uxL-j0sLk%ZPAb2YDyy04 zIE^6gEJK4GtbejJf%m4tph8_B#%gyE?9@w_6)M-KB#5u8wmoCb%8a6E(zA zL1|+sgmb}5sO!pKi+lnb;8T4#-qUl8=GoAJs64g+_@)QcchaB7n~0-ZPy`U&zR3Z_ zd&DZuzm;Bv2;u!&f;|WnW#ehu-C8$m+LEVd_Qqu-dG|q7Ceq?(h3B zthQ67`;gN8H_cNO=|0#5r){P$t5MqBO*UPiB$!VI4NXT*6&s9(`|11b-zSw#m0JAx zzhkOY_-Wcysr6fAM6gbk4t$RX8}Q)3R+R3;kNs4-O|iEZEXMn|q3eEFA`6?*7{7R+ z0bkbA3(a@|S2u_kQ0M;5_`eemTF`FcI;!$-e4*YBpt$7={Mbv4@5Go&zINM>6!tNY zag0)Q;X%P3n7pNO4fy3LvWW%V+I@`X+JJ3hr9*mSub8~?^aPV97CX%uO}jh)IK0g< zWsle}Wsr;0aPx!&1F0v)(Y}nVj8ertC~~y7IK0b}9JQ_8veg!snwqZouCu!Aho$*0 z6vNaAW-{Po%w79thh?>#--tG5Tu9#X5LH{aWrv#id+-Yxw}vCb7VKf@4p^dDnqGs> z=?O9#;NFE&>r>z-Xnu3SUd6tqkgkElNsgMSu`;lx;J{eT^I3-?z0pP`6BRWBSH=(t zAWTMDFb-c8-vd~IAbY;+n2Zf%D4Ce!^K3xbjW(CBq(d373AnM%PL|uZjPng&1)nA4 z4A~^j_j2`{JKVkp1I(Fmwzh7MCx?Y@3>qDON+|_~5(pFJ{M9&EtKEsn+=0Di3qpaX z^@bstKa+?qwpk9!`5P%#ekj3DV9S9fb)#(0OfNhG{H$5lJn0i%meh?nx7rBV?qh!y zhTvdREJ1=Jy>;Jt#xpv(&v9Dbh7Nu+zX?sEbG+RfZ}+y1(~7yM!)-w-o#NiO6?S96 z8t&EU8-4~>mD87Z2CjLmR|0DwUOBNz*^|=?`-R%XG)x?4Nj*GH%{z=B>6z_pf{7%8?>hmZ=N{!=Iq6avKkM|XCK;;k9NzNE&{vZKhyl?nt z)XIb$U-BlN7sdOHl zk&rwDVu;{;<@{2XZ}`u~NpCotJG=o%x|6$O!9Z%9Fiy*DZUY|IQr_SNel!mfvPtuM zaD{2;6*&!{Hx#Geij~j?&?w3sqDwaNgf&R>x8VuSJHVg^90PCme$x{3i*4ze)Ms&S%E7(W}R!}#re3#lZ&X@c>YQ)Lwc3~;R zEA3mDd(h$PET{Uin0?C=+>8?wFr94b6KSH>;w>kpz6PHz&`B9SF|R2~{(i=EJ|uWx zx`(u26)#pRI6`@P1J(9ra-TUqD;c05c(%<>P};ZQQ=0!gRptr07b7GH=oOp-NtmS9 z#4d9kN*0SrnvO|YEzNf@G^fh6e7m_$Z%_-_` zM_}c6%fO@K)PaYwPSAD1E|(^1;mp(R8@^m=ua{8QbJtW^x^D%|rwcj?y$&&PzXKDx zoaPSSN)zfG-jz0bmb*NOCX*iK)+f=EyyalE}Vs&KLE9kw1<DI=b2z)*zLDRB3Or06J!mBoI>>VCWabV z=?Hux2R;VK;2|!omcYkQ7oSIwH23%L3nwpyBr*oTX#qT|nlFj+_3h5~?8I?&&Z7L5 zvPQMPPogJr`!qV58>wg$QuKdb16#?8>JAJO65?96=O&&*@6wK?OL(*TkSP3@C_G9Z zC`A6R+o34!mMZAB4mvR%slVxhvIXu(f-y0m{$S=L9cR?2eL73SU~DoB-fip%&l{SP zfVdax{u}-MyYLw6#s3$4W*qeEz?kvE-=VG%7(>ahHrSCtE4F5aqk=Dm-WqriVJcHoRgzYRMvQrG#0Y@Z0!jr$FR=}vMy zjmr;TQz&xr!UX>HT~Op6WJD$Y1>g0)L-`n025#c~7sEpnIuBeIgs1=k(}7$d7rC|6 zE0jQuTTLD2*7B~fxz)U3lmYyZ8WZdB|@Wr#ZKEj8mQ4 zJN$pa6XKZOr2QEF^Y|l!V#Ae^?6`1k1EY&m^2els@kr%og9*B|@q0j}vS=zTX(|C}5WedH!;0nBoq7bZhGV(v8p)^30Kwu+~v9yOnn`v$RHJJ(&?{ZsU z4dt14sXGCKw90};Y2&RaAnf6{#99%QHjH~J{v!xuMO?h}=-ISP`PuAmTgx(b`yT)+#j-|_bo0^+G5dZt*e>yp{Ks|Y# zbY&!@nlpS8)iRrW>~D z+_k)oPdw^?cVyN z+CAMIK!Id=NGynXmwhXy8r zFJ*YJ9G`PoMOap_oxvFEvo4fhBN^97e^`&~AZ%Ufp7cU#Vv6xA@lDK*jV<%MLVMI`Ap9S(>nrioV@H8V?oQZe=^7xfI@NJQWt>?I)#r}D!5-K)%=0ZcWK*{hNe{&mW&}W3 zto_d783p@e@=*NA9ZKf#+@WL+&mBtU@Z6zf4$mD*=J4F1gK+^Fe}Or?W~9r$tzgAy zxG7NkPW%3ule3Y*0Tw(*d$ZHB3<(h8Jr4Zs=D7-gEuPEp*XlVRf4h6mz~3I89@JPn zx82VDv~!>B+YCT17 zN6(_4t%KmwNGT`-tHD~+9{eY}>M80j7}(O)W>PtZ0)%hL0Jzc2Fzu~5K5G{1{eh1i zYK_{A8N~@ER>o+un)@=pb^EM)FceRBxNa2>ffBb2?;n>fn=s(+ZO~BK={b_Vt{_$M zxXZG}Wp6H6rC8RD@j3fpAxsb0_ZM=?iUB(Goy4S0TVZTOY{XR zBf+}r3WBw$M8GKlPB3(6m#|I((@-4evznD8(j?Jl1D_Ao?Wb-bm+;0i@SwrLY$7qqFEN_Qy1V#w~>7H!sC9 zj8pGU)hi&vi5ct%HUs~>jDt()O+=7fa&?|3$?w29U4_ex;~qw_c1_ z_yyIESN4zKR}}4+`ZRvSaH~eL!(n_dJ(xKpc`S)us6Q3=5qE!Iyr~btYfML>nyh8J zvoP=awRGevIh$MGe(VNZAVOZw>rQ=n$)s1vzoZ7*r1VHB!KT&-jRKBBSbNv9KLh32 z%$BN?hdC_!9O`~Y?Z10DEc+emUPrCJha+RJ)8{%Z9tmEh>I78T%LO}8MSSBbvb~{T zG1qeh8j*y$u&+a^whptjsrzcb=w;cb?nP4>dwt0V)wQ*H?~Jw5d+XJ;!wO2@O5e{ zOmYGfS7Wz#SQ_!Wpl$KerSs>itK0px$1kv~t3BLvz{a}{cL$|f)~F4WmSr4lZD2r6 z|D~?N`}9i&yflF`#v+c&n7o7XI=|-<>E#+L4P~Yyqt^JIJ2Rffl>t!p7Ho&>z*X^z zPrDQ$t628*5NmQrOEh2 zCZJ_xB!m64Fhzl}AIFtwN2->>s?rlDbbvX_2~Z3Y zIHcRvE!&r6b&$ophMpsrRb%!5Iz4uHcUV~bK;X{$8A+qp+UzHXJnG zSI@_BfEWjH_a{6yRhrQtO=yJeuHr6g3zr%?)pgnSwFRHM^BbJVhWj%dQ(G~zD{a)A zRQ@Zf2HS3+7V8KV3UtV@=i{`bJRT*1)%Ml1FMxISe56Bf)N(7WYI0?umcXT=;$2iZ z&;W7w{Gv;$7Xo@{TMysJBHT7v*FsW;(n4n)h~+X28!mgNgaI?Em1CCM)|-DgmFUWF;iE!QR-?>Peyy|6%@_+ z8n=+R>jw5mwV;I@tvG|CIsY*dMS47%%TX~)S=zu1yx>%aznW2#6|iQA+iox_--sRD z|Bw~-+mFCnGnnP33fi|!$yat2@9S~ur>b2@EJU>7V$PrK2Q`k=zj(p zT=_ec+ApnRw1iBj+BD}21BzYo-ln!d9cZQJSk0MfYlX{5;}TLeu=;KnP>jGhAOmGm zB5of;VIOxiFjhr%Y7Q@qRtHv&3Rp9ZOU$VM>kwQC=TqwbJakW_ivw4KbQ3P3<21V1 zz<8T(z6Y#)YJYTN`cU@s6L zl-a#_lc;uJndc@tzpQcC4+*Np5eyEIF;u47N5f%+^BIs8$? z6r0Kvn+l5EiH1P2sn;{bet{2AY^qI{-Au8mOtCORlTV~)0N-N-lWt>48g2VF?MjFJ z`w|-j-z%v|4&YYKIw=v5fetw);n6Q;PKAS@Iu7mOF9)zmYkr%@Wlf*igAp2u=LR&n@N;~0R;Y8!(Sxqe2U(e_NRAHgfKVQ$|;{71M0MDQP{ zG@&+|Ra-06Z zSf19)d0LUOPN(oEIUo0NeMPD@`i;F98I7%1(qcTDn@&7-Ewhw2(F0h@<)Ov+&m3kc zm)p2KUX7WR#8WUb+&Uz#pE0i&62AbrzX#?Wk!>~EmO4L$a)1<85ns7rq=*N&0W+d5 z|3B=#3w%`NnfM==fKky2ikd3A>B?HSu{H{8Q$sZaGjK-E0aQ?|QfZ@>_NQIN8E+*t zlAs(9L$Uv*Vz+M7?%LXRU1)b{u@y}~Nkl6Fyrf)n`!UQp?>XnaKJRmXo|h95fr6NKyd3uy9MVQaL{+l3uIP~p>6%e^&7ymtjG=Td zyMP{PRE^u3tewgmn+I~nK}mMXKMw)(KW5H^TT>dleXoM*PyId?;IE+hePrt+s%Q8k zUp6!RS<}uh`AK?pCD~HiqRt?&MCuOeecZ%JOMY_VJ<35yFxW+<@N5W_rP-T)JcL+i zf2&0oiYiVbf{B3OP>~cV-rcuscl3xD;sR%La4t%x<;^M0P68{1$kZNHifnWHYd$vZ z9MJGYcW(>mOR;I0S-?qV0p}n-!EL|Ck6_cX5SzYZ8EjgHSI($X7Ld@8aqj5(vEEh; zOQT8?)#pVQsB|=~?pc&s6`LVo*^?A62pC1pG;F^zu zx^*F2$GM|e$ThuK8&Va1r zje0kknKL8XeD4q>LufuJM(0fCQ&-08T{4Z+6E>6Hu{`@96!^mgBaEDJa11kYrUB3e zW`LiaqzgEaA7NT%hNH8`8Kz~X)~Dlo%m+}g%*Yvu>N%663vOmei!d`LYZtfCajW|6 z=z=d%#-S1;^t?O(w#;bh0NQ$b8SwjuEPow&k1vm`5qadReT2!gWA3(C%jUr%l1xfO z)~hs$4EdUrTrp`tBJw20eZ)o)7B?cB9FA-vY3OZJG7 zYg*nNHgZk$cN(05oEVVF?a@j-Jz$W5F$Xltboj2&{i2#&4uN&n1hi-Z0_Wk-(y9OASQY&hshI{%UL6+G~CyUZx zv6df-0N$~-*k%+L;LEm=-z6UMg$2;yv z{2LvreWQy-tfsrTgnv74<)08=2jj&hm32v7Cg*S@y&5u>^v)S?xw}ZCU<51N)H+kc zp=|>vBTiiqT^b)~!N63Cu!s&rg~bbdt?K7*ES->vigjha6>;F1EcGPG_(_ z^g=iwesccaVf)m41ZQ40w3fKXca@m#^PIuy?1kwp+K!a;JB|`rw9FBg|LJmce7Z#`DEs zdhf_poZnsBE%(j2`>fnQkh|X`_lt7(9b>%s`M3BVx6928|E5iDEWH6|$xWqy(~RP< zo4@U>|NH!H<4>+X;O|5JcGy_Q=1v6;V=bE^$eNZnwOxFGJqF`37>~ht491&|@oa7M z&L7jCWW{={cfD)R>mBjzrsuCMnvfZi^cvTNUALAf-DCf#nyK6^s=-hQQS|iv+hA9-OF5lp#Ivj1Fhtc?p;kTs5yO!|}s*=UMo~sF<~Q z23MAwZUeV0YfZ>-iq_1VOkt6=b9Fg)sbl0YWUrWWh(%xTCfd42@Tf)}m2n|D$#m4h zV~V3{JruQ0n*^r4kc8V{FUL`FM!+INYEWgatF+xjGams|1jKMrglv#LM)pU;Ej2}{ z5;ERM%|*$btMr{AY&U%T8|vDM(h+=A^f=a)HS{mxO)WzW(y*!AohKyH2A}N_MW2np34X_z&TwxVu;%;})tH*zxHu^Au@D7h6MIn@&we zF-T&CHZ{PVH&dD#PG#D2JTVh1`g9#Hne^(Nw<-BdXD}~^*zv?abK4InPZV`R3+{K$THRQY!?%Yf% z|Jv?@Gv$r>_et(d%Uxcsh4)L?4;(pg-DGut)hU{>5;QVigg~$ou?l z=WhoV4{?`$pTBMVZMUnpm_5q5e(X|OWe%FyrIu%=!86m~nQ8EJ8W^3-mS<+eGqZ7* znGMg(hNrW^RMhL%9>g5yZ|$;e`Dq>9aKw(- zo!c~an+Geo==z6(;=_aDQ4K3)56jfc-uAbMd?Ae-Pwn-zoj%HMCfZmm&K3=IO+_~! zu3l*$h>oFE*G=}AxR@?eQQ9cWwWR`iye zUGxN$F3AaULh0BQqw{tV8=-M@Gkx)QQC99lV6tUzG>#78hIkmZ$7lm0W=oCE-$kSI zchTr@7x|R#eV^Kic`=}NKBZe1P`cNkbf|!}I5BpdIa-cKXI48$i}qGZ}3*1mwrViO7e}1HT&1(Z{_Sf4n~+ zAE?Us5HrhNvW4FEbiNx{_zY>;?*hUL{Y zv6T3`0(FAgy{V`B%#071+3Ei@sK{TfxS{WE;sGenGQr%2EgjHM_W+J#M+(l#T-`w$ z2BQOl8I5p38rpsN}Q@9*fNcDY(NU3A_9)CK29oJ)K} z35I)ayN;Kn07s5QEq;CxWU*_YB+5)bZm8X4zp2!DK@&s6CJcwzH3BZPR_YiU*5N-n zqE)-cfQkZIc`iQGq*82r0g-)2;`9Nj!{NkN^Fr6rkIE0nm^WvKjvi3tF&l-0_E~m@ zBr_^RTBgeOs;q{UmP|)LjzS_$j!FMF6HyB;{>}hKpY}Sorxa;_VX6$htN`6mgUnGD3rXVI+h-U@}ku zsuabKZY6iI@Z1iHgA)?oz+}TJP2w)7A}gh~|97 zcJ*~vUk`w8p~xYoHv_C%GY_>o0K3-IYZya@E^s?BGrY)&yuerm=wQ4rm#F6KyC}oolSm#Y`P8MB-{^v3woso}@*k^Oq_Bqk$7@&?Eakd|$b?D* zxRP1kVr|jLC%6wx!NE7_Zd11l%fnd%#RMmOyXV^O1)$D3r3Bm_iy(d*2guryG8Ton znmOgXbUNOasJm{1+rEHn(T=svdN`hmA3gx33^OlH+V0dv$xIE(%T>{aYha^oPa$kV z#;)1tcLs5PEorFMmf-BSwv^zFwYJM0F2-w1JJ05u1C2r^Oz;8I$0%kdMI*2wP<;CO zP0PEjLs1n3K( zM&4(>zZO7EBd>@0@lP3kr11jyISu_1@FRUVWcb;}wC3O^Hy)|v{~G*AH=+%f(lrA= z(wR>NKPU06Ae+WBfghoQ2H8A6M8HN+DHfNVSO8h+Dyh5xYy{zc4A|%^2M3#ej}>g1 zePp9JSMa~bZqaF$_lZ&iY}%6U_F$VTys&=+-+bA2lL5Xt5qxv2;G2Qq8}Ld2zPS~A zlVqc|fNxgKde|oj?9n10?N~D2e6;f(Qv}#Z9}XF8{>V3&Tn+MEE>-Gyv=V<T;fzv-Ql;VXGQtMBzN1x*!Htb-(r1bq zqqlWZrdZ_FiQX_8pK>x;6{oBsLqU8M6;7dQsZ}bV#`G6tutZyDhTYV=W`bAz+$1ml zTnRD3&!H8kSEe)WZ1V*`R=qv?W1r24S7!t_#IOrTf4r(XBP-5TbK=O|i6e1CUnXWY zw{DTImh?4{Otx@9ERpD5McW9cmP#9@`#Z56iL&C`I2(9L?M-{0zd! zvuozH<8eHo>o9YHgoAVgH`PI@vc1EE?X{}4pzbjLiJXm?SuRJ%VJa-5?^Y%wX1nZf zXALN#r#$4WEqR#LpNyCjvx|Ai*qR1J@3g_8)E~EluxgC-P>p`jwlu zeB4@eiee?U0}uM*)cK~f=`Tq~k5joM+9-kDL7&sJ*;Cpq86BfbMf00(%dWmW~=bG$YOs!Vu-DhUFj$ux1!}u$;BcS!F z@m2r;ld$_jcJ<9e82VfO3xI=ZRv?C8c01DLRPVg$;m)zrtf*2lswl_2pMnamY@)4N!JPZ9tHPj>hE2JJQZqcwcE zSv60DJ>PNyEa}+s%<-`+{`{iQ)kKCmUeh&yykyR$F;bb358J0P*)RWaK+#k>sVFbnxL5)B zz3dlmJS4RDt&iU|j|gXF&|Vq+z>9jNERjGFvDggD*6zt@4EV@X&SvRdEJFhM$s`D_ zl&}3PABxcC{y{f+-!0>Vl%OY1Coq23gYqf32~wbtWTpm4k{KndJSvkKu14Y!k8wg$ zcL9yktO9}JILpmU)0gk7(w{w4Ue1;6Ek9jSQM}7oe`$ zHQ;8_BYd|+?(E1)sm=CkOXa~$*LGF%U2*zy%bNfX^xYEwg&hORQxMF(7)85qSNM8m zP}NQ6>igqCfC?j#iyUAQVvI^Bc7NUah8K;njKj#U-^~7Mc=|*QR>9x z?S#Y#q&wckvLuW(pJ6r0hHZ?T4vxQ&G$oK;9ljl}Lb#b)udFDEfwh^e0 zU4${}+sr)C@;Hq)_okOwo--e-Sbg@p>wx=6*N6H+g}toZyQR1Dds{&bzW(F;mvR73=VR}1#?iDF zt}S}xD*pMy)6DKe7FXFbKHQT3pd);6Y~h2=;e*{D6ns&FfM}|EjR)+|Xk+b8TKp#e z$lbhoJ=_fy##El2$1d$8Bdy|)dF70)^UM5$7C0PJ$We95(J!*BB?G@7$>-w7G zcI&!MWnD7@LD>=LEIOsSyipDfyEaa`meY)N{+bDDRqYZZ%Adsu1G3|GW#ofe*J)($#Jz8-_Xj^Ns+56@x{kGK79s$`IWH4d$nvw zQF#h`>lO#6x~`#?cS~g#X}x+UL}pjALqF$@FLPVm)eW!JSnmFY*Y(}E^xYveQ}V#T zG+RyF@xD`TN4`@!DRb?0MGp)}mHkrvAckJhF#EmhG5=oB8t0e)_-HU6Mfoj8O?a5? zo?^RSBk~fqzL`C>Ho8D^nIa7vzQbukPIDr=C35|aVxIVr+u75pI@?~9J?2%Ti4_Cc z_g{Sj0J(jO_#QV(qec1tFLvfiLLm=x&KKOD^@$g>0DYuSU-V;{OlwvRV7rB zho>vY>2kK@XiO52-Mg=(#eDr)$?#`?o%n(mfitiaaX zjW2Ie@>INJlBZJ9k!bPc+AzZlr?Ew1JI2Fu9+Q;%Ayy$ir90%^-ji-ivtCGIeNZ;sI{HZGGTaEOsQWv9&#pp~ztaL>_FH56I z%ak(;)+29?Xiv1zX7*)+CEX{DE<`K_gdwl*O4-*eQo&sXV-~a+kAlNO3oE@Su9T9% z0NXstol;DfrW8+;XO>g_Z zJ~Df#rSBek!R(>7Xyyf8GJ6R3xAG+J{Z&cLeYAiF$=B<^M-_w# zLmVKnVsOq@-1pbOG>*5;pQRvJgEkDJPXb?~CnsHd^h}4mXDx|Ha}u9KZ1D>AH7YD zE;{A>6)pZ-5Lj2U+8grmr}z(+G3kzYj$MkTWTzz=h@V5-5GO?h5@(tFe#53xcb@Pd z4X>4_qA_nAUU=Q^JYiV6hV5Ka!z85!?_48XnY&y{@$M~mwhiK+hc0@ z&NWI(hGBsRXFev>gg`ug`7iEGAPqE{y_bnI)P}~3yPrEx82YXgi1@1EEz66J*TEzIH z^X{e;Sq2lW>MuIiGn}Bw3ekySVV3s9!hDk7h4hIBvLHtrC9k7DFMkhhJknFqN{p{3 znrTX7dftKQc|%fC3}G}KIC29zxl+G3Y02zdT9mrfO9arZu%O203NOdWc6|0aGEQ|0?keI?K3M0}^d z(o8pe->FSI)G$~_m~sjv7x6SX~Z<2y#EJK|S@-6rmcUkP^*%A7X-p5*Uo z{?@Uh*2;F|?hjoE2mh9{gCxWDV<;45@HJMj+oNFt*zr(YxM04)GM=r11R$A>>Mz;Pqy zlo-DRXGR+(p#st#5wR-`oK1pN8tiyqD-{{g@ou8go8i^e0%^OGVC4?OjQ9bp+oVdl zfOne&w_tw&+L;7twm-1Au;gMg7n9{;8W+>#Vg?s8 zbg?3w2$JBN!=#wJrH>;Lx6NwlDvtGDRE9rAp-akt2fO)54QH7?mC1RRbdu9y3~EzP zlO1Jvnmi}`=Jp_-2F^X{LJm2O?QH9pGUn80k}e$mV3_|T9u8ibu}lUgj_*3d`elv0 zaH91~p-bswEbkoo%$r(jUdA30UaO0CWU|nZi^xRMS{d_bV<@7}@kaFFsKDE5)N_4| z)CwBZ2#-d&4*RD*`FP|vY=w?K6BjRAp`{;kW)hy^3CT%AE&;r4kh|jE<#e;7>)3$A z1XPXe&A5voe$^1;Qd|Q)WWNnaofwd_q5a4vPwMGKYDPemE)D8DRqQ;6n_W1d>o_@V z_$XKy^d;g^(JY=i%|h8u+mUD=kUD0C@YBLkh`$wyK&G#LR7%t_=@x|81Tb#9J=9)K zF%{#SZ@bw8jbUy682CW8e&HBeebUb_|KWTjucU*XJi<+3PozY9^6v5CBGqmnWpZrt zw~Jzv83&9ZIzQ1;x_^dM&OZM%Y!HO7pcX=G;(gYO*g>;k&&q;nDmX$~sVkd+tOo0K zM1mwQ40h9j2K(^~_P9S-e)*62sOKm34K5TmFXN&{N;sAyZ^7UZ-bfuSJf}o^7p&Ol zbj6MhS1iW^=9cX7u1Q69tR~GI;UY13HA1C;Y_~(;`ZKU!*h11n zIfp{I!3hC3xO25kQu->sOkXK=luKTD9Io&Oidj`CG_1pXGfxKK^)u+c@pWD#sbB z)Q1LOOogj@9KU z<92tF+$W{mEGc{+{Vs5qJJav_cctrZ^UtGlWx76nnRa{ov8LO$H+>oN2I)>6POZ^K zN$7^G{HmCrQvW!?yW%mfUQAuhE-XQZk{SZL?U?H{DU_=$Z!Ga{l%v|lX-uxAe56F1 z@#T(G#UaPOrB2d*AGTs8edzj!N99NN={P#;CE7;5IQim>1HglO?F62UM&aV@$R|VS z%lGjN@csYS;O*xJg|~B$`CkriU94Jvcx!;;mu>RD7v9dv!P|4C0la;Cz`+1+Roejp z?jZQi=xo^%U$tss09s2#rSQZY8wcEOp;i_rprz0B4nuQT+CVnGDoMt7Jh}MNgP|qe zUB{A;FOA`ZOEP=?zWEx7>=n<-R?*zeZiemZRz@N|pI6=t<39`K^M)0eL^e0^5aTe2LsG@&TG4N$xg1vk|SW>u6g67g-)#+`7h&Cbc zO~{NgF$Ql9_8Ld#$$LHAHuJ47?sapUC+%gqU6gy;L8>An>k%}=bs*~Xa2-f`ZCrtWO%NU|6ngYX!H#~?fg;a%5c zS8s^k`LFaPS+OAu2kk+m!yV-!LRVLZ-L{rUvq5p#{ruwiYF}i{do{i~5b1KC$5#g; zU4B_0(&d+hBApb2I-~pkkHwUy`wUsnRmIoKnP@DW&kp>1DA7Neg*06>~L^c*ur5k@OL9h)=>Deni*t z+!v=|bw?f1bwoV+`{~QBk#Y%?QssZ!tY3G|rRJDeFpFm0Ch$Rv1U%y-F_rZ1CzQp# zYfmU4tLzDWd;4hb4S+7zuut3Dr|n(0Y`lBMP-$-;?Qwd*P;KwJW!Ff#XyDjU_{Gfn zwbk%l=rD(wTwFqaMyL9vSqo)BnWP%JkmBfYvu6fb4HL=+;2X5>dK5U(#@#%1YVp-+ z#atuFb`|1fo}zP&P39GNKgkIBhL|K4{wJ>p__Md0k($^FOfr#+W4&RcG1{hvz{Z`I z86&yfZ^j6lUNOnLb~IL-)aa6~kz$=a6KXx$Jdr{%+hCmi5b3)Mqw37cF3hgit(X+K zb~MY8hGR^WnPvVlE$cGx7`ef7+OzH4L%eYyUM>Dqm%cCCmXg-%i%xx&Gnch9CvHNtHW)-w_yu22cAQJDHyP|hL!{awgR;T6Z1sfbvUI) z(lmkwJ2)Za@`krmqG}CU&kubR$S?n?LRoi)D8M*BIq>n>VCflWdwGW?UxH7G#H$Jf zxOH%sbt_072}~>k)aS!+Hj{>EQfAaexYH+F-jdkCQF-`KVg*MvQSJ~C1L*Qfv~qDhO73bCTxglLh~>)`Lt{Jp~8tLVHs`1><|FY@=Y!+}M9 zl>BDUBEj9x61I*+&I-T)JRT$S>fiwwmdCI>rbxrdEC_Pg<@EZQa1^TC z>IjO%!Q>amp9v78^wqo?e)B>@7T z#^)7~(bq}RZZPcJtO`>MlDe01rQ#+8>eVmH1Q*f%;J6MUCZ+6vuaBTg-aO#qS;?yOI zXb+52dDai7{!CkjbSh45%g*LpkV2f=WN@n419VRSz@vNK)Or*{2B%)Y1hF%k4}wz# z>QLpg=QK7hU622e3^zM*x?t9X`0Mt^tN_ORVTX6_1~q;(W-Xg+Fsqo`LCE#v=MOLG zJXKCcdzy8>an8>!y|Ybm|7yd8r%o?yBU}Tf2Zfmxnn+a z+Y;jLnFeGj4u+$|jdA!~6S?#>m*HwL&nzbwGr`DFp_&Mymaw<#M!Gw~-w+%1Jb z!yr-mkb&rxt_V4fgjbtvP&EHyOc=`#>;{iyA+sC)QBm}}GiC6KqPOuHDB6+Ck#N1& zpqe134$$#u9)O{T3Wgpk7CoJAn02Jj{Ft{L8qj(D~7_a%$C;DK7!6306~v)herbhJ<%N%4G^@H=d~6xyb}aH zJJrw3(naovoL$r&c!|>s7+xPan~fpJIRSIS{Qi$1=by?tiCp6& z=U4H>IUsU204~Ux?#c4!kh2{bBLQgy${iFr8#Wi53>y!gb{1uScj+J?$616?q5dGa zdHnog13HU7mg}8;fx*rH;N#|T^M^+}zr<&@H`wQTjUmC;w-(~h+qW)Z3b1O&y>FJm zYN%NOCK$8A{@BjP%6XU?;@~aqos;msR@Q|@`>`4+9Lk04k~HvkPQra1b-(*Mso=^T z!V4#6hMmjSzKC~#K2-=jX1HOTyq*`7ijx<={O4Ql(*5l=?6CAnqAq+>l#J8G7CtSu zb6iYF^I|f*yjS2d>zK1}C2dcejY{ z|Mo578+w6v#q-xAfq}S}Y4pevhGNwo3t%GZtVWc(QwrSl5;Qi8WSE>U3-|H!K{B8B z&tN(555*n#dcB$_PK21TjVJH&X?myb^W<@utalDr^?ot?0b~G%vjjjxrhSKlV^l6| zrVaQ!_!jX;7anG6eastnipYdx3T48&C60I1DWy(?e8j#?h@^5#DSC+|TIlmH>adGU zI74N^t9f?SDUi$2BkHei-XpHpI8X$Bv%Vc|zsU8T^8jYF=Im1FKFcs~A)tU!506Cg zb%mi3mvbaKn3&v9bk879M_^{ES4Z#oEbqiUovFC{x^Y9tIRrlgog~jpl5s@EFH$B6 zUtgV0+9xDarj!MPz+$|Fw9=I5B2Z4SQ0Ef8$|A{`OoYNJduSF&aw3t$L{`9GC#(%& zq*SnCNf)8qLH6E-gNZc6LJ(;yj&qyBbx_Zfa8cD;Sr$dI?}~RNZ>QqEcO{d&T!zI7 zsHc`rFEi$KnGkYa>J|^h177W-+?ptNd%0#|$Buax(k76t0pL%hw*Th< z+2WT6FI+UT`Ro@1M1v4u&`<=~zVXG>X(WQB7RH3h-ttXbhjUR*8Pa;gYp{bnDcsW$fHW?Ymv@R%ahLWHfcPqnGXBXxk%%ug}jkUqYeuhW~1k(8j{Micaw^Jn(K53`{daRlVGn?>B z^KE&lAqnq0SZuL-4emN_$EuptQ9D)*OtU!$lXSc*!ari?!}^6%2rs z!v=fwC}IwomM0z0DeA&W&hQGP_ABa zazmcgvp=q~^Gc;FXx3CR8*Q{|ntQT3Z{JGp$?9fm^7pMsYSkfJlgLQ!Lx9H145_2q zKr$*fxiKKj4wsu?--^su9qwBcOX5`~-elt3`2>G~N7pT0X4+X=9X^*(*xnBEZ|cKDjLKGKT9?FWPTCW%LIteBvEnDLivck2e z$YGt)M#*q(yKM^5ctFE~^$Nvtb>JvP{6)9i?PMJjN=|fwthuOBmAgXg{$h0D6U+=5 z5oP}1B${BfApXK+r5C|u4L<;rm2Ps#o)43iLfv(?DA&FKlQkS-&J!ujr{u>dB_9F< z#xrv6D;f8BtbSzNS1RBd2#+;^V_b!fpBV61j|q?UKy<;?(p3}01Dn+ZJ%2#BMnsB5 zqJWQ#BQ$q?^o}xK6Hs7Abv9)p48-`MEqO2^Q_dt`;H6qECcH^!dm$Fndb-dKc!qT2BtP`_6lG#3)*)|WQ+@J9M5{3rrbiJ}p8dS-8NU->M z^;b8AtkcAhb;6Tvf8LxoWuM<>=KSY$IH^hFnR5*riY^e6$OP&jJTnN-48lVeK&C@e zXGJdLXzVr7JLH_GV4B@0Wf_cuQ}JPR-WQ=dw!6+tw`c!r${++7gD`VE5AMnVzk{(A zerHt;UBcCP=c;nKfZy57K`lHf4rzyeWGWaj7!lVgTxk$uIvT zm|UdbkHF;r04Co#*0-ador*9O;u$nsU5B+Mnwb{X8%0N^4#^e%DwF2VutAy341{AllXxuq z7DueRtH}nV)Y{}oPLk9Bek)Z=eBhPd)Wz_p~~P;;Lw45oo<(_YjFu94N|} zu3-(kC#EY2f-qcI9n4jtNg6&#qc_lKm;1*`x)_(FBIy-q)E+vL+w4uTfsC;=ky$XJ zo_iX+^=7;`w`3nAqeiTux158-;T#j98eGK-q6~~S{*)_XUzVWTzk^Ft>HMtw^?~B% za1+FPe)MY7-4hZ|Su39TSLcd#;QLc`DkNrIk(hhg4F0a-73r;rT;gKt zxNtb`-BP65)Lj2Dm$0Ub>fJak*Job>3Xo4Z3jr?{Gj%#mBJi4NlBiO5>kJWIPx68c25~q$rJas3RSY{^mor0k@Y$mPFx<|l0s4I3Q z+@9=$#}5;^KG%_vJVBt@oxSK8>db$V_c0+iZbx=<-*5G_RQDCKu^iX;V}A$GI@M?g zIDpY@&JH$d3XWv}Kn z@O0zD%yc2Bq`qV(@&7Ofp9oAw_PWxm>b|{VNDs+k1mlXiZP{}k>ocp5$Qx#Qwq<)Z z^cmQJ$MT!E`aua859c_PO|ccSr>%_Us_(Fa$pugzO1!4v_K^JL5EE|MUve`wE`~_VIjrK=`F>f3&vbmqHW9pPSwU zBIOUy#7t(H!SC7Z;8s$lI?Xh;OoI2p>Q{mhFZZTq1*=aNtUe8-p8AF$bWA>jlkVWI zp@Pq2Yyupo=9DA}9MUEZQ2j69#tN!W{}f2=Chsl?Z-pTE+%1)+?hU5Pc|cMn&D<#1 z{;|ZoH`1kai2)$#)-CJ&N13yRIVF;9)@4jVjXdmdGULeMv4$>9T_%ZP&0rCZH)ZdA zd020bq&Xa=eAj@+0W z{9LuEYqZK#)hDS=5tz(5RmY;g`=Jmx%-g{>Fx&eJExHl>*UScB7ZDhm-L@`VCTi#h zZ=rUu678VnMb%o8Dv8zKAEP1Mes&Fx-dR2vB)E1>qT>iT1*IPH7TYmTo)@R8R-DN= za|ld&dDmijwqsRsdUIDY@9vrUwWYE7`mk#}HH_n}()1(#8}(~T{D(9;D1Ah%J|oqX zb`6(Kq>ry(TONFTM9_Ttb~>8it$mbO@^*@REAM5m8$4LIX*BU7FUW)UV)ZM}f@f%NdRX@CRa<)hIGh)(TKs4iSMk*LzVg(%YF52B`%k~$!T~7D<(qhQcY1_B z?3&bxa`g3kBR6D!`{6+O;Gg-xe^I`>g75esb&2JD<@EOIqU;2}AVI;+yqi7OFBlb6 z^erkPF2nEOcj+L|d`b2PE&ck}RpWRo+nEco_Ku>$HBw>c@3hJEsmYzM#wF}M`;RwI~D=2^j9D*+e93h7aOq{RAAl0kSMFFttjVTa!HvPm?^{27C&$LQ5udWP7^ErNo;66MJ6)4e3W!6eN#cT zBl4=1s{E?69nJn=zR!wj8|R#(pMNPFQE_^ZjOO!6WD9zmz4}3gk`uGnKFTMxr7HxG zeJJi4m>TG=4&Ln2v8IaM)m_IC`qVm4zF)y$u8FyerPsVzB2})+y(kbPW%6IRfiLIO zyU7$v@cg9MT|a!1hgfw|Cndc(CH0&4#pY{K_BQGXm_i~i77N2YZ^QS<0lrc`&wkZR zK3P;+=ShM5MOI?*j=wg%p zp`L$~GR30b(`VbcXgqEipPH+t@M=+bRnL{x@ODjl12e6tXY-c&Re~N3W1v-c)qDz- zOW$MluML!mI%2)!ni0A>LYkAu4(WI3Ptw&961Gx*zx3kOd;tQiAMgV{i%Ut;TWl~Z z*8K(WI`y|z7Nw7)Lmj+K)&YyTz z=SXFuLjOg{vm?xn=GjSAk=UoosvcjGuF_Uklade(o)*=EVwW_$risdV#|R)wS#>3ssq{ijNHx}3-*A3Uj51UFi7 zaHGwco7qp^;(svv$r<65rHM7@>*~tvm_KZhJY?$V1EnEHBte7OE2K9nB6kxxJbkqy zoZR&PE$(h*<#c0q8Ph+ztSUNBPLd_Xf?0z1XTM?*n+{K|pc8?wym+a**F3oZ%%}g1(7sKaE9z~;fzDRy%^QcK5-QF%U z$cBo(;n z4ifxHjyE!26hVwez9?z0GTVhi@O~q+YkT)LX^l@hwJ+M4?~pHfn^VzcM|LKA|AZId z5>#|qD&S-T$(eyhRMJae9h00Bcox}M1v9g$k3$A;p?mYG%<5fh)$VpOlS#b4(XMzt z8Cg%78Wc%b#FmRW$-S?Xf3e+^@PpB(o4Po-UPgI@cI~nm%+U2Z2hiNHbn0oVVwEFj zU@|z8<#DhYpT^zgm0H7tr|Zvs<@`wEvg(bbp#?SAUecmt)0h*$+sWK8z^;AQspwAj zK5a*E+q+JjX_=?{M0#>H@n7h+VNxZ+%Mhy563v{d)m@1C>DC%@4O_kII56AE%%X2y zc15pUvD1#com~H(RPA23jC#>F3ANX#-g@7(MLrT^uTqn1s9%;mYn!azAP5Bc`8h(^eNG~`TizUGXNFAbZNb^(eSC)_j@d%lA$NTpY_44a}z&E-)EJ<`JYauhAY}re%x6;SAbkdkD?eR_yMGQt{ zM{pKax(S!k}nQxAW_ zdS8W2(ix-4HERMyOD+BhX;&M*%J^A@60%X>(W zFu1_3ZPnb@59nUKTQDmRo6JKHg;l*fnz>mY#%@6sDrhp&u$y#M7cwx|kv12Yb7$n;-qM;G3pQ*H#=}Sl$KaP}T<=&YdFb z7l4CR+a3~P7VBj5(682q0lQ)qldpt$ot3!-LcA*^#JDybh!D3$GcAWeh_@L+EHtlx z5YN+@a5Z}{j)zK!FHk~!A%ysLfiR(#LiT1sh*t~Q15fupjnxFLa{(b$`z}Ukv+;@h{k5|M7Q$cgGbBD)HWnrtL6e4U_qq7$P_Cr);}A1Xy~_fR(V0mu7! zy}tXMnMrS46-0~TtA!R{w=B7SPjWppwCg;`!Ff*PRVVT^cLO1=1Dyz|SJx-k@8X6> zQ0liSd%gC7X#yeAG>Zc1oboB%LbKN3q z{cggk81{2QYGrz5YIizN+Vzmb_qf@WKeNjC1XBtneVtXYT6VJt`}t#OBF{l(gL#fH z3A+Z$bjy(54cP;YBwrJ+Z`p)=U{Cs~@Vz42VY?qXHnXl^$ zm(ECfS3+n_-4Ob7%y*WYQK}W+48nR^j_#0;2AGd3liv4gl>WYFSHB(2JST0t%MBfx zCmkYR7JrIj+21*3r!%hRDGz44X^!3=!CkrWFx=Diup5JEH!cjZqLGwr|nYlgqbUmiJy zfz?=0M;WZ3kgKG3r!2Qt(h*%SMxXeLcu%uFF|@mwCw*x0&uu=;qsa)zYIIIk?}}zz zedr6vL>ccw(?-6l%=lVqF>CAUUqUXCVXlx@;Z353|0uOU5l z+Z8XWa7?C?G&DIQi-cZEMp7UfLp4M+F4fv@&7;T`taWA*)apaKqRojw-suybe}*E* z-3Nugh3XlStY=Gzj;6X5xK^5c!wlQI@OmU_r}k}|(`;;!*q^l{c;#|P8m29GrO;$| zu_4L#oi3~D2C}hT{Vp7>R&*;Q`9dHZX?=qYcbX(SYz6&!8jj9#r$drOHufW3^mqcs zYiVshO(y?}MVx2mzo3<{e9+{}YTz-=ma;QKlb^IJ_ShBMoe0#(2*=JcDpuhbP6U7^ zTEx{X`#w#ELeJDGcyNZc8QDWSnFTe*i6zr%1HTrXSR;r?YZBcr;&zqUhk*JSOQfK$jO zhvRNdK4>|8Av5e^`uVof+pRR*u64Q38%ldVly<*E%Q%#bkN$pC1)=w&?&fOPv0P2L zd!SI;=V$$ArWk759M6onP^m3|c0HWVHbZVjP*DG2Qbw>fGgm|qaVH7Ab(YcgrIY#R zO61#L$SgYEQbkhUqk@#!(e+a3%IsY&^!Bl0=77 z`xY|pnCS0|(eF5$P}LV-2=Nn5qe!byLRR4{>Jj{u*)wDnBCCMq8Nk9Z2Wizo1ekla zzHcDiGm!2XNH=s9rKl)@=02M6=iWdd5{X^^D18*nO+R+~{=NtuA6b*~*+Bch}VpdxSP39BlDs<2z{ zzq;C&cYUhM>w&ylAn*nS*6m*p0RfgJ8bOyVQ1vas}~Al3i9qUV)ENC)CHol z2-=hR5pY};UC_m_jWl~JVk<)DtI-9`lp&m|z^bC`hUkJHm@;2rMe1!M5Ym6InPCM4 zbtGkdh@+d3NzPL$SK#Jml*;8ViN0A0qRx9W5~~tnp(q#fot+b#y}O%a`YL)L3gTr} zyDFKv2wApW_#IU$qsHwg%kEHtalFc&mqF?7oiCLrTjgZ_4>aI?TQtgOUC}5nmksIb zIY^Q%AOXTR^iw$=Wawn|i_uKGp;0q(P$pzkSUe${R0i2xem#|OE?zgaxXVkl=EXk! zEaOgyFr)k$RUtA0nK$?houjnr1-oL0s)Apn4nuR&^XZ$cBMR@+wekmri~^!UQ|TLF zfJxy7UxyUg-nW$Gp?nL5TPNgLN#2V|=8S%>?}FUbqYH+ff;EHKp?TA&&(%|H3aKjI zln}gUAb3lnnent@gwSS9lzy)6vFi|-c4603elfaKohm`z&ScC}^~}BS&(WnOaKT$H zo5%4Ig6MVf`AyX4=^V-37U&!u?`q`J53L9~>@}kAwM4C}I$u$*z6%e@X&@A!Wqgmn zo`@59580B->}WgEi6sf`BFf+_X|CRNB3Vlm%x@Npj?s=>*I`ARP5tD}X3>4a9=E)O zzIW7EP;GQ6s2qKt{8ypBs4XP~$4(K+m4VzW#t zdTmkGa@UD!eLwT}l&E)=o#;h%zC%^VqDb#ynzvFn%I;mfCSoSf-%mz9uru)^2t9oZ zg)Rbq?Iuzu%jpYfbwiP&h;RDoP8_%(KGweGyBogW35C=K<)b(Lq+07i9n@F z)*hasVO>+GVMSgOS2yXt(hy`in|q;2^m_(0Nrt#U0_uIOt5L5)lXkF1(5c&HPE`{N zO=>e`X5M{e>yIewLz6x{Pi8E)RL%K>r-O%|65;vmr%ZT$_305FJy`NnCOj+ux`gKg zLwG(L5}pl8c*N~lR{=@S#SrfwI4Yw6##c*(Un|Xj0Il<6Yxx zKi5!1V5x`*`ym~w_)H=_z}%sv1Sg_8BZppFa(xds=<2}tl#4a&wNM!f#@tGo3J?W~ zPjsC`$aRR46YE!|$jKD{z99b-vaaekhlsrOnwk|wze#iGH!;PbF72b=+$H+Wao(uE zN9JlD=MDLC!nNDcZ^G*b`b|j8C3z$UVQeZS=4IK@s^82bF|&lk+y;r6TS#K=G9>0_ zI&a>$Au*!cJOGI~m~yiw^OcAYipA^{G-W6s1MQ??hePe;SM`PQGkmcpUkAzOe``Ls zI8evuRfS|`Bta@Vxk^4Vs>v&nqC%zUD(&8KBVXm~AO*%m2RR-cWRKB73e`mssLDou zd(aX__Q}&w4Oy=rQIwP;BLg+0(K+^z>C6{#g!Ks2j=ahV4XT<{wIi>gc3hQ2y%k;B zt@_4e2f~dZD2cw2aR|YgtVBt>&5Rj+BMQU6(PDp`%#$(iE_j=c`)WwYlhG|cN|`T+ zpI*#llt@*#3L>ALjCAX#K&k@eqDD!2 zHv|lh>I82>ctc1MouC~#R3T~PiyVJ$kz^p_g{10MpcQ-e^G>FYD!XyGb1HTx`Cnxu zQLq)rNPZao!Bvk&NO}s?gOKztTPDy7O2F1&?u}0HWyf&xN$+<)tunD=NJ1hx=F=)T zbiua)t>XIXdNJ3@0Ro{`uvOUc^;v8EyXYcp0+rAe+F0z?cLscXC(13z6biw|`X~e+ z7rHbdlSFpsl+=7AoiX^Mmp1gZ%l~ zmyD1y>{+AydsYm1k!^jHedzkGm+*^g+~P|FjmT-Eh%!5rjQH^_2iM?1ztHv>E#Bpa zNO?9N66Lx65Gl{D{*-6q$b7V8yiNpDsn^Nx%tOIxg~Ci9$C93CW-0*RSC}E&Cpx*$ z=~f6;b#`r=+R*n>=>de9^;#^#%!LRu*cUdaMD%m*f|`YVj}k*x0u7sya|B*QN4MXX zM0`h+dM%bR)!X%P9D$SwJ@Q2xQ=vMK0GX?xOfVRs^T?RHhE?Y&;-qT}t`%@J7OQ;e zrkY|S-KhVFjCnz+UnUc!?jUI9-lXk7x)DbeJP;TB-jw;aB;z82j-W5eIN@xa!kioD z^@j%~HC;=g02`o5z68)jf~@lBZh4OG5E zwYY?s5PeSZ}1K1z-=Q+Xt zA~?JFV1oT2D`?2J3pO=YCg5CE60Sin#`6O{N>pzLGG`@gU$U!JrytGi1=9b(pMxH{9cwk3fuw48NcBA-t8x2(#&W#u?-j>%;!&qe16-PUcVYDMxqX4Vhgx0Vs zmrsM)CO=}5c!ZYM2PHGZ#-NRgF5QNAqA0zhOTmeO-iX9xI3l2s^Zgw;DNFnv(Rvk+ z7RSB6;cCbzuI#@lwQ#`3-x2-S285HbDx7f0!YuTf-Bz_`ABi@!3G{ilB5SnKrXJO; zJJI%js@Oks#W8~HFRS98`(^rYtA=z~^vL#pDRYQ*W;72U6s=J*BJS5gchRy7vIu=m zIr#SVV9t!k3e_;5@`r0=1of5CZ&?xKK5(Ak-b(Xek?C+QHMpf{k$%&qzwFA z1guSry%glG`Uw?6qjO(V9Pg{KKF(k>USC!}h>tYbJf#HT;|w-m)wc=^HgA7HHofYg zeA|bwa~HS3Kj}l<0{g101UaZ;s>c@BXo>s)P-mdB!TKAjnvDM+-hqLibGIs{ej}@c zf1R(Ga>RCnV(Jcx3+3Sg?Co8Mps<@AEH3jXuj-{1+zK$hwZY#Dbg1ir+~-tM`bjhB zqY8jU9R+dLPnx0qXrrFa*GAEc*5=)=Dp`CjwsA>R+cl6b~_O2`-AY2zwzQy%hl+_#MzOMrhX_S+TD z8RUyC`@fHTt!lL~L^B%!O`ijIB!#Bf{J;>3MBLSaAQXFmN`51WAv!Z#32y$$`tV@o@yXZ@n_q5o`t(! zzLT24u2Xm+u&TfA6|ay9bBphh(^4Qu)vASx&OL(N7Mcb=4yRs!h&WX|+AuqaQsX0x z;0^t8>JLxvv(W?GAUO3_eJD8fx=lV_&FO5&VCHythS-$>5_d5g5LO4LKyC9qalsB; zw~O`ZcniNAQL>;=nWmUIYh%dI5ZEl=qMT7b^Uy(Tr+TCPh^I`Om^gjUFvBVrXl0~U zkmsHCQkBuls7l6XkSX%@FRG?d|1S0S5*-bQSe^%p7Z5Xw7tzh2coAo>?b&;}kA#w7 zRP%kkP_lfR-6l?6dX{E3x?sHQKI2EN)8H#hj*-pjJFa=-4dcuqE-%wv-j*>1&UpR@ zKa*h=dI4@dtfxlsxHw6ea(AAC&x>Lg7OJN;X&+dal`6 z1vU9-STOY0k@ojdrYKotay4eYD}Fg3WP^#%M`;aLTW^2Ym;JlIQt5 z9R&OSLI*7j?kXAT$7A25GPp*k0XK_Y9FH%9h?9}$13V0sQWb?FV0^$t2FQRz#hW{_ zr@+ZcsZ-7|3_Zub9HvF3fxASVs5CC^gKN*y4R(n9>ph2vYlrjR$K%>x^~bfJKef*e z&d0S!>BEoWUyaFCBGB{rSMkaeKO;TD3L9C-zrv`Z2meo9x;*|BwiZ3OVC|3MUt>nm zP3{YI9IBUE?zJMXs5YD67csRO78Vt?N+`yvnvA?^Uh%ouHNwTNp@_F)cMbcS0>#6& z*{dPaO z5cu-ope4fgd_F>L0|$*+_`>V|doDb$DTcZXUi2~)0b*TnGB=_K=){3jRlr#iSD!8v z!PWDnp?5;JapN(>&3Lc5s?x!INMv8}Y00?)L{wVW<^1jA5s=O~Q9Ve;0&y{@={w^D4{hKH` zGsAHKeK8EUSZ!x+G%lbT4iIhlDX;^U17DR1<9X|3HpGRPBY!HBOp>A1%i?Iq&zRbB|>c~B+nX;NC(Kv0}wk>`nz zuv#{27~)9`>}-&s8WuC+h7z6oSzThY{GKkqr=Vha1_(R_0^hl$L6M;WOwRyj5H+TN z890}eC^9S%)5o47J1+>G5*I}jb?T=0_xdC@!{;S^5nL=8;smmWspHig3PWIr3H@g+ zjunXD9d)Tb@Q^QPvx7tVTm3!qgl&<>#sA~bg>71{?wI{A(lZsJcSjf8AoGda2l!=1 z;0iJ>EMu@f7k3h6J{Q;dg_HAVg%dAjRupv~%M(JZK{^~&iBdvNq$C)n#i6EgCVx7eX>-a2n;6o^iWSsbu2u0#~ zf2LNOM?l(ad|I8_?KrJF6}udXlt=x@@jU8kk68z-mWOu0FoH~cv=iz){m}K52JMif zLv)bpHAUzEXh-u42-+bTnaBm<&f3UUGCRwl9pOsk`N`p@BmpK*=N`!n-8Gf`t8;Y?Sh^2C@&cmL8BFYkon3*!N*Qf-& zQAThbh2TnD3kSkIXz<6h9R47@MaT#7%car{PuCtvMwT;(UH-jd5Cdes+!lJN36P;` z6ywU=>i!sHz=?%>rQ7Tk7?&-dktc#d*bX@#+MHAx`T>{_r4A+*K@2~DD}7q5j%5#O zvG@V_VLCV0sBZmT1kt+LNP@nIS%*76gt-r4j!EPGAn% z{G2C$IkH*w*FiRtm5`;*q58i*vXNYG`N*bORy?q5kZ|-?v1lw;Qtl%e_TpuelP<^w zRIv4Y33M^2#^4wvI$U;<-H_-I-|`U5^*)06S`e?Y-^VW`2?4)I!UL$e#J&h}5jo9Z z7mcJ5AKm>(Z6kgt<<(qW^+T24+L7Nr2D>yeCgN@syD*xNSyAi)7jqEoQYgP6xE)wv z8+kB+O@d2a$IR{vXQL3#3h+t#li`zR4iTSB>yJ-4=BK{6)4=^Tzk7P-RohS(~50iS7tqyC?9A1btg9cgbSV$wsJSc?dKoNxEAA(u{#ux{e#qw4(b2Yo&H*cyx=998MSS^$8OKc3o z21l2Eo$Zam(Bx?$9}Q=i7BJ^{mcN57@@+(vx5Y1CBo;}8OnMEi+}P;GNOp z&Jx+u*Z7zXjgRUl|G3y1#mLC3>MtevKkB9z=sS!D zhNv)rWuxo})Eb6}V?Sj(i6yQ@bQmp4=h+OS_D^zCVcHEUp8a3E$EJW!YM;HpNCo09 zVO$=*&N_6So$EfhC)`jcY4NAEq233yKf#9bcZ|l>9AHBoC>B>X6k&pFsIB3K8c(Zg zveM)6$h$3;8YV<`6kzvtk&BIBAURXEV03|q0QX{n!uA4hv}Ho3_yNO^OA>~?tgg!Y z6EdS8%GviFqQ~9!lQN@cu_EiBmr3_2>fh}ftRz!U!y9`!^6hiLcWA}hqJ{2|?s4Ae z&y90ucNYtcS8t!SO!my!Oz}DF)A5Ed&4j3sY=;6#pDD%IFX0v7GRlMC<1`+m3Wu7% zy&l%$PiuQUcgWkzCrFCz4zRrr>PBR?*L7^K55nzrMs9mOp#)1*@dA~>_6k4~E`sev zPO>2jc1-^W1yK)9G9ypzREt_dSVZmlMDNDLn z`Oh)#koovajz0eycGLWUD1n^nCujZE-%X?iV>gYM7;L6n*i5^vYO|TH0v*qkY=Svr zbRl#WVr1)PNI-&M?)M|LCtxNh1tN_W^W zLVcCqB%wEwguP%fDY9IRMPhdtpFJsx^x&_TA2>^$vzc$9IHES6eRq!H7-{et zp*YP)XwP%p-H}B1_<^jii1J%q)W~WCVz87STWG$hgpq)cslgE)RW%{2PVFmp#)7@$ zG{Ln_#goGA6JL*3+E*W`h>G^d=&sHD8D@|0OS}3$DUW8(1CV1z&LRX8--fjU$V3Yp zVG6G>lgdpT*;J`pj0n`N5`JU{T92w^0s>}$;{V!!F|;&H%`NacS0skCMjRg!gs>mJ28_w8?v`I zf=iF4uj|8R@klkj!hfmy`z_Vto@Up+E-CoV#08FxA%W1Uk&Vu6>JP0?mFSv-y(L{$ zxUkDjalj3!DZZz!#`u+r*a1Ic08+G%RV;`}HwN?(eK64*{@f(@3ZLO2HAQvL?8l^T zKEUo=t(LtaRB` zNFf)c=!S@87E`{jC-#L0r*6 z7Gu<@qMi@JrQVdnvF@mCW4uwPj&)Pp42#h{>p_8%@tI-gAlHBtZx(0~M_dCiWE1O6 za0Fa+$Bh#K_(_>7hKl6=ZTH1+JTLO@2?9%S6MM);_4+t(*w5i4 z#=BGQD*}E{J=03HIu%6cw#h6OlFNS^9Kwl_ge}$0XH0RWKj%4(n)-Q+uTe)0QPkIc z!*|f|ohpo~O!DUB7y-~7lQ>@3=fcPspZ0IhPFR=or4aR3_iT7F-|s`TV3NRQ_MLsY z-ieIrs2&(I$cuEJZ=(VdK&ul#`ieXao-YnGtm$NY(jz!v?&SR3ZB}34Y2lGDX-uv^;<|V3~l$UrH2Y_mXdv-4M6+4 zfi~NHU76S}sH=h+xkdh8?%oAHit6ki->_MT+$PG!SW(bMMMEtTR3t>QvJ1Pg3#gz} zprs93t@>7Bt1WG9#a0v$$Oa_KMG^3Zq7qPH)_6ft2&nA; z`+d&L-V!iW>+k>j@%fOQIp@rrGw1T$&U3yGcjPd|2{-bNOgM1;o>yU-U4?lzwe>uE zzV$pC2A0zXqd83_=g_0!hoeUU=c}0{Y2@5Kg`?{FC>RMvj@D$5qrWB^;lLs)9X7pu z0t{RZOM?XrtXLnELT;VnF_1HuBJRZ_=oN{w5GZNFh6*)#_+x0bQ6Va;0PuDmhUQgk zZH$ZN_s%(g@2}hdyEkH*V8#P`bhitpz0PUw14mDue-u#F3z1b|XCXZZPhDg|z4w$m zh_!klHU09!VA-297J4xbmGHt-d{x$VAUX=@ftx(=4+rKDeDcFv@P$064*%XE99LMc zKTR7fUPW-iJ@D}zL{8E_@tD|H)94|$4%DK*QE6%7FUJLp{Kj#*N0I)rTL)IZmAEGJ z*>ne9!us`>tPb2tc3rv-qOVpvTlz1CNO;BQzvoi@*EK(<|H!#v1_78?Fgh50Z|$<| zAxISVRG`0|hl~rX45TWQ+AqC&^$U)Rkn6@pKGbxGqyKWQ^Hm=Bnm&63i`wq5CK`Bb z55SkvU0)hq2aV7J5l6xT8|9QCYE{{d=&edT+7^{eD@9p!4>JOhDB((hqkWC$rR#0F z7c9FOFI)Ck@q;U9#u-5w6c{*2%Lu3wJwQ4GrW^qNL&*je?GwSVHzz{31_{^RlbDGy zt1V-J(*R+U#$G&C$t@w|BK-AWNFcy}NEw!~l#9LMtBw<16d@RpHH5a6RN;&75lZ=_99{Yv zeDQ^ljn!`M5%9%t#rr@SVU9mCzW9UIF0FoeeDO}wv|L!ze+OUuexcXj6ki;YBG@4C z#rw(YsD%9pGUscy`;CP!P6)McgfC7)Q8pERt`U$t%kCAka7`K93{Ghac*HLaFuo9L zFbiP(!NB1F#(h}lJVEmRSAg*v%yD>)$q#Vg{rbkB4s-B(E>NBkJQbJ;Fuu;_a3nBo z0*uoE2iW4r5@oy)*y6bC3bMCq#vfsr0|BEc!DE{eXqWp$L5z1M`NaWDzrGh@OCWk3 zNDoh8!X+|@6PD;egqi{d8&72Zk|#3PqS-i!$2o9h_^`rw2&*dD%e>(8cWgPniI|4xDaejek zVMjjzBp!gZ9l#~Q;{j4jFq*YImII@WY+)di(gTj|5MP{AjJ`h52&L~R5@2h17U0@` zB38imgNrx9L-Fgu#V-{<#;*q#--&~nmRmrUR{#wDwEL^`TprYG-SKOKPj!Va0^;;P%SP9A*&aPd1Qkld!Z@TL?O-lRpZQJI_$w3;Y@ z`NM*Xg9{T}ybUf4h@)rP!G&=IlTkkA<#J&K)t3z}ULjog>%qkr=5XOQz{NL$*@4kb zgDl0ZF{s2oMES@87heQh$`GtSkA4Jj@u`Y!rcIh{fr~!~s|lnPiAG>Y`B1RQX>jou z> z#pemN2U{4K1~L_J@kMQeixUj{`Z~I!Qy=*cfQyrV+UKIcNlom3LHI{d4|uaX#_LE_+f6i+RSRaVykHIIv02xz0X|a^H1ecWOsI^030>^=qS`&>^qx1o# zUZZ+Fw4+h_uOE< z6>L>;*I(E04uMvPYf8pS7VBMvKfrdk!NbMFAAOrTYL&LB1+o2Z_sjc!eZ7U$9&m03 z?;XTYXQ0RUv%j(LJC9;k$+6pwQ|Oio+b-h9f*FAXW4hVy~; z{3<3P-a}afTvF{%?1DC)3n`9W7wI)-iI7M~a)N-14}f?(GfTXFtYo#RDMF-_l-(RL zd18l0EazZ4Daar3D8P;n)Z?vqQ)@`^7NnxKSvc5^z^DV4b%BJVAbxNf4u$|5Qk2yxWKX9oX8fkg{5F{J-R)<_;40ZFaa+u|S38+;u1eenGydbZ#*7EG zhZ#fG_*!PHB7H1RF=K|@0y92hqz_mU?2udSW5#k|gdw*wuNBR&{ z@nBo1;x;n|x5z{l#~F?cRB;CXxPGCaiYEe2*bX0qv-3R=}3hDuw57-iP+62}cL55zl{5IK63uGL|@&ToIXgZ& zZCGeZyM2rPC?PEg0KNhomHjz+@0AOw)ROn!JOs3syw`#p3K|b6-uwF+Cc+8^-dl%9 zR17Wh-l@=R*|gn3{bO|n7ggB!aVY#f2~0+q_0J(qU{75zGU(X)Dh#9GjtG8WZ@+Jb z#d?Rt)FKKIIvfz?J4I1WLzKURbK_0Gl-P>B`L1KGg4@8)fTs$9gd7%*9ptd9kCMZl zh4MM-Y8xE(nRas6k?rEJFSnD!PHoL$ca6#>iCG+WoyxR1Y_`e@MP>=cP&VAunLjaB zE6fIDF0eB<$?=iv!4#nZ+=84sJ4YS<8!kEUT2N3Ia?S=^w5NI?ea=Q5-A>?P(e_|E zvqAB|MOPvjq*Qb|b;yRZ&W2cpye=mM$v5pZY-DYsKB^d|LLM@evqOfC3O~cNQ-ms% zq0Dk)S|!5Tfw*@%c6r2LoC(uvLde6Z!okp0;U3#bsjA?X6U0YIHCa3*iK9Y02 zC0fACR2tP)br6w}E9XHTnul)^zdj%&{a&SIfr{T~m5cG)E#6pxv>e{}mY4mSaS-tg z_>ZU!sjbSA%+VJ8EtZMx`WT*TKVTkoSb~b@>aYq_+$(JE+XKu~is!A-i)zN~A z+kknKg>QZvfO**QP=I+&!toTSIA(I7@+CSJ3t(QeKqe{Q;yu1xQ1NyG=E1FnfO#V_ zw9g1!9|vPyVHsSRaWh z4nN*jsN&#UL=|s>fsv@<-lmNGBLKz1l^NK4yRerzcr-k{jt);8wn_$#B&K*_U|=CG z1LY1Mw&xx_yz&Wny^pXK$p6rZ+}ft6rC4`S`#AEwpTnXnF*U%@{(cKqw54=H1+BrO z@KeM&RL0j31S9mcU=iZC3K)B~T^DhyQefeB{0uv=Bv>I-aoetI`U%voK*nj!4N!@M zwO0RxmRcBWl?j(xr)9#0+Svl|Ds&u8xFBgbRF*d3vR7JJa6x!r!37H6AB4pn6$)QR zdF1OM#iPO(zYbDd>7C++aYRV*M_co|eHA2gX`E{EJMuSiE_q#LlA^ZabqkP~!RtJV zX=Sl9#pwQDfE2gvs%y|yw5x(y{U3l7A2U3AsIu73*~t8s*iPSXne8kTR`Jc)jup$| zJkhbfg;*AZY5i0}Stvb=T!(rVLRlz1%L-+Y43un_6D{8$l*KGC9coz$BT6|06X;l> zw7vp^C&e&;wUYOM1ReoVoKcxlD6J}5oVlkV=zB#?q zx5r{^Xi6`ObYhqNCw3DIyt6dDmEo#=+GnDnM8Omcv z0u--H1B$~Cveggt8-@FqwopPaSb&ih)}l0=-(aoq;4J(XmG!Zn3X@u>!lo{h0;8r` z`VRaVZ^(H3Wc9cYkJHEod@A_bVv%o`BgIsoV4E9gnVmAxtM(wY8!J*~MtG{&mc|U1 zNg5%kW7(EQ{O*A%5&Ad}7*jKnIxTD~8X1XMm0@HQ!z0fcTSi729kFf9VhClJ1#PuS zjw2sL6?pZmt!DjWwoj6L0D~2d$3)3Ij{E~Pe=Gy!H1YlgfECrJ6o3^v*3yDjix#B5 zN8yRv57em#RQEq1@`3eCP@c&$QvY$t5%|=d$o!W0)W^aMzCHEmmT!+w5l$THJ2vLN zy_idBJaPKSeCsintk4%9W3^a;f92!~aW_+;FC;LK-wFr>S)GDBW%V2I3n4!h`U3XK zOh$!k8%{jK9EcMm8wE}rmO!Am!TpkFSm1!zUN~`Xw~dQ>ybgb~>&@!CMwY!#f?Rxp zLx9TO2fk;4ipx1|Wl9rJaoYO^X4?A-7~R6M_hGlKjp!CMrYL*gS7Pt$0$vp8&Q3_1 z`NX(_v8So6>?qVCvzrTR&XeIHBECz}2Cb4!iJJ;3DR_-Wd>hx4tg zlyPsBY@C@ASjmPQw|!e|$ZTrr1PY)6S$uZ1e5bu|;_tMJ z@7&lhJ_V2AIk0}L>qOtWlr z67guO9Um#<#5sIUVX}+iwJ4o^;{34jkwEWTu$rDBdH;cN2}~@ zYb~psWq>0RDlBi{6$+776^a3pHf?!3R+`386iS)l=@4}o$&Qc2FBQWt%4Ek!!Uh#W z=4Qu7Qb@IH!4PPM%VZL5#7DY47eV~S6oUAqCc*hyz|W<7L`x=O;z)U}J&1`owgIM^ zYg)4d-QFX_{%a7#DR;GXM%_9|0iRxC?evjXT?}HMMi8gx;=hL=ju?B`{Yg=2~^m9?=HO3<#gS3cH7#AJbX{#vBB3*|)acNHPQB`YWHq$(*b4q!#@GbY2~? z-zMli-G%N8f;fWyfij8z2&UnY5X43N5C=Ls&b{-kAczA~yDbFqTFeg24}i20KO8t@ zf*<}P*n*D^Kb+2afDS*FAmW994##EJ!H8!`{O}XOPC))AiL-@;AC9f-huO(mcpd7; zkrABf4XM@P?0rw1^Cb~lz5nM zOYkpj1r)9v64{^cNq|^o;sR~~0p`R}@e7!+7#ffc6}bEuMU`O-_&~rFgSFkqZ5=U# zq4M2C4*wn*f%qdf(I0WB@Bl3S`DEqVoSni3EC5ECKepRLR>ar1zw8Tbj!*H7B0PCS z0Pz=u1$-UY?PMvHB~V^+Hp!@LpeTZ1S@}iyKUXr31i+|hI^&|idXq)Du}{K{J1pGv zt_mnO1b^Y(u=S)CAGT&tI)c(|;Dw0M7$@@5_+>)KIlL74i5H%x*EW8LoGhidPss6X zYAr=btbreHnVw!?;|I3F51+!}f(C<1KQ#~rTLsq4|4!} zBcrD?N$&>9{N|+hns1Nv?gx#;r+-_dm#P^_@2wW;h4@|}08_AN(;&28f;Y7I85trS zyy4#?z1WS2DALO_>dH2>O@cSHV2l8q#z_^_H-M%H5-ol+@WXclGlDzID@Zo*D-h#2 zbq#bQfi-~bg~;Hr;bh~e5kDM>#8IPhCn=z|X_W7`6uepne)s?zKl}liW|gp;p))`e z8JskUFh6@ydlQ}Q#3Af$KTd3VjKSMS>7kR*{C840Z>pT>+w+sFN9of~f`$3*8Bav> zL1gLCc15N~Tbjr&lfL*7q-Ekpv_)hc{QMju3%7Fkt7XyH3v+0!-C%-+r#;w6VU>|5 zMPSiW@K|G1JaJfK@7lH<&{q&v(pND8C5`+r5^OhbJ^xuyRe?XXsA?zCqT5MTuWu(+ z{j^7FSgx9 zY!w;6;Vl-Tg-~2E!en@L(EuaXl>@eQMO?b3-q*^d>w2s=@ny4ov_|6|?hVQ^f{*8( z5NL2OBy+)_C^o3USYe!D2)EQ>S<9VExn@1lniBu`jGWQQq{ME?{N|K+^tVTexBh1+ z@fF_zCC2e|ixNMBDQqF<3MKwP=AQ_`q{J!MaFK;Uc5LcP!h8(`L1O0!C03>e+P~q8 zLlTn$nQJEfCCJ=|1YLH%l>zci+&P?Kow^nB2qHHOm@Hyjw9jp6JRPxbtOot%p6Z)I zf8R!(O{^#goM)V3h8<(@y|8Fl2%htlzgLwZHj(&SK6awIRtok^rl`iE<*~ z*a+gSBH$<|A|6r^iP6>`l||xCB$F=L`!|^u2gte#QVXXtGw{PPNyQuuT1)?+e*-_9 zo<8ono_&=Bn}Z)d*`kz`U~RXZfvL1Ket0`0;GBLczdOTiXHln=+m5m;)UjuHE_f5F zyhVJmJ~@RF*VjY&!ds_JlY)ZsrT+>fMhK%vfb!+1r2xd+1?BrwMOo9TNPEyV`%5)~ zAl_~$Ur3}DlrN=GMF;nZF<`GurlmFbAw~xXA3p=XBz!l5@bNf?plzn1!M77g4|*vT zQa{7jAU0UT$MD414#m~Z@KHsz5)p3T9TZ`xFgUgFBn5!F1VP-xIm^nS?*o5f7oaVO z9}ctcjbN>r_~AIdXFH1^UKotcneoB|KipRL%Tn5YDYk)U{D}Y`(LMkc+XiwtLy<#; z9=;EFctbcL1wA|fBW$$#1b+ODXepi!S4V zOk(&!jW5DRVh&p8X+j7EJ-j{WzqLXNzaIU!4gB!O4~rlE+y86u!!wj^1=#tG@x$*w ziA2FhRnH_k)yVngMCYIX8KP6#ZlW`v8mO{CW)U4V<#Yu&opmN13c?tN zC^c9SotL<%)Y=N_FQ-BkD81K?n?)&0 zK!u{k%NU0QSmM72eSv=KHHPi=M~B^r_wVP<2#zpw&vi4r#t^X`+xX!fK(H9r)u(f( zpNT%_i%fJI)qC@kjc(+Ts5~h|MbHXCRAy#sxM`wtFF#X=N?w~p1vm~_L}d?d6;avT zLJb!urF`)908LT;9~McmA;zuaTJT21v8zK+X3-mT4N0Oy-W1i=36zK{oBYnzBaFez zK}Yn#a{wrlLq;w=Ix_Olc9N0vM54+v_FZ{c5b-gRBOv03(@CvkN9s^g6MB}L;VBSt zm=&-ovsjWx0UI%`Yhnv$E|RU|OHe8;b+d+vX@De51px>ri1;4a%+ES&L@*_5ga7Mw z%e*_&x}`(}udV}u7GHvlXyBKV@$?lv64H@67BnE0mIf2gLt2h4ua97^w?%n6Am^J? zo`=3w%7eIcugh-A_wZT*qCz->?QMOaa+UG|-W$;050=3821GJOF7Q}1MMC&xP#%O! zAVq>ffncE4Xo(}~+YJ(TxEl>HQ zeQp4m*#HXyBo|yEC=|6vQX7K2RCmMle4U%*KIiL%tHM*Er#d7Xkq2E5Q`@39wh(i3 zhE9haB};~(1sk!u;h|fk$PGRX3Y-VPVn>2jAQQAg*__6u($aY1#YnSgMPh$XX?+?m=UtbrE=}4YP&x{| zc`YgejOKbRx&}|63xM@T;K51$lFd+xuoKFlM&t7k&IpS(3r{?gR%2Buc?w`F*98EOgZitO@sR@d5k-8S%}(uTHU(jBwA{+!Uh_1NENld^QYq> zN{o$OC*e4+88S9n-3eO>DHnR2!9J|(J^kjnHwkBXBH76JLC+F_@Y|P!D}Y5`k^HY<%&kT9#>i@t@(V z61TODFFyTf@x|L*U|Vq7L=a*>$5dDRw3XY~ovRx$->IZ`TISBs9eg?ac}h#%Q#7-6&&XW=53=X(3|1l^I z5DiL0%V{|pw5CF!ph61TI#NL<*jB&rU^Pjbb1lI`d zxCRE?YHUrxkhZynGP++ap*DPrDVnPV1nHcJ2n~Mcb0dub^;kThEQka-C$&3Yh`O~o z_i_Z>t)kH%UCvh)UttK+-!l2A7;PDio^pU8k;@;jp5|JO{Nh2#;lpS0(2J6 zc!sa+sPS16bf&ZniJChx;^bNdwd5=FH2^wODpK)VvAsgJXGzMVz=zbK`WfsRk(4i2 z+z-d(8P+vND(Ui6W4sq~g(e1?ahZzv0hM3H6sQ}c0=xx|T z#-c+2>W}P2XUFrC4W!K<=7z~=W3{R6HTrLGe*iu_DXw;Y23La){h?ONIFgiKRg6CY z4z-sD9Y6?FLc)JY*8+>MTw9ic`dG&dW z7vxoh)p0&=$*aST$re}f(DY}BdkT5A_=I5D=foeMN`?ifT{5g2(hQ48g>L!?vj|1QFq9vaqHjfj53l4y;$XT%zlp=j8H=;H9BLbC- zg#k?T{LvzfV(cUciZ2? zv7GwgB#tglFOBU*{N!`ayMaQoyjOmtncU zuFP07o9y$XJ}3M{ccyV-Uq%LO#YC&y4eKymf-SM@9k%U!;?ue)cfpVqgsJ5rUkXL)26(ho>|Eehk_R_WkxB1Q7=Wxsr*d zP$r@^HD*JQBOvU0K#<>-u2!5pttmC#s`fuLrAlncgkcIXrKr|rPAQ5Z1Yz10Kukdb zF4N7a5$86NgN$Aol*JtQn0LgD*l%9$Y)CQKEP(w3V$x1Aj=(|*b{NC7QJCaB>UtPV@;ae2tJ=gQPsvy9#3Q$u4uHqo1|^4KKv)ru z?h}suFYSUO{{SENHE`tQC1Q)xv#&*RK;I&Gzew+SW`ZXet+OXuuQF19f;WsNb=zrv=^=R;E=CoS?Y57H%R}_SK)iK7i#!9 zX-hEui>MVmf+byj8oIZ5AhiK#@v3i`IsFkx|Eo~|-3t@xjDN|j#4sz#ndU?>4w4K< zN28n9!vKZYgow^E0dPcP(Z|QpWZeP=$8%3A;NBsgV)|h_fXcmd^SRtd*5&t?X_y66 zZhvMPuiQP+eVP06OMT%FiXa{MF|7JafQa@R9X;C0e)wOJ=MI1A(e9dnSsSc;xisd{ zD+|4Po=mwFg6N8I7BzS3&%Q&(SVwLV<=D_?O(J;m>aTMBRP z>Cw#wv#;B^20R)xMITYr+!=KY4#DB!(js4cL_aJ8ha1!=+|ot6Ya533!esH9CXgb( zq4|tFU-aSvKIYet_ZfqH;f6xLj)9!n&lkR`sNScSCVq=&+AOP=`oon}ZS@k-0nn2kZLA5K4@E1~SCCkR4$1l+G)ul+FAW-+KYA;h=|@Kdj7|acOiL6Kk zEOWefonz^B;02{I^Yy+CNApQi-pNNsYb(1>{3#}f^kbj(e!Z_h+_6Jx4EXn3C%b=Q zW9Kg!h&Sb=VGa}_6|X%^2Byofs=oFIT*ePjJ<{11ZbVbZV2I9dv%1{Yug8a=8mq#9 zJ`wZV3-T7+WOl+A5oyh1Aif zOQ;5Q1uGj$V_rQ_j5XB5ujdzI5e@co5&3mbF;>w&t#&BNxx_w*(MyuygIGr$ z@CK}-S1R5iOYdT>BPoorwHA_3@8Z`(#cCz_^})r7N3m4eEY4hC*jbR6qe|F|X$0VB z_&UEn6Z57FGct(J^cg(@(TfTKy3-v#SWu+}je)qwLJ1WYA+a>6meV>cr_oo<^BaZO zWhoe~PdK3{81-S%^?+XIH#+#kv7*ts=Y&FE3DmQaARI3LU2aGOUQnCnSNd?)Xs4k%#wKMxJ z<1uzd^DRE3)LK=lYmMF<92CP-7x?vI(r3*V%V_%yCsvkU@2L`ptfJcJuMGwjNgcl`F$Es?*o@Reg0J`D>aH4TM*OSqaAZu8bL9CZzueQ=toaYZiw7+X6rXLp3 zuqrO1(rw;IQmZ`yY3^_mD~RF;uCRiBf-4V@;^4OGhW}sq0M-O8iC7aaEWn!Z8^Hp9 zcuk=%{L`ZP#AZwo-X+%ZqB1Bqdh}&JO?FV=HD)obpmd9+^!Os{Zoe>ScwtpqjBJ^<78fFHmO+7oX# zkHN#NsHoX(T@^N;k4)Cxe0J^#STiO77n0^t|c*u<5nX9=iOD|P@PjQYa|^0Y^CIl>X>F(etxz_rv9VM2p&BQi~)CDR5)hys{-Q14nC&@b)h5C5#F9wadF z4@}p#i&I_+=Yy~rQlw|G+vpICjxKQP-h93$Xq*t#rxx(xpm7XHnY>2ihGE4rp|yZ9 z98?da_BJrjVa1sO&KOEWBHv6n%aU(E(J9~*DFJ87SrBmEAY}qrSkUm1BA;bTID7q- zUPw5gd=POKTOtnUcuTO7$^>iyw-qF|VBE96t$=(3T_LhqesLf=2`PO*Dr1E~@D*ui zesSWVBR*5Q;R;blp3X0gS^_KC@VO6IFjXwBDXD~W~6Upj5khIn4!7&gCk&D(OZi59p z_nWe%Agszokbpq9C&tV?d?#o%%t%Ney>`h)n|Ez#%pY!PV@1;9Zqsu=?70Z`1uBjp zUsq`#$F9;s9j?+|i-mV+FPYl%SQVTLH~E~Klf5?oWGI#&gd@<=n@$WcsAt*Qna9oT z2vbiTq-pr1;e5cl8SgcALb(s7uFkYa+VxSBf#WtqFu|7Gj#?+9)&L?!;b3ZeiVt8T zOSUqwMREg9Py4kITR|dky1*CyV%kk3{Q4gFSp-Ys-csyKH~99$)oX)W`#pkhuf|V< zx69_x$%xR5IJ0Kr$6Xu&xP|Lm-Tb2Hm3tr*PeqKj*WHQ@peGPXtMACUT}O_p>pE)W z+zBJ|M%7Iil?P4|C~KIpYg{zo$n!`2IGw*?=2I8V1un-3KAxhZ*AD8%R&J`&Rpm ze@#QBUd{6r;$;R(5v>AZw?2PTb28Z&xf*}LxgVZ}UpcN+K+l18POD!{9qRCC^+tb4 z6P_}_cddBfW3X^-RKwCig?J4WP?#Dbd)`kb%{3qFO5z+IuLIG$T`W1*@Z(8$W1eGQ zLqVuIV1&1#r8PVD*GUF;dg^0)?{kO@u#7#obiy+bLm=-&<&_;i+m$qoLS)oa05386 z<5Fo)d=83J;i(jgq;x=kQC{SWufiftE*<{`)q)rbJ-c^Ta$neurc{LbpfiVudIt>S zLA(pb{ZQx9b?!R9>ZX#d-T6MP(+XB z<1ae8Kz^cK)m~@546GvE5i;=ez6hd%iYv}UP{+~=Jb++}6;{i9+C^*8^kQG-W~+sw zuwf}~55Q|f-)ROX!`!Z#hZJ9UHMqh~WSbtC* z;{fCCkLzaUKbhCuVbD6yTw?@_>}$viosR)53Y~+$$xw-VcJfM$Na)nsb)k+(Ix$p) zq^=mWkcQhsp<{5n4<)L!ec_RKMM3BUqz|v^;fseks{H5GKTa&eFJ9jvG)Z2}cNJA# zkWmPk6;;RV3lGOj@~ZL|v0brPlgnMRW4ovGT6aC?oTpCO+5F2?b5__bdsOk5?PHL{4yk?vDVbY(v@!p^o{0f@Vj&E{In4R7RKEkakn#JSjPK`-5*)mGvv zykZ(!>d+#K@btcL0AEt5MgE8zeisLk{65OhGKA`x2TwYxkGgl#VLz&7QrjPOHPXNK zqxRy<<)i56l$a(P5#>*RG1Q^Ra$aNP7JOJ|^V)ZIB}=!Ig$LqWwEI?3qF&L0weLm@ zGktLd%B0A`bBKre*pdO)V-Uc(o+UY|f(-TW4JhOtgnjJo`@$9Ipnjnlm=q*&m{(E_$(iSsi}uUC)eCM&{5T~=GJo@ zp>CeCdTC{CAMELSYxjk^81-y~c{y}NI^Tr9%-8OwL%IhhTe1Q}eSk%b6fNZpjf}?| z!Yjt3)-t@@7-yjyBkS(y ziuua7nD6}zrQ%^;^Bl1E^)b9i4P;Sh+)|ppDF5x%?vTO7Z*3PY2Dw;ZU(B;F zYH;BTCn~C5oojGBYj*6eX(*_Z>*lg=^g6cBUGok!0BLc}j;{j7e0I6J^9ExDyE&js z>w}fg`*ihXD83&rCcF7uSz@*K_O7)ECmY|z_4MIC0zb`N44L`n&R^v@=0>kZt+gO|Nqja)UZ~ikCl5#NZouP-MieA@33ancOD%0v zu)Qa%3fwDb|7q^Flw1T!u#$KZKBL<`XF_DdfSy!;2lD0p9{qjDDu(M?WSPC$uwQ~A zmF`0`Z-H74;X`&}+963FJ7K6J>%Ela&DB7=YVO0Y!31bU8wie18>q_@wxyY)E&ga7Q>7%i! zd262egCFOEM1%_K&txO`aV2aQj9Rk59oTsYmtX$=Q1IL#^~D$}yeaM)!36v>A4y=g z>#ko1D=0?5B5)d4X54j_U0?->H3a|Cb>XGc?z_(cqJJI9KQ?%v#k*%8=#TQ%@AwRn zv)U!MtiFWWP^6HH9wO^UNo5~Z66S+vTn~=VzHG zTugQ`rP40foZr) z`sVLZV~MU{(o!av|9Ev*a&DCOq#?9ix}QB8e|=GT4q7$TZA3h#2EOGgxAtEfuF|Hh zQ~z&R2fF-A{10uy|AwnP+G|_+XN&u#X7@|)dn4PbI(Z{oLMJsJ@70!X!~ZQIm$&SV zI|>j*8HeebJD0|qJ0^Rb#kMLn%7>*k4wcHs%Wf=~Hd_ZJ$~+EjwU(GUau+*O#=2Em zthc_SD;$k^XPet!VX9?gVrTJhhV9?{@xw` zUe}Kpm+JaDjBZZXGf8!QDcUwS%KKJb&&2Pf>z^2VT;P*k$!{zxb9>VsD zel^k|vlO6oVjdn;dNbFf&nQ2e)u=LNXUr4KCn@-IR%+7~S(qTDvgn@Mv@4l-0U(*_ zDp#B;RsQDPwyL}paa&cD>#18zO~7N^UK22G!Uo1w zo6Ki=cW{6mgoc6EQt}KMbF&rlfl$cLnJe>~vt!lgkTHy9B5O8d2RiX266*UwWj2R_ ztTZn%uiVTQ$OGm>JK6PWaj=YDVD={QNh^Jc*?1nk`^Y=|)WK=SHJ1taXTHaG=&n~s z;v?D8AA=@V*_j2$XVJtw@F=bJDbSN#nh5b=@F``=#9`S_meF>y^g0kX(8RtVZ;78k zbx}*M-`lM8=&9YNF{vf@+YehUIVPzk7egn_jq<+Ll4Ig`vgC%btw*4CYzUWJG1_WV zyGbNPZBRSaXxBMjwd6j*l*W=f6}M{1`9RDt%CQ|7RIS#Fy9ECVc?BTyg>3btBRfL-3%Q{~T`4e^18z-?9r*6a+q(mu0)6?BV@IW`9rw5eJ89ny^wZ zXHER@(2V>Y{5a( zje6ukyi)VN?$M)*aD|Q^-o&1qkX~LTOu#=BS&Q#9@7TTzgh8&c*sdADfuodoE8Q^T zuKb+h^LpS>Rh*6Rl+{sY)N0q@Xa=Q`SfM2_zK6d~`E5G4v)ZYac3bFQ<{R z-cdoZ84CA8bcwnB5*%>TW8rca=2(YWy$x6Jq%x}D#c|hgT%jgMb5VWa=VSqq7`tc~ zTpF;q$ZNy(eJQO)R-;_~Rt!np)zx~;F8}81>{2Ojlah&D@pD0!c+}CV{g?a@WY<~V4hCKXLe&}%@_G7WipoOVLr$yf6 zY|d7}z>_&4U@p*VkAb}e9!v6pmiZcU+lcVJqm8Z~?s*z)?(;Wy!LSkKLyXwh9s}+& zFE(hLYr`u@2prlyr$I-B!5KH;KxmM+FdnJJ-9X&IFt`ab41~E(YKY8}pDdd?+=!w5 za3Z2KUt`vQtD;eoWVn9uy)tOv7{@#L!ge;Y7aEE1*8Z|hGkW6CIaOw(ya;bHon9E< zE<_pvvy0!Fu*B918JFUI>3nGU{H?htlLMlQn!=1phe;+b%Z z^QKdfJ}z{kd-fqZMTCyS#X?@d0DtHoxTxw-x`;R+8WVle4nx8>DjxOel(97=RX3oT)Lr=Aqn)&^4w9@6SO(Jc+$Q4m?JP z&&pg%z2I!~e7wMZ$Z-7>4>cp`qiYf_L?DQKydTeo%lEwo7OvHPfV;#&{ArBvZIt9* z0_Rae^ft(1Hs_mg6hmcHq=xD#uDooM0h5#veOn`iXx?*hHf9bE6Tg$e**`pMZ~|F_ z!&Y!qcCJZ}N^j8#U7d!u8V;70;b?T6Z9aiV(Cb)-#Ock~e2`Zj*}543fgeTf;_EADcjywKMDCv(UB0CMB5-T2Ey@OqXG9fuG4 zGp;y`J0>?l*g89tw!)_7ns%8Ygf5>kq`3oxf-M%oHM`I4Xo)07x8LF=Xs8x>3vb81 zN~)a~@a>@EtPcNhS!!RZc22^rv~!%a^J3gW-m?tg=IU1RZ+QQ1t~N@c&0%C2J}qt|Kp ziMuYf@}#okn1jk(u=yvqgoS*Mt@^KU`9Nf34FAq!rJC*dk!s?uH|jWR5J_#4u?Ly$rS6l43CR#) zc_n;%Y?^VRBJWI6G-K4NT}guO7e`Wpk#|FVv4yV$UHUJ;p#{Qk zb3KGC?Cf9KfaN@p(yV`^NV+HHl!W+mIW!n^86L2i-r2r<%C7(~`3!s!OHYez#8o|1 zSckdeMOYu|aoZS?*5f-8Qz48(c7v?9ufZAWF*gssYPGSt4x#Sw%|uewhsj>2lnr$x zx(FE%6@kxn#A`gpLK?3?r^jvqy$E#;7z?OEC$@ZQ>(11r(9S!~t-wzmGtJ2$9{Bvk z-%%+2hOXIfc*=f*2XduRK0M?36RqcegCaN&o$_ar(;0B4*~%*Q`TanspltWY50veJ z@)M;}e^_Okr_9=?Z0}EL*igKchTVi-sMyS2$gnOAU;=yoE?O#d*DZt54YV#z#d12{ z&ipHcEv4QrQtItL@derHZKLbau9(~qXPUBA4LX!BS@0=Ep({;wQef(8#TQp^NKf*h z^hx{tKxST$;)^`3Y|nAal+GkI$15@I=0z8J@6ri2zIekXi!`;ej7cv}NtgOFc| z9nraAc!H?Ut&Y*hp}l z7z?k>qtLq@LCL=A~w~WQiD~EJ(#J!t} zm`}~u`?BhZ#e}T!>A-&iB!E)<)IJ@x-KcjHUuHh|JZHf~e6j=Ya)eH)|1~;GO6zZc zL>FO)hWYV1l8+({Uwkk8MZwLL@KkccXdT z*t|@m-GL2Az&~?>kS~`PtyVU|$JrRjICg=V7)Xe2>pW$$QK{8l(-CAd&VA(BNwL_y zhl7Ny5io)6(lBowOls0tx{pw4`az%-ntxFT(R4EYQ$v+?w z?s&HOJrsuJVhrw;S-&GcBwU_YhpC~}I&qiapT-CuCk-alB?`n?Ad~+-&IJ53JE2Zg z(K3Lq1phrB6X^jv^DNLbPNdl~kGfzaacBWUl{J@kCY~lmluhbup8NO4^n^jFF9M@squjrlhkBdzL=AV_pQViW^C>ZHAcn@6Cv&P-%qer~K0d)Y zwNU2NIe19TDGoN~)SCXN!jjeg@U)s!-0rid=B?^ALB6Ky`|_vZwz4Hyc4!9u(0%&b;F0F=AHaqW4{&vV(EK6pf%XwB0jB+K zvEH-Py0c-ak6ziNjy6N2v4l3rI$O=hks0^K(t_J_6x^@_L7+PbZa8r4-6Z{Nnd_l7 zLvV}9!`r!-fGpcyE_>GiETYP-e#D*Xh8D7M)dTPer^qL~Vg3>~fF=o)0D~dj{$tpF zwl#)M%leQEeH4%c^$lpbG!>?Jh*62A9qIF%#9cv=RV+g7+$ypHMY8Z*((<*9KQQ|P zN;l$&A6+6#crO5n*5XQbaC7CbU}cNh={#)YMq(@?8@v0@&BMMVB%NUNiM$H#-hAwf z&R>LlbHI6=2((VE;5`KEsv$VH6FNRzmaIAsMhmU>N2uP7180fxxJWw+c0kjur>xiF zfQtUU`35=>?t^R~eD@((*{?PhGtKN=!tRW)HmvSWoq4c3@)%xC$_qOppTq7mlRay> zJE0>lT>j71)|TqQuCQ$3t|(io<{mf@8?Lt{UyJb6rnQM0w+fn%KykCF zZ!uom-ib5ztQ7U-5adu_CMoKB;UZz>xW^%ZBHIikqh|Da=ml7B0#Ab2(Kr=%{Q#}v zzku;~8H&7&#@#}4)K1y)$up&KVy0RFT4lG+GE*^0wQj)^Vy0q3mYIqPW+_w!ORDP& zQCLw$nyCO^1?9x^cbcj8n~(nk?H4oE|CZ*OsiY)m;UY-+W)D1Ijl6l+xmY-uRHd9$ zXVVf^;Esb0;9oB5thzaeZOR_*>3vzU{DBI45BFTYG47g!1pZT7#D%IwL)8{>2X!|< zZ4rMqNLqVxxV+&j((YbtPrgw`d$4&tbX~Ip8f->!1unu~q}l5gTtG(QkVEdIaS1b9 zZbMixl404DVNvEF3X8L6KL9|_&+}{E{pO!$c7%%w@>A!}vUDoU#G_i@XW(Np*Z1+b zKg{|L3~IH$Cu9#rKG$~cFlZ5z%OgjEITKwiPQo4EYJ2U!-T%mIzxx^g*4lr%-dg*I zaK1vV{XMwKT>GCDaqaJv{H(RV!76C}FGR$DXYF5ddi&P?MUNk0?LQ3d!yJzpX082m z&?^43*S;&GaYwWE7oXP7wg2efjZpnZB;Em+g5q0ECUv$N2I18?fK(WYS>zm9= zVeWXg7CG9=+LKu9FWVs@VJEJobI28L=~ji4z#Hz^8FIo{0b5LD-|Z8zYhS3{{R7yW z;kV=uH)$TdasS(Zfq@5tNAm(Q<(5KE*?#Tr&M4y1AuYN~_Jnt7``>mu_t9nN&ikQh zdGz>2HN*NjLY)$~;Wp$9$2!1iUA&%#(5(>glzHa6sK%|w!{wcqTWj@_7JIFFaFw}M zeZ9C=&y##D@({;RIXm^W3Yz;U@LQgeJ{QKnoviRrr>2*K7e@nfSRs=XE1bVjmID*W z3RA3_3E0;92=cx82TY2%>#qH3rE;4k@=vm5V}*P+w_W}h_wc%N*9zU>z>jJ|Q>Idm(_)r}52P5GN-Ho13c|bIP*;mzo z;H=QEIn+EAz4uYBDOC~?v=CGiNc!x4_~r5^9_fc4E{K{auL`U~MUg_>aIjXy=oViA z>olZmJ_*BMG|F5bV|KJ~r-n^;1Iug5B`s-n);jE}S63ZJNiG7wwVsQetAMUkdokoOj(ns+0 ztCWu}W)2^d6R_A#G`IJa)34Yfk|BV;0ZL%Niksz+#Y0?KV!D!LCgJPE>KkE~ii=sN z=P=B_V8@2bXFP*(&NNN_mj2b z_L=QZ2zy8;92{1Sp`)8Lp%!ATx%-bC+uZM{V>Ow26Fg0PWpQoJ^)Pa9bb*?@cZBxK zuK75huol<>4cG(iqAicPow3B_C;$-4?V!^oSWV98wY{-aS+cd$-MZ9ZtV!r{6 zwCxuUfmpRFgb8zN5&V{&XPXzu%60t$x5|1!6$dk}U@;~b;Ae4{;Gf0_tDvCi1ZB4k z7oGN^DdF;MPoXdm3dpW14o^P&DRya}z+-Acan?aXcCix6ezD^*4palm{+eZR01j0M zRitR^f~^bsYp#92peJR~FH`KtJBU8Tz#b4?yz--P`I%4KOT9k`ifMFKOML+N6NF%< z`Jy8Wn~w)Y;tiMj5-xQs6JZ24VWR_>=mGt)t=#g^5$@(QtUC>#r?En=ii`irW6m%rXJpIUL#dj{S`&nUSq{zlpyt| z1GhODN)?vFlIbL#`X|faN9;)UI;{_xU&y;8WF_;2Zn9T*m3;P+S}U2PHrZ?ciBkIb zB@0TfmX{Pra+4%i9Rt@XetUC;*eu>R%}0b>{LS~ctuMv1e71kx1s|4aHl@#Y zcd0zXXZzrjs&aFp5Ea+RRCRwN*N?k)*abqUCvBRgpMh5UDm-4Z>e%Ts&i&)ZLmkT~ zL18F|gV3AH9^RE)3jGlYi~FG)jobUc_`x~Y=w0nFuRWc@Ay!sA!hODXn{a}#G?w^+ z4;T?XK-ZETKCONU_r7Q#ISmDj6~ma7eh9X^LZp}_6*#~0G@nl5942bwTg^4a!c8Nm zQmZl+%Z?%sy&Wg_QjPnWynt3;!%Bc-;-B4eDyV=~+Z}TuVAM^+7q{2xcEJgxUKU`? z3E&!tvorHp@7!Yntm&!iE%6c>X6$Z+?~{Cm-SiuV=b7_w;#Z`I;qw1}f)hSt&fUob{4;mJ zlmRlm<+uuKihro4`1N)H$2*yGPVx02+;z;H*KM8?@atP)GwFvW(~!uM0Y(*Q*e&-)K&3=&yZ1!2I*(au&eF7LJ z$xYSxoF?-Dt{r}-udN6A<~(3Y7|Wjr_xlT6N6k6t9buz3CHe$1dWsSqy>IS+_r|nT zXGDi)r~;O6E|WywuxktdE>+vyD03-&WclVY@jH<|T6%H)Mo6Ms`{uG0R+}3!8{TBE zse{>OAuJH74s#vUDpJ0=@~Y@!J}V+j>IG+;|AQCU4;ijCcu0J6m*YZ7E1l@q8!o@% zam+uhHXnD11L z-)7~~{cuBYnD;)I9-t*A4Na`_n`G?w{Ho z;^#VBLmWn74DnOAS3~@eT923fS%&z2u1Ef9dx$T7Plot37ETXw9m;17@nw9wHN=BB zr!d5oC}hu+&gwO9|B0`G^0$aH#iyUU@?8vXZya(~Z=*O2<*y*)ZSP`4IO6)bzh&9? z;lGP1H(y=^bCgWEl$RoXZZ{m0ZpxqKVYqTp?V>y;0=0R=Z?T^)GdkSz^UyKjmaDbM z|Ki1g=;HC19f|vKow9GzKUd!etD;~3%Dn#*Zf>{FEo*0Y940K=11Y^SCVR+)Cw7{F zl0DeA<{{(OiC|SUT=HC<=?{)%Tdpt;WcV+Vgj!CK6_tsl7sfnk&>Ua zH}ONOpxJRjdVP-IV78NSKHV*~K230gob|~hMS}lyFV`pUGxsHV4`XK@bS(3!`>-Ay z72My6yYAhI`G$Yc0-8|9>{KMO{FOMQ&3ks{kCxpH6?RbUP^@C^Aoz|~)SUxY@?odX z_z0)Fts@rl?B6DJv}|77Oca~fyhUiWdX@RXJT5Z{+G$QZA>Yw_W<3RM*<~u+Vo&hQ zbD@{uX>+kW=G~KN`Kto{k_@4F{%>f>mmUG> zwYbV0&$>f-7|)v|KWjXHVih#cqlRwL+bfP@Ja=_z-*~=?4?OI6o&){Gd>3mqHJ+=j zgVy$Vp5I%>vpQouZ)op$Zo912c*dZ4*yGvf*Xi+`cf6Qqvj@p<4N`iT&)n43Fkg$8 znj7!o+YUF(<55?7m_NnLyehrFdiiBQI+e}i1ZJ|^7;c^e2|tx@xGp($nBy;4neg{D zdiik!igA4X0F0IpRqAgsP-53vQVz*1cbZ-9tc-Fk^(@yx%0Y!>xjegENk+L%QtpjY zSZ{$U_ZDuX-ZL}GEtGQqlyWd+g!&r2ma1~S>ieh5iH}J&%35@*hD+9--*)VZAwU^5 zx?P3Gadu&UgZ;ffvg^(K-hr&Q+fZboAnM_V47LkqesCu#c&sXDeX(X2%>3fFSMrT! zKY63|$?xN?)h92Og7vB(zxhO?*BVvu*vxM>??%C8{Lr}TtGCp$B&qM>(Gd^)koki7 z7$!{lf8kMD916{@y=1fSM@Zm5qt|U4hokzcUf6>1Vr$-`?*T6{#W!i{>bPqXviZ;2 zJ@GEON_*8CgFiXUGN6aEUN)C~ip_WLRveJ6${)0?xfk5d(O1mdWIm$u{*@Q^zL~^7 z^9PrAgi3t<+GQ|@u}G6ITJ@$m%AMy3&w3NqodrmSd8uExrGIE!1}d6w%=M0?biBbd zd}sy9bXAkb_y-YE_T8yq{D#!r<3Xcp@YY4<;@1x)@gCSfy-j*tJd6au%&!DRcg+Gm zwA~EiU4St&&pnq`FRgYu8kt+|OjYfvD4OsfA7Sg()@}=F;aOW9RmY&Zt>)980K#K7 zJ{G+gcZJ?m?4oslrq?3?fPKcz{rouki>=8bZkPDN)k6k4s!wMeX<)tk%3iJhz#n() znQ(=}AJ6M|!WFP;qn@s{(;J_ z&x|b#bQoB5Qat||86rfnLTC|R*(cRI(+nTCvpz}YKhyk4mVcg#{z6C%G?`9JxAy~1 z7Jy=X(H{@=h07e;-OqDOaT24@0|0Hr;VN^6y5atgAquCs`TUFG`J!O>8PEjL_w-G{ z=#)VSnd*dIU)?`YmYntSNF#rlJRA#cawlU5MY+tQ1C7`AmxG7{A3hfS3qry!eW-L* z$tq8oS=BFSOolP+)1YxJK)89zpc zZ`1C14t)&oJOLMBKQ$zrz(hqK0p%EH0}uxoy@?@0j|OAtOCJIs1oWy+K}3oKGtjM!mGD&e z8dMu}e#A7y7hs{Mx<4pshnUvWPFsXDzq65PMgGbuMSYNgeRL_m7I_FX@Vo9!Qs_{? zxgk(CF{aHKgD!G6>~#8_FCiviz}ez=9`HL~Mi5nh)fE7{1F_?#~>y)ZMKt+vv;W~SGq(+kq+Q#M|0 z70%C0950D|mSm<4u?oWNz;4Bqjs1`a+;Nh_scyJxrud~F2PBNK{RkIu&mU1W0GZu% zji#~OxB27Hl^9I~7y*h+*U1>ad@Szn1F=TtqlhZ#ugrhLU$Pn>>*PC=| zlVr~ME4$A1mAp7wdm_+?3b1Mcu@1^H+Nf@<@KxSX(EL`wn9_YxuyS%i^RIbX!OKJ? zhO@PNXm|?|wRyP3TPy7IFgCsM8RLY^WKuFjVzDUM=IReDF(*xD4i}GM_6K$7M+q?n zx7odJESrZgT+_AMfA%7F=7&|s1i5SVDDHg57-{{* zsJtFM6RcbptXwrF+SBiA*x3oQrU#oEIo{#8C|(=k*)~o?ru&dS(n^0hBYhguJ6Y*l zGtzHC`Wk@v^F42-(wFy`hxZ|?#>%1^qpDcmW1-3_v$EdJ$cm|~edu1kklKg+)K-=C zq?PqSM%Escb)A*9CnJj|_Rx$otgO#6vZ%TsYbQ2qSr;vVc3neM*27lTml;`tZmZor z$;xtI-rG-It)A*(W#wmN)u^nEa8qJk1sPcnsw~~g>S|>HCe0mQRp>3-pv}1u^}9h2 z5S}Ry;g|wZ&m~_W#-KBR0B?wWhB&Y@Z?>o33FGKIY^ARF^&g{vSr(YXG+Kdmd6MYL> z9Egq?7|>@eaxbAof%A)3BXJpp3-R`Dx=KQB5`!P&zQ9c0)}=Ep~rzI>Xs!A z!2>Y~u9Hv9zXV^H58CA9Og$Yfb<4C?k$?l0zmujQEXY_;Iw!c>7c9%!`vLl2mGxED zMmUENF{fk|NSen9irB)4u)lL|2~@7)7GZRJ5+tsyK?^f*;+SZl;wvnJ4MKMDB1L*C z?^E4TvI%r`!Uhn=gNb1%p85<%T=DBFI3SpQg9)yEF$PviJK)`rtH7Y6lh7C(v>wkc z)2nK5&TpDrK6V3s7!y!`!4oZ}c^A8ZpxN(&6;!}u1V999#M5 zV_bd6_9vf5Tb6erm&e7UU7BzK=8cGj*e=!P43v*s%+C!vabW)M{QiLRZJ%?6^n_D- z0-T?d+4%-Rj+|d`#()WM(m)}W{xPI~APdwWkdby*18VV=tcR^6xsLIb9)v95tGs(Y z8|{ncU*b!y!#Lf&T8RS(m?b8cj4UM)NESOL^QjuX9iZ!Yiv5_*3ao})AnEM$%ydjE zN$2=vremTUkb6uZ5^zMsUi_T_?Z<*#xBy;6U}2vx3I#P)N&Q715y=h2~^g~gdba$U!X;T$cU>1sUyvxU$YH| z?tkWaYqw~%y|H@&7ZM=}SmMoR?ORnyDDfV`afSB=^fGr6XNE0C+@rZ8LY5#Ui_!fR z!I~i6YqbIJM&X3ooo-xOeD8h5_kfTIzPClYX9_P$V;0|A=Wci(e2;e^YW~V~;CmIB zeD4e_?09X8MA~dG0n&+N4zB9U>K^2Je^bf1Oz#&execCoy2@#Ta2BRCMa?*S*=Em`3FT%ji8H@J1LG|6y@#J&9XyB5sK>EPvE>e7M)yygk)(Ko3 zFTfcnhauq@GeoXc;B(_JD{dbhtXzW_Lf~_KA-8x4${61HCEiOmcTKTkb216=U_L|D zegs}Ovq$z+C;R&_P#KZsONlRf=|G?ET@uh+;CrRWHi8hSDG!p4Kt|wq6BoLlB_|Am zeMdH8Vd5yCEV5%^LGbAtRVZs{bH2?V!KI_}!*S6N^qGcTd)ulrM&fP3co;NpD+6Pj@8SGB3LG)h~oKQL*fuRFsAI*5s>-;cS z`8iH%2c!Q5Tsx|2 zm1cPBqFuj2hvAEXJ-!aq^9~#;ZfNQls9Y|CrMObH6OGx;G=8j|2L2akS_c1fg8yx2 zS_c1f*5LhMi%iboe@?~!K4x+T|8p*q()*dr^$ErhwfG+x4f&tb(sJ*1HlZl^UjT|z z*&%JtIi#iP!=Xqc?9e=%#H$N9uf%_JiBq~H=zOPPH`w3%zDh7o9KcsS1S*RNBz%D( zon%iem~s~h7sMVprqzZ3BBLc&yP*|d1hse*SYe>@abbmlXrD{`$rmtmk8e}o@E)`H z#hF>^t0jwll$lk7D%d1E#V$=}UAGP0D(US0%ybNaq;uY6rgQG_JzPhb>HUz7iGrm- zUFe>>P$RV97^ejE)g^Aja}tevW#N_%RfzvueG=?7yZp}3Nd@~x74@q^gv;~H53n=V zd?t;FC3dEiG+$x{9@y=7R-c4$q34?o+(c8W8S8+74})cUsvkmCv8)cpN_Rg?<{T`0 zsp?8$%$U#bTAcX>s9>_3pTGqo(2kBiB`nxuoX3r}vQMi{i+3asfe$44aWER{1Ag3F z`0+t_HT0x6()k|OVB zFp<@ucsr_JP4VHy;KLsRwH%JAaJ5wA2}Tr)BUjas%TBV@NzachF8d1f%`su*z&T}| zt$S*BuEgcH!*Q=wM4ywwX00S!15`5Skey79`ypsM*jFyc{hLZ|gX3PMa@ydyr>LAZ zIPRMmI#kjI$9+KMw83#NQ8{gJ+-@r8v(%R??_qJ=wHR*H(+0;4tDH7C?u9C+4UT)D z>)|-=Q!1woj{8fM^G!Lf1FvZ>$DN06&*8ZH`y36&rE!G{C1Q3BgxtTtQY?+@7y4kN7`u+9-5iP#b~F|Jjyh#M3weCjjSTz zT+L)ILpzzw1vXzMi*_b8{Z1o03aFQ4s+4>x`8?Y4JB`B{gi5J3;lk%!Eh^;~DV366 z?00U0;KeS0a_Ms}md3s*|}@;WI83RtYRY=cmp2 zK4Wli^I06WY5sorU|!X!J}2X7-&XklG57WHO;p+Y=^K<5m;#EZs8yq~qApq#v>+Kt zAe9uWg5rw1RSle?&k5JhX}% zC;!Wmd-FQ5=>Y;*;GIwM{0QdbxUIsaDrg1i4%J1gDW{^`hx)7e%_SF$jVat#(cDy5 z!%e}-!_}D^VbM!ic}~+vTiP5nePrv}BuahS?EDeTe9*vmD1gCa2E|zP0>OU)LK>9- zZZTrBQPHueZEXs+qY1t}Xaf!FWeepA18lHi>#T1w}6*@<-RvaOZ{X^BX=;RuOFR1MU;UkFL%c{n_Yd8(^Se* zmC|QMNu#L9d$e9v_VuG)G+}zoD5+hDl&h3Zm2!?5CABRPhe|m_r7Sh0r1mMITs-6J zH$bIyn^As8lq5lvPm4-9!;G?>C}*jZVX&J@^q?8#A)>rerEFFyr<+ldxriK!C||Eu zDW{rIlF~+AR4FS|%3?E0(&5NGDrG>WoNPu(Djhk8Dee7cP;n-ik&${w{uQQ7+WSo+ zvI%Bnr0tQvs$@1ID>5S^m5LOD45}BI$xO0uvpJ{OG9&k(YRAhH(l8%$OJ;;F*t}7; zr`cRnig4vIC~1Tjyd7(drDmS=93wAUN#DR-r6rdX$hI7Olmk$WXnl%uTym;I&Kx5x z;{I&p6)clwjDEl%dKdl|<)Tbcczp-m<>UnDLaXnRN3OQIckYQd7)$O4iITTHS=1PY!b*c#f&Fo%{&fu!VG6W z8^}n!!B8|9dJ$rwtYaOV{H-z(+64BGmnY}(3~A(d>YEaG72arI%NkXH1BImK8-um1 zI;@@Yu>AHCT(UhTr?ESI%q7o&Tz8W#npV-+KT?SyEIlwv8c+)5X%OqF)*OfIwr1Le z*E`_hnbJ`xTdmTtv9k5zG1BvjI=3JxrWpw!$c-untdTkNip3s6Ar59GPmJ83r*nlT zUO)^5Vm}{g_pr8QE;*T!UWkt$$~t>BlNxn4j*gYKgYEC+e(_2hN5@*bR;7#A+BiB^+fvYtlP5HyAw|=9KdS5| zc|v!kA?>TaL2VJY8!SQ(RR}(f#p2Y*C2e4Zb;y0}=;fYYAm5s!_HzlArhvq2I1(o`U@@Y9*qU%5_Jn;+uAookrr;dC~ z3(%pd*@e=6tSXAkKno^3kq#mR;2Z+V7qZm$G=J_8sJoP|a-u`e%eQCp$`?`YUMSy}QwV?ku!1Q&9kfpDJ=}^d zIVxPz#45W~SV=3L?C`jUPjAV>H9wAOr;Gr(uo7`Q~If94nw!;s2c z!B2uGN}EOR{+!Cpl5;Tc?LKFmY`-dZT$=r=92bUCxIF5EA)soTg~*Z#1+v|miIJz> zn$tGb4#%tLJ)Sb#?vN*22axaae6e$LF38=NCV}}S`5$|M$_6UIPYb!KGx6AlB^<`@ zdJtZa|EYj^4p@0CZNy}7g#*{Ps6~b6L-BL$!fF#N;+IP>73#`scjmkDGI7or+N@YPBrcL2IPVc+#WM9=L{${Xt_+MWT^U$dHM9V3`R|!|kKq9P z3HUUewPGgbHpQH_X=2cB?E*Ju-@ur*0dxy-Np5AX`_hvj{Ss6uC7G2rkkkYUIO=P`WBPHAFAoGeNOC$Qr$CW}saB3Ojx7d&XksSxLKzOcvv z>uK)-EjDNoGn}|a1{C#?>!F)i%;ZBsbnA^LDCgB-U40bs#&$ z7DCn?(1&zuc*|qJq?=D=$6~bQF2FhE(&6Dpob;_mT7~Fq>j8(+7Uz^@6ibu5m?`}T zVNUNTi~9`Bo+~Rxx1ul3p(BP{N+M1#egyyP2yw~o;hD0dqSEFbSeaVVw=%cnG#cik zlMuklhvjX3_-{7-b;{k9U}Z(uz}VVUVbM(Zy>zR(!eTA0hY~l^YACTzS)6(zJdAQq z=j9Bg%qYcri@8{83qOs+Dhue|qmt#-Y@e`?B8ddbNZ9JPgH`bDba$-C7r4SQ%j@;)5@n1 zd>Dd#8Bg| z#k4Ci_bD;$x|mEN5f)vb#85XwOOva_dW-vb7BVAIR%qyn;v}>H8qSX@GQpQJ}0ANnT)p)3zIj^{IqR61Y%x+bILKNw+j=% zwP1yGG;b%CIYAhB{buoJ?QM`!eh9bc(5WZ z{}S%#J_w91Z{is| z_$R6H!W>4Ul)0)?cGEaaPanS zVbX63(^|kw#p#SCN(E_q3Te4=XJOhQR0sH5nD)KuTP{fZ7ntoLM{+$97YxSgWp#Oy z4PN9MQJs{Ralv$(vI=Nv1LX&NrYOq2K5BU^ipr~x^2DNuJ+Y_>4e-k|8nIFzj^#-l zPPR@TPPI&5-);!U@+1`QRkFT$xaxZr`VsAUA@0e&4iOS-kpUE^En6HsbszqtL_SALL+DOHp4}<5=zA9WChrUZS!6E$_&Z7_ zp?}a6>z@2JIHSvZB4xG{xoVPUap%t3*^moj_vOja+ODGhUC+)28wdse3LL-@>!O(C zzyq?v{GXy-yk?q*QOfL+R!^tmN_SPM-MhOm0&tzvUXbrP2i-fGm8S094+Jq~d$fB; z{TS-=qKj9Jod~@$Md=gglwIiFr54KeUO5H9p=s#f!3)sKLKx`aHHBN=rw-l;rGuw3 zaUp<>9Xu4ll?Eod(!j)l)WQ3dnAlc|4j%5-({u1%Txl2W-!;k9zdI4@-z5V=|L%m^ zzk52}z&zuZJ@_*Ecg@10y^ujwJY2HEHu@v4NwB1Fy&W1J} zpu<1RhNcX?DsFrWWhcg^XFB8y?V6)z>rqO(w0|W^fM(jKQqu4gjv9Vfdn5NI7cRL@XJOBK>N=A`VW*@@ff2vzaZ)Rmf(vY#fXk}7_h zI=49~bz34%m2`-bff?qc)c1*`siXrG(g)2+sRI?+fUBG+uZo|hZn`-s^}-^Lsia}Z z1=u>(oRnIg$WWEESs^VpC#A+J@(sBHkO9R{Q#aY1l$w~x%PMJwf;!2Zl$xB#y(%e* zIPyBdoRpfNNG_93?hoH8y92>9cthg^fZC%-D_jlmn)ZjErp{%KN9|LDH@$-nLRuFS z(l|WQh{zOjU4$ZcgH@PKc^B>)%zL;{bK_;#xp3DMWJWp=H(s`%3wMn(Gg8BpbDJ>q z!VI|$7+PENem)J_l(vS(V;o6sOLSOvBM$VyaE8)`UjVf-Y>UO;N9$_xw+KNu7P{J{ z-G8>{eQY26@fer}DuV-d;S#4jmZnuWfS5$nDo*)2J9dgmiUr|2&9Tdg1OP163}4hTVCOFUSu}4Bs8D04*}YIN-LhlS{f*c z8_Cp(b?n4h2Det+{ybdKBB5bA#*1iasN|4#RWGp?{6XB&h7&nE_veLpA1@Xq)qk0) ztnEW5)I#QQHq6`T#`J6|B85@M^ac*IpP8-&79+5y8py*EqNIV-F7zWtH`>qasZiEh z76S(1mO5k2Qh zSoDAzZq?|SKv;w`a2aQi7CxLFghk)tFX7YHU;b{9624XqC+oxE)9GQ(e4-snkJ!`Z z%phW{-5T!9|3UcuKTyZg2`v2_+&Q=t^V#s+)7sYwvoP}6hmp^it^y2u27+^`*rs(R z4*f1ufH2;{mPqvVab*y1(Q>ESu*DMo#q&ftPn3q1sibYYZj|4&kVSUNvmk5N$k&XP z+-DBGLCaKR8f1rP$P~xX3?UjWOymlc#%ZLvjA)n<5!ydaIFup|XAsda6C-O>8mh85 z8Y|Io1w{T&r6F@0N0Uo5TsINg6+_=5I~zwckZ8E#BdID48Q3_Q0Yt+>6KTMij)X&& zHI4=wUhHSGz(vYcnhGNgG+h$cJ`$`L+MW{3#s3odBmCD{wOHPq=2#kuQLy`km6j_{n7ks{$u#N zxS}PVlckgNAZpkxGXOtHFYx&5&$++@r>8ijquAFD2Oh?ttEnl)#gpsKMZUtTKOi6R z+Ya(j;}KVAR1Clm{A{@U?D--5xQv=~EZnUmZ!|jJa5U}^JL+*h-Xg?zI5vCSB?a|g z=8Ck@;Q>3mfTH(@A#-}u67a&{jhU3Rt*--5a35CCE?snAX%I;b!p|qZK=h0nUXm?( z=BJJqeEU#o*qI#P;lqw}b<6sZb)_HEDIwwK=TYmz{v>-jeCB~BYl`S;O|_T5J{l0B z=Zh2etgx`gv019$5y9(E-qsXHRzz5{b`0XN^4@!((2S7?&mXS+w=Ct@O?Om6A{?8@6md>mmF8JPr zM~@z}1>e_jN~xhj?D1DvNUMf=FmO~KpFlTXecZ#0WiUFsl0qS3%YmyqSYR>y2piq%I7KIxRX%o_jmIiI4;(Io=S1q-+5c- z*SBf!K#DDNAkALBa2yw;rPH3(fDDl+cn{3aZnp=T zL*Z_rmhSefrT~NCD-^5Bnb;A^DH$k+zDyN8E#HWqeJNsSU%De}lRdzYxKdtu=%~+i zKT2B`!Xutcfdyy1=~zgblIi|cUPt(%fAA@%H^EOqcElx1Ayfum{(d{;TI>+-M<3|| zdX&Us{67^W)A0%tceYD+{b%LkoDB5BDDl#RfTE${|~Mg9+n`U;+fa;g<9 z(&MRAFz51S!GAX8^5$f@>>iiP%k{Y&h8*Ec`y3^wIf1g_N=_*}@-`0yVxmaSJT<3( zqQ_It=?K9;4VWE{P3a}QH~t7AqC-K#x0fRKbO4Mgj|-;hd3;-WnS-;~&>V&aAGfB2 zT2gIU?MeYM5rj>)d|p**N&j-krcgN5nvxm<1^7=X$#(MtRTC9GvI`?KeT961o|IZl zz6I%&i-{c-ZeXs@PgbN^_v(vuOL^Iq$XKB4D*RQ-fwi>C@?XpkyU#@rE2X4I15;hn z)*r8F+Uo^v-IZ|EqFS6|@Z0E%(?3?6R*1=|*V-+D|7l>Zza?35UYx2gPMmyQiz3D3 zD>YDd9Rg4R6dth~a{3@;Pce1F{-d0B6Z~JmNwgkqqPZ;nG)13NIG9;s%gbnVDF#BJ za0V>-Mv|#+_NBMo8wmkA+lBHK zX@E<^DL)k=u3)B?uf^!Nfm#$An^p_>Bi&Fe-GI~c%E%%+(Sg?*6_+$UlPThjtP0mr zMonyPiIZ{ZdR+yVI%Cxj;d>{?B?<#B2QqC8;E2*Q>^*5 zv83EEjTihjxb~oB)Tv<=p}G78)O*14|4cFrPU#8iGI(C#encdP>D6%sdiC@0t{!mY z!RIg*Jog8>6G6_{v}P1$4*5h#JEYyP-a*dz8{$bBn8KEDK8$n}ll*W|<#ox>pE=X= zGaf;Lxxa=B9%n8-MBwsin|ShH!gsM{v^@Q~K>9FW$UUd4QOrL!=MZ)kx*u?2S&?^N zJDo>{Yd%tO%|{5G-d$nb^MTbgSg(|}qwDn7YOY1c4fje@lI~(7Ii9m&%K5VVS^a7Oy2qkjcW+KHzwrlWKK8530 z&YY2S+{PC4!P~JMVF;#qY54rpL1p;d2gB!_g8ZhLN9eeXHO{mK+-_sZ#k3+FwefA+ z^H~4g_BrmG(D;j?t;Qc=BQfZ~{EVX2V9->Yw2zTf#yGryL(R;g#qk^xeDe{Ya4Aeh z{@u^wQegeHmTAPM-jt?CH8F|aPl-{-YjlhX{A@fX9;g#k9n*?7^1r5j8dd5kb5>^!5sX=A$xgxian4%!~v17>I%VWg9BnAfdmy4 zQ=|@5mxu|)V&RGJA;m6A*`*iID3KMG<_bQK))BWu!Y^V7LtW z7?mHV_s{^W9F+y!;8-9X&fAL_jzxn=f_izXNP@_li(KJql2W`wg0NKb=Sk4+)v5$R z4BlV~3K!;wXFo;~G)|GAGzylmr*f}z@VglH7UaK!D&6et+@m~ga%6uj_&!Co;J`MV zzzi7*!LQd8_N^v4Dr|x*!9<5imfk5G{5GgqmS~Y-AFlo`_pM?h+(8)F+=!~3H5BJk zK$OVo=mHZJxef6*A+~s^&)y^W)@Wbc6g~@I!dd}pmWY*IH9yhV9ujk{LmFyr%ZmyR zeM2KevGBZw1Sysw&zdYt%?YHIaLnAjyOsNd`ItJpbXYlX0xZBWOy`X$A9&l?z`&cw zluy1bWo%&b%_#*ql?OiG17m}e`$C|$Ir9G{cTX%%HuO>uFdDkL^rFB*hzNiWpt*6H7U5K@8F5Dt|JI_pGz;D-mZ(?r+K@s zaSOrHXS`jhv$~ILM{LQ}P((w5ue1b$uRFjg(Z_0{ot((MjgALz$QVS0T~m&7 z;JX~C-qzvXW4VIwe0n}MNbun%P&^=3;0HK4yWt`7KA50=xtU>#;KY=gye&h#N8x5Y zNJOs_(Re8ya~9!Qgcc?PyM!CW)B^@)Iqf z!J3_1R7|lg-Jmf@UX&Oy!&%ngK|aDW65=*cIHDI*^vxW-p@o8iILflDk%Bp=;j0l> zC@-KmQCM4=DxD}hU>R<)lpXA9#FSurSp%JLtc2Bvv$Ict%9-vx_@1z;9$hYHI{uWV zMyTf-s{semnwEPS|9`Nv2woO^P{vBnqyqAVM8#y?~UKfYe^e>S3U z>p4jXvo`SK<2uew&b)V~I`ez7J`4W8f<&L$u8e;YWJ1YigD#dcgiFj$I zMTgRR;JEi-cdYzPcS`o_iR;%7Dr+UfRd#GQ{wCq|Jb2Mgh1aWIOW>ShJf2RBPzfiIqP)&ah>PR(X&i0N>!Yv!Z+K0dZUv`t+H6d|t#Is-eE$sb&IakJ zu-t}xo7(G35+f9r_fCvZSpNMh2~Y~lKS_*;vOJU!7sv8vIoh1%e#HGR#5?@SFLAE` zOgk(e-Ni9-02;xI;CD>uCkVcJcm*Tx;Sc6osq=9;$RdA&-`dRIqVG=+!ca`kxW_~H zxpYX!$vHj1dmJ;AU%;drdVbPpjTu8hNftT$&6{cH=9JvS%YARl2C@n0@dJp;j)l>!cr>>$<8!>xKbMqIheyK~!&~qbr`#)R zQ$8q4(4BsW77V+)V^)}Y0gBo8y{VY}4QTPbn@@O;_YxLf4!ey;?bG7Ihp-TNJic(% z-UuzBERa`H{tD%LOAE0G#yj%ag`=pS^BDrYBdc$~jTC}!C%@cEd7F2hGyj}R@l?{^ zm4DGM=%JS@f8-!MppOSS+-X1hdR(2rH#h#7p!0teywrT-uts6QLOg_T8O4`=Z$zO{ z#F8qpk-XZL@YBN&;3)Z$X)dXS;|c~hQnXXvG!^Fu1blVgADS;fqw(JD38e`S)ye`T}|Gj-GzmBIhanJM| z+g&nbJ%Yg`?1_>e#Rg}*Si)D~5RkIDRj+=!e!k$ZK!{jNqn=0)eB5*FQ^8NGEY_2% zXbGKa%A=JS5LY81{_C8NO&3)qQ`E%Uk<+r83M8WFl5@*yp2sthmGt%2kdR;NSxpswneu|N8c3W%+231JO#~&qyfwVu9jo8a>Wj4^0wee16Szqy{5R}M#x#56 z4!n!CPKp}Oj|KENnjgo~<8VB(MxBp`0y)@3f$!oE2h!poHITGmo0E>`^_@U8o^ndY zt9&mXom!dV?$MEkwE=bDP-VJ1qa!Wdy|^-yLUC|(DY96ZLoeuz-$^gI?gu*3a!aO( zwZzH@l@*x%1pjh8skrj!0WW#*irsf9fz6D!cumLlu%~&r)B_|`0ype8a(|UR_kw>6><{76Vo?Hon|^`xD*fgP{#%h+ ztR08!ko=Cp@2V7s|MQZ&8Z#C@uGkcVG1*8u$Lkcsn}*^J`d(FOs0ISh$nt)sdv{be~207ppO+H>-zO_9JnvqxDOSl@ z8|g>A;si#A%On*_6oiw;3;zf^c(ZQ zf~;X^VdC>RjPm%0U*W0>3J-^`Jx{~{SWezV?~siO&0CrpmFJK$-lz!vtQf$f0EqJJ)e@MCs9}M*AmL(j z!G=ZfU5P?QS@){oujhBozzF^~@U9ve!T&tJsD`E!?R(@8OkM#@*ruOfL3c6`eFYUX zUjGSE_X+<{yr>nl5(SJ_(4SFTsGvV^rDZ&T*>SG743PitDrm%Wx(a$3g;jIX4>{oq z`Xj)6_g90SPLNdbMPLmpfr9_E9f?)j2!0Vr(8kn zku0h~ukwqkK^6R>YS0qAsBHNWpH5OiTdUOynhNs&T?MUpR#!niVmXMLkIfbKJGPJc?&ey6?|3s`TK2X zRKs5&0tW&*g$=uKs*JFn*YTF5K6$VOK1+WFIDitn@Vo z@nGyCdgfZLCDqPV zO~Tq@U#}3#$`7>MhaW1mhsAhsdLy=y52cTQ+W8S+EFSd8q!ZFH5zYn_vaFT*Fw$}9 zgjoM|cG-Tyt&j95I{-RMJ(h@MAFls8-Jbnz*+J^g*t0w8zrhB(9ro-_M;gtV*+dB! zYP9xtV1=W1U#=+a!u2(M9NCBIj0sVCAFCrzcVr(yBaUPrV38!=z7@S+q&u>|6YIa| z=iQegyymAGb7X&CzwZotHf|uDxLeF_aOQmg2i9rqz$)p5&P~gmbS)$8;tIckIupw$ zrZ|HuiT$XWBV2bQX28)#b$3<(H>PYZ??aP4h!oapF(n5Y&`(fnZR_Q@t(JE8n9tuq zqR8QEmoKqP`^vUjz$&rxE$}OLSEF5U?1O~arB-iiW_@dpJ-gK|?RTQ08vRr?ptX4S zr@DKIW!o)aE+X-2moEC{n=nzqx_zJt?>hHDm%V&7ZHaOPd1n+vl=eb~3(kXV3LCIf zk6DC)MN9(S=U@w@BT#~A_O~77!-y;vS+ZYjKo<^QV4T*=pltpoe5@dN6IOhVx zgki{@x)y|q>%cOLf3ICw>!)|S6zXi2aPHvSm}Hdd9nwC#VBhB5mxFrC#3Ayc_dvQ> z{}p66Ma=%dA$@@*(PH+8**lmGDGup?6r>sjT@KyPfmGhZqaYsXBK8tWZQhn#F>fob zVM!Ys9B~a+#O7_=Fckekl^@y7SP2lq%5*XBy=iu7>h*Yz(M=-cT&t^D?s z>uyUa$-%bvRQRD&eLG9`VFf_O*&%OJ3PzVbymeI2)VY1&{%y+fvN^B_j;6M5g6~|^ zrzj|H^}q$ z)E~gA;V;tjz7^{aWZLt-cI15z$)MR0_XM%*T}uF7R8l27cKoW>z4QMeVwh*PEdv&XR$RRvj}UX{Jc7etWgbORBJ@}|4*zDxkSWpd!m^B*1)`-KaI%r&yye$QnVw?9wu_7h>K!xF7=-X&_sqt(rw5p6D#nHnvEoWR0kx zF>6Fw(X7#^s5PQG^3JWcxKsD;<67yq=T!r8%r;CE>>t54DMpH{ z>KEPf_QsN7p;yEG`>->i@{MNZq_$Df9B=j63LMOgd)!=UpUc+{AC0-mbKH zXUG{2e(Q-7Xy)~hGxGTjODTD+qmOWn_~L}y!ZYqdvrB%T*%Hbmy|png?2niyXw2CB zay~ULmhg!)VYZ|enDnF6Mbxba6mP%PDeWqdI;9_!#h)Y4*KkS43Z&g|K7Baw09NL7 zxvx~>+=xSH2%$2Sg<$l2=rzX=flUjk+mqsZ*-8dgw)772=7f42HK)-E_o7q0JYW- z0$g%w4${)s5JKqki~(}#KsypDA9=>wf>27Bi$9YtaDgtYgp^v5v>nd~I*K2B^K9Sd<_y0r^K}GiW1WvUP^4E#5Yi4 za$@796z6wZZFokI6F*2i2BA($Ttp;DJV_xfDx$={gkl3S;78O(Cdnj>02`Qb5#EbEapyl{M;%P`cof20N2@+Q-q(w6*@k~lwrG%8a zk+>Sq2nyi`iDw}(O0(43L?lSutdK7DC_G;Nd-?_aZY8{$)D|c$ctvO!Kf>Co1qc+@ zR+F$0Ry)xG>!^}u@nQ-W)-L}8$Jbi9yA1lJcn4M{lp0txq6ZdT^@TVVEnxAe3|P5{ zwabgivuKx>laNuals;4S^9s-q1&FQ=kgF;XCRdX;gtBC#R$j>CaA+Q)fautShfFS`TnCV0am>Ha4@mmxuFAs5St+kXxt3SajU_5vOOaMP} z6$!Ik{XP>ewJs(?z%1tki%ISQbBJSWtrZ+vO;Qe+O1uH43O{ny=LnOlTbOXEwVDV4 z6XFDmf23e}IjI5_s)<9Zzr!nFn(>Cf-T0BKNNMD1nscE-wGbg-!kl1nCI!pO(>b=* z+RmZX7Q6!HDBb`=w@k=Yv?fum9>9c4t(gcT7+O|^nxZAIfXU(5TI&D~t-cJefXT%h zUQ1ydgKG_>rq@2$QQPGvQLJhX|3I04G>HiGt31%BkJ2N5P$PiMlV)=DA-Ocf_sJe7jw<;5IZYpv$c>N$7? zObBm)X~K_ORf;gV+RcPZt<6LTnBAOU@eB%K>3%vhF@xb_@|~CKS*Jtgs4aS$legb1zzBM``6QXF)YlR_^!vgVMI za>>{93*-<-qh{$B$n8pe%~4A2vo<3b$h$c)Zl+-5A1Mx1%So47!yH+2LP@#AqH1nC zN23*_Um#~vxUjY+i?r2ewP11#$eH*-_4Gs_^4y!^V095l+!(--H91PkB?IUedCui% zXe#{z`79;AW+0{ZS%)AP$iq3Ympm>&&ZRi0DkoiPb#i3QASLCJOX(NLMI2pgokYJt zzD$X)xq?#rti=ch@^nt@9fCk052rY^nw%7^B}dj=r=(mmf_{PQ;b>T1`UUd!N_>rt zQv0ln5e($z_>sL65GJoGq8Ml{Cxo_ARE>+0$xEE{1Jo*xgtF4FykaWH))Z4ppEZO) zU^Y=g?_`9@t0qwl`ZSyjy%~zCp&N04IfH(H*}{=%M(I~x@gT?6OsAASYdZpgd6a%& zaWTb9^_0oKu(J52TP5XjnJ#%W?v5WffQ@VSS3J+L==vZOxw3I&O$DX&K7+r=qLZSaviL#&lVWP<&_}|Y zMC2%GF(+G6MZxllS2z~hO9`Q^99dIIDZOvuFEC3f3d)KfbV@0vrj}Ddafuw5i#gen zY6_NDyw9=FTS^E$<;a?5O6lE>zrd`dD5xoZ4u65Uo1&ng_>ot&Q%ubvP6cHpa$vS|vL#^(mRF>+@rABZLg*%z zf!O653z=yg63m#H2m@vge&kh08S^ww1vMpdVCHhNB{>u%43QCC|c~vgO)C}ZQP*5TVW)UY_GJt~R6+<}|`bi0)j~rPugi?Ah!(U)drzof+ ze&khyD5l2Fsi2xf4onaKLKle?x`&^<5QNJ{bn*(?a1Nm52;R_w(HGDv@XW(8dBt!Q ztP(*4R)t^uRO2U{CGglQglCKc+p&tD2ZDz2s@}imgd#bmS1V|;SE{STPrUzZ^>U8E zSymjA>`x6&Za& z|9|j4&jk6#S1?Wt&*)F%N6hgTA&4J-Ne{ugHTYh5Q#YEc8jeA?E4W(u`TJtb5r(hr zPIFan(^OP}?11%)PF7(updmV0buJOaB55)po#(0;3o#^xn=K>(;U+wJKC^t8@_9)PNCkv-U8v(oZ_c@P%QEvU^ z`$31|^j;=TIh(*ME)KsgOPUL>kFC!`9X&y?go94mv0i39)%5-}kYV?atM_#8R?`zF}`YW;Q9o-bqs|2G7bcQC- z88d*%o>NVrGl~!rb)nKHHG#g{8zc-{+a$5<3*AJ|e~+xG%HDm#Yh2uL$E*}A{M$O)3efH`1dGBHftrJRUt%ih~(2w2gk^ zc8eP~I0WlR78?BnkOzp#q;LmJDz8g};U+2^bdyIxh$LIC2IW!^R{iRNdQlMC>sXKu zwH+3Gqo9ure@a1UKQwwUWe_ptZG_|44|>J|Mp_)X5&Se#{WXs2Ya;M+du0)P4fKX} zt`H#{wV9^rGTsAVr5_X;5%@SVtNOuK4eAkLJ%f?TLuXzFDt2>KZ z*zmm+-cI3XYvGiia3O_fqCF0$Y2j3w@YM*<3x$7;pT>;SZdHV+F{2xv=$}zsO8T3N zO8C>116_?7&&?jCBx}s5P#+^B;m3~SNnRE>eY_$rRfEl|4fX@HCrz`wk4Al1f2y_K$ne*>-V83-ZRco~KFLU`m^gdGw3_!pCG1ncN0 zJOQ0Kgk{WGl5dGT1OiAB2@O`p4Izjz_@iHc6W3oF&c~Zet1GY<%PDO`r)e>s9C?O* z)3Pd#$7W(FIDI=Q+*JIfnngf}Q*^AOemL1p9E%P^>9>J`ev9y{nbTgyTNEqWt4MpW zX%9oRhg>{hp-WN8J2=tUg{3^fWiu!!7^IJe?bEvBTxT2y9H2nD)dbJg+fW(2R23&V z(?({&M+0{3`;b>tV%*JEiXX}UApb1}5X=aDn+oBSR!<@#$xr!-y5&0>8JN#61 zXfjzTaMps9(9w60O0HwB!Ki>j8lM?{`2_?9m*b7h8m+E($tx*RShJE)=!h_3%@Xw> zE0-M11X%Vim%NNnMbC3CXkcf7yds38Vt@$?CAkQEEtHm!%Y_TJ0F~A;n$AqQ1y9nr zVrkq|B$}?oyK$z~7MCPUC12R}Su0&}iu^+WS?8lyE_xWm- zf}jdDi}f;2CRka7pU9KQ0fOimC-GBE+k8|FA);y)A>Xi@B&OI-f+Y>!11G#Eeh~b0 z5*;nw_IH8Jk%9CkF(6Bck{{0fzZDiWGdh{6rooOX<~k(X`cOQbmkm| zd-k>C=($ueYmaBY;0Wv&vpyCBTbbrOoFSJXhW2+8L!WmqcQhf&dR)xfYs+fz?4NJ# z6tg}-)+hs6_4Yu$^|R)PBk;Bu`YIJU$3cr}q1FsX>Q{lgHrfN5ZRI5)WDB1?kyUTY z`W8nSdCFHlg~SLt7H~8Lb~lH`tncZ>qcmHfB!mRp5Y>tEvdSG>t@FjKP{6S@uv<9? zue@-(r*%FK!zuAU+=^tuK1@$-hL}-6H@By){EuH>Ch)BO+FFnL_c_pbG8Uq{T zML7`w7G~xlgh~EE)b|bs$x1*t=rCee(60(Fo!&^C4&TzZ8wMzEMN|EZV^@aFx)##5 z*;~hU6W5$WSt00x|2jN0`lsW2^bdyDTgNZ%Yp{YQocRnY7KeA{K`Xv;U#J-)|2fxE zPhL3+GjFGM66Vu`v0hc_rPPu5ql|K8pdtFP_rQTu$@R# zCA++C1~gwiWl8W&L~hropg)L@Jn{*?C9f++QNjzdcu1>8)iGOxt7jlL;Rg`K8$n)1 z?s<^>EIkD4IK4vjvxf|Ve-~AiqUXFJ<5l8`u;!&v&_p%2G@5|{z~VNnz&s&#y~B23 z0qQVzT-6!QDSo!&`DIkVlJ3=aBEBu7`d9dI%6|^g549(LFibJKc05U=i>1+UF8tYO zc3l#mhL~tiE3Tr##vMk0g8{)lGMIFJ;NWrHQP~aH1|s-x0x`?ShgVWAmJQm9!qS0M zA+qwiQu`jTSjx+;K$%CNk^1_#_(j8TE2u```jTGw^`R|Vi9&Rg5ogj%a0gahF5uSr ze#bkearH;=x1h6?Uy1X6Y=L2Pcr(^nV$0N=eRMHM&_&PHE)0TK4B3SIa(kW@5S1=Nv$}=T3^1dHxNN6}s{+*UCG0XwuYY#Zn7T z^t&IN#Gn8U5Qd9uUn9$vf2?KShpV#tX#)LE_bsQ5$-={I5 zbtW@my2b=Dt9qe+Y8nZ(h;q|KX;h9%Psyb6vauABS~9*eg{8RIAjRhF(4^Ru9Z!%2 zlIs{L%2+dYq?)l~i7xdiv*Z4IHFoTLgxOK5v4gk7>11N01 zyX)s1q=;+i&?ek$mH=&UxIy0?myu zy29jIcHK>ahBY%v-WK(vckf2ZtHnK_V<8E9dWoPOWsIe<^^vr$EjX^~I8M>&IeYr- z5m-1$n^$vYU}d%JufV71tRN|~?LPGtkCWBMX?QMDp97h=dOpEG_Pxy9K(gvoS=y%C_Hh zETk4C-F>FBu^!!~E`Nu!nqu&8zEg12w~chl3#YSehTNAb(&%vyat57g&K<{`xXIBO zbf=^_>rbRAXGP~Y1$#qVccdyts;HRWJNsIktWU?Wl(LuxTS!c$6p~SX#v^2uAE)6N zGRn_^6f+t9-7n0m*C?YjB?}o{k;^h#8I@5gkFKk<3LQIPL)m5Eg!gEsu(01CWjlBa zXSJ?^Bxbu-Q$mm?u@f8DY_)OiN#MH1^$6-EGWi;o7)IJ1Lux@>B9hi8+C-|PL#iaC zy*i}NV@PziP;#VF1JbVvDO-os9z&u&T_RF9wRBe)kWM3{bRE*s7!vjA5|OmheNL88 zS2}FFu|#Y-r1XcQz0hjJB_d^>tUGh94k<@NGHbsx%-U~})$q9POwA-s zNBjPkTdZnL@MssWUhsN=GCFYTKp~Y=ek)TICz0AQci)Z;?zeVux5viay(*H(XiF*t z%{iT>^2e0ZFI>$M$w<)_{XgnB{#Az*&663Y)vjNB@A-LM>Qm~AT~5?CN4#DmrUri zPPM7fd4{skG17m>@5gjVr_S$ry42Bpn5nngxsOxt$8XX2oi~m79oG2mG^qEMn@OWd z=y0-wZ$B{@qZVbzO~j2F}CFAQ!&F0}e<|`u&j3Jqu&5V4mkyWLaITug=SugWou6Z{Eov(JPRBNm%%v)8hDok6| zaSAgT>9QD-xvkGSnXR|$kfQ#LWVSy2Wa2SWhZL(|6Y)?hINsLZV4B*b=W8Y&zbn+l zqxK#ak4*CaljqB5>*?$hgRLiROXa51f>ipZ(_BZirqk3luz~z_avdYZtcM8`OkD$; zb*W>P%Y+GLo|3HBW);yrS?QZPn}%7zfEMOL{a~f;cFr6S>9l z`m}!6ITFtv!N;|NBfVyk>&y5(b4}B}XR2w(uH*_e^1xivG#;2Xa7T1Vwiq|fg-k;- z6|y!Rl2b$a*@n1XmpWP(Ki3fd&Z!C6Ex%zQ8>9(Yf~Ji%)wC4Wv|JLYsD30fHz)N; zKByFfkz%@HqG_gG%SUvnqx}{$CYW{N|1w5nLgBBO3BxreknaK>l&E9&kORsUpjN)4 z9?kq85#8ZYn)jPJ>TTS^974Q^mLM4~PHJ@yz}*dTXQU`s%>=^K>a^)npE55R?HVt{ zyOnE}Ud&=_Ew zObl4vMBWSPQg22Pg*8E%g~bUUs#w%VQh63@6_U{b)S5H4`#SQgv~^QGlir5oxU8k; z?E7ZtOYP*r8}tZ!@Ivt(JbG0>7w8S@5;c!JOU0fPEq_X&1s5cblx)97WZC$jX z!|9X(ooC=U&?Dbo!Q#(IQHv%7BZy1hx@<$N9*Issj~vn=6={}L2>#U+N$a7}VS#!i z+*W0Ye4#^{6hoS5ilkZlVFsjg25vx3kj!OFE1ju~Jq#qh?#8qJXUo_Fx(r3x{d0A98J1fqGL}7& zWvo)`H5jKc_ru#79k5YvxWnTlMW$&?y7p38no#lIcOm|Txh+^SMmqH_#C~1sn7*2f z+|2ruwQ%t%-1zBM=0=mk4fmb2faf;kDntRnAT5l6*TuhAnT#A^wA%TbmC48p^^=i( z$$=O@8Tm)$GrKjWzXHDMyREmw2c|OJ?Q(jnLx{HsKA%#^W@7fKvnWlM`jiFc_izs= zEc*BsVv+wS=RG9&Mq(bvi5X8UJ?S~?Y-2y>%S`UatnNnr7-fAEO{{)|yr>giI2T_j zJtL|>v!^Qari+zcS37;Ik(hvc9u#T{QbJVRNKHC1aT!JAg{Dc`G+X334);@d15t1; zB0&x{u0VOCw|VyrQ)VIhE=^_MjDBK=KMXiHVsl_;@lhr3rIS!e_hEVyx1WO_KlBt9 z;)@oknL3b1QIzt9)bFz9z+pz&5!N(2u`|Qjwbd#00m=Y&2JaO7J(Qvh(%xy$9O8#- z@4L`DjNH+K0~H_!#@TkbMz^aeR`wV1Ih7~Enm8IAgMJSpEoY%{no577DG+60F~b;{ z8~tQ)=uw{Z9pSA&$QVMFprfC|fkAfHJk78Ja&fQwWxEyLJZdezH01Thcr1 zIfH2JE`@p`JJo zZoV&s`BN~xw|bPc(pAyYhLF~yR8%M&OUnZUxGo)ACEU}jNYPl%xtg3s4-_ z4+$07nIVs|Hsruota~QbQ5lJ7V{_#_+DCOLpNCi)t^|AHI6qoJ^E!%&rGtveKj_M` zL}5rxSx#!?sqIz3LoBz;eLwXL_TO9w2hQV&xiZ;xC;sQ869p@4A*ap zt8~QYJ`jg_haNKzn7ABHWk9UGAD);=b#QlX9M~;-umd+zo3C2fWm>c3%Oh@)nC?a< zqhh*^UsN&OfES1_$0aI9CIjW{3uun?qG+-5qatjeZ(iPN*Q^ck3k3`F`WpA&p;s30nSq*n2-sTCjn zYIL9@1kLM38?PtS%a<1+8=CH9(pS}b;nI8;t8epqG1Z+<^q6msQR{^PqZyrRVt&*S zS-koAKo52wz+$>HNvoH^YQ6MO>!oBAMrPOwfM848qr8z43-y)F49jT4OZdbGUtpIP z&G-Os83DNj``>9RoUkm^X2aD7JHsDi`Mo+8Qz4e+Hg$E$RYTB5hUdIvhEN0oAjG=; zv{OXdiRSo&>D(MIE5f&^XQ&mUF_pT6Z4apLF6n}{-=NL+gJ>M&m8>EdsHv2oo??RXS@qc>2$l z4^*P?=HF5JhP2Z#AC5ZxUXwJuD}16Y5O(R&V*Gy!yG=^2!M&*o9GHkr61qdU`zq%v z>TkykU()aew$OKXNuO;X$)T&oeeY)=Z-%rVMy`AZgX1pgU1_UJ+7ljyUAhTGZ$x^6 z2s`ttFp#nc{%MeHFK?Q(%sHDEWRoh%%H~sf87WWrKz)W~oj~$}%}Wqrb(5v6XkFMv zJDIRW26HkaP=C1EG*|FhA$8imCf^T~Ho8yqExg6;(+p=kMAE6Oyn}>N4r1Fg)mzcM z`%V~lXL_D>k%+666nKi{9$S5i@M)LyR3*tJ3HT#;P%7>kJe_*Q3I4~hKG&@BjN3DB zHl?#mohBPJ%f6@D(ZsFfmys>Vwi;kp*+XLZ3WBvQRJ3=BHcnyJl)ap{ui69uvX_@p z!LiW}`}P z_j}N(CC0AM2pG~OhHxN$`BOB$#xBScw(`}q4bzdeOALIAxHJ)a36-6f*kR~#1Qk+d*aAmD9NI@aGu!Q1J3%PevpxjZu|G2dZ`h8xKaE2g5Yo+&wGAKW zjsSpshWPm?0p-krPX?4?1&)Z#U*c21$ET1(DjD{4qGS%BxK73v7Qi>kkoIn^>>Z2lTmZV$YR#3?8R_JrEr4THfsLurgU*y6LCo4@V0l&wB}5tj<~@K(weVn-=X(YGp(VE zUm`BhsSMZpKgvGOpSe#na%%(R5glHf2HO?B?ru~cHoL-5fKiqWikVmUh_X{J++E6` z^Go2u)U1{J(#XXCF*YuOzliQ5iErc$9knV5LU`hK>ShW42;6nJkqkj)t(JDWV$)*7 zcF!!dB_+Kh+Yrn9EjQr-Ch(z+n*CFA0y7w?LR?I+>QDrfN|UTtrz!2q3kd%IO|mY+ z=@LIjvVOu*5s7q(lJ&@TGs)UWr%jyowobBsvDZwp{zP;~puTEr3+=`ySkZA%lN1W~ zHH9yxWHm^}wT#1}Hifr*Y=%FK2>$>=_|0?XTvQPd_#;^ODtLbj32R6no{Py9ywChDat8u%3&lPI#PH-0mlz@Xs}QkLuEXLKi&j+X zTK!_186RhNApbiz<7_3OS4w*%{OKOEvW_F#7eH&s=#z_*mUSL#D6XszQI#c@)s-B= zW-RM3&Dqr>ImA!KTpTjwVn-g1PDrFJ%X{+u^6)4Q@{yjUVivROb5qSK|%CLJzt}`lUO+L~x?(L30B1 zp+wQ8JM)AMxe(NF_Am_oJCJoPw<`bBl9#;6$p5u!$wg&(nRUPjT=6)FFw5#K9$410 zWAo?3m$Be9ghd9S^*@PvZEZADuK~EtGV&-k#>J`EybsOP>(CLk&B-NA*k&>#{ zO=w}_)a!Z#=+#T*%2$D;^3anZbRu;e{MJNDSj0{wNribKIn4bSb;U{MB%04sZK9g| zzU0X-H6}k30a`A|tf~;!r9@D5@Rl=8gijRWF&_eW|Xjt%_VG;KPfN1Gv;Eyc`oKBhd3YI z(YPAPL4cl}YC%RMhxnJVAn%wLtD4 zl0#f-gg8@$IEkS?f0LP^e)uaG->vHnhWY~>%9A)47)`W)0j)t37kZO&yaK+dxO#sQ z0VefsPY!XH5yE8-k&+zZEF(k@bBGPUPg;QH zJZOZt(;VW3 zFhV%ZAu^Lg^fy9em_xihHz_Z6?J)3S69PPvh&vrVam>H7(&O+iwHu;P8H(pp@%ov>mZA*MsonKj}SwOuOW3?Q(0y^J4;z&+st$A#+8Mi z?n5v0?{CC89pLtj^XW}oYu1;2j#8d@9er7%*L-?C8qE5#vx#;mXt8!6Zkb}CvP^Nf zoA;0L>eNP{k-s^%;CI5ulrXxo%D-?gziZ2c{AYg(^y&DMxSsJuE20{z5XC3`vF}us z^HHTqd3pst7{}9d5WqZ5Ksh!$DN1;c0p%kEn4_#pj`BAn%2P>E9!icf*@!YODas|u zQTiKEGLoXS&PvLc=G_LqY(#*8FRK2nU=&joE@u>-{yj!0q{0bxG%EvY&w4Rpb&LAu^^GpAd-Xhc*GYGD%u|c~ zx0y+WDhCPT8s08VP2%Uqev=&HSL|NUajt;e3nWo$+pSx%cm<*o3#aX2BgdM)?e0L! zZ)m$edL*eF>@<4F>NO8pmtmGfl}tG~)>fn2aGk+zsB+fH5T*i^%Md!Y2n3<9#khy< zJNS4L*`jr6K18gZEw%I>-=zu7NXnMwppI*P7b1X_EFNNRatK;A5eIP%O<6!swY`O7 zQPuH#3x!}`&?J^gljHB=W{89*KgN4o6hs6c+ey=M&s`gn%<7izzI+G z$2;?vVRZcMZVIFEH$pSVI+*wHp1|MHze~#Bmp~s^vgHUc;jbk*#55zsM01F`hmz)k z7H`DmVm$(k{Egq&E(HGwn&kW~MXa7Nzs5WBmtl1Ly~z|tiImE-s26|TMr~<&mEwSV~-O7ChRFo4sm*o0U{j%YEgz5iV|6W zvZ8E5tiC93(0hDQj{P=iQG%e3E6N-Mm=tAAa)|5K86Yl4fLfGXLs9x7DtWDZR~=uJ zkLf+WC|4xU#~M(_73J>;Feysg{Ykm;yR`<0yAYrjC5MWl)4&@Ll~@!_1FeYF*Gd+> z#}{Qv@_ZavW5~w`2rwy1ZgPn0-!wp6jsUeN7Ai_~`!(8BL?sqQJ1^+FRq;jnnBL=y zvV3|{maYMHe61irUlg^=Gm#-oyF9=9Cqd}CJa-{L?eer!^QEs9L?sp_S}TZ+s}*{W zFUmXjB`wMUcwpj+@&N)&ic-!HrbY3=y%JZHM-iYFrNvN`Nr*~bl$E zsmY7-<7y5{H%yCi_p64Y6d^$CpBp+AS0gI1C|alD48-b-^3y8`MH$BV zFdgmf0d-uhG$FvGDBsuCK1_@9 z7f{C)C5Ql%qWmIxQEq$5P!tCO)S^^vjc+0^MO5-y>4{iF+U9Ef7$jz9NR0i`v9cLLXKmb)7`b!PUelPECOQgqhF;JC- zXEUg&KwbAY0}FqF0Imh~e0kkzP`weAC=J>+==Nvh3-=+t#|!q7dy-1SKS3QQ4bLJ# zpATKfZ2_VZ^P$;_>GWNl*&9#q@l4Ly>4HpZ*1qWev)* zzZ1%`zby!h9H0o=Z9^0|mW>uRdRuMvk&Lb_5u#AnI+pwfvg3j5#GSWt4z2hNjt7~s zbU1TmKSy3kABbK8F>kuz%#{mz!xhtuXc8ArcC1XqjoqZP8?iC2&AU@sIJvVI@aiba z=*dvUwZ1s1xGq4lI8K%zfbC3tWz0(sG1>@ml{rLyatPNmhFs($K(%%=49c5}C?n@% z97;uOj6=ec;T3p~FUqRlB<03ippN6l|6}jXFacCR^n#!j1V5;#32>DqI0#D%aZ zGe#7*LRp&c`#dv~q;1LtKlkH5zh7UFdDio6=Q-y*%Q?@x2uRQyGuj97Fi1`d5O*O! zZ_1=rO&Nx$_M37U5wEx@!jZpaQrF{_3EpG+FhXB1P#jToh zAEMfC%1FevP5!6S8xru0Ps)x#h;w8zCN6h}$3kf!|#{jjWMg?7Tvwi+0i zIFb58M6?BCh}5sO0^=tz(X9rZkjx(6ZV%ss^etL876Azc>6-RIG!OO0X4@PZ-lv)^W;yh%##3rvAhn849bP( z3v9i2BE(*(I=ErK2;8s@xC6VwE>9>|7o(txA^2&f45ve-at*NZvs%eLavia5Sz5s-n((QKeYhGg$wkk@Z~zRmXP%JIs6P@3=Fr>h86-gx9}G< z$05I6Ozo2tz{CrX4tdc43YIq5ANn^`^-QD_Yio7EJ*Nr(QKVGlZ0_HtBKlAdLDF zVfK_C9Maq5K^XO+mVc#|p8^n0{iuakXyFuqaOz8wv!@`=U13a1jLRl14MnOiBY{3) z)#Y&8QV!cvb{YMxRh;^FeuDlDMEf@&#P#oJhu+aQ+ERYDrR;7C>~{=SabvL9d9jX0 zKps~IxUIxdz3(XEZrad8Gk?yN?NLw6opZ>N;&B)%<2j-6C z-kv@%&zAC`L!RD0or3zZpaBjoD4T)=7BtG1a*|TzQqUw8G}V^!6$Rx{&};;~Ind1p z0+ky=gWG{3D zxW@)T6AR6$2ko_|IO>Iz<3h@2Ath)_sT<<&_8Z}kMZT|ANU7!vKj9XA48MPPt>sO-8QPH(7UI=y*)8qNZF`I=V{S%w#{xEm&@XM zkKZ=Q#=Sj$+tgUDY$HZsF{5HJ=|)Un7Bj$z>G7!%k;@|TjEM1{9@S!cY-15rw}LuH z=^?yHD)-nrym0)$>^T>?Iu4h|56l&$9$VRKsvB}`g&)uP`p^7C{tkWuKYqeSA(FZ^ z{Nog^rw8pcnPT{Liy(fVXOm7?$`)FPqewfTJf8<$@>KSMH(ojgS5R#7pnP7o=Vz1g z0M4@;ApHDsn9k%Dksi7reU5kAZV*zo&LKObP9_mf5o-)_%~z&l+a!I~wk?@!8Fmvb%>RS$yM%C0YCJj|8lJ@6K)(3TqzP z2sT^FloKPHrFw9ahr0 z>!0b1X8QSqus%0)xS!t&n^ZH0`1xIUrfudxl^#74S|s8Ye$84-3Au$0%uR{8Mf8xZ zl^%s5?QA?7;_Lx%ub(76LG~cK;2&}lM(&chMa)W(v8>b%J=-B+*mRh^}*$4J57zoT&EYirr)zUZsn7GJlK*1qH6E}PyLeKmR{`fB<} z^wlSkYII`XW?Nw$`l?PS{mCxhhyJP&B3q@OpnLrA*#y?!yQVB_Fke>8dTcP?SBS7t zrNv7u7W^hI~3@x zf_OaDm1&c^<;&JxQgV1S0@7VwY;qP0NRr2VDczJBF0#q}SwI>Ej7^mtA-rTSPdFgm zkrmEsJ$A0%6%$!4ChJ4jYHVGZapS6dG5?!3qwi9~>$sk7YC{a)`7!)h{?=Q@+N5Ry z(vb9-P5PCWM`Ro5{3{467&6TTSbHJC${}~Qi6-wjYH6!7X_Q z8SGLG+4Th3Z6I{N3(`rC8~s^X(fQ^mZ5US8=cXI|-Od8;Tgt|F!FYyCd_8Wl^qbxV zmM^Af!=8z=OY^X@IX5Mh_?)+3Q1OWL21~y=U79VvIoZwj!cQNnu%_CxtY%KCS7q;mZW^+Y@M_vx}`dlwy~vA>7I(sXId9GzusH zJE@kh-SI;vWQNae;@%Wj2PsAUCru!6KQh)iFSh}2_%)aiSZmZtHT;f!cBu|vEb`FQ z9Y0tv-eAeBu}DKx!yUn;w1oVT2BfuI+;vCDl38z&x~gOo9F@dd0I$SXvV+Skpq5vn zmNXE~uCZDQa!I<-qMm|$t+3+=$R+Gi&Wqruq+5Qjqr8rG4m6 z<=vwlP3q$aa>!}G5>&Ps9h~Is9#>mf2jEtfB)6zA>dCFT7FBJg4n~J2Ir|FL`}G=1 zpQCm}blGwPxer^pRYQ`gORLePQ>@aEP7$*-ipVXxjmERI&cUsJn+T^+nx&J8rU?2>9t`RI5SnMQ_5Kh>aEVIP=FQTm z#D$;|(r%4NIENdvIlfTBJy)6xyn)bC(gL7I|0}uq7)t zJ;~k*WPE2HFPCJC0fYE5JP|)UX%kO^_&$q7b}2-}*Os!$AifI_N~5gLTgIktwE44o zI7$O0W!;93^!GQ}j(lBGX1|))REaNZXi4AES4T?9#$VlBQZ{`kX6g8$n5AJp5-90A z{c23mnuj)6Qv#0CT3e*r7O4Xs6XiYEp0eLTb2953zRZ#j(#zAt>}$`*mPe~~6knF) zOHn5_M+;?~i_hVoR=S-f$ zeHIY+ayt}mUBHzEBOF4?_DIfEzYPF?{m|O)fGzT2jdv${(qvn3(hLx@F11VF3I0k7 zTTKDVxsQH>=adh*Iury{B8HZ-S16KqpBT+~ya<5nHqP^?=5jh+@c+g6fYo!r`LT10 z-T&4nNUiLg^-Tne^PPfh;#OsiI#O+dA#vx~*0RYa)PZ7R!7de z2A$JL5X2glG6S4gNdYF#Qwq{lfvRGyHzw4=xLO9V=&&Z|DGjr~iRf)ruSO2ARV0o* zSMU0YA)TJQtvsmnM@WU^XiTlOkO=V!fK3Li?@_IIsab65fQ=QVS-@AOAuQaDuk47g zwICukWmq_?%5zT##i9qc55|hqW68zMpQ49$GtU*w^Owcfo08{d@Z!ld&SORpcB8~l zvv~9v=NZ=(rHIW<^V2Mnt3KR;_m`weRxDvAR|wd}5K67}K`R+lCuwCGY-(p=hEEIa zLV#G5M}X&y;bl*L{{hcn6VBOHIUj>-EA-^|LICF(g-(RXpKpRsN&c1@5X`7pj@;@% zLWLh6L25}$%?C9w)bHV(Xs(aG(YE&pbtp+KKv5FqUE~!cEFYlGF|C$rWRsrHuSYch zUXmcM4!{M>b`EGGVNyx(JKnSVtvi)oL(C>|?oN|)GB92|deSvtt3`ln5p+`(=}!o{sXFv0 z7X4C2opo{0O^m3&CN%h!rZgpnFsq2&hLWLnz=81fT?%po2qg!pK+jVwoq$ zQ+HkpT6~k2V#t=;WelA>VFj6If+;|(X zXR2L#G##4~Q_;)*lAp*ZZ=TqEmh(KkcI3*$uAU9OnUx$qOLyj<1lnk!`3HI5s{V-P zeJqtY_dWC_j~Ql%ov0yr=70y0z@pl71;T)L$2reGC^;~2UT5BaN1Awi+RU@m=TNjo z`USy2xyA4ZrC$isc2MuyVHO^}#+tARG1$fkAQ)x{KY))fTSex{u&YJ2w*?o`hyGyd zEy;NqU-m4$8|&L1_%02`)nGXdHqn}4IW1!|?|Yo0P=5k|CRq=Ci9t8Sh9QXNv*IW$qlS5iirWsX21q$zu z6N~Qh5kg`kEW!te^`|hKfr_>JF+{zkTX>zq%v)tH0|w z?dKy{gr$6KpSF=rKzVuJC!fJQ+(UVCZSu2ZIg~H_^x>Nva+QMY7&n&^e~4K=^;N~dCS#u$gfan$T{yYkc))F z{$C5*9ro>ejbRVMMNp;_(K&%3mUH?epLi^JZa4857HB_UUafVndK!2(p*)-;_~(`@ z8@|*sU58AdK;?G1kWJI?kT!;<+~a2>9;iX+AV^&u@+!t9+Duso#Gv_n*)y~-Y}}CS zywWDmOLycGnHO67NLS$zX1uPAefzN4sFa= zko_x?RbdT|y?Up+ElFf*%#svhzxC`FEmewL`xr+oZFESh7_lOzoKm<;Z1t%cu2+;(Q!n5CWu=NO?BR&}Q}Q1;+sFG*S!dZf!g(}y>7o&`cIC^*zgwI-ZfREZMNIt@Be8%BZ5kN(#JLo%w z`*cA)`?4-NMYj+z22@JYWd_$JDj67O%$g%XQ9ODt=chg2a0*09py}cO#dE6`F^&`f zN9z1w%ZasQKbu&S#iIQSs1L5=Yd-seNC{p?Sx(RkSfn(p z7cnZD!{IDS^bSkpDnw0}7eH#J$%nPWQDJvB4tUHoz{YS*3A(?Q*(99%u{lOm?$M6Z_lc z0qSR%810CEzq+Zpm$ondjRy6k3aj^^UWN#GgAsT$0^1StCj5JRo5c#hxP5%1{#LjB zMg?mqS3?2oDL|ZC3mI-6O=c!(GZ|Oyj+u^w5@W361y4**8Y8kYO#w#D9{*rs%Fsq#G8ZJGC`Q8Rd_Pd zEWfLss0QSCH)IawCJ6b&<*vjRfNI}O5`c8skSy$lD~T9z9u876Yq#GOuurR}InCAs zj`y%0ptXR*Uq&-m$+=cv5@h%Lg30UEKZA8XhVWy_zW%3E`T`c0oy=tq2Z6@y1eHz#mA)DOZwGlEokTP`Nuylbl+b6$rO{{&9$N+p z{?)8X$v8Vu2cjC1b*XQH&sZ3UbC;T&XUW#3t?(W_0Lo!4M;~w=dO?~kNuy7Tm7#`Z zRv&G`kAXlS7F|S*apol`Si;~iRDS*!LZD50V-L4#Y}%PM_LonijSZIpEz2=H{{=MU zR{0pYshfA9^5S%D|3XGH-A)T*U4jAEaN{Nw1;(G;ojR!Gg>&O#}KAJz2l9ZELg?46F3U31Z^OMeGP#^5Z)BqU_COKc*t zrJ{E)6{vN|nB}0+55~%J-i5(fs`UJkv1B@7!~%VV$vIdodgM_Oi9GZkxQ45278``_ zD`1t;tFm=P+c|+nwY6Mb2!K>A;x+$C7Q37Qm9SsoLP4(ba9%6+`Z5ZRvRB$)Wtd9L zURt1NUN_E(IL|7rhUL+4E1cHapn1`28YNT>fh>N;O8a!u^L&zqCMjI@jf5u2_^~Gg zMQ*|WKNFfH<7a%bL3$?dKvi_{@D(611SOg{Bc>3s?|?&bi&Q+oCUX`EM_*{1L*|5F ziOwx~aLX}Z#$(FWD}Z8Jg*5U&^H5qsOj^AjQEf>V=eY&apjh5C)d*Od00IyRXp1?W^~aHSZ#HxL3)N0avJd@TywJ4vaEF53MhcfNEq`w zaZJXoTA)i?m$2O%LAnv*%5${wK|)bhek+uY$Uq8UcpDs{Vvqc}6=PCaK`Z&F2si$z`GOrB%Wg&9uiMwuYca-RDz6eQ6k zZ)Z%Uv)oCUdA*5Wza06(#Y%WG62=R+*_8MbNa-Y-^hIXeK2bhosTPHh#}IVnPUV2Z z%$sK;RSdn}g)fF)=P>lT1ai9m#D;e@fN03&sIAIno-`nX8_ylmITE8QN;icTuAKMD zFeZ}haDz~R=4gaUo(u0nMt*|B(g6T_M34)Xp0usE%wWh?||8@XM-3es%g*Q(fEM2h+Ah=)cPJ7qC&YD^(;nkNo0OX0X5WWl&vig2gKD?ETgk5{cH1^w zTf)j)X+lm$Mbz2)5>=ytY>ApiOVl)4qDFzdeXe=&cW#O==yvoS=E?J8)Ix zv1F}wktbIe{ojhdu)Ct#$v-ch#O897P5M-jez8g0tbS{nl^gLP+d<@ygs_2VnYNjB z5Qq6kr{9YcXon`f*!*jm1Y3`Gh()U(W;pXYRiiXTn5GHMvP?|EhBq&X64D&B6uwSE z`^>3?deUY=mZ-5>3g-wtcGfmlK4R#8LHC`J~g+ehfnL11adK~RGG61R*M zBiIsu6UZ+{n&x%#Ph=b7+3Ks96w+}qg6;6X(bS>saJJ)Wm&>U_4(|bHrcGRzAD{|3 zvw()b_QgoDZRWDY`NILxCO@CA?TUNYmr^!XCpjLa@rQho;L6Ec0XqdTGUJXa*|IH?Q84Ad+(Dt28eu1Vd zc&;tzB^UiM^jH7~&7v*%u1I$FwaIhx)AQMEq#)&-eQal(!LHV9W1WmMrC0PB^P#!`RK!4-5##ffn*0>{NP-JX!V{07S;X@!t1W2X`3UV>IAyde+ zve`Wa(#sHVSyzy76^Xt`33+)&w$gvq2UmFG91yEd13l;)B-82ZX`yO=PG#i%*q~kG}A9tmcfnT$J?+C`N z-S?y0gTF)Wr<F zN;nQ-^9yMl7Oh$N(ruVj-SUOt5Qe^uB%XO^@qR~| z*aUV>Z_Z1O`fwMEq#_C-uOkH4!|UlL=(K9KogptLwt!94S|U0bg19z7L+Qlo`A1am zvdh5ACqUM)%kMIh5EKo1&?wS@M=s~N5}jn1WuhMyZVU(YrCk;e!*7@02;oy)_AX6W z0fH0K3i4AlYUo!60bftbN~B_ra>KFIaJb=M$0eWQWUm${;>m)<0F<%pWls_4{DWZU zsp)Q+r1#X~j8Akf%M$47g}IaNZ}(0F8}m z`!t0xKrGrhm1;khm%aK`np~xUu(HrgH)&iMYkMJ?dONb&{FNpWDBs;cMBSOOme!GK zF=CW*$|12Fe2@VmvL1%|ik8LAvbf$wWb_)%bmXCRH?Gpyq!;R$Fd1=P61M=pP!ZVt zs0slX>yO$x>JMkS-01>TJ3L43)E!?eK<5-2oB6iFiCFs5l}1|4cF^jIrSGA8u=K5@ zDu)Ld$2m4>VlTPV4#b3^z!OnEucj5+M)+v~ngbZPjzWdwi9ciUOSee8w8Kxmh}D+1 z%?}x#W>VZ4jI@-RL{-ac|LkQKsz=9d>_U#R89r^4!fd{1vob%1tmi1#jcth_t7;j7 z408XI=0QAmibcn!(8wl2j611Vh8VZP#TK@A>~75ypBI~PTMqZ}#sji(&aIAwhp!}@ z&^EwMar5ZZP5%mg9c%hF_^9bTXZcFS?y4rv9@$$Eh+g*a+poSC1WlOs`7SD5TZYlL z!Dd?Or>onk&)|`^=qoO6;aeSbP#N#$pRx+VFo5^a2HrJ2na^=l_IFNj8PI zBGxXuaGMH)(-j^}nT0wzyF|%B?QHV;5Nj~@jF#1~DU)T9ulVk6Y&|SOgjn=7oXK-; z!kt<=1kF+Q+(J{nq?a+@%aMvMG6dJNx!xJM-$WKR<-=(SJK~rfGO7S+KvEY4- zjaiThG012NU&}}lco`(!BM3-vRN<=vMWVA}f`mF8Eybi~8G50g^rfpY-TsWk#8im& zJsLmB8g6bmz&C%`{v=z55)x0c6X*tQlKl)9n`BL&ww`3yxtpQG#YB?0H9vKOcIzzG z8$@2zLl7ZJeAAl#Gn)wdfeV-I>8|ahFYca)wDBh{Pj}CzknHEX69I2^@=~LmwGQ>u zx74AZtCcWqiw0fWrw4R>pMG(Y4m~QKKAogPPtu{s3#m2AduyZ6X;jpiC?QfKHfL~4 z9JCF_Cg7M_RXPGs&>Fz#VX7iv8e;W?XTur(L^k)jD}K52BF5BM?gYYTW4RMhKBzDz z5o?L;0EV5zroDpH(NX3eUq}s=MM5&jDYOhRgdCEFu-_Pyb?Ex}Xuiy=FMDtwXf9jz zumC0h6Kp60jch?{I;%U-DKlEoe7vi@mY^#qc53MW*jV&LQ{l9F!l;%=_tl2>kuLAf z_K;q5`WnB#G)oegu@Y6m@|?LT3)V{3o4GZCvDP)(A^v}FZ$OJl2@ zaoNhnC_tl3{jnqviyoV#t#_)LjP=eF*!Wd%)-kKX%^+c5&UpDT4R8!Zy%W&cdgp;w z>z#@4i$y0Vvh_|mVHhTiRwx_UGhJl;3XC!ey$RrqZM4{WCw8B@7cYG#o6o)DdI%1` zLH!6~#FCpbK=ot?met)0JEb7Xb(PqJ)7PgVI0=P0uCE8;Jo#>Tg66L#TyIK6??|1# zfJ=~a#vwAC7c_5*Mr_a`Za@TsG7TAd=_71KE+!cMzZ`?~KdUnz*<>r-WRVW4Us7+! z?jHn{o!=27k>}P+*ns`4qsdf+4x8`H6puDp{FBlw+=!4>nrtFru@aR5k;Zh`LHEAy zfWm@6`$rRruNKxja|HQGMx}{>57z=+VL|?@76_~v2KbF4QT$ZAt4%2kUaX~|5uuWx z-VClJpm#vrLs)S@x>zY__a2NB(>E~syx)?a#7kC+hwfVd>++(9ATDr={s+GnG|AYe z#Zm^e4qfX(gfzEayGGs>9^C&xCnnDsA&a`mdzP}tj@efzlE}+>KE-qu^qt@u9B-1a ztKA*1riuJ6rIlFPAcKHF+>SSLJk4@&-lYf*icxWQE^^sWU8=VxGuoxKBq9ne7Ga#{ zS9C>;FkGlusJOT_!KU?$p{L6^=b{Rnt8D@;l`HD{Hl_giR*=^(y5j|-B5dMt|eIhJc>fuMHp)8 z{ZyaX?AjG!cdN4lWgGV1am~pX!}|9LO;-Pzq2o0)QQ5F*r@8WTgjxEcne*Z@9@6@? zv`gSImIS&~|0_DVHMTAs3rdNdDifw&TMZ!s9qXEWWytWBU9({w!vGuu=Au-ldM0=3 z1ShRF92yejNRE|CM`V;8D}}7_T`zE4e zi69Nds;Cl?8kTHC2D#H)@B>TkDQEy>X-tLkCUVGQDhR$Lh5$uJ99$oDuoL42L_Ju) z8RrosA1DXVx5Sw6%(k+Ex)ub+CUtK$B5Qg9A}>ZVo$oSW&oE$7@gEg1#_DOnLp`MW z1mnsCtN6>?Ow@b|@_nRMGCwr#dXU-~_ywswv}+)aoe&c=k3|TI13?}I7Yz~OKSn&i zjy#~Mym(?7xA0k{W<+=i94h%NG6;~ghnn^=RakGD{8w6RKx4K^@ZX3tzLB5v(uCGH zn0S^I^}mhq`xG2nll}Jsmkb9v1k&U$#X_(nA%;ri}C{ACId!T@b6`>eOJ5Z$F7t=L8Z0D(?RbdSjSTndQ+ZIK?A4_DTXoeC~7TWaR0{O(#@zA*QpLr6&)2~ zQlRmJ{uk}D$4Zy2 z^^$d^T0tuc*2@26KOVsP(&)$YqnCX^nWX)~w4Zii&{w55Y(t~ja1t{Nh)^HB(hno&+Nm80MIR(Ik`E^R8dL7A2cS9Bh} z2BQEKv4}7&NEH)gb_@s^&UwBd`xsFw+zd+sh+rZcXa5wDuKm!iBvns+d*6esCX-={ ziS+7E@DOk1r}LLXs^A+v`OL7A>nuiHJ0q-SNI#QGigPUF1ai9{=?BT`XSm`{N4dxM zQh?tIO|w4G@q-7pJ3drMTT;F~m#sT+zG<=*e#v>jMor;V3de@B1rrjwQpL_r?zLCK z4XN=Y;)%b#3>t$53fPnmAP7q8oQDVs-^fpcKKwFrO8g}JzZ*$tKb!Q}JLBerL%InE zaZgbYxRG(_CPc(t2yy?j1mzs3-2~DI@vyd2PhMD4+|Lv~uPPmY*VC}9nfl0mrq#`$ z|4_OZI|B>+KpeQL*@#_FN!I)~lB^yDml7!Y28Jh}BI{FVf??E*Jsc9tst$LU^{1Zj zSUstRM=Pmv<7r9vR5~hJHpDy#YQlqhyE1Erm}&Q&b(Z_vs$w5=s(6|@f~b5wD!iYK zb96m(E1lou3DR*vY=$9_OteWXdh2G8?77`#^P&BNh_-eQn)kqk@=W23s`TN@O-lF; z+V?5SzX_yzLBs^J@N=_+<}UEg2O9EK^b663bUbu8>*xfGaFQ}*9z21L$-eFEb6 zO+0QN@Z5+!>_l7B_F{K6Qa-m&3lkbU{IAS-;u%P@2Oa+RXWRynJnu~+`x&Ssqr5z- zWt0CN!1MzSIfq#a*AlLC3(rM_0HHu%gdncB9yd$Tmnlx{7N9av0s#)P^8=_e(Bvri z0jnx$p9J&ZSMoya@0-g1qjl6z;!@93qI`KuLK}v=j+tB|1%2Q z8&>l`P>c5NMO!$}YiJH%^(TfNOAt-yk+T(XkN|-m0l4DP<0HTkEdMDz# zfQ*-j&8c&K3YwoJnD`5(MCL=7+J%zjZtoP-NuTXFcqE7jx3goUT5QUjb11xBI(+2w z>W~?Id1RM=PEtfF6svo3Z{X%lrxL)Cy8SC?=5>IoAE2tT0imFAjfwE|-DkI`eZ zr3zt~E$0W#|ALEkM;C3jRIZ@zxaJuI^GCkq{iE|EQvH$L)kjms4Lz%s^Gf`8=SBGH z6J|&0fgy6%tK7TWhe%nk2F+8EgZ@zIqh#;qRQnOImvRkWxN5>TNk9Sv0qrRraO`yH^lL;9*9{!i@~rN(0v33M>P`8W1#k zU`ypF87U!?Ci`G`g{%rXWIo*n3n3jSh+Smf?vOj$cBqcbYDekEHnAyv7IZ`o4VP07 zm7`(yiv!`p5q^96Q9JIPi6H>o%K+{LKr+E%mq!8MJ_5KG0LkbIj1~wx6nkd9qhNzo zs;PLP>A+wZyUDW_9OjSwV3mHVKGuP+ZtBVR-fo%JKsV&9DL>;v<8zjRpDn$A#^rd& zv>$5GE{DIe7bX*(n*H-tVi1e%Y_aS_=Q(759^%jh;;b%kG@JZjcG=kjySsWo*`Qn5 ztw{sNCb?kXE|@HcHOZa^7p!52&F2Ng+9dQ`kwdCQ%PI4KGtE4IBj+gtzEllBB?}tu zF!_fYrYm5UZ>6%PG8vn^)|GbL^#u7I$hi-duM@vR54bmOIlWHB$ga2s3IRjmOu@} zq5`ds6JvG!2Rb}q9X~;vTi20v3m_`Uqp};TQ=DDPl3-cL6YwR&=s;uxf?S6pIj{c< z6+}Y2gsolc3hMY&o5VvHDo%$MsI#L@V)4Kv$xB09@P%(&Uuj$)O6?m5RjDy6e7E<* zSa9IP{__!-du~>jN`_a@eP-^k(7Ra*QUG_?b@*4=+~{~ zM$6<*{}=`dm$i>u(jP(rHQn14j{jgK=Ak@ed@C@%G5bIp9X$MnBVc86$jiMtibT|!)IH$bzk6rgVSs+ z+&v%W9jk3A8^al3d1;Xx@0%nzz>Mty=U{4Q4^&tQU5&djg$n1PYsVCtPobOjQ1A2T z=%Bg7Lxb7oB>zFg;h&zL1bevr+JS#my+3}#s5fjU>7Ct&YMF1;y;KkFPobTSx`$A~ ze?@3xLaQ}Da4W6*O`K)BKH@knhwM;i<gQ6y86hUTp3->*1mP{#920oEi17&V()4;yJIfa$L9b zW!A``KF*s5UEv(TsMj!LvlI?`p?L3era6TcY0wLk_C05cY?N|do&lUa{~!1Tv#O0} zR-88rxmq#ZfPgPn7(~ z1G?sME9kEKT0w3N&t?C233|6mKz&2KgzmnA^Dd&Pj=?sm&%vb>T=@;wxLShvPMnDP zN#{?%Z<`8iQP&`+(f8b97#e3FsQ*ETAha*O_o1d(d>GJO7(#H^62 z{{tj3+^@kMG=F=))*<`{N$PH}#Daj2Q8dY1j~L0kmHmE%-=MihPpeXox7-iW`Qa@v zVn*~9i@jDPw_Yq-g6t;T3&V~M=Dfk~SvFGaAeuMs%(5N+!%6q%S81deO3_B(1gi8T zB6b({(aHCtdQzO+_x{1u z{l{10o5p#b(rNh&s`3!M%ASYyP$z}{WLH%9#Xq0~;0u0JOx(((3Z;kR7@@1|_vAemC z^J@HF;q1+*e=lSu3gq4o>Yq!5tNegQ{ny+}gsTF-;a&v|I%zKmNI5T1M9$yX?{oN7 zrrzEhk0&dakD=KC4!&g3H4+>)a-#<28SxOq;Ay3@G z^E*n@a^Y!_uek_`!u^Bh?)b*=C45oPoQe?I0O8luZx~y!KTjKM>cB$iS1%{71Rp}% zDlJkEP<=HT{{oQ{3@lD>7!lFp;(O_7lp>w~B!1NhCDFT*TU@7SpeF0Y{J#*?rXC)$ z?VpnFMydB8KU)`odJpoGT*@u^7M&7Dy|FI96;&7V#L-qd zuWCcR&7+WrXtf1jLKL2%3(@L+2tiX!dF3-hKu@w z;^O;cXDRhb1Af&mDBkEeZt)j-hB(0+mqm$Ix2%VU6kHVBMMSG7K_))|nfyg01g&=9 zqeUKt<$D+Jg+tjZaF%DQXp&SHgAmZ`4PW$x7CuqJ>&!heXur1D`Tkcnp za1NqslTJ#mT@`fq4tI#LGG_-l9&-p4APplk)rmO*hGV7SD2D^8Mx$IG3z7rZi`Zi> z=xG=J!$yJMui)N--S0hskFuno8FsNYSzu@eJGO2?I>s|8;z$!FoQmKB^LHL z@mzuHk>2|eA-_O*#p6lbl4N+r!r=304)-^Q!aVM1Zqa^((owj3?tLZ) z^tGhQ8R%TQZ&+3iQglzP`^$RM(s8ub#pR_WOf^aOD-RV6p;0wPE1?x>eYoVq3IT|wS;x)&#L*{Dn}gmome ze3`rcYM^loV<>x*GFD5aE%epbaFx|^$>N5 zdRa6L^PU^^&ZgMRsCNc=PcTwIdB>6WP}EyY-ml@+FlZ-SP_#U)gRq~7C8J3$|x2uQA%ZB$b%}UJ0cIIIk>J9^W`ZT1Q zDKrheWuPqtoR?sy8|I{S$j;dJKYGBC3X_m+A3K!XBHoxG;VH>VK zbi;BUt`3~%7n;^$CAHp!doE&SIb12Q)3x4(nuc+@)`$yb&JL?_*&DW1_|+t$G7r+y zL`#NdQ(gE{x^;H85#;KGl2((vU>LJ>2%@b8_-`(sRs96x**=deJ}=hBe(01=JDd*Bs@95 zePG?eXKv@EYVL#8H=uQV^>-b_gUx)kn!;y-nC(sSJwf+TkbOeK>u%J`nPHK~?6gQ@ za6}ojh7bbTHvs$k)k>;(Fp0;T2T1&cz<`C4d2!!yYbHwG#cx;OIZ~}4EY!?r9xd^w z`YF435M>>${=sbVr+&!bWgf+Dt9X#(rNfy=EmAE``Ne}h`RY(w=21%eE$TQwv$@#E z>dbvGHzXb9KKNHL%0%(l6wEwaX5GvC0(`w9e%r*;;}q^tl9gK8#BYZt?7ltJHa-wa zL8Muas8*B3gKk8mSX1iw%%3b}(v8#%7>KZD)S^`j=yp45Ki`rWEcOM913#t}2M%_y z_*jIcjM?=-N%JikFo@0i0C9H8)L5PE%7w)V0Q)gNDG*Av0HTk<4+DT!5FUT9N}r<~ z3uQsY#Lyl-v%0u!?snQq&MfvsoVmsB2uy2>wb?$F44u#ysl#cS7sy)-M6=5;2=tMp z6(AxOZk0r;VRq@cQ6Q#PT!wm_4rv-UWOLp;ASn=%^DY4n@<%oR+fB|cyz~<~A{X;0 zo%8enjA9?_-y=17i08Z{#TyvRdG97lC9V!23UOoMJ5rO&+{59PG0QA?+z*(X4y08t zr^yVBFU&f-EKw$$HNxm0lIqv98W4t4!%6s$>siuN#L#hM?0VJ{6r`Kr8(&-CtT>B`kcubaKUQlC2ng-jbb?_zz?&gf;!)4{_k^oQ2xgCJqIY^idcheAj^w97?s9I(8BH2Qj2s zYVqN9GDm~ex0SE|fp>ocVw}tezDc(D7$~dnOFj?=o&L6&4}5R7W_-%K_oY}e>Mg!q z#4gL~yCW;Wl5f8CupfdYVY0a5A6FQ6AnLN3!i-D4yi}_^cwx&5t)~RqO!!&p->OCgfVf#afWEB(Pyz$MFITl} zQq^Km$@N4k*Sw6eSl#Ja?9&hKf(v)JEg)9Xz~J2dxue)ugz)*kLOiD@Hh(bRy`W+%FNX9nrazCQ#b7VTMFPgRb#^=yFDf_Y8S| zi{bsrDjilX&THA5;_*(LXFcj69`DV0-e-;s&a(-)Mhl&@aT>Y2@1qs@{e;-06iKSVw8I;9o{t3pW4!B<0V~LJxKWt@UjH4HTys2pOE`dicp);*v6q zD+GBqG6juz4R8!jxwD+S|1U3!k#nqmK4j%eART7SK=^oP67L`SqIeV$w}fxtzR!;Z>-Qk~eZ4%x1k8HCQMjq}lgj?VLQvcW&#bf9AM})YNpNf6` zVG)q!8G`q@QBObBlXuVIB6+S0VUjXw-g$gv>yR4D^%3knG`C3L+#_ym#wAMe_|4p+ z8ngzR6kqjn--nC9lNR4+Qt8?>UlkxHNpgHuo*&L2bGpg7jya2$z)24f@>S*Je3dy( zkHg7ihpKXN(o&SKGA)JE%bb(Q`3Q3c;0!+m_)p+_FJI-R?_KyliSO+Qe+u85`Kl0o zhx1j%PvbiT#nE>lYP$^IeyA#aFK;bE`~r~?BE)l8U+c{ervc_O_u=MSNujea+f{&R zI9zrXrl0nCsPjHS+?YGWJ*d#+T8rFD_!$jfT<5cu>bfh?FnzJg=Ad(&YJt%QLMU1e zYnw+^E53OSml!9zY00a8e2AtaLtjvd=oB@TA&mtQP{`Ys0QyPJb>0{h>QpPhjyF!RiUcwR|*1K`R>s=r}(SbMcg>5cGiV^H) zJx}u`g59jAm}7+VQXRYwy5$BMgXsXw@P7-~J40=jV_S#XjO_w8$Ls(Tw|rMsYMj>2 zxD5z(>-V@A)&Biw?R*Am*wOPD8=h1upw~`u|G5PEB?0H{5GIpc8F;aTED`Pr4~IXQ z{Onbpyzsy^MVP!5v^{}0>4-DuLEfQFZ=v90?8|29*F#s}Ju8s;cwIxAJhm^%w7GaB z6dQ|pT6B>esql;rX{=DpXr5cY=n5i8^eR@e(}L%Ws2VHMUDvP3hDt%%qG9Asa$UY6 z+4Uz>fD~=q;L`3Yf|26P;A_}p=V{?|-DS4P3qyoS+AF1=zk`?PZLC>DHW4p{rkr>b z_hqEBP#G=kB4i@@oqFVc)&m#luLz+E)Mzr7m`t(@ds>L~lGbaqLO6+D`suWK=`j@9 zs+XdT;$p2$g>gCTO934kmEXFNT+4aabfINdRS4w(4@YCKSI=3@dGLS_#H6Y|s0$XM z1K_jDuaU$j7X4;t2XQZJ7c-V$fP=WM=fn=;ZUywyeQR#xLONU7fNQfg-dZ3e4&sin zi*Z-MJdogLVS-eA*dkrwL8+*&mdi(Ljnrnh8S9Ak;2&43{ai$=N^Cfh%JtfEu~nx%VES`6c_9505lAm9~iD3)33!U4e8k7o8TXnBuLAs zoArBpe_-P~d*T}pYZN$qSWmY*j7Ci87}o*QDVA<|7_m3R$66?sZhIK97skbUX>&)v z_@OsjK(pB?B07RvU$_GZ%vpD1i}VwQygSfI*v=w^#)DjtDk+skeu0Jxf>APV1;U7F zXOl^%aZkfZWE>X*tHr%|x)65&dms!K1BuXi08YCeG8}=tU#J(GI?j4(NsL=WxF;SP{#lx(n@D#;uRCu5QLW5BJQR>&g_UgkTKI$Zp8dVcMOD zwUB2_VJ>Jshyd*Rnby(|is5+Qi$pfT2N**k3m*}fvRO2PNEQCT3{ts8bQmcG=s+s) z7-YRh#-;G2a5=*D#COl3@o#yPALiz=z&xiCoR+*%2Z2q<3I7hnh*N_|c1{5>+6qW_ zj)#gDrW>xHSM|kLsiTRA?z`rcbv%@rxQ=K#E}g!G;?)WOJtd6S+kv6CGu`!L46t@~2+i5l#^j4I&d1 zZUrFPrYMHcq=R%0)f<}_+}w7+8Gx|%#4!k@r*x8$Ac!owiZFCw39w~2#S}g(0BJaH z5lgnP7#>swQo$n_E2Fs@Fp>c2Tu(m-R0D~GI92Pr_LTjnZ((D0kKHb0Cdk( ztw*2N@Fm%Glinyd=Y0lY@G-HF^ZH^*(0e5*+WzGUYxyg>tl}QzXhobcaoiNj=F}3+g#m(u zO=}g*F1oO<`;qI&-&c_Yw27^^yfNYfY0{f2DG9%uA!Ai=?z8{ zNI3W}5TL|pwUof?6LeDi1pO!>q+1A50yIKbvuQ~~=p~Ret!~g)fT>QG-Xl8`0&NBk zCjyEEZy!VrtdGu`#QA9_F;RY-{0u`UZLy!kE&Lv}7sO*JoF~BQcq|nYy@hHj6d1YjemT`8hj4YIqjxB{$ygPmG zDdEFXc0%|DRL*-T=0p^-_GIM>92I9HnC3z{eZf9W_yTuUphj^d$z|YfZpp$0ah~HGF6~8G=<{)018iji}A>5AbwMt$%iJBunGnIXoklf45f1gbs-y-eR z2mJ-+#|u#qBjijC_F)JuOb*9AJldcn; zqNJkB++yx+#HqL8dBc)I z4FtFNBJu$sEzE2Yyt<>PuK|wLKMp4($8k3@2?-(r^+^QkOG|yNX_43pQ~f()v>Wc9 zVDD4A;l3s6+5uP4d^rjRy*IJdoch6!6xJPKkPfs3o%#=iDZkL_yA%fapB;eSq20=s zTa_oVimsTAJgvKB&A-V=HyOeoDo<(27zn)()yGb7nAi(F-6(Z%>a-2C2ej=69PFKP zMwFre^<(q|aDc866?5L3e`P*8*~EI&0$*$s@LDa7c8}7XoproHstYKUwuH^X{mHhg z(&ISrP$$QgR&Lh`W~!FodwIBr`9)^jRB1}>7j3C3v$T-kVD|vJ^h72G>9}2Y;7JLS1pKBPHt8_3-TD=KPiC4oQ z#z*Q2XQ+lj4}w#+GgQO)7t8iXs$tyw0NbOSgf1eXaadFpqx#nantJq1oF`ByQ^j~g z5B0u^jt`oZ{_%I~vDHX$?Ea~Lutvr!_p?UOJ8NtZSK}Oms;p~dP^FZgemOuI8LWb& z^)2gZbd3y_=Hr%Wm|fI0U@ABl^Ad1sSwS6NSdR+@mKHi0&jJl${RJDR4!Qv7jB3QT_B`@rgVJ{Z-d)^#$j({-t@f-beD zP4@t@Sql3{^)dQK^)bd35H%c&-|%HEwCM^dBIkPcdmVn2b1!a2x0o-5+luk0EzzEE zN4G==En^xP*b*JIj1(5;6&PEh$aSb63V@2mUVN#W_zLP^_jUR#eJ8)y04suN0R)Z#wO9=gwBkUJAzBxVHgv@TowrVlW!2Eic#wwu5W zsfDD7i;qiG7Sxo=Ev~^H`Y+rASCs7Ug1zIda9(mFImK^Jz>*anOb+@F;Tn*_~MtYoFY%H3H9n*|T;&BbqX6LO!N!c92=m58HA`alo~ z_K?|v<}LX7VjH~ST1x*@Hp`Wb(Er*@QFZvahg|a(n_XaNf*42@3Tqz1gQSP)3c{rp zZhemn;;t%acNCt#h9zd#6dw8#X{%C6&h)=e!8INR>P)nWNf*H`ZPNjq!NF7kGFFA? zctR`t46+^qhEyrPD=V!Bs!sf_tanmYQ>?Sjpu*=-Rzlx1Z)+WJvFhmW$m)Ew>hSN# z<~o;m2l9+*WX!8nbtTP-HoFrqfyF1DCHw%U>yHM==u{1lGlJ5>4#R22tq@&0 zN(x_RIFrMD5VB<*)cEYV7Mzd{DkOq12UWhGco~wGAC6Trl z1jOpBITz#h8>Om&mJ5W7XuMFmSwOr{SUvA6|LvJVX#>4=71_)!{**TPbbDxJS=sKU zD>?6L6vkC8W}t;golv-)^Sng+J+hymm!)R=QZsQdM;@5p`_mqxFQa?@DqnLkoRYKW z3A_9jMcVvx&i_?u#L~zRkw&80r+Ya5>OD+E>Q`6eeIN5%7m{XOs7XH*q$!_1a|of94oop*3_> z-oMAaB}V*tpB{TUCh6oUt%*O*^g#SmFjobUi2rtM*F%Z$WQ6Le~)LleGw-XWVNKSDtlc2x) zEJi_-5Kbn&kfxKFxn~BJ61`k(CW8BaN;B=|HJSij{g9vDi!R*!a6Y$wT_-BoKa6hs z`e)&uE>zs+bXucnmp`-z33W2*S_3Az=1d6Wv>1VOtvM4>GDaQGDBmukG#Y6K)lbaHqG`JA(KI(PTKGo8X@)XuR6M@Ma3+T@Pe}Q?C8B(7>$(#yXmeK5mf*cb4Q)yAERwdR zfV~MA9=jde-I}3;>2Miw^rh_pGTauvh&CHk{Hm)diM}JjEq+YT5H)nLUG0S+D|R|? z1s*%8cftp223_%ChrsI7KNzlMa0Sgi07akc+X(94aOYYXu$Pfo^&4#K76jBEV5wi1 zhx^s3FZ~wpONFnXPCbD=@mP|L;04&>gGmJ17sO`Zr6>fSeC=}~K0)(&dci7>x}9pj zSo}U0cKRKqCvgQDw`uW+QzS?aCOQJRk6mk(HYqEnXbThv<~pfyu_x_|;h|S9mn=Z* zaFoHAOhLnT#c9VLQtDX9axaR_5b0)(5J)A}*gxArp-+5M&zXTSZKYX~SP}+!V(4()7So{yYh`v9^KLqrz-Z#24 z)+>%$C@Eae>NdnZ=Xz);TtF81=jCeZ3AV^KO2bD!)?%Ien0i7ZQ%~54>XUlHRN4t& z&(sq>qw!kL)Du2pPNtqfGn!w|)D!4HpI^_^6W(A>rk+sFoJ>7onHEaw31wO+=_Jf& zPEt<@&jNhIQpstuOy&$TXP;dr{2{=1oiU|d}V#3V~D_n&z>yhNNz(kjL zBAHtj5CadlnvJAmaEX?_F4*~=TML65 z0a|oVK$!dj}`AroTuxJriEBYls4L6ub2p`O?ofi zhp+lIn;=Ox$&*h5l~nKrnfd7;S*6#=bpIss|2^g}CO>;8N=si3+)?Mn z;s;PXgg_&I9{KNx`E$uX0)AW2lTU~3_-CZ0GkCRMEbUT6QL>}>QZluBEbcJ*(_(&w z{EbMZ*E>Z1Z)5&lYRG=)Wsre$-g@050L-$n7@Mj&uM;agS$H0@I3qgEPG9= zh)|mZpUO;ZQ>R$+d#Tfn%$EE-bz;mjTP23C*OB&$)FClHT{ckr#r(_3e-Zp*bEY#} zC}jggouYP%C1U=Q2-Jc4DE?5)?o()9ddYOxTWOWJ5TLTSJuy_w$&^&@QSi*LA;QjMcjlft*^1@{d@0i5+!Zg?m| zS$lrEO>*XEhx;Rfg;8fU}`aKySJDF+IDm=m)ds@q=A*K8>qV2EFBSx9i=ya9KPzUT45`7 zjk_^RnY!Kg6Ag7cTE_$IQg*&V*w1wB9>Z|7(6w`bOW9pG%t)wg=W3~JXI}wj>*U5AIH-UX^_SrjtJX@FQI(Ckwx`G|p7ZmJr zp2glGh%i2b*KgVTHyoxs*JI(${72qjIpoE82hS>v9HP)`>KqwuS%v}$Jke; zDayVob@o-Mv#&~>eO2o0t5RoQl{)*X)Y(_1&b}&j_Eo8~ugX)hufZJ|`&tV2RcWv< zXYVNc>U{?6%cZlg-a7kwN=FRW<%FSpCGj2u_if_3e8Mf0^UsiMVpvN`b~NQRhOt^x zvb%3N*o^u)Jv7RY)|jbk4F!SsU1pTTIA3o;GCz=uQ>Qi1Xv18pbThmi10MFikDQu* z9du1ezfR|9OA(>)>PhI=tpFpt2SO(?uZj4|eu^Zk5=%zGD>gyDZWwcD`gH_e2i=lO zGMI;;qf7dA(5;hQFhsSOwVN0kn^VnLZnEx?J~8@6CB=QCr5d$Szl6ST{5)?(J9L9w zZuA`1-WMEWZ$ypZ$MV`6LJpj@OLHM@;=e?u3h-#Pw9W2^`ke$LTRRj1l@uS%PI4B2 zCtQU!4bI@^T`C?OH}@j(=m?znkty-H0lTD9UdpKC=viQ;%Rf2p&15-6kZ;MgNoh6- zF9FBJ7~7)J`o-Dv)u?P6`;AulZB2V@Rd;rW;7V*Q;10p<$^et{$-dYw%EB|)Me&Ye zyC^lfP4&1t1h0^$iIg)6Wl1?B*smSGLG!ivC0q@U)V5kEUF;5l{Zsu80n2ZbE%|hb zAOm^u>7ad58Jr(-G&qbtegcZDUm_TkZ{j>3!VkOpOjqm-b_eF^*+^IH46ZgE!w7b4ZzzYsw(mjBwy$+3-8~3#o(J@%+>NFvR~eynmxj`kKA3Wj z9_l4~WI^-2-E>>6>}4421QK++e-dsaplN@Y<@T;x(@3X^VT5M${vgx-irRnN!EPk5 z3Q}WlV*_xI>3|t&3R|V=t*0SPFeA;`Ez@{60G$nGFscBxzRj%#hL|?m zcpH7$`qn}r!u}s|Zv!7yarKX9cM}K+aD#&4ds*!x zbt&$MI1X$b=Yljx+{O)XyUaJ;RJWjH2h$7NDMS6zs=`q0(yH<{Qr5dnTD;tYw0H@B zjngq9Sp-ua+GT!_4)wd$h#;%os`3V&U{#rdAL;G*FW5Pxx8vvOR0^s3f*}Ck-d^J! z%y#t!7a+5}$woD2&-L#LK?teW4R0v}2%xC6#l_kK0F3A=wm;X~(+h*!s@=PwveF;ZJCE!PL=`%%k?qPTEtFM5KW z%*sR0LuSx&J-n8d>v~$QuVXT_S6HskMcUf?yGEp?<$8oj)Au6?P}2Y7(*J*L*WDVi zHI2=_cPBsW(GPga_fP3V=Z`DY_y}qB8AGcN15^xcgs}+)XuCdO*{&PwT-_Q^MDE`J zkz#J{1sYFaz9`~%(&giXzT1f5Z`rO-q`tZQ&a_>h$agM&XWFh$k*dDS{d#Z0oh4{MNlBEF6E;)nd)Fv} zWIDP&341Hz&!(k_S8t{uDcj9>6KZpqUhVnX4Bv5XyNw-2g%MX{*H7%V@OOhIoN0&aP^#yVN+o~&7IYlF*&F{kPHGDc zT!gYrUitUkZ7{qJt;G#J35c=ytIilV-e)F`du(basjUh6x2VDW%8a#!3-bXZXAZ+6 z`l?X<>!CL1l);|rIZ%B0zejmt|CEbz(N@AY;j<&5j^%b4d^Z+(LF?$85x_3Ev$cj|AbKPY5e+O^Sz%;lqeQAXHRo9EK^J|D3~n&*;dZQ6gY8-#7;n*@}C zyY>dxm#7iZEZiN5<895r$e5T}DctyFrApNRe6!BQihm(1R;tcH*6~)}GhI2O#~h*Z z2Uz(Y(#dLZM&%zPf89t{z8gxs(39(tb-a~7USYNTVSIIj%D+RSQ}?86Zm0F_>uzPO z_sLo{tf-HV*5{cuYUduIw)v98Jla?iI6pPsWD?|}=f&T({Oi}h21cTkb~|`%0w{!g zba|B48>{i4h+nCh%hT8h3ETjxdh{h?8KH~FxIR5R5}7{z6{q-lu}S=_UB;62BH|ls z@gii9_9GD=D!1q>EXqvuvl^Yta5Ys4?Z-nd2y_F0Qsfdq>dYZO4)iuNP$Vx^Y(4-{ z_9jn+lxqCsM!;jHD8UD$S%OF38Rkban_ZOc3-IZ(d|+Lw^4eT+3QT$JFgypK+Km;#+Ct1P>T0Kfdo^@-Q}xm>5am5uu)gb6 zF#5lNqHU3G*8>1t7WYQG-E%Tii9$efMbBzguF4|-z1Qu9%-^*a$<>_@xT0R@=pOyD zyKf$h7wb{xvII^U)#Np?o}rHxGrGmlF98^mAJG8|Mx#QQ6g+xC;?}`nb@!1NqBsDf@CeqB#<5wATxO zD)0&J+$&HmYN(#@?Gt&CUOL{0cA(N%&{VY=Vw4ypu4IFgFGEhrEQz0Ss=%)TR+!|H zh7-hZ?9uR>2peNAeu-w{=fxWfKlcRU#|0Gd^GN)<5I>P6@q77nfuH>};CC3SC<^!E zrr%$OcA#Ih*9B*Qt#jV@wa;Op0vDnfoCGLZJhhvnn&Kew=zd7IEXxNUwO z10Z9?wO|!;8FA}kJmXqkoXSH6cm4W;A5GXo(sQDOCego}nF*bzzpcoNt7=8u`OKm# z(?#3rjJJVA=F2~sFN?f*NxOwNwu%kFEzt;_ikB$NmiXaF-w&}D6RnX>xQ+K}vzXse z=Y@h-n=FhBv-!*Glq$xZPvex|A7>5gj2oCI17j5jx{63*`8Yx%ptsky7Hu|blU02O zk=nVuAwX?g4g9}x|Y0MvcTp(WiRiPT0Z1=~W<)a#@bfg9# ztZAf^Uv`Z%8bI{z`)&T%0v14&(w**zit^%fSJc1D9U1OOS9>vDkO1yT5x$Tq6(0+# z0FE74FgG&Hk?LobRU^n11)QkJEC4i7iO6+FJPveKeoFPm9={P}@Rffv<&d5-Ws=)`VCxaju%S)h%nKTgHB`uejoW4nphFXPyahxaD3GL=g zW=K*NYM$(<0f^?FRNutdLZEarEY0&+O^EMs^)CUj3tAY3zMG6|-Nb8B$FCPtgqhC7 z9W0y5cj^9i#=XcBckgmW`>T-w z*do~Jigt2GDs0#(*x`=$c1LcuBQkI!ejTX`z>G-Q`A+2rlWqJW+DVO6*a^iYJ^=5m zD@5gaS{JqDBi5Bu;}s_U(L87Lay0^Ol`I_1V|-sg#o&;fT$#zfmz(7<1{&Q_$?>8b zpzyKs$ZSteHZ;up)|f#@h@q>w&0gTh#jtfpu=|^^dP|I9Yvhu;p7xQ;M~+;v>uP>r zjbXma7{h$b7{l^Wj$z{p+TP~91J0g^o4gO6qEuZ9G|dCS2$l{K8s{KKvZ`56l5sYS zb^O#PKdoj#>lkr)hw^&}<}{gI!{yAHJTOS|vrEN3S=Cu^nDUpeqP(Bh-3$PMZM06v z#^_I=JYxvm)?9IyT`Q}uz_VU4L9c*vJMT_l!YRZI0S^?IBg#N)Gshj&y~jDuSMyVZ znnh!3s952UUAmC*mreP3H7p?Fy6WHfU>dU^7=i7F+maLB7G%n7Yr4dG(|%{^f9?1C zhQ1htNe}yEUj5&%+WcWGm|n!}?GJycoh9z&LU_+SfBB!;Et9(-;Y4DpeE@FN^Xl^o z@e)5C{Gf242M<~Vm?vd%s@O~*Wb?^jE_vR%ihdBrU+{-?OZv(`SE^{VfoBc`CM)vy z+oK_R=DZ|8)j)|R4Sl$fTgo<%;%>rKw#xkNAR2XI9XEIAfkg6Ww4lTSi5Q+^LRE$W zx8A4UvDB--O}8DD67Ak)XsW;bpW?m?JU4q4-}}kuVUFOuJpU3*=)Qi9J_qZV{h`s9 z6TFGKHbNCj5uS&kZd>4TNP8meEB_j5Liy(b4qS?Sup-B&H@1Lm<8d6gHlBa2w|u`c zk74s!vYS69i0bY4caP&^K;(iVAEpZ#y~BxnKY|M=wF^NM5&}1c1>lE8av<_#e}aYG zB>agozo($XxTVSQY(#9_QcSy8ER09%-($1A<)8ZX7MH%)r+?*Be20Ac!Q@{y(fkrv zijCK0qTL??ATpMD`fW$vQlBF!V86tA!ikyiNf3^Z1&yn)$f97Xq>+}7#1q6>=K~S^o zMwHFvKs74pCA+A(777ZLJd=$i;m{IONcdwfu@)bA$=7cWHe*RppT0{lmLzUqS+Xmr z1dhU`^>=`W-Xt;I`q$tekQ8&Hi~RJJNAbOvyltb&KVwNS&`{71{6hyO5Nt7i$nGZv ze={IY>k5_eaiKD9oAqN1I;|MQN}>q=b-X4K$O?kTp6yR){r-WjnKdo9WoqnkBCd~H z%2s*x|4sUVlnUt_>idcgPbxd%FO7FURM_UFTvZOOohtxwNqK10o!rAk;w)| z3krymD_HVF{F!kc$IOC1VmdT=26BRAf}oYtfPvuf0^o%bnE9T#+`A0EN|9Hfoskx-8CywFz?&Eg zy)B>m9WALMzuxNaw~~Vn4qf4kAz;D(ac8R;4D@T9YR6gb!oW3Za4mycLLUfWFu(#& zk?lk%##mSm`Gj_6a5{$kDH!r$xk{XkW!~CGFo{hYCG4dL9v*idgkQ=u)q;(9!_wl^Bb|;SfNR6i3h16)Y>%6$~7ufP}OH~yPU{ZBas;)&U zOMO{%C)!V;)s2Rh3g~`e=2+@Wl1m76{P^`2iAWJ;-p^3vstT-l@5f3QL+Y7vtGMfY@%z66<&~;;F~0rr>G|%c6Zh}z$6X!|V-O!`1m~q{opYegIF~I7P9K;TxZwC8b+aJhd-Qmn^HQ5% zzq6E04sV6@F!-mvZirm00srryrxG;(xT{c+IMyPW&92>M(J64FKNgoX!Yyr6QLkHh zO&wq%Opl|}cspAWiJ*cADu|$h2xk*zyZ{%gY?I11-Brq$d4>%yEfC;9!pGF1<+J&0 zy$`JiDf0}jA;D@K0bpkIVN+Hg?riTv^pao^!A_zZZ^sw;+9@LUJ*!JJg?*VCD00`z z-1ffi!A@oYlh~=wvhxq3xNKr(KZ{Ku_A?`op{gHO*14`|>z2yy^{#|zzJZxd@Dd)c zYU4m;%h~Da{;t}Cp(z;ZQZUp&gX=!CoNOUx;Y{v4LFkce=-mHwM;A%*z5(*i20m8T zE8$<`$?SenIXGYydQJ^KFd$Eq&GN&WKlnLABwf(bcrZEl1Qn`yQML5N3M|=A(4Mg#C3(ktJkHS86|Zf;++K==gXJh0+EQp%=dKciBlh-wV3pC^MlL^VoK_*~uV;=PJRN^ouqgDcn z;W8>+FjH}S8n4V2mugNZGK5AIjr%I%3#xB&UnS0WLc5b2D~rT4jmp?qF)qf5Q}YvH zXogW(Ld(<#CG@mDXjMji&`9A}Y8p$a7^T~jR*Z}ks!5lU8wgf28?s*&8GmBq((5Z_ z{yaPz0TRQUK{H<--jA0n@W*;-3}a+TWz{0i>)2!tZ&Q_L6UGC`l>_>qaSvCSW(kG_ zScGTea7KYf7$Dpx2AH#y`Q=!Q8dotlb9R{l!dmQ$`?~RDDL~Yr6mXx=Y?LY<7=zLS z*=N`}0pjg$l$N^QNv51h-6USn^BXUusG&-D8Sco_&W3N%UpUtsRwJiU_;sW3GpkFT zzPw0{bXFl$teirN98|ExY+HfZwgR(l1!mjjXpXGBkC=+O0|is?1%ayh?IAhur0&l` zXR!F<9N?p()>pf^Bc0um>ui*K*F=0*U?=7N*3?kE6ECi@Ro3NSL9u-pZgrgYdO-x@ z728mBO(g#c@rpAYh3GM4AJ09vix%TcJhn?0&66eg{$JsEV>XUnJX-x=JP1Qb7EgVJ z3}X*0A6ZlC8-o7QprC~Ril>cE7o{F7Sg-Q* z`v4w8avj=Lu3IOa-6b#88MD%OB=EglzzP>OHCRLY3KT0|ddJ12$i_t;KTbpG?Tv}M z2Fx|+W30Z;HJ}YH4Rf~>0bEj{{J9C`Ij!XfdNT-o4QImS7cZivV(G|pwLq9v`(rf( z;d4Mdzed6C*F^>Zhz%ZXtT#4aZV7CJAAq-ft`lErS78^#tJm;_8k{ex%G^y}hM>A` zbXOYLPMiuvYm7@o{$tz)!LphK2Aa%Xhb}M(H-VR92&= zJjGor4$;Gr6_#+E3By&xcO=JAJga4LSOWSRn)6D!-%(*D}6Q8RuJe1_g13N{01&b^Tw74H2N(e zyBcny6kF23^p*JI()SC8kWSi3)uCM%rH2L)n zouJ~q*&j*)D@U&hYas7M2+eHB(=PVL;)3lUmU?*OJ-d3#7Y#x|rHZF6Lo?sc(|!qI z;6zrcr+CEDQ)oVZhp?Bffq5iPcp;+!ouSn5Ymfe|;(E(l-lT*!;I&e7a`{_Yv8Qdl zw|x8LeR%Zr`_$X=51(UK`CGBT+u(+Oq#Q`VnvB@^f{LM;f6EK>2+d5u)!4P2gVZ8! z04&n1IiZ(PJuD2|XDU3n3J=c2?18dvluW<_KO{eFu%a{cMWg{T*&H#BGJUYoKg{P& zQNNEuGvChBV)gC>a`KEjF*uZ(Qw)x^Y`r(x`W)FFyIk^03QxapE&X>l-cSx`7XU%Y zuh=&G)~~OW?6{KbXg13j1jxy4uW;*Wj|l+0X$sh~ZOO+0OmHe#G!tor8AtUw|sVC;3QA1vXqN@%^SO})Kk7u8}1FwE&y{$i~4h(ZXZ#Ks!Q``brHc$$dN=d zvu+FE#h#e2H~j41@Wiy<&f&UmQ2*h&HV7$V161%*)G?-X#`~f@n!0X1F=~d1_nx;8 z3(rKe;#dH9T%COECw2%4SeMYu&@X!*Ot&347>A%U#6UzC1e32^AVQiodiBoU&~?2F z(k)o`TdRhm>>8|t2s!&H9(})8-`DKyZPV_9`di+ZFRy=D;<}itus>fL!Oe%; z);)qEY`Ms}k2$|FF%>ztBIiiwtzxIf3MTvy!XF%TXr1(4%z7ZH>RT|0fP7%>wqzwRQDMP!eCICz z_lz$g`tWc|!WQQ;BjcO-f2slSHKz-{%{3(4uv2kxg z)%RBaa?+$pYReb32kr5$zjGkI^V@-e)$jRlD_LD~0h-wI1%>v^jkO0mAyB9>k{J#Ouk!1)Phpl%%}JczWhf7soYdbF&qrjcI9 z@kLI2mAo3626o)Qp}G1X)CR4K;NaosU`TQ_2sXC*dtC$_Rnyewdw3xPM*Je0{7@5jcy ze*%25{TO`FnEcJtq8Sypd{|)(R|9^Fy$w1Kk+8OAQmrVxR_hlvneTJw1 zcMNnTI`H@z=#zXh&}9Pu02t`zWrBgO&1Rs#FChaJo9zk>9Vkm}MPJ8;Hhn<``W%1x zFL~u+^cNWgOmwkVcVnOxus9dSWE5_IW5&MIqPhM?a@g~b20JV!BZK|^G{Imc-g>uy zn*Q)V$zoRkWx-;X|ITDF|9_mt?uH~Xws&N)G0cCGTzpQDE$pB#98A*(Q+o$_X39}0 zDJ4QG<_m$BJ^yjeHpQ1YosoInrn#duZrrk)@>Pce!x;&rZMB zLDfkuvE*EQk(hf2Bh#47X+4`?)p6~85E{DTIdkTny+_WxQk}mSPofu&qRu~>skZ$` z)%o?9LXJj!ff2F>z+eGiYcyk4Ear z73T){b0@!_id;n<9~BQjV^T4Rgjlb}#wSBV4LoI0^AZ7()U0PgLCp+ofDMeV=mS{X3Kk z@7$_fIH6X#@Wxk_3r9YuTLH{d zLJTNXoNeme%X{MoMolby|H@eiw-w|82YGncpFr%k2A96Mc|F#>I$k%s-wSF}aKZ*2 z1+^vGT`rtnK#ZaOGrFT>wKslKA-_!ZP?6HdFZWN}zvC@`?6l)9>y4eJ2FnKp ziq+t6?bj+*d-G|#ZOmeLI6n)ARG0qw>ggZfgJG6Dup0Z&u{aydFcYyk`!RBY&-t)Y zf+_vEWq88RNQ_>OKBoy!Y>ZOHfSGAJxGg$(EIPQWF_R=9$n`J}aGMq2FjnWFJ{+K( z=&m`eLk%@v?ToJ6heFQgx>7ZMBVM`JBkk0>si8#B6%pl9oy`QU2d$!^79u~Tn9xgi6r`1zGXFFcw zKMt`$_{9%50q{fXKYpC}iHHw9q1BD3pmP8t=o)e+>I>Vk(T?tC z9z=~F0oixh%+ZFCrWS9N}NGa074 zyKIwBA5rMjb@EWIz=bmq20#tw1_VLd;no|In;sT^LG7d{!<#)WeP?pPQsEKQ{>H=? z0K~m-fF%IYyC{?krKTsi$UHlkbRQj(1w^k^^+a+=E*J@+4n_`JE{w7^o%zPIIans^ zAE7xy$Q5q6>ko_V$qXSf0j-xK{34`&pb%NjUbnC(34#lA2wB4t76~eH(Zr-UMhQ>A z#{ZfzAQfgR@`lPtIM_^@U8u&cNFH8F<_Y}N6O#%+Xnnq9q3B$?Y6jMD)Q9fF^T z2;pHU0BAKngQx!r*pjE`AZ4-h_lp@|IZ6q?3V(z(qmG8<4HC<;4p_ojq9iIJjYv#O zB69}`Oc{K{xD`N;fN4=0Qy%s?AxwwB2^(%!&F*daf$r+?ws;|ch;9icrp zp%t<{=bvbMMl0cR09`ZsXzlrKiD=K!Sc}1HBx~6ta|g4j^OO!rS=YywXzb)HYBG7nhP=;k zUz$xj8Gr48Zq6Wd&d73pgnfINNOwS|BR6Y1hP-Uni%6YNv#wLZ%itVo(n@Mv`PwXM zd&OyOZ+0m*pTPlzblj0Tw-RY%mw_{kJH_|y8rt&^dQ!OFgH$zdq&c>R#u8bxr>O-7 zvJ^kwq$9!poM7)o^~VOw5?NrObR?Ju^|k6zLUU53;OVGJeh0yMoMmdNfJ50un9lSVZz7yj_1&t!wx)PG0cMuu_gI9>t=x<5_c;-Xdf8p}scD z2=FhQd&SK=33Nc54Rq^osiB=Vm%asubzbL6A+*P?hW56)^iA&KgGe2A6}P%0;uStx zOG3Ex*4nQeZoO4`Eo{fLz8b z)jYyUJhZD36`vE@c}T6@)7e%0o{D$HALv_=dpNYiUiOJMhDj6+E8eO`V`R7Bjuv-B zd|V$cLA3Sxh(V_jb0Z zPqPFf*0CR9e`0UN!t8NfR7&E(x`CJuF=5_7%U2M&(4MQ!+SKMmY5ZEJ;@*dpQ|lV4 z3#t)Oh7*rS(6mAOmSi1TH+o{G5H$(|hp0St3T+&MXN8$#B~cLuj7xvucUP*xt6=#^ z!eW6GOdqF;BXP__j3eeD6%&W!m|6+zhs>)5gUM7$IyDgn5aeNmG-O*q?xzKW!4hBr z3BP2ro9u{e2C{e%Ok?qn#T{mkgT)}-)Y`A|gF9xcvRsJka`22j)ObiOu0s*E_G>(} zpjbgge8^$Y6~?B$O~oIEb}DM|hpLWOdkes9cyNn{PRs_|g?7%a-Q!S;KL9E#$x_92 zF1rfMW;7Pb*1lv`#1&T|HTGWEt_>IZ6 zu#%Mo&QudgJ6?Z{5PkT#F<*tc6A|AD&JqAx-hi~u(~8y5TZQIm@yAw-M0Zpt@PZLW zz4f69cn+eUzEzdkb49+Yd@#2G1(*XT8Tr#Fe;VXZLb%F&3ZDmT1n`2BL^L9z9Y*HU zPN%lif_3ubi3jDig%l>uZ`c9~d`|;KE!#pn^J_o1r|f0h8xIi1w7MU9TwGW=R@FC?bU~sz%_X@0NROX zD&Mc)SJE7$h_Zn;(YYJ(s;fQK#Y)=Lh{&UR6y_3GhQ}?0eBh8wE`0DXxAQunc~Lu> z{{k*2jOJor4AEU`_h0SB|DKixZ%c#cT=!z%xyVKE8`wE<`-gj3Xy(!arRrnU;M3>Q z)7Xb&;PrFag}+A^LhZsFy%A3cr!#&bO`*DQ+Li((RC~~)KU2up`ZFc+r!Rh5YOz{s z3tRxtX05yD32)1OKOh&6H!BY~Uo6<){kb(r&cb=hmB& zJ%d7@%k*ZY*`^ueKe>Ir&PD71<0lI-Ghh(Gq;X+Pkef&7qjQ8ULzv-9BXelWa7JEb zo>2*KnIrD!;01HU(a-I~SeYoomhsOFTSi9|V++zKUXqC-1qc;Oxr#1{%%LFzXbMZl z?*K9r&1w=v3I-mjIdL>$$QTHi%|dO-vSoY%E0|@==!pG0^V8Vh6rDr;1uM^nB!uxH zEn;55Z zuRx6?V8+0-F3lLOqJ-oo8?s=HJN6bG=9?&V6IW)ijFYJ#@8Z95o{CG zsl-_MKBGn>j2dE%Y_1-M;bY4mtKFKBz^*%-*Xia**Ze?(8$KS*stk=Dn^x#%WJMeb zQmT4jl?C5is+_Q+JVRaF8>*qMm8Z;q2n#Pgu-p~#CtQ(nhzLG&nW}#Xr@^Ig%TlAS zQK{#CIc{`66}ne!OkZ#4piP+zcbmLuh#Ic9?Jb`^rZ3l&yYRS-yS(_NYl0fR)ER75 z1I6C>ukFMU;X{!Dz506K)aNs#v3|RV>2(nS%*SJOi|&UGki7DiP5>g()Y~2aqGp8? zzgbqI6{4c>nQ)Kr=u`T3EtQ|AprjwG+Eu4uK_86~ZJdcV>z|EGhJ|rO#0#L1TzhjT z?uLg?!z)>-RpahnphtAYn}7i9Pg1I`W`=0fzfTgWGnK0CSh*svN1y_oZZ;YXosNde zqF$tU`z9k>#{=7wLucY@x&5F^FRh~a#loWY`2ECJnP-4@tP8QEp!&z$LC+JOmR9(7r4X}HoYMrT zgMx+b4KhTWuvNf4C4x(`c86L^rYf*@4b-~8Ed-^oVyFh1d2q)7%lan9eLxS3v{`q0 zVR=^`Iun$HeW@%F+S7`QMt$*~&TlJ}Syg|ZfO3;6lvAqyJ{>9Eb+Lh@fe*IbQ(iau z15Z4Es;9Qm;Vs`c28O}1`vu)`xDCYq}iq=vf7zC>W#>N*^?b5=DgVHJ#!8s>^2ibDK;L4xi8IuK?c zG2T;Mt&0&jsNIOY8m@zQAPDifo%|RLB=Dg1_r#|31?dAlJ@u7+Ssv#|DGUq^78Oq$ zEONbg2IMZzZ%6-w2!u)?_Fo<#iq8dvca+{Y0* zq$yRGA=eWt3% zKtyj+<5Rv2wVtiaYd|j}0Q$cZTy;)Nlr>M%SF8aj{8Zz|r>yJg4xW1-gxf&`0=yV) z_UVr-!yDrP4|r`2Ixe)ot1|C3K!8U~eTbk)uk32Y(N)CZ3ALhZ z6t7Vc#?vI19uvsnm)Lofn&rU@(L{ZPK#5MV@%#6NTF;m^7+-jlbptot2wYsss;(Pu zm5H7keujkk1pyKeejg!VqZWT;y;C0wHMWNK!({e6@=}Eo?$ohxzFvwG;R$34%_0ip znba)CAXQC2MY*SeLR2GAs69g8T%lO7474BNDj-7iW#VdLrmPw$Fh-C6MC)SqMygBO z7Bk8BY=}uWEbuuJBpomj6{2QXZJxw1^~WBgiNF_&kwzop`8{yvyA(N7IZU{6fn->Y zenM4eX^;YkPS(2Ah3^DU*|4oC5_vTj7MdhB{T&i z7om%~I0yGvs{TS

4gV4JXk*n(-OBI|xQbcLxw7`YF;Hj$0mQV!vZNeCY?k6UB zO85(scH%yZEliQL1GyCZ?y@$>emTZwV2Xr%B3r1T+C$!cuaRfq_7iUQDA(0tYQR8z zRgtkH->H5A!XhRnG!L#@HQ}-&&D?ZmYMPldsXYtU9Pue4$;&TOqdl<|oOMuN=yg&q zZ`MGQZT;ns5vj=qb)8C6CGIGK=DdLzhkji!HHc5)S}w%MjJJ8n!-NUMl?4xr#nT-b z<5jzhV^zDn8ahsToQhEi25AojE=H~>lQm9P^DC$_F#bM9OK1&<-bQ0K99sT-uh5O# z2Xze#n_GQ8eP8mv8SOieV$?%zOb{Lf3gZ!s7bdSu^h!Fl;hhv7pJAavd|zt( z4nOcsUM56hTKQc7BMx20x3m@HA!Nh-U`2#XAi4g5U&@=7-T@7^&(f9W_u;}lBBe^)GEJU#}76v;}LR^38i+7z0iP+h% zT({MlV+WwbYEBnNVY(F|4jS$7sBuYnZxdc6 z{(K)imN^Q%v~>PKc&+AFM;RzR?#$u28WzqNC=F9{2FhyUc@${tf0+x7g)^W%mVPdDhqXB~9I?`lX$mt)m%}F>jf@CT9oq+$%J3i%8H@k;3BbBAQ9&JwSpu5T?$qg{4WMiD}%bCE!;)$a{Wtl8YS2O1*)OSzHr9KO1 zP(L55=qzXw#})KzIr6&u!AV?q2TnJaWvy6_Y42NWGh-n>%pJvl+HZ~G=}4W>j3uxM zpG<=kj`zidE>yNnSR|59Y_|y;$vmzlz@a!B>C#^;MelGKuD{Y(q&B$pwf#lvL(Cry zO3mf2_^?{8h^L+wYOTo}=?S?TaIMb~oBZ(Y!q8H+5)s34yLKy@CY!MYsS|8QHbv&9L5)69Q0!P~*@Nk) z6iSpda_ytQ4ZQ`%;|zKhKpEIF^N=Z&D6DiBy(sJDS8enr!28+tTsxLi4^)@~}*ntXR#Qqe!03zsQw5 zESw>EqW9-W9;rrthE`cxW{#dJ3;Z``gYQ*FZ$FMg58Z>RjKL`Rf9a!}jE;SD2_(Gi zqh?61AJ#{R3Ds9lK8dNFxpvbl`{vRkYf+?Bxmc|@@l%4-2@OWEXqnEYh(*nPNZ}H9 zr)iNk?!vPu;!GF09I3P=dsC@#DW2u{P_-+MGM28HAcW@tDLiRmHNOaKF)jVHePRds zGx&Zqs1afOHwu#-<<3o@t8D6dNS#nqCGWsHhC2(TS^Ugb)%}T9=JJR=u?9mDT46%; zNZeyX__Mdr8~TX8Sw-dR3~QChkS5KX&f}Y$EOD?p_dICYd$bAY;vi@V6mytKdgBM~ zBS$_6`t0#Jk+#B#lulok6DhX>;D_x;9ExvNv%$&c4_YyqZgA5E-U-5~K1?6HQb8dc z2@U@XPo$Smo-u(3>3-w@J-Svl3x7dKWFDn%4xfxHNZZHo5L?od?=w6|2{!FPN*JaG zDU+55Da%L?QbJFAkp7@gb3I5WVGx%U?lM;!j4=)+e|LJ8~*)WV6a z_Dg&5w`%C0HrTt}jxQ_XUBjSPo?85GSmbd`#2<_9M?VzrQ=?D%P+@Ra3vT+w_blbt z|F}%dAb+GUs9%pZ;pycd-p~^?{v#AKo<^1$5#LHrP=N{dRCsoyy?fic78?od1eg;^ z^;noahvUfjOEO4L(5U4JD&U58!4p)}hBLsW@e%L@{Rk;~g06=rs3=2!J(1w9-Ckgb zQw^xa@&pw%N>5P10n!tcC4?vF5~5G8SC9>NV(#hXzCUYDUA@ajwzxZ*=LfPCP*CbhUFv_~m! z;(aKM1))9XFuA?9v6G5Dq~a!2&0bTB5kn1IQL|N?JKFIX_|&G>?m~@?1u9q%ZzF;w z5HdU>D%NYk-A@X4PdYb)!FPedKMn1GyXUS0j!mxOk6e*W4MwOj7~Ek?AUpaOv1toG zPG`|R;xC*(cg!x{=!$GiBs(PCO4z1SI=|=xQ)Z&yZ4Vr8)3_WeNZAsj@%+I43C|RF1@y0}n@Nx;kz! z4&dB8Zkdb6$!5uyZsPo;dEiP0pS~v&pet`?s=5h%DQBDWk&?3w-dk2j91DJ#X`g;~ zVb*l8&JK1$44guo3%{qE~;$R<#3p^}wVDmBF0VntjCd$w_I%;FH#l*fAX*e=j=ULQbjr46~9%@J~pc5Q1=Z^aEOR znA2;Pt7Fr&c2~!a1l@_d=S+egpQ|H52v%QkLA>V(<| zC&vkZmOi%Gp%Z$wH|8i#jx8S7|_y(H9NH8y4%xT zlEq5LbZ@*W2f;_tJCe-5K;pKNHgk(y@^={SP=cra6YrpP97Y z1o*Nkk0EtJO@T|}$pV^xDLrsu~y)9#Gz zn;$vOjMoU;`}{OmPV+}`X3PXj*SakEE5L};n8Gy1)0jthWyB>)g(fu1m9YbYw3d9| zX-rcMKr>B8#&#&}^FaqU#-$^3W|b@_#@l{=)S0D&3*+@2AZ0o*_C5wA($AWxxJBEw z10;?6}QLASM<<_`!#)4&IN;GE6A+M)btvOEH@z^RGKh^R_U?JPJpISRg1o z-|j?Oc)q!i!1M+0fYsFL;MfxDf?|vKb$s{%oCsIuwQ#V&tAT#ZJ#cP+IxBz=9Bwt( zkm}8^Wylp+I{Tu@uxhh}@PzA)=lHd|LkCKxb`P}*AGoD}mWS(`YVZn+XxvRZaiy5Y z!_BiMVILPRaEGvn^62~ECmPz(inz<8g#+A%YTzUs;5IZM1r@#O@Ard5p3oa`fZIw3 zxSn25?M{cMdPOYcgmPcvM|wGu)_O7M|8a zUCRz|SHT-@FP4+3-XNG#wHit3H7DNm#0MEjhFY&ys(ywd(GjC~i(7ao7MY&dm{LTg zv?(F(#6>Gds*zeajF#X^o&04s?IK>1Q;r*q7Bg|NulyCVSKxFoU7xSWWiT5tCsH|* z1$v||#7BdSFM%8qKTZ9jxpH(#po>qh9Er7K3d@ z0%xHmg@IFvB5cS`V4IhG9s>d>us=!9FVQC=oPK!I)Su&X-uzgqjT2Q}=55(PCe}`e zk0Nf>*#SG`6pV){PW%pXMMjKH(Rx$9Ch3bt;xX0POwjuX z^e9v2G3qRDs(oi9R>2?%nxuqZLQ_B#Tt$rpP3rVNb4I6(Ha??0d&8!kFZx#r zbNC_y_84(mIJom`S7gjcQJ#=6N~R7n=@aM$3bL*JVF3j-MAK3vT5nGqBD#$j1PXaz z24s^_q?B-R$650m2;cgLRwB?v4YRWi;}^>^P6KrI3#>E#zxO z_*geve|{kwS#9_&yAG zBrOaDQ{5%#8@P>3nf$vh#tYZEOEE2^d?;eqF3N&A5$()3Tb+Cqz*40sg-c~VXE$`9 zo*jcOgCIB_%jSk=R%1Xui7$jje?HyiGbe$m?$8^DFvzC$M|c3l2!S{h-rKl|59UhT z06q?XaPktgf!njPsLo>(uTq1VVLe=ej|1zilJT_^!lJM#h=(CM5XFNYCRkJ;MBcBE z#=K>eKzYSfx6vrU8V09U5wifhbdc47<&f9Q$g)nLt*+)@SStdjhGqs~ZsXaSY+Vo6 zLnPlya64FYVV+K~01Y?G(SE5Y^SUyrDC0eiHT0t@_UnIUx`W{c7kCR8^_37|EDNWC zKN6PEB?CxdPr%wPdt8FsmI3Zp*><3^O~$2YA{!^#c*iosOB%=~PlV4*d#e#*tFNKp zZ3a(R%rFnQhUI%PtgJVb?e}mQ7Iy#?$6<}d;FF8xQqP}7RH*4!FZm+}-${dNc#C~EH|7Xy} zB8qUoRE3jK(&@?}u~ffV(;C)83Vk;^ht}jtm)^+12y}@jPCgFWy7k7$4HAo<@8V^(r zUS$GyOJUf?T$LQP6V9c2y*QPz1n<E??b%d8S>zj!ap}@zP8IdC6Ej(Moz1qo# z_#H{yKg0mK{)w0pe%lvUab;w>qRtD@A~+d&&SSHb8t3`AUkf&RXlbuQLC(WbP?8B6 zlg{R6lgOu^gf$lEKc4i*YA7!`bcaQgKwQ$}KzFS&bU@M0$I=Gp#bRCiVAn?Pktz)x z=mAS2r!UfFB6bG!q7-hN69p#eJ+e_X^CLY{dx0^c@es$Lz8RI~C+izUt*N)gfU%k^ zwtdHW^nb>$$3c_@Tx5D;^JvXStlTD?NeVU|h68{rqK@|HG9UUw)q`mF>s0B~)jV(z zTqlkh_+pRK`tMR)n^Q%?Z9shCEq_C)`VR6}sp;*CSGEZMr^e8sQtcBweu~G@%Dn#q z*Heq!aO2a^BA?|lH@M5*kkU>KwPJ5<6JEQb-Z6sv!|$M$=6Pb{PwNson6Jz$Lr%~; z((a0?qmAEiEQJn~YxfvuA&DThO+oJ{X!^JyrX%P)RMif8G5{$xH`+qGJ_{Wh3+RW2 zDdE4PjcAWmfk_GDBw5eJN_Zg(uxbRIDbdaV(Y`i`hEEXMUy#ArB|*2TxPBE4#{=j*N~iy-Gl{h!|nVc}Ersl3jxjr1`+Eodb$%oto7#g<8+(O(U^Y zjxZwXXh@xR@kz=d^R&~Mr{N%#IuhA=>TITyMGPBW2c$}bs;3-@Z3#~!$)h9^cE5TP*i&AHKLJySMrgS&K zigu?8QOqWCniG)X>oHdmt7dg1f)R@AIPO3Vf*NRT;88Z-9l?NJkA@W@x{M=m21d%1 zQy^*1P($kxOZ8BfX^2jTEAl>`{JF^+KF8x50R~x93WDVqX%~PZb{y5gda)(lI*s1k}JX~0Y- z%T=)4R#J!~a}b{7oK%A>aZ{6kb|y>FUy2P)z3+)VOOp^7+oOwA_>);z`(pD1!^dy5 z`5g1uFdqzED27`BrxXXl#eo9QL@T*A-V=5gAzh5uptK|U!n{`AaNx;0&7Gu zH8)|o)6C^<9P&?X9ySu|xd4*h(5$|BfpgX9u#wA3(T%aGPyxPW|D5fOUGGF6dK@2k z(2ZYUV#z#T?kWFtS~uvbVx$+5p=A&iq=r1mC5BLNZPpapw1}=F>jXEDqaC-EL25)>=sXOvBjFdYb#RTP!;Lo_I zD}q=xIs~GBIRl8-yQ{^-^!tw)5(sN{c2s7tbkDb>1qW2-3OY4%ds z*sh4&Gi;>s0(-1}m=l##ZzN^0VpppCXiqiCZP6LT-N2cl)`Sc|O4WP#TB$iLXJ&{` z`83pud4ZvKcuANuJ|&4{ej49X zNGz=cW51-if>N9UGj(QFLhH?E?Icfqg^=JY?1b?Q-XceGWC9OqK%EFEFe+Lx3Kq0~ zIHQwC3YUp(XnEI?;I39!J4%9^?U9O6&dB7EfR!4DR+XX$oG6m=;7@RK(8}Wb%P4|R zwJK1;Pop}#CrwkQc|yN|kS!Kp5wlch(g=^u>+RZ^Sj&|)Bh0s?wb@(A0no-%-J2^Q za|=--`3+=+8oYLNsTi6V$}_kKYP+`7m_qqHF@bT?H)l*jbEo)Q%8^DCln_nl#@+Z6 ztr)Wm1iT5Ntt+JNramoJYk*dyVvNN!H=_WS7pB1TwhKJJCGc*t`K7?~L+Rr15d!Z4 z3Oo!7tz>w7U>C10Mw{^&afaa-0uTK{VQ2J31#I7gzsAEX*~n4(&hyA4pEU2N@^^^TTPvES73Y>*Y2Vx zUcR5_%HlP-*!-CA6`$#yGs`KO)2+SL^5ejI zN=IOqXVkzHgI*W~R{SH9R^`SLJWT3%e@FX{kq4svs6Lm+6}VHyS`^oA_;k#`xDG=< zj5Q&48sOma-65r_?JU4YaIrY-U%0k{$R@Q{=z%F?c;+FeKD-dD)*r8M+b}#ZA5A|k zYQ*S(&2=$yaL#urewy74(CPky!tyE$;d?p$edV=JGJP)z5UM(2FyeqMzczg@nY4T_ zSw{L^5^mb}@&|pI>w7uAJDZ&wn#_vciFol=?9M^g!$yHiF1TTn5k&Yj?CUNDX*^sN z{ozc}N7Dz?IR}W_CO|y&*&N!QL;yveRByDq5rnX;887@eGqOd6v!=S$fWIa}D8kvO z5!Y0_r|NIu{S!Qd$-s-DUFV<}f_3if>@NNY;TPS-ANyht??=UO_cR0PV;RbdToLhE zeRw&D1?t1X^6D}a#1B0)5r@ACPcH}YMydKQB-?wHPMPh!>X8vTVLxSOzz37m7k7;i zGHH>0(TMI7&D;S8%i}=8uqXT zXK-(8^kLzsnJ_vBcOEKga77yUNfFfj9gg767FQAc9}@|L$qY6&;lUYc!W+e1w9y@D zKsZYXza8f=h&RJwCU!dTLM_^cg2A1i;nnP@U?&$MWCDxG8_tHWfSVnTlElt|uL|7u zZRk>}SaO5V<}CWaUG!0(AP_wO4^*;*yXa%EC!6n%Y<5Op6`ETR?w}1R#AkzpCd%62 zq^Tx$IpC=2iatzdPSnuiii-Pb+(qx90kaXKD}uil9c z^XXG)aL>}}F*dBLLhhn?)h6bMjWG}#32?m-8$V@5B5e1+uw7X1oM7XqJW|+hv%>oe zt63zcR_RhxsNG{;SrRyArQOq&z9%bne1D}Zl2fTK_S{J1RGdBZ$hI=e7Bm%=^OL;fPbQs>}&@^ERNuOs3W zJQCas;WX@CiXo1nwHd=BxT_GleaZppP_$mDia=~2w$(y(03-}ji;>8yb1%)S!u}Jb z3GAx4wh7@(%Gdq=L_Z#9^(JIfa;l(sU@W^I29^>?s3Z60z5T?=rhaBm zA|`qQ&4c}RG5jx6 zjizSRSCg)9F6%o41dm-GOXSq2%)1x$!C0|jG3I@5J*op6^is`4SL~FidR{7Dt;44v z7osY01oK}oMpR3jkrie5_35GMXk&ATk|kdTHfkqkDM(Be90Id+&KF3BM?q_qvN@P(F zeh~knM9{if>*npZ&*Nx9gqjBA(2!Vyw}bdrVw37@CW0>zm&0Oa^Fh#x*aqjC46#Bm zMDuLy`L7V5^%Z>q!%#&vpYSp^vxu_b668@TeTK`}F4_*ahV|T4ZvwTrWy&Btojjqd z^8z>EW}HH;n`E(0IF_(H^<)0^##T!*wP_W>*$A*O1c&=q3k2F`_s3hog#c5Kd}>WA z?|IFg#UVTSI(W5BdrFP|O^AJGb3H8N(6|n(5t-wS&FE8-+_=<+F30@9?xZS_84NUq zUND1!in#9jO^B&|Q&voEsORKmzy9k&gssTM1k4f(NrHt)Fi%@(JAWkYgD;3BHzM8^IBh_dMjP zyhk>5lKG3Pz$fXBl%vjphT(d_`e1r^M8xojL^wJ;`r_%p#|Qzebzm|}`+{i5$Ng(I zXcLPw#uy_FRn5ZaCN3t{CQ8*r=}v(X-eb_7R4;!8N}YgGCxKEh8;|A0gYnd3foiz% zB$AJy_jCGAtf^OW<&q4;Ku+`OL;EGvgd^DIWBVkVJ2s7;tko0zZxmrv?`e(RfgA%p|_9`ppRC&kRYFJvr`^KYxl-z%5 zhZd|BbIcI|e*WVQB&lKP41h0n1c-QzGaz|Gg(&HDz2Qx-I$rMuppP{LXI@a)z6N56oYB_Kkiy<+aV5QUR{f|W$q2zD zS#nzc4jll6B#CB0K-$p^s5mP)Q{wpbR$uJ(-bniTwff2rPP^2nACweyMTDA}eDd7g z*!L1?!3W;*`f8Mi(Y4OtiDaL?->W0O)LN>pxIEna4tIht78wj7LIbo{$EEeHFvyu5 zQ~|hNz1Cm;j&{B;CcdUAN!C+u<*7^eYu# z_#FrQh@V;jO@8*{9pGhyf)*iKA6r3twJ-Jvxxw!^2sJ>E!m&lN27)rhN=c^r(ErEY zyT?aWUG3w!5D3>3R5U2oXro5sC4#nSw9Ua8oC7n6C>4E6rHxv(rL{2QrGgC34Cdr8 zh_BGn7AkGkrmbzUf(8|sppuAH11iPh1<>k@^QwRq0x0=C&)Vlq<`y8-&-;G=`0>%q zIcM*)&)#dVz4lsbuS=XmmeD@V%3ky74m=5Ubo%=ezY_J(*2h0NB@G!K7>RmaE*>dl zI1Q~F92r=ndt_i~Ix_t6q+DcR9S0e1IVT4hx=_n$$b3ULH^;BbZA!KBw)xNaDY@~$(PzxZ)q0i3u8zXmUuu043(^SDhg z0E!;`DU%gU{|L@PcJ9R{pn&5TcPDZ$0#O&rR`k!Pl~faB6A@)kiP{`1&Q2)ORC4Grvrrp;bw#%aU2K_HPC{51I>%U zG^xs$2J#jOc7okAO;<@us)legC_zt$02jml976BITZES&`EMpJV-Zd!MuMxA@qZcl zAxV#9%5IJ4PT6#fQjPac1a<7`c;SaQ*lzR?sTB&*gNy``CD_2&vqU>mZFg-{wzan? zEbc&+ZhaBExEDIdWo=kaPKEL54Z||n)`U!D!}NqZ_)f?gSq-Oan;&6&qHX>Gu38V0 zB(kfoKg!qS{V_g;{qVsvEZBmr*MySBc1+AKLgct6mXzmi(rm%mq@O?SAe(fKd*YMF z<+hgYpm_U1TO&}NeV^Rq&3Rg59j9++9IQ2`p>#LJ^4tcctu#l)*H6tEFSk%+Sh(k&rIPCy2Y$$p-%~4uJdUbo2Drbbt8!6nd6Q z-FV^1FFF&SZv&9{)Du+_{o{Y3L?3wiOOxicaCC=5*}j9TBgw19?Je;$%;!Pv3EE&! z01s4HiN}V=M(lnXv;ZRB#5VZt`K%jDM{ERcKsM0AU*L$;XFXau9yKIEMnkJgnb8b~ zQRKot0Vw1zxrPO6MS9VKWbl`7+29P>Dz?8=q#Ji29=0p!ZC8%W-8 z@GsB7u-%Q(7de1bvW#(ZT)b_KyFm)jiTM0I%4Y6^p{dV0*)ksIBW?AH=g@{LI&LS> ze4utO6`0~K*A9J?VXat(`w=lCw5kag$Vmd53&ez5P)Ti{uXaHtWhoU^dvID*ZB?%C z4p)k1%wKABhASH=JV~T&qc+0kW;~Jj4w_>a-VdNfeQ&MmYYjkTSj*)ThPk|w8b!Xp z8NYh)p-RyvCMwBdA#F=4xZ#F@m}E)z@er;&2-h2h9u{G{;&%6cmZUe0)7$CsuB#yxDkfj@CTk(-csUxu8$+z{Fi zf8)uRFmzB0Uk$x=Xuqz7hp<$78~x5+7Il-q!(%?1Jesp1CWczL1Hgxf8x(=9n@2EjNmA`}OMd-f#83Ds1 zDd=^k!F~DsI>xd#YFi|K#|3-=r7)vi@VwN7g;i~fxGxhRAZY^FvYB0gz0MB5bAikb z4luhCmT0ZGpRn^<=hD<*!;K_S%$)^6gzaqT4JfR$^M3riAml))535^_w3 zB}S-YlopN+=9(L?5^`+vBO%9LB;=Tgr}zZ$3g#0Jb8YWQPsOqG5UDtRqEd0tz?3Gb zb-!~`ap>lXr_dOVcUCmx7x^rDNiq&dC`iWfB$t~h3o`K@iVbV7EWN~YL{G`gk<-BH zAair5_kWT0{&(?;lbhpdv^8S4(JCzySp0r^KazJksX6AOG&$N%x$!l8GnI0~FjtUL zAoIpB$zzeqSK&67a4b%n$+J~kw-3kLh-`f$%K0rPwTImfAM>@;7+2$lW=~Aeu@lQG zm7rsy0U{S;3v_Ti7GqTBeQ%;tMjY92ZvjqQZcy$?VaIv zs_%}pjoX9syMuen||CN*#v zY^`8F?Iw|&gVhm9y$nCF@+z0RNQL}J;*R*RzM^#mmm`JMJSH;gH-K8ntCmXdp}E)N z@Lt}tq_O1jNCo4AoxeA$mw4>4BxA>zXs^E3Dt4!?aRmY5fv-?#7?6S4dXT>ZSo4)q z3>dK%n7`x28E?DHB_mPM2t897B+>`^_{=DQh=UkrAn_G%#(}-BaIxAB71c-lc^E#9 z+3YnZw8dBbNf?GYj?hjpVlDCDj)ybl{F=QtdW+xonTypniO-D$oMDXeFYIHi(T-c3 zigIjqa=FV_4X>S@{(e4lu9PN$s&>6pZwDbjh4f#oJDis_75ImFtW{MUeXE-zDTx0x ztgJ20#2=uxDf4nRI(4VccQxM4%t8w!@6!8dM5_ST^d*LM47`Cn79Jkug3tu2ny;+ z++%Qw&d%sRvnl9@a{^8{73+|-D^ELG?aIq!JZbb{1|BH-FbY@AH{%;h3g)Q0qYtc= zO&`*@mgmcCuI0~YQeq}whk3*y@$yP_Os(Bl0qugrJw38gaZe+pZ-?TZ-bVx&!&+=p zxGnzcsjl#!XI@G(G8U*#hUPdG-tU+69$7PXY_)$c^fd?fudmfmTVM z;;yX7T;vziep>Jhi8}c&u{RLM8>THHM@dw;V1uIoyHY-#lX5c4%EQ^%t<-5Sx z9*+n9xp3wMN+_wIsmOneVa+V9#BsVX_VHP>#k1U-_CaJ)!>80o{|8)Yk3R}-0?Qh6 z+qhWxWiq*h>6-{)N(5TOd2dibN}VNU6o)GdP{pXmGP8e6 zNdwGqWe0wfAm$5H4ZKcHo;9ULH8^*?f&3HP##q@08v~@;5dsjO9n3TOQ!!>W`j5d@ z_jvTqsOg?^EjxAxzDmW757J4vl4t4;OECx~JPTh6`oO`8L}3=eW!S#K^>NPijkxLO z+%y!W=#)QmYd-+MtEEeREhCjh_e+f+0CpAo(l|>;x7cq}JwYpr>=zdwEIDvdqk3u`NE}n4FdA1RmHH{{$p3d*s@a zVMUVQYw-h0R!i^)YZ&Qq?%sj5X*0_?omW*RAWHQis+@}|&dN;O1OOuH$Ww^pO=d@b z8eDUFUL0(S!nGuhQ+vUDZ*}wmw#&WM~TPn3eNreAg6YkoczE$s#h-X zEh0b2?Z+o1%{pc)^g&UK!^)e+zX>{r<`8^5SSK?v$FBD#{g zr|@%XHEr=<36W&6tR{GGA~w!`Y`Cj2Puy_dDt&k=cs0e7c+C@%r@8GL7jA|+H*n57 zA=%%#b2XeW77UG1Y_lM_tjKosjIFYlzUns|R)o3Ps$WF5vvgL3oQ%{1xf$S)o1+k# z1bkC`{X*sv>e{Vt;ZpK{%~3zGsJs0tSAmvV7HM0S%ajc7!;5m}SEg1adFS-*z^0rv zy+&)=JY0g6=1f3Q;FJ_+0Viz$Aw|ra1tZvJ=aJC$3qb3{Ag!+$uQHW_uYL=6_{mLR zMaYAB%~2g-6|2B1mK)K#3ghR%D+~Ii40ci2T(XOcNXr%NcDP1Q?Sb0|`J%%v^uoDw z5bmZ`;qE-6cK`H~z>6dNlJLkX+Z>cwY&hQc$E5|y6T2P76^9Z1&e|L!u??olH>eW+n`TY;Kqf z$p(At*CtLE)+6l;`%xfY$lPRp!KE(8FW2Gf$TyiZq11mX8}wh4ku0hE9qUrgLMHFF zlFzURQVSw|pE$h}W^S4FSF?T^se5l=&RPI>+O-wXB`)z9n1hU`79J#^#mS_F+dz8N z{`kk#iP^!Hbyn9hzVHGz2(F(<3>S%`Z=*+NXw|vJt58-rf9q(@59_-1focO0Fhf|Fp9qor!SJO z2hi$>jY240$i)EN8kG5P0w~87B2Yl{i+n{oQqa;tO|)x&0w5$t;BR@MQWp*Ed{Mk< zB3oSAIL2{_Q6ros*1h<-4F43BdjkeDNL;krzu0BTXJNO_Zzdkck!l76B$bJH;4qa* zkN5A+XA?gpp#m+7p~IqQ`U?-rg--Z!b>z5-oJBF_EXp_9xAt?iTKHL_5oAkm$;WIKS@>jJ|8&;Q^ksA|&Kt~qqfYPAlHbJi2K6j4;=QbS`xSttMteQ3dOTW!*2!k$NoBGz zOka)u_3z(|{~;r=8@2a_*!c(6k^e9#<-Z%}8*5h<-*7Xv5s?Y5A}W z9?)p1wGS8&SnjLjr24wc$_fxEQVWx%0cQ+fCIs17~-;?4q4ifCUPyXZwKdS z-LMQbps1Y;o#>k$a*Ut~5v=e!W-%OSH-|M+UR9}FYlajos=l)Pv+S5Z1rtizP6*#YP;zqc6`p?Ln zoEvrvmTMT&BFoogm{*tT4VRZ?Aqv|%0c|~1gHC}=yVhn^xN&|y{NafnRO=qB9T@HB zPkr>t;iNv&k(k0fEn|Kfzg}%LE6pq8x>E!UqFh5dUOqmkmY% zaHusxU;8R{M{F<{s)$4JMi)}9@R?)UeCCAq-4T8QXPGNdwmVXco1l{bsTXe2o$%Qp z*ahW;A16B(y`~hL052UUeAZD;_&a!2jEr(aVZL!huVy>p{}c$4D@JxX;qP;t@E<=G zyN)`AXq55k@J5D{OC{nnDKC4(h;sL%dp-PLzJLo(2OtJ-VaG*YdtxCWVY|w=Nk`;MZlrOP)`A{9a$>={{8Xyu(ZW8&CzQXD%xH#fN@6^x^6%ILNuW3U&bM zSqKN%>Z+x`TmdCF4goJgb(>0Ybt`luE5CWkyo4_G@H0ogEcmV~ z$9danels45w>;k!Z~1NTmd6bW;3B_Wqh~rC%60moZ$Amn@lp!MdibovVZC2F9>ZC_ z3|({MrXi-c$AOA)M92H;0q^?lU=h9fgYWM}d2waXT@-UrqTdb#2J3pU7}!9&f;4w{ zv<-|OgNJyT?(pnxoXL%V+I(#L%iE`wJ{mJHiRPO2HMwix$LMjz;?K zo-GOdR5A;>9r%$SBw&RKIaC-kpzNjLuB>UJGqFH(mZR?G7BM{Z9j=+E; z>1;W~i)r`K;RYXN%Sbj=#h<;ZYD5qrxWTcFrRvO2@e4C;{KmtI<0V@ z$wPXE`w?#UdhqfIh-(zwjMsxpX@GT?5o#@!Bwkcc?u-BadSNQVlkurMtM80d4|sIa zlO8CZgZo4L-H7r~{4tc>_y(VW*@=>q_|MW{T}R-2Sx$-{C3D2nl#}9P`##TBALnu0 zX+ajc_#?T^bU7*Bd^qi_B$3gZPXf-wC*^4krP$)|S2+|8IjlBGM(j3wb=M~As5V<5 z*<}%(-0`M6J}&z(2Y4dZukLbuoSNIFQM-$tgR@JqNR8sP;yHL8kBK%~D{Js9-gn!( z5MkljH7$jkv$^<#zad=!C#Iq#nX}1|VHJ`-U_+3#k0f&HPLY7exZqL7wT`uoz#3ec z!($0%5bRpk^RA`x@gJ1R9{nGDToJJURhPo+6FIP4eLCjc)|135AuVQ24rpQ=gI%Ls z3L!n3q=j%PM7Fy7%W-K`Z}8M^y8Uvm`LY5ngaz_(@DS|44-9lVs|vyWY>mIM#76?r)#vU|iaY84I$WxEy~}b*BBBo%;d=YmfOhqDRLioloWwh3#Z` zK6KNLlOaWqEGNS&I^yMf4q(P5E*uo!BOr~GWAc@gp}f%;tmU2^Y#_S|tL)&#ylrUU z)5L3X_H0A-7cs(!u8%G>p|;u6ak9{pP0sc;oQ8HCU&B28HV`xtegF3ERNrwzMij>o zzMeA#`c~+TK?zl)hEaxLP|<{8@M)qr|1fwsqlUo*dOaNm{0)CY<*&#;SuTg{D~=R} zM9k?UE{D9fN8z{}c0cm(;WWvfwXTt0=Y@jao;+{^6uUTd<#H$iC9s`th~u1KKN7lz zwiUK)En;fcn4BE+M+U7`{9+N}g16{Fi}PLTR*@(Y|A4~PA>C>IZ2yIGa|I!0((5UN z;CmQAyN>T+_rsn3?>xi3#_msk$3r%DB#wvgK|7phpwqB_sew+!c|=bK3g5$f(5~Zq z*!@5oKg~1HZZVqHs`kP}{HowZ3ZwZnadiG+{0ZkbY8dli^3l^_!2j?usFNN4!|sRi z?5;e+m|~+Rpet`SO4uC8*O2rf|E{Toq~9ANvW{kOj3K{!>!01fRe3JlbPF@#8# zmy&(#iQ1mO$v^~uuPC1$Sb?P+r@MK*QBKRLZiBnCx-ITBu6f&0)Ua|t-T-~}L zPM0f_w~_KEvxS_qLb z#|82HJgud>ApZNKgS9p_t8eeWo!d9oar*Yi!CG?$neKwPFtC+Jym!=1{kCi z-r{t)B&F~Uq3lSt)?b3cyN6DP&vky@nHYdmWXI`H_VsVvmU24e{g)!3YvHFr*cC;y zaOD_&rO~vUeAU@Ob8T{#aAD5ugShPTxYTLf6viGizu;-yaCjQxzuhWfj!J~-gGDer z6XEvcMRq<~CaB2ob?(Od$XFpX^d$20ntLL3tjmEN!kQVlbKxf-H3;34wE z-2r~Z)!+^y@I9(do)0I+1}4zNW5_tS;>T^ihJ#ZWEg)--I_$dxuf~VG`8iA?RPLIU z{h@phG>IcyBd#UgSi7lT&5e`Rgh{11Q1_y-1mfu&2El2i+aItH|3!&|B4cmy!mWIk~ zNtarc*|G^&bPZGaDnl)B4O>swumKZ1E!&XUa+74X9LN_up%%D?**P#fA>nTl*Dwwa zCsMZp(c+(trfZmcQQ|Mq-DAYCaqK9({l^>@o&Px+SEGsm8{Af;wlwO zKG}D~3vhMuYOchgMvH1%m?pV|PvjC@=uZ?TKp6n)(eL5IWnC#QVblHul#+Ie%Rd1s zPKryEd=;;V&C0QO-gxB|Nc5*g7{&}KmMRQd{fCAC#7yPb@B%zNC9frNGx^U&7yP3T z+AzqA;Ye&rL<*b)2if2@X0{A^S|xcYCkh$+SnKHI8GQAkL;}xvRg?UlHmAnYO z=8)K1c!V@L87_w*T4dlvq)JgaE`vz)Agchqv~yg(&5=(VEja?~fY#HkH~kRac%$-CnHcvL-f-*zE(}<4_hz3UA)|7$%7Y zen<~4YjoYu1ef2wUlLs2UkDY-^>~itxcJL-O-ruDMOuQ(Nw}2+m%P9+91wgT5?tO6 zibEsb*Mm5y5}3ffr9U15E?R^qGfXH&uP#YgIUEn{)S!~!GRSnKL-7#DdpO3^cop1+ z1eaq~g3BT{aIgfI99~+2%S-J9mk~Z!2`(|+C!qCG=#n6lF5`%(xQaE3JeJ9G0*I>XTnOkLq3^EXJRHz0Y09ILqQt*$x3vv5fP4)r3t~kD z!G~#xx?^?0)}n%Skwv)1T(4wDid>f5Yp$L8?5&;J4%ivVVFv=ZyAWa>RgGFvN=?7i z)vzLnd!LC64Z}T1NQ#?ypJPgZCNcleZ|UXg zttuIW8bN#pc3)^TkognYG}VBE7oMSo3kfiUWWeW~Tu04>Q1U3}DZDF9y$ZeX5>c=@ zCNIN06!}ljn6e)LqmV>&;-dHjKQf3SF)lNRO7h!G^n4sN4UGuW*||d{Q{1nCD~a_O z6SREXr;+9i-U$t&UX&f%$>5esWBqoZ)9!<=yoMjDBc1QLeX2iJs;QGBnc1FP?) z*4e1OS2V9kW{C_F9Vm~N_{8@nBZ=o-sH)ha%W$OxTW}vYN!yad^GROYLBP8*u4m`8 zyzoZxS;=Voq*U8UG;#QCJKjtXW4b;lSvfED=8k}NMrs6+o_!@x8q&wvmRL{TjjL|b zklFy5R+`a2l?iqsv;&G`ivDCT(-vMVxd01qKNF@={xTrsGRXvsY|=RAeJMalDcCs(KAoxtCnI?+|+Riv8DueiUV_!UY03Rd7wU=sGa#7EGyjM$j? z41LMOs>G9E7GU_=fTS`Anj))AEeB#~@Vi%h68!G?PZC!^IR%U)HcI+ba6gKhv;;RL ziR#U$leQ*gF}Qz%45~2c?mi#s(Hlgh>zY-^Eog6iGqS*B02D^$PEymXe55b6XSHHw zzSJ$1X)`KmisLn+6tveZg9d zUshAdwaxV$?o<%N2>{vc%wgDh$}vAXQOjW`-oka_8kwQ|6aYLxRiYT$GbBs^Q>6HK zoc`v^32ILkdWEGM19fmZ(v=qUX3YHIufUZ4oM}P7@pjhC*sTlcbU1^IF+2Im4D)jw zxr~T8;XY`oOiJZO^mrZtduump_t1U|yj0LXSr7WI?4>tOoWL0Pm(zKI6NR`c-r9EU zp5Njc{(Qq>T8;$aD+_QefG0Rw`rXcHTcj_Nsxjq_uDROui~0rn1lJ>p*Te}FwHPBL zcDEdI4~CaNjbG949r|P@$8d!77*VV68h))@GCb$a?w3F%z1b;=AXR=$!@vx{>;=4+3%Lp5dzVW-~ zkTVpI@)4%n-q5nCf03@{(m?pE`pDE;+Oou$^WWFe$I)u#yKf*r@{I5rHbFD zQsNGe_W>(&EHmPc$KWt}Cd!@he(LE(c!~CT-~I@<;adK9qu`|IN%7(6;L1>Zh+ZvE13f4zD>iuA85M)!vE&_2l46W}wp>T$K|HwF&yHN2r_fntQzF z`|-ixrMbFR0KW}Oc1fWgPccl09$c+N18sF*&DE|)^|vJ#?rbaxdSN#J5p=bRiu^;} zjjqZo_0Sgxi4m366N63FbY2C$mE((a6i-NW;6AjkRtwKY`^np&lZm4nFjC(Er~9o) za0Xofvf$=z_3NotnKd^pH{uZFM)V``2|iP*K65`RaNJ#Awnv}19VM>X^;%>dfFP9- z4(t5NPxRgBeJ_7mQ(<7h0GukZvt#)|UO7!cXDlE}oQD$B`~ZgQdZ!B+K;MGO=S(=@ zhh|`hoc@Z>nkRdo$?S-}+7|5|nvlSksvLf|*#C^Doc+(I{qCRB{;6M7=KtjYBtN>o z^2!71<1e#+4scH;T>Yie$x>t_1T4oR$ss~Ip?8o<_Y#^V_G6GKdF&rzw4xr03YOU; zf~zQ)iwu~1T2*$>?%@t&5E6UL=EJ;dys8pfsn+kS7~+mD5;>Zxr#>U6TCxppBH<4Q~Xu)x{FM^~S5O3~oQrZ-ZgZs?!^;z7o-l`t5!-_--(k?2{}Sz9sf9sMFQs zX=D8=%Ey!DGUYm2avE0z*M8{fRMFB6QwEWop9OD+f7S`_RDR#jWd!;v4#9``JcMV8 z+jU%x84H742^2gZGTm?R-8yD_WO^NhGecfR&=`BcLTTn7Z)bn3WA?{dW`F#e4$G(W znEvrBrhh!$s8vySrk|L~|2T*~Ifw+p39u7D!p}%0fP}Tb7QU4|Q~5dHMrT)^fWB(R^^R?F-*6O$aS$uG&u zlvSBRk9F?$0<6a14I6e?fp)bh9hBkXd`7Sd!MHdvW}rRQ$8*#wZI9nnpjIiy*6oO< zK|Tii_Gh)Ak^dLq^x4(xhVS+{sN@D)kEEkmtXolos5gQsNY5eGok6Ut6j4qXiPR7v z&w&r7xNk1Uu0O4-y5vwMT4P!L0^zl7#kkg zF(;w&74jaI7(3yrq&`4MHxvTR+~A(#=H{gL=C+5%g4pyd-`3gNl$QHml9&GLO&_*4 zm7_PcwT<`!;Xss5TWSg6lqnq29l5EY|@3Hl46`)1xh_qjZcc6h#9A*G{ zwl+ZdQNCwg5bbN>U*T`7yS)NG;(g|Rtwt`z;}1u&hni)8I zo`@)Gqi~My-kdDMh3Rg`F)=iETak<&RL*N5^RrY8pyFt!;%HS7r!*5$ahE6b+zyY` zdo^^cP-sp>&w5qDPwNbRKlB`8OM^#}LhRruj>9cXF-}wzWWh_nswmY(ClW5UoOgEX73h##KIO!--keG4j094I3y3r?tGNETaJ2v4dX{{c&~@A+TK|~>e=LK=jy>TY5POV$!!Gj_>E*gTe!ga-y-uf;?ZBxd7J*OqYDvs2;vdDAx~a*JsIuX@tl%h!t z4KBrQdOgb5RNy)8n{bbpJB`_~1`LXV`r7!dI1$JP*4NQ-HH0k#j%Wzf*eoo7whcy< zv_$eoR}r&~Xaj@ntt+hXw3fWm>yiTWq#$SfW&>`tEQsb^g89Y)L6Uf$w$P?t%Q<_b>J zrP}J{rNQOoDkXNd8JO?2R&Wu(-Hm2}))I~c2frLf5>|5VCUg%OOr1Fy5$k+8gwx4; zw;wOM{m-UgcZOr!6x8=vt2nrLM5aoMd<#>5^={lspPllUYO`ctq&gcw`DhJ<%mHqreIPoWMey za1IoCD0+i~!Zri%qOuOGBrUuUt$OMs=aarhVt3!{Gn4dGG~alNIOxM!!G;h07mTqM zlvFUPVCS=Athps4c^Qh;j4>AsEQMjn7<2BxGW^oR$yfW&Y3*a9SDjGkjgEm*qHX#R zPt-L5OmFykHZjf&zr=Sy%@u#DO!BZ}utWF<+#89dfzA%n!u5~@LaRvj!TYTMRm0=H zT6jHZiM4{A4y_`tLFrzGM`)91%Z=-3Ca#^vdB)oih_=8+l(exm#kAaQ{}07{?gaLGu5zJ76u2ftqJug^;Gk?;kCCyU41#Z&BJ zA7hh*FDSQ*Z?cQ;NEPGIDttkOT^zKF=ckGx!iF!XvWpkl#Z9T=%`C35itjN+Gl#c#nQf&ep$U$ke&8y)b4U}J5Yb}u;}a3oNG>78w~FnzumRAG#@{3Z5! zEDX9m(FM;-&#RGk0RaNEzwUzM!5SR4Q$vQHQ-g4GY6$FdY7p>F4FP^m4bGfXV?4*5 zQ-ibb)EJq!MuAhKdinDe0>cH**YH;j##1czyUaX*hrv}RU=0-b`zO!0F9SMk8OvBd zx`MPI{xZaK;BKT3)MoZ739aJ#DS#=7sv3Xlbl|#)AckrYb+&1d5AklI5%lWt=nQx1 zL;&uYhgaR9JN1$*hW_!95-f4A`LSW{1nI%joyA34VN-_0Cg9IFYjH^hx-}XksfNEM zeo0qq7t2!8=AH#gz`HsOPrL6cxFh+hLfvsD-bLLpwF~UJ#n?8C+E-`xcO%@`eV<{G zCr`TjMBdDe;|2t-qzW&1YyTNI22W?5k^Dy5Gyh;b^PeTL9A^zm+>gfi>bwSAjKeqC z1DK{5ns=k~7Lqc6a+ZTGYID!Stbsk`@JO2QBUFh%tijFU0nwq3k@qoBES)koS|1^@ zfLbB2po*(xm@(Mmavx_(@43~eYyjZ*ox-4y8>`v(;W&cqHBS~U`V!PdJC6dsncigi|u zv?Vy}sg05&30#Mx6ZRhYeY}kmW5MkeI1w$y|HpO&EE7X)ojN_@@JL4(%Mj)7&`C>Pn_1c~NH!u=Px~ARt z2zTi}${pSv7>Fm!f)`z^h2H?!@I(s>i)6_Ftc4Ud08B2<(AvGQV&-7Mvee)Q)D3?# zSs@rR%PKclRS{*(PfVG>(7qz=UbRCABbCgImtyWZai=|nu5y8{FFnsbM60q~cE2YHQ#2!7+2$m%i|58-0suLt*@(AsiO z?apaSJ?5$`G)=+};m>^5D$D~`CT9Q7L}IuMP=82b0JJ6wvCv`9{eYc&S#Ts^w-GDs z@Q^&goDzpuRWSs;a9~JM!nO3C4EW(m?2{sO-SJ5veTs8(H`O)P=nc!rl_wrL?DzGF z!5d<0a6lgPtt~?0diHsn=y+r3$x^tRwCfY&zx^9BV?zy0di*1F(h{jA)X~pBz;uI0 zMwidSCn4g%jy!?2O zihugIoZ)1vH%`QqD!G-OT|JdOvUDXp%~g$Uf)Ps(8&h$U$eEbqO5;rzAAn^$sU+9J zqBx1h5*Ffg0~rnx6#)j@4^S+FyPn>EgWe!FUh8O|`2h9e9_zp0iSVl?&VTTCUR1=n z>aSviFU*v$VKLygsA=h*FeXR3DDKE3z&nE|SoXd8)bF4+m05Ce$K3fLe*&_(NU8VNOw{Go0$2;b`IK zxfaB?BZ{jd9ul$&cdy3De`T9w;NSR<|RonTi?31JxXXFyMut2p=v!H>aWY~p+5Zk zoT1KEGhh&@*pVX`E|_S%J;*;?aSwg9$a#oDV@pWdyh_~Qusps9dMNPIN{9!JH6l>F zBSsBoh1Q7$ByJmh4sPWQOS(sbNAeMv6vv5td#AN(l?_q3>q z0aF?y!|SVk)u&zlPe%|;OhsAG2VZuqJzdAa_%xGjYvCUNlhkyLAVwY`5PE<-_rMoh zHWBlo+}^yEqEHW$LLFgmvOsh&#Q66yc5n9oF1I(Ar+P!Di6iYz4`6en)0?SzdeZ{_ zMa`6nt0V4Bnu6j@pp&`96LrVNU#VXO>8Hw;eqakhzDA$W8lh+pl!bZ35~?osDD?QnemFZfnqpsG6Sjl}b^A7mcHO-CnH zckcwv?P+(jIMvfqjh*$MH}(daP(6ExlYHqEq$KRY;j(Od<;foI@V_5yFQ&gN&0S1I zP?9S2T@QzeBSzmWpzXxy)HwG5VS7AI_<>q-pya7tLG_Kl%s#4h63N=JIgqoAI=El4C(7U;N-b5iY{t#V(il2{1K#ffT03+viBen~A>5 z(S!mXL&NkCcQL=DGz%!wbzFNQgKgD`=RPpV;YyiCrZLa_s$>Yau)ze@PSPZ6}z zqg~eS>4ab4fnyAFzA%WI_kdwGlS#BU@c3lJOp;CFdSt-O+_F;pHPmv4+^<=u`~8}w z>HGEV3v>5t)^YahuRoNtU+0UO>U$?GYU-;NqDeB=aH_>r+&JJOU=kWZ^W6qI7 zIygXZ^yWPJxZsDT4Z%lTkPs0-XI{J1oHr6biF43+{MSE6qg)B~u+F=GqyR2Q5`%vH zknmxh?%~7IbogAoAQwKYXj-bm^XOVoN_`=C9KhTUt2iQt;E=$@<(6+%>yw_K~Q?!>1UOLb~yJ`%bfs!>G zgSU2%PaE~I4`Q68p1bcZv~-X!Wqu@ik=I<83I|Ii1CC3$3CGVv$02C(8pMhvtEG>2 z{8!DrE(PSrCSjzomLX0V#c+R_4MC&;XWc=G(TkX<>S*|2F;V*xu@XOev#SF&X&p#I zxV+*&%+3ypbga`o(y=rh>9*gWi*&5xAl+}5<{+J`aq?QdJ=y4vAw(eJ6;UMv?<0f- z+=kQFJ8+PHox4T~pTJOULh;CRptFGU= zhS^l|H@e&F8rC6mfTU7Duh8HDSHDeoSl9kBZuYXPc((*S;KSI*MU_E3E3PZr4Kq%5 z6V+i7h;%W0#jcJam}60f@$8{hUgKlp!5e%ZpWY$HgG@$H*PtFZK1O{OUR9;4GY#?( z*0W_uIfGOPXbOhbk}9DWKnU>h15AM-7l_q61^8M+y9sb*K~rawc?_ezGoQ>^t|8I8 zh)bq6v;;z`^>9Oj>ZL~3{tB{)o|cYpdRh*A)3c}DvuBg%tE%j)s*I!;XCAC($`f@y zRD#$x#BEd7Ax;I;286S&D%9tBxT%8Un_{zsJMN7)-ZT{Q*Cai1JSCRqb zyg~WBmSa}If`cTV=DH2>(EI73g8T0Xz5hjjaDA)zu_A^@Qt_0LziAm?N%X-0vZwcG zfJ061(D#pMdJ!i0;fsUjcQuOd zLzFp!Q6Nz8JM9=n@539#f?wtt#blx;SSG>i#^5M)7W*Dz1!H?sv4XLK+4x7Nhj$Q? zBo!;TF1W4&ILViiee4UOxlEi3UCSQwk1$X*WdFNIG-SjI-u{YeHx(%O9u7a#Ca}V= ziqMHtPiGtGFog)Mp+EkzbBW(b1C9)!g~_NYX*-CkW`>|Wl%kn+ve>fSv&mCb1SWJH z^l0HfrJ80c;O435>7kltovfxI0>osD&;xVELDMHm!wM zZgYrS6jwbyqbAKvd=E3|xcSq+-!S(ni&VEYs?trB@B^5J)%YJA=BL`c2rfLm=nIJykKY%Ezi)>2P@ap|5J zM~_6*tz8{3Pl1aoa-Ab!#H@ivVOSo)0ycTlSWCSN?_YW7L%q&*M(A01{qC4?j~DYo zC&-x__iT0=oSSN}x@~N&`q+#ojWblM$tGu@wtu7=?+)v-GPt`*$kE+c3Wxyn`VLAv z^;cJTLTgI9%JF@xO=#~jT-lC|SYXS}KEysX{#6TINDE-UpE zx2)?`RzY=Sv=?4qcXuK&Q5I>b$GW;yD=X9n7s0Lys}-p>gUy6=e}7*lAJYaG!bll5 z)P`9KYh=_mEc=B}$N5@h5I+%Gy8~5VZjMs3RDytdtjkfeCh@UMuUscAx6WnRb-rd;z#dK!@M3WCbo&E%n@jfPDDJW-Oq&h`P-vB~nJP&W&3d4NWV-=4;?#sYP zmvuuOPOX;OM^s{^w+%1q7M%Bc2Y%`@AD)jgs0kb7XJ$L}gp1@7`GO`lBQ#_U+NpwB zM)@rex<7#$&@eaq%$@qx*tgnYHdz+`@8iHgw1@@V3xV6LVzlhv=(40`LllT?9LhXt z*pgP;A-KcrzZW*=jy_uWb*uzL6VM{mb|a`q6ITZ4ixpYQrDm!Juy2i4^4?n5Kzy^@ zHSomV1txHC&b~0>g=XvsomY(S40t?IfdD+OzttJ2;iD>jLT8{Hae}?(KYeE0XYTC` zlwm+Ikm0uYV3=bOk{Hqy8Z!MGv!RDB>gVVDWV#Kb4`q!(uK9}x1#V7(6TnjtwE}?O z4P_U@Ph$eQY{L+#q_zW$It8b4#LcaWk3-&D$A*wpJyhE-@ZUN@AWGA{{i|(wLK~}q z=`Qyn!ZVum)xYPlM*7T$?*L@tqxTRzs{}mQ1gXT%Dh5)H zcH$+d&yA)(0h~Ej0~!fF1+42&Jh2@|Up&T;04zwH&0`FGC67BWJyon%&BF}672OhW zmS>!6EL1ankyrD+?1KwDJ8$mJ>iivikk>1uO@V7*+>|V5^5|& z1}}L5R_oXD8Fc^mU7-qVJoQF}2f@DXtFs@3?yM}h8^MWvHOLKHzztFh|ARfj6RcRG z+yS47g?+#5l*m5E4YPGN_fj-bfW+Gq@kxb<1Y5iXRs{rv*+P)0g{?(!+}kO1qmLFD zkLwh&D~!yd8-n*$4!#S`*hYL;pNfA6pKxe~7WoF6Bi-oZfB9f^Bk=~c2|(1ms6Q6V zGz0Z7;)68o!6)-fPyWUZe45qRM|^O|#$;}-J1T4MEY~8{z&p-2Jv-qASH`KqKOU?9 z8NV>RZhF!~Mw2`D*uSbAOIW@>*B*tMS3b<~~zqeMV80 z*LCyRq*c zPGb|xu=t5zx*W+tyR5CghjXu+U~=5$E^~GzW^J831D=Ae7m@uKRl4q;6HpEJqsm%G zk*4AD9wA8PJ;XSddCxHX$XxF}KYgy@!Vr0K5QbiVlmUuk1Gupcww2o*Xo08W!wsUi3wMqc6aIT-t)0c1JshZdO$SDJK=!)?Cj=^@jx7{lPI zahQ%-*qktF^p}l9&^$m_rmYrMBh-N{k0d??H;3Pl;P5w;k+S{hnTcfl=&f0-P2hzBk(@`I^F#L0N_#oWPH(S4a?&eP)Wp)0Se2~`p!MUAx z_D}5J;9S>5$gu#@S^M>1`rRnh!A>%{nG8uCz$@r8K#Oc)!$6-Dy2ygCktv(uzX1$s z04tL?V_3Z^5j2)K<3<>$b#u6e!H)O#nWKR)b8LJ;u;JFxHnz-B$TCOa%A6FcyabVk z{rU-+4+mA+NFInPEkG4%+`*LI4yIsr-r9vAdBq9Luom8o8O6HSA{TLLg|T<|c_CE3 z={(!vW~Shy9FS(VBb4njpZS)naTQ@JFMjB}7%#_5?DVHFJkvun%P!HvKZ3|YSo*Aq z<%TsAaEI^T_|m`(s7Va7!x!0j_f07Gq`*408LmfAp;u_D`_K@ozkX4%7U6+=@-&RP ze{|A=@N;uTZ`!JBqo0S{8}6c4Y}H1uhf86E5Qd8(Jl$Xt1?R6BD^o;lYP0?%Jl@tZ zaTCYe)$Q*hp(4B8(wDw$odH;r^bcML2d%Tw8XjojV*pa15hTZ?VT~;{;i*3y))W-b zLhJVWtYY1|6cL2S0v8CfsmsU%zyXf3hZ&*BXhtbiBJa`xxU?}tI=CG8DNg8RE_?_D z9=c8b2xOJ;RXQy4J2-Y|8)seBr+l0>qfgm5>xX?Re6|0eN83k;kPY1pJlYmqG9PRn zf1A({*qloi$^A2zEW^FaeDso~xaV&(KNM<(N87Gxf5_;mB|SyBj`>L20fRO44>3&G zF79rNY$a#2yF{&Ri#k9+n6g?}IL-Q-wObW@AR;R9t5*tkNH=g>@5%m<|Ha zxt?hLM|{|p_gxJ_Mr=Z>o3DYE#;|sv9mNVoERqkIETQE`s+p77Oy}Q`!DH4tnLD6O zjuMx1Od=mlUFNAD(iEc=p_0O@*Mm$!WS>;(seTc9PlPmuV{h|hi5GXBHwXLV`;AEb3E&n^fEh;HI$ROR$v{|RTQ3r#{;IB{=g zJFIsx>LqSOVb`eAm(I0o@(k~Ym(Jh+l{K)Z`QVTP%a9n)0U;v!`41(=Uy|;oB*wWS zhGt8Q_mgl@VkGJ6k{ExAyOhK@mH70(Au*1}xVa276%JMK#t{|<65~Ydz+4Fbmn=*_ z9IFwneupgqeId8&F<#QhrkEJW8b3M&6O)(@dvqdtUfsrz z-_1g<@9;qyavgLjrz8Ch&wQCk|Bvli{aVKdY5nSEHRl~)kljM;lI+IL zI&@=QWC9!O#ZTt})PJbpY}%FuuAlS4!NCRIEQ=AK=|-mPVz%VyzcbGZ5Rd&e!+Z(c zBJ_NS9wjFR`&056nArleH#mHAt_XL!^)>QH?uNypfA*QjR5I`_5|%F(8Id<-Zu8rf z4pa7eHXpJZp{euj| zf9iv_w8$SQ{vaaAy!a_#YB!FEjj^7oqA+Hd&%DkP-Z9pUs;V)yGpcH|`=+4|(-I(n z3C>byyoMK>*(EJ}0mK{~&Xdw;_;dP!CC0a0Y-o zxL3$ntc8nkhZsZW%Bgtg+A-DsGpfeafBTG)2-))~0)4Zr0GP*uIu?v)fwy=!3rg*R zNi4WY704T9cEPP<>KC68B#h)GMl(9MT*{W8(SXM+UX&_6z~TzKc&S~yELFUT#Z`7O zCy;Lww^ZYAv$zJukd^AjR4+fH-LA5gRc5!u_#@qT-&3om>7F71rvM0ZMOeVVQ=n!F zxDYMNQydY%6)#lJ1=614wU~@Mr2fNd;uPo^Q~RHu;#D%W#S2;FDc%QjeYWi>ZbdK~ z&KqV!=Gj7K+2}E^6N|7`8nABW!~KBsO^;*n3Xn+EoLijpg-h8=?F#;A_uPTkJk@do ziL&!$7!iCn|51jTQ}v>&_zkc5b#L_i39x*4ouC~XUH;ipLZTXZb#7ynsZCz%>ljbB zZ*ji(7U%2m-y#N#jru>k_3&RIHjS;m>a$5>>;0b*n-0}8;w4|G;|s*gL%l#G=L=PQ zff%0og1!12aP6>bm$7z*s;#Dtv%ePcr?z4qjN*mmARmbS#2o;dBna0_K`vuYRpBv? zsByn2b3t<@`Pm__tid0@m>orz_)HGbeo9O@PR(DGcd`AxcT*y$Lm)@I=|Ae_6z~o`{Dd*Fl*VleS;E&&q*+ZrD3{t)$`}hc zfiOLR0k#TPyohs7k3(yO!1@QJNNuDJMRAf;_w30rh=u`qbI2yAm*$7;R#i~`WYvT^l5)ZXuHo?#+Al`Iu?v)fv@;qEZ~}D z!6X*kq~3U)1zi6uxYbwx%n3n^NxcNqjYm%+Me$WXdIBj5i@5`+;+I%VGR5Mhb}@GV zRV;ns4!~mW0DPM}fcmh!?d$-o!X1EBw&K^A{cMc4()ZUrwE{6sb^zOV10h8fFjo+? zPy;GJ3xHsU<}F@APp)f_M&;2W^3Vp#10z?oA4uP*_<6F^jLA-A`WYe`P_@mu35>0@z%QJ_vw+UsJXZXl%9&7oh1k{*l_{F9CV0DeReo~pi zUAxeBPRXb&+b$|AGJc54oV_to*NdRuhp0&e0B`W(q;d7%e(|R6KTix|y*kz#-+et| zA?sDK-pKCjkvOwn8S7PK)I%`V;>SsoJ;e$TFdBjq3EQb}DM;5Mo&|Z$uO!xh25}j4 zQG3nBYMrV$cOGQanfo5~vDV}oaVQ%J`74l-uEEuF~E;rNxlW|-H1laB|-_T8WfzLX@XAY|b1zL0%=w zLw4V6h%mo=gc4G|hU2P0UpcB0lr^U|`^;V4An@e2LBu$W0Q~bR!EM^iU}woRmiali0mHJ5W$u%0;M=eAQQ9^zmJialfjrX8!8ewE z*)8tfnAu{U(={zxi{bA1r$g<%mW?j;F{H2X)vCQfoBLEcDhB+8QGYDV?TnUpd*RE{8t5KSsEr6_9?Ou)LsM9UIJdIzLiPbM>kfxxu=k*C zG82hr^0ig~%+6%khYT|6MoO{b8BxL`QVJU5WoVv{~XS2 zxKcgdXp}4&!aIYLpk=_YN}l=RwMiZx_u>L)7yim}xDrBF?XRrhM~N=rvZ~^BSF<~E zHeEw@=U*`M!sn_$%-IQ-wS-;LO{Ap`G>2C8>cB>ha)@eQ5o2Yq=EnL5n--ecRuIrI z!@NQm8&i{(vU3b{D@l`L{Gj1LY) zE&|O!Ive8>^Rb2xM%em&IXw-%oYm85d~ood%DxkRl?O43GPrP%XJd?EzUAOh8s;eF zfzSLq%-n8gnEI6KZT7)yB5cO7qP*O_bYI&(93o!3BzZHh4? zn_{R|4?;3vC-GIhB%9CGz$OSdpkzsOG8d`b)=;Wdh;vF(cA2s)#aiSwY{{WjT%`!Y z-74p&HutN9YIDhE5wVc!F^zJTVYTJ#%l7)(&hu`70ubUaY}^$9_$$(Y6=jp$y7iPE zaabjZRsACz%f*xv2v^hyM9ASARj@x&pv?3#zalr{K=7qc*X5g!~J zvvGc&Hr4icY%PgB&xwD5-rAU9j~kmyR-G2qIoRU$J@lmvaozf?A+F$qgAdUYx{GSg z2L@s$@1mB|#1+JK5Z#p29gkk2>^Hdm+&G9IIlr>;SnLnMeXz>#a=%Prt}8lj55(|7 z?cOu-+>!IFsn`uaP<9e%*S9QwA=+en$D+NgqOaIR``Hz1@-jEJ70|%~K+$dWNBUM6 zNd)lH4juFc>hn^3ok|Kbx&wb9Fm>PuQRC4K*hf47Bo%4ZSN~tVuq?SjLL}Gby#;0+ zlKwKono(Hpvs{HRy6_iPj4_`XxC1!J-%`{?jQxQfxaV&f?njx+2Nqxv^S2!LMs0`x zD2ZA3OIRt_=@6kCJN64m)D{@Kb zIO! zskKSR8q&%5rEv_|w&XtxmQp@zK&8=nAG?Bc4!vhk&@4xkR?3!}J|Wt3o9P{#u5Kv3`x7ElCc!6X(?2ZDki0}visP48KQn+r0E=xM$QM5KF^cvqUTPQHIuI1gC#eHrF?Aq(yA8i=+*kY# z8&^7zmO56U4un;<;@6n{Tns;|8}E2)R}c`64n*MKDc%EUNP)0*O!Sz~2zamM08oIdwjhWqoGYXDb?x2~)bdt;XmmcWcfQ1w2Okyuc`EQS zyn&D z#MU-WhgwnC`xeQatyTi%w^d8U*aIL2m3(IjgWG>RVx!MI);L3wGPRbt@sR)G1k#7MU(v5xYUVZ#C#SBEbg%t1*RPRobPGy#tTgA%vu04bYe=s1KDZ zz#QQdx-~>@#Raim>17kRq_{O=3#IeucogDilKd>0f*;UNkKD=8pt<5Exlw>qJh`)9 zt1~@_nCyq-uzA~Owt?r7MxhRs!F0BGtABWWmA8Jz@!5J=7SypITQAFkNh}b(tgl$q zqg*a5xYb+#%<(}C2*d!&+>~C{Tm9(qve-~;(mMaKZ=w%h01wcHd zEtW%8Z?S@ZvA`ceuW)cDuSEyEB;=|X3a?i!nTc#n&Q{A}8{=$XN;&NaQ6oRKg2vjt zI_a7^NA*@q5lmP0&KF4HUK$A!XTNZHbeJ*Dn)@QD9n`d2mSULR>QeYbkJcef z4`;=$EhL8B)FVw~y)xFT$f)O=4~}!Gx7Z?AK%FOUn=p$C^1c{o&?2ANKk*PEiTJF! zqNW{Z&Xwg$=1S6$yra!sM>T9F8|`RpTDmirRPU& z=~)?~#D4~^hMFgQ7<${uN)K~t!J;^=MZI$`T=uNB#l%8b0H z4$!lWM~D)y+1{Vu-KcGH$8d!-S}2nXCSQO@%LVPgzEZa6*UqeccjaojcMOMPI>1l>^(w{kte}k(SkEkd* zdY>ygdJi~!%6%@)^=@eE7v`sCWHWEg2)l)oQ+A3TL(#zBJ<*A6@!wRyaNFHR?06Ss zOIz*!dvyHP(7vm*dw&crh%p*&1$7VYM|iit;&Y+>NZ0a+T;RZY2`gmQ-cQ| zLa)j;5+Rh>P9-Haz&MP=el(i?{gW$F->=8_gERmBO&k>|Zxk(AW0f>KfWvBa->b9j zj#9JaHavl3T5=11UjZ5IEcqd>ItP9af73rTAD_}|pVK0*m!|qMD7^v)h;ws)2?iAy z$Z@=SGP-y(-&0>KO0Qmr=ObcC1P(Zh+kJtyAf|^tKg<6RsMn~_D#E!Sa3K;ct^Dtc zS&lioq=lDSWFwY}xaxV#lHcQz-Fz81CeCW&U+AHn;NOnrDj-%ir7~;gvwCnf#q*JY zTXaDA_Um2!_xrE2hD=3Eo$CRTA@#T-NUp{&L4vWsB%P5mL@Ur)G6n_SsC=w*;Dxw} zcbs8Q+0FR2JtL;OO^{;lS5lAUeg^JsBq3V~+lRY2$)T<9ggUMQ_&P=hZm~+`ohg*&PVksz<5*JcW{V1?M2eQ|G`x;u&5|0_F;6@V zf8(zMdASfC>*nL%#B-UY4IslZOVlh_CI6c5415c&_~BRZEB!0kz_Nj@_?w!19o=D<5kjG|1fqaQU$`#$?Kv_iQ^zS@eve4#IRqX zDWo-&?jPlJzc0Hl1j2k9F&Nn^p)80VMmhmlgx|udCDPqC(4LNh#9x2{_!4Un%iWC+ zlK@#m-oEeR0;^;z{&udNy{{d>(xPLaltDA|UIo$e)Nkx;b6F)%p@!axZB1%+Z$mu-`4;?k%`TFKDP%{g zLBNQ;GfS@I2h0)=TUIN&GyVzIB4_yu;613S3`2#k#0>G!5SEO8$GE_5{EVy4XdR83 z1qIPjA3zy>d#Sz#@>@Z2NNDZmW)|pc%J4U|uhgrJ?$Cpu7b&`I4S9JUN9THXc+6M$ z4X|AVug^T7H?(%aCk&cm4tWSQt$~l=FB63gV#ffh7XYhyc&1<##+A1EmjbGRci|@V z|Izj~@J&_s|9IOpr4;HdN)erCr`<&HfmuOkW$T3mlaT-_h+ii@3}xzcQ%S%nNH7iL z<`TsLqT5uyb5r)VNo4coyso92!f$5IkDpdoFmi#P>|_Xm8)5#8G4y z3qNid=hA{zgKNY=J|z@GQ{(KcuY^_y&CwLI%>OaS z^R)8aQMUYN_+?v9w%R≠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 z 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 z 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 z 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 z z74<~=mjylT#k+6+L19X@PvrkeeVkomK0b1S{GM)k)t^qCx$#MTPY&q>%aX}&Cc1Ps&!px3qVj9<^n9X^3J>A*#&dGy z1fDh{IA?~&asreeC9!eg@tncrQ?U6|U=H@|!$&zSS%x8>`*tHHO=he{K0b#udJUO&d&{4F1CF4-=3d&7&2Azc>ektv;c z_!r-Hm}6(}Fm!FE2FKlZDYcyq?UT7g?dfO!K|e+DOqV~jJ@r1lchEMk&gSD9JK^yDeC3CuyIf{)g#yXJ->$mD z_QxKSxSkY~{Gu!l#nMNWu=se#WB9aX2ZXD+Jg$^pk8F*!DWaYvHNeR*lcWqhE8L(F8u4X$pA~xcwLWLXJQ(=XS#b=uxOP^Q!BXfvLXr}%pA`|%-8;+sTO6Mc&Wa3pU2{%o`2`07y7TJSQ^X;M(T|e|#gk z*Cif&v)(z84EHr64(!nw|0|O8K`Ywfk#6K0!!OTvr!F|!{hZM8f7o>c&xtMY_m|I! zmE$Do#dzuslBD+&s3Vx)FL;Bz&;&E!#dpsMeF%S;l|md?e;xJn%LZRSBlKQ>PB`(~ zIYYi9KL6*+g>i7~QR2d#uoQMb&iMFk2G^7L;c&PT#{EG3aA`jIxoA-7NAkg?rPKiv zZ&L>xaECZB4QlzHREJ-f2l$mumWYGP9J9nq*t&9-I0kps&k|Au>)14l>%!FEB1;&c zUCS)71-ijZm1%W_V;6P6#DiJFmEST-g@N!Y zG{Bc{GG7Ujlnk|r^eZI}EV_dqp1PYQ(&1;)dEt~KN#pF#iwHQY?RilK9lXzr)F~WS z!_SLSI6dIJ&`#y?^Tv7JBj6JUH`70v|EIzfxbc(oA`?E|c3wD6lcc`4&htJ6uW?`o zbzCnc4m@`Iyx2nfFPzO?Uz4OUkI#!hxD6WML%0RL%DFugUZ`|I=x6YJ^5O-qwQ+pc zy&&9Pm!v~YFNk#5y4eL`gcG6T8ypX9E(ilW)boOH<~J{0dtDHLa5bC<9ebmLiSQ~c zfOQS5tH%YA46pfK5IJz@kPAZo;J@|I8Qz0>7%<|3*aCkUL%!Lp@AwNM0``CPf;a|G zPp1EylJsCI`QX+!s1Kfkj&mgGHgtte=Uxygu)<2l^Ohtv|CqYqJ73_R%X#E0>Vb!0 zDy*}E_%ITd!acC=+mcju=LMmIK`;V-0aKvu*TjP(pb>6{j`JkxH|Pon?_yryZa5FN zOQ%0v4X?tg-w=PkB)tK>;Vqa9gLgB2_yf#=?t6&4fX69xgU$C+2V4qQLdS2Z8_s}b zuoODK!zWejBR|Z6^Pum3^1}>x6?VxW|3XRH0=;3w@5m2R;1+0ifc!8SI=;*C1>IoZ zgBL_FOo8)YAxwi^4$&XZh0-GOLTA|aFzX6uz+`wDrb6uz>W1;K6drPq2p16`pJ2EqX+I6mPvxCPeup5q!O!!no$wTn6aPEr?K z1e4(@mF_W#Lc256^*)bd=nCh+Kv)Ln z!Kh67LnFKj1AZX>QXaR^8}>d+JunS!fi2E4uW%)FTtul74212o$q(1SbXYBi{BS0$yMp5edc%;5d&UM4>b zgTe4)I1d)WG}!bC{b4ZV&se38pfk*ade|tJ_;3tNg&)FW@DePA_424^6|Xa(4t@e7 z;6s=K{qm_Fra~jEZM?wy4vZhV!QC(zRw2u` z3}?NXEi&P#DB9QadLSlS1j1jY&<^V-XA8%VCF%YQ^1yjBi32OXN&5yK7jv^kFl@At z{xI>qY~j37lHPtloA(;2V|BLBZeqSRW{Y$<_}gsWlVv_nXAAunj@$Fu;uu_UDOwpa;Gh1tRg>t7@OCz4eCI^%=gZqN>A-XhPZlGOP&b-@vLm=9R3jB#vZogR?~ zZne!3rSSI(Il}ET#$72#tb`M)<%lwP=!G1i-;S*fgQb4dzqlp`YGHf@f` zfa_Z22yGg5w8;^{@U7lCqV5-xw0{WkVc%gn!uv}}YT%zE=0V-49B~!49Ygz9oCiXP z4^M~E4j+vt-VWwDEJp-FPeYC{!X)UpljrBv_`l|HxQ;sDs~dB~F?jS8@pth!$svC_ zj{~TKhcD%bIC$w6@nPd%@P8vozn0|)1H4f2qHx^J^UezwMKJVgc~PW8{~;Ge@*YX* zI`X2(f$s-i6m|DLp=-#%h;Dy3AUagme&py-UIyromvC0h6JwKK?^IJ{sYNQsYY^6Q;qy z!|XS?BvPRsUWKJiFA3Kp>~};DgJBAE4ZI|BpbnPG`w7%@lzpg&+GKRcXoub~b2d8Y z^yVe81?pi2Oodlr8kCNc@2yKh2etDU7YtrNKbW!*{|WlTx=?zTJkSY7K>d4{L>e?M zz9huRrmpP%A|hi27iIU@S}~)Gdu#*;gC)Ahgq=h51fBDQxDAD zLOn3y6Y7T*x3QiubNeOXc$UZ8=d2&BpT=bb&a=LqVDQFfQbJUF$=WswfAHM%UW!m-URi@Lcy54E@~yy5O{mqjvs z*!Qy70>|~cEHdFzSOyP5Z63#oj{Y#$i~jJ_!Ssh`U?vo>40iFQe?G56pf`Ltg#K`~ zAN}Eam-F%ho9~z|5c9j4D!Rt-;p2IJ3xN;KFont50d{UUcW#$Xmg1CuLIPE<7Vbcrb|C!f4&>PmuCO>=+Zh;kZ$Pe#aBL8(> z$K{eArW?r**O|x<+ZK}_epNz#*!wE^Z!pfE$PZ6L16+UYvPgr~u3r{LIQ_Rb_Na9`sq!U(Unz9O7%GoH>@gbvp2cSXd(>O-!G zRQSP|Dx8#T0 zkCPv6%qBnV_#^r6(teZt@XUSk!{wS>kqU2A%N3dMa>HC9-Q)OgpDSFUv16_XhQD>q z6)EtgzPTa;hI{0SQn=eES7?8weORv0!;>%P3IiN4Hdmy<5#w`(5xzAkS2*40{1ulg zbkK2Xu84y(-ylD%{WkgGss-dPV|`P|4{xj_KWws={4j9?`Q`Rc$q(o5ApdX7Q#$!! zt$pN&-bcs}r+!aD+QKj86ok^Jy{0r_EgA^G7wmEAKjn(Lk9i$*EmtgsPCt`Rpoa@#=Jj0RDA`D9H*&=s zm~xXmHa1e+tz0n!>Tc(X>ri_yR}^XR|C%d$+uBIMWz+{}@2YeV)jGX^wfKg@cV`sFWw>!4$X}##PP}T^wnL z-Y~dIo;UZ_k8T&vhfrH%7M@2cpU6+62Bhx4J3X8@(#)qcVWulJmJ=m{xA@x`R0ik z(BMbEM(Cj@EQMpB)6hJT2vcDeG(xE{dG*u@_0SWhLIX^LOJN4w0yE)WXc)%4$?dR3 z6Y3wHC-hJcSHm=T9Xk0lZY}c$7s5<<1-b?>KTXLCbubmCz)ZLWN+VbYsD(K&6<(Ly zM-s0Y(C9pLEi3gR-P!5Ifrq(!MF27R1dg-_2>!TC9lksJdxfD zzR!4i!{x;713$T-A~PV~!hl#=K%kc`+ zer5dQi2ECPp#Jwf5gbI_k60&IDyTb{dTjHBX9#}#eBl&I+=}_)3QVbzFSd*)PW60| z7)JgY`9c?tu2#ONGJ$;c@5PU}@WY zv3e5qcgPpcQS|SaFLppfC*nra@1=Zk5*oYai@+G-yXA`_sOw4GSmO517Y|`--+VDI zj(T+YqUL1A=aDZ`p{rNEXdln`z4JvGj2oOU4kZxZFQ4D}r=DT?VoVbH0P;^E->7_X z7iNsk=Q=&{#^#HK$>a|v|1|0ypD$WWC;r5I{tkh9UdPcXJW>HUKzA(-ve^S1<`X>3N5N{6gr&8xz#G95cq_>%m>CD$W z;=aZ@%%{E?`J(Ou_y+4C)4(|2fwS{P*g`mmal8xX=8Nkx=jDsEMQ{P@^&VW9FWge# zBIZqI3Uw}qOY+5>C2(oJ@O~dIXFZov&x(A}a2fS~Kt0Q;YZdiE-G_{41>;zqFVa_1 z-x})pfN`&79#%1)k651%nYUEtZ8iG!tmhi^A5-62^cxt@N9Z>)UZ~&9yrt5?|XN>=2=J|7u11NpLx^1AYFY`sfM&j>aJ~lDWUo#&tBb_=nQ~z$}V+-}{ zCEr%&c^~ruOZVps?Wg4VE??-k;XlB*KO^oT#<87x4%6>*;vAvh7vw)io-Y~SamMu( z`A$&h4)iBkubt>maXjooe}-|UqtE1c`39aP{%&+x9FKeGcY$?>895y9dx>)?Uj%=P zE*Jei^5iqGP*;#Iw(Uo6V*WDF7w3yE-=Y7Jd4d@~k^cbtpP8qF%+n3#;}HFC68A9U zzJ>k>ac|S_DD!%Uc{_&w7v|?UT6&W*I{Wx zqX^DL-=koFF=n`n16^8Yj9b~cKXBI0&6iojyxc4u5A#O+}eSD|Zfqe%M^eP8Okie5+E zKcV+93dd{cy^JCgI(aicKQm4rqv&#-_Cd5m$=4`6Z_s}Tz$fx3SsULl zbe(1tJ06m6hEe1^BJND1*!Gz5&0?Je<9my^l19?LZR8gpG*a9G`oWZiMzLC>k&N## z4qFWu7?>A3jig^j{tEP4!8l;XD(1nSeyfcl%t0f$rW%EtBmLGh4={BjbylR`X2#1e z$~b*$6cLr__Zjn8MI#x~SkJ2T`_d>5!P1?KryBjzIZmr86KieQSSKx}Ercq$Z#8GOS|T*U&>yEWse zS|G|`hEsvq;Y?jM3-~*8^4Bd8?c0*4L4mjmbxjJyhIZs@Rv?1g6Sq}?XxIUL+X9gT zGddKAr7q|@74Wy`=(`q(Dz5DJC=i)2wGaMI==&Flz|QCfpnnPfpaNlpseZ)of`52{ zi0F!c6#2X1f2BZ_!qgz@>yCeXfk<}4A3^;+@JAI0sVD8R1tJ5+B{05T%=gp+;ntgZ zon9dBLj4;B{Cy+yG^;>F^<_TZDiF^7n6LTF56oOxAX0VcQwqeG{^*w$@OlvaiUN@Z z^&b|96c2PC6^H;&#``gTFY<0K5LckI4gCP>N-Gdy{Bo9V2l2hBFTFrqhlai6_hB3v z1tM_}`a{$=82zyV{`MCADeCt{|3iV8Glcf60^#jPJvq$dQ2bYzN0^e&JnHFZVjhQ4 zUkUR#oP5`qN0@nodGsgmZRRn6@!n+~N07gad4x_6na7dTA(+Qe)L~o5-$X-)LVk}1 zRxT7LWmYc~DWl}z6-$Icw9)JHrF(-_5@G2DE;nd|_$m>Mv^eq&b&@i-6 zES<%u{WAH zafQMVLmi2XH$g#xuY37;ge~EM&Y;N@2W-)bT#!O``7Q zjCTt0KVZBtZZ+ebO1zI4Z!&S#Gu~Z@Q9 zGnOz8N0ZRKkFK&w*ezu|)lA|T%zVKl7A_-xO_R_sXTIv1M9me%YhdDiXXF8ZFte>mZ2J&>2NQosh`y6abXh~)T}+}3>bjf6-nHm^n)n+u z>gi(=o~h_`CgHe_dOc0zBy=5U5-IB$&mfZs_?SFHOrq`v#;Z4pE3nkxBvLmLca%wl zZKAHxCgHpp|5%f_4)q}>k+y|?VJ4Bd6@7$BxP3z0D3f>yGhbIK2yl?SJgwr1Se`yj~FmtC#tlZ0ZzcGn1-=g1Z654&_+iwy@(CMH_Y}rq|BPJ1*LH^?= z-hX61PqF?`pUL_kpq_KA|3Suef%QK`zDunCVVKMM%QUk7N9b>2{f`o_g!Mm0zMois zXt>V$A7?zbSpO5myTkf_PriGsKg=j&{ZCTw@2vkR=I1f%f0}$YMWPG_S11yD&)|0~ z5{69jRVfmlKcKH(#QRi?@5Lf<5~kEH5-I1XzkZPj$RdBEB2o7|@w7$a3e>kK5~&x+ z*SbiAWiwyxig+J~dR&Ucb(qnqNTgjPPnRN*c!@Y}MZBLvzg|V+Aq?(YBr>j$r+<-{ zlS_ZkB3_?T=fEOSC7(J57x8`tdHjmRQX}IYRwM!os578QG%Tc!QANTCb*~hO4JP7@ zD-sb!=tGJ``(kwAMWPg@MHGo0C9F?Wkx2fLal{sh-dCwBzDP(vQO}ejaR{bNE8==O z`WZ#S_h$4xWFai4W-PW}f)Vnz$%J>lc zyLPeAx>85IV(}2_8x)J2PSn|`SnTLbySA9uXT)z-EUI*6ep(g_w{DE9HTk>KuWhkN zaid>{VzIXeaXS`^t3AorxmeWfO&wjSuMhg}#k}r9-?Lb(?1#R0u{fkd->+Dd_D82H z7I)q0?@rww)ZtMq(mm067K_zh)ag|$32|47CWgntz6A><3B?$Ba!>}C96^c#(C0`onF zcoU0-?^yCgQqMT@PbwB0f~YI1SY!q>{utIH1bu9=a2}6-aqL!ZDrgriR^7TYE; zzA3ElMDk6A5$KbtBa%9&Gk>oV=QYMZiE+#*78y~*d!2cYW}GvrD~7m+VsSE-d6-4s zIO4y_{7+^c=P-Zqr0Gapw^CqhetD)SXJ4Bk0#L&&SZMXWowUxc->BPVl&fPA6HP4dgw=dT%7pY1U&C{W4ka&BQy) zc(;%@i}8L!yz`9rQ^t`^+->x`$U1yRJ(oEywi7Rx$Lr_RlgH!r3*s5c`z7@hvQA$y zFGW0FcTi6W$IVXiUS)lDF^+4+Vre?@ud{BuiF1qod+2|g_1TO67v^yv{(IE9AAcF+ z_zwRA#(4n$L+0Ti{>RMQVf;2F;^Yzhwk5*t81+^t5vj+i%b`R#e$Tinm59WX)K#TK z7*CHqyUciKtRYKbI0wYGS=z(HB$qOXT~Jdb*W} z)jv^(TZu6IjJ_9fZlLd5BD`;**OiF&x6yl)2&Z4D!?Q$mxl6qRO1R!azk%=`^?EbT zUx}+H{(U%%I?CubyhJR8nXvb7te1ZY*Ik$wSO%ql5)t@-xNrx|gpR+{Zv=I~444Cr zBTGcXhtxm1L`aY5Hx?b#29*fc$BYAd!W5VaQ{fJn29LoEcm-y{QfP#Zf^`Tj5nEts zc!?Mz*-83n*2Bh5%7`ry^PtmY;z0x40W;w-XoN;s3h%;{#jKmHos{~1iAaOe(h_k9 zW-KcaadvPy>jYC)upSlgucU6MgPzc7Eq>?o;P5<9_KFf$SU zi^x3`J-`I8X24rXfpNU&{iY!ICzJ*8eO1vJikwX59WYXU?CWH0{Vct;0mx1tO1+B z22e|BHCn*HiLJ&CFc*wXK`$^7Yz9-ol#`JU=7L3_mfC780*g;+HI{=Fr{N#4Fs;?7 z1JloGHCn;Mk?03@jKXgx!W)g>!9XT{2emP+Mwa{r=Yw%$(HCqO*J@OPiRZT(tH6{= ztws}=ei8begdUgRZ?JF*{s9A1DL*hV7dfDI1#-X?um)@f8|3#i>;;R#9bf|(dopsb z#9pupOa-+(>;-GV9I*H*{0XK{Z#7E52Cx=vzPi=WQYqK`RwE5epV4Z}0Xx8Iu<9D> z0a$o#tC4&P`W2ujm_C#800Xn|6Igg%t1;|U&KDvF41oDy?e*9rcq8_J4YTnJST?uS zSPcf|;}0i|`~e0Y!5?77qpe1<{CuY(^tSh13RC^zhLom)C(~EdD;o6 zt)xDj3I7G`1Ji#>eFSq~#4liR73b67{jAl<0CT~~V8hQ_jRLUZSJY>Te}(!C7XAkR zg6Y4fz6kySI|S?S>sjC*@r&SV=nYnZMPS40twt#rc%#**0Gr>W9)PuPQ~$tTa9|KqqWs&1{>DlM>)S9IqBrzPC0?KU>aDsfp!K~ zZKOVeflZVmkY8JS@5vE&a{CAS$BVBk3N2b+&4e=sqHbaMX0He=X% zoIja-zz%ReSe8nDV8bbGMh#ea8ho&JIQ&uQaYmbw2F9J)W(2@oFb}K+=Ln{?8Kq#u zS>z9D=a9c(I{8aH*aTLMz<#iBWScQ$G=4m{%}55Tz;sZ{Xfv|GW-wpQpND>O9xMYB zN3|K1U@^D~j2qo%)Po&hvtTB2Gm$g4%@__Af>~hVxHcmf>;UJ0Raxi@R*Xkqu=afP zmGcwO7i;ucde6a8`?33R)ZS0N7`ODkbqmy`W4cH8}gMle+hBl6T!FaH6D&+zu z=29+T85jUNz&tSb3hb2g)38&{gB9}oO6&xyz|~-S9(IBaUX z0kx|sAFvF}7R+xm3c%(WZALK|xQ6-z)`Ba*lxwL+U=`Q^b`((VVA)LkIG*2N0+>4s zKY|Tl23U4on=u(|E<`?9d_D5P#2b(g)`Ba*+#8V(c7P3FSrP36Ou31A3pRkU=cE5@ z+80=SGxY&%m_vO46X#MNBpxi1cyJL|JCF7YYV#=%Fy&Ut1B|`#30C|EX$P>H^d0^r~i9jN_?@&!A27Ai66jpa1K}o zt^jMnMleuGx@_cwXYB=fS{A z{3!SW`d&=FRrG(8;s317s0GV@NxDms|1$c3&3~YNv;bh zIeWtg8}?bp`{!W%I%C*1@b+8Bd*{dnOTgm&*BRAd?g8tJ7BKz5bw={F(OM^%3C16^ z&d39!4<=u*1Y9M*6V@56U@90_Ks-1c3>>n~m?Jo19nT%nXB7I(jMg&7uj4)SXsrco z0Lv$=Gg4+nYjuHjJdZ@qB=iKUFI;D6*HM2jLSMnl$QLZnB|oqOj4LF5I`)CtGuIg% zVBReBy&gG5>v(>Ne)I4L7+(zUM)JP{`C!SN$Soq>-Rq2HU^TcJO#d-*Z$i#m^qY-; zz#%u2K4U%ao5LTy-pHRDtyPX)Z&ZOTS?i7A^P;t)zP5sbCpc1g-)*-(GKMccSmR=m}PTy56V&%RgJs z`|0pMUvG4P@ty09z+L0tDB@&%K?GO!a|1*ZO! ze1Akac9Abw0nU-%G3`d;BJ|n2-Pi%$wwU$pbSHFmwyZY%;@z*?}V2Ko0= z@85&>6Xd?%ZghZ+P3^q@O#UCY8^vHlIaHyDY_uw&m1ymt)$DDYwQK6?ZEi}E{rgV6v+U%Y|$ zbJ1hU2BR4)n!3SAc^v(&+Q9p{Os*)W7wPY!#8g<@&0q#Ney@=K2IPV%VDztv2UEdfumxNVcGhe%5;szw zuaX~F_q$EJpM>78k!}hTrFO7^}X*zs3CinsT|b!zeU3e|Lw$PQ_aEk`80C7NfPS zBz+9Hri16WF zjz7Rmuo^4`8^L8@Cs+%{w~`N74#p+%yN&VyQ^8y?8(ahyfmL8RxCX2SwIkrI!(Olo z41n=n_!qn!Tm=?=z1iph%MIiniGQ^%%;%!V;4Q`~uyW5Wynli`FzzVi?X$(m1mhF8 z@EsWPKXD7+n?c`^{5}@{pS#6q1zSdMF;bGTKXZ#Q8SESbPkxWvV$_0pSzC-D$05If z-(dWc@K2?@z{y|+SPbTYE5H)40jvaffQ?|{X~+dL!T3t_22;UhU^Z9_7J;o`38)Rn zPB0#91XIEIr?wc`U@BM$RzJPPsF2?)$WMMhOS;q1=Xvx4^S~^y1k493!4j|ztN>fU z8nAKY7NZI51b2Y(FKjV}o`L;U@W8y6_>?%KQ`j zW40RkVBQH^jSes)bu05o=zlutz|^z18mqwQk(>t`&)aGY%fQ|-TbUn1zwuj*HDKNa zTaCE$(DOp_0rM`|YE*$mmvbI0zXG|VIDgevBNL3DvDGL9TMCd5Mqj_xXa$pQLhsR} zpS#s428-q+2Q0aLEAukQxpS+Lo(ca){07Ux#4+gg2=c(BO5}mn&!8_DXhhFI3@;q= z8?1gGyDlL8U$^pJQH<97DgK&>oPTg0)HdSJNikXqxCqPztH3gF4OjfR6{mC>`IjN* zROI9kKfKdO2aC=?9$1prX{-XX&n7+CIii#Gr09EIrxBO}FSFAq1M|jp^34j)kLNcS ze?h0QEEl~dbsEiJXEyp=LHtFXMj@C7E&~e-(dWt-trpA$^RDkSs=#Kj8O*p5ee%c; z%m)(}qvv$efhl18l1{#}3Bl z%I$?t_C3SS*Rb~*^4kvYTGEgGf_19+<(QusRn#!OAPP@jV#ynYPV{F68%> z+l--LQQkHq8EgSF&O}eJ92|N*a={evkXhS|Y_O$pn^6vC z&)&xOVn`3>fkogPummgxTjmj8M0wvrJeUNQfi3r-_f7Z}tOMgqw;74Ei3hX5w8h)_ zJ`8g2!*5_?`8Ff1m=OM;2bam zECsW{3NR0>28+PeVCv7du@4+PuoKJ%huj7aOaNQJ6tEM_0Ha@`oWOXn089dl!D?_B znEG?<1{;1!eYu@}sCJvN=1$_@*k&}Azyn*s2CxfET!WsAD5uZCdyu=CdQpm>|Ak(Q zv2VBS?Dqv8u-z!U4><|jjU8a;VcXe1i~N(ebKi;H;E?T!AdX>Tm`mdZa10*uOK~GJr{Y)z^d&=CRp-2tBpxERH~AK6{OEPWZz< z{)-XVkAOdJlz-^hz4o|yNU?U#L1!Lwa?)YMn&~sZ0CE#0!a7pH9RB8a{>8|WxDo!i zb7Kd^E%c3z^ZSP zBZO(|EmoQ~63LOwpXj}6@(B5<)tmoA#N;iA_C29w$SL8AekGT9KeS9}JB(1&JQf zqAVW5mE@`X_U)G6DDrzCm_(2B1%n~^-Q?tFE1}$B*0p$+BtJMq$$x2x z+a8gBXHckqcZ?l8-jVvJV5DzCFl5P>_E3cUtQ#!-m3XJz&v)wYa(GjB!jpPe2k!=p zcMM@U?0PVJLA1V6G*j`CeGzwf(qFHVhv->g>sbeH zp~V{??aIfue8GXEP3Z?N^j#JV=y&NVBgrS4H1FQ3@?rZC^RV^wZ8Y-{KPSU`?KZ`G z+0C1RKkm1b=bXsRfq(n$iZA|hkvhuEqXIWq($AKcqia1IczPS*%{vJ){>p?wMwvel9}jzF?ew zjh!Uax%b%Te`25a{W=)w+iHg%wL?yMJYmOuXopJd(C_S!Q%~v!vnSot%I>-Da=8Yx zon|B3bZVXOAG7!e@8R;(?Uc{WW+qZT7ulg(B7{B(#_10#J4vGJcF?ymc-~hN4C(LM zr}fwEpf8>CrXqR#FQ?AD@-t-*xAErTlq2mgq}@sVq-0U`H+IPJ)|YnNieN}TPjc1T zk=jK*QNL38T)K}tpD{F;OjRinuO}#FC8xTeEZ@i7L;3|aQU9S6JVW|hrKnwde33#g z+Pr7&(3^JXIy*GO4o!~`vTN;3PKss8QS3Lo8?Rctq3j(x)NQY{4^{ADqbhg_y=IGl z$PTTuLrz_`&+2E`W=C?6?*%)ty6TB{)0`v?_UVs;q2K^X)LCOkI&IJQwH>*KElAI` zgTD6Q`H;|8!8pCzAzD{&b^T7DZQS^&@>enblf$lu({Wd6P=qhv4p|*$3EUjgZ~ePU z|KaXtawokn5PD&=`Xgy_e=tQ!=x=t&8PC1rbd&D{PwQ7Zk#7ehrx74a^ZJJ#f8L<< zn61=s^q7GiGCr{4OTqY9wsP61_}l#Igl)HPTv!L8s<3E#O)zKQKZ7CtV|#Sy3vo-xb{}$~yxUY!YMy=7_f4|n0v+fr0N zDJ^1mr&7LapI&Q+oH*xNZC@|+R3~w5Fo{0aiM*3Y(|ogjL{rA|;*>ugRMAfTkozd< zYpnQWFctpZdwb;L?>zV`EPl)nl_0159uKQe_O;(9*LHRD=hUa|PSuh7K=ZWz!@+jY z>Sd+!+!c)Uy=;fJ*`Z(9p`Y5JvOb4Y2}*8Nc3Rc*N?flY{RLGT5cPv47~0ngfKvq7P(-IqdvyS`aRq2~maz_u} zDydJ?g7r!4jAty=n5+2jxcNC0r_^>UUicaCpT0uzuW|EzQ$+r#AYaO>2!7l&#lN*1 zUv{)s_Z!RMEw*?I-Tv0^@C(r_e|Y;|ujKuGkP>M7S^sE|@I=pccwgMCct7#Ec?*4^ zil%ZpVPBR^&Qts{+L#=++*`Oz3{mw(TGM$}(MvtcCfxz|sB}^8axYpCE#0Z=x)$2y zu152!yvs>H^j?*o*Uint&i5kP!{nfVn}PxT45_a$#UG8N*UDA;JTrBO-oB|qGkIO` z@+_X%D~Fv=zVe31ON!?eF^jj%WQFj2_nGoCh|hwTa=*&=Hurrt_n%HbHN#v9x=cmh*9A2w44_mLBvHzK%+13bJTIn@*gO#DHIj_)!oadJ-IS(l@j(wM) z&n2cDvX+TLMG$-AnWxS8Kb7uccRJrh+ka{B9 zg-x;kR+C=d)0rOWE1t@*+JiDj&}-0!#1Kb~b5@mMRFSzbk?`|3TF?of9+9}QDqq>P~+ z$c&8$mhxIjx9(FnBhPG$lcvD}gNB7#HdBKoe8*@nAg}gx@DtVpm@xXP+ zyEB+VKf$)dnnoAV&Ryqqw!Xe`q(QdS%N*L=KR;3OyY&xY{f}JrO>@k2<)kZbR_VO< zTasTr>5ltUr4xV2Vf*I>)iapa;*bk+4t|V2h`qn9bmbx_G@Y*yN7y&rPGi)UIX1s$ z`{`K6Pn~w;(Kb_0a)PHhL92jd$}d zmHIl<9Cug3yVK(R(#`Wt5Tfr2tNkQ%z7hWLBqjHx?)^lx9xLW6K^Z{w4;Wt`q4>Xa z^DmLn@hByy+TH(4JJP>WewV6u&TeKx@k0se8c$N` zM1MK#c6+r_RCp`lX(uaQrjR&n9+MyPJ0ATT;bmI9>#c{>4sR0m&8{iVZLwc5VO z{ehG0L5E;9S0RkIV|~w}qxi4=5MIr>T=`F2DTnQs$;!{-|9Ivos-{TI;2Dg&KJc7N zjR4Hk=6yv5{H$EX|C@?-cG0 z3wFm?sK*< z-HOyMA7eyf%?% z7LWP-sR;gue^C54j#lxupJcs+evrEJka}iamtDbtGE-uI9Al~|!NE?lbESJ#gX9qo zcd`@Q(+SRU)HBO5{&3cVY*70BVOV$lbp7v6>Aht8N)HK!6y!vupA^nHPO_!8H}&h3 z)RyAM)Av{XPPgl4kz5uhy_N>A1>Vms-b7tehqM#Mxw?~= z)qpE5S<~!c`H2H#@NloM6ZWZj7Vv^>)zom|3c-UNj!T zH-W9|7gJv5VYjdGsv(vT+XZjf6{>uWjdk&SOlUfHpZejpK_O3a%5Brk2e@W)3mIED zql^e4tENyzw2~wFw%<&p#|)*0Q%`vQAdjAfw-R2B#S6H3mo12vhoi!4gcmzY$?L|W zzRt3EUGQ=&-YmB~?tdlU`NSt3#W#j5UO~6(;#dZV_G$wCQ&nuzfF_V!-8yWt+r8x{ zIW40S^R(qLiF+j&XSXBCzmohCEcs?ztW5i z=_jWyh`tSS67i|v>-@4Gmx!uaf~r!~hXj$G|Db|<$EJKqR?^mW;1 zoq4L~?6{u?L$;wn>v#?Sh?E8Cto!zAM zOCr^RRi=|fem(Mk`;wCXhP+LkY(}S&n}$j37SfAE`G@$iH;0 zlK-Mx{v4XaBX%V}+$mJc>(U6FLj6M8fE-EurJley5H~8h@>>pDZ}oW1D$undT@0Q@}22I>$#nHK$SCV2*kreT`Wo=A&n63g7q}d>$d@`S&ov@#}4xj|a2xy={k_ zY;)~w_4Q8haN9jjzIwhyN)A#gCFHw4QRUn1xrVIYblSmzjyQbhyo8hZCZh*l2D~>s@Cx7^oV4?N%i+!Rz^j4xTMxVz zczYkQ^L%4Z=97CKc&YGy;enR}Z}5>j&$k5LB|G79snS-$d*0$*=Puu?sV5_)Ca6RB zP4EvoO67ljBz{IXKQ>jp5KdWWjIh1AjjJz;WK?uY_OM2YwU$;m3QIAA1^YtPlJ&_=zWYmtO$Cybt{4@Q0*$ zmtPNmejoT<@H_gzPae)({)yi8$$`JdBVVpdrSP*(Qt~Id>s!e6s~X;;9(YagIy~^A zPiHmo$ve+C8D6;uUN*eXJ@Dqk8=kuJd@JGI^$FuGuT?j11|&K zJ05ri@RCm5dA{ZFW?Q`J?s`B!INut_)WB=uqyFM_jAqxkER}XKa2VN(<<33dV1lGfhF9l-*91==r}FPjUUUZIBM-b}cz1Z< zWy7oWz?%=x@W88tcXrm!?U1SVTRreP;njHHC6ML6Jn*E8IAi?I^(%lf*8{H{-YSdN z+kH?Cyxq@N`S!+Zfs*5a7dwjgE_T9`el8WBHbLb(TUFDrc}DBiCG$)Y|MTF_w)nm2 zSqg8p2VOP2g91CZy9r)_2VV4O){%MOCBuumVCVT}!<*)THy>X0PIx8wuM*yni7MY& z`zeRp{eo{26EV(%BsD=V&ta?$6J)Nqf&sExi7?q&YcyKT)eCjG9Sm8OU_Y@jC&}x` zHaU}Wyjtn8teYP4K8d5p!*-U|egNd7);5bm>fwL5Y8N@GIY~nFdDfQrnR=cenr~B+ z`XcF1!SmKMyTtuH7&nc8={T{Y6FdC3Dmz{}#O=?QxdD;KJ!&<}bUXBv9daH+*vlF8 zh0bzFSvaLup3Sx&IfTA6vdWGPdF5lhvRww=CfnMynY^Kl_NX<9wgX z4td|id7ONot&{m~3GD)U7wP?vs`N(;cBS`?MSx?ey*x_~d7fdfE%*J!mVbh+y;^dq z#A+>I!C00rKc(_}<}i1D71ST)cPTmLcL^!KOGp_ZA*Vv$>8zs**>>O;raCb7D5Z`B z%blQA1R_d3Ns`c~!9pk(5jJIPT|P|M$zKobkYF&_|yui-*E<5CG8X*f`%zT~aYI#V@L;mb{mHfkWmwa>mkW*3bHAToHKJln( zgZ5eoYyToSD{HgNvsPBwh^;4|W$&we#<=sDgB@=M^|M})5{s7Ead+FHxrCIOW_c#D zxbo8vl-&2DT>8s z$(6`C_hTg|Ziq_{AKvgao5{&u&rr2NG+7sn3<)_4wVlw~AWv-{pya0lN$0bU;d7Pm zQEvOM3bS9{yD}3>y~-ioytOJF+k~5kU9WuEBy=*b3})`@HKgw+b|FdpT7&$H+m-x# z-F}twwihM%7MS9tyq%C#D|6j@^aM?7-KgZ;;jTBgpr)!f;>$;EH6w+jgHmRia&wS7 zV~dhI!!5V42f2>AQY$RE(r;HI_nj}4+~;G|3CFKAK;MU^nqsaJCn5X#=~L^s z!p}N9Csd9UX;(=sqP+EAD!+@n+Yz~4sfH|>IPK~I#}26<^O4*5wUWE9yMFZKAJz4X zSDrSF3@;ViQ{~8SLjGFcDAPe(-R#mn>=_S5%21@oNEo37p=Q7|Fn#WM^GA@~1jEZ&W70cj! zZoJa#q@kwUoN+zx3rBXC?Hv7FH7>(01vp zV#o8z%8tO^-R+3%V8_)?=y9{~#794~L%ZgzBgGEs`znjbPQNK=Q4#7_PU1fFEM?E8 zL2i4d(cV=>7CrxyD)DQ{Ux_!@{U*@(*JY@D_jLC&>|{M*J8~U6?2*OQW+A5{rwcjPU8dxCy{=3CsTXP5134<)7`Go~U4R-7h5OObBwrMe zaq@iRd@@DJ`MKMU@NtDoEj3L#E75_!8q)tHSEWDPonH1Wa>iw&R4R4f(@DBtT%ppv z?5=OJzeF=^HS~1quxeO6)pcixT5YGTkv!#kop&+wq*tr_>fQOt{+3(qG){iKhwPP$ z*6oq#RUgc+k^Ih>sq%Zfdw!wy)2S)Fhwe8uloD0;NyyAk>O;n4)W9$;k;hc|IMKPuHSlUBdpTw<`Hl+~XwPgNu0o;mEREsJY(K)LOllS&7`F zJCxk9Zn;v=BaKg&n!b{H;e-|kwN-MvkUOhn*UHU9@9ayNzxStAbNj5*2doLksWF5( zu@UmB!DP|PtcMwwYuXQARd(I(Zl7|0A8FpfY4=XQ@|Z|eht!kh$bGa{$^FQEeUte; z=lZ64Q>ih9N`}hJ@_|d{E;@5byV-D^e4E} z%eE(<2pO5m*|-K0j9ZoG7p1g+h+gkWxpZjN&F_l5*ZLeFy=?tV_PJFQaTIz+aqx!jX%QhJ=I)Nu4y z+mf66P~^aS&*EK|poosXvJZt+RyEMN(GEGCpFOAwZnG>^<^ODAgB@~u$=qO^e$Aj@ zFyzHH=S|4q7MbFS18hTmst=J!bDmte$J(4$a+fiWQg~!Aq%U*k^PSV9?97{%2E`IObYAWS3gV>owM$ ztq`BJiO&Z^`t059;JNz*gTB>vNcF^$y3>yPl^yzhFr>C?R(h5KP3V8rSxWzDySw$j zjE1K47w`T+6{0w3f+BdCtg3E3_78Z)mF@@XWWi}F=I&2cJ!#~-o*$}g2+6pq>s z+`P8yW-q6L*5r~9LW0%^NMcV{{*Yj~BWw?GjhSIK|8uV5z3sV5kAvOwe7w)B-|rO5 z@s5A3*V?2koFSLFS0OS*ZZ&c*xI@X6y(ZN-peWBF{b4=&|GY-&|97{)eHYN)e`h)aF}`iVP{ni=@?s_TPVJuY^OUb`sKTlQyWZbZl z^yO<*`UH3W%vC;!rQK!avp(WemCsGx`rGk1NaZ8`SNTYRI_nUeo>w=ER*kq-K9a_H3>hJ0 z`B~;$8qwpf^-7N__j}Oc?-APOI`b&{K~6hSmjWq|_f>r$=)A=zS;}=LV+Q+}eWCJu z!u{T&>_g-~sF4k8D3sJW=$P)vzf|1Sx!&`$H2aHkq#B{4y)Fnh%xw8+$GN z^*&1ezufi4H;QspgHQ2)t|?zi@7YMDca`0fn471on!G-k#^>CO+99jOO8J$e$B79_ zj}`9u2jBVVp$bs+xGpGDf7_`r_6SBF?C4?FBC`m^-Y)X_;82y%k=^W_fIk-nz34n| z*MAYIU$EM1So5%UmzB8JZ8>(xsz~wZQ6i1@Sfz*6Et>Zk%ZZP(;>-4d!!g=lwwFF~ zcYg){hxmt>^T>7ZD$Y{r3x_D4-M?L0sxOIN8l$(xygl-*k@e;$0#uYqOyYm^O!66} z(svx7(vS8xJQt;}J%B9CL-b6Br%h43pq?2-Wk`A}zC(x{cK(3{gG=?r(Mw{M4$?nk zoGV)V+0Ol%~aL8GX z9PMr;C+Kg9uO>du6<mN4KpEA-+HNs3a(m#2mKX;@* zf25siB&h%jwJ&vN9{mMZ%z#260jnQCfwUWjJO z9+ze#u}3r;uk6VPNre|i`O_oX6HFDfNAyT4)U@2iN{=d23sa9PO^KPN9vS}O8Kz$| z{DDwCM)>ChC5}~kj5Je?^AF4Lr;uvoPEtu}1pT@aJ>r%qJpz^nw{ASdm5##NS_3io&{w4B$|3-?gYqE88O z0{1Gra`#k*+3hu?z34ae-0q}Z)QdikDmigVj9DLBh_AKc8;12F|L=$PsHezJzJdLB zUhghHgZK(7zT==?i~4ciQ)YLDcPqgERb9QJ45v z(VlDhTg_hse{1+_=C75%j;O2P=$TQlM)ks)EUal!q@PXb3NP%VqWr^OLzh2{=w1m& zAY{Ryg@a3d((x|k8>X03awG3qt_`cw*6%dGf{-mV9ed%muS{1)V-Y*F&l`7MXU zcM)IcicgYrMbslJKG@Evj}!dqw*{M#nLZ7kwl!RDxzEWaKF*3ycejfPrR-C%c)zhr z_P=1k(4`0HPelEB^jo9f9{q<4xHhZxljWoje4*r~L`t6?lKz42=^II3yxp=lQu>|b zAAb|=<;#CB|9G*V^d0{S_e(1A1;lGzDn6H>9Mt2bKCU$j^b!6<-z5J~YE2wn*AR8u z^m8TYa;8y#-Q{8jQz|WKnaw3Qz~+HS8{^o zoJ4#j@rhQvb=xE30QDJQYX(Gk_3)0gcvma24sZT~=&Klo3$GL2VvBdSn>Uw6$RWIh zIhyvS#gld|hn=tW{mx|KGT;r~L+M@Oeh%WB!o)=IsSei=_(kx49IN<`ick()u6$Qj z9tNmrlV1t{=sgv`*@_S0N1JQ*ta#D85&mv|#qUXP;dQ|~&jT-MF7G{Ayz|`o`_fHS zMP3%X*DPMTn|F)j*CKd>_EP%wR8Hcjf&V!YDtWOu%^lz!r$YIu_@-by!bF8-Mr?w=O;hQ;s69+4Y6pZ;S%mH&_2 za(&F-6*+Q+p9cShKJW|Rr|z%hQxxW5w_}Z#e27XvPNp|ZIigQJ z{IiBC`471H?DwXtNA@u#ed4o zHKd>ORhUevMSVCpSAjL z;YHuZIs*^9WOyH1ymYs`kp3+j-a$v~Jm2~7F7m*ug!dDR*IT~z@ZRwtuM?jC$ert# za69XYEM9NSfmNH26myt>pG}9TPqC;4Rq+ zPx3E?_l3oKh2L`6_C&be)fBTY$T2(5zXjg@$M()M?Z1Qf94y`vcmH9IW6Vv&(MpYD z(%|oLoRaIMKP!NLS0DJx;TslzPB(p||Jy&j|AT+?2}&QU8*u#R%V5ADJLj0{o8zi3 z_-Cbf=O^DuJvveG_i>MNee!_t;V^x2;O}>`cmI^aU)l$L4gB3wmHhXWSt0hy^M|Ej z_O`?S#NzMO&7Z%5KQWA-uz>N(DN4Qg!e7@Ttt7(MS2=4)lH_gqn`XkA|3*HWkceUFe zSCGB=99anvxydD(HuWr(|CMgJ*E##DXT$rw#mjT^xK7?+={XY;i+74!p0!Rycs1~Dws>RRJl}a{Rg-dVf%iL$cezgy zZ9mI8A#xFNuDOY%D@Mc=PaVojvAM2B!!pnoV%Hs9pAJMZE z-hLS>-?e@v(AHDlZ`3RN!4@R^8u(ok75@~yJ73o~+U-a9?eI^$Nb#>5)SVx#50gb> z<_X~^FbJ;5QT(CSgiNSDy8ah=N^kSC;IGP4{DkQ4@^$?^d3I*==fiKzSNuaF>ho77 zOdbA8_*-Tv{)Z9dN9*_513=Ng34Z;JioZt${iF4|F#Tf}@!a?p#lLZHxBdYt$`AGq z)h7-9*u@q-7Ue6qem#Y?^Hf}itK#qZXy_|yl@gqL(T?c3s=s**eP{CXu&cv&i}$w}MRe+)EclobRzK?DpY;nR_pJzgUBAHQoA$%s zSQA-ztJvz7u&;f0x6nvv|wg*C%s4 zmKrwRsE42PsDj)~{YlJ$iA^P<`S{*>|^H@!PuT^BVjggthAo_^)qP{3pBd zMgF-qU+P&A{DN(Y-;>{kw;bLL7H>Mg<*@B!`Khca5ndg4zn&a&P_%B&}FZT<};U|Bo%6UHop}9^uxXLYv3Pugm->B{LUl2^AmoeX}=z(`2R4q z4C&u)qI+8rwAQNs@E<+eJAXd>JC5sencph|| zcll}XhaK;oUjToP6TI`6!{68kem(rZq$v4b`sXhAb5B%!Fa2k7Igk7Mz|Vm{^Ca)` zOX08W1HT6T6(=kCpLT1Hqv=n~rTKRIYKK4aRK;(L$X_1TeiQCzS>oy5`C0Je(-i-+ zi1L?($)6AZ%d-{V%lzI-_}8a<=QqJ`8{wTF`vCqt*E>HA{s$R~@1?#Kz`x@>#rIO* zmc##7ANcj~ZyM!Yei!^rec&fQ$n&4kO1_u+lLLR^SjG2JKTF}CJYMm=)SnvoLj&IR zX@?&*N%8OQc0H2$__|uEL%a4DA^%-*%|Ivu@FAkHR0l)GV#s7`F-{<>u`aHYa zH}4aQ;7_|v@n4C=pB>Jxgr9JSclnL*KU|>rHId}c36~$eocW4{iodAaxL@YkMud&~ zQ{f-7MDdT=O*Js*zE}AFuqWE2J?6pBd{FTlc6am7gMSwb7@cu*IsBndD1L5iB>sM} zq5L}dbAGD$+xLvbUl}&P(Fy;$8pXe7uSooJ_6n7s^nYBZ-&FkKi2gY}%s<)i=f11> zheh5A{A{-nZ>8LjwU>Q5g0r57pw?GfwG@UZ$*F8WMS{6izwpAW<8PaXUdu2%flBi5h! zVfCjI{vl;WQ;L^F>t{y%N^oBa64 zHSN9^6#pdmJUZ_W>KpCpOp~7h|Bo*z{)KLRguk~v&0_M4;2-p|;?H&02jQO*u1}@t zQ>*w7x%C(Rg?4o? z_#NT;=fVH%LyI5DpY7rPEQh~ev*J&3>m&B=74FYE`1zkJ{>_p6d2+Zuo$x=|p!g5E z^%wb*!u^@_B=dCJ6yHnz%!dEZFBRWQ{VajMua;%jOE2}a8vghpitnXx)a(>(0{jddZxJ@e#5GJl=$|JVn9 z($jo@d7^ju+3-K}$e)8gY0t3#Zfld#APTb3e~G-%wNze+SP;!yV!pZlMBa)R%3Bd} zywEj7Uh|1w;#;au>mh!Ow|GtRUPaz%ZB0gVAM?J-TOPKqE}hK0Q&+IQ;9JVOioB!O zeLHq1KTCi8E#*OQT*uPr7`;@(E$5E_;aWG1H6db^BbFi z&=)qxo3DRg%HYv7@E_>Z-9Bzu8?W&LDcb6#z9+} zjKTK{JQpFYN)!n=C7F!M$Hxixb6 zA!vcfT{wt0y!ByG{y@GzodE*UhcQ5K<&eH0X5k=}$1Hzlz#kanPgi-YB#%{{-)tUn zRkXit-)tU5=tGmmyRLt!mo_mnc z4KZw!T=80f>>9|soV*LIycf$o*%H}gW2xMeUGGoic5Eo(;@Dq9Zpjw=mgq~PFY6&* zi{?6!^b6KsAybR)ZjZTfht;>|`nIV~-Mxhe+qDF{^rbO3df@2$`#i8Fdf?3R!0{qy z2!2TZCG~L7M@Df>&wg0IH7>yVpq{poU{DgQkNQ!%2Nue4jqJ87$_RgmB#hiC$BP`_ zcn^ZG9bXLp70aWv*{~e`J)2bLd?{HpjTw*&IWrhV-SrOS;93a$;1!x(s>k$df)+j!gbm64y#x zu0)vEfZzrk3#D(n)}M%v&5bx@-yk}r1$+mt)JNYI8n5KB_+6?8Q>1@h?&Eq|%eaO9 zyjh-oas6EEo2_mF2+guXqX$C1Z_5XIm;S%#eX66ppI7<^#(4*RWCUdGj5)sJRyA~k zNEy-%GB*ljJJ}e0Uaym~Wig?%vc8}9Hia6_)i3RJCqNf@a39E7-j(p(-Un`eAGq_p zb18;s`i-PN5;*iDqgK`s?W|lHV)WEOy=Bo5RxW&e$UE7$z`rJDw7;3jv=!-N9x%@gL-PfHOGALAG{Nbmgfdb^%=dMy{gxP<>gFb8fp4Mio4<6B@4UBtqn$J6K7$#^ z2%KQumy%?fd5<*F{GW)}JkFPKzLv0-;ZK|+XA)u1j zvup^zzsn6ik?~DdCiZmt@4cR8)ZvG#|o{I5A z2jG;zNwheeHRJP%FLlM|z$qraocQ3pfi;JMCPkssl!-D$GP_$0Wrf1lRHn&cA|V)~ z4MTo2^6QYFF8V-S>Z1UzQd@PBiTpIT?M&u$?4Nia8E&q{T_RlH*x>4wMEPy5WZ}Hb zOQgXca*{JgF`T#nanZz?K63Sy!8S6xyQ@ukrKBAiB2V(DATHh&S4~`8NSx%mnz&fv zstAYFV@&idbE+#pr6S|DVAU2MMZZZokTzY?27Q#@-ABSrfm`n8M(}4Q+#I+o;5xoA z+ZIaDlDU?T2yV~KWG0(>k2W{;9_KI2^e0*xs{Nm3erW}=Rw65xu-Lay%H}eE9Ck=! z;^Rt@M5=wlC;1CU`x7ZUA(LF>?Lc15zaww7KYx4#d71Uhne0&Q!e6h5j8LI0PUk`bk^5lHb*SYvk!imJkr-rs+XH3pTa(?&~gZ_au*`!J7 zW12;z$?Bd)nzqdC7O6R0ZjP)y;iX(_NRv;RM8a}NTmx}M#HC9FM+Sc_#8nXY?_T3Y zPBG(y+f{zRUBWcNIvGN0Z!yNS>A%=B&cPtGzwV?d{o;jqMo>qhSjReXQ* zXO1zypfJ&&o8?cR?jg-I4;(Lf{|6lEwfHppUDnr}MjP+u)1}ejKAqs`EDxxH&2fa^ z_Se#AJvORGXY`mT#2GzuLJa*bbCgdfH!}ViKH$@kit!(mpYrL-_qhK!eZZ%?(x-fI zOv^rFz^A*?r`c<$uV)VUbXWRx#RrTJ(*}IHD}CDaA@l8L4fu3d`ZUnQJ;&JtKHZf* zt^A1l_j3k(x+{IU<74J8(+7OID}9>P%>2`c0iW(FpVo1ITJb6Ct4DIb-_tr%=b3PZ zzwqkbCON|1((&ElnW|qG<)3q|^;O1keAjTAzi^J{)YwqVU;f{jZ_Ho~wHG^bb9)n? z8}?lL5zkaUneNZeG{1g10c*zlbFcNB*0dq{AIu|;>fbhWU_;WF{%u2b3-dMO`nL^p zK4X4=eE+r~?Q@ z;g|Jq8yc}8{qp{6!(^UGEL+cacBV!eOIsg{4juOec>3@4MezUWXKg&g#J8R8e1A5V z=ce7B_bhQe?@4!__w@LDtj8Bm?Aw4P(IHd+J<9nGK0{;NF8)f|$aw1to*#Gfm;3n` zPpX5@3VVD+^?iOmru>z?34cu+@R!{HmWDQf(2Ak_RnmdKt{m`}SASJ+#$R~@{_^Ut zmM!?}ssVp_^;di+{+d4EFR%W}_yT`jJ>V~|{wmsrzw!tC<<(!6+ws?o0e^Y*SK|)+ zb%`SN+(}f+YW_@II zbi1#MFvrlBXEIBAvm@;B&42t%rnZaq&4vBjhLW#XyM1H-wjuLto~Pf`zio&$cusk9 z|F)q48_MVQZyUFXvT(&JNvf{m3ov`Skk|3 z$Y&$H;w_`*MVocXpWue$Z= zEhudfc64G#;GRhD5V_{_FZD8=Kjq(e-Q|3L;0k}b=u$i=N{cS--KXZhxt1=>9=qPr zP7m%kwlv04%{ch-z#Abhid%qjHRG~}!ecugT z(sql|)|7uYbXkoq%OCh|=#ssAl$N{fyP-=nx+FdP-O#0Ak0`D6k?)2sJJ4n2|9$(q ztft>BVe`qt$Gom_?RBr8ut^f%5xM;~wXRxa#+^Y$I%<#8>W_Dm%>Qk1^M|j_d0>*9-iG)BU;FA+{v=qqO0b-+(Pw zo4NG55mT7)|A|GGEv?v6`tEtwB{Ax4_k`kqO{cKzaO?_?H$E;JiZ^c4BaP6 zYkKkfVM`0Pq`dU~u%&9>D6ORW`(excc*f7a{C?PyxnGo){POq1miYanwBld)e_LeE zrWsorUyU@^5#bpZlM=m*$HM1q&iCi${TJtKRvZweW&PH}Gg?n`Hk1CnIh#B+XOlWK zO6#bNq>JNI?{hYn`vb`Rcjs(s(WU(N-wj=|4rIJs_ubHC4Z1Y_@w=f*-a+&yuYWgm z=|GpHH@+LX%s-g<#y@>GbQzKmr4`hFH*_gSm$NR-y~4!U?+1Jj2&n~6+W6#RGRY@&b2eC2!W<>?tm(6f6XEVc| zvuVJV%D;XCw&a+({8#5}mM1b_`oZ_Zmi$AxKWO@X*phk}^R*v;KWxzsr+;t$e%Mlv zEj#}H{jg-$ne6K#ZU@hgAPkYYt2Xg)C7l$upiO4+P zpP6ZHV#^N0rWZ)AI`_BNBT1_@CU~Bnpf}A`h1o>3$VNX z80M4lfz%%(`iCNXf^1)L5h6r{9KLjpri;yHl*>C$SW{V#hkLBOy0Y5bH z^7^m=KWHt-v3_g74_f>2QQDjVKWLpNL}?WRe$cwOP^=#C1K;c6dCq_zwAhn*-(kzZ zbu&ISN=qN`gO+egl$QTL?uS~&lu4&@KZYMPPw$CN^E~Ozm&s+dVXwEE-&w4rb~?_+K2-!`P4&V1hX{%yk!Y^d4Mzip^FgZb_+ z`?n3nXR`kFU;W#Lj5MAHb@gu>hMdLw5MT9g8|ty4_3Qp^L)qD^&(S{iHrD9Nb^5<} zjmtiV^#oD<*9Kn4(T1k;KAG=h190Y2m*~8G>3T<$uK|bc`519#ojLd``|BJ$Ye;dy zun~+O@dvLfIR0?WuixrSEk~Fl5Bc`c+W|8_Q=%l+&BfSq+2%xC@&*tzmN zo^SmR*jYY`^`Ft-|Moe5bd;9)KVWBGCilz#19oPOiPBd657?PHmgfck19m2i zEDv!165GFR$i0B~6Zh=jHY81CKSqE5wxJap+V|?;Hmsb)`h>mvw+)5aJpbFLf7_6H zA`B{!4a?&{-gRrNncvOvFcYlSSdZ{e?q_SPSxTxUU(9+je8y!dbPhPe zocQ_So^WP#L$(+%@W62`FOMi^oH@5XKDc(B@#NTDB-u;uJ#aLsV>x`ttaX>wv3U{f zOm}^7D&oTjmx|w2j%NC->=O1j+;3O4%l{3Z)m_SZwE>@v^bZ-~4|(yWhkCE-*^bM2 z-+#boeezlI@#^Lv+OF?8{xBWV$D6f#q{-=Ooo3>-`Cvd zOlQ6NP@bRd>h}g7?(LaO*wX)-{P`ozHwMP=#=s2E$tIc)uB03iua4644*UjeV2>lp z;TF#-{hOAE4K3JEdr<$jVMRXI_k{j!L%|H*Km9@fwjt#j_R~D1f7{TB4JnEJ+lE!w z^1S=d{%ynj0_Fz~>)$q{&*XVVQvbFgdKTleBl@=utFfW$$o^|XEc4~1*Rj9jFxT^i z|76Ym^#1xxM$`DrkG8y!`8NC^&l2qYToy-q2jN@~Pds+v^A`O2Uwq!8N!?g+J@4!7 zvbw=@fo?YRmuD%wr+`0J-9URE@CWyl${(w5WWCSPyQ=T#|Mg={QIs}+z#n$~XuXO4 zW56G_KX%Nf{}}Lx?T;aI=s%7b=s$w}>Cn0K9|Qid>&LKp^dAHMu>CRo7W$6?f7t%W zoKOF8>_Gn^{fErCPQI1?1AlaMyLb7|->E40FU{X4+!m#+NamgAT|Ixl_?w>fX8s;0 zNjWrQL+5edfDKd4EdDF=_m#J^zUhSiZ9{%B^OY(6+lJ&jc>ngq{%u1CHYAY5m&IcM}=8w&AYD*x|2?}eeVD;gRa6&V#46%`c~Ca}w38{6(CDw|C2Hn!o0 zdR5e^XcUOkE`KbtSy*J0Q?baf-%2tRT&vhd{jgS%!^vtI78TX1{p9z3&Ux>>@B7|+ zUS8IQdl~QNbK&0SJm)#j^PGRrdCqgr%l*|+HXj0Y+2=gI)tM1l-c&lnJu&G9=sp;;+ZXT1Z7s| z&1{*a_u@Qx{>+xS8)cRh%xsytpGALPFtcTLq0Dse%$AuR#Chn#nJsfW$~-#5WhOQv z9%13k$w}|0twotbMYw0p)*5?@)zE4Pd}9@!z&ei~Z%(lojEy<+`R%%h^z$NC?poXV zgukP>3H@&oba%YvXt&MCZJ}7dCE$Ov?QEBEMNwTOHlzL*p8y$doNiqlqbQJpWSK8LcaVfJOWwu;3vt{Od3FpWC zGh1dS$}CaHsq&47vlv%O~vD3$UJ-*5l*f4{Bh4!ytJgtQ8j<+0Nu$qYsj*(+rjKi-0MNwT; zd=>W8<`W=8<#g-f7)5~$Bu8dD?myb%d^si{hwmEa%hB^S*f-ZYUyk~RuwM{xz8ocA zhyU<;=gX1Yf%)o2=gTn+IgV62UyhD%z@K}w^W~`eCgMf5I$w_Lhq2ze)!B0NVm?0# zIZ|%7J~P=6@AdfD?c#i0bew^&AwCqIz%Hpf{W_2TN{??{-y%=odXG=LoX;|sc1f8f z&N@$7zQ>R4sbWvya*wa>bZ=h){Yk?zsdoqVw`(AS3W4xG_aJt>QsglgMOIdy!T(?x z*=fL3f8nxC^;5PnEw}m%N3mY5jn#II@2B#y&&bY(`s(6D z>uq*RZ_L!;R5zU-@c6It_*U&j^S;FfRX=aH1-#v^_V}7k_wFsEKU61MA49zSXE25w z=Q>dpm$5SNj#XY6CH5=hF4W~3RBMavEMgD1q!a7;dOLN}Y(smunDiYQP7v^vhT%dN z?4+wC)18Nr3sZGCYdvKJ{5`Cw#>+&t6i~JBzLNAf?%!-U{`JECsP&cS#7#QXR~Dj^ z97FY3zWCPMS9;ObMj=znHfPt%j&C7;?Vj0HFE!uB{q{j;*Gpa(?ssgQUGg;+6d>8iW7iL$zc)M|5=@*?{F9}b=U;e=Cs+VENwEN4> zu9x=jVgK#H*;Oyq|AX@yUv+l9ZRic*spom z+4WNS6y7htV|LX`ZV%p%_?WZnMfssisqdU!^)dvRly6&~r4xSLfPKI2+L`m~l7DRb z)3C?75WjGo{bOthewekdkI%B|M~Dx7B38YaeU^5-i}rn%>yDGpGP4)^Y2Q5oe&oL& z7nh}fnl4LzPlxgh?sxv4ojR$v?X!&NduDu={g9#Se@;NXjA(u3b?{kke-`&W|G?Sx zQr-vu-cz%yUb6aOU;fb9^)dk&(tb3%>SgzHxL@TNXV*(`7vhZNQS;*);m?0QKZgn#eXv#ValAyeybon0^8 zKgap?;n`C!6wkNq7x4ETcww^Lj=!(grTUns%Y{o$YF+G3t1z`%mp)?AB2^Nk zC-^V^Uzd`3@P)}PJNyUKeCBC)v2u8<>a4goL~~g(e~g$4@$MeNdian{-3Qc#Cll|z z;N5-LnY`CLkMkn0IFt9BU*i3QuR4?W3Gm)E?o8gheueq#Z_ebsYCrbZ|KUvDGk)z- z%Kzm|-bcZE-ce`r-u@e`Zzi3|d--p1-iaNsXVaWS^J*__f|OyzTe}ZT`rY_peXhof zFn0BJ=IJGS497mUSy?nK1|#cc`>1SzeO$0iG7Lk8Z3zb^^X$j~o3e`Al&i_6w3NYU zC^F0YPK~&?S;=5T)nsV@9qgM#`!ZaAY%*A0CTnDD`Z83!fb)xII$MT}1MnB0?Q9vw zAj8&koh?Jx2;S##p0j1Bei8nzH#=K~oP(Gj(wr^BQOHo4?ra%)UvepG9TOk_)q!pfyov-{0Gzzo=kqM zZGXUc`cd0!g^M}wtKmOvuretPUO~&V?*>f!o<{CJ^d5F8gCBP$@5;;AZ@$Qxy!U|j z?Rn1Red{ZDKiUFk@}B)i%vTGY$@@5X_bzfK@10}Vk1TN}@0G8*l*HxERO&IH5kc!;sG7Lb5oLXng(DEWFJO}2N+e-Q6+k6jtqH+Ww4=95GeZT}lGWCWcpL;F$e z_cb|NhKm1lDZTeOTZW9+aK5nB*)ohlhO#d@TZXPl*h^n>whYw@Q^wnzEkllrDLr3x zwhTuh!?uThOzHBTZXoHrer+nY#IFXm{PIR*)pUjFs1z| zXUlLHG7LZMY#BOFV@k@i&Xyr?I_B%=oGnB48BA%}?Q9v2K!$;zIa`LFM5ZL{bG8h% z^O@rP#Q~e=Mp-Ltjg9d430ni-*xk1MeU?5mgRNoTvf}oV*Ta;o=MPKhHLd zY$g1Cmb@E$bCw((BW8&waCO+$mTNhea@9#G4R`~Yrg1>Jw3_tbZh`-PB+7P1?&(g8BrleFFtuG@b?`#Fgb3=_6w+!$KWF)e_z#!^!K^XgMZ^cc4c7q2!6CZ_mjlm zw;M7Hyyk2fg6A{kh-<`VTRJ)G!S^Pnq{lg1hU8SH_!68g!+yw6bB42JXnQkLc6gjE zga0i|89K|^GNiwiDatv{mfEYSS@4ywlk-c;A6|rVMAxknm2X zB)-SlG7Lb5jQ2WQhL(3>Kj{6=mZ3C*DgF;QTZWViv3~fFvt<~D4BJ2KY#G|$&6Mts zI$MT{_b_GfVn4Sl*In*tlJ5WndXFEiX+rU**!VmZAOwOi5biY#E9_ zi1oD3*)k-42F*)o)U82fRnM<%=M`IjE@1UAA!)=vJV zwXeIUO!F_Legyuda=S99=Wsut?{()MaedIGCc_A1=(y6ZuaZ3>>Y;<`;q{k9lcD3I zIFI6YwhWayI4`%(*)n8)4C{vqXUi}S8HP4GTZZnBWBpL+Y#FwG0_U?fJ6nd_T&y3e zoGpWL5mVgPIa`K)$dGisvt`)!Nv5RU=xiBEF2?%drjf}sd;X>S;9uGt^7E}dN&HJm zd00>1Vpj(BecaFIn-=pF&qs1w?mPcCe!d~dFmkJ18Q7Qg^)NkAPMn`_dp_cgYn&}Z zc>(qx?sT>cX$zP#QR{3OMj?Z*&e<~T@G_UJ~EkQuO3EuUiK*Y`CflXG(TT( z3C?GI$=NdaO0YluptEI2UW)nQtIn2TKV-;!$k{TqEyMbu!`U+Um&3pGu(M@I_c0~# zh_hul3>k(WbG8hfE0|LJEoaLRSc(1VE@#V-eF^NP?~d5J?%kf_nxOXvhr!U z%KWy2=PXa|8k}h&p6>``7Do(ie)=hA%iz5X{-vj#EknZPu$P{3whRN1A)(*dGPIQ8 zzLQ3%q8%aE}K=i~O< zK8Nz0I4}BD@-LB}@AdVRY5t`#$dK_HyL;^FCr%PS-zxpN-L5NfKin|RfZL0!91!*J z$VuhrtG){7<6dyK3^{(>4>#g$8ID4Rod=yQL+@JHOQX(~p?)3Wm;T^v8H(2Z$?$lQ$mhu54f!#HFZQeL!s2K=OKOWj+reo&n)!`3Ry4{^?xA@>^i zmlB*UgK{nQr_XS<4E>OyWxlgz*mfP_`I4M1LrDPlRi5o^8IrDtf9aeTClz~fWWVtQ z$i2to$mo8)Dk}rx7^Czo?J5IJ&CfRk83J##D}%b4`}yd79GhQP?pO2JNKJHOF4FBU_%-|zodGYo+y?VQ5$M(8Y1v`KHnWUFZyw3%aD90-iLCLvt`&1 z8A|e;EkoOd5YiTVRym!;~^Yz??c<(a1 zwm0qVg8S*cclShak9a<)Q1g-1HlRPOe$no^-C>@WJ$Z6SqRHUB8|&$EXUmYV4d)-O za<&WukYW2;XUouX5BB3KoGnA?z1V-)=xiBMJ_~{HH`q4#s}w|?5$GSq(_`_uK#mZ7*6>xa9YEkoiLaKHCG z&X!>iGE@YeEko=5@GmtxTZXbPVn6OaXUmYfohdo3&XpmW_*sgW4LXXcJg48wjUUFCck^W6im!)@tGUFps@5$I#;7QwC;7Qq2;7J-N@Fe7W z469oQtev_1k08G0VZ;d8TH~=*R`MU?;_CHU4=Y^$M=@XRz@DEi`PGYN(Hd9C{}}d1 z9yx{O?_|ohM^9n-AIJFj*eNXkx9~oS&QnlBv% z3B=of=MKGaYNZg+@0`)gwk%dv2HZsyABFcCSgylNIqcIu4w$6V z!1u5p`@I(@d+n?#{LraIxrQ~R<%X3Bv$DVwD2T4DVy(7(sI4U)e~Im~)lc%h;HA^q z3!V9qfUn3A{i#mPZ?I=#^|Yveci6^^4$Q@)S=lJC#y)OzpU)UT#!r&T|| zc>2_wPLHQfd!Isle9xRtkEc$Pe~9}=pPtj{@ziPM(>QPWqdA=(Po4Js2>#h;=5%^I zb(-`H?kjk9PN&CHrxnlQyhs0>PLHQfclIH^__;Zq9#5SnJ_mpAkLPrHymYEyZR+2J z{r259S)^gO+H$nwSr1Lk57;|IpI|>>;MCSZ;HOOK-*al~p!#Qc-_gEPTL)VQm{LA? zYU`k85BAr7eroHWb}!EF{^HcuLH$1X?}tup9c;tqMezAkTL;0PW54;Ar?w7Se!-OV z{im)D_9O1L^?wo1{cBq~@Ope~lgD4_fHjk%kZge=ysz>%wqj~&9Z-5a)*mJ-9c!VA z_&C|uI6}6JUoxfUce7JA_pg{T_`>XzZ3MEVkIYWldiG;I z{o?GDZTqj8GH`Hq%2xdw><5g_PT73F#rf?+vs1RrVcd`N``Ia5!te0@wZpShwo%9y zczO28M)z>^z5svXD=$vA+lhViv2~s@#Ej*8D)T*oe9zW=>>lJJUb6`Cn)!&=T#g7p zpU1a;y1Nhu=yng-;+CP8cDD>n_iG%VZ3xoU*a5^}jlDQoYfo2}x78e@Fhx`Azu4ou zoB}C*>=n}LwC;jAe!5C|5&no*ZMUl%ZOL_okn2y=mdj#;=|r>^6HSZK`CT~PgJ@8H zp3~J7R~>O(1zv)EFg~X%JGyEc#rd~WuI%Wl+}+aTF7RYD$Kf`Yy7+ugPQyIfi@DC@^Lz5_ z@5mH;0=IkekX?Q&j3FY+B6`ZSgL7Ok6=fJ=D}RRnAf^tQ-MGl6j&#rv?}hjko-7EG zf$MG3aJ`N0YMZ>exQ2MT>a^Lt$Og_5uEr8XwiVdGwnI^Zql`ej5y+SR8uk(`>zL%b zS;tqNS9XsNYAkZAtK_bqnZtp6kgKg(qtg^c5~T*lo;;QwN?x2+Dr z&guLY_Fo}mnx!olw%6CuM%Kx0ukVCh_5VgZyc$a`vkiXvak7|UgF`j{r46q1fcL!r zz@HD^vn=a`?CYy_Wu6T7wZi#Vjv^kx=+POa;9kI(XjpQa4#S9aP}@GMo?F{i63+ZDww?L1pmQaw}c_k{OCZs2FFudrH-8DfzTyHs;h$1c(P znR?!!DwWWI&G;?L^{_#D`|(x!jTDPD^f6Mm;Dg#gPcr(8{Wbs(M|jic!^OSpu2 zlPB*aUoVkdy=mA#Jv&zHSj;mlmhb32##IW|KpR8BWXE9*B<|bV{x;ZikjrL$U902a zI+n5WR}Y2dprDHZK%QtSALhEW>H79>8UQVW}bV66{_H?zyYUjlyzl9BLz_byIx18=p zrrVKMyk4<*{`bNk_eR@o>b9xd6l5yrGHLOJvnLiW_&)6C%;{>%{ZAUJcD^6;XUbf= zva_!~nx!gTbGowCu97~8_3L?a?aEHO%KZ@H(dTq!t6f!Qt4i+qbM4AbyK4O~;>+fA zWvgBFegyvCH_f#xJMC)hqpGrdPFJ?tRm#T@51TsIuBK{N6ocgbxT*|7SAnV5f^?7A zJs#gx)7e|{c>=ed^s#uwpTPX~=7W=ddpfAHS`Q!NKGaoQuPbn|*n$&4eTrDT;#^f} zgZwtzz!!A9p1k{2(~QL{xd`zFZ#lJf;QOSiRG;EHD7_f_o2R%A%JMLOzV+1Z3+4G( zAD-em@E5@UnRaTogNg;J(sGLHpwg=Qk}b>1mQFz-3w~WSTv(cqy0Ryx5$s zZ0!|$FNc5c-E-|~s=ZpuSV(F z_|77q{Jo)JJvY0nn@++#ThE1~E13fyl8Jx8}^v!1uhbf|Bu`Vz>65q@*) z@lxZ|Qa8J8t9n_}Y5%nz4N^+D({!D<5%J+4oYQrTcl?H1ie;OfhOW16LcHvU=5#$1 zx*n~>eQ?=xx}FJL`!?e|&WGo8Jrla_*`g{bADPqjOz1k}8u-KKbnTf5UAJC~{pgR* zwd6~toCg7IenA+oMPzExjv^dQnkb=6&xEe~YgEObH>c~F&~?_G z@bBf%>3Sw~-S#QmM_Mqa>zUAX!lx0Bv0zTuGokD1&)|I5oUSc>smIIa8>z#2YwujU zo{4r{au?1&7tZPWMC-a6YxJEB*gs!*aIz(a&#AzZ(HxiW$*POz@3ZlG{A`oenHPUu ze8apTYg9#qRb_!EP~h2GfPk0+&o+Eo@Y(Jv#u=6Z&kmQ*(}nMT_E}HhN{{~<9uT!a zpkL+jduv(sSKmu0^4vuRFUm^+k66qSv(DzHrm2+ zw1o}4Eo|~s;=QqGI&^N#ekqsR=7*}+`s9?MHCWVzsofkGOl1W1>$?~C{S@O~czgZw zcH6Qq;vH>@eo1w4HLr{H#=4kBzqDT+_O*6$SDgLEpzu1*4&r{ZxjHtfZFbdhN)zVS zMRWZ)dVW252Vhf!v>2X5KR(*5DrJl3>UcKS@yLCulDuTDj%RZn_kSMym2-7$8vbV2 ze7xfecpqrVTtA-8{W$nV+)uG|u8wDO9S0sz75B2aI-bpST>53iFVEHSte%f^9z=Y{ z^0|IITl;Yue3_|VRh1my!O0|i51*xOQVTq3#yG${w!#>1iNMXIfdWqgy+4AVFl|zs z-Q_lLaFrQeC2xwpi%CrvCQ8wFuLq9O1-0b0!`}-X*}A9Azs|P1m)&L?^?Fa>4%^5_ z!Se)o&RTJBava~S>(z8{I;NH#Rj*1n$^SLn{{s2D^zFKl+I5pVdhcu+b#|@oYM54? zQ8i_O*UpD<-fboB%$TREH!0uh*{W@J)MWd(H`=CZfAh*d&6T!GSClHKY2@pOuPr+` zsc3cG%eOboDhjeN0#TF>kZ1?JdeEb>#lRIwVpKOPeE5q!eqm{qq~VUV{FbTrgxwf zukiSmc(S|_G;~gVb`+6^&nU_qL78OJP??QXW|Kq`oE!=7U5ENGYZ1*}7Z*^D-y%(VZbOV0G1sUgCT#Cxrwfa`t z&ZwDUgGtwN1+3&G11U+6EB8_83v$tSdZ_RC02>9&PXM&Fpl-go8f}C3A5u^uT0CZ& zAj^vhU80AA6qV6wDvw~jT6rNJ=>HI4BRakab{Mc>9V{8Jqk!$#!2nX)@JW6Q{&c`Y zF$`LNiMIQ3g%aLOSn0`9Z+C&;aNHBwiCUK;`=7d1vwOvq7==?}DBR}mCjQo8u2I1( z*D?CDW(Rpad1cM<#dY(F8WPk;UHc0Ayu0e=H6%30W2OOLx|WqELY~+q`$~X>A;pwT z*|eyrc>liQzM@@=1SR&(C|rS8$cr;kQj{^US=ovCaRb@~*>0E)8yGlUs__x;~Un zUGK7w%nsPcRX<{BuA8{{3A0a`ZI|OJ+n}PXZ{z(9P0%6LE8RT4DHvDW7+>5puedp( zxbC!t4X3kmt$9-4TU>Wq!|B1e#`var%?YeAT=Cvr3-u`r`*u;AT}Yk5r%zbHA%z2r zd5a^8UQYswraJ5aFNd48u@=8~;4=tVc1x`FxZY>Mn)E|W#0tuaT!_V%PmNMFHHu+O z3l#)DsgKljVZY-o(#gEr{>Bb_?TUt$vK-b{~V;7AhJD zG*&H*Krj&zWK9H;29hb?fqxJ514JL=)q1LjqyWuZNvI{R|6Jhg22LK~;HkjJ2iOGh z6^9?_PZ8U(!CmC(N>Cf(%nPWl1hM40RF+U;Oi)rmdMC;$-wvA&--*8x&fn5-+t{zA zhx&Rp(8d5OqdZ|dBy8U_Md_R9;-UQMPvCu34`^lKcQ-ycfRzANdj@_?HEs;L)SE1O z?4ZjqZZyTodttuEh+JVGmDZEv;5)ek_x5S^6C_($=0j+AsRu3jZa4CMn&o(BM7CJS z*MQIM-$ne@j>!F>`gR1vUHy>D*eJpaciH+Ji|yDe`jtjF%BK2F>BfCGk7(nZb^Ri~ zTHWmO1U7j5_Jdw6#5e65*vBM)#~}FjJ_g?&wQ*P?YwOhF2F84tY1t*zN763+Fa9p# zd6)CQqHp9qiTSrv^LL=getb#+%X=LCMO!Obwy`c3`@Cl-BFlU6*^SSj>qX&uuG=w z%gS?0~er0kjksES>QPgDaXO`5qxUdMqptXv>QJLU27;yB4sJY zugfUu6*-&vNH+`|XIpeY$be@6p9#p7_dVD=njbN?eP09#)X%x1{XfF8A8|!Yd-d0@ zU?M9TP>XG$v(8|mx&cODFfqo)K{Wa62TEdd0a@r?i2nb<{Tn|-8$1gD>%NM1qpD}j zw^XUBS80)bRAzbdpw~e5YWrl>b1jEpBVEh)svA+K!2;A;20dqfANxUjFecm4bGuu8 z$f7mod)nQ4J*(~0LH_D=kbj$CrEDV`7BQny9A{Y8i;*s?lk=eLgnqaEKvg<_hxz6L z8*R8YPQB35sIQGP==MO0ymSmf24wbS`?z4W6d&(XSZ_^YoTN1YY%$IEiv_OwPFHXq zZ2!1sH@jc6{g(?<3w}DxMtS59zAA)ML2Cfez|)IQ8|Y@ZUJ`2!^y{c`D&%tmtu(j{ z`7WRsK5$>D@H$k)@=AnLFaIx6*;32Q;Qt6d{vMq7VJ}UNoQ5AU z8iZ7sD8`7+-W(Nz~{wE>m` z*vK1f=&IIw$GDamG^O?#26y@}0voSXR=}zIwp-&Qi2tQoeOx@_GU)vz#&l`u1UYHq(GvZq<$qn3n4p z1E%F9Y!{Q1goperqtC$Jz3in)KLMbpCU(2nT*9{n^bJ0ZCRP}R70@@JrsI?LEZQ^j z`n0@_>}D~;U^ZGr-vDpLrxWA_=F4KeAHbpB9Pp8a2{i)~s>vg6Q2jdFnCvp!s1~m# zge>$FD5Od)fMuJDRR@$C9BdaF?c+E?b=z>%CJ-_-6OIy)!YE@BogXDJ5&s~c#NhTv|DSW=W#YJ0> z7B$ymm?ukclKWP&Lbl?|wfLg0wHz9ZxwqIa2y)Q)TJfB!_%_(o6}b5n1791&S>JZo zX8K~e3^Vd)IeHjTEtWt5@SVB~_Df~d_)7c6chOP#qPlq1=i>V?I`1hehWx3QMf|B6 z4{kkTLJxp5~EPr6p9(Icu zgT;C#i`FyR7_5U_6NOU=k~N^e39?*1CU+ zc$XVqnjA;p5`9iOM{=i_+pR4#yqXKoyv(Q}*V#X4F_MqP$O`&(p=Dz?u477dtC+3OvPd1HeIu z?IZNK=+L1GBOIiN_7Tv|Jpr_PK)ZAR@h+g|_6o-8Qim8tE-s zz;kqO(cx&}x-oF-PLEJhUyJWskAiRNW1p!zy^4Rot&af&-jnc2-UI%dG@BQ{ci@u& zSSMg;y%+1nC$av2mknKvyKlDA#JJH5 z`U4g2xEjy6Tm9-AJVy`_R~vUZeyyDbiSrVWaS<}ECo&hsX=Ez@yNq`;d?Xf3Tg?|4^js)KZ9l((ZoZrEWo;TuuQSO*P#KXLz`Gctp zk>=z1kL|Ca5BGw8_a9Fj{j}$?e=&CA=+}aN_Nyn3{s`z#oIv_{zl8q(bmI7L2mR_l zpE&x;ub}_&6Gz_<`V%LJKK0>V(C_|>Zj9g|DoJ*F77v7xVrspNVnoyT!`}NV)*(~- z*(^6GgYTRq7DTF4RfsudzS&H>^R)Zn0h~&<<{)rM?U<8_U}z z4Vad(7zRxEl)-1hZ(u+E9rhzFf~Mjb0ZCYV!Y?6lly@1eSN}9{zle~Yt115JD$51b zv6rCUWT|cw;jh_e9eTq=KiNyVoIu$)N^MswpbJ}aW< zi8$^yq;EyKk1|j?>|dhQP4oe$@AT0B-GFrh7T^#88wM;v88z7Nw|j0AYdJ50H%#qjZA%% zg?Fq3{R!asJfq^A5Asl%3BOa7)UzVA2$l-i{&Pmf9=V2>1z7dDMwl0{q&G%jv?eM8 ztP?OFzMI!$Y@yz>D9Yak`~l$i520c(421drNL8(@|1)7lZrjhv~}+7Wq} zHJZDDTLs)M9nE3D65g-Xfrd8@nAZezA5fKA6D$R=9>4-RdYOQwWEo+3fK>zL)8Ul@ z)&*Fv4ps?R`3H=!8o&}h7=h&gzXh;vz*;D;WE^Id{Cd~}L>X7c8J{IX~)K`lE8wM;3-=`Y$ ztARTL+yKdshiGmCEcX+mlZtM9Zv!mjB5lk9P8vR4fTic5zP0fk2QlwsVjm7ZSwU+E zIK2fL4)PHF!+=#4MraZ2C}5SvMm~~WLOk~(BOmF2buBUG%>k@)S!4{OF}4J-%H{UQ z{2JhI1AdoI4=sSDuYevkJ*0td2Vi-ZfNo?g{)B!krm}Yfr|PoN$?>pW&_S_}|11mb z+hY!GmKawuEjD7y#~0;Pw(O9^!8Vu!>Da*aTonl}1>?A&mEc`6(kF z%9{#U!qrAt7GR}-^%4>u!t(;AY&OEm0P8ftssJn762bE#Z!KW%sz_hvzIyYR+Z{dj z!S-&5qxx)i^BAAqpfdnEEyPr4>^AR*OXdyt@3CKS%@pH-C-!(i7W z$MsX>x6peJ@^8Cgiu@LOKZ^X7H%^gX!aue9+{1_usD_=6@AMGN2Us^?egfbjSOs9p zO&DjjF)anKt$>x^g7K5aA9VpXBiMpn8h$I%l5R(xX!tb0>;SCi4)hbU^OkX%aJK`Vd#`Z~)Ct&*&!Ug(^wm1^D9I)|y7k5w9VLS@tf zxB4p@F6n*kE>?*$NC$05+xpc=`yzdH0X7QQAigVL20U@x-GH~XM|4a1hXFfcf{g=K z`ZXh-`;VC40jnjNcqnfQV5tuo@iGD13YcG;uhW5-2U!2t^|IcCn{C|eu6>L87#;af z5bLi>;PrGs@01rh(bh86IJzFkzPNYMKHgyXEipXqay#LFBbx4KiS9~4m-NvKyzXye z-p6;nKK271d>Cy-aBY9L?e{Y07FWJT0WeVWsk43|?03QXs zi}Kza!7m29rc(#MbQhPy4|ww9qv1Wg1}5}#@4m%-?8b;3+klt(En|6P*R%uP4Y*IL zx9dP8qPIcd4}Cj=A1W_M#f~l)n1G{|}m01ON!p=zlrM^-NSp5&Q ze#HBV`c4|xzBj;rL)>x@@Q7|FaC4qE(j|C5;N!ho8z8=~6}$}tzWW&?Z{vWu`=em(AA9S+&0Gs%!W{2uzuLOKx588)@OS0DhRyhb< z8oP|L|IIA>4&Y`E>G;!R>;*jedE+=a1X%4ajeH#jY+%2UFVdazXUO+kBb@3g1@M{| zBJG1Mg`OYRvW92 zO;JW3^7fA!$HY>=l71hp6Z4o@1H6Pk*c%f`|DA+?*yt8)G^_^|AP7bj~Wf$4#gPNM)+He_@u9F;Mb0U52?Orpoy*%YHtDL9eq`k;fBcg zxef5DKk4Aw_}LEl1mJn5_M#s@iKpGbOB|m*Ph9@L!r%Ir$e3wpV|;FkjImS?*}!l4 zYh)fFSTSJb6OndBuyVk50_MYadI%N(YyvPp0q_v49YkgaTZ3is#AKJP|gLMLy z@lUP2Xs}+uyhn_AhXBj^mu4dXkMw>Rura_!@LjnMdS55TNab&sU;Z6glcga!88H8U zwEVn1ut&nJ0O`bY4sa5W8s#kktP(K2ynets02@IbdMIx-V1fTL>R=mSJ%9x`mcVNR zEaf#LtP8Me!2CMAe!zMGYtg~>1C~1(DVJ=OF~Aa(L&Emewe#y~>{(0_3R@+40_!p0 zB^lfIR&J|&ipHEpq4v$?@dCfsb;!Vb8DOdGP}m zYwGQk-+f5fH9#l5bpmz-ur%Te55al?bH^VNc9jMj0xWHwG4El(jsn&T9D0bKqk!#5 zh~_8x@2LONjQKMF%RSvFV=iFZbuj8nKENgbQ^NiAdTtM{fR1koH=@XVPz(J2GotaA z1OH|dejey|0lzg7d>HG7EzlyU8uu*PyLcb3P5l70Oe71PO@K!4e4{K0|A4+d5g3(~ z3fNYH{TF5VL8If$Lx#3l4Om*zp>UtbLRs4Y8v~5jE!w6w28HFiMaV_h$#A)-?t74D z|5*{92{s5=_Sr_*C}1rn*byqv1WWuU*0XOoWLO8J0oDyzJ808GWn=@EmmF!^1S4QYV21%KPch;h1#CZHwK{r9M=+kAXT(bftk(p~0W9}?BVGw$J9RMXV}8K0-=wwg zYtiRFCHnkUz*AEXh4&3f<{)5YZ#K%@4p_Gd)(u$FTa0+S0jmNmBug6T4Fk3xu*lrW z7GZI|y^mc%J&WsE`4{@@TaERb3|MWNvEDKO8vsmSZ@GYFyv+#n0ag!KFUqHfjI;!TLG(jyRqCLU`I@_cA}SV#Onqu=^aMcZot|A)3=Rbz*636#2W{!!vu5x8~nY? zh?fFbj}At4nF&~NhBhxyUEV9|(hGRrg+}?x0IPX7V59^*q=zcNb^_)n03L$X0_J{? z5wDf#0XELD1l|t7QZu!>)bjQKR{Y+`*q;LUAYc{m)5aDtcmJ9yI}K@LNXvM?eyqI- z&0%XFJWqV?Bb=oFfS)Wq&KQN0Aj`U!a{{|?{;FEZ%-e?$5Ek>>lPKL4%AUlp!b%6}L*sTZT|@-_Jf zTxh-Z^txoWpU|E2T0;cabUcd&IMPTIH zC)8P@dQ*( zs)D^GpFJ6hftw3lyE1GAez^_Wx!|J%xPIVHR|XP!8$P4R-$lGp|Bmd9>CdsUtM@LU z>qPkpRou`L35wyzMcI|pJ>^=6X6)@l#8#LT_B>F0z~xq|S3(xDsYASI_dn-r_ij)` zpy3{6vA>-~#~p(>?6|=)6}McY>xIvPi6gVz_cVsGw_T#OXI?hWwN^E%MNMwDY>#)Z z{&Z^^*h^(@rMOg^Ux44lSRREH@#_MRPHi_2IIY0x#dn$u#U*P=m3%f7F{Flg?Evu8 zFV*ll524sF+_suRV}^F9mM#joBMK6I!!mA_59MkH3xl9v5Bj`+hV*N`*JO1>MY@U> z>c#!bx>KYvlD(Fhb=r@S7jq5jy;^lEBj9n|*d8V4gxOP8F^Gmx&KqoFLdG1ZEepHn zG0v76h!)$%R0}LaD-BdjP**i>x3c?kZETLz74^#-o8pR^NI-u=!E%f+V5+BE_E9753unrEX}-sRYrz5ccaELr zR(9TswG8@p=%I1geLCzTz()ue8Hdr&{gD9{zj%NCViX8-a;W1Ao1hf*@@~`CLZF9B z-8z9m>*GdNX#D0yk@dhI0e(O$Uw_YCWhl^8WJ?pb+HKN9DVLIk&j9Eo+#a#5BIo7V zfAk0A)9A(s;FnUyGu%o=O~f9F#LTjF`U~}V!MHU#6f%n|K!}xS2uO1KA9M#mH)MxE z2V*1xY^O$+N8hM$#Fk**st0cS9q?_q0f^{7wmsmtyyDd`ZKxO7zjbG&RVy=4wT}tw z*TTp!5Vg3phO3F&&Yg*9zqQtO{0?rYYd6jG?KN2sb>Yi5nAf&N&)1O|^W94DGnyZO z*AZ;zK%<*&+;gksQkX`!cMrc4t^#@eb?6Uzo1e$#>F;Ex$rQI_@Zk++8NbjG?L@PO zwHL`XQfx_{4Wtb=aA0WBSZXee&;2PLw^CCNU!BIYeoYEa*#nIUxbvR*aA12&%p>Hu zmt|fv^U{HC`dYGQFBFF2!Z)gjJ(yaQQ+=1_6QuP+sV8ASs(d@(J%FcawugR90MB)F zKcTP*(o8xF_0W7AAPc{I0~aV6WQ~cW-J=rHM@$^NoMmc4*Tu%6mK?;V`b>26yWwx8 zL1?P}Uh882#tl#b558=)>QA+XLszQXgof z)_7k8ZX1>tpATyKDHIpOSqvCPT(#SU3oWZafn91pmlt_(vljB%F357cHS%OJikU^7 z2G8o6u%wsUXWNOAqB~S#ylFif{o~6RYiW+0s(;|9V6%!tgV*5DpykzU#*=-PRb@m~ z4_O+4M&xPGwVX(eR8I^l`J+;-$PY!}kp9ok+M%@?gA&u+kjfOC6`Mk)43Zemq{ z-YC)n-++Ck%_R}LFml(ex=Oc>g>@Nu{hD}p8EcNLV`C(9Us%aG@RvQT?LnH_ExQrZ ziOx>u{tw`92Y#yuBkn070zfF8E@W+8)-3j`d&ZF7_88?T5361mE z|KgfrowF}g>teqr=Z$V9@mtz{1GU4i35%ZEZz<9`kd}(?wzso{ThWGH~Gfi0oED|$!=iJ&yRl_UcSUNoH4K*Olg#7bCDqq7JAid%V(_F2o>?+*oDr@3C1U@e4dLG=04RHUZTcp(^| zpN<8+BMhYWP!IYOPYe2VPXs+-K1xD*V?Tz@z-h=cBzoEArP^LqIYTtcpmjN ziyp6hBtY1{p?;H^hH?B~0zYWh!-6_D-b9>5ZJjv4>AYt3R{aku6|tqrR{=Wh{}y!8 zw1UIqlTXZV?18!qn%}OT6}PXb?-u^`=PrC@>-hHrZhYU`{Px9l7pN*D_*xGCI>80{ z5J$g*gEvIL*XXEROyFukOd*2yz1_z+S^w4gBp8;>-J(5b6B{QQzd^xz3^=*NI$@QLb_h z{s$GM<_VllyxfC4;bQu}N#NHJ{uU1Y1V=dleyaDe0sO1n$F3Au1%3ON7ZCqG7C=j- zK7trs)M5Gs7>6%g#p^Sd|JBVe3xn$NP;a6yT6#a~y&UA==K}qh3nc1&eWW7w^?nftb0P5>wFs5@5h?;*)O%;7BHz!kMZMom;F|=M zG9A1!f-ahgtloc40*HE7<2eD*9(EF(TF6VGiq9j6dcLUCbLqzxQANG@s#QGi2I@ru zXEP@!Dt-lhzgFO1NBEn$o{BjNRs41P*dF}5dLJtnSXA-L2?;Qq)Ts(rKI*a+pY(K$ zuiw?`pM0%&!u?loziiRlg9bY-G%iIgIJ8MEdL?p;Hj+i<5arYO)C0b{zbE)AvEu7n zQofXW&~d*5zK|bi@|o@3%OduZdapLKM{_HckCn*e(57RppH+d6Ao%e12tI;V^7KjN zk@In{jt`WTj?Yn)H}oS>9+gi|xLy(4O}}~ne<%3r6?jqh9iIo-56mM!(Jx27(r0A! z*K_(*kM+Ro*YJkPcaA5_hkm{1ldfBZ-v)F#p4ZAd(?o||qpQgKrADoKpEQXRr13BN zU6>aSiE?Vp^~5%7)Aj>q`!<}v8u?ofi~LdZD(>=j2UT?*ni>tOG_eL%G$L(iCB1ed zfBGvTzc#E!^yLq_*9C}-NvL&KB8?8^%Gtf@{BFY;u+X0w~ zHN%&EPBbyjcEs-O4MRx*#D6vDb^J}xOC=zlaDC(4G(CjZ2E2X^kL(wE!g!YnJd(2? zcoQ1lu(>|;?dMO@e#6^O;)Rg&pMo!hIrAr6o{kQCK-ZTH!<@QNUV@-U>!oTc=RcyH zV7#fE$U5RuttFcD`J=Etxj85n9ekV~09`*@%?bMGy=Zu1@vlBD9mmwirOlu1kV(B! zmVol9-YVXWaXLxxRYOeS3G?OU_ViUD)0pbL75Ld_34CgQ^n~%ZM%qUY@ai?ZsCKD7 zhHDra7?nQ?ywW!adc)@StJZQnmQUEC-6g*V<)0()quS>J9`eBD$^~AjhBwT))bYuF zjF;rWS*gKEjw+&iuAoc%h4h5wT2vQDm(bu%hg_S~_2U}&y)MVR|f&3q*LMz)L?*;6>>Z@#Q3UF7OgFG0$swsb)RlB{kZ>R-;w7 zVc|jfOOU_yd{NGrIsf9YpDe#Afer6vd_AnqexjWOk-t7w%MW_=gyq?QqX<{h(LXqC z>mU!(dWhdQ3;a}$t-~*gw3AWdOT!~R=?T-_L=+eC@iOtf=$9H^&D%_Py8f@8d#<#_ zdy%aabV@JQ^lctT^!Cz#e6*l(q78I93Iv@hbAP@(F#;N(M z0$#cdPsd*?@VqwgdVp7918)>~^%~wlR6pL#<)CpZ@q-w*HVHX$&GXY@oxOOq)PCT8 z+fvYJy;{&IG1JkHe>cnN(7fFSI-^^RdZoC3#gpWwVU=$Ox)bqj7tXd|{|op^mB1g- z;sT@bDL7ipWbTiF%04%7xR?Lk!^!UAc|wjh_cxF{CDJ==AOS_Z55D?CkgHno*+cL4 z!4u6V4WtpByVLNqk7F5`A?^oseCv1f+?$RiQvtL%-IBOHRFaMPs&=aSqKRx5x3_D6 z->>0^+DWt?-VJZj?MLEfJg0C6~M^AJ)6wRyC z_X}tn)7FA0uk^!c|96Y>I_;J>|5&sx?52K{=M9ST%DHs0gr`a>UEc!v>KwR@4uooP^zIHqyj$OOrU`$9UP~B6ytV>rr(=HjlHutBBQf;uFpSCb&KXw{%Rsr58zt_$R4 z6-cdK82CCnM$bDg3X`O$FH8B8D*Y-MvCwW>bUm>RvOL-jT67k?m{OKU+q8?3=f~3Z zw=@s?m#i4|?Z?2ujUSSclX8GALE~)6$6;rje+BO#!_)`yg!_qp-VaFGQa>k8dRU+2 z1??V`SMgR+9<4*@375A>*DpUTZE^hUg8LJghu$XWjG5^akvoo!>b-Gn2i~Q*a1Yz9 z2bSr7hY{61dfA1xI5OX5xSy}T}tx0o-W zjcel_{8|L!h$Z-2kNnvsB7b>w`RIRW4iRTKyWQ{$o6eCmZl4T+Uh7gpFR0nq;dUS1 zS6BDWizSd?pPwg6y%_WUDnX}>mJN8qboAp{r@a5x=`?O|70X9$h!?xYr45|5$g-$U zN!!95(mWZ`#^}}M5&B5SKQ9hk^{y9s;<2fEJ>4nR=QKZ50WYaS;PJRoJ>EjmPS_vJ z&4d-3A=Mh7kUXT+lF+Pq(+UINV+ZYFlsBXf~J$s8FXlVC^V>GM9Iu!O0aM=C`l5h%xekMMp`Diy+i*kchD4uY+3ox79iUupd zJTA2!_}vE_`oDgU?0n5>W`Xz@VWkfIA=y-b!vnm~%Ez$bA5{5ZD= zITFqFp!ff7mCh$ji@b_viweO*1WUCM}p#DlVyJXplD9F`jNHj{B8HH6x zK`PAP5YTnr{?cHH(>XR+|B(W&jWWGPvE#%_tQ4HBAh* z%bX|7N!|RA0L_W&HyL6!sN&Q!D8i$VzET@=qy7squG}x`f8bnG{p;G9#p3Es(&K)Y>=LQrEOl(@1GZ>{Zo{V)W0;P ze8C05pD4V%wU>%NzxM`mY5(*-P|<@pbjeT4jyr3Rwc{lBVR#Qh52a@87x< zeEnAN1s3@e=1Vtkt7l2|5w*}y2bD3=CYskn>fagZrv`Y*%g}!h3cNA19bC+# zRQ`x}T8)F!Asw4(g#mnG%v>P7vc zbUnfE2N(vOig7`w=4`IUNd0Q(Qq<)xl&lNi#{mxY3^RxXG~iU20b&cA3o14j)raCV z9A0oa{#GqV`(*S@+!sLq!}TikdJb_DRu{V_7+2I7UsN}5Gc7**3b2-nYmC2v|6p4< zDiOg$?PdVy-qJuDPFxb@W5X2DZg907f%y>AHM)!VaoE*-X^-QS;ttH@6<7~z`N)>0hswuH>w;0?sEE@+OY!thXeZNx{Sq`XBUyo~VrftNgAg11cQgZLT)Ubco8 zwZC6nr!sFa4!#MrxdGf7TY&0R8`%2L7ZAWhbh1}MuV;$#s?6-i4v>l&}atxcs13dX7YX?F4f!${he+wT4$?E_X5cyKW0+ zu-gWL8ASu+{R?+W9pF_rbED2Iu2{@PLAgO-hN>TpsWI-(HRH0v zSWK|{VnMm-Y9_!9EHiL@tn7T%W5(oeH8YT(@-qYZGTRJfF%`f!V$G;Ai)RnU;*@5Pxa!yC{z+LNRRQq*sA}}|`;{_^q#-uhXYop?0IbGPVr78EzQl#s+(29f4vwGK#)Pt-Y zYSk)G=UQe@$V#`6<$yHLGtv~fW_C&Q@F60mHl=5*SiX#!baRNe%~+*KeJC@LgSYNj zT=5njE5VHk>*#9OA0HR(yXrhs`^Gs8E#7@i(4+2(8wh$B?FwlN0o_Slzd8`|Q_+ly z8Bt`ch=mp5-7MkG=x?z{ZLJsdn z8*xLkx&a!R(G9@RY;FLCW^x12q%*BUw8Z3UdratWV?uuz6B?VsvoUdlF`=e$SK~J{ zLmNa3&CUj3Xr46yV@?z&0y8uN8%mGaH^n?labh*=us^+Cw7X$*oK9r^{c>==%H|CO z=f|81g$2$Vv~KQYk!G%gu0&6se<^zAd=_&IWlLh!Ow0}*vvtLs#X=h|2F+}V>bdi^ z3NIxd$$_Tp)*@+BEMUk3ZJ@rAM5JMB{^D49Xl9uo+TAf^jM-dxg;n5hW(EAh*NOV- zG5ZIwkPp)N#V$TbVCBuvFA|71Y(0Q=5LbE#KiCKW&Wxj+R+N)>gD7XvE!s`PP@Q)EviK|aLT_fTzCO|*w7D2x^-b7#L zUuU1yv=_B>Q14M?NrIfx3j4Br1N<0wh;mBOOy#g;y7g09Xk?8pDLXW}MkTRO6-K9o zEXnAU-^lpJR+21a?+@1wO=X{3(fdZB1*8fkc%Pnna=!LK8_; zLa4h(C4|PksD#ki7nLym9MZx=19?;#(!!^ogZ)aTcqy&WC=$gM?ixOR#HL?YY*JP_ z+bK&yRE;c&aerZ~#ig7aJ0zthZN@BQ8ARzbJoiPVge-)pgy~n>Oyrn;pHLUc>*YzA zjxhv}VLqAIjD3Qyh;ex=)if^a#(#Bpyo{21j(k}DrYuv)Jcz0kX@|i}6@?)Xl|_Cq zfc;IHr$?G19b%+yFSJ&P;!HXvNCzcp;UUW_sthS97FtP6Ba1XDijK`o)GzH6A)iH5 z`RZCGBgP73Dbv>_3wcJO7+_b+N|E1DbPVN(yg||B|5IANbUwD=IbTNY7YrR_bmhzZl}$2giB zfZyPUntf~bpBnZD-XbNe9#Cb{GrnyUbAAmig`yjoy#IYq$^*Ma%7QfVXSUdu)1P_S zxJ+BpK~Xxtspm-t#px51iXxp~*yA!$m~^UC-zaZKa)VGx&cYy+w!JxnFtqEd+nZBA zA+ML6vT8=0Jp54Zo8X7~r5MK&&G*+t{80A>lhr5Shf2nq&tte}VmmxT#)ZMn61Llo z(1kI{cEDSc%<|#VNxm%>La22cXoXBo128m*8-Oej<%&uc{-&)|ByCJ3$MhnVQA)@K zVIUdm?gn7dKxmfdGgB_+rJ9>@?(ij{_g=F<$;;zh9~PUiB6?MIG5(V#wrYHOkU#Ky zk)OW<6tJ+LXtCx`TN`qug|_8ztlkU~SL%S>5DptMqxdvHJ<7j1eyuh#_96P|WJWPu2rI>R%On zM8z-RJRJpDvSHq4s48$+jzbohA;QMjp+H8m8&bF89{xWG`bk#jl;~_H*H6@ZY&>5J znpOBzgRXl*&Nn#?#f{{8A0ca?LiCX9%>Zuw=rP23yit@_{dZAbra3MOH!V`VmuiYF z!L=93w_-f_hlZa6hVg{k6)V&E?Xsm~j=D>#6DBnt!$U~49bYCcOnlhe0GpH2lyi&6!=-@dsg&*og_Ku zav#h0Wo=-MEP>rCO_8o;)mAxg((z0E!!cx%4{hqCvYfh6U z{Z`*0#r@cscjG-acMJa8&Fjd}dBV53G*3a;nZN}dAo-C$?;erASG%7y-0t+}8rSH{ zHgYU~#Ri*@%5tlep8QgG^-5_b5-68G+u;28oREjV6BMwpJp4W%yeSC_6zx@5@ITOH z^^{wj^Ql4pyjGDv>fWGoG0~B~paXa<8eY5E-%=4-j*eZ-{gBy{?|qMp?h@0^&0Z41%va7>Jsn*nt`Iex`g07w#eM>7xxV?ac7X;v-Wfd ztu6uWVV>~PEeDZ8qN3gm_g9~nzSe{g`x@AQKwCxd6@3Hh_NY#_f|6DvsUj+=N+ZPO zqxLib`La5Nd;zn5mq*%@`WvaP)TQ#Iv-NF_`hCS`F>X8|%8TmvD{$`e#$ZBGJ@?as&!a%5 zCz_td=krLk!6%oW=>AC19ph9j=hm&*^nCp5aD`w*h}CHcuW@1|Fb@8S1mo9hky zs@lgs$mT;b&$u+OtM)OuG*-HoeFg;_kx*9`c)t zBke|iG7V*Qqx?3M*Sc5mU!uiFPg&lx$T;2d+z+6{X=gfs`k!{D=3`-x2Aye_L<{0+ zXPUW^mL3axbcw~ZWjc5)_4KA=C<$5k{!Z!VaIWsxqTS|7+bta^)%BALFeXn|G_AaT zl$U-;l-FaoU;gyi`X!A6*`J4ee-`C+O3O3J_uR3SSB~;JP+sf5weqC*q*H>}^K;Wn zvyHmcjWgOdAh78!>Rxi$1LX_7n+T>d&@CiP0G zawnIS$?b)#?k~WPmMG+p^1I=FlSWm&7fWrrz=AF~X;iVcjr`#1;`f=9fR2(R=#0?( zfhVlTRZXh8jp1$=+-1_FUd=DNK|1Nb9{EPk7Wt~Q`VHsP>7TtOv+AYMNa{SPk3i}H zWi_&5EP@NA`#|d1(gr~Kp#iu4e%MQ?TKgj)p0NC^i7y06Po2OU*YMJ;^z=oU0CGK5 zO7$d-CuDs8Io6KE|Fd^4fK?RN|KG<=2;{*90!EB_QAAX#Q6o}C8z6*$QKLpgMF|=Z zG&~A1Vnq@qQq=IUMnp|*RHUe=s1ea(8wC+-P+BQsO*LAI)Y2L?rL;x!|DKue-d8g5 z#=reN{{Op>d-gMP=FH5Q+1c6Iy?cYNzG`=oXMQ`s`QdcskF`?&d+{9KAnm7paztYb z`YEiRxUU;sZhmi`V_d^_CYjvnJ?PP{nz~&luEhN7cwOF1UEEN4`Q8@Q{?Hppz2VV% z6ZATO=&glb3H63V>s_%$h2-LM2lQ&FCw`MH=%+Dyt~cImH~nY{UI9GUTY6Ob>iLKJ zFfN{;%kNze1nq>cKbDysjA5vzk~V( zKAj*~jzHB3%w6&2lT3_*X}r(ppO%=cMy8@)GJW62s`TQob{ie<<;4+WR`4fgqAXtASXABbJUngL&$VpXcU~26 zo>QMstIw#y=%P4t@C0W+$NQ#EWM=Yorz!5%PU5zxf|RI&s6sg}Ntw!3F*Y<_!=gHm zHsZ-T0mu&8?}kqDy+d-5XHNS$#Y*iZ*`KXSb75F%9&J<& zHxc7j6K)pN%+~F>w(IXTxW~Jp6j5IHaBobC2o8=%5ux5#6cOl+LlJ@A7!(ocjXx2A z!5@2w4DI-tBB{AoRoW#*`9L}=Y0e0}BUV@!^B|CwTn zGC$Q~e$U8NCSz`Q^W{{zG0|w_apBB0CNlqMk9bJdFLEEp{ov2E-?E~w-|@cN$?6L+ zW0rMu9#Qv_^W;RM)?M(`m}T7xRN!d&p3Jgtv%I*gyq$}^9cNLvViAIocNP9NBmd=} z>-_7Y-7?J7U(n#*Y%HE*T)K60%>}>6)OhAM_j@z*c0IwHowtkdX6WrAjBe}t zVAu7btLrI@#SLD6wyR;+E8@OsY+~b)W*nZoo}!b-;WwE2irdRr=kp$}F$d%G&E{8ATx&Asj_78L+LvUC za{ghA*<_5_W{Pp2OEgAZZgjMJozX+?8{wzHhvmX+c9AW3UR2k~ z^7?gG|0*y~w88hv7fEr0U;9<-=Jl}GI#%1Oj-GGeLQ>ALdGdjL)dBdbf>WqoS&Eyb^R1L*<{LiUDx%K zX4eOZuBZ4;uUyS9P3ii1tLrKB3-`U7nc)wSb$x994zKf^M@(JCJpEX2O48Yxd6y}X zV>IWOZ^Xnen>%>3hH+lzUT+>QjngbW{8}j(oab-AedTNQxLlAEH7U8-;Ez`uIkaoOged`k7IViMq_mz zHYa-8nCNt4$&KEgVKQcX98Wwa_x+oGfqBx)+Mh$B=Uq|ny^!B|OWBCy@mE^EX>gSP zBj!m*8NKWtW;}q*9m@RP3v-Oy*XYVl9v?KXvVLlEv-?|PWt~S&iJWQ181s2)v@wnG zs5kZ+^J#X!DVM8F5#QnL&iQqhGwI|_mp?QaGuFQAb?o}=vg;}ErJe8W0^5DZ++B?) z<*r`};CJB+MegMFHZx6W+$3Y6J9#Ixn`RyYUNvSl$C#CVFL_6EX~(;d-fn5k+@U+M z_8U{-f=>~&&&N0fm>=n^FlA$GyYH|cc0G@-A2(PrH&xMj-V~$HYddg0JoqXW>G$gM zoj>|LPvP^=Tw^w!{1h^O^{vD1WV~_bt~P%o+5CvIv&mFhH{xr|5vw!!5~VTK#57~n z>&Cgbd#r0rwaq*$FfVVtZ8T^8q2!%_O$*YG{uV|6`>qvvnu=-*p#4v3TF7MZ-? zP2QZQs;!=@Z$kQYgLV2G9UNNs3j3a>ZwsEQr(U~!Jbx8L*K%xhfYZbf$*Kf@6JfXT z_+mk;FnXPCjQ6uL&h^zvmo+-?u(2Z^v~eEmDD=YWq;vICUiy22n~~3|Avzzqj*u<5 zzUaLNPk%vyev0#^OgEJULvvIB;^>b^-ICB1^wZS z5mj}YKwK{RDR1I=ctBF^NN*bZ9DzDRLR9|iP)vyzG%IXXvcR# z?I`V21N~KFik0U4X#ISzeVi+UPq9Hq(lsL8!2DvB!u$SqsJ^?DYv!s?H9n{TLXCfo zNH?zQ>4r1xh3rF&VFz1ugcUaO$*JKt2k_fQncbJa}H})g2KrvSth-(@(qVx8THy7r_Kyj zVX1Ek^jeL2WkJ1au{WVus?ljZ>Y-N?gI*K#>SNIJ;YYT1#Gp3>daWkCFuxQ*Fa1(o zkIwuuA9^)LJ?)p_@Wm?V`7hJN8j5nHkmmhu~)^)mGmqmLISf1z(I6xCON-6wJFq}nYP>2i^7$Bbg^ zq1~d#i}3FW{@HXW>+z}@c3Nj@JB`X(SUD%?ao<@LHpzyLgSP9>&SHR6yqKJ5ZncI$fXI=;Ot? zI;=j28vW*6X)3hwOr@UG@H$8MooM4Cwef7|7_TFY6MN?&Q-M2KrEfB(dD9qUUi1I0 zF-?sz<~(D}|G$r8yZte`1}C=>z2DrH#skLqK&Lw1W!(3@i}U@n`go~Up<(09sD-{| zuKFn&Sv$b%AC{>rQWxHwWHt{pQT>uyO7UII(@tO?>RDFJ3GUN z>+#`$^s?3CZzAk${zb8%H9Vk1X#Bn`Y#6%EICi?n8Am(!DdVb2(Us!XGG>)!#J)o(k<_G=F57U`n9Ab9$J;nl<@2H#8^uGu~KV&If!3rh?lR_7bAWH;+4OGP93*J{5&6V8xc2Ot_gy1lW=3<)uoB&;f24W z-WvP%kMuo6(O(Pwl$o*XH$i{mtd8`5rR|S^{ToB}Q~u<$*3SNGTXnngywOfy>NXtu zDRbJ_P2wgX&Toh-LtMHcZaLyI3~_4_m)Sv__;xGe0*Kp({g5x6Po(!sdG;c{#gNvw z2kUno#EGdY{FNeYS*AWd_C>ER=E-%YdyZY5n7^dkn59WhQR7&A-&Jm#^1`z^5$}Ue z!o_HTdMC4t`B5>sD#>WAsNdW?PQwk2+uo95sNcbf3yCMLj}@E)-5rgcB;F`n2l*$j3KV z=TjT)FF9VXlH(N}bg8TAy&L+gZir1^_5Xcnzxi6fx}ANr_Tjd7NV?~S4%mmhz;bU# z4p?-#{Zu)CvD+iiE;UcN-y`B?bhI|D3}th4dA3hA;JbuC>f(lsGn&7C@3yY@i8 z#qm2|E@@Cmy|C*}mMiig;?M}EpNG@va9}wL{)*%8E}dU#wBL07YTXX%SA}#t?&(^( zD&)Bl>2mMa>Dt{_)BWv}i2indc#oPE4sMSKMcvy}55iBeP72qIh|Jx&|jX^`829k{;+wG_UCzMKkwKI_Rn0TD|x1C>B^Aje5A{MUZ>mFEGH_e=MOu8d8h=ldMx+uFHaF7$>#Z%3on%WP+FtNI<`DPq*USnXdX`|1b# zykG6(^DnT|x?S7Z7~SsfQNeQ6La%;D=Xz4E&Cn~`rS;nNTlXSW7WG)@wW@HJssL4_ zX~7c8c_rlwj3-To`c04tx7+G+t}Ob)pV$+|9dSpX?_uowV zIR74Idt<~zZwEh5@9h?OJEPm};F$;5uYvv6&$az_=MnV)pXynT^3&zwEEQNGdz0nk z8u_?dK2+Fr*;5_Uxm9-cqm?DHs|;PB0!Ic}TUQondQp0NZ#P9)9^krO3`8)b&A8n^Py5HQW z`e%yn|F9#7G;0%42Bb?rM5n8j0|Q$y{|iI+InBSyWquIEecyPKz-=@xy1K8Kmujyx z-!@%gG-!St#Cv(9c4+uLF!NiP%uB-N7~}IO#>Y;+O_|NLiN`EU{4eu?@qWg)DuMZ4 zhq=3bix}539;%((TYg-|G@QNkxYkV%P)if={C$D(7&gE3<6HUXTh#Si<#WBMs^7}m zcUtO;O+_>JMDueL-)YIdTi>YnF}401-wPY1&sXd8=_+)-8Y9mKE%D(8G0vA??qt8@ z>zI}%lm`QKLYWWc9>n_}b7{}k;lcBtI-lc-A-IdS)c4d7^6%)7+~@$98i>DDu%Di% z?aTZ@wxE4{k8Lhy3AxC(5qc%mYvS)R1@*$7+jmbf9$7b<`hhXRU1B_Gx}O{K>H4!i z<{O{J2P2HnI2doQ>g)ORukpLA7Z}>peSnt_x*bX(a-rXPq1G?$%%jpe{KU4=Sj^zN?c3Gb_--om`^}v2N=KC1{9uw( zYpSWU&=g~S)~nT&MBP2=$Tyw5Xy6f(G2>~~{EoR>j58Hun()Ig!kOV+K;K_1auTe8 zx9Wb?>GvUwk459u)A6JTr=N}^=A-*IBH!GF?9b81UHJIlV66TGlYQq_Q;a@thT!~D z;3il_Ki2sdq(mK0q2CWFtnT4nWjB`4pj_eN^eWercnM9lpSwx z90D&D<5x7EU)`g_qFto(4r*$*ST&IIeF^w&L+!79(es9|@6EU;7zYgFDbDjqyMe@b zRmygRNKZ(xYVOhHl71yyaQt>gRQo10o+}F+)xO+DSr5sDe)m*I+3#XD$ zS=Hy;D#_23J}N&S{8TUb-Alhke=jEN_t4!T<}rA)@qFt#MsJ&6Sr&eEK0166pfK#P ziHN8Oi-;IcVlt)r&&EXD40u%gArRevIPb(!7CG%ifg%GYM+e|JXoP^ zzII8x0IZ3kU5mP5{9DcTi7uCuSM4iryjuFtEctLosLwa_^g*pd)gXQP8l8S)yYz1a zld82o=Wdl!@@+)A9gpdB@_s$pLj884OzSJ~NJd!RIV$hpz=B%;N=mSHKcUk%w#!$2 z&sG&#=Ub!lU5h+&k*@wpovt=|-RxYsKkSq)Nw|315NrKf^+vaj2CKs z4_~T4*$|w+Bw=!Ns54<34)Sn4dGl_Fo!q5~KYA;FX=3hM_yKi1La`(PJt!YiY=*6Z>%IjS0=b{(sq*Kr@wN3EOzaDgQ^vz6j}eC|g2 z9WUtg?VdXtr%yc25_Miha_>~+T+%M&k?0V-oGChJECX~g)$aq8^hmHazohf8jxN9V zevYfuco0^6zSk%``@^+_oB+=YynyODp<%R2we_WiS)zTU<1R+(u`GQZAE zXXjlehs|=GzZs1g=du@?k{G|k8U8dKEWf=krsqV6#j$gX-t1Aq5Z$}=B!iZ-)d+SyU}Bh+mx zbqaOV%`0`@Rrezb^?*4Lb~eLK*=yQP0a&)sxTn7;UIY94ptqTNDgC4L!moE8^qCsM zy<2y<4jSCeG@nw38KY#CMIABiTF`mG6yqLiE<|wt*v_7tV4U?jn@m~pAnc&J#zj^4 z2xDd4Q^TWF0}R1uRa%0z{X^Y;g}PZn?WcN@x|MW+w79fyJ@f<3TE8w@U#(xsRN8x~ zo;no-zuz`R*A#&|q2%xDiGD$QGG59S>_2(<-Hw^KC8>ke@1bTxKj$Nze{pob4L^=P zHM!OJfVo=ls)7AgAAfUy-Uz)`>Qx`A3m7bScz-T3_vf3;T`At5u?mWH_yfk{#yzpa z{#?{6!KyqMdw;Hi{&wouv7ZIo@muug9k5sSmCnC9+Fl-JV>bu8zv|Dv-k3*!{h#a4 zC9q%8)_H%f#c@;(y?W}^b~Zl0XYS9>nEP`?V?|tYxPkC?jEMSH)HgD1@UnyvX;}*s zN2Co~)NM>!WrBNRpR{3H5VmPV+TgdL^%m5(AzkChw4@PGz%o#`YHuOvW;b?aWH05Z z>X%^oCVtkoQ5MC&sXWWOxxYKUvn-Z(izrWir{#%MM)uZ-`ga7AHr)- zZE0KU1wxAdeHo~4c1v6B1i&}>zqyBd^aY*Ox4B1ndEDna^?#%?vKRl!3bLy z7AETs!x6R?VWpyk6JM1xA}!-KcSKsi$xX|64I!IHh~+?)a~m(;l&vzP+Z|?0>@P-G zb6A+zuSHnXx3Iqh>C!(6m0xPM7h!&csrAapvd-+NtkPdH`zKh9AGfqk` zJbgF9B_KB~$0;q?e_)cS#$Kl3?@Kg>^)N1h~I72-?& z)Y4WEl}|0gYxmHeY?x{h}%F z!*MDz=!madp;xoFrL7wKvPoFdVerqNL&uDSWg=`N!c={zmxZv5Pf=E|Y@(Noup)%b zS0OrV0>T;)7M@2b!iN6^{W?sq5@AXEBExDBwj(NR4Z`aF8qyQLZA4h<-_WMCCql}z z1L3)!;drJ$C2TLkwzq_ICF~%=)_&g7HatwvpP69o`XbT~0})pBCEE|_B=2De%V`a^ zO~9F$mLxU{5xx@PUcHAPtOQ}{e@EU90PW)D+UkIFey9Z621g&h!!K<#7%DZ;-|-K$ zBlVq1t#P$ZcCjMpW#O*@x?BH=F-_|R+;f#uz_~`W0?Kwk4shtoCgo{Gn%slzzZmb9 zI1VlpMIXCSds5edhhts}ed){I7QoJMgwIF#R0%}lQ7MUjJjA%rhnwzl-8CG4#n5>b zI?qe_f;!H13w_R;!MAeB4_IOS3+suv^{02R+`DB1+NBQZ^V{HOd4Bwx#^%aV&c$hU zqnz{8Do0(Kws_RYwB@4;(^ihU5`kk8c0*_5WaX&vaof2kcHQ#WRh@DvA7&M!Cb4|u zP`(ieoZ7|mJ&yF}qkiWx{Z&YRZR`cfOT!9*5OH$MEt6*yuYe?lm0qz?%Ogh%8D*y+-H4ZQI<6uCK_R{HuLkg zQaPU?&q|q(RZ017lk1wr2_w_8ZciMUHf&k95otLKG2Z7d>OLZ^(3zi>kJ96ts%gV; zeUtSDl(*tK2Q#<~%;5YDBjnsrSn1#!yxptZ+kA@?ZpW8%)%U7%j>h@!a2%(|Qt~WP zrxE>~>xqbK3X8iaEN&j+0!M_>sgoK`pmIr8gSZmJiI2qQg<YRt>T`IoOc_t0S`8+IsshqE{$@y|1;>r*w`pYtY=0QO~5^+#9>!e&c=PaK)%U+VZqW9Kc6Ui}d&^=}_4_4h*6dluHfX3Bui z+X}lQ#y0>Tw>Z9eDEupWEZBPT{g1K6#60TBYj~>v#3`Nw=s= z^UZ|#$&kB`uNi#LpcMn}J!)m(z9a6>e4u}A#!ve_nEo@r?hllk^8@wyq55pr#VUN81>VLQyrJc=ty*Ti z#!7Fd7dB~`@v4^oSF~i~Rl2u0x4H{`RSCBxF79@F(vt4Wdfe5!vueTsKK>J)8c;xofFYg2{=Iv9e7F1NfrBZ$|6 zE(y}rN_kw6M=K8E6opccGK{^YCnQ+YPXD~EL58oW@bXZ$R_QIk**Jo5RB9VQfx18Ef4L zE0me{H}#R(?u(ta(CqL|;{LnSmXFYN?(MAR5vrXY#}S$(G26uITqlhgVKnyaofR<~ z{f|_CYV6tnC#vth9DDQM7;{lwtcAzgR2RjpiQ87O8l4rh<^;1Q4z+_ApR2Ml7d-#- zw&IwMJ?GD6gCo)+I;q<$cHg^a_+q#FuTF1jMwG#s9J|?q*c;X9^gJ3_f=-tlBUEE= z)lTPT5jHO|*B|Y_PTGH{-2eZ)ty)%BzG>`TXS*vpZPj%VOS#Sq=IlqLMd_X&yDnZT z+Xdxkx}tnWSCn7sf^w&~f1+H`*@;!!Y}hc|uP%wb&1$>SW-rC=THNdEWXOuFlzVv> zoaJ_YNfl-J?5$!kCpNOt+-+Sbuj{wMU~H@i??^x|2ls>) zgdW-N7rCH4G_T70AbH?V#xC?N{|ORJ2G?8ySd+m z85CdL{~v|+xQG1`^*L9$T(4cNL)=Qlr9f9Uxj(WQVXF{UAot|iFL7u23}EmcvNZZW z=p9^#^QL6NP15^vaXx(m;fDxFPf z@a*|twEgz@$nZvlA6)%KTiFSb;kyxD^4l-koUrgBs2oK2#IL?+tClK9&4xSw>mh@ZNcUijg%%(AoW44WXYs}l{FYFZzUB2lYhDx3AHzW`D=Mukc ztChR_!F(=WC@(t2ta;0Mw>q%oNbJ6>ES*oPQv@UW``cBpyF2yE zwu2I&@6|8&`CbEfk6Hlb8L$wl?}ctex;1HEwoQ?AaN#m%v^>)?IxVooH#%)_bwa*8 zBZsS^h273g%PCD8hG*t59^lCyvgsX}@c0%R$KJhw1dz{I^{mBQ&r;&?4)cWU< z*O4cat!5oxMlK}(m|RDGnA`%E{5Fs$e5CnZas&Bu^5Bnkd{Thr1xx*oAUBiGAZPti z$6r9M1WSG;d=A;aM<2gq$pP|(#&W+$*O4C~H;~tox09bIHe!eX5uKpdR0c zlV?L;`panYF2-L>UP*gblC!?j>8~O0W%}9V#f+~c`~R%Vb33^hEdA{#5-cEjl+>HF?{IG+(m+^lfTc7Iu_mVTnt)BkZI=ywY_J0=RyOZ^G+FICmmCnBxIY91Bo&R-U2w{P#IzL%blKh()FRyhG zu4KHt7DL#&TI;K&Dqt2llkwBYhm$MGN06IoPhR^f_UaiQAnzp)Ag7n;{Ei|ICLax! z_Q)jdR7=_Gswl)Y5QlA8_2`Sfl?iR7P*p~^KuD7+HZBQ=&qj+Bw|09YWIdH?$ z9~Z@+@%=PjeqTrN*>YfprLQN;cq7{f1GSX#O160qhYYfb+RgXJw!8V zy-oC(t+kx-a{S9CjJL9ROW$;h4#cON57ZW@QG(54HS_(_bh9PnzHHtS_R3pw6no)?3p9K6$fsdB zAIRqAkJF#7&&@e1yp8PDqlLV5o{m>a{{uc|_nGqFQi_I5-7e9YuV??;Lb;Q259NN! z#D{ZK(tebKD2Gz!QI4maN?A_1h;jwxYRdJLTPSx@?xEaInfOSKC0jqrL6k!&^C-tt zPNgiTTtvBoay8|8$}N;TDfdwBr%YVM{3!=f4yDYa98WowvYc`eZ>{gjETnLp(q%Au5bl;bI< zQkGLLqFh0_nsPnm7RsHJdnor)CjOlHQx2jWN|{GFo^mQ>IpreC6_l$f*Hdnx+)25I zazAC_8s<+qh;k@p9_4t-sg&iEizru6uBKd1xrK5k#Vxq@;v<$B63lshT+Q0}Kpe4P1H4x$`NnMXOEaw=sx(EyDrGt4BFYt%t0~u0ZlT;sxrcH; zW#UuJpK=i8P|7^Y@sv|3%PAL8uAp2^xt?+hr-Ii7MVWjW;{$`zEWDc4hOq1;KihjKq< z;xo*jauDTE$~?;Plv63oDHl<$pj=J4o^lK2PRc!$`zaHjW&V_dD2Gz!QI4maN?A_1 zh;jwxYRdJLTPSx@?xEaInfM&@ryN8%lroQUJmpl%a>_-ND=1e}uBY5Wxs!4a<$lV< zdgf0#h;k@p9_4t-sg&iEizru6uBKd1xrK5k#V zxq@;v<$B63lshT+Q0}KpT+jR|2T=~C%%dDnIhC@UauMYU%GH$XDYsDWq})SkeZ$tH zyv7%<;xVoV+J+)R)|XXEd5{B;y|=JhkLn>p)-nP;9mV(fX7CY^aQ{>k;VY`Bg& zMepHxt`ln1Zae+#Q%*bcWckpk!qXHm&5Y~j&Y4;=xomQvdy z55zqX_dwhOaSy~j5cfdb191<;JrMUm+yikB#61xAK->dy55zqX_dwhOaSy~j5cfdb z191<;JrMUm+yikB#61xAK->dy55zqX_dwhOaSy~j5cfdb191<;JrMUm+yikB#61xA zK->dy55zqX_dwhOaSy~j5cfdb191<;JrMUm+yikB#61xAK->dy55zqX_dwhOaSy~j z5cfdb191<;JrMUm+yikB#61xAK->dy4}8}i@P5zj!VO2<_LmzqNkR<&JK@%7O_hX#1{N}gXI}O*Q`&okk5Rd z(VWHjmd(@~qvKmBn~%_T0)3c|&aK_2^iOPGSLzr?W80VqHP3IcEJWFr_ANRf`g54? zn|gpwk^QGqwIkX-{7oRs{6Tmg*~PwuEhbBx@EURgIqku z-(GFs`@Qchvi!cU)UTKcTkG$Vq?E_J@#%k-tYS zA)iRDC7(pzLCzvu`?S52$ysFi(J%4$MDnTRmE>%4Bl$G)0rF6C=3ljanZt>_;pAcD ziDd8hzUPzAK)m$VTC)7In51tYd%ySHO7?#5JM(Wkzq6@dK>h((j=6c{9LBFAk6`?E z@<_(-CXXU#e5UQ^l8eZrnSMDrkMZ^Y)cRw{i^=)aUq}71GDh^?`8ZoQ5(ISvvi-`2p{Gxt&cbWFDF~4 z>hw2w@#J~r5~jbAypsGQax?XBBJX1Sd~(L$b^bS#1KB#i1>^>D1-XFwm0;;l)#O{q zIj8CLw}Qo=b>xNQb=1F&yq&y=+(`a0`2cw_Ieot_@9pF)@*U(t@}1-|ay3|vhc)CS zjNeFJO5RRhM&3(aPCh`si=6TgU7nwiGs$<8tNx|qYsguQzlWSlUO_G*-%BnguOu%f z-$&j|zMtGmet_&hp!2UK4K zN6B^M)#R<@pOah3YseY&=VRm?^5f*$u{+*O42@ z&yWMB>-5i(4>J98sHj=YgqB^ z2gvDdI==zr9P&}*Qu5K{TJk`0Bl#GzWoiEnA`c`VOD-S}CRdV=BiE9TCvPC1K;A(f zLOwwL9y#6C`JYJ6C7(o|M$RHvlTRkEBcDRvOFosH?r8hj@+$H$ zax?k+1q`@!#6b@@^ux zkT;Wk-LyYmBWIGgkh96JlMBeLV9BqD{CDy+@_uq)q_+PLawYiyxt99>1mnN8o%}Cy zGxZOW4>0~K^57(G|7&v2D9z$51O@HcHIGs4|)o=+|!*O4zKH;~7Zx05d+?vHli#!n;{kgp(5BVS2gPM$8tC0|88NWPlv@1x6GLe3>mATu;7%+(@2BZYAGH_V?5I{fL}RzKL8yo=>hJ-%Q>>UO?VK zt{_{7X#17qf#h4rh2&ewi^&VgYsppQM)Gas-Q-1ND?{h^V{(AJm|RG{ojjX-2f3Pj zCwVQon%qQQLQXnV=eLxcOBi}_{PW}nGfqXaF>aXqBkOz|QAs3NXkmr-{ zC9fr~B-e4ib02vxVcXnVgW4I+1M)`lhvX)5GuaxX^ZSS#Ab(8GA^(v)fxMesMg9|c9eEFVEBO<0 zD|s*3%Gde-nLPMd&7YEs8UGjZG{)~E*OLEAt|$ME+(`b6>>I4@w~#Z)pOXv7UyzH* zUy>`yt>m@jzmvC<_mf-6{~-I1)A=7D4=4YVTtfaASg!XLlmE^5b>xGL-$DKgjQ^H( zyte-};|G)5$oXVhe30wMQnDSzP87T3hJ0<`M-GhDoJgKed)>&Dj87srle?31#_9Au z$QzhG87%d0A*V3Dj{2!!{I`-$(CO0{KZM+qY@MUy#g=TI^ww3p^%QR%#aln|)=j+p zr_P!)r%W$>YC}<b$sIG?pTJ)d{<^EqZCSJLicIH)Gg^{#xCIa@f2QrCvRShO-wPDZ znRU&a$uk0FQ|8Q=K67%}l#&xoDI&u!oKklEoSA{EXO&C|M8?EMQg8W_=dNN)5vi5) za!F)B7is(dWqSWOx#MnG8I%Fa!IW8)&4pTTFJ%kmunTl}4&`jhd6bouTPe3w9-y=? z)ajEb{glHfiz%m3{^=E~LCWj-UG~4r&Az2l^;^%TeT!xL0rst)th6({NC{_rSkV8~ zu5)XpUEF~MgjgiF07yi!RJ>gR<+Rc#L1p%Qx{mA**P6DfWWiTb-@5A}p}tbnrP zS}98U817nVV8r_*9@5=>5;;fdB})ANlug{TIzlIEub0Gh#H`R{P zKIpHN$Xp~^NK0uyuOEv`t2m3+}p;#=GU;T}-^2mMJ&8E2(`$pL2A5byOn)gKjyAHY%R5btu_a)aYj zAWA6=q3@%vb6&_%amTCA z_8*xDa;y{a*>NWruHx4Qn~w`2~-}&{5+1fA@yYamE*knUrRrTet-Op#-ClOpMFfoev&;;Le6|e zM^6MecG6tfaGY*agnZp5h)C)tkKj6X;`J&n;W7xj*JqU5L*ld!Ynill%Rl^6flCJX?bBBzrAlKEQI8;84!iUecPm=w1 zHtmE{VKrfxe4Hg8Bjsa^d=$usJg}TFUOwbe;e=xO5Pv1w_8Bmkk3ajK6sdfmL>_Jg zBB~t0w@Os4irSife=uq_f?txTM^scxzfja31pg}(RT-A*u~MDTkOrAxRstQcP+_}`(Z#bL$p_dxUEkE!ayqE1He zNQwHD&TDZfuW|&>mndE3K>twTmm&CGiQ1x4S%-w8UPSOFiP9xZ%3xGC+nzpohV^@i z(grt#72_`m{vs5$G8lD}otSJ{eeh>5Lig(KZm(tulhFCUhw$z=7LK-_L^fj9O1#NF z3!&pAh0bSiu;4e@B?z7sipuh$dVFaA7{OBJG#tmJp? z-jG+QWLs4--w_DV)yl%2s#eNQd(PEr*H^yg@rvZ__E1Dgd41*e;J58DL2h`wqQ}Gb z#o&M7FZmvO2E;E_2D@|y^AMmj$UU7IB-hxtBJ@v6ZLd;Gst&3x!k+S`INSF*1^`v6 zFSm!|`D97&D{n;6m)Xs$P@Gip z;;zyjOYP?oB_;2%#C{1vG<#Ir4c_jZ_G{ejd51k`N|{!;-9B{?br;*erb5b(?denI zCEgx#Ys{`<<8uT^a?t*d=3P47qb6os|?TlT-8b1Y)erfVybx7j}IPf&aS z+-Rp^|8~V&pR7oJ)6T&DONv)MRgwH_`$+8nMe$zn8}@P7&rB108=kI6-ePBg&sDs5 zT}AS1_8H&>ig$rG+d1H;6|Z@wB6*Wt0B%-%0Q{U>g}H>Uyal|`z72el z;)eAV$-l6dfU6WQf1x7zCHo%m^NO3nFWNr^?@_#NLq+li`%&;Ay~JMSixtT)*iVA< z6>kTxx1R^!qj=KcR?+ol z!_?yleYt&1FWdejLNUwXIi;C?1IbyPs0@LTv<( zmEdDk@JCcu>91Gmi$fVL5=E(Nch?J*^mj>cwn|^(o#`b1M^*Z|Q2wuk(tDvQqwPvD z5X$JYkfIl=6m4|&?ruZK;-Ltz&r(@?p-S-trD%mLjuyo{rRaq!#g3hMfl|x~uT00z zyi6%JdtURLIb8*RduPs5>Hk}td5g+A24~)(6k~AaJxVbKXFjMD+d1<|75wd;xlyJ6 zZ*k^pD(e`W`Ib@)In(NMHHHw&N%uJqU?<&|@IFMJVVDqGcAuFdoIdqh6l0C5c0IeLngo|GVqR_RH;DG>c+9-44(qTf2P&tqTvsxHoJj!opA`ocxySl3hYQhr8jOiP5 zc&)1m_IEYGu^8vQO2<^B30+Nadsh>@)YSxk2}>ZO_cyvV6DJg}(lI4CH!ML+URu!A z1W$K0L37suQ3At|s`rs|k+6DYHwJ zzNl*nI(K>9cWLaeVa8(W&_`fa+@-po-_-<_T}#lpv$lPg#`N}G@(uiT z$51J2Ahx|>!U#-vE$gmBm9RGB`rFYr8QkyNry$V2AKsHcPqk5NTDDIs$TF>4zNP|* zH9u<&RNeA*9!^8{Zuthm#}NBAZbdldIleQL?bClKly4hBk?(WbkjF9+>3Pq zo`OaBtGZN|HBd49p zE1@3YJ^pDsvJT#WeXR95iv?2dv%OVu(N6iPpsx`{C`O~DJS3R3@HFD1f+=Tv_?V!- z*;9T}F#S^x*9m5P0aTWs6U_YD!wrIg6m&Ti`wPK=hk5ub!NI*wXY3}yA&DNoE|@jQ zQ+`u0`y>zF794hlhwlguAK~GA)l)n%xUgVkjyI{%5$6D5H5_`aQ+@mY) zOdK$2K9nmp;Jyn_U5B`C`p#W9+nI&LJ+5%wn;|78_216-YVloT?56$A$ykQqo}a_4 zbsux_w}O0AuP#wO?)eW;Qty1r`VCU_{1?c7J;_S_vvVPAHHod?J4uhgg8vU+bs&Snf-@D8EH9i+ZcJ^y&Nox9C*JBD+vxf_g!6*4^RsE%b27~Qi>Y@x+Gdb zZj`v?l@;CJ3tGbpZAH@W?MKiJUWc|@zPKXkeR~dih(4^BFGy;#X9uxH@P;5ZEa>%j zJGWTp)<)TVzdd8_HB7%|0Y=A0SnhF&$l)gmocUH$%09^ zQKOF5Y@w9DqRQOX&D8JC|3$0x$lS%QJlg;dTF95|RIP01A;eATTO=&

    pLofT6t3q2(BNxs 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%0ALgMZ=WH&aOZrSSq^pP<~26U`3?;mHsE`Bg!l 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 z z5v}KB|9oj8JoA+J*~SmE;DI^*dB}P2>{5x7H1gMJ`QN48E&T8(JpZ)VBi^&D7vQ;u z5)WzY{{VhQwd8sI+<@=lS)N0Z#{c`x5dS0|^XLCV;6Z*bOt)8Gc%Z)cQ`|V!m}ZJi1ldH+7JF@TB4hc@FE4kK8WtV`Kj(@W64h|E&AzFYwr&qTi;y z_MJ(8`Am2e-VvVfAbw6zb{Ra@Mf$JK+XEH%7|6@&I`|Uw#ABjg-=CatxO+c9YQP+& zA%&h*$j^(&JYgwzJ_gV9m-r0ghYj%5kMu|6KZhSNUFHL?G4AX&3qN!bJ$dAV@GUP5 zRF=GPm>5*9<(K)}eLVcLA4LB(B;3XD{olminfS_Kz2x;3M~zxYf_27y?h8?w^-VhDUz(`+1(? zUQ6WlX~f_~HCs%nT8?zJcei z7C$6t-@WFDA2P33Daio#9He;@|8)Tyz7O9YEJ6QJc;Yi@7d?NdhNmBv{uQ9ydGJ5` z`Q!O=cz&bUsq@2q@YrC(H|TJpp6i?0R^V@9*gNxfgEV zDDkYHhxV+))qL{ERZ=4H@FDVvHzf~5;NQbDo&0&gnpfOE%@udUupKt6rU;0scu+&u7x24OS`E8()jCXPT&;$ASO3@P}4u`>GS;><& z@>3P(jpuMW^66@^)1qG2!dLt@NJ)RmAaMsg@jLm7a-WBvdXV^Y8~JdH;+_I|`6co{ z8uw#2ULbx*v9A?Gz60F4Q~aMIuFADM_vb{A9}KtOh$<4t&MELT`=auxWzE-m_}xRz zSHf=!%lM+_nb&JQzYJCSwfsZyz%#CZ<+CJV(s z3C6D&=Ntyl-YxN<*B3`?`KQHl&Bw!A43~P%L(f#Wy+P~`;J4+9dko~|syg`1b?~+5 zPgfB?#M`^@NMef8oNpxsd{>8_9mrcBNS@JtZoEkRW0l900$ty>@VxOo?jG>S0FlqA zvn;Eh!&QE(@#nWm$OqDrmvkI1fXAPa_KoAW^Wnk$WgVJE|6TBq@jR>N;n5fUdftPl z`5l}9dbYw7e@Gnae7n=(%Kj;S`&%r=KgRtVCGgnq(!YYVOK*6V{oXj`j)0dK&vQNr zo_a^}kCtBwPwtTT%+Y_(hi867o^o%4+r46{#3=rJ7@nUdda~$w4IVr~;&~xfme8le|LwnPr{wIK0orGQV2URP=9w=a)%8$_ci%!R>Du_o?rn z@a*9-US#oSYiD8Q&O>6Xzar?d9qwMY%3dt_NB4_i@NfJ3=drWkU8)8t4c+z?MT_A1 z?f!PW5+1u%>YE^b?svEw{}#_R!hGumHH);PI2#Uu`b-G+ZY2 zO0Po?ad?p8RNiywi@a6spJz^}Lq6tm_j$9er;8Tqb(+IfzwYPn*EiOo=YGYV-wpZE zKfb>P&l|t6^e4ho_$RC7>q~!3!*lTW8%v&s@ANlXD6g@VB!8&-ljg0$w%Kbv? zZ|(QPPI${@(vI`c-^>}%-MpGVlkpc`;&3qhCLOeC8<0=eoWx!&9ZA-=ZBqRh+^+hu@Ho4iUfU zIBdSc^+Vxb7sVa_tgTcZ>i&3S9rDAGPhKeTqxTJ};pwU>r6)tbTV98rvyqQ*-64Q! zm%~$^i{JFR^#OR+c;3r8_$=c&tDnNH?vj7<`0a0aVo&j>_D}n>iu)&|xHJF!MCP$E z^bCOqZ}jKADeyo;f7~vDN4m-SG=QFS;q@j<|8=&_)!!rV6~=S&H^TGp`sa=RgNNFQ z-|oWy_0N_#-}`0B^E%F3J6z4HPw!{?cU@Z z@k4TCOxY8s+yfQ&RFs$9khi%1Q0K`oJoCBOpG1BXJohVk9{nf7FJ%9@8u|0#_wpQx zx$vvt-QSS$_f-7$I6QME`3nEP3D0*HKg8i%;P%JTUMcMP5q?dt0jk75k>8~_MtBbU zohyEOyOXI=Mg_Aiaj>|>;TW6OgvEEBjLdf z61Pe091BnJ{Q{j=XT$GmChgLI>$58y?v7tC8}s4IlzgH8Z$?jkVoZIQK;%An;7l2J zbh)p>Ya0$$k{$Mu6E?$>!^D2wkA8*Qp9$CVzLI(%1W!Ic7E;j84DKH&aYfJyK?HRxpQh4I1)8;E2qzzTU|A)vS#7j`3owm z7A>`=&Yc~fRlBgZrbk6-S~R`nRt+xEPzEUBI~v&Z79`6cDyaJa4y zLUnym>ew)L+?Wx=#zp%NJhrmTd>=MG4;k-m|NGM3#`|8z`wHW|p}*A7Uux(N8~VeB z{;=B&p8AB1@*EHOJ`WlCLWaJOaek=WIN$JB$gtl~Z&+7usdlq_h2=#k>~GnDV+Qvh zH@I@}*pWjjql3p)4jDFL@K|3t)#2%dpSs z#J=|HW!UF*ME~c8eZ36(dKvchGVJSR*yoH2KK;E7`+6Jp^)~G5ZP@1|0KY!NzTSp? zy$$<%8}@~4!@!X3TKHe@aqau>oon5H?+n{Qwo#doZPX@Y7o1|$CuAEH3fV@DLe4|M zeJ%*uW}Q@*_jKBjIRJ!0rlld%(vWFs!5~vG3WZEd)wnfg+`vVZ;gTM%TlH(Vbp6^b zSig45)URE~=+~}K^lP^e{o3_}e(gFzzg7;|{l;6es`&0tyk)Bj@BYMFx~k~zPrT*( zE9kYr88iPgC+xLA4fa}F*lR)9Tm7)t0ySaSeU8@xHPzVtiPr)(NztFE8O-iCKKFYq zDD_%U>b0QM+XSUv3rf9>pk`XSoHDNu%Dg@(^ID*0ce~H=TA&8P-Jf_ZP($GEPmB&> z_GqUiJe|Rae7E|ZPu=1@Z;j4q6jad94BZ8N$n~2?y9yHTd)G(a_l9vQK)j#3E#!G$ zYRIeR^nPy28}^hrv$C4n>P6F?N&mFDl?!U8Tk#oloyEeeT4%EFyqsFOU{O3icm6`> z?Si?B=1;BdQCc3V=wVw^E9cI47Acj^EKVb57PxSJ)ttf)X3UwVbXLx;U0CHV9#ko_ zoaM~|NAJ`{^XEHj5+$*__)7Ovr?MsEZN+BHU9ikq4bA?Khu}4}3!HhTE3FmHnCmk4 z!CT*scPjMEfZg~@V__HYyEHB4`>noRenHbi}7FoTb*KzD^Q0r&M8c4i+{iX<>5~ z7dEGPVRIf>S{mwM_b~E7X=%6^EG-7hiox|FH7YAsqq1T(Dl1l_@?teAFIJ=SVl^r+R-^J_H7YMwqw-=kDlb-} z@?teAFIJ<9Vl}ELR-=kyHL569ql#iRswh^YiefdYC|0A2Vl}ELR->N9YSgn>jd~WV zQO{yE>RGHtJ&V<-XR#XfELNkQ#cI^ESdDrWt5L6FHR@HYM!kyFs8_KX^(t1QUd3wE zt5}VC6{}INA~gz|>)+De#i|%CrY~GXUukKv(|cYfA3!vLQ3ZUCP3ZUCP3ZUCP3ZUCP3ZNU#1<(y=1D4rtpcX(k zSPNj08kN~aYE)(ysZp6-q()_-Vmd=bbrz|6nO&srWp%ybYkmwF*H9fZtu5OVsqw;L{*KVxC-|DzkalYCDrl!e?-EP!q( z7C<+^3ZNTc1<(z!0_X;q3BzuH6+kz@3ZUB&3ZUB&3ShAsg^SfFT&zanVl`5uUqL~| zYNSR#Q&O!Q3ShAsl@_Z}X|WoW7OPQdu^N>Yt5IpOHYzPvBeilcjV~+KMr!3yAX%(N zYUNNMS*%8Cy9pDXCTt1+Z8fsg*;4WU)3iDjna)1j$hkG#Z{WO{J-5c4RjLmv-R-&gRZHAW zMb9k=<<20ju4z|>kij6cPh6Vh(Zr=!^S7!I@kx?a4BYk z&-m!D(UlYWj~O<|5q58&Fbysc9yWT=;IRXhv~SR6y;!Kh-PU#X(%fy=%93#-qt2;r zOYE+hZtmSc2k&lBq?y%1w5*7|OXkLF=a|!ccZRlGo0>oRi5u_6EKY@{$y`%S=2~m8 z-fr8tw+NWdbZ)3wP+M6t(Y=+yy<_12F6LjVxLcq9)xnJqmw0APY8`Db)fr6Y*4AW2 z^r@autQIx3)7(AMl0m~ps<7!@q^4TN8(zia-0-TI;q0&1&Y8aOWG6tpCpZhsLLbtD z<}O;O)^qy)p9exZs|;f}7|H?xHKa zjm|9Ays<7^c*WJ+y)yfJ*u01vHt(GXn|D`)&FjKp^OlXUc~eK&yzL`w_WiKg_rnE! zzu;CDGZ}=;WDqj@e#q?mA+zs?%&s0XyL!m%>LIgdhs>TGGJAH&ye}za-nbMp?`#U0 zeLrOO{g8R(FJxZ%3z=8`Lgtmfka?jmWbTNE%!Cp$6H3V3h7OtA&>?dhI%MAW7Bcsx zLuOJ6nfuZqbEh_Brmc{fwnApw3YlpuWTvfW{(P+Jt}POpoYy}S!(XnmO42|W;DB(WonsG;<(wF6}bx;_r3Aq zg#IJO4<1|h=YyR4jqCn&+%Pp^uS56b(WCw^=enAApYNH+yR$lX$l5(!bLVtE;LhmW zB4<_2SyHu7&)@X>-4&cwHPiX{zqM#@cPsb*N6MX)i|+r6E+^>!Kct+%uTyI5n1SO4 zj~N*qGkW0Qv15mgI>uRaI*no0R&D$mW4PMY^Z7(=_8U@a>(D3VF3fzuT}JwVS_ztZ zw3MgA?!HZ7cQdIgAbwrCDZS^pt13hP?t2#g(KTVA%0k1d4c%klAX>exPQ z`xNPp#9wQ#%igQJ_FCKPvTYZn)kq+O)M`ZtiGCnb1)c&e0WY0?ETy9;FOm8Mls6C$ zC{HK?iAS36`^Fe^j`^>DyLL$&Re7)fHZNn2`xtY~^F>7{UO5V256E^ot4@l?Uq5;L z{ja`x_*5O7zdh`it6hBAu!CE)Eqnb9#ba*`Kt?{3{PF&HqW zyT8}oU{=k*nB^Joe`{ktf2#oGFr0>xRFtFA58rWK{d=5O{~nROe~*~lyC)}e{~p(@ ze~)wR-y??eUO~8_4>|dsdOYNCR;Eh-Jx;8DFPuSXVTYW}L%wDusr1?_p5`(M&b0p$ zXWH}W$no62N6PKr@1AZfAtMuNJ%ejA#fakq32^%m)o@i5E%iS5$BtPyt z5cP3(n&J}oM(G_oH{)`#I_%E+PPCo{qqxfFSG6!XK~`qJh2Av83a@NodNy0a$<+E( zdMK&TQ2(BhLQKV3T3o{4G+$r#o9(UtU>wPUg3(T|+2wXW?SAd?%kN&i>0W;I)$1p3 zutImQ0*<}?%|mRt(DgiZcDY7k?+oC0{PlM)zW@5!Z(-Y3eHETTrC8pab;_YN zH{um6-6bF_Ax+WUoa<+uq|M_pedidh|{io6r&M%hR`Tnp)opsVH?Pqs7WJBq#+%n@6ssS+=2{34FJGf+tZcmfvztyY zU!!TP@AaEbFJGf+tn&4nPA^}hX{`12n@%rZqiL-8^_xyFU!!SYh>Mh;y^8hSYcz}{ zzjnj*-D@pZ*cEk1EYc!0dzIMa)-Qk9*Xm)k?n;8gK zX?ue&i+vrdUxV)kI$!g3pQYZ0PP=7d7ScknG0(F9rt{BJ@|9m2ff=*;5(Ua4$zOW&viMo-HQqm z;Wc_u@Q1;1{IM;biaFuRHhJE*t&q2EE97n43VGYMLf-bqY%8RqS=c#hTQ3#t!WBI# z_(QJ<{#bts>)^`zQ>+bF*54iL?~e6%$NIZt{oS$t?pS{c+F_5X^`{^ouB<=B0C8pg zDQ1W(>rWv?Tv>mgTYsNhf1g`_pId*QTYsNhe+pJ&H>~xiSSGHlKgB+AW&J5MiYx0+ zp;TO1e|N3FyVl=b>+i1hch~y6YyBxEi+#7&pJKSUvi=m}#g+A^kT9;SKShjjW&M3& z{e5BmePR85Vf}q!{e5BmDHe?#zSf@tYq+xh6hy<7^{2=;uB<;r%5i1=-LwAgS%3Ge zzkAl-J?rnD^{0?K_7Yov3en@r`cniSSJs~*{+inxci;NEZ~fi3{_b0U z_pQGP!;RRrZ2e8>X~&iIH!=L2Sbr0vhl%w!v8}-q>u+NHO{~9(^*6EpCf47?`a7}y zPOQHZ>+i(+JF)&wtiKcM@5K5$vHni1zZ2{4#QHn2{!XmF6YKB9`kPvRQ|oVP{Y|aE zsr5It{-)O7)cTuRe^cvkYW+>Ezp3>%wf?5o-_-h>S${L@Z)W|?tiPG{H?#g`*5Azf zn^}J|>u+ZL&8)wf^*6KroLSARzq$1{xBlkV-`x6}TYq!wZ*Kj~t-rbTH@E)g*5BOv zn_GX_mrZ1t+x+I%-@^J^Sbq!aZ(;o{tiOfzx3K;e*5AVVTUdV!>u+KGEv&zV^|!G8 z7S^AYb-`wL1*rMgy0nTcytYoq+Ihrl>(;8R@Y*`I+A6%ZuE#g6@9|CRe05fZ9$feD5OE5=nUN z{ks&k6cpa~{#}sTUM=4D{#}-iU6_ttnvPwZj$NKw77V^~iE4Q>ymt7zP_>L3-go?S zxoWvOyl-e`*$I0``LKk`*%5OIZM3n z{ky0gyR03%upPU!9lN+4yS%j|D17e{*V3kV?ftvZwS+6)_x@e(TB;WBd;cza$1Z!v zE_}x>ea9|-$1Z;@84TaM1h#B3UVHy8gl&@`?|c6)hb?7|_q~4?#bcMnV;9C_m&Rik z$77ermIH_HT_Ri79Iw597s{4z$NS#D%Vo>d<9+YnMf2EY^Vo&+*roH>#q-$Z^VkLS z*d_GXMfBKZ^w@>;*roK?#q`+a^wfOB6 zyNN+u%(wd`?2yvxZvO57!zbUu$PmMt>|ylmV9;Prn{KvUUe33eOmiJq^Ysi?Ons_A z$@y}}+4~2$wZawu%(sV&ZgP5x1QLW{M%d=?P50fi7jM7?^gI3JZGYkQ*Dn!HvzH(J z=9?$>^UIgtJ;L#1y8YERFCY3F<+JqFq$qi@_2EDNYK_HPe|-aW@Ho7HRQZi{5WnILb|nV|IUQXM_Q__wU!GbiUZ12!i*4KlD?gkqC#O5Q zrRPM><#Yo4P_=~_3I^YRa>vvo)rGQj7)H76%-wW0SSO98R;2voM8f7p)} z=X=f)t=?2--4_D?seQjhxn>q2+wE^4fm+Y+=s7#|mEzCNJMvq=E=i%dWUi0@25+2f zSz3%BVwm5525OpTY7fWR$lB}{aBm&fv(aWX>%M)AacG>dJ{HRl-Rmb$f6(nFmq2C| z<%Lk_kfOSpV7>SR@KlK!;7RZ0#l_F@GQ!}X!YkS(l4J0Du9ZUp@qR9)_UK`pay8t8id9&65e!)3^uEr?}tF(R=d1g@tb9@wnJCFM$F^uS&srPmmQ-yMKQ z0q+g;0&#mhTdX#i6KH38x!3OzelT{6Xdt$}fkEhoMc3mF+gu%x)pE*(i$&AcOXlR@ z(FoiG_%{W_)-!N;{KLEYagOYk)nTorhcR33sE7AnoI=V&eD!aiAPF8w*NkH_r9e(M8OgwEy~pUt=$TMQ?ga$hp;X|K z_3`JIOUMEVnj5gLBna>6l?zS_sK}CnCQ*XLl4eQT!1*!TyglL__I?4@p6^MCYHt~s z@=GR^+PB0xK5y@-vF>iY$%&Yr#b5Y@x{FD6=TX}^%lJGM}trJXBU`T*6Qr=Kz37P*>V+AjQu(8`xG5o%jXas@~!9 zKwF3x`uulvj@Zu!Cp#Oi!Z+DUL6qjqCVe!_h_^NRJ{^!_m7UlP94i9K8Z8}x=TE-JKqk1F%%m~D%a3_G0SN{ z72|eL#Rr7V2gEgJ-IJGJ*-XetG^}{1*V|3Kwwq7aGomB`1;V0b$3Ik)kzufQ<#u$w zThM0ED}bTY?tE{pJ8a}IlgV`gRSD}hh4#&<7((qpcBEc-NP74A6%iY?d-|qs3BPkkGtz@!%AK9_`1+I+W5YU&@8%Fs3 zSh#gLS+3-Q;Zq`8xuJ&7PTt3@2rlb+-l zT@mDt1LWO?Un5btA)4O>3?Nr`OS+{50^*hvOG6VPX^1`Q%8sf=(!kU8&Ocu6Hxo5; z|7JIt{RloY9|NvYUnR6-TnWAFLx`c-CXmA}+&Jvs9YB3lK5yLf!kipu`;I+U=}TBE zM~`>V(U59tZ>cPx*;W__DZCB?0s0uk;{Hug1s+L(y{pnZ^cU#z3+;JQT@b3bU#N&F z6Ycf%o(k>Vyn!ure0ooNBW~Wn?mS&eRTO7_@(xRLD07{+~N$D@bpYAIzs?cSRJ4>Vw(VEER4U>(?R5U0;&dhdxjZ?y#GiDH zGo0ehv2Ci<{e9X43d#;Mv9IJwUbYP+d=}k#1o_VE-2O;NxDmyM*2fXX(Yt z#8+o`mb2yM9Vi_zN!K62rD#bTu_Uyy?IXJOL_b4n0)|L3H#OC|S>TQQS8$P0tm9#`ZlB*`o!mG<$ z#lh~GgPvzd=d`|{ihWqqSOkArt=QtIG+S@kF?r^xyr(*A5I;;2qymfHrx%AV)|vyx zEx=)UvP7g|xto9=;*<@NDLfS5);Q3B3Y+fwXS@Cf;Mp|A>uvHrv`t0WtntzV6~#0H ze1i3XG>-d}fZ(36*5gTfn^6Sxb+Va#94#k6DX7W_>R<-0H%}E<@r(1#rSw5lsnG%6 zqf6H3Bk`kF;1otYhsc9p@4Cs!?#4GG&Up83L{SR~_in^D;t_EH&*E13tlYWru-wDX z-vFn31}#?1Z~o4Qeps5d^v@6^Wk$O z+-PaE8iS8)HS7_-fb53(h{a4_@HTGwDjvOREpVy*!|vkZ#%A>0>nGjo*H3Qg$MffZ zMSovCc{=*;#jBU!eDmZ>9A5eS*&87YKP29j4_~}|(>;6f?9G!eN2CVYv$0bTYC61o z3@HH|6G**y1H4zFo-e~}0kvSL`W0hS3?UKO6uKgu8Q^_D?d9wiT8tZD;n-J(ZGDxL z5V{Hq1nS#{Z3x-b;@4e+>bkF9J$#O%4_|zVGdb;mPXGP%o0pFse&c(LyEhLJBIg?h z%OkoPbzlA_>fJqitXI&PBAigxm`x?Zvm4-T+dXbQeeqrQn~powT$nAo)ss> zHH=K1#MtaDXeCd?*w9U@rR<9B8E3X^dRSVsHy1CED8P>PY}7mvH|luIB@5;NYdwcreCzJ2iE z={L_FJ??JZxQ!wK(x0K=Q7w|Zz)&H}p}n8rte9vSlUA$VDD`jt-{!#~6CxJV(Ujc^ z3b|o(bIAEjdBxeY9R-pRi4n*dcibP~pMj=qrwTc61oz zy)2O7@QJOHb*IfIUaI?(5b;i?B3H*wFzwC2M_b{6;lld~oG!CPJ^{RKz-XpYh_nTm z$1vgO{dnswI&wJ@szKPba{}x;r14CRN;NyqQ+!+A91OS-BIkkzy ze)A5_i{(0yBqNm*TyKrf9nE)+ty*O^i`k@+YuZ{&ngLoIchC&6`ALel!yaqU z7^Z-1HUnxMfNw)7fUO8?=}c}#dmr*z6%QA4Qo4$E#3GD7p|(g7=gMN;pfbX+HI4JZ zgC9J3_4?V%7wuff;*eU$hb*e$PlJC3uyVkpqo*ShDd2b)TS zVpK;-7sb(%Hs&EDIW~o7Nc%iVaMOGTpWcy_q%=hzTQZm?YG5xaL`*w(!Ryy4=@dNPt1E zpzDkl^Ub0q9UFHbgl9ViI*5R6YL#UhQ#2g(X_E}x2}_5I-!1d5E9KNY!OO5dfWRAQ zq)k-|iX1nREnBA*6y*FLIJ2W`HUZ4E#VTKgJqlJ%oscQncGl z@89os^zo*3WGyv7(W}1bw*W_Lonc=B@aAfM>AWx)>`-TQso=`LR31i587CAPviQ0J z*hR5%xy|ScJHuak7w{JuK>k&r*uWf3NRmwDj${7TdIQDOQ|Jo20$G(FOO*&pq?nQV zqgyUIb?`%Ci>>hyP_9LwmZCWPQkkVvRS@y6E=L0l=n$d9q!KL*F?jV7!)PHZ;YV!& z;W&+zTBT^)S`6MfG1eOTCW6A47rnreB4W93n9SJA5QKC)4Sob|)s#@<0xScB%om!p zOh-ei9}q_xzN1df0iMF#+re{s^07OG^BMp>MlsMN7reK=iDv|>oK)2?X{U5|n2HL| zRMJsn%)$y$jC}-n!1ZXoRc=Iy7mW4fVzWUMk1;qnH(=Eo&ARNjFE=1o$Q+9gD12*B zCoN+(N;ourZ+S<{jq-9tq@*x-XtJ6rbT9Z~_-=_AEt2(+MOtXpjIjJV*-?o@dbJhl zj$HDnARN4(&aio?X%azQD3y=ta(QB`QjeDerdbh|-AtwAfPJNs?CzySOM*FZ(%E{H zhr@(#!~#1i(b>LlHLmi?(&_CyD=tts4hsR1qyPXGc?@tdWx{6?`c09OJwRvzu6#9f z53XQ0eF&LXRB0Q$4A#g;M2C)xs$gz0-UnKZI1Mujib#8qlFZK>&duQX}z}i z2OHAtrYvmxoG{kUg>c1gwWUZ*kZ+K z8&q$rK4&=J;Dsry8eHaRBx)!17VOA$E`TlA9c!v*l^>9YF!}*ei}AILg5jxZ&r+~- z-H&L6be(1Xo#4|Xnc7lFZWN2#K$0+fi9!zKvxZvN0?qLZgB9VEKf2gN2NR$?vZ=T2 zC!|QU2q%bzWZUBB)o>-AS`}vC-rN<^b3xMXU!o>xUdDkB-_Q3eDB)a8(`gn* zIt|<{5J7MxFOcHUj<;D+2=}VV_!3Qw0j0GIsakI(6c-r^4Ud5b+}9IvEwWEVT19y( zLu2&y`#RYO{JkQcPWkA}rKTv6W$}82e|p$n`~5 zFMaPGE*nWZ116qgJ``}l5ktGOb&pAyF4in4P&n{jYwC!vwUcn(6F<3Ez)`&5i`KZ3 zauUe0t$YU1oJ^nd&jYK%@F@BnL24SIjk&<1$ODZVIF1N_HAW@y9n_Zd-*E#&^;dx_eZsd_NFK zB1t*+&8`?2SOPIvOs^(liOt*t>Ohb%n&fhXf$ba8igmp+rN9=~k?2aEHw`g|cA!X@hc*QV0dCqV=&n&lkeLxi zXaU|@;B-=I(x+(E^le&*{tCokGd?c_LanXCe{2 zc4D&-Ibt!F3}dR!vJHHn!XGfGmU(uocXv3LC0yQ0#&7Ty&vT z&%Ce&rez1B{O>v}{In8@f_){D4&A}IZ9Daj!XH`5IBZXl=Bkudld4J)g5UBVMX)-1r>ZV!R%S84KqB(+Lnc>sq+qiXPz(ZG zx19`LY$xLjFg9(j0cm}eRE?|)MN1azSd(BczIgU+z&b$V-Is2PwqdBgvTcCE%m#r7 zAF5=@i3_EkxpDm#OHW!+WEd!EqkXG7$+T2@6Rj&z#0Ij3|8oKtlyAivamv8Ib0qh{ zxY0&b&YXfnIw6HbkDru*7$mq(Kxb?Q<|;S<5C`>LjNpXGT^LeDf~i7c^_mRK14<@I zP*eaYrAAy7haBk|=FiTC>15*3kupLEx|B}UPqqR!0pP@IZW1*>v7sIEXSnYobdXr| z7O}OTw1?Au&CtKN+8tnKurX8vyU;_ou!_2%$q6dl=rOr~aG-|oNsGZA%DXfSzQW~?#IAZzTFhW4g z$p;N`n9WZPNEeq=B2$t1-J4;eji7>Ntd=NRGjyHcgLo{2-g1GY3JAhni13xgnj**@ zZu3DI!npsD2;mk>r-ceD`GJ!oAbMDjcyvg&HAdimZo7q@s&l*Tj!0*A5(Z+&vD+Sd zR)OE>b|Rp((gf11CrtwFeL?h%pj_RtUO$4i&anpAPZ!vSP6+lO{n=thWS9(QTgp5X zqMoPZ&e0+zHnt%yaY+~=h4SY{Xo*$^ck?!a7xtCgm};mBs8fQiR`>`_nuQ39zfm+S z`ip&t9*%1fGJK&#_5ga)H5y!Xa|DS}%&HpV?S=M33PWD;oZO{x4YejfaBXLegu&X8 zTUv*K<}g=lm;=-Zr~4 zmjJye?Z7O;;x~QPN5&dOq`P)%l(r5?6qGQegxy+)eDENtFys}Z?mJ5oeLCO2lI!L* z6SlA(j~{m^N#LUjXpMuQLu_)t#3$6*>H+}S4KfKiA-KZUlSg>W+VjqX8`z?X9hImX zuSnkgty2DJti5w8X2$YulnhXc>IHWDResJY@1+QATlxDcd zL5hGVeTa6Dmy77=1P2y__}%p?tH>=FrVN+dFO)v%O$3Uig%=7K!fT+FXc0?>Mv^8R ze6^#Gv_tnQlEP@+ajypA$iDS0`z>v!Yl?anq%C#@#U$IKl%&xHX54^I9(9m{l}VKk z1JA2&)AJ*R7!mKkM4G1#%=Rm+C>BA%zaF%Pkspkp5t9bAU|30&6z@Ma6K?$FfrVXS z>o?*XnIYO>K%?0$m(>D_iZ_e`6DPHg3fbo-@)+2qaMxlThHhFGt3|F!@+)u zY%yQ-SOk%^S)3J_dQn<-D2XUO>1g{dG1ekV8fz!mK-H`Vbzt~&I2o44eazR9k#fOf=0>1W&%pg=xIy2pM90!6YsUs!P_A9|n) zz!f6DB~7R`4dJ2;^16um0Is+W#gl*QKpF@t`4`Bws(L|{sFvKCusWq4XmZxRH*aHZ z$iFA90&=$f�U%G!uAOmO~;z{PnkwgHl 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�aC%G!@kx%1dJtp~b;v97iV9i_>Vl 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ℑHaBA@J35DQlOxbv<_K1rO8{myZg_4i_f6wDLP|B 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�>3#S`OKc#i_G{;D#6O-lpvT@2 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 z zN{F=PN-#&Jrk|G=Fyha`f!}I;@GX=Yy|FbsAusqiidgWw`0IvxrPbgXIyGAc+-G*_ zPw_JT#9ek+evkE0jBnQTV_Ni~?Vv%6hB+?yqQ9fm`(k$|e9E&%XP7GhDgu{l(P%qU zmAB2iNGpHH!1er5T2pue67!!1zn1bW&Siaw%0ts165PUL@kF$5^kv~HHg2+I{~EkW z`5YEJ3~{bV=nQj`777lo4Nt|zQ#rwW_=szoQHC%2vKZ}YvvYy6ul#qk=#LZqDoq;EvVd3&ZAj-=ZqVLdcAK^6(nkn!M zVC(&^zmdnfb0(AEPVk>D87x+uqm{46dbyZ82kx~nIW67~Me+h16G8_3*F&6)m%oXc zTEiw8kR_!Dq_ZzrN2TU&jG9;}Vcv<~d4)=3Dt`GkzMsC=@a1`d0wF^a@I2luF1boa zBxz!=thpQqXwGluv~kI=@P?TUM`CajTTNLrpsW5>2%r-A98Xu4g5q9@S&9_=z81eE z<{tcJBW5O^Tf`hmBj%D6V(Khnu0Z0XXv?OR5^i1x6|S6%qyNr1D)zico*ozik=Xkp zd4?w-Se#twB`S`M52B9?zg=Y4{J{W%)KE+e+g|K~hpwhhUBX@djIU5au<#Ko)2H8A zhjf%`?5oyUH2}voJ`eePKdz`;jtizb2n=A|r7a$85{~Yo4?=$n%YVbGE&06zpbF=T zOLB1G*6;kqB8EJD3f1_OPoMuBv^tgquJl05N0(8Gp%&;C-U4yO0$aqEec&rU>Q$z^ zWjubXB?nwjnT_emdbbh&68+=UW3f&N}y+yid!+HGCKO;R<8UWAY6+@**9 z=e#K2sVu$=7a^Xqel9MUWIz15BFRIz5O4O<#un!mFm#@+z4W)}U|;mkIt*^0J1`2? zL2K$klS+gugoK!2#}sis;>@+6p537?It=QMt0AmYUnHN@uBMq>vFK>$meAgivSPi4 zy&@2c8o2jsXI>(yI%C`1u4a<^w(YR?XFng0*n{XIgmeXP`Al z!(wu@X>dBz4bxl=TDT6gA@ON^7*gd0ze4O%Jiw1sO_@!~rx{HOMz;*y)nbgxn@#~( zTV}g%<z0roi!RAv{tqSdV+;L*VE#9aCphkM*b+-);j<(2AGVo4a4#6D>Q2G*FThl! zH&Jj_CDcJg=uuc8TG<;o#I#tP?i(x0>2W>%?16+ z3V}($L-8L}mMbE6i=Wu{@dNUtx1<<$JA5St&GjD)FIZo&39Dt|gQdw{aIk*Q@Pdwl z16t)Ky&1>%0tAau6xGo0*~0I}3%j;!mCe>uFhrh&u=P!9RQAk_Yb>hn&FHdnyhwIb zBw&eK*%qAGh=|Jw+1RTuBRArQjDf}?i{q|D{*aStyrnjs68RK4ncopJCDGJcvYA0N zr4uHJ_=bIuY;q;?3cstd$N&S}i=O{1AkKA3m-~m1#-1W~_m5F9URaG)n=*S!iF}J+ zSiZ>aFXj~}HP^GycQB?{un&etY~6!=Ln$gg^Rwws0z|(}JSbSEbhH3ZYD`pGazb z$@qV~!D9TKXe>IbGqnB&JSOw2g883A%QUmqz0Sv3xagV3*^9l%ffD&LYw-y>(;guN zgTH7|KP{Fw5}yh_pvv!y;!-P_TDxaZ%onU(%k@_6Ch^;zwHt@W|5EL|sF*pZNA1w; zqIqI@L%M4h_>r>WQf0+7%(o|FzWsG)y8P}bD%ei>-BGYxt2_kx-NPw&!2x(bA-|l5 zbG}_{jh43fnuCCIbq}Jp)nOim|4?+4Ed~H!GIjN0aFqEeh&KjZA~}Co&qUv4q8xPM zydg@YRS1_H>BXELOKF6oUBE z$*ecG?NFMRb+5F%Mw?;ehH{W0(Bk|{CopUJ@{t}fm zUc9K+`VC~FKO)ho)UO@1iXX< zW88y`K*=HeDCfE{hMyav>5`mJ*zpMPzW^UnLw^)wnkV`q?HGUbSsH%+=pV)S8Gh9= z^rJ#meWWb86&FT_u%S5VcqCAwp`mb+6p7^1WP*IZzjHd;9jyL?O9J@7pluq5j zqvynSFKx%9Kll+boTg7~jf=-hKKzS4il^o%8K?+ar{cvNvjD&I`UO5U={csfi6Nbv zO|x;9>bQu%W$bo|43#C{#XUdUhF`0@Y0h`|w^u(3WBq2Vtj{aoRMl@KvQNaP`Smt; z>{cu;Y%SlkAYPlB*rZ;b6X=5_r17|0e;4*URw)HWz{2hDChG7wvDs5w;<^01;IK#{ z_;*NPhu77>!?Cfq3pd5!6JJcriT^o+-(>kSt?~zm^2HZvBp6?Wgws<<5Luy5(r9=l zW&Ui}e+%lrzGwYA%Gaa*eG$j|zf}L!{R&5G`Vp)FnNH@6Ruzfx#gSYpr2DaRA?ESN zJeR(Yz2gyrS%476vHss&d^>yU=GB zLlI88>cp-93$5J&L^L?q{wcu^Wb|uCd-a>)RBY42dpqt@KB>D)3FO|Tyj2(8qii*l zSL%X=nhqynTVm+h*N?#m_0wWA3ShI}Tyjbu8P|>BA(A#p)$K>AIG<7&Bo)#-C3w>>lQsb5nOZdjUVBg7wvDd zrN?(7{qL9_DLD%jIm%){?r2h$+3@CUk^ZV&1Tce&vd)ys$}f`?*(Ip>0#(5OI{o_G z(N_NYQb9h*P9wh!RYDhZUTF^`DxdY}@IaPwaH@G#|pn|Krc{62VpafSABqFr;{wcp@| zZ8oQg22wlM76oAEU6rq{VFzl_*_d4<+dqDK^r}2{4OT2UqO!qHi!v5^Zb&uc)XT03n3HUpcSA3EX;UW2=W(2@SZ!mFc&^;%_)IS@%gM+&S5(Hs-N zL)uE(%dnD`D|5?GH;b5S;4(DVBOM}Il?a#cUmc!U?+BEouE6DYzqP*eAhy8zb}+uR z+XhhuD{X?#v{PJ_m{Ff^r_d_v;y)yLr)PZ~zdp0Xzok?9d@ z7Kj?Ac37cyMFR1#%EF^qMs4#G+BILPxk$F_X>8X*w(AsBLrH7b7STK@?MnH`q*k`8 zaeM;WlM!2J&)}SswdHemQy7i-&Tc8R<#RR>14J9L?WVBp`ia~4<(Z|+wlYG~oQaSEhk-`USpMn-)HS zAN~{KyO8khm6H>tAJt*Ra4*{H(>v(Tjb2k^-T_sj);>a0FSPeqXnnrANZfd%w-=d@ zq`X|87uwsE`tm1y*|_jEeA!o|7Td1K2k^S$^IN)8|&2vcS zb=JxHL-{0IM4W_tmoE0l2rXHUWF;a|d1|867hg(!A(9I7R6k@o!NauRI`8K`p7}u+ zJ)cp5*Jub~i9R%%3Ce-YO-1OIcrNN&iqu;4mmwOwu)lqjAm5e7g9?>@R7OO|vEFW!{=o7N4xp++y)q zQYAlVvq4l|`FA3Wv%ghPw#je@iWpW%*YkysjA6SeVywMq( zCjhn12@XEKL0u%C3);3Zo$}&i*M^ufvEHjAABg!cx zjP}o9)AlVjL&yVWcEu^%&^xBkhHivCNCszG-Zoa~OLF1f`7RbZdyeAPY;I)R7*nvG{)H;AEaHz zm)KE8(+mj>s?khqQ6*@Ag$Al{g8Xz)CFoqqH0immO{aZ zZ5Yvo8Fz*4U+F%dKrCnZy!I+YH@r9!`~BQndzEuy|KO0Tqwan5S%V&X+x>|J_Ty;k zl!nD#e(^>Y+Lz(HY#03m)`=8_}2J)Qu17#co)N7ZdUy=lz_c;M4_8o&KXu45$xOQxsaXn>XNh4DdZ zSA7v)1?-Ys$ggS`;+gKK`Ux{B5t(c;W+D>`5K8ohj}^`PYWRZ=+*fuUQhwB@Xm?-7 zp~=dEJZd29G0`~dfVce6>{{$P)%OA|fw=fXvksZ}L6*uo-01vQ~Rqt4(4Jz9ro4?VouZ6&~pZlTz^bWNElQIsavB}57 z*kEb+g6_pPwDxCv!6zPoFjYw;H*ROU!mI# zIE^E7&@u5xP)5HbOw619yjRO+3eYt_`cLW ztO21}Rd9X=V*SlKzTXIuHv``3ZG2Sx0X_9@{ z&uslIa0WV-@?5Vhegc=aJpYei1jsXvZOjc^pCZp!r^xdp?g}zXtAudY1@6`; z(puL6%rCr&X0cMybyQ8XRMfsI1$834mQ5JnF|oTsNH+HDgC)yME@TeytU|tKI-;UHa!1ku^?pQ8{V;s~4X7V#r*rDr8Xym@v_w}>}G#AhLcOc8f? z%eOj%C+QUVvC*sEqHkr#96r=%CQnb9*+B|jyxh_;|QwiVPlS|$9QZ;8RhxM-Hm zclM`vi?K3e_&EJdizAAX!-rOWaQ15;Xc&hN++g@v!QlfWRSiK7cT^#q<}EQg8O{GG z7&lo2^Z$yD^X9sF?zK14O90PdJ?QKflrV_H3T{xsDlnYU=qNFFK#OFp&`cC1ji_X4 z*(x+8qc})QZxzBy!**4F9sON(IgT@P>w7#S4|rUE$8lqcW_0=1qn_Fo?DeUO0;1PF z<$s@tWplyTv2w88t()dEfZnZZcE)4k79C_6foUD`IQ$i-K>q{V(wpl9^vfaGZjGeA z{r~0j{|oZDsx_PRV1BnD8eE43aa#QcC1rJ3!cpff z=x|2|{sqZ&m^;B%x9)Gp$)8Hitr%96#h4aiq*4~&jbC^`=k~|W7bVba@xD?2HY9}w z>{i3abE-yqp)WD<#q?BJ!o8Z|@0MCT7gbjio4l2cYM0m{HPD}yk9iow4=ye-Kfy&; z1ODU%uI-uEms0aufjwT+@(LDodfIaWr-^tzE#iS*Pelgz`KyVcJ^9_y7b7lvAsE{=|$n$IwgmiS(8_;}I0 za<|@*IxDZSGU+D7ix}DP?ruVGk4$(zBMHfx$)xO=?8?k!y_E@$4l?;t@VMEAtM2hf z#2+vi2@D?X^N-j2!l(HIH{r(NN}W8s_D*H-gJjoMdRXq_;ZQuN_)k8SH0lln|tPY zX=eIC5e-S6{Z#Qg35ywuboxwtgHv z3<5{ne0|7_N>12g<&wtN2R2x_jFwiV98;7q`53v3N!oqpqs*lxzDF=6{7q?`{j{A; zH!*^>H>VIo-acfmwus4^O=U0HZ0eB>1&?kkTXP$BQ%U^{m#6(8WxbF}eSQ;_xxRrb zHM_$7l*deOebjciiMv2AyLQSEyyBZsBQ98OXDmZbCP(w3~+ z_a$^-n)ZDP4+Mu!fVVK|>blPQIz#W`P?L1M`!e~#*1P9raA#o;5(IO;-%WzlyIb)< z@MUHO8=5ogATrpOnE_YoB{|aSv?N1X_o@77uh)bM9_`mRYLz>oqV)N7*x1=u*@?ws z`c9Ajn%3lLMyFt2z8PC1>YkOxvC3Smr-Whg6do&!p99}wCBO}G<9ZCDx!B|~oZ#I3 zWifXjjk_Y=iFx~(_Cz%ma93XjPa@81zt@R{tXO-!HwTL%>L%CbN z8jo&zbc4%W!h0&BIQA*rj!hJUb!vED5f0KS{wh+!kvt%9EB<1q%$X<+SGQx&9C?M% z_5|`#V?SvPC;HF102i-@6Mg1llb41TKLF48xp?$zJW>|Ya>C<3iO2c4YUP!u{4FIW zK-R5$Rp$om76PA$5?h4C>;RoE9P~(d{z^xn$XEWJ5>{CBqP$XXVjb>h5A(X-M)c7g zRp+2nMUNU+eA_bhQ!9=%Mf1jK`gZID3O_zq@ClgUycF%ec6Kv#atT@#7Ry@9#Sz&Y zH&Du~0R#$`fhe32C(EusoFA?~Y~Bp|xNl;Cx@sI=o2B9&iLb=PN-_tGr&KyTScw`r zua}qT(nz0P-c3XY^auZA!DF+pJlL!(F2J36F-0Q3XF0Z*q?Uc6ckR2FSq{AqR}sgb+X!gdDU>IoNYTIhZE7A98S^yn-A!cy%gr&>@;As~o(+S7~y< z_Us`Ch2;Btx@ABKpADX|F{K$;K)^T+sJu>S?gM|a^7nSOZk$qYOpt6zfO zZdRX&JJW|h(#j^&r{Kr7f1Mh;4wNd3-^X9%yLcmhgEMe`X=l}y^27_kgtf&JLPtvi zqe4f=1qaF_6*w#aPAsbn9lb=RQ25vUhy?%x3lF5K406I2Jw9jt{Z3eK(OPw&vDe~OKXf(p#HaC=3)(O2fu z=_$<*48}UjuErcR7`j>Jt3?HM;rS(bZoMSxDMgSMvlVd&xLBY?Pe-_w2)2kc1l*mG zE>IT=UX9S|PF($|V*$ABLVyr4-onUG@P^6V1Y~=r!4P7)QKWc}IBqM6dq9JGQG}|?qwhlvFcdksk@;s>=ROcym|^4@ zw4mQAY(k5r%xdiB-0;zg1%2`U%6Z={>r`Xz(%kX}Y#?YL2j$vUckH&odGL5^v1R$F zBA_X^{`ETS*K!OIMvvpfL;Q%eGzbZ+` zvuKglpoh6u6k%C20+GU-ayv!eAlmd9d?CV2(bZ}U@rs^Sw`;GO*sLtN92A;SyvGOq zO&+enOmKJ`s)Ew2ECN+FoY^r+D{l>)*D0De6r71ZdlSW1?`6l<@6W@zN1(E5l1$$^ zxKd^MuiEKHpktYSlt^ymT`>$bTyVNla~R7!B-Q5U;7+Bc2!ye5%#U#k$!bT-U|&)) zJ9v3Ks$RVw)VkH!ywb!$rKsW+Uo4h~#~O~eLW*(X(v8D*u`JiAZTH0@6Y$8V`$~(D z(t&HYK7FNIzvUOkBn-e-S5k(p?i5N)I36JlHu92c7$UM$@RhRaAi!m;Gn7OO2JN7D6Tlp>`{G9Y zs^v|}($%~O*TctDk1Is*{TV-Q*WvJLDkVpte^@kLZhUA4BkIf8bh7K+uHW+p^`?SS zYC^Cv%C?ksMi31uxV%F7b)%-N0u!R}hZ|I9m;5}ux*gv+0wvK1Ss+~3DYs}XqA;W1 zsAA1sY-KPvG7XG?2P$|vPbk0%f}2A4(U*%vD{zS;V!9%-< zVRrWnw7Msl2Xm;8XdTf#1u=KuK5F@EZpCM0>7Bpbn7wzN8I-Meem*dJ@8C%D*wmcK zvEp(lD18}8w`8PxJ=)G~iHJV^&z4kJ5+YDmB~!9&F0SLlen?MyeO+4PWeWp+=(GHcNe| zu?0E$eT%IYB(DjBz)~nQ1&X56-$v`bZ|skgGBGenr6P!Qmkas=npP<)2h1Dc<;ce! zT}|F^%qtofUCwGJ8g=mt>l7PHGYJgw)9lK|`&qTdm=P;}9JO$aB4^9tMR5Z>-+5mj z^?4W0MST83)jG>S4IdjYZ}cj(p=0HD@CWzbnOBr(h~;TguyT{7jQzAvB0s=W%xdXOjO= ztM_p(NS)I^yqa8txT?ko?F(2S@**cu7ugk?o}*mbfC&)>{dTo{ow9T{YKAtUN$9OS z=!^ajRlL7)ozL~L-)ZQ%Fq7xGR(|)cyY2$N)6_VcTYvamS8FWqztE$u?P_@KxG9T9 zT%^L{Ol_V#^Mn$W>;jKJ|l~Df5gx7gQt6a{( z*XzQ0Bg@IkSQvseEI$3H<~#(ErH;Tk1XN=_Io2AxuxA=rT)c^j;n(AQ7c?;q7Lka3 zE9<3sk{9UH=olM!Haae<74oLWuFAm<`DfAI;{KNP(dFdMMhDg_U6pHcDQb9i2U|aI zxqKBqp6KrAeqz%UZhYd_-*atGtS#Rf2qg2ea*2N%D zv)Y(*A=V06)`9}QSuh~^#+A(!xUwLd6pg_F0hmjrJEyV<=O^f!Y}tM|AX~P8(6b6B z&UaO6TCi_G_%JMrabR>D_Nvsp$R{T;fd*yMCYg4Sw-+katW=Keg-SFl)umE%3s$aL zW2|L|3e(fJLdTzLj~~`h;dN@Q*0`WHRXj(F#u}A5diY|?$dW$HAhB9pSS@1ofIYg- zcy^x{)Ht=^&>=@#XyuyUkaO8=1cyblEfp7Nwo|ekVGiZx^lqD+4yMf3uS)-H{dyFp zdp4!3RW75juNlW0JC{*oTA5mdv+*o;O0?{4k&2V6sF)XF63kH$o4@-ig^lia?XW(^ zT5-*J7|O)B7oS^dRH+#PzR7BL&>}QENNO7^Xf_`dm0+@GFjQJv9uvTvZrRV{e9$dz z{3)?QCvEm6wJ3G8i zL`{BTe4?>D7UGnp%J!G#x@)nD9JT1I&kGE+<^hcriLqi7Vr_79k^EY9ZU?;>k(R!L zwg9CRG5C~HbbH=kbK<#|ZlR9s8_dTbk@q(~*j0ODsT$goAKF_~w?9vR^EvELR%F{_OtP9k(PTU@)oy63abj*~ z4jX9x8Fpoyax#JLakVz)UKk(61^gxU;BtEQWLXE99eLR*v<~gpW01)*Pl|#kvNcmU zORm9L*>J7Qxo*&xtsyN_rqOXhw$g@XDGdjCc0foj|NKK3Vm)TxThYYXa@yeR*&4xB zW;L?1ojHm_6GGfN*y+$l%IPfDFV^6XKp5d#I^HC_7950BeV5sEh(@HPqNUpawiwJaXkyqeUK%o3jN9aO@+3>4 zk?na^He2o8DWc9)4>0*`BMoL>RHz5db=0*A}M4ZJfxGUecM((|6Hwu)o zROTlPMayp~JQxded$yqxnT2A_ui>Bycde(iRyaQ47DPm8zFKGCY$YfBfi%69ZcE%; zgc!%}Tg%Q;BLB(9j1st=7lh?_QHE)Pu=L?_kiJcG5+ApiE6|P^GER+TZ1QAhg2tR| z6?h)567xRvmNYLulzPjpAHW#MkrY^z&naerFdU+flN9~7QfxUOrUf)1ilWQMQxi#r zWF#;$<6JGeqisLXGB@9sAB7)C1rgz6IGn}b99_oAh~n9qKK_(|ATBFULn)CRypte~ z<@ZKh8X31>7!za^*)t^tmJ^4u=rWS4`?ROmV zO9a2(Bvd{mpA`M%gYgV$u+ibW5RvOu=O&CLYEcSJAQ&*XGCQ(Xg1*!+N{`fvT3pphV8bO_Q+s zFh9g8#Gn#B>74KuOc4Q(J&Yh$*c!3PIhc!@58%#X42vJw_>vz8)eGuy&mr~{`Qu&G zv3LGBFY)0?_``vH%*p(~9wu7D=`;;gao_{k`{i+i!Dq)dVWW!NGS z?n3l^k{jSUlpSAz1NkItkSV|$ZKiP}`orpGn>VEnlT4rsACB>f3f;93otQbqD3N`b zy=24L8P7^Av>4m|4G_*kffPY44TzsfD$D!;zTU)k=}-zq;o?>en=H`ef>b+I(UI>&aWv2+r)WdAa@_r@d5wN?1&j0;c+ zpX(S--SRuJg#(U6N*H$`p%|R4P2?C;p-T;iuZ^yXTt|upJ0Bc zHyWLu4s0k>T#CJou`5T*3^4&K!Y;~#JdW^u!x2!VQ+j~C*}b6susU<*T04GNtUn_O z9=!>HlW41`AN%OMp&!B_$?&k(2@g90Za6f?o!G89Jb$<&2v`WvLHXhN{nXfPrOvoh zb-rExuCnwQq{2s{fiLFDOtDTSnMlZ}A(1!d-KcrOr84*w)cAfQxbHUj$7 z+6ddRG*oBwt3HB|wMoIg*jsyA{Cxbq(Kf@~dh;lDUcJ!|`%zR~R(&M&^Wj%R$CueD z)apG(OL)+|MBZO0Sf&qIJe z3*l?}ly6}JAO#0sI+Rl2&(U~fLp>cxnZ$U;g@nn&{zFM6Rv$)1DH4f(RDTm_=bHix zbs-i^cmjxg7O9DPV4ltvAf9;uJUgPxNCX#M{RUM-63bV06fQpDt2&zWRguJh3gx8O z8{fZNnAl`5TUNy!p|bPCEW`4MUQo_10V^WE1vbDrC`?j2FbWd}G4Lz!&3ADTZs_c4 z;P9-}wBkpgn-qRW0A^)&`fwRyU|RM=mcn{ECOhz?1nFnW{O_eHz9j3 zyz^QT$r;9FH1>tmSu!Kh%%3FD%&qBYCZ+C#Xy!kFPhs-G%GziqrPBRRpqXeQ zF=klWLZX@MYrwliGpP;I(M&dijb@Tk;g7b_%))u3O!|g|ju1ow%_MyS&EzKn&7?>I z%_JvFG*i3*nkh0BXeN``XeKKw&`e(RKr;=b{MXS;M=xlml-_J;rj&}_mS6zQB$M_) zGszvcKY$ElIY5jxU&$^eD-L86lT$@ANA^TBMTL5xnXF7!G?T5{jb_qd$wV_b;6SYi zG}E08%_P?dG;=#s63ygAFKFgUiDuFyl4vFy>EDKC%G&gbX3Da%qnUhXqnXiDKr<;l z63rwlXP}wn0?U;SG_w_V#=uJj;vwG1r7RN7Bp00s&1731d|tC!(2r^{=6s zYzsP&Q_xISSE89#b>S^ZsikqzCCTd9XeMhWsUeyvs1inV4}F8levfR=$eQh`p_v2H(M(pqcT)#wCR;0An^==JE~Fu`#!u12*{GcT zQMSr|K{S)xlYwU1AO!Yn_ZS7fEIF2@v>v8_kReG?T4`Ud)DOvY(P@ z=GW5EOv*9QO#Y^znX=sdh7)CGVv|mSjXT zMQN#nOhMKPt%GTl#p{-e3bFuWwJUowE&s4*GyRKbCd-p(W{)~d%~G0D^L_^iyr(@A z%@lO^>4omkKgdG&D)UifRlNtZX@_upIFtvz3|!7E!yh=ah*L^uRx7RwTCtR!IOR~h zO~ENCkDMzLr~D`#rzA-yz$vBB3#FWHpV(H|WndWe?MiaDz$u0KC2&f9D{)G}djh9q z`x!TkhOb}kfm4ds`EX43UVV38&(={Qzd&~8+%JYx{slN=Do$x24~G(YgpY|+MtDJ- zk{84&g&Gz(C8fl?laE`>w^MLRQf|*n&hMoH=VYzGTX1@qD^hXF667VJK(?C1DcNcQ zhaxE!PMMEO3#Sw&Lv)#Fztgd#Dv3k!JA_!ckyPT8kG`LR_Hcacfm2QaLA~RYEWbD6 zmZy?&M+#0U+Alzyk~Bw`F`d9EdyseZy_1pm$1FG{TTI}Tyr3`XBseAcQku_}*TJ?r zz5z!iTm>uf-kO)o2%Suvl5{tTL5|Zn+jVi_mua(z>AYDCmJEyOI{Z`91x`u10GnMU za7tmC;M*QJ<*GEC^3Q2FCHX<(lq5jll&mrEK=S1&@<$iy*gJpxc<;$N;QXFAWfr>F zn+c;$smMlwj34aZUSpc{)3pgp+!1y-0q8p+VY#Cif zHnAeVgk#3=je^?xYgUM|2xVu3DAVHM{*U67?|vx@Uip*Ko_OU7Bs>9LITfFLQM_`7 z#49%fuUxq(D_(hB60cMxV5thk5>Z7nfmja3iEzL-fvAP|=GE^#qX5vQ4*`V6*Uy#k z$K`@agmy!O14;+JouC;mzN@<0hk(Nn=M=dzIhUHo#} z1OIOPvI}Q)B;!3dU@;|Ckg9LOT1*atSYO4FrmQYH^m`~9QJ?bAQD4~`I5wkMT@?aj z;3TsmM0(P@SAp9`;Zy>ENtK!oU}9U=H!=b~pKPjlf(BJez~?Roe74&GpUkBjz+9IM z_@u&11288f13s0aep+;DzA{Kg%!DU7f&=WptiWxZkp%QnC|C*H@;I*k#A8W$c9jjmbpU=eQ>wzLGNCzczwiF*# zE6Q5bFg_FlPAVgKN<-G`0j-OcaX%c7{<+$<4x@>P1H}QHHL8dMJw6iX=SVze9OzAU z9BAUod3P}m6v1Bz1ATluG7#YB42FRM85YZXuxQq;U*BrHhod|(lCDG|4984M{NNP{ zeoAw#<}U*LY!zXk4R#nPI}=3N;O9m=473qppzUsbFTz0Au-mHbDA0Drvl}14Si#Ud z06$uEIokjyNd|91KXK5u`+!L3y6#xejoq=JZD<7x2}KOqRWcS7o5OBW7TrxG^m)8j z!yEgXPw@ho2qcsNMs_%9&ChVdLWjxairCw85)4XFe0f9Qg3bt=T=f1j?joeOj$;2` zk(h+QP>mm!+R4Ro#|tkRR)KAl0szJ2hi8}*PiMXPRrS$f6%ryH4C)AxZp<|Yf;6S( zYj}X$9P>Du33ySfhue~i^=0saB-H9=Bx5Ap1hllzsXYgK!~%TJ+vxII}(lX1dMz*>`eiJh97B>^Q62<(g%lx9xaTWpt=o z)~34Jq^#yN30DC7ld$PIfQ>k06FnWj!r6%k|GY@&0<5nSkE6?3I79V+!w-(zAnI`& zL_J>EW5NGAAXiyKMf)LC^b>@Nev-aemAc0`|7N$IZ8qkb;4t7)RO}JpHA!`KWqh2tN`V7w3R5p2~_Nog(5$34kYy zNDU+votGt$G$$okF4G}=_gUHd?%Qu=>pL9?ShnTQ3?!YxK+-Z1NGgO_iW1}pZEDMp zTd(*9G~ami6y#wghx_5YVy5WmzSdDPYVaU*S z!}qQ1GQ`irL}Jf@bW@X_0aQDyN0cmQX=me`XTlRCgvJs^Av1pfzlJF)4g#`W>)1UE zDkZr|81^8$Qs@)zfhZVtJlYBZ%DP%8tn?M?8`LgS#FWOyU*EM`bsmUx#=hxPuHBss zCv8R%;9+VbY8$D0*kFkFVXgXfHdo zlx7G{dO)P26-5_V1eLOgU9mn_}TvY^@wlWR=aTo6I z2{?9NGPtyp!KLIK0mo931suzZ9&qeov8d(kR5*5n<%aiHHu+qp6B^j5L{X~2E(0}X!-FQ>Y^ZmOTV8B4|<^7j*sfbW82fCOF05Tvb|mJi0D#NUF31# zYZ+e3mo^~#ssLoC*x{ue(79E9Z{_DAycEYSb%&Q?r-$X_XB&_`h+rciv6Kt=0PFB$ zgo`nal)+6N=f@Td;H`YE*ML&CAI@*=HK5d!Yd(S=39lA?lMzsAF>Fde=`kyy^e#H3 zMR2MBay_~683-tyhB*{Gl&pOQ1WO}ELaWSs)=x{HJh}2=|mxIT`uOVD_=`1t zIoluj>!na;5+TH8PA`_BB*^O-f9IGi6<4c%PY{X6`hST zc$AbS;a2MgaI5%uXYaA2R%hC=qfI?xM=L@fSh1rObssw`2E57G(avP-XlG{Z=rPQc zggRvGC`&&n+A8>Oj*^`jez+log9>EA`6>mr8WuUF1{RP@8x&UbFG|akXOJ$24 z6}dTOxF5PQ9c`7($Jo&<$%wX!(o#p4$Jb}8(5a%W*McLmuKzZ)wMQLxv}CD6 z&C4CoBgY%EqOFghiL=qYG)qp19laM>*|DP#am$&4tC6-dM!A0%;5sF;j-Va=2`>|H zZQ`>RWu!H{Yz<&P96LmZ+q&+{#_mh9o|S+*oLiUN516MFMJ`~Tv+>6QaU0WuO?Q|t z2oSeZ>IZ4tKytmV<23#lZ2Gw!Y}yECC{;y<$rdVv$%e=o0ohV$Y4S<#Q1T4vCeEenPfkDG>O>`O2usR1ZK;oPl+u(o)dl(v8CWXMw7zwfX_$qb(r@h zG228khI0?FP&Qm@Y$?ZpQ{;~!cE^+?#VmzCUR!rE{%9vM+8tZk3ti+B&}q|^#v1S} z{S&O=Iw@sSY|IvJ#SS!(BZv`Az!g@MDI!Y=+hXG&M(S6v&62UlDf}TkXU6woUvUi6mlE3D{YG^^sI%{7g>wJaOSCDr0-)#JTxlc{2-$Nx9REl0T%}JIJoo9oJ@MQR z@=l27&c!ER6wkd`;<=lF=MMjVRy_BbB%XWX_|qeY1k6x$m!|x%nSUDYQi_{_<|+cr zEt0XQ1!Z+!y`NW~ns1@Gx6fRQ{b2vE!gCimPm1RjqRakCJoh~0uALH|`$u#)Q~sOc zQB`|y{~NXHziZUB%8KpNVtE9w9KP7u7xTx3eGO_#U&ZB>YT`X*%zX!xG579K#(b|$ z8FNRyGUk@&l`+$Qqm0oWRK`?PBVO23)}j*Yt0@Iejl)_#(-)UwO_-xBk;H0M{U5%v zZ8#Ojr$1bZh$siPl5f$Xe=ZH-8e8GuB%H;i9Vk+4G0z)#aIqH06ff?@wYUh`7o3!d zC)~JPTolVh;85)RK=G=v_)6XZj@$rmeZ0@Ai|~xL%@PLyJdb`1QAcX^ zdm%in{s4bM^f>Fgy!G!5_l`WI)xVdA9;!4dQai{5j zF2x)Yt@TPN9Je6kg;E2A;4p&mv((rRyTYI6DGP5xN>%Uh$0pA5IP3he@8;nB+#F12 znFJfA<|jnDe#|k^hy=NOc$`Q7E@w}%2xq4|Y84Wdg_IwdJqo9=PQ`B3XSy)}dSVq_ zSb>WIpB?IOxHerI`_7p;?%01M{CYd7;0@{Y3Rs>!M<8}ZGOB@=!h$b^8?rB z;&cKv@w!q|hBQ89&CWGLP-V7vJE|l0TD0p5^G`#26HKtHOB&fPzNqXcR=*U`%^Tsv zer4hB@J5RboqAVahw@_aWG&VQt|-iy8?H>WqiqQdDv<>kna!t>lD&o^m72%-S=U+t ze?)$U8=SF=eSdL*^H8yG@O)gE-^SN&M6B!Efkfk48^!cmL4y*R$@einvofiarJq<*f^6@hAFIy-(2e~C(1KN0+l*-Ux4U+N2WLW$ z^q^JM(B={~)KY>C*gcnTRw9Q8;wN55!{XBgZ`f^P_hM)Q%3lJ`bVpH+SKns-8Pz7O zg0f%ZCL3i7#q%di>)3>`J_9=XNS=NHrKMA))I3BAYKsMBq4g!|8c7w1vZ;%<#~2flf)3r(j1GjS9OX>(L) zif216(SE4jPW%;|*Mk4jK-3U~h06 zPhg5qVjg%K{HnPC{eWYB`Ue#}!#gDT7=Pm<@USE}3=c(xB0FT375E9B=P5s=MDE3x zAWD8y$(!(ooU)J1XPHtu{J^&2j5JACD-z^UgtmKef~I7-D+H52j3bbDYO#BU=4jlkocIAh)t?gQ(M%-($iEs)Yk7L`4SA^ornLSpEN*zdjNu5YapdZ(L4;MTOAgLm| z;^+AKzaaEv9Q(p=CmlFhBnSRS&4~k<8!QzNxe~Js3cHYKTk}G)sR>wGGfS|vlF!mb z5D>Hi8`sC}8oJh2;L@*n*0GI4V58BzKxgwbxsL*8k{KMqe(^!PE7Ynt;GNUlhFO88 z@7AD?Q4?&ahCr|IUMzY$IwQD?b>?G7a3ZLu(1+U#mC?-__RQ1t9m>rEU;B1nN6@K^ zu7@rNVeqbQVXoCj#f{?LVFs9g*IMw6BjCq(edmnu>N~yRz4StKl&_MXSdF z9bG%LtsmO8D4KhPwb6>*eF%p~@mRZ(s2Zw8ai=)}71iN>!9V135DYQ~QkV#O5goyy zFQtpw>v!-G_H7xa;UL>6O7T6ENzRjWTNO;Q6dgnMu}UJC0fbD^FSQ7 zGh{+o5u_r?g31HbRW=(+@D%6TV2Yu&8Cdjyv_7gh%SmF5kZJ2VaU{Hc#9O~NFVT2S z^s(Z5k)L1R?cMq@tPpR(o741%i&^Bf=)=YL;hk51)4TOOd?6BOTle}4c3-1ER@_0d z$~$H~XLF@HR{T|r>Nt>*Yooy8Abz|c-Vz!dL+*yFJ*Ht*cbkG~C@aEEFM%0$?U)vQ zVH;`D^bT#Sfk#_EnAX2$n;=DhVH=AxeJBQm;M;+@)I_^knbfp1&+szH2fY06yX{vl{jn@z>y zHRO9K@@3CdaF>3ac9vk;2T*BWUxLFLwZFvAEk19N^80zUstuYQmTw6>4Y z2syrjHxGK13$~!pElf*B#Wm@|vs>#=<+}t)#*r$mv+j3p(JBw}6lWa2g5II1g9~vA zdU?a_3COQm)Hho5sZA5a_Jj?AoaC;y3#AO|F^R3J(?)^oKjAVI^bgmf^r^eO zFX+FxVuG@8DZF(|)u64R6geCn3$&33VYQD(7_V?RbA2F;L9M>MAU;CFIdsqk?S*Km zsshbf$L7VB;{OnpsF7N&x-pl-A15EEBmU2`N`-~VQH8UFdUKfilCWTb_JsHJ(+b+W zin|5J*@O3>jpJ^f9c?Rw^TQm@zv}SStE4sRgTBPTrcW%DDe#H9ns1oYyLF#8@w$Ix z+}Hol!uH^|&3I`Osf7QV#m0PtVfIM6m4#6}VzI0RG$(YOD9W2y>nZ!lr^^@Kws_#G z@%Vi*bU$?@xPzw;xuBWoq<;jNEPN>&%E=kXa7 z`D3EVl64IK5l{WGdj{uv!wtE~@)vSk@L3XH*5Y@)Vb#0=g9&HwY!YwV{=j6r=F?)Y z{JmX#WY>IrIgS}a#miCgwMAZ>LmRg%uEpl{PgY!uU5jx~w)yO{yw1;it2F7ULlJCz z^a?A=;h*i{P?cq`T^%d@y2V}B#zs8thH*&N_BnUB^&RTgkJPT$m^2W;6fWS$(Lq>a zEBVgr++eeyw|s*Vewl-Yz8)jKWKRf5JHF&UZ=wYTfP5T2nh1P?%;4l)CEr3YA=?ZF?7rOx5;_Vc#|il@omT< z-UbKZZKL&eoH-V6`3>hr&sk69+~~K~9ahK5c~L&~SqU=3yvY0%#o@c)!|~^|@bUYV zrHe>X_3?WkpWN?_7IINwPB)PjaX}I{)yjIf`9J)so45dp8)Lm4VJ?-02;zoVPxH_s zu|9p|9U55DCQ7W3w8g){!GTQe)$3tRXt8UCdh5;6TK(SByLNa*++;$lZa{)bFot{u z(00e~7m7E8XAUnnc8+XOMR)iV&zrsiEHW%E#k4W66eq$3ut^-MmxncEe!Xwp>DSNK zVEXsd>f^)pnPOa~Z%Qj$mva2eGqg>r*J*e$Q=FEm&Qxz(3!bP$iR18}1`B8r-r~`^ zX`>{8rFmlt4Vf#-SKS zE5aY-LH*Q;XGetAMk=T#T7-Cy*2wOqqAF%ZH60u2J}h*+s&~1e7DfJ1%m^UK%vYsD z2NT93;nNwfEUe;Zv7yS1@ae25&INOc5mESbJQ$lIze55Vpq#+MZzYO>77?n{nmgK# z2U`!DtI&vCvV3>^H8frbImG*MZ``lPm&=)83A{AHKY@;t_!Q38`$7X;5&s3}=nq9c z3SP=RENdl{i(M;6!1TX5R@@)yD=;jsr~RL3^2dCaw8s1KValBMEJ&c~!yn4VD93Qr zE@Or(r(jnIhrvkHcjYZoSJ3f6h6vtCPe%k%0S1DbIk*7RU}L>QjKE^cVQ~(bH043TANoou_Rb!`B6IJ za6Dl?9XNw;#oQjIuER-*3!x@ZJ*lpm0YVa`tA>(!DzX?H*;5X+YR(ElbRdRZ=Jfcl zjCH^L5Q~VV$#3_r`3BIyd)ZWMR+-TY=G*^-bHe;4 zKyn&?*5tIM%?MnAF|APgNE#vVh4(_GV|XnzMAto5*nwYp(rU-7ZSL5Nujb%vvIIB0 zejeh8+2pin%{I=qr|C7@+L73Nl+uks;SBDc0YklOi#8GinY6RaIRL{_1~&69+}j3O zA+WnJontjq_k#`n_(Q*wQuB$4k9w1q^OMP*I8m|$Uh>HHkCcU*ap~7v&BOS886@{L zD^W6LL1S;i?CM=W`pUT>JcqCEoTF)Y1vg9X9k2Ki`2SS!in2OvwF<4~*4?Fd0JgyL z`|kml08%kRoF$0uG`%?2sO)VTOVd##^dP4>e*F+I1ZaJfgT(=Ck)PqMct#UlT+nV4 z7bW&ZE0T*R_}+>YkT`Ede#!DmADdO{Qn#z5KG5CzUfECC$k)(KIhA`~#d;my#GY4slt*G6__ z!zkXph#!7XmT3DJ8#m&Ha#ewX=^WPZ>%;vx{K7{+_NQv>2NI%~gOsX%6cEKvJVm+(oc^(3EVoQo$u z-N2CNEm*5n@0F+o5Dfs#$hVZU;QfAr5^S?7w+}!C=G(G+Ekxo=p4y8fAn|$$Tza0% zKT#s#3s8~7MsK1KpDlP(vsLw6qldHS?FKE@>1L#c-3Aq5xCH`qaGD z$EKzt8#U*oPyZz`Nji?($7aWIw({D5IL6UL!eGaq9NpN%ywcHuVjtGZZr!UTpuet(METH}JTe*(2#99jC#C zJepXqya867l57pn8eG*S0ZoEo~BAfJc691uKV12IVq@Hb$fm=T4!(Ky-EBTy!(R1sF^32L{7& zLhv_dt28-(%&|A%-_t!Re0R6@uoyg}@yOgZb5g(%YD~kmwy*parV{0u0|n z?jWxS=>yYjfZ=U#`2Bo;<-2$RTG3ZGltAQvbuOE3JzYLKtv6a_p!5zOJVmSxxJ6Uk z2Yjwg@d7tm<_-xh(D76A7)aOf46`$VD|i7Bk#v9xBAA2L{8LP0yZQa_cu7#fPq$Yc z?kyKTdaslbMCLe=Cp$Ja4Gx~gA_KhLNQOoF;2E0UY@rH#WT6V87#Q|~1MK4HO;|aUK$RK;XAR8?}vb_n!(C^SZ7Z%5R6d5+mH{6iFw)C_`Le)S3m~Qgyi#kMlf3xM<$qz z^8nVvbqh41QFFEiA*ta0A<6?C_?prk3*-#*LgJAN+!SLe2O1g@UWzHe5s_AzbBUCg zIfH;5YSnv0Qrd0tNwzn+#NjRPnA_jmRflXG!M7}Al6fL}bb=DOpR`7{+&54Yh{h;o z$*p`MXqj6kOcGFQi4sMyKuBMsl)kRrw(M!)#tL(AKQw&ww$gE|;1!o^eZdnoZ&ObE zvC16!%XlrEfKN&$K*oz$r|@UFzUUu+flK9n9L^(Jf1D4JH(G-o9RgR;`*$CHwU`%^ zkYY^A5jigS!0uz)j5tIk+YkNt_%xaAL{cTkI{I1SfVv9Vc=Vx1o&-!l5a4WF%U4jyCaR zXvZ^U=5y!sO#LKG?KEyf92!d?5ci7#gSiS2mxH(&FcMeI?_FzeN!;QzPv?8S@8fyU z+1It#^}pWrzr0J|t|GJOUUaB`5Cg2k&t!};&5jb~%eSF;eiZ``QdJgZ*C%0K6N^9UR_lcp7S^h*Lq$U9X`@EBC^HXcedxA_`5bhuA{J2ebxXOjBoU`-+wjbK;Wj0rbb4^yXo+@yD zyvS=gG~7#_<9$DMmNnvNwM&p%<25W9>Ss1OGsG_8=ctkg*tvUvjGnfsqWd3wP;K5+ zs&Yi%!4bC8X^1#>!^MIoRAn|~+q8CS?LCUI$y622UCyiBROSJ%WiO>YLyBZzBYG^a z<;ZZ4;>aXGgKeuPEv$E52K}BrGnJ|O&1|$V;KvKy)Z+5PL1sCnUhJoid#NRU>b%)$ zsd1Y!mbAQ^f{xk@1>5{?#-2}khz@a5h1NfbHY3y3T0K+mzz)bv(ALTqDbtgYPnukY8#$B+C9Mq2S|>)e34U;S z%gD`!1t*m@1EJ(S^UH`Ifjh|WQ#0WSFI?$0w00xJtC6bpdM@`t7nOBh3sNPZzB~e9 zGRnL>bJ=q@S8B+*?5fRV0LA=!QooIILpCt7pS1T|_6^qNRp}GbjWzzQskbIO;W4mH z%F$y)78rxeurl-1dcIc`Znje&-@Ms;lY^l;$jY{Ugaa}yfm+05I0_kVhjuh~Wj*)I z5bxTV4DMvGUpB~dlh~w*F9>Ih!XLCIH{mwfCdvj71reSO!cEl6KyUrg%5a&tes_4f zX2^m=$~8!$_FPRk=a8nLn%tz@x`XhbxBei{)eM<)&er+jV;F&I!g=TPP&U&%`6a~9 z&0$L=l|QPl5!uOJrU^T}T&*Ru(YT&WNtx5|&(xuxizOl1E~4yIagf^M)t>WfcLnJ^ zrs|oF&BWWG9*0|#xBdW^n0fsnjV6D7__E1ZzE-V*i-*ZHSu3JFoyI^{1ylw)P1`@* z_f6X@d=&FbhYIFL-^Se1;Q&kb1kuE@fwE^b{e)Ml!aZzpT*(f#4SNP;(<|f^fR9L6 zf*d{_%&L^HX#tH&;=1;`7dPO?L3ph~N6WbECg)8it_@s4_eyhFsb|`5oEs+*}EZ zzm;CsHa9~BO!<-X2asR+XF$oxc3 zS9+Q5$ygCBhEjSX81^N4zF_KyHM5y2?^(vxmFB7(R^qEv{e1;>PxU_4vJ20}(__E) zWo1d?#p_zs!_+yo%13hx%xXDM>@6T={u!Ztcw)N zpvRW{m?WcE!!%c_tn?}DpYKfh1J_JfoYf0^nc}oP(9OBTpV#)lF+J&p#Xr3!C6%^RJNpTt+<=aiQ2B;~9uIYuEXOWMuf zwdODKn6mA*2FS=Ca1S;A`1h(&7;g1YKSUqhz>MWPZ%+Ke<6dsghG}G0$-br`19mhR z9}GLQ{T7vno;2s2fmtX?kL5dL>ErIKkE$Rz*RQQkZtK4 z17ewb%G)2C&0BZy+<{^7~gwew*U_E~`71Kq+*%;WFHW4V2-?d38lq zxQ#`K^Xf{!w#{uhI9!j;B29gxo?iw>Yd!5~nve4!T*10r9uFYQ_QhrzkBm2GstVbtcJ%Q7#Pjn}0 z+@ONtuj623Xz`;*F=X2uI6wM~-jLkj$*_gR0HR&#rIu6rl+06!O#2m%)}3nzEFSnriI;6vSfp__ODrbJ~wi$A9iJ#LBpeTfiqyz zjRJ6fc$m|poL+Fl3tDz^5vMkq7&w2_PXP}15BD=~OR-e|as#t%@-v$ZR26&;QVWC3 z!XT_%S7ZUSfHQDjn9@zX=cg_Z>PTWiu5eupbDbYA3`#l=QbS;e`^$}*Bb4B`P zjGHQ2;xC}*_=Sqril4>pBVL#kUOSabYv`-22bvG(( z)i!p1YWg77@~t46YZ-1wgUnHj`_WTfYrwyr=+^D-OK*2;ZQwR6J{Dy5O#T<2KA@Bz zh$_n{@0H;x?uXgT(kY{55v<**AP_1>Z)t?6wACqpTTykY$slk{N_JU@8-=zRjw>Yh zdrS*cZ`1IN*!WGQY4}V$6(|ii`abK9myJ{gbU3r$F$JG%#9)x>NE$;mu3D{*{NJN@ z#p6dZV8%c2hN)&BQy4?U!;VG(*H~Pn7772hv=@>};ZWZ80E*0g0OO!|7fBW>Nj_hA zGrw#Ptebq)D+UMIH-gOO$-j6YD!f%dS-}@92YQ;NhS94ip8V*mJ*a3hE2eye-qEVB z_$=K`LR;M-O|9k=p}mt-i|PQ;gs*VVfXS02g7lu5(U6g2^q5JW1$<`tlo9>BN$8NO zME#TdwdsWMq}G{My_okDk}#lDk6b*xbppNYY^OTcM5`sQ*0!`7+16Dvb4#?7*h_pW zh@Py#&|g*-)UISsfoe#KBIi{tm0Q#-vv`OVD{^2Dv%@=DE}I%S$lA0WamQF*SpF8P zWEoJ^<~6aTVlexuU4CX)5PpN*1XU(_DGmnByn(k8bI~F%)e3~gve{vD3{9qAc;NsR zTIw#1<4I5Tr*spEmcYM0{X)rxMEX@nb2?Oki4?qSI5HSiAR&I0z9v_(B|y5dXtnb0 z2<1FZP_Q2!p#r)j5G5Be8zAf?xx7@DpL(zSu$Sp#5w8WS?r@b0eamz=wZzRVF_Ljy zSon^lqr_(=GAD)Te2@FpZG{>P1uS-1`vsX+XU3n&6(BCHI*CM9HocZAM*?nUe)?U7 zpcfXR46)UibW&5{!&VyY3<#*Fxo5fOxQm=w=g5>_+sqfi`|)46!JMXz3N%PBHOgKg zKP_%>0(4NXZSkUU%)%{B(`!7$TBpiPzEP>w48{^An_9*UT$x^mb%2rH(e0*}*F;Zt zO!L#b`^#cv$}@K-%`B${>cq5KIB8u`5Kh`q6i=Cu6 z?@Z1I2sjpdalxrZH}aWXa50W1Y?uZmLwR#`Sh=i-Kg(G&wDA1oBYNJ9lBk+c+m`ZW z)D+4yr%`4$zjiS#2&yg5dWFyE+%N?wRjLq`Hc9aQK>!?Pwg z48XTVAW-&nh7p4YZ>)D1CY+t-jJ-xr;8169C?hUNo%K?0qs^t*lkkd@#*mcGGz&gP}ak{VAjFpqn|^ zt8NGer1syM0-^#V!Iq*evmOtIr}>4hH$9eO>h8N705R7*KC z>d~_$82NV{tQw%|f0C1^*;U0+siT%C;Mk8U9i)?8(rMB)T_*P*wEdnN64^pW-9v3u zg{|d1R$q`^cgSh{JFdC4wr3|jC+V#WW|NE;o(G&*bRCs$NH(sG?HgXI@&=}yw(+^? z*8*0${Y>}xaQbZpeNrz-O~0XgT(0t3;)UA0Oxw7y^0w~zY8$EhKqp@2+~oO*_5jt( z7~r@az}e_az>&36Mlca4+4R!u-BcxmJ=M5DvWBj@K`T)=cU@?-lKL=y%_yj zlhFs*TXn`|SGQ1QQ)71O(-de|vw#tG8-b7>n1}6Ut*G@1xZ_{-MLK~_)$gSRccU+2 z2|8%;M_}*=!nv?Ix1i80yctd{2f!aaesMb>qEKJL{!+MBc?>^ZhuOZ*rZ=)2ffYOLhGlX(@)i7oPT`>=^V+W3^H>R<^un zyc7Mho9zysQZae!!HH5o5!M5pUrW}sv>wE|$@J&n(dG|nG)85qHGA{qH2fVO@}lX5 z_>Uu=$&2&X7FgJR2Fmf%`|XFo^jOK_4(P2rBrj^)>ltlE4X9Bd!*xyZ$RS{jn&L@A zjE)RcATMfrbA03%^o|!#Mis=4`EtVt$qdSWNe(4bUEH)%HzcBUo|noNwV$fX^ef8e zn&NQH0A@r7_2NZ7=4DyyUJQ@EkrclTi8dxp-CILtpysmv4g1?GvV zr95$C{6xK;sNo5{ip%&7=h*;_S3f^O;j}j#jn9Vn`myx$8Q+q>!M-@PsdHYewRC?l!iWIGgvEpPs)jkF|Ax&)8=&pBAOyNQ96`zgE z<2vKpKprzY61{Cfz2{V&bc<2Cjh1eTjqRpZ4t-j4l+=oWUI}Mb$Pd8-vGDx zUENx(m-L}g1Ef$? zsOT*wjtZ?r6*9ISkp1i}LAXs15Y)m*7!VZi(X9=9m!-zsiktPU^XPItqW6EB_j;Q3 zhMQ?2nheDPLbO%RwK7=YMae9!wX|Z%Of3-+)M0X@Ix;l@5R7YrrNsch_#J(8g=&KT z40q-m?lCc_K(FuzH)B5-uV3xR4_OQA1UZ848o}>l`jq}c$fj? zUKCa^Rac&GeUzX6VFiW8tmj5^%3kCSb7wz_;COkDT+ij!%wIA@q7NK}CX$>d0Yfjn7n#zvnk{Z;1Sl^7j|8vcUZ$THk3Z^YAUD1Oqo zSP~=fm!|e^==|t!juD9cNl2Pm0Xu~ul)kc}EPv`9MF{jvoz&TuLtCF!pA8DYC$X2y_r%&SAcZKPY=~)jcr#r_6}y zb`v77`_A|kg$Q&=A(%Rrbeg^p0UH{LU2BZYy+wS3zwt-vZj{&CsO%31+Xw;U=J;-> z@rhG_K*zr|K;UrQZ#Ar@e&q5Yu~yxeK{@K!ncZ^cV&n^qpx;T*H3$q(kb8^z}P(3_v1 z-@ygeC;Cdh*v(T;<^RqaK!B4(|2yX^&ejPCq zQ0#qdzf!f+Q~ue#dPza)NM$s3si1a+9}W7C_Y5w0$oWN?8$^#`DLaIvY**m;+`8?p zQG*K}z+gr;VuM*q2D4p%Fc{CtH_IN74htaslBxqsS$>@g0nnsh7UWN`O`e(Ba4$2; zB^)90g*&;}vOA^uH@dc)VSU_ryy-eg{rqERk`RWEy+sJa-TcWmoFDEqu34v)t}>hl z_dZttn;zTA&2q+l2h27c67rhg%&+P8kIH^FIDeFI3LF=%7Qb-c2eoLVz@YGJ!9d|E zt=mU&m<=~P>E;Se{DCG{w;UrGw|HTGJxRN@Vxkvz9?R2G2))Q6sgjjjy|zQ=chnGL zD4tWe_L}&hIXQSOIe3W!x8VSWVyPmOQg;4lNZsOdyq$@|ac19$kO*qG(Y!Y@<9!mSEzhj-j?--7DYz!_V(47%qp@b`UEEAv_6tAa`3*{?Bd_ZHNB=nVsDW;V}P$g)$lw(~ai zvCL$k(fv&W5TZI^#XzPJHY4X6`@d`cf$i&crjZJd_Xa4Bg#q$uSv|>dK>CA9<(R*`~WFfA*kt0LP5-WT{m2>>atx2*uzYtX`<(b1>xJ$MMqy| z?12jO7}35=I5&4bsKtz~6g>A$w+H8w;%Hy`zPRe_=Ge2JHBolHBo5?zBGRT zkkKaP8KxKMwkYtgm6FZ)*tUVnqt%dAy`A4l+vpuV#uu_nstQJV(Vq^8AH$4ZkpC6W z$p7J^s#dD}rn(`I&-VS-Zx{#z6Z0-Q0Et0ZSzQ5 zdO)4Ecv1eJg|`(e;tbi=3h zqYm}~P9FS+L1dl~>dwj^4ipP%<4e4XXQ8OD{Pzl~W@Wp*=#NiV{;=}+X>-4x`&>QE z)ib(!hO2dd#+5T%IjbvYb!8$~&T{3PuAI}AYOb8)%6VNmuPgU)dSiGa=-O;zw0?KP z!gKlCndahp7;oU}*a9fGTJj%$L)dQp!G?vWIzKd@rCiS&j1XI|&ga)AeLAVS+nn15 z7lcEpuWLA<^453a(QW%Z7vH&cFr!BQs7mUQ+EiBmKUI~~A@!G?Pyb8CLU^MY2kcn4 zHve}2UN_guiIg-^5&+3Lm0iI4vn78!GKLrE&&L>BPUC1gAaawxDB7|(3O&DHojLpb zySkQb$rn~d*$3G)qKJj-O?B7GeYl`rHt!LgzsKLZ@CVfZl8z7WCOd$3%6cVnt^p}^ zyvELawd<0q9^3#sE16=SV4?_6R|-wf;@N;OF3dSCM=MCSFx${`&9j56qVJCC{NT(} zRnfOU&GA>NoT@{Wv;GvZw3w)BXZCTIZ=lz}55Kt*#i`O1>QQ>k3M?KVBG{7j$twH; z8ro(AsrBLKjO7dN{xyX5606?^d>-rk4eEV@P@>U4Ppw{m@YKQqb@w>Gene_te5r{! zw#RiR4NXeJna^a2L`c0o>k$-P7}!5XW{_3&6tnKS`e%Da!N}CJN(XgaouBa2I24>< z&n|JX&pb7KIP!CVXJp||9-@CIvhbmw55QnE>5~J>-$JA@JuWa4GMnJ27@C{$%=Xf& z@THXAh;zPXluR75FNdExTp8Xa@9mje>uz*2tEOBx_J^N9c{R5F!YDR;BR2Tp8xpH} zr=F3@mAZkV-eu0#X*n~0rqs;*gm#;(Z3e>%EA(3yqH3Pm9CiiKvjd#DiyHP1be~`J z`Cw?Er7w2LMJJrEVw_!2_5v-UDsI@HWj1zOx<@taV^^*PW!eb^kt;fndJY@*K!su( z5HRrsS9s=We%@4lY9aPCDaoRvA8ey)X?~~ii1EP2QG&yyGhvgHB3*NiFttF5B5);{ zIvL@&5~Qdi#QW-o8M9)WNY+ce?lg1We&H z{SUs}Sz)7T8oJAz*>g?noZ-)H8Zd6gVo zR~a6}D|H;QN98zPQ zuLH^d=$66YO6l`~#&a#NkI}G-83%33X001{xOc3kN=1?LuRO^=QREzf}iw-PWUogaN!tGljuvf*;J=5ZPU9N=nfiGSA9wG{vf$5A^{ zm2qxD(kjW{`UBM5NrO{Ddv_*Vw5h1!8KfZ~OC7ue^UxD+?P5QAy;Ug$xj!o!mn$4C zJE(kVz4b)suM3Kgjt?h|E*hVkG#c;aqhk8PMO3%EV(eyxqrHY!JeUv5K-7#M&#gG^ z?U;xlKv^U20s38^Loe@MGG0QrVV(; z{OTDwvVU3+;AKcu1V@za{JMiqqv>M?NFS@6 znnM46Hn{mpPiFm;KV)N(anZ1Uackf9GCNo)MkTiz=aTd$o89-qRWjeGjmfefjr=+= zdQ6bXBa_WlJ?$5tz_|oV{RY(mjcO{+wzs(ghbb*>4|kxIZ~fyhrV663j>^uOIB)=K zgMm=8;}yV9m&I40!RI zx;0b4OUP23Z%xfRw^uSmZg1p8=$~>UZ%4r483Q81Y4$MUXIyUL?cG7~I?zONJ;M`= z>2HhO)T$mrg3!#j9rH7t$<@p%?3B)bf@(>M85b&}4B>yeg2VgY`3x+LIf4dZ8pUfe zo_JFy3|cjJFuQ9+E2CA>U-sZuSDEQ{8b11Yx(q(B5{hqErBBEuF1?<{p!jqp)5*}H z3(onegMQ{eQ*LZHdYDXY$~ymb5w(N@%Txi6;xz4-A0#Sk49yC=r~%hhNWGVN z%Pu(oW+6=vCoF4Ja`<30`t2&fTvYP6y)8{Ei%p`jCQBR0x21}MWKL_?IyP3Ecn#fS z?bPQx4>YTkn$q0o_iARxee0$=mM^cz7gyVfecy=A-%l>$Yt*uj$^Dcjch-W7In?C7 zT{;+bTce)QbX<50&~FaflY_O%K{E$d@glpZ=2+#+nYl>Qbl7d?_cvu(fCKU#WP;`X((@2OVchWt_YtB^OTSm5)9yELQXZ6&=s^Z+uS4w;3AY5JO;gICG;xWn6c!C^-6xWJ#!Cz8$;=*BY|HT-u_TGzMZvJz4VPad>pNms#kA z4-^@f6!|l~$dk+o@@`7mq~u}Gn3H2Ad`wEn@wWM?1DdduZV=*zY46O$Lux@sf!ex_ zvXIiOyxO$Z-gdiKvaN{!Hk`$O?q4b-?_M^^T2dHhE1SKBy$azu7({5#}a`cPr1^A=I>EFb8weCgvmX#XUbj4XKSL7<}*y?>_-!%x7UQF`^Sf+ zd$8#7pmA6Cqd!4ejlh13?>dcX`fDN`YogZ=spf;+w~9m-XPTSF8Oms=j^-XR^#&>! zP6>sa3p7q?lKBRTCd-9ol4okA>Rc(Iu#4efC7{xI^$6`v$H8S|xm-}?osLJC9Mm)K zVh6wGlXtrClS-ylpD7WN$CLGxr%|rm--nPVparU#l4C=O-=l4Hy&XF@#OElGyPuR&>|QHnYZ4X+@fSu84pC$ zKgG;*!p?CjxW!LRC^+*+B}0yuIf}l|?SC-bcF zE?>rakih#}e`92{lJkhv?(bD_OsN{5fadf@p0XU3;L zp+Ys4=_R{jByVf#mG+F;_{DY zjaSB(@JWT3xAMCW8ULQ-xdMZu93P|(c?vngF|{iQQxMd8;S}VYtvU@ORj@N_J-PQF((r4ST<-t=G)fNE zE6i*grcrV`g|qI_)O|dNzQrWk>NHjJR23viAuRM;{HWqRRY+Bey-*Hkg<{jYgK&B8 ztZk<3Q_m2TJGbm9s?4Zj>sY1-qUP7;drFOr7pAVjtlY9G= z4+C5AVqWd1ca)zR7uM|}g}ObY(8}G(N9a?2^nhVxLpy(hsU)aHn-P~j?p{JuFKSKB z?@RpFL@ysQEi8|dnrO};wQqnKd}xj4bGlxT8>sH{ig^kBCi$1ma)kM{c~;(apXoz$ zq?#U!var`u4yhC3&rYDS#u7uf75c(-ELENDlU?+M6Wlq^f1(oGhtnCfM=5>5&9H6y z0XY_@db|vKa~-u!zsAq3VP$=CXcdgWL?>!OSN~yBr-wk?5u{F2A0EMKxP;LIR94h1 zQuKh<)k%462_M|Z|D*gr%YR54*0GI|uttiVpz(J(G8d#^0L0cr{%sU) ztDjlLeXt2`@kG?6y1W#w_ndDgBIl%^;(@Ki86M}M#cVF7a;sWi2vU{Df%mJW+EkM` zGhSyoPNz==LVRyu+HqC2ruHd-sr|Ue1b7Y+FhP?A;XpUlWJazZeP;kD-;cgDum+Ds zH8BSFZ9{2LKOD^RTW~}Au&Qtu#k4N56ecULvY&B1s68*dFxE74((Jam2_HYF1cfW^ z<33`+i0!0X=)Ss^RWNAM{=i!9@GO8!wNxt${`#9Z#ym zFJ1&M%V?!Wla0Pv9}B@Iy4j4^9=_)04SFDWW8&Q`LRiS|C7g{l2r<5mBlRlFk$}ZM zi>1r~g|jurZN3=!tAyMk^S0?Zo;P>ghR<T|QD??rtx0J;JEd+1&K)vo zw;UNmibgE>(062(O!=N3voo;0PA@yuEm$BF!gutKZ}d$4Ncmw59u14=^7sl=l=l#d z&yqX&N;L5{oLja|9hT^h@m5Fet~rKOOm%inCS1-;hn-K6eJh=4!>^GpgGzY7HYL@O zG^Lhi$RXWxiC|WNh_Q=4SvquZ!LR5OT6(*K&E$!b*u5Cm><87i)jUer01%pAv$b~P zFmpPhuA%utcHL=@ADl*yVUsVM@^Mxj6pDt)od1FOvPCcP%M2*JoZoF7b92gE{A|XE2qA5IcrhQ1z;;ldyjaWkf(0cYm3G&yr~vsZglrzN1BP3%Uqr$8o%K380NB%gQRdywOvPsk+D2g8KNwJP$%335IQHo zGm5K3$XA7Ui(TL%BueaRri&zTU!doSz(=l{_-KmM%yP$1Nh5LG&+s%J9Uyi3zF(^u zVKFf0q%yUX=K=^wnH>;~E9>cXUP}jaOjnTFruq|#0=Wd?qeaAiWO2g^H!4T-dC|sH zD&>dC3gKmD0V{2taGUdLp0BJY3tKo|XCPDx_;kd;M1!9;(i;e)vKp3?bQdr4Hn}52 zlj(6I{5+g6V;*-i$E}`@Wi>N2bSFV-13WzeAz0zV-3^N`1mS0b@GrW(5DF+;U0Q&t zh9sC(sZzMA37lCE83}@BPIsfJV69Ug5ottH*}n}J(3NzLRE;10SDpoP9jS>X9h&B$ zB_Y-jA^I%Hr^{(t&qI|V`qHkh?b+1PhP}iVo_C{>26CZLH>+O05`=4fZgf%D0}?(@ za83Vo|0&%^X;PI;QL4WfjAt!T(^Wa3G4DyaoqvQNl(a7 zd4;q|x|eGi_I|B&|7Dx$8%YN>YX@^~n}uF>vYw&`xu?K%B`3Yy)4;jcPf8wpxx4iG zS{_e^LNah%hD?DndI`LP`bm|fSG=A!wY7S*5FX8~K_F_FT*Z1;wIObXr$AED%Ir*l z9zn%iGRRJi(Qe+@??ZA0!t*n1xOB|u=XM5}oisE35eBRikjnvY*WyEbN=g}v@D5po z*9yXeT0osy2=Abv(rYA(z8Zw5-f4!8G(E6cF+$FgpRGc8ZumC#Fb0MzW`aXnlV&dX z;SP<6_%at_ghz1XJ(4d3{W6>Zc=5pSQrl2g0`Q>DAs?vJI$szUj$EgaREeFF{-8nv zY1T=PTdB9+Rt$0hwQ2%mzS@adr*mhD)e`_YsE3G}N9 z+0-c(!V1{US&?%I{G&JB#JB@dgMh5FpwTsHaTL@d0+I5jFT^7|7Ot!cR;nB6ei8R| zuC6A*)YpG(M^E}uIb-y!x{Y2?p_FhCwt@yrKwY50VF~6#;Zz!bG16Fg5I$zvv|rKL?s8cOM-Mub!t*8%m?#YXOVrNVXK+k z`a#1x0W3sjw8Vhr6QZSLZU^;4O8>g8h3L;O28Oa8$!AY9AYe@t$!_n3_%;vLkm<5QMgoW$8 zVyJoS8$o83;thul5kG6ot{5PKElW&Zdhp@R{@Vbe%ar6)?hruK9PiB7p>i_JbS6I; zb}cb!gE2u&rf#ejcFMDQOp`y8y}gd{_HuyuEF5khDc_n@IQXsNE`tz(c1`v((ZpgQ z#JX#GQQ+75NRCW}awEnb%&Ame=VyCAif85Bf{7M*T=W^!u3)tolZfYr>|O^6DG4U}s$*};P@J+92-V`K2 zSETV{w1qQ!Ot6MCb88t_uVfT@8ls3kjos6f-DvEdNDdxO4#sj2TdiM#rCnG!y8j=~4U%qlzf4d{d={m{dN%cg z3KVWY!_K*ym#TgkTh*LRdeEv*dD<#M-!ghtXXa1uP|aMf4V58s_8WW;4Y5g(fY9qf z4~%ThIN{o=a071E0*9EFL1LIpQ9t4Ka)1KAT-MF2T;0zM)Xjg09`>QCI1Iqrr$i2L z+c+s~WTpu+`?A)nPV)_#5VmpfGwl@kW{sfQ9?dYqkwI!>kiu3%2jND5h8dV9egA6` ztXV76OzmJjY~Y635$EYZ29rR#>V8rh#oicve#^ zyCX7Zi^CJL-P0mu1>5p}wehYoTpX%hGxx)ki57H?RT3HP;U=!&9!^!EBYexxyoGO6 zSh^E)kuXFR{XB(Xelz#Hw!+PH5F|CE0!L1 z8Os3U;AV;uPkQgOj0?gE_tQfA1)U#Nv7 ztVh%|wID~%E=SV)hI2O!lH{&29Z8ippT5BUae~vEg6L0x)9*P=3wRR6F(4reeIuPi zuT-VZ%g?haeN??bg9L*gq6uxI!PiA}9Nl?^6uBgLeT>)iPe7nReQ@Sm&jgz9)Hi^v zy$ee|p=Z_ddQQ!*lsWqbP=hxNyxvq~;Poa# zh!;|zjna%BnUYBgLa}Woql)v&9V%GaZ&e~>6lkv|eDY`!hPi_W>t!EhFy0K@ zHlyNMq;yc*sR59f)t*8>X9h$(K%R)tHQZDKk8++208F=slbU(hK6gk1Nzb{QG@cvDSW38D@mpj1+FPm2ylP zu2frfZscw^q~hlqxgnDQIPMeS;qg%+n&Sm!^(2Lhl*HIH4%HiDafL$)uH;7DnR1El%Bd(>4WfQv)|7eg}jO$ zj%&`09|GpVfgWo|JIj9inK^ujC)(upOG` z{oL)+`QDCq{nQ&+lO=WOHjIJE%##m2-_nyBHnZC)iuT?Uy`jBq6}(HiE-?XNSk`!_ z5>)LpKF`&pelEfD5N;86C=?ESC=r@7mM%f|Q$g`jvR9&yvh81qH82~n&!>apE)2}} z4ID9kkvJ7R6pe<(tAl~W#cRgd&NE|A!XX?!fx{Bu7gmTyGdffpLF(8g%5xl;0LZ2Pm;4+CE zWg0`a!EK%8$#;eG?o5(Q@WAd;VC1$B<#*}|NDe(mYCmMS zZuA!h!|{+{oW4Dc*UWHJ-$?QG+9I%=I$3zVB)9IXZz_+{+}P)tn&{=4Qf}6DR^i=v zQS=S-D`PdIc;)%4VYdEQ4PW|3n|QcKolm6~R(p|Ou$uAQlG}~JYO*8~DtH-IqvvD9 zOR(C3-v+A%Vd>UOu-bu(u-Znj8daHKwTo-0Dvh4C1HiWJYQi`XFz+W@@PZoV)lv(v z*_tZ;0T^Ku-IVwf`nut7)ffpJ4>4;Wa%O#5ty254d4)`fqS*e0O5bVvG(5n5nxG64 zOq|2!o|{F>i((B6^Ohi*0<78RG?nmZRfs-pA2>~5QSVfxE?At_B_E$|eH|G<;B1gK z-a!VRac7$PQu>UBsd9mp3^6l9PCdE0Zh|H49z^f=yIH< zC+!E0D;_;%I zaAFsq#i{M&CwQ_*-AS(M{GB}i0y+jUxMk}QR*Yypq_s3-Bn+z7^MZUF%jR^Wfax^Yiy2FhM z&nq`sh#TeO!Pcw#PI@hYDmXE!Hw`7z?DgDXGNRRDRC1GK;c%|=I@8k2WjAvyAVe98 zI8;wnS;plmI>A_WK`Qr<-3-o++A3EZ|MSXj1_R+>kqyricZSuSyN8V_#Fz_M%N`2Q zjRMqgs?UZOn4On^)eJ;C$4P5UgBVJXp?%Uy_B|O1@SnqA5REjb4965uS&-iAL9~L> z)l0v}A}UDb-P|+yXB@{D96eu~H{e;k6>XkyV{&GUiE){m2AA353ZM0_PvJ2YUFB6Z z38$(2Za7Ly32j4#w-qXTt~oQFGcNA)jQG4Z-3HsLWTGTdmwH2|^o^e*G-=;eM? zPcyQD@IuEh>zC5Pm5kc*4&!2mGF<+9t9Zz*g;R!1F+dV2n}92N{z~CG-5;*|oU7fF z)fACMh6Ol*7$|Hdh|QzaosxtrwULj|u&Gj%AFV;Ig$ z(wCMbxJsq!X{m{GfRR6l9_b0!ut=3beU9@NtbP|KA zxPLLK^26);qpE%$fqgFOzay%`68k^td{wemVhn=J!Yp%DGs6)h2$ub*8vJM?`Z8H7 z5k5<`^vC0dd#70to(^h>0-}>?bg{x{=GPZr*)DWsGMCOd`Gi?y?6Y7?PF_dY1Vx=8 zbEH>S*6OG7eny@^OSp-zkS~o`_$NhP>OxS9g#)wNXVJVPDfA^t5R;LaSV3HdY%&tT zVdv_>QR;mU^C0JkY?+c}w@tu(pQ%CGH@jTYw5pUel2ka56JE7u;~2OC(Q>s=6RX*e z(Gv2mr%rYlEf;FOe#mL5K~6ibtmSf3X9z(Ow|B*IgPb~tLvHJ)7AZan7w5LZrSw0h z3Q>kg2^4F&Y+0aCs7f;`_5qr9{H_vmTv%~qP>YcV-zt?7KVJ`l*VB?k5erySrRtyS zc(4uHhn!ggFg{L_dWG2m`4Iorpl=$;JmsgMljp9HrnJU}r|1pBO6auS!Lb$#>rtm^ zGm^e4+=9Q8v4`)bT*6Q&+Mrw=JPKPr{1C)qRlg1+sgm-B_1 zaKe6)ov@2!@z&dG;Y{pT51gSNJ|Q?$yN51s<`(2Y*#XL>bK527l?^rOm5WiyxXAyg z89MFeVY_YGy%%&1dCh(W%OMO zWu#}N6b0lOC}Re)oIrsxA2KEmU5^UeHU5>j9P$}=-8v-y$M_WlP`=0IN-*rMv2sOv z;hl_=^L>zJ1W5%Lal=*R%laS<<=NK-;1$EMv*H>94pY-_krDV_^mx6ure7l~aGRWi9d z^HDalRpAEUlr1h>%%m1Kg#f94GrH5u^+W5ge%7*m5*$V7#K6pA-^?%x=1;Nxb^duLU?$B^J9SggkW=pbC?(l`M1_aM72Fh<4zg z0of@Q>jbEwQD@5pfC(RP!}4B5J@bzwv|S5e9b=>-{yXYPvXU&1;FAoh*v66|49Uuy zbqABn%Vonkx*VNYNUu?$G$m(Le2o@Uj9kSsY;#%z!t_J=wPfKy!i z#h9esV3MQpHhS{gx0W}vF0>A1X!^s^D-0$%JX~aeDRzEq=N_13xoX8roxB*6*b+c< zlT8!K5MvTsz)G^MD!3e@B*nXU@U!y#Fo6xgj}59p{lf|dE_o07A3S#*Z?!Y)PUbPM zmMt`Q;E5goHNI)j0%e1AJ_a5O4q?3qcEbVstmRwggkWPC9gXvsu55hfQ2@11w9~7cRBNgy|CvLL5IMrcJlCWM%ia{`X7>zqrQz zOxNTEiL`$pn)ImwQ57P85wQ}rhyC>4n$&`hS!7nf%5+V*phFpkiqnQV=WdbH@%3ta z)*8yFYcAChvw(44=W_U7P1)R3GksNq%Um|n{^wkm1M1^FmZo4`XWgHfawY3=zxJ^F zz4uDqk344TVZU8C!Vun8jnlRgV>ic<-TZpi-a<_`<)=x&;4=gDhF$$d_ z7bc&`e}gONEjrr|oEg5~CiPi@ElxG;I>taydOs#ToK|d7M0ifdBNeK|(erzHmK5HF zYKLyPeDcZs9b711*1211GjY+N4el98JoGUnTR~lFN$S3sfz4_Br(Y0HVPjIpf~SZf z@SWgz{_nVaDbtZ!x$#aT@=}FL~#l zH>~kb`H>WUk!OS!rty2}m%;Qihfq0(nnbn^*9 zYThniHq!>!OPnhM&YYI69pZBPMCx5>b6z0*Y&a_a?!WY9l1$uBCK5!G-)RUUJMudh z*=GbL^6o-TAi>Z!kD?IAIf#vXZ~Kewkg7%ZuiP<60p`PM36&_b0p>d)h}=zp`RH1? z7qlE9zRnz`>61-TF5`Xi8M zR7}Q+N@&e|V?Vr?9(d$B-?z3867OZ{a|n6k`4nVOYJRkg%arasB`$p~ zT#HAPHi~26ZQPy?@$ui@?I~X@nonf^qbN`GFP~?4UD6@^)dT1aaUat9>lK=j&@u%e z)SGSv*T@yRm$(CRuMOT=6{Qum3gKjRs}6P)PO< z-ZZEn{}UL1jhs8-eE3XuLiUmDm$P5_(j)Hkhg^D~Tq+Rv8gmMHMq=K_A+%OVPYg*M z_Yz~qq?lsHGX86Qq?j-8nAR3AsgN{UJ>}Q07S+g!rb4Mx%z;+m=HR8|-~|q>mz$K! zN-6tGkzyK?tyY69xM!EsTiDSPX$-mW{$5VZ;&?}csRLOBg}ciSXW2VpxZ%XivadZy zY@-GbR~8P;{;ZgAK3s(rGuyH|rp2r*eyg$=hx?zNN%mSO&CWkV#t=V-8MD%U_Qvkaj;F&Sf zP-G4`2YFLrnSaM|XJ!ky$BpSRcaO33n6qev{`8pkoChsE=EaY(3XM4#?PD5xmSqxp zOxY$A8aG3asYWyjeK8i!b;C8k>M{yR&8g-PdQ3Iea|D!{$RKqU59O;&Fy?`9J54wB zw$3k!0Yg^`p8Kx+ZOu)ZS}$ltXwG|yGWP^D{U}v)c=W)>|42lc@gs~c^GY=FUXnD*y_v(9Li1=$q1of|;Q{9)$Rs#H4*7Ldc#__+A9(nz&-~9^A{O77 znNj09Z(Q79eI%N;!8G4wyB5j{R(GoolwdTdbGb(O4afA8&}jC2i4)MbDR#I$;nMu? zq`>+prqe7r4woftnvY$PP4ltK*fbxzj7{^g%h)s@yNpfqvCG&rAG?fAb44$kX05DA zw6&U*1#Lp8nYOJiR?SN(H9v!LAgPra>TqxQWHD-f?lMMAQ@@5*)3J=2s@2|Vylug< zL6%bU7aa6aYU&|s_pg=?Vx;Nc{~xN=P3lv+b&Y%ej_psc+0nm0E+{ko?*j?FW^zu& zBj2$d931ofehCXY`xD4~qP^&u62j`By@RTfear7y{QN0hZ8=g{8Pz=4umpllGtOda zI?>M&ZoJEkv%JRHF2>n1jWaAfj5BuC7FBKBwX+r=aAxP8CNtQUq!`{`gS`G_6Jp{b zf}$xPhZSDW8k92?vOQ%R&cd{rjs9{}Cw9QMa7+3$CtrbE^xW848EFkQ8<$rzUhvX^ zWxiRc@HI*Yqdq$zxPwG{SCvB5c1lyV`fD~ESQV9`t3ZFe72PP5Op91&@uOInF%L!+ zKdVY@f&{MLo+h7geytsr)`@C!MSNU$(gyd!wOQ#@F3G0W&iWE$o7M5AWuRDZhbt^92p1KHg0s zh>LkQD@-mAz`N;kuRrgmSkx0SKGvBF;eVTWH_>(AW!OE+kERX~Mip?b#0NOUiE(44 z<|r=EZ^XAL_zh!c(koc;!;4Efba`)<=}O=pyF;l|@egyX^tdUIuE|O5FGQoYt6IAg zL}Zy7>5$1K{JJk0YG_1+0k#Pr}m@S90KU`M6>C&>(5$4j@e7Ixsr!FGw%KOB1)Xu zOF1*|3n(Tmn@tJJW>dnl*;INd%ck?A2E96#KfkQ!4;j0TZDrP}jL)CZ6~mQAE6<|B zg=8L8#nS`SY+>ANwEh!1jhijOJ1F%`v+--1jmJ&1A#0M(@ieLBf5M{3E$a--j&WTDkig84r`dBgMth@WnKHy5=}+^yRthd zvrza?4ws9YDzy}hSo$_(1&_^HX2L3x4qC@&?|JTVeU_!5bY{^FtL=yU z$wWlyOL^i%Aa<}_+I4E)z2p-g7OK!Nw_o9-CFBYI&^cy@7kTd8aAvWt44t!3U+31^ zzJ4X#i_}j@M*H^ zSaPa?pW-E{$gS>F*XCVDMXFlTKY3rtkL)R4SI8v0pucV^nx(n<)kCt(8ZJ^?s+L-D z1SzS^U{d|XT%@+%;UZmo5f^F6J$Rm@0mI|uaw^hIP?6qa^q5lAT|z|)zoJ~Lu1rO` z7W4Ey7gLembIeeYib8UcGh?bjy{HG6Tpx<27r-jp4y)|u@u5Emj?J(4WVTOv+)$B@ zgo<{p26wfK=tzY$R1VRRrV70Daj}uIsrf~0r1S-`k!Bm(`_qv=6qQ0%S@;k< zm9vxsK>z@kI7#(nbyRZa6-Y^!(WU(8TQMo=sn7H2tB{gbg~$4nl77Z?<({fUp-gD5 z`r2~(8lIj>4^R4c(!0?>GlSGK!QhBsTAV^NgHZZE0dLU!K!E)p8GqUhJjQLj4cSXsu04Rp2~EWzCc`mx(yl>BS!!% znq-62fgp1rCM5Mz_{1!=grr_E0osO;ls8QIdDKt01my>?>W!ggAta601kj3PR-5Cv z_30bJYE=SQ9mBF073*u} z=l-9y83i&7r9t#S%uq^<>E=rrO2;{Gmh>@{qBO>f{+qPc`YS=6L28=A+!Qj-Q5oG~leP|GZ1%^HJeNv=6&Csk^q zO%OXNlx~pUDJ{p_s=kjJ4`zpL1!`c*Y;Lug9;M}srO@o7C)MrC=}C#%z^Tf|GSRc(|v6)|qx^<@Z(s?rAo<_yu3;+BUm6|2Ql zm(r82hn`fv^O(yorY9{qAu}b^rH1J2J<*ePT6$9DKXDURx@o+L_u!O&fd7XG-V?XR zF~o)+efLs&Qls!^Ok-{Br6;B4dJXHtNxF}obe=JaCvGg4%2?c35zjhxz zDeJ{97OPjHC&geQr`rFA=}9qjP-;Odl~7{08*!`IZ@&4xcxpBDq-tOd6F>SM^rYt$ zR-n;R%}lON0UKI~1?L?@7p6_f(1>G!G12zojSwljl$x$0XVA^-vp_EM*%*%D;vYNx zup}~Hnq&G~Z-wItq%NIIYN!**xSrIsq7=PUAu(l(i76Wj%wdJ0IkRMhz*VZ!M3fE1 zLnygHK$-5?>1#4hS2jBjz?jwR&zwwH$s|k+u2hMb)XsR?AD;*lKx6 zIj3Sg#gXwxR%0BRvGLm=QF;9;j_f&1Eq&5*_A1p47gWVTsyUIQel&4FPd|Sle0CnR zoDeSi%3bU)lxG9-*nTX#m9HH@`tgO0RIZrzMq2k~krd%f)EpG=#$RZp-f-FPem-mv zayaN^gCHlyF&aIQ7uEEz!BeJ1{G?6W%qs|PV?JKy4r#Q$KcT&&a^fol<5dszq&FFQ zQiA#Uj5UDkE&894xOkstmYS*NYV@Q~`X=5}`K>7Eja#6y%%W-LHZ!4IVW#;RPyVu= zn$^Tta*S?j4%(B0waGy<2W~^2z0s~nPx@JOAMigRLxj#SG-BPlg-OZMlgi6JAw zpHy>Bv&IxFjo0{<*>)+vT05>a=U3+^wSyxblgS{7S1cNiuke2UdS>YV(;v|m?8>a0 zT1adYH$0Th3d;w>YmG#mVWzKuy_u)F4w^I6GV`fp47-B8>mEl;1 zM{>V1_L}(&8Rs{v)wDi_11O$ZVgq}d0-Qv!i+@_o! z8zRD_ZvTp6u*pS5;is1w7aN4nN|BVteo1UL_Pv2F%bKP;cnJS3Vusnw2;Txz%oNpp z1o|v54Z-0%m1%-@mP5)=%T`J~mYehmsuW#wIPnM!R1@=-f$FH`Ce=N;diWO%H>rQR zTOLLD(@w_o{2Cas2C{B^@j>gB3?iAmkujp{ee<`v6CDX=%n^gKAd_?0Zy zed7dT+Z?^MaMxO{GLZ$jVc@FGRpD0J8t#b$!!hH^+OFORXB)lY82|Th7l#_dOo{`W z<*jPB%%qk#JZ2{KQY*d8N-y*e!dnGVDBu@=KSNAP+e5Rq*^h}yclvDVpqWA0&#XZ4 zqo@S+&bae$<-6PX-_9UthGWN=FX%(>(8V-7GwA+y=~-%Cm$|^aC-BHl8O6XB_F(2V zYd$z66*qAbMpIAJ7tKTm9b{YeAhYxZH!MBEQ;W5M5XDxtxTy(8X!=#+DN}nSv{m9I zC60^f`Qi?%O1@8(&abI_WSA;H2&NLrdMm?2 z>4i6f@(j*6MR&ymu>6z>P@yE^Bz;YTq83|rQ%pT;Kc*Sgd|Ynxh$jJKeH=BhNnV*6 zVb1574phE1cEpW;h?lxcy8-43hk((+=UE&+!@}#R6U9s2h4WeE5S-6?Z&h9w$4j-a z@5`~tZziRWCWw;s;u?SlG%H3@Hr()P*RZQN;ZcT>RKH>*MUENXBrkWPP{oa`$fw>} zz6`xp!$O*%rMjWwUPDjB>S@yN4HTYLA>qcutjVfJ1x9kuUP9&I>!rXq%CE~dZt5So zPDj9kZsdha*c9$*^<3@qM_wm(lv=m`(H1UCs^9MVTHYRS$gGu)6lhfFa- zd&e_$q@A!$?YtTtDSW<78_YYH!GL#$qSYm`Fq5A$P1Vw_IgJf-On<<^@oH>Sef136 z)W;3m6uJ?@F7$ph@j9_h!ABaanc2w%T2Uq*ecAxv&Odh(KGJXZeh>GAuZn02;~~i; zEh#>$YZ9U9sR|HOSJDvWWfqU@teJ=sqtusc2O4J%MUdainW-2dGwfLqk@% z#d^}vc3~Z`Y%#o<&Bxepq;SfJ@Hi7k?OSaB^aJ)biQgn8y(t;UPrj=Q@1R%$E7z|n zx%XK)==KtN%rNI_C8%@6&nU`p_5#4v8DetWP9Mk|5?Ht>+$C;hZ{%W}Rsg z5LAd+CB=wLp`;=qg~6|(l{#HSo%R$u4T_QWGR@O>dT9*Epr&u6NhG@a`~omibVCI> zruqz2LUB3{&&0K2W2%^v4x^kWtvP?%bKiIug~iqnSnfxE0p3{yg%S^8l@Hf+ zZONuK$tO?YUZw9ztj2_-Pw^2vuh2ycyFty>&)ZL+kGZiy4Vr?OFcqz*J=)fF^+z;na+{) zS9PLxb8Z_2AMlgvUw$qC$&Ehg=7L^6QiI}Qw-?xH4Fj+f7pMVthrLt+>`Vpp0y{Hy#B&2vFW=w5|4V@#%=Kap zAqv<6JDkRL(d!i!+z0HgF~DxQMocfTBVK>81$Nk!wij4rR~?p$)D%9_<0j6GGFGQ1 z>;RENo^dH3sh2+LrMup545`vhdtB1}{4gkT!@vMNW)MkS@sava(F^oJ;F<_xA3jom z-%8UNqIog!djuDH8RCX9LfPlEe3==3hK+O!y~e90;0DzeJt2{uz0y*QNJfZ55up2= zD{VI_-Ee8I5mHp{S=YnTqRy{3G?bLG7p`wJlZgfUDWZU zQpKZHboaXjMX9;RPL5KvfCp_SjwTEN55_|MDisGlBp9R2z{AzRLpL>PWsxhkdX*t& ztM_t`n9#IG5Ez%C!;dHE&=)#n^-E<0kdjL0XCRXNj+QAkoFvUu$cAT(R^9UqDd{|J zvcU$Ca;DZ@A{Zw1i&t}NHv;CshhPJP58>Klsugs@>OxWmAM!ba4?XSTp_`|?VrG{F zA1Z!f!rguG3wV35LFwxwO%8jO>*H*_iMtN~aqb2S5Q)qJ-6?({277D_q&sGV9KVl` zRP%fvAF0k1xpsAgX!uA40I1*J86ld_#0c>sKGI&S*vm(1@rOl?;vc?T*A`HeD2D4WX99rx8D}GxzRNENPFNT#m;l)=YtB~M1C`920i$yyxZTL_yByQ z?cyUXn9o=wDy86JK2k=I(atrSji}k{u8exTk}>ET@R7b*PvX+dRXk0*nS&>igNKuY zu^hM!M^Vw?ljSsZm;}4wBlQg5dMYq{q)YzESbP4SEMpy-n9!1T;%>58w4_`#e55@M z`){Wl!@jS;NI=<3n)r4E2M{hNl5R0Ni24?p~h_(A zlpIUpBWn?GUSid@&DUBs04eUN8rDX{vsbsI77G^WK*Cb#m zN$my1d22m2B=IjQQ7PM1g=#NZIwaCv)jY*Fi+*8ZgZFL1$$EfMXG{{ZlgBm?aIrkA zfD#hYO59MAHk#^@^i(}C3$T8P$r_rOx?{2iP_noUuSQ9VVfy_kNujygW&$JoC`p$> zbLF-b?xgvd#Mhyk@1-P7stPW|K1$N0-c$lrMA&-6Rd^oL60U~QLg}5V)Ip+$pd{VMmU*ojCjnX%0BVp%kI5oM z9fvy_EnE`7?&dZ9Goh48OG{N2H@1MSo{`l@uM^(5u82PyiE#wlZW6G**hHqx=tJpQh8Wk@69fmiW*J+ytK9w8m}+myR+6(OKcF5W}*B& z>iU!noa+70A&}X%$#nF%RM zKl&8s)oc!6BaCgYA!o@rxqLh&ro3caT|9aOEcHoW?o$Wl5Zd@SxvtKQUYjroW?68C zP;asZ=0R7^9Xr)eRSK4_>cT1@3Z`=^phf6x-k@ty#ZeX5d?Ce}5Bs5c%PgT?9g>iW zbzw7F=0y;Q3ol^#~R6HA8PD@gO1VK82u@X}knt}UV#hKQ8) z0sF6N5kBCH)P~KWmpSar7;6Zx_NLSfY+u39RoQ!MmPb`+4NX(x@OBZC<9V)a1qd|c zo-<=Qj#K|$!a%B8&1P_qet^|Tbu|40P+mcp(in4();F7ui8~_w^=^(?A<>cTjA%gn zK8*sz32mp**(aTCZ=y4|ssrl&So5U?t!jHL^hVMoBe!?h#!_7anT;sWJn)k6yBYf7 zF6Z`2Dk0{-f`4>?<&(HBND-Zn4FtPU#a%R`_(ul_zhB4f)_ZIEUDD^mKiY!3(;mw| zDxt|9Q{umh2LS!oOe~kkhpOm_gnzWzuiYP{+xzp6O4z~9*`aye&lQM&R6aB@|ER4` zx8XixH~u~ih*0B6<5%5I6+!~4#hPRtmoMQT{d_O~D0@~vuL_TaTv8ED4Oo-msuTa{xrBdoe|1#2momw&ZE8;`^m-ey zxm#wf;U6{LM|7Jj@Q+Rx|0wRnmYpWyAGOBhsL{GD<%T9qSv@iT=+OR5Sq7I$>X_>9 zS!8gTVaiIpp2RU@^!5|09h3m06~LV zd>ar?2c%5H*KHG4Fv~{BCC$Ar@E*4kI{9Wz1=Dm*d;av}BgIuwUl5Yh4vJS{mbapg z0QIB8^^o>q{ALk$B6gBP-9_FO7)nQ$%!~kiMuNy>J^rj_CI##0$(wZ_lcbnP6GWOo zwFH7C-Bd+UI?2@2CnW4h)1+i4n;?XPv&kf`;rNQl1n$9lnfXVh1gDYXn80ES(td-q zkcL$29pwKC{_m8ESdsW5)e^JE8b7t$%dGLjo#AoGWkVeg$J-h-5Y!4TkS%_uC43iS z&_bi`=^S2#r*>*R?{NkDcdD7N&<&$$&_81MNC`D3#f$hzTf2GR@R7Cy($H99Y&RKQ&}#Wey9Lr_ zaY_Gl`$dj%9(=~tcEoXWqXuI5)tK{#D_ZTi~(&E4C8S5=;QzX>~FFwqqi zEmf?krY+9K77HD%8*8@i)U{!6pi|n~mbSF9PG?G63JKCFY9L|CaWyOIluq?td)eIZKv1Fb)7j}7uoCMS!+F? z_w#@5=f3~9!)u$~4Xvd%R44PcuF;z*`r)G!eh=|ZFRv~#rrg1pA= zvxw1*Km}B4YVSi$T4v|H)TCWnqJ%@BCUv95z^sFOy#p&=`}|?7c7)gE0!G$RlSrQ< zSJ}dt6>z>=4PgJ3b?YJJBbz*dW?bFVa+$z9-W6ahTW%_Vb|ci$hLadhFJs22RRIXJ zj({7=p`T!R1*w(3TNtt#QD+zpLky@r4Wr?C--FSXG$8rR0;3BF$F4Q|1uV2;j3%!5 zei+Sh#p9*U0LG>wb+`wkAwS_A5JrP5esM0WaN2n=A#IrCGk@k|O_J<1BK&23;X4fN zPCrGcQ6SnxgJ{YiJQOik{A+?}ioS}_v5KU3s_24jR&0J%=4^1SZ2qy@kX%4f&oyuE zJcDSi70(p~f806^eT?IS4QG2`vXjW(eFmhW-F3QUHaHLeL$9rxrp1c{nQo(+oNEtV zt&FRPWNs~^B$mnX&|}Yhsotmi!*!o?HMA6lhJF|pPS(4{GcuYkVJWE#z40!BnpO-# z&SGJ3q0>XB%~hjK}*UTfnji_P_b36cX!D(mJ4+NmL| z=L~nb%UKaOM+BssELextXm;blrf+&zA(2@m(?@qnL0Td0SXMEZwMV`xU$vZpP@$Le zkqT#^hqgrgqwU$M=cs3ULSZc6AFa69R=B8IDOGnn@tTI{QMyq+%+z(`ca>Uc5j~gc zGdVM?)|>pn3zph9f;PKjCVGq{oKL|K;Hs{efOG}8%0@aGK6^wu))=JpAs{t;0~6KK za|uXiQC|>{z6-3Px7c%i2uK~Q>PJA@$L6os7X43zRcyaLMz>=~+J-A=2WL%N*D?Ot z_+X{i03&+<6D!Mv@J!Cso z`i^D~$3W^<<3h77hM%B@A_3>e$_A>r-I!Ab?FEs>uNOC+E&hA)lV(r7NnlAun^36h zB4D4B-uo&4W~ymt1_%ma1e><}$2x5b+8>qGfu$V;(tyn{8ytwh(moK>4z8qwW0ae4 zd`s}_3f>$WRABeKL@bXP*5iri6@59eWZa616PjX)iplNeJy4nrO~}AtPZuRe^8L(mEcmv6r@kuGv|iY=|Xmk zf>dve;n9|F(b!Q~oekM=EUa2@cnh8*CDWH;?;%f=9tYco#4<+FK6%cXBT2H8$=(KF zHo2Y^^*%>Ix&py%X7igwLE1e&nB5NEh#A)xI|@?pi<#eTj9^S}6nSl?6BrXmz5&LV@jScmQr>()Fs2bE$j2fI(#MQ_Q)Wl%;Tk)g zlvDRzA0@h#Y6xT_QgJk3&#Q)&?ue!9-JRRT`M5B1DK{N{k-kF+2x#zLeK?+%dip*+ zc&mNSshgPRM7N(UjHWVOy{5(T2kVi`fKxYVtSQ^F8)f(@$7=sdP49(Ama1ej#NZVK z)IxDAT#|TA5T=Yn>`v9El>b~|1Zt*EgD^XlxsgiBZc{IW=^(&&FNDFcN)QIkd8B4~ z^;`(!6cGx-iu5>3&D0BF;0as?ggL0n%?5;uLe0cyzCt-rGi@~tv$UU@$zd4fFq_)% z^;0tm!>A@rtxOV?Q1zj?P=)rTW?~Xr3E`PAj9S;5+xD(%raun5NUiiZqk^g9D!yj5 z?uWCll5RQ{0Eac<`IXYr&9IL1|CZUyYy zF>^RY1nVVd?+5v)!4!9yJu6_!6J#MH+$>7D1=`@Kn2TZ=!waJ0h_MWFzcO}Q%Z zkB%0UAg11E2UoT*b8-{@(F3Tm?1^k@EBm?CS19hd;#A^R&@H0hVGgYj-?AS5QBoOL ziP+Ma6D*FoKlqV|ExoOWE!~Ha(`)D=1@xn*99Y4cgRWveMsyeFg7AC53X|}=(2xG` z|3hF!f(eP|C@cxME<;^HFtDV?P*{yS97!mHDQ07$u`Bv?#6ilG=IFaX%BZ)QZG|aBOG+5$N_Sfvq&st=MKmE*HW;dI z)uv!!$YsWn>3St4k1%F2zBUe0VUMAFNDkIch{uxInox=6uMeqFm9HiU*)OI3a1jAOc zu5+m5lyQ)D63myaw&xfxNcfkHgY;-GDp4sjXLFD;G3X+5Nv&l&T7@G>-PT*ID2|Ki z;M%xg*dV`g8;Xw|F$ZZ5JNRtl(LNlcH&X5SMvU_N$H)FYz%QTNXd;kC*kZJst*^-% z?TuXcc@#58y#+ZEp|g^Q-tnFIBd=4L8WJa6pcovxpWY#c&s>sSO9Id-^IQ@MDVJDr zNGWq8SM^UR>N&;-b*3*K{z$_1Q_3j08cr`Wr3}_-8>N)N`QTioj3yVoRFjULFsroV zm9k2EqY~aoybX^|-%mfC@o|j9Ec+VH%Cs*Nyhkjvev-~SRy%h5+3dE^>|>8qs9Lh& zf}}Wf7-1D#g?900!}`>GcNbE!Oi%)qn-w&L!N{da#H1TY8TVmOj`i}0n6zhp7wUZA$Vn}U7Ok5opU*nbk(1hGBPabe z*BOD~cd^T*iv z>h$zQnXn=zq{f?D-~nn_J&NUna*zoyU0gQfBPfrIBEq5s;wzRoICije@>U3DdtD(Z zg3_eldb->QN}qcA4_mkt*T)2--NuWbelsl^Wd2;S+#!m^Jd$m2Ib2Kv<} zV4QR;MPc>xY&`TyL}GFX%R!tzeY{=$r|DD5o?g_4byO-KRiU7xzGdvAG5M%t@eujw zZn7L_htr)9Q^tsY`J-6u)WYqbsvPJMh*iJ0kwk6Ij*2B$~UwAO9$b zoc0ey^Dw?J z^@hsvg)ujvKhjh^jnQYjhqSH)yDXfFwGs8`w@{ntU-68nMJgA3Fkl|Ep5!R7;vOPyntAuZ@vC*@1LZ%b1O6}0`oG~lo-VOIeaZMYU>p7O zXH>11Zl1^J4R2mM7q-#0#x~lb{EBaMlx(yhvYP5W^FF8tz6oK%*Snv~gts0~w{}%{ ze|rz>u0KhS#eYfbOx^k;VJwVu4T`Kq@&1~grc zx}fwv9o4k1Dwjm)Znuv#|4-bn!b?BE$oFyJ?<|b14svxz;3>+~9a+Ky%{yCH4R8;X z*6DnGbkcsdzfIr#f6L|n>*W6{z4@OxO?m&e^8We%n7seY^1kP9j92N_p_bhPz1iKa z?Cyy3-fw<5hu?KLz#-%PYU|jr;_uWTbkUFLC%Khfle+s@UVSRvz1O>T)*Ifn({_8; zeruz5?UWAh+B<&fT|4pby=(oSc-Pj?VUT60$BC$bN4*_9PhH-DPh~z>cc)*d_|R}( z2wQABDI5XJS{1Qm2Q~3QZG6x|Z?{_`<0}uwSL)*{kH%Lf z##f$*uS|)rw8vMb#aA}OSEj@V(>So$iK)jQC!O@|H7x3a_Zqc+rC4C+tL90(QKkXs=? z1%!d57JsUH*YRaIE72gI;iJWXgtQPHz-zll4;^13H)C(!G@Z20uJbv*lVeP(%e{GD z;;8u0c)*oukt^nC;Y0#u(Rs+@37HZ^~p3}~*RtN7##d#;8Re(T=jUJX76TYZp6S+zzF1Ov{dZM$4TUy;9lSu>i~o&#Q4=-S6|3{T zXP5Co+O)Z;_;#-6YSUfm)^)Y$afwUtkHwIOk1tcko5mNl8+UveeUNUVUQ|l)0`4`B zDjuZ1)2*imH(z*s8Fxq^^Uu=dT&ry!5*1_K8m=8*R?pw&s~b`!Z{7<$M&8^Lt8~)3 zhV{U^w+E6Q`JNp&Ne zhWHrmZQiBJBmHnRJE?D#vU+3vfEm}Q9qRoR+|u`vXG^v9Mk{LY)#GGd`ao_lo8J_; z#EZ7tr@;<6?bGeb;&19k^t|t~V6%R!Hx89>*C>vq2tAu3s@8It2ys}?AvOtTsJs^H z^~2WeEln5Dz)kO`am$*|D_x|MYJZMuEK&U6SmkfK@5p1DF2Ic%Z>~vrM^0*f$yHEu z+H$z78Vy=?Go+<$CcdHf?YhNh=8-HHnfCS%m9-4O>2bAQe6t;UneD}AvwY$B5_&^f z6QtB#gJurP5<{hRSEb*0nj2)4HvNjv0H1oh%9g3SF~?enDt9+28*qlAP*A^dcHKnZ z%bbAwDo0)3Sh|q(6G_`>bqkXh1L=E`4TT&H)3JMixUx3CW<{yF`)0SyBiFn1Hd;s> zP^;E)5Ng|ch*z1@3n-2vY zxhfoq9vY)Bk?Ao*?bZv~&AWI)_p_V#A+5Ho zf|;$7yH~OiOEe!?;Jj9?xcveJQ@{ksIpHsJ8CdLZ-j5+UBWmzNODzLz*6J(8HhY8( z22NnJoz;4x+I!$KiIv8v8AGClkyZ9f!l&z|kjzh>wAyeRJ-MKwjy>Lb?`O*u_&$Yt z`ez;KsyDp04dX1Z1gooVl(e}J(^8&>7tK#@%!Xsy8Q6>c!jQVozZ@h=bWJr$@QP~o zMn9~0&`;7{MI$`p=5R?yy4{U%5&Mmqx;xl*rw@}evWoOTFyp|~fvX@%ZvLMKU~Kgm z3Je2{hT@kRNOyAs^Y*=cFMlD!W!PqTvCpn)m|np?e9jxc7>7#w!--4o9(7iy2FmvE zqeUH=;SqIXtnuoL|HdS)HmH~SM+}fpy2zyAgmTcsnD2q$wZ^o@ch#<*JfC97Au3n+ z@xvT?bE||lsEK;NV8{){ttyW%jZ_n0fuLcslCh|f3dqBYz!Eqi7C2DU13utnuE-Ut zkEgp~3E7tkUUm*bUSYV_`oon|Oog zbBR+ZpGK=quujBEq=qQ9-rP5BE2_Ev!LKA;At94KCP0aHHzPKG3mi zP@Z~EitOBLn`hMn;fMwuS+peKgl=9`Bdc1)JRoeNEd!W6k3>CH`Jz`d|||xeE5TM zh?lXq$_Iz3fdSdghaslSZhn&*^hX0eL1PI%6>@6hO6pv~z ziAz5uGAA6%X5pb@>PPutV|Fw9E#!JnZZM%s$taWMJIZizH1EkZLaf0F?rdJ$HC)KH zp2A^%qk$S%sn!Vj(OVyCy@Q68XLGQrN{+Y;+rcb6wm zDCSErrfw9^f{uss%X3(lgAU#ty&I!Ob}!+gV7J|uRP_^{S)h4D6RGBYCTfc{DGc9gr=Tx zWLE{GqM;>l_uEhQa+|ePAEBP5#HijCA8d#Z+BtCCW)cm%_yGIA19g!uK8sWHpQX*G z>6p;J%rBOToXGIPE~id-tZ;*dP`^%^Qoc`9x{Pw)Cq zdAATUpiuHS%U7hmy&ISnyy=J6{WCfWeO7rHkKgMhaK}v=J~B_Fk3!qp7V0iA2U12i z=;1K-ds(C1dQJVvaU>mfz~%K^>UF~n*}~-EDAblQy{_=XG;}D?Fp&CTt1XO=+0+5O zF}-)&G|z2pf0*SpyA%1<66O=HYHr5?Q57sW2*IfqA~hW58Zn_?Sm%tK*y*+EX9DJ} z4!S55bqlSW4;o>etJ{K$Q5`#>bzQy4hWNn-)L=h=pM}f_WE=!!l)yk|)5*zqBZ22U z?i;D&ecu3hdb`H~7xpmG<=LJ;MW@zaToJB-xdIDANa<3o?Ps#Vx4SgXRCRG5@a7*S zuUUd$`UJl`C)DM2^^`dI{P?hG%Pi-r*~R@)n#=661hs;n|7Z8wr@3+J{cSx*rufjU_YA*TmsDtBzsRv-4n_7b70(RI##MoxZ z^jF=oY&&X=dOGe?afj3x61-9uXy=z^wK*bR__mt$oqXZ5A}V=D-85Sm0U*Hdl1`uv zwHABMA*i@qaXG=;+Q?E;_W9Ke>N-A4P_+z)@+vM2gJo}P@Dg2O4P9f6A?#o^qo9l4 z0$SfwE0c}{)QZ@9q*ll1G7qCp>bc%-fvYf+S3a0@s-`#8tZG;w8tBTR46;Jhn$Bx6 z2Q_x8QDT*WnL43ytxKrjWpK%*j4kA4 zKd~+@yOcM2$aFTBLHOJo(ps09(Loiz*tkVpFR({4sv zGD7dco@~U!`iwR$WCs?-vmT)*e1_^G*m;5I2N};8l)Xg6Bt)@2iWj`kXNd>LcxMUr z%0DJQ?7s{xTpx2T)j z8==NWUtgGb;PeW<(nCK&pnTI~Sc4700Ehop+@?tn1PRvN?Evg{b!??w7}nR^jEx0Gc1oXUFE<<)!kc8KAa`5+P-&Q?l0nTtYA1O9CZ7kRUFK?_&ILhBjFi0^ z%7U3bkrIeT!bPO(UZm?1!hTq%i{~e^!9P^1PGX$_<3q>zfeUp6XBr9fAzbuwgp0|9dqLJ5nGaSDTteRPEmUH|QYQ@XH{fH_t^vr*5QvlP`gUcFanf$cvEB zoB1$8LR(4F5WI<7dHOh(wvGnBA@Q=pxHTk85aRc+;YUcw^f&63AfYj_(ojQBhzN0t z2v(A8Fm*G4VCstqYuG3vL%NmRk%&@S143`U7ZBRZgt;V_+&k)}alzzHfY9UveSlDo zxY#m>YxmmD=ask_$2m}+5zzJNUxFra2LuZpYf-ifjiTH=rv52iiJ%$S=vcmR8+I>G{fiq$V{%tLrq0rFXzceJcV+f=hYKH49_5WrGuNbUFHbs2z*7 zFox3K#foSk#DJ0LKmbNA`Y~!ZOkS}f>;*>I#C~kwsnVBfen&y1=)@J8{qlaeD3_q~ zprS)l+O7_xT5z~%vEicQ`2@6zM~T0%Ln2EPhEhNfO_qvuW1yC>T7-*EVn)VXk4K_Z zoe?e?8;*cZ0UNl(+-e8Hxn2ut&T7<&u-5~c@`VcGJV+7iu+!8XbcHnnMrxmPfRV(R z)vtj$$&9#{tBS1&G`rh%2UFvYln-uWfA_W;N(4q)HUPgyrVT-)T=|oc&}}=Q##gr? zJRBswCZDpwAYJSXKF9GviPY3h%)TmC;y| zJ-)NQ)a)c46K8*!t75mQEy7Q25q=`A+0o~#_KM%%=Cjl*;HQdSd;E6v!+hRwiT3RH zBw@u;uNZt<>ZZUq4f_Z_J+joY$u6$$h<~@q;M1poPZ~B@ExIy1p%Y3h_+;~}@+ov+ zZ%okM(IJ-q-|P#Y%<5KZAbqI2`2&E`s9M1&PgmGgp&rbzml>Oy^|jJ%aj?&_7Wank z2oOXyTe@2OyjS*nn=)e<>Sgt8Hk&n7Gh=JE_FJI?r(ZC2Gi}fPjG-OZJN`tJ53s9-y${F6g|LaWtWO=BDS7E_T>IQVso1WlTIS?I3GSyS;??n4sZyKmQdclHUT+a(yPu?(l zIy*B^rzWIe4KJAUO^XVc`2o}p6A0GV340oz(F0fAiP54r{saL7e-NC2EvVzsp`TxWQyK6MoYn3)K{+Cv-lpuzCC2~^cq<*MqN-=(UhZhYW0c(rHc zNxv3eBwid}eMg`2!^vK^Xnt^^$N{DUT-(KHUE9Dk#VX(X1!wY(e@>r$+;a4b#azbG zh5t-j8Y~joY;kFNGl!79Kp>=MgxHGoW5ZE9CA55Y0e!-*r6V~qT)sM3B_Z87Am#I zn>#HI22H-;_<-JkkOfd2n5ITeK^d&5$T%x1UCfFKc2rT{W4mQsFr?gXJdOq<{Cqb) zC30N@XQtF+VJt%z(75_sqT&DNI`Wp>gdTf~;D+Pggcyxo^phG@YL{GiJF2dg-hz1~ z_JfmR-&l!BUZN|Gi`4o$+{5TVpFSqnPZ{2`ML|osX*P4Li>OH&Uup{dLp;ocNSfa2 zT9*l2bER(QgQ*)Z&Y1e5{5Z1gUcj>E`e5%CU^IUt@|8V^sZq=)Rei~Q%sI5=AW}x}O8J#VKXF8r zs@#t+)DaSFFR=3+6+&LwWcY=KU|&9QNL4A}f%Urj#G^WlTbG=*=vBN@rN|X3u#$IV z8NqG|AcodvOlIL1=d7EvQ+ezx2=_x63yGY3qRWY!e2Qg<)K82-B3vZ8xX@R^^c#At zNHHSdQSHYkHu#Y;SS)X-U6U)a0o~{gKe=AkCl{D%slJr*602a*-G=+GSh_YJk<9t$M!S*K(U>}}hbt+|Gs2V+i4~EXE zeVym%hum9hoh*FPP0GP#hH%ue_@}TxnwpGzqnwd1SMVMl<4zYWG~2i-l9uuCi-oSF zK$#jbKrzS00v$p9qlGv6Fc}+AjO?3oiK&+|>2-`R+<7H1^HugQ9614YbT=CZfl_qo zHY&!mZ>x<#T+1NnS~>k!%7ngfo0y8P4Tr#r6#d3Tbn~ZNmgv3t|so`Bv)(8`0O^~mGEp5RNeSi-Q8LAKAh-!ct zw&GKaA$tP)F!5~+>E+uHA+f?)SP5X(6iq!AH1)W>5W+7-UDv7eoZIU`%2f?j%x11s{XTKrUJJ{ zs1vweOT%EHw-G;OWm>1{0D~$gR|R?$M^W=!Sp7*g-=n-e7v?^Rx0jRsxqx_p+dxES z&;w&CVHRaUWZ38-6I|ed4G1XhfZ!txFaplVxs}*Nn^1-8Yme)-!4h-fl)4KFF1xu| zi)`8N5c`c}50cFA61gUYF3sl>n*lI!e1R=Dg5tbHIW#G$RV=p%89mn{LZXQP8N9Ry z9wEzBc8Ol4MH1^3y@U73V_keQMnXM6$$g>!6cUep)=icdnNm?T?p}I)Dy-f_;SiERt&VjB#ZOhgP&exhe!BH9JD?7iQfETuL4cg6A5HY z9u8T}iiZ|!E?{OSx8XNCM4=d%>sSC{=kM^7W^mPkoC}iZ^7jIu2zK(M)pURP+pn&r zTKOaJ6k8>ua7&f?sGTnXF1MLaV*`%?7NVLk6nLX_D3UbDu~Kx~w{sIiI)S z+B#}8>1JbRCWMGJlb3AkUQwKF%R@@92}RF%KR$7dO1E9xoa9&68WI~7^0Fbhnh)va z)*rd4Z>#Lerbh2del4pCg%wT``r7D+O~+Ll0V($eLwQdub8i8y`+u z3k-8(YP_Ob=yUdb@&(APM!h{QXxd)MpKWAlNj~**Z-x*STAVa)lbH@iKo9Dxj3YNT z9DwS#EEpG#z9hz3vgRq{5uGceF^1D@7hC%1o@%8pW>ZmMr87%pbqXs|j|__TA~=`! zu-_2X4E`vOYoEcPwzwX&d7(_G%c}I!jHw)8<2+kU(%t9O&lryS{@8HXI<+k7RfSY# z5Ga=l`at;&w_yOprmw;ew~$WpO8jtGDIliF7J*Bv;lwUm*;+n<9Q^7{D$n>rb!W7K zge8C>ew2X?F~BP9Dmgo$VXn|E-B?%d2EAdoAXT^GfaOysvcW25cGi)*b(sq;NQ)4i z7#&k9dI!FApSi>vJeoHQhrjsCDp(f7FZSG$1c)ie16Ve~jHtxwe4!py8%BhSd(qox zP_n)3%@ul+0AOxT;`!6RK3T%6p!7u*G#4c3-^9zL6RD@FvAnqtXs4IXD45<~c*K&X zpAh*2yH1iZ4zodFU`@2ZZT&J@+#I+uTlh(ftVg+`xhor7q_Hb4hW^RNb}+{QCf1vr zypVR2FsDy&H||DQxGmM|`{6kW15<|xym4FIXFk7u;whltOtL1NP#AGdE^!Deg$cok zsvdeNHq56cyT%oot^u3Bh2@32!*I0yVOVOH9AS$Zo%i%#X{_jDw}-il-wVH`fv%|+ zXN*K}Qn1F+|r3f)_B*0xyBdef4+yH15ZY9jtE7H z{P1?ZN(RY>$rx7=oD-4|3L_BtSb|T~=>3@g;eTG;>wmt=CWp2$`Z@|CAA?8*>7^#F z9$R>Ntv!UUz#@=!j~(n{vVmaTow)3+6m&@Gs-C*w{J#>u``R$I#_z*-^$a`k-5Zgv zOQ$ioi*;S<1OF~v*HE4S(w(F0l6LU-=(^OGV(ccl^#^rbXk1u)3gf9qYk?44g04$b zo9nm{NEN@@czv6cx&h16j(8N~5fSZb{kwEs`i4HLnN!8pC|B|R^L1UQn!vnlfc-vQ zS1$EjjMZF`F||Eg+2u0-Co8+qDzXTN#RO=!gC2yk>rzz%YAzs5<3>o_P`O2aEoSLG zmopB9g-~{p{w!seQ*v$a7TiH1q;9a`_;#j$n{LyI4HjJsXOKxdx=?TVfE1*P>n)ib zvvSGheT6scnwcZwDPEge3$39b4B0P8W6Wo{6ah_Rj3t4smq~?wvQoq(nJ%n>R}d)c zi~?o3ySbDTb~CS+#t=sI9Y83T3uSDUm{OBc+>Q@&Qe)*JH5SZmTzn5TmPT6)fo>!V zeId|DJAZFA)^L}8OAEisWG%n%rN*kaG!gP<=^{<$ze|nfKGt82r7T8jEakqh8jBV_ zSB+%@#i_AO6liYXxp)>95K<}r|DncGVQrajC5lQ4GAYyberhbW&wrR2%S1Tymq8uW zSiXt$erhb*hb55d4-lFfKgzHENsXn}F*VlZIvCY%gB9Khdh*7@UYpz>#a={Da_x7P zHdLDE7Eza>$hfIN=5X*p+8x_fjmT6Ja>B!_0)c;r>KRs{kQi}Pucd~ z?^REs`g3MIYzno*{Kv zCaad;vheu@3PCEkKhlNi(3Oz;YNwd1d(6GvNLV`J}yv0>9%V2|m->eZs*kkgif zBm(%!x*NHqBmj`3660za{nNdX9HXTXR@IX;znO&&IqDEFuDD&>9_{!ORWx&MhgK3^jH){NLkoQnfK8pvx_VNlMiIhuZX}~f)jc8 zC$VAESk*2E=038&luVO~h<_PQ`?^{|0;veH;(M z>bF$B9E_fr{Ne5wT$LltKysU@n4WXIwQ?rtt73u^(3?BfHVBDH%eE7nr>>-Gch|Qf zi5o%jY=GgIx&kYHan`DBytzO6Ju0SHV*U|2rCMIbB2%@k*+L!#!dPsQ4CRjDDfOpp zp->B_MK-9y`=0A$RrhiETBKwGPyxSj#~`MXp6VGjVKq@p*J(6JUU^q#X#B*a3z)__ z#ul2c!JHdFHlRc%%Y+9-R(N?;hlltOlcV(Tfh zq%q&yM7QkF=%03(T2nI2;(kYE#IK7h$q)a+ltT^=GLX?5M*5*?%1VI2Fm`7OG1>(x z8=_aD)fqC&ZYo%xuu`NS(i0Y+9)7|&K)uQ-u9BzEB62`}XL^_%#8bGy_!)X5)uSg` zYTpXnogO6Eda~SaeZ-2yjBr|{KPMbh6GP#$^dk5O%!;aY_j!I5Q(}giSnap&fxDxF z?3KY?vgoAJ%-i(TKm8LZ+-q2z5vM@uBV1}aA8+R2Wh5vKed_VY4U_Yrx>Lr>xP-az z!SB{KG0K>8J(MwKEz8X1esRAR>Bva*N1c35kiI-#&yaF>dUG-D`k&Vpsyy`3FUiSTWv?NXDuPN~<+Ua%)qJiC381JI z^iMglZsgRHx@_CnNRVE)V$dwN+^Hl=EUEN$Rlx>VD8QWY&XmrjVX2WwJzYYq9@;Llmbt-%zk-ZHw) zs~OPq)W7PfSoX(4en!QpO=ec$JkG5g_g+W96kM22uutY?&5RGD+*?2<*uOn>T*OA# z6VM!K=~s1?KH(3PbUVIvU<)5;?W&($ji3g|Y~Bw|>-#V+;6>2ubg*N!c{is#w)t?c z@$g-~_ubWgm5601LYGcg+~o~f8S{lfS=n^4xTGq|ng->Adx*B351MJweV9~ql!m5d z=qddaeZwEM^iDrjVGM=dyc5wDo_dX@F>yutbC!xC@he|We=Ysh^jFf8m%R55m-8y> z4?l_{p(I6gj8t`oINkF)=70)!{z%;h31-F^Btw(yY6>{JoEkYB-}=d13CD4jTcwLQ z3K)|Zr)pUGiEV|d;y=Q=nr^wb8@`TT!OjVL53j;6KYjnF&x}bnRgSsNoA-CzXnpl} ze(ReRbJmq<0K=t4vh-6mr2P#gE-Q|CGUDxumjSW30V?7@3YQxs^knWv~Gy&&qlhkl@6eqV44UH+l_c(l5X8SAi_piHpcS1b$5;CfEu2yh#|Hw@|#I@LoRjUcKH29dq29*D)7>`KFk>S)sO*nbeoEe-wy+%dCav`BHR=gvG^@22!GM$@0FHNH7&fOq?k+1Un~79!Q=>TTbr*s)%*|S zq_#8;+QY%kgXVQNr%ONOxVHJn4M3>TI8ijsOFwHZI`8eKEAukY&RmBSTvP9dBRbiO z1uKsYr{27wbe=A9Atp_`lv%piz#n}L5jRv4Jlfrkq<)qGPRli4N0AF3F$pj-9;Gp* zoN%bzf#&^h4vHGOiVPOcuB*uepo)sR&N+7=6X7?l%@iu?m>g;{$@cgyKakiM8NC|D z>_~KKE!NmBbH%7@eSiaUQg#-x+L2p)mL?i3E;CJ+i?nT2`u;&tblHyQXge z`rlHXCOQL9q_vt+2@-}}X=xb`jfIa)^KkK)1OrmXo(!^&7FRt@SCcbs+rPrkT>K?} zuwNEPu3S)CQJqi%Zw0M}NYL(FgXWxn|Sog1`9q zz_MGtUysHFL=o&$UH4RR+LRq&=OnnBZ?(R56-(?~ctP9s_OUVFmjedjJ@hpuG?WLK z3+1YDp?y{*24bm~6u)$1yx%#kcsCFYBP< zon4HUaNue{2&G-ZtXixi&*$TIJ;L-Tt z!T6ws1HZMiz8P*+$Q60hGf?_Ksiy8nOfp6MdZ2-J$8#PZz{|3&ubyX;tEIU*>o`E0 zi8OeSDH7^}^qk#gwPh_qXL`;F9W)S>A}FOHSs%6OL%2=1+^j#iR(KCBPS4qk)Ne`8 zIb}cILreYET?5h`yU*{~GdSI`uQF4$x}j=qgZIxxK1AOrYr6O;xA1IVq=hH=u5=}i zZ%yYtW$Vq0Y`uvoVMI*|{Ck$C^sgnR?&-cy0@Ugfo0VWmZWK6|9!BM2NabAw_Y%9+ z@MI6GyDRH`cXM_QQo0Hu1H&`s=zQo`oFMCzBo|J-1kwjos1)QG`ku>m{fYs~ zq0^Ezyii<#*Lj?Z4=hiN%!S`Bj}i#tqOS?O5#r-niR(Jr}b*r#&UPuq-a`e62H zm!zCRoXSDtNj_<9Kf+eDEqm?1dOSdkmA-pUr zd4cc)TK@B%&99fP;U>MA*aglA?cORPLCe8&-oE?Zf+=^Tg3@*z_!usbH4Waccf|dJ z!McHwl&@l4`$*kN4vSCGesNa2@5`ljd-Ga!Y1Eo*)p~DUlFB)!uP~u@moDt>E9&*E zUL_fuuFwH50Li?4g=Ea7r}U#ya2_Y;|L+Rgjlvzs+&`d!dB5#vJPf5w_wrm={bs}b zbXPw7s}q^~Ge=L@?G|ox^#oT>>gq|ZHhq^XC%JM;S5E25WUidz$~(I9j;@U5$~#;+ ztt+Q>qH35$VgkTe19q$PF%6ae*N9=F6?>Ht0uHXAHU;fmGqo-anA>s((}@wMbnmr~j2I zQX5&x&FMuN&kkS)m)QtRQ`q8Q>hxT}BR$$#f=7!cImAN z@g@m-b!dCPMl9}L={ZMq4R6f~^@k{wCtEzq|yn4_o5%W_rN zM{PxS>hWy`^InfDrN5DY{}k)*8cb6l4reU4qYdNmzPHi=yLGG6txFlp+lhaKZ=7D5 z54LAF@8_K7QO}ib-~u}>>4nZe`BR+LnQy{;gJ;+9cDkN34m7!lqAO3iQ3c>W$dVGzruAEd4C3YvBhk zrW~O@ahdNpIEJMq`;vPqP${-{pMTH5))ga5)#3MUXkGCImSA4P>09T|{$V+8`9I8s z-x)x*nlJZ-i@(Y15&2Oj3J)!9CliXrrPm%B1MdR{2GNVbJ?GyuD2)^=dFk+;8#vO- zQQ#i_^!%wm#QS&!FHhi4<;^YLjxT=ImRqjFm%6$$`8`Z>&uP8H@k(n7^ zd6$e3#hi>BCL;vP+EbBkeYHHp8n&{hkT7mn*M$>$3VOmXu;89Q`>OKs;nb9s^ip0v zeIO`Fx-;ftS4eH4g?FH++;;ajvdJ}SobHZDF$;;u#=}jY(0t zeU}yEt8!PMi(CRdYxne$R31tF#Oh_fH-_hLt-a+qL(!U@GJaualUFbKPzqvtAD$B z|J#epn?|O+XFk`RdI2ESy)HU#I%aC&){~!1dzmAN7t-@T*PTxt0Q7!Z1G%pvb|rW}cco(*l1;6f;oXmoZAZ(g zk{eidUYw~RN!E<|hBzu5rPQHX(5;|_@P}FH0&Zk2H9tDCQ0Q^6tYg?i?D@f-$AMmH`SEBxInnaFO>bW{koyX6OME`DHZR!B6~{_Kv4;F8HkI zbK1>T&KPz`u5W@r?z#B*PVy);&X2%3-6CwdnIYs5_q~6fOS+>NAEl4KLIw=SC!Vw? z=dB7pjtqYeBu622r*w&7^ZzrWyg2X`e4MO%^R(RA0{hW>W$;11&%R za3Xl$Pv&*Z+u#r{T}_%%FQLzLZkm$ec(6gGE0XorB?w&I6f)HywFyDBxPd}4Zu~h* zG}yEtl(;qR`NF!b+?2*m?IrguHCBd=Y-=g{iCT&$tfi=RHLygqwG{8RmZHVfQpNNb zzN(?6#nO;zU{O1m5+6*A59&GaTlceA%Fa3cPXPAWgE{yj)qU@I&*%lEi=V0I$6m(h zyU6z@9K~mO&Kcc|%T(|El-1pTXc7EAs2RPk+V-0Lnt)w13pK|b0_yat?Y>-Z_tMP! zuV-qdnYWj|tc{UR(D*jdZi*U-iIzq}oCfP!SD@Eig6{hG%WC5iN4$vU{UDbqXwF?MafdN&c*76SyY2JEp;zhW3a zg{L>n(wKqH;WN-VAWziL;&DBY=Ae5GBgO(EY6s#-aW9k*`ij1WHSvDZXeo)lucMQo zU+qv)RD1v;i10(r_H*6LD@`{t>GlEH&@Wf`s}xbJ$9H_1I4-wiq@{>h2&$`y{Z*0E z-eh7k?yKVpv)2ih&N8%r!S~TXDsPoQud&{1&-G3b`~}`HSE;G!M+X8E)A+DXiB%sk3r?y7C}RH^5t)>k0f9bBf_teM7j@NVMCO4Vg6H{t`^Lo!56vFXdCKF#tl?xtutLao$0UW87kb>NR77YV133lv_Rh z2nKcGICPkJrEQW!ahohwi)n{I^P?F0-2=HW$|f zF2}Ha?5%|}$WN6BXbdr14jRnVvP|&SgdnrIvLQG^+hSLlw8lQ=b@P_fzh zZee1xY;5_|jc|Fb&cfF`_ph`n!$u1CdciCeNYj-HA^~NkVBU>OA%RTP@2e_BZyU}i z$5i5&+E*-0>f_nq7C)@k%AQRPf-KQd8cg-{EVU_3T6$yAYx}=A_8TeA+0}%Uie_iJ z%{!`N^}JbR#m@PRvZQl5@;mCN`NXiBh+QzQFnR!6(pZ0?&dLU(2T%!1@`=ee$+&j_ zmC$pGGu;z?Pd>F<@s?c{ZVPAEp(HuGpo%HgK$yu7!+4Wx#Gh@&_{1YiEBUT|=aU~| zY%aB87jBV7%Pk0{=1Wn>8^f8Z15J0+;cWO-TbaaS>jAA|QF{1ct_F>dlV{9F5wjE9 z9#REGYn1&2rt66>op0QVhM&b(1ss^e9<&<5Ftqa)t(MGyWtcufs|sCe-om2slMV2y<`dFW4B`I@X*&C zl`!iyyyCZ>D);72xz4qb?l`e-q)yNo=q1oQq&Cd>aMmUns-Q)xGBvaQF_L3JS^S`0 z!*H^v#H>>R1UN^|pBi!2Bt&z#Nhm(p5FfO2;3lC_o8%wKCZwAk9F4X-mIMzqD`6_p zacGc&USIiDW`$?PC5hrR&*Tw3BYH^a`?_)3J0@erdnd_QcO?=`-T6`b#nab*AE{f! zFAdzzkKoV-`+c%*tKE)zTioXnRF8AL_!`jcKlq)B{$hEc31l&N2cLlB@`uc>h%2@{ z{P4<&nsKqvQK4W?nmrPJ(57K10&sk1$Yp~!gO&2c$Of8+P^7u+W`hpm1?MmylvimX zGmQODmXxp7LS_Y*Hnc_X!=~2xqQk}-MA(M{*U%&k#N`OM5-SKe7a-jxut4IV`KJ>$ z15a_%Kj;Sgu@;&wpMvjk0+ZB2vpRM*g6cDxa`UW<_}|q4UlKVh1FR_LU3|}J7Hrrj zSZjAu0`UeN;oIU?TEj1T4VW<#htDF?ekC6~N0<#G(oU2RX<2+<5gtrG5d39R%Q-<} zclxPL>(P?eHY?-m`jW}soqq5!8AAnM>(T;M)hJ7GwX!!~_8c;(@f-1u-71SV_ty-5 ze~OmhPrhMe2-$jUmNYpK`Y?T-%7)*=qiC78U>b=s!Krkx953P?CnrLEAA~*9Pr`xr zN+$WHpEwS>*SfQNCZPx(s%s$|GCrL2GDe=0UV#;GNjA09MOxN9g}2R|?y{dVFl4V_ zHa&w`ZR&^^vT;UF7O}e=wQ5|DdkdSn94y)>F;hq6pTwT;tuWGobRv>$TNPTtqyC~{ zP-(4${)u0L9vo2X`h~kI38H*J`YFFKK_rm})D`_g11*Vy*`9fx*8pp2$`eTa#afB!m#bAnHqwZXm~h0WO2XRmV}n{7*~(-e=q+*-eO-oo=fZz z&dR0sWP<&MmtN1OUT+A*xCm3t+H7hqwh=qo-!2;0jaVS%NR6o~bQ8?IC*)2oQX8xR z0R75dis->;+a9y-$$Qidm+*fF|M$=pvH4{uhB{`@(1|d7cpLo*D|@AlE^~q0ST_!< zM=2oA8YcDSc?@I?&K! zoBOXUn&|I|Z1PMtiC^2Zd$b{rsxK_`%)mwoYLEK~q70qd}Wf)JJMDymf#! zh1J3g+%4K0&ytKTf@^e6bW zv^ot?Qym7*Pj;Lgp-E!cg{*amVtW}VD3>|~%VaJXGl)U#CnjGAug&bsa7gdDGkZ{% zZnZAQ#&!Snj<~$oQeXmic9~`Bx_-t-m^{g)Vpk;|S!?^S{LWWy0?t)fx^JmMe_3TU ze;A79c9fXZdIubk!;J%STQ1C8G+=zVaH(ZKoCa7}P^X7k9e58&w)hE564^|2m$MQP zb06h8W_}P+Mo6L5G{tW`iS-)s%0QfB%nm`&((GIPs+BxH#$H=kFvg6F0*tc{GOOe6 zgRUTY0pe73 zfN6N<1sRBH-izakxHAQv;x+b=pi1Eps|75K;N+cgw;EZKCe`V#<0>!Pejx|dmj3yz zpX_eFdeo-4W-(G8Q`t=<6h#OyxnQCaZCs$*m=Dw$; zgH;^wHKf2mTg1cQPtDR=)Ibcq@if{O$R(E^!RNhV#_*t%2?BeV)Q0PETM z<;OLw8R=FEl56#m5AUXAPu4xkJ;usAYJI)xVN2_>6E7dE0z1xRH+C6aXX_HHL9g{e zkREhRvv=l`4hQ|q$9PG2-H$I34%&y>Va-JXK?|)Lu!?W`82N${oo`^$l^6*K5-M2) zdK&V-$XgT-&YU^=z#$y$U%^|Im?D1gRd!bHp=#~{ z7P*Sk+EaBTwXJGbBTm)l&G)qorzb1hIb>tL@ikNe+3vN`-`02Vk19jugO0}pVLtiF z_;50Q)DZFjm$tHD0DyVjTkz8Lf=gQ)g4d64O(#~g?!qamYiw9y{v_DU89wDJ5JeJE zL1-*t{@}Z~rhmHM$uS!$GaKTGN&6ZRrqWPQT1^#}E||TEg3jK6w2wFtxpVf!8BL&E zKVnb1FBnPBPKUs@g24K4Au5?Zq`d`$6)s1}4<35YE`>__4y>J(bk739B!gm$I#8y7p zLPC$*@7vbuB7Tzv-JmC2C*S)E*JYGhO`hxuUt_(BCy)KztY+{R_IEl|Yew~U+ zG%l!+25&iPAu}N*GvgAOHK1%fk)F2Z^5*`VA+^^*YR6%S|3kw_sMy*=g)?Cm^`PJ` zklS|&Z<0_8m}n2bQJzaIG?~{RxD;RhYXLbEHxO1wKyJ{ew=J&TRSeRGU}uEn(%M*k zg}(dB=oC^aMT~_DV(dL`C$dmM7fLxmezR6y?n>uai`bl2{n}7 zoDKHl+|$Oh94AH(0Pw+cc9Wy@&al)A#+)yNoK2wof$jSy5TB^P?bht`Bd%}goPm7L z#_~syFP1^?Re9mJ6cCaC#=?LH{A4E-;0HtjZUIz~(FZim^`!v+a36N*9tv>uXj3l* z{yk~SoqYIBO6X=t5l20+N|l1)kIjV%G-U2x)`-9ta+6g?_!Wl%31=&9Q3knrRSUOJ zvMt9+PD-A_Llp+d+~y}cJlQJzBNkQ|@G2~<5FWHxJcq$?2er=>L{H#S2_F1&zwvFe z1dQjd-kYnQqQ=yj!NG+Q z90Zyco{Zq&TYl=T8TTle005O6!NG;^0tfGb7Q7!G9Nvou?K2S`G=6Z0`M%tX3=Iwf z1|$68Fk9)So{wUfb)7(=10Q`sp#$`QLU&8tpY}Ncx^wZ!+-b*UWApAPEgN%ze;Gje z$oT`yek(x9-bLrYf!bimedf=#W1lUw83%Zt-zQ9C?KT@UW~7C4n-16VWdCiF0~eu| zZ{eNNnpIDu{q0~%d@wOSsOP{%q>~fag3JDlo+3W*W}}%dv8A#G!^-au9$0pp_v@U` zCdv=WJBnk)nf#)cgS*-P1bRX+KAwvpIhmtH~9CV0<|{*tts znok6_7^YQNxsIul_zbL4df}+_^BJbwl7jFQH`~BKm>jv+2VWq%c-d=C{_At zX`HF3*;(5&s#UiMZ(e<-0xQ~g1-pm_ai%%P_v=a zMZRPj8E@Xk;au%kqeeqI6NpJDTze0`?08@sU!{WHZea3Q-Vm^N;Udz8vxk8>uz^y6 zouXeMZ{IMGXGD}RD}&y28;Zup!}-J!L?E#sdo)_@j-^czyCkTGlN4-xpoUB^g8=VV z@r;0DKKNW^KAcpC!NYM}!1IYW<&*+skZ{vu=182jvO2tt{$**4ox5#V^fX&kIqFz? zK!SW4xLkFkT?5cZ4}yQJPDr~K7XcFV1OrBeVW!*3rj}F~xJodqwlkx$g~5C)qB^lq zuFD2XS)U1PvU~-LZpkHpFk9Fk3$~h`ZJ#c3B^~V0gi2i8TeF#1}& z_XQaqWFeDhWu9+bLowv+-)5Cb-=e9rG?q)_&3}_Cxkh?DPh^k3!rnpjSK9##zVTu1 zCLtr`uI-?RykRJH8-d%MVw=pT-tZROsFb4gM#-h9dPLI`tz4ygg3(Rx&xK=7+xL^} zY0IVR*V!Zn({QR{Q2El#OF@U@gV`@uP6%digsyS1f{q?CE#S^dL!@}i14YH+Sj-bX zE2YU&In#%1JVk^8`Q&PSLEnaxn=Z@VR1qel%wb-;j7Nn;+cDgteh%7p8(T$F5O4X$ z9lYy++xcN#4f3&bva0Ug$$9^7H!hrgB^Ob#TVfYLM^fWaJBQ5M`Ya@ooJ-fJvGJZg zm5*49B8IfnCHSRGNMWY;k79FBb>+1+lBIElAuo;%UD$Lv<8QXviDW*jORXMO7^>EH z3k#3gcLARHu+EJ4x9WN*nr-)P8Q#+?7I9fa>r`q3tM+?#?P}my@exTXz8?(7iB%&4*Klm5)%@Pv zSpeTZb%ctWTk`<4ZPzgL-%*>44JTjI&5k<&)V3V+0g-j~HHh})5XB};C2j8P?Gcx0 zaW_83b@l^$Vn4LZ*>3nkK z_{3vtkF$_|^G zqqTpT54NCy(B@{o>cIFQdV>A_Ut`EOn7w+YzY2x-?q0&9)p``^PCOE9|F&WRFyrd+ z*jc#Guy>_x(pBRJ6E$7m2;3bN(R!rjGW=@U!Wjeug*Vq)IatG9s#Osy&|3fww)LN5 zXs1@pxC=r_J4ddpoy9x*?q_DhFH&jep{wm~9s*Qg%i1hHqH7}AeyIt0*p9J9>9*cI zQMcuT1W+a!aix#MUs2;+-XC<7D(T3PDGAH^_tB`7W@#B%37kP_H)#4b)8;JktGCM#Ut_6OSOVR7+TNQ2CTl1ez2{ z41o!D-szTRQ*yAD?!Kjrm6^qT`#$tS?1K>W>02P5a)TU?*+sB8r~Dzqn~Wqw0Ic!Ca|;~oq@TH2J+ zTMTo&<;|UGn8OuY;!wqDNWLKT4b%R6i8akD?+!RBF3dL`RqyTMMS08&@{P<3?J!$| zIF6YMiiWC}U8$)^iM;tIl%>Xnb|!ZTrV;m7E6N3(S8^A`p|now3360&77<*dPZQ)Q zdJBF>Qo|bu1f%Q$;f^gd|FJGQufrXC#)o5;sT%Uh^@M{la`Sw0h2f5UG423zZ0LtO z6sDJOAo_`M#}46+S7)T+&)J7~^Z0N`^o7;-1-_k6Lfo)vLNIAJubs4uaki94g*!H3 zwn8<%Eo>|y{|Ru1hQY&{k)o^$KTNT6loX64o!`NEKCD0=?3xWTpktEpac=~7TZPAX zm})zwK@j)J{=FHr#TrtoxT%6SbXR>5YUt-xSvmG?W!U=?b3glxXViStbYEjzZ$(4v zha;8*-Q&W^pCE%^L}f7XrU1cw4y8YDv0qGP?DwI%Z|RrbVr3}|Bg*eqJRz|?QzjQ_ zN04}V!rKmFuvpoi4YnW<_5&&CrTdT_SRhGpbwFZ(P7Zub9Y_aT-0;Wbs+0~CtanK^ zu?|z@v{Q#UW!E0WK%Nkhi6yj{VbLtozk5YK$!A#Vy^&3d=o3nQh55)PR*EeHcvAis zwuPz;=4AYyW)v|>(S6~1r^;U*up+0gV|{sp-C4 zroKF}u(DwIAFf8`J20}Ovw(5e~A9xNlTruZ`T1jY-&3dZ?~ z26Pi_*Rlp+vgE>M{wrSW%WNvw=EA1S8F-=~WMu$J8jct*nh&RDL$26X9*hNzuQ?68 z+XE`qB9-?&Y8YZ-rS_`eWD*-#qgc`N0RTaMfL@z(H-D^d8lwkLu&>2HfE$hIoNdc5 z7O(xqYVQD=P^iNM<~5U$tXU+uKsN0B6Bm>-nfttqRFf1i^#bdp#9CiQ61XevFk26| z$t4pH@VF$Kw&zl-g5rdr8ubH|$t7m`-9CZ}y+dMEtX+VbQTQ|UVm#BkvNQy*H6)L+ z0ArG8OZtx!FMMhM6{&8wi2BHfxw`Hwrb3$CpJR5n+R>QtJwhTeDJhjVzl$q5ti5!0 zE{|a1GVUgcHNjoeCyd2t;&A~$OmpewI2g$^x5Hbo?NTQ2paaE-Ez3xsKE5rJUz&-mtbHMClRF{mPgLSj2E{U*?=TXarBuLW z0m*xp ztshLaiQO!SkU+iLH z2l0aF87elh@0Fqe<6%wgd!xBLpV*U6?IBtZV*zb}8yGg_+tMPjHJiZPc1t#~czjq9 zP3-$^V&^mG+r%z9OK8|NvHOXYel)R9w256AB+kTH6T7;B3a(PAe#{ofexuSeJ6q{V zXQj7^9c{sC8-cjQkvN{%|F{vSiQ9Hrpk-7K4kus2Jh4;4+kjr-!CJbLAJjBRSS@9s zHK5?dqf zv?V{e$R;;nkYzCe^{bK2ytc*Wt3r)JYt_gqMoa#lVz%C>hzz#mchd~>iuZszZ$8m( zb9%HkwK@G?tmuI13Ej4BBBrr#_w2{z8}}1mt0y3>>VZf@*b3pcovR{976ECw$htb3 z&slk%6_A#j=(gWAzE;~1D~4zTHJ@*Y=kqP+%;#2Km0Ndw%BKaD&E=ZcJN7f56OiaJ zHJp@qZLWUYeC`^rcRsgs>T1im^ZA!p@BatQ=k}F9G@nz5#{neF<(jV>6!*PtOS|NL zup}KUH5EInedjk)$`j>XdVmBGpmuRl(>-RlgverqJ;-2@#t)m;XQ&2szU6*6DOK*n zX$@U1(F57cKwaomib|-NV;9QbTu|R9f~dCawcUUzErFkK)yy}t)I-lOT)n96qgv_+ z6OwP{i?wCeBf!`0+>~bV$U!hZD7>YWkNrm4_(PS5IyHXOuwReH9npRQHfdH}I&J`#g(U6r7 zVtsE*c`8c(&RXMVz3dThz7_|$#zW^W(&p>8rNa1V>U|<+Z`37;7tSlkG2U3=oxK#H)J0 zpL||;{!!($@MQFf|ChP90gtM>7XBwp0)YWfK%%Iiu^A*9P&Ck@0m;!Bnb8TNq5?&0 zi&EQCOXCdK79=s5>Tw+FeXFg#)mz)zw_o;NwTeI$CJ7;cUqA$bChi+TkNp z2qiH8gae&29Zx?ES=j^eXD*gkuFTx`Y$8ycRs?}RFo+hHy<6YVV!+3&fOl|{{Vkym zw!03W)9d~4fhemhW218AjHUcDKaVM5^KxZHZ@SSvYv7Se_le5#6B2EW8ZNO+pW$2q zTaKHoO;yXTjn6tSC+^RneJ%;i*b^#!d!qY=xANf*@+%V@HThdBg)V8Tv_PyS>X6(f zj_wu^)~`^}D(bDhQdWC#sPf24zgmb=R(f7>+tK27<)N2}m-}PiwJnAP*6s<Xop0tLlIQ3@L5e-zo#&Rdrmc;lJ^ZTAr}d`F>8-` zf^&|$f-`mnIDA)Vjm^*J5>g3;$$J)#Jfys!=S0w&SHi`Hc_mmkIvH%i_u|%I%T8-k zrROB~luCHIxF2hivPnuzh|lWHBgn0}cq6>tn%6JiWZcd2#`~{i<17VZ@u?JtxG#LJ z8<^y=ue6y zhG0kjakE$+BF!Y1oSmkbwwfTDHKHYrsAs<_2@atrG}V3;v)^me+5v882CC&3K9&M2 zWB0hMl{d!6E`&YZ828SbXn8LaR>I4c`n^}H%@Z>#Q|ZRR-6y8??!?&Lm&u&NKLT1C z&wkE1ZiweT&m~EKnuYDYx-vfMI$>Z4R_=rdtmxcOL4_|cOE0Soe^Zsx*M4usk(d%COKxHwjH%FFk^GD{IJDooA;|qRZ{wq zZf-kqv1dMzL6auOhu^QnRcEtEa z0(XJ*w8D7kZ%_)aA(-vFM0|Kft~7OTPujtjf*+1abaPBRjkd6vl}$3TBKEe8$A^%& zY)^bzM!i#pmkW`phZk6JbCzfH5ITt=vWclX^V?KFk^vmVsgg zb9uVz*NzMo4~@W_gRFZpUT*HH>V^@Y!{MVD|3L=NinY5@qCjwEdvIu9){5UOUizZ& zMR$V>07YW(w5QP5^9rodZr1T&`EhHXR2cF!Rv6DV$!id28R2{jcid%2!Z3DT+@I~3 zsBl#W%hxQCnTuTrMt2<)B;)Ci=b}1lGUI)pu*b7y7Xv99f(xW^!U)bHAa4zX(yFC| z+CR!>8;;?`q!unc^|qYz?7+cEs#Yu~)*dUEcNI^q$_^hgevtR@T1;=%w(aM7TkiQh z?!lV${wl5uH5j!UU&h?virhgXonXk%k)4{ zb%7LDIFFjWV{8kmbxRi`<#1V(r1y##Q+_aHR31$Ik!ZPb5}o}T9YbY(mS_OAO(WaV zPU==bUu+2|^(`^GNUc(=%XqjKpQ$_f!_D2uK(QU0$3fTweZ-V(X=>6xG?JycqMLde zN{6nh`4P!W*tj(^RqztV8Mzn9mp!80(!~2VF#%mIykpm8h((<%-w@)7^eqJ zktour2@8bnAFgm;&Q{A_bF52K$E4lVA_=JT8SIrRaTZ}GmEnyE>u>5DEtDyBc>&n~J;g0^FW6LUKiMFjo{e zoAqg~C~gyT558Mrz#nj^$}!xAltKAya8n0Y=$42&A@zr3CL^|IvTz}s<}MH>qNuE{ z*TzGeaxi&CUuFwBwV@_vKsTf@526n~kQ`ZHhMOY2rlw=&X8Y=-)5Q)&YC z>Ks8YHR!N3{^QiI4nmWe)Dye(=U=f?3MWgIZqCB)74P#A&pWv#*SU4tFWkl?iamf- zgTi@PZy8omzsS}_q2a-g$imJW=E9jsz1#}r5p}=T4;8BWPOXezE0;of9l|Bep~O}i zp^adC)Ks~zR=*dF@3=tR@2E?myFSX5OQB=GE2<;efjyyC`N{o6cIrp1EELd}v_fu$ zrgpEVr|^pX9B;_K)K*M;Qqc$R=gOte_3!1nQWtN?WDXhU9}Cp(F2U`?-59b`MvqXq z1)#)H?^C!$8wFIiX>cnw8*IYvkH{p zyqEy+HNbn%DIv6s&^dF?uRZ#W@Hu?`MtvH!M=y>P9d76mK9BuydXR+r*RIYH`8LCz zO6rR|A#Z34i{Ht0iD~f_GmW!+Vw-!E*C@Civ&+4V{x=pF{X^b@K#ca%a;!J$jzmbt zgQw*sjmeMC*_omA$lq&M%OWqeJtyD4w?BSv%j*gsvAoaT80N~f@m^GY$MbgZ-6;DN z`M&M;+mau%1q&bt&B*I>Vz|6y46{qmTUs&7CTY7^w@HUKEEv=58{9~;v?HlmNy5;8Oy1CpdpL=!WOsV)5f7XJ?klY!r%v()dDLj66ZpL~;g zPh?0|>ITAZ&!i0gr`Cb>jp|M7;r(AGO}hW0oNAZr@c#4_(i*Om?WAWT&QujQq-ez? ziQFuaCs`+F8V$RgNT=;t^$b~}(o7xtvihA;sK2N5lW%ExR@zhB{e+tDwY$d{7yG;g z#>K+Wtbxip{IA;Qd5gr%BW525%7>SafqV>-j}krx@iACFhVwBv5F6+THnqKJ{q!wOO;gi^-){PF>WQWk(+@PgJ+&F`*UQFu(}|slrXzD@mUi$<)|Wv- zFvi!{gMbf>TaFpi-koX8et)7-aujqNH>R!QbH_xWAN!1pM|pil$>?v<7}F>@Jkyxo zZj>A&-RJ!O&P*TQ1UAhyjj0dLoV4`Jm|o}; z$n+tVDt7wN(egQ!gzq;|WAX}P+9oyKW+!Mt>xiBLo(Ac+<{hWclsCeya;EKXnOM_D z>{GC*TfxB)4WFLZs^j_{QomCQb^a+s^|zXkTh-JQV%aTVnYbhj2A@c_{QONwhhyDVvQEJ$;NzI&CG;`G%Tgn(7LepA| zTX+FDd*@3MyA^&qeXB8TJ%HWJuEET%TRtQZ#^Z!ha!_Ut_YS6|jgoQi&{yI5i) z1Oy2)5sj&<`5#iAGg{N%`zx|AW0Vw*CIe-HAo;tBzf+*UDdd`+c!`EdCrapm)LUQ1 z6fKb{>eKva1DtrV!xpf5iLWj8{oGlp-!?Mf-Vjh{gD%&774l)-p5Mrt zYE3}w?A5hBwuLWRB<3fMjW<=R0%Z;65@}eV6c0;S4NAz3S!Lk1-f#HU`i(a>n(eKe zW1oA0DUNy0^@(Smh5*_cK0905kj7@H4IvnVVF+_YuoyFvC*^j|5Oh0{K{(N6T)+sr*AMFzm-t3hD&)Z$Th-Ig=(3`%!+U z-vKmMp<=XMJk-ZSnSs$1iy`4#V(Auyy?X=LI}RJLlmsB{^w-mk?_C(YfbV4Gxqa zoO>o$Ao#Vx*EVp>*eL%KEk805FKOvEkT(16MW)tg`XuU29n|+ zqO$%~3=5deeWn_47of;V` zUJszxSuw$FN34)%WzZk%q4|ARzLCNtjUn)hH$^V(%J##pj*eAVRIjIrQG>~5bg zYzl`4ZPrni?v^CyPM!p!i!4@y(!<+73Rww2A8AlaThOyc<0`pE<4XT3TnP$S5$)98 z70I5JA7?Wfa44nzAqUB4@%}*Z8r%6Q*M{qpqv!y>8P>o>WJh5xE(Am7 zlF!H#P2i0pktM8iv~lhQ)=Ik2vW+9O8EZP2@mOxyjdZ+mW)@(da9oD1hQk*P26}BJ zQh%Tr-jd7>df2{f9UBnA9Mv(hxg+mO*qO$*zG%>nv|k>xe(To$K1Ns&%ZFD755q)reilUc>1)ComyY>cvta8-%vY1D*r2+o2+*{m6Q+ zs_I)z_vK&pA%#D@IUW(rv=zZ*>_)=WGnob9uUi}H_nsXoV811MfwQf5+P8q06(LLn z+ND&FS6c&{d*XP=y{hIU6Vnw~sz-(MPy?UN_1n$~dXOeJuqMbJi`T~dvHM@*Ok-Dd zC^muF%T5Y9>?lD~WUzQmkim@^An)oMXks z41|K!78>3#l%7>n0@suRvC%&z6mkP55&fIeQ{~`cw7UT=q&O#hhvHdDvzMH;?UAi5$IKrTvR1$kTlUIo*almX4V-6xx;Kw%<=(_oD@3?b43qwps!^z@WA*w9ilY+ z(Qc zQJ>5+YZ5XUOvK^nuZ2Hk>S@GGF7ZW1V>+#aDOtyK$L-$UPY)OV&gr2u-anH9?4_UP zmv87;Ol`LiEV0G=+c$`jr{Z_gSA6-j^S+V3kai8B+OJV945Ol>_9-w55RewEU(yk4 zx9LcD)a+38{G94OHiY_jDW^zB(g6T2Omj`@hRUEJVE+nt<|1x+}A z%s}+iZ1HSii}-J$Vnql{FqV8-hw#O|vy^on5-tqj?GQd~O&qHlt$EDiA-9LijbSU9Rc{ z!VJvPwM=2n7!NsYYEUDxipPk_E=_~=bCt~F^*0Y+@Dvm zP%*;8wMWmJf2PQVExXz`wS0nb{!{|zW4%zz5p1y5uwa0Y@FmiliaO@oIL-ZD`OPrb zHSw{1x^lk>03|kcH32#y4$Sf5SlbM{gTY2!M5h%0^t=-usd?TY5ON=-37Kd#INYOt zFNV`yi3Nyl!rU-}1$Kq;XZ18&elc$iTAy7X_g$8c8{N6%LgmT1SOslPx_WWn2%(N$ zTJa*G8%(_Ahm32I!T7D*T3tt$i+hQ*WCf0xcc5Z%{&bgD@IjEnL#qWxQqQ_}GGTmj zd|gL@T3>u?z}f*%ofNR{fX3&)7_cIX0@kewt8%5!!YOCW|6(9^>!LucG7-CDWh}C0 znH;cM^V?{o6-fr933R*S+!;(~%(W zmZLi;I69kHr9%t2RhXy;bV8M$gqNs<{%SjwznW%0LP0v&t&gw(&%Hd2T;P8K$kY7) z98le0|DT*7Lee?d3yzW1@;{O0{fRC>K9=(#Jp+kPOKGD?M#iU93!1rs49Jb!WPVt| z6gHE0AD8C)S=Ojh;ZKDStKGURu03b9gzEbQn*D1)th&`p8}-Po;rGSnXbFW2ET%%1 zf4L6GrpfXzibVs!ndH5j{Rv5y?nMCp0r!ro5sKgXCoa!O5wT}wTw<@vu$*rElUEFZ zHlo8Nk@~C0E~ZAX_DD`-lz>^n zNAQ+hptHA;Y(2PvguVYYzI5p4?J+1P}8&rk(Q|3z-f53qYh0s6a z@=&h2JS3N$%9hJT`7uD`0vG1&xVD(<6~xxgAM7%s&x6|9`GW`@Q#hW_a+3+)5r}bN zr}pHOId{MT+mv6qKyw3#l#5FX>gA?d-t+3G-yisqck_kM$+tDoi+hS^RS<~+KSo9Y9n!`x*S@D!ajP0OK!<*8-8tys_EcKX5k!)jAqsgLB4b$u1 zd?cUbRIsBiF@BPK@KcQ_JZ{(&b8CT64J*MVemNabl*2Q$Zp8EGG8x`FZ;*yyA5kc0 zvbRLj%`@H-VwIC*O)-D&VN*=ZUvPbVatZ#oZY@a7mL~DOE&il8pY+Uun**f>LveO? z<}KYx=3G_ZW2(NgMDp7Q{znw!M*jMO5z+mM^Z1%!uy0ZITgioHj@)AY!O1;2wA}_L zCqV>qSD$YgfnzT&jMe!-ok{gTB^rH=7bE0##XXa zdcf=o<=j({@pFsibR@Tx+SuZqN^iBx*U$yKlN<@zDE&sP zS66)xJ3b<+L4vx^gNC!q`Kjj5%3J#+)uT5%xHD!R6nDnCL7le(pqRSB>{hRU_GA{Q z9rtJVFwu?Nk|TKG+4CrG^0mwk5d-VS6BkgjxKUR|cu5A~JP_xOMj$rU>%Zb~^85Q$ z%E!)?InLtB94|5#=B)7L7P*p7$TXlxYXxtflh=UG>Q8~VDph(TN;2KkdOT*aUE6GHfkmWwD#L4*%U zGPBuFEhK7C!+8Y7z?sZ9e;ozU*nr_1>rL*Y8v(ljDRqPTmX;^~ieSRx-A@@S6MbQR zz~a@o#%5Q>xKPklvs}girhlh-hdI45nWk+t{PaEUp?m!6U3QOIs@ne{vff~Ca)3tF zDLr0tB@N7zQsL5q3##kVV?DCTb$g{^Y_FNMq@G>sFH&2l_-3e zxG1STa#r{XoQs49=px^kqwy7$B2U-erc@u+dK>=?2GpY{Pta6>c$WG(-m7J{Bp;$R zsXbgsr`;F&4JCpS{7T4(%3h6N@pVR29oeAQr4d&fQIY=vczYO8+4>9ljbXcFJmirt zH$I1w#={vJ;7p3-VCi$moO>rtod*Q25VS9%d-EF6r|XRoJw)2n7@C~DU%G86wNb^m z%hnEeCC_C|?)1kd{OUHjvM4LN+67I8RjCbEH3OsgRTuej>#=yx)q*TO^(k}7 zewn+7Bz_C){XXyPO3Tj*#FN7zu%6_99HZeKlSvqWbo`M?^4ss#MT&h){G?+tjd+=; zfHmBkY|`$frdq-C!}dBYKzdDlHsae39~kaaBi27?LLPZp|1!|Mz_&nNW>{FRj(vU+y7C_j zhGij2dcYy2d`H%)k*@GJ1F^h8G$d#}EEuJa@=9Rj;d*!Y%tv!jA=V`x=@C8ye-uPT z_GAiwPI=_{c%jZi(`04{33g%bb&n#fCLb5n$MRlNiF*Wf!$d&YrOWl_hn*zlKT|` zrtx1##G~MIgvHL2D7yj{On#hfSokUtax6it5|lA)=u;Wg{N%In0@md4dCsT=pz)GG z458~GrmsvDLq#RGv&f}#$*n3~NJZS{>luQWOKzCq%O7;ZjCuJ*ofR)vYoiZ=hKh@* zc$Gq6N5$ULRg4%%#l5pDE=qn^DvpsGm7?@ls^+L%NyX$=)qOgC*D2j=kCy z9&v4K?A1_UpTEOa+#*}Zdy3?niaSS)8)DP1F1R5!>*^vLnRy3YTRV??6yZy+jqyva z_g?Oj>#3|cjG)AFy}Y&#FzfPtao<;SPB$F`G1|-J z8XrdP?$mBXd&=s}9y8Z##>TqXG+jqCD!ViTTU|_Sb{O|2b7@eBLhcR4h=WBBLZRXn zj{1)r5+Y|0P^p%2Oq)SEZ|u z@ggu*$z%<=dBhpAHt;ab-Qs_=hrccn>7@4RrxG#8?L^#seW&!3Zrk`wz# z)-J#C+Vwf=vP`rY)s9*HV>gc|Unl5~T|Y47UR@dcE=KL%He=IraVdL$e#pH`tdyP+ zP!DR2+8Zc0{ivLkF-Zn{b!CsUV=!Yk7gWZloogDel?LO}2Agl3%TPqu&6&c*Mo=@kNxcd{xy4YQ?}94IXWK=Vab3 zKX!j_D!};vtbRQx?S^=$&=qng9vmAfjZpc5MdjtgX+JrgQRKx;J&HEMvwp6|H)tqt8~+42v@gI@(2a z?4}${INHif#mhqR@8$$C^f8R-2^n36!2kvy|H`jj7L0$Rhx!PXH&tzC;>Ufi9Q4#U zAS`dVKi^5>w21~i3qOz9L-q-HcZMwgbVKG0^u1(K7)Qbw_n#uBh~!bGLQ2TtYpDGt zV{tn1C2F>R0n(t|Op{t@C}zvwoZ{b8A*c8i_SY8{zm2!GryY}6-lH95R(C10>c1=V z@h>j(s~u$y?^5RZ|6Q3^QD$mc7D9Kw;PiN#3OPM~&;I(t9`ENiP%1)6?2G}fu^FqpinglBm}vMO7k3YF1|*u@Lg$MU{ye|=$PwNhDrR!O5fN-FJA(vbhI zq${PQr6L=|^7jAL>HAI{zQF2EUA_+cxmMUgL{sJYIg{)Na zQzg9SMD9`guig9REpYEJ!_nsB`0=rEg@QUQG<|d=IVn^O(~MS?&0vNj}o1)Ng7pxDzA? zl?WO}7HUsE_5my(Q_}mQ7-{ zNFHD-xTJ#6Ok-aH(-pn~F<{{?uF$cDSoP#GHKVZ9(hPOx`z^p)dI^e1V*WcLZtN4f4Tba4K%qKA6pc(@fH-=*Ow1r|IEC%9Y^N*}T9~|9JUe)l$PwPhM^Yu@4{zu49 zqNn+>6J4YSOs+H}-_?mms#Ps7XSc$m6xbYnfEkdZoUdj0q7*4!CoFfPR2}Ny4 zzQm44)Qwhj7Aa!tuN9Tij;X)!_^1b=ivEcPQ}=I7HWK!|uLfqe>R&Auie@4U)PbiMv#qyt%tH zNnC6<6}kU;_Gybrn?*(!vIJStuwcW?E-dfq;}jNuN;;{DE_sGZ`hY@({MAI9rVUd% z+K~6de{@0Tw?1~zIa}qEzunQfo#uB=jhN~YjME#7$}A*wModjadd7G9DxH>{p(}l9 zN18JgWw^5w_E*d^J1U#5nxktdO(CNLbBlOZRUJ=B<$>?58x(LqrE0BhfYjqp5F2||vIj8oV!dN+ z&aAPbbrP%oYVH$LJgD}_$q4ld?$P(T(vzL&OgQMYR@Gvuo>H~?sy#Buh+Zo69@E?_ zrWQ2lMzy08Eveorkz5wB6Y3uZgd4#+Y(*2&*3*_0(=aXr&1c4?6Io>PMbo>|Y4_=; zx1QH=J+D{kdA(NAbI0VqnR#VJ=h3M2-cy0*Hn4gPt*_yHCItL4^qITqbU*vw3R|@-$H`)nL7Tf#7oZPQX;cTO8zI`$#ak$ zvm$XXR*-zkE`FI5ANg(iwXO;BlVLl-f2ai2>0fkDaEnf0)cpwBkwixHc0#G|@~7MV zx!c$?;~Z$|n({T_UdBRxB0Z*N_c+;;!gN=@=5*x{w-~bOOm62pIT4xl)cdNGzx4g` z_rv)W#zKB0xz>@c#s87K-HLy*Tk&;L{62(B=b$P}URC8&_Pg9qrW!H1)V%}#Q){@Q zTMb{48se%3AK1#eKPdQ-_V+SgJ8komJx*!A;`p|Br7fR{XlrHTxZ#8d2z&(tmYwLs> zCq>K$a-43Dg(%dKEjy`7ULGfs>w$IYKi|obPIN3`;J0Eu-FjqMC zk>svEFEDvHR+howzgW}azVv)yOmhAgCSX3=yN z!)YSLh-zjfxyco|q|4XfE?;i|SP!PCi=IUFU1EsiV0b+zNJSOP|kx_=|FsdmYWX+L-!(dU)nxPcgWGaBploNcy- zFXZ5WOmhZY`)KY}*It!-Zp2W&G&fZ3y|#L6nJe5kgXx3Syq&9RP7gxgJdg*B9D7*% zlY1$WGY~P%TGtvrgC-hLzi=rRe?qeN7DX60k-(Ga=XtbJE7ra)qAe_bZ>GK}>71s& zBTZkGk{gidrX-;rZ|LLh#X=v@Fyn3hUD3xJAH$8Ah0MHR+(xgaCG*c`mpJc&;0)f9 z@;s<#V8&_=Ox_I{zh8mr%BhW}A_v~ZLRHU`9;*6JeGMqR%i$NH*iHGN*f}9Tp7+wrLVp8;4*6ZA$?pQ%QWTiM!>Clx(2PwO zdfyT>{@NhEMF(y%@6@!(Z&KzAP5HYbP9p5-p{uPO_Z?N0Z7@KT@<;qvv@&GW{B3Gh z0=Ib*`}vc5aKCwAk6>-XNVEF*1y%S@Eqwb|qDC09L4K^lvsFtA-%?*gE>vGbR%lqM zhP|#~ehqtB!-i?t3mSI0hW$>%ZqTr&HEe{2{Vxrhpka?`*u@(5Qw_UT!>ToGsD}Mm z!^Ue^Si|gg-lt*Z8g{RS4bl0&rD0#wu<06hj)vW)VPzUNNy7>??0OBmOv8K{)?dS} z)-W3{V>PUwhFzgyHeO0Jtha`puVKZy%z+w~r(tJk*aaGvuVFbF)!CsOvB#MFhj#uYS;k{TdH9m4SPky_Gs8&G_03~ zJ*QzQ4f}Tub8Fa>8n#2j9@nsp`YL=x!?tSJPc`hghSh1vhP7+h0~)qT!>TlF zyN2DXVK!dw)Ub~I~2c)3}_S~YBvhS_+rVefZ=+2c1+=Syo?NawT1?|KdUM8g6a zW{=->8fLe1tcKa`yh6k5c9v+E-Olqh%x>pk4YS*Mu7=s|9He3P_?@L;ExIiOHOwBr z0UGvh7nnVMcD^??%r4U&KfAtW4YS)~kKb2xnT;Ce)%DrqcaerI>jJaK&xZX&!-{mi z_3CSgUEgaOX7^#OhMl3y{JVzr)%o7mus$00UmBLLVXHK(r-uDi!(1BHq+!Q6DufUI zQNun}Uqk9OY_Ep>Uc)}tus1Ypvxfaf!`{=d#TxdGhW%Q@mTTCn8n#5keyL%LH0&h} zTc}|_*RU5g>~9+O7Y+Ma7ucV>~mFH0))a?_mvlLBoElVgFmhYBlV64SQC@ zey3pzH0&7-`;~_MLc@NdVNdcEKzn;c?Jwa_x*bCv(W$<#Q$562bKVPoWs&5cmA8~o zbKYD0MGzyjnGh$Sgp!1ERp>Aw(L^-o<-Ran{8|tiKuC7v&3Q$H@>S?kLcLXJETKLs zbUh)D3QZx@SA}L0>Zd|sLh|0HIqxAta(2+1_XHtss1f=PLj6_f1wsQT)4JIUudvo3;gw9o=F@y%I&~=1{ zsL*6W=c~}S2qFDsn)7B8DpGL|61q@@9wYP>75aBV#VYhCLS7YGNNA`EEhmJUkb2h< z8m2;RghWT$oVS;dXf~VkJ|~1Omr$So9PZ*Em(UszTQglB++> zd6Ni@RG~WwU9Lj22wkB(W$ic1 z5-Ax-C1=V0NRe_%D0Ai$H{W!Nt-ZL_ygg8}dnA&oX*C)B>%99(P;td!pV9wyuUrR| zV-7xE@nV~Tli~g^c-u%p;Cb&F9l(~o4m|07Q3oFLKBog5yAhD0s?~3pOFI2$dG9j% z-|d}b^qi?aYd@gz-D>ix<%je5`oo z=P_@I{59ww#z=w+-q-e z(L$gyUlsHyr-`Dw{ZK;z1I=}ytu}O-4Rz&2`nNX&tuUgsG$QpY{w$V>t_pj>PX2_G zya$EJ_zWLucF2$pUSb4gwV>q4M5rL%*t^!gzoR<5191Hgu4Nx+(-J zj6*@svZ2Rli8MZ6pu%bt^a#gpf`AWfXn{b5{V3>W8@kknD)a~=Qqb3J=yM7x7$>iK zj3|iz4;%WBo!2GU5H_XqR@>0Kfi9xmuCi6e?|5;F%Qq}vnAR#&A-ae>UMEk;&NI>} zu_8QTu`oGR;-xlp08n0`Mh0{gYZqwY7U9TH(bJ8SKasN*3o}%C4`P;Eu&{x#q+%fe zDwcVzz%4fTH4QG%U}2jI{E7{JT7!kRlUsPH0zYMge`JI82nf4W;5jyUngh<2+`>Z@ z_;wpy?tooF-oly`c#I7m3|OW>weh>d^@26w3M$1}c8X*4N?x{-qP@{3A>mgl(SZXR z0oVZp0rf@1Q^q(4yv_!5$5g=88Y~=8<^H=3W~CIc@DOqfn^oW^ZSVs&SQDu5R0WRM z;HeH+_3$bOe47ovsso%);pGnaYc}}24sZcr(E_Q$2if4ynex&!mrIZ{-T@!oZ_j@P zPVf*}S}sgp<=$+AmpWiIHtJkQNc@_@$lZC!|p%op00~ zBizaTB6bRSt40AiYs3aq?be>PM|&F4ce^CL-cEX{Q&>TG@?s%JRn>4CS^!k~s@a6B zaSGhe26JCQfk7Az9qEAg?$fAP2e@PIi7=ruud$)8sLahp#FJTM0|kD`20x`U(59M;D|W|j^I<^h(ZO9a8%%kO9hSqML8l?aZykSUEkn6mO8xo`qXJ0 zl#lyrj7wY3E|(MG#^kHbJ2I@x{F8TH7plAOVO|rDz)1v0MFqG$L0Xz=e53>?ZUQQq z=PD^ao|pdzQ6O^T(cr|~=_E4L{|nvB`}*^CJ+q9cTxU&15icFFT;y*I;)vBSA1;x@<1w-& z+S`VaY7+8MAbR)Na-VMh4uEfexukZk4;nEUc&5A~)3|Gg=#)JlC^&!>#M#nLXv?n#Ue~zQ?Rp0Fp zPS*Y*_1fKCzyJ6WlSS)?Rr<5%cm002EBrQ0v;FefK_bEN4C=eT1E;Z^U@=an5?Ivb z;4-z4*85_;eb&mMq;!pwKQ<^PAc;p-8Yh43_!-2Tn8E|qSf!F58*r6mc(k|gk(J&B zV;9(wg_62@>jJa-=z{Q`!#VQeM=IXKkY)*$p)uRUhbT)Y!Uzx(YS6<{w z|A*b)*SfX$_F-My*L<=|`%<64gR|TJ$FA_MW$#Psfyc^5B!})igPb6o;D}HCm%e`vYL{25yV?&$bBLh5B2I1 z(8lA8+If_PGhAuX$Y4!V27GZxb_qgd$lA5o1rn0?K+y`GJWtA-u||Dh_B6zi7;f&! zq7#noNOZiqq8D6!=e?`fnsuD2$BDrpjqtVp;}9TuVC$cLGt_NxtSJNe+3v z%iW9Q5C^hUHXNLu$9YW1S#%!p>DRN%I0WIOf0>;168BxZ;$9&Vt8Gd35Pp|^f@$|Y z*$VzsgPE#bW8@rk}IcCjqZHnw^7BSmcqlci++FZKE zi0+^me6<;M9^ne^Pq+?V{t3_6IfbosCwa?*jpIF+bBP-3gX05hckx~WvwFe$kH=$o z4pP>3=eUDizt>%}Q}nsc%crl@oK&B=Wv%J6mdMnA93y#4L=G-%Ek9^H*+|rj*&t4 zo{;A=9&uFK<~FmQuwXvt@vHLW_|~Y)<=3(5ri|~JnKzMY!d6RrtC&Q-0H3MiJ9VqI zNz7l0z2IQWZuyf8dD_w;qwW>DQ**2urA@2SzLP@~iDottHJhP=y;njs8OymlI5#2;c zD0Z#H#PTY2OK6R4{7=(e*e~3#499 z(oAiS&>>;Qv4d??diGXYKj@B4$J8d)$T0;P{Tm|)xiF@`moddt=dbmc{;0ExgrY7@ zuns0pbYS8{7fkf{a(%Ng@#(xTg$ZX&i*1_4m#H}QJuS^T!@Bs!|L?;(`pY%X?#!?+ zmm0PPLxTUL>bU7FEDM|Nb+gsf&hyY}ym!Zj?3&my!g_M2TDe25mWkiO8v_3j4k32F zL!NZ|W*>I-jJi>j=kU+3zyL8(uKA~O9Sv99C;XGe<4CGENyC*k`y4GSGKD>AZ0&cj zPwah{wFaUY3*RRD6#Im+uN3Fio;OqS?iR0-nuFqPatYsJncvzcz9wJbD}*Hl&pxAW zxa!xCGP=Wc)7Xdsx?l8Zsvq*jd}wMME3b^Dr;YvWBGs*GdKj&jSHpQZ9f)uYGRlIC z71zs7!z#q(X;H|tPtBEOm1?d$$4{5J67*~dTHokCFZ8+`WiJCt_f>juGn!N*vw;{M z|3va>V~|I~Vsbz7wV*XV#6pwZTqF8(lG5af)L4n@7G0~|>>yrQ(vi*#!FHJNnn3$n zsOK`VG+m#(%xA6jtPEpLwVy{f8cUpZcC)-8++Qq|vIpRP@I>L2>5Bs8)4c_A3nP7b z*;;i5Vnfx|bdRbJWtGS39v1Jemvmo*E&3qM?9OiK83+K7JsiPkLu4|2s|q>T?C2LI z7)y3B9H$foqKaf#g>zj_MmX1ij{G*~>R!8Ni^B6M5-Mi&Dfsj&Y0Y6i(OQ6 zLJMyfvX^uOxj9HL*51-XMsxxfeRn#_N2gn_Y>1Xv2YLl|Dd&%6?FWn+OKjm^twunRR)k=&#!KV(dJ(`QV0AHP#u z{qD_X`v=#?rx#y+HnAgViIHPVdscTMF)2aDa0krUe0L~-_iIT!4x63WhR)HPI z0&Q6)80dN{ARD}90(A@NQO%5WsKexBzGO7*NI|a!hN{dx=cnXjj1lYvm${myIhhZ zPO7CqMhd}_hlrcvbBl}#YmEsf86O6x^_uv+3oc0KE&Cx!%J&(e6SbL&`K8uzyj8S1 z<0PYWR4@e|HmK3sE33ygEMTXv#Ctcz*JgeQX1V*jM$+K~Ly6+}yui=8kOkvw@as4T zU=Nxo-3PA1^Xw(L@T`EafPQE5gKY?9Z5T(w9R`PMwkwIa7kTELpT4fJXO z5jRAz_OCAAr1Y209t0`3RY|$)OockEAUBxB>pJ!%nz({&q&#nb0da{LdX_%VdqGbl zf)>``^b6t#Ck%5b6B6*PX@sp0yR0Lrz9fT&b^lX_%pu6mI?jT)0U;{$w)#;;HyU*- z;Slh_izz7c4khLj=vv+=k-(sXT{4y(1dd~p_AP9TvWa_}B5r$Q1aa>c3U@X}&yn3G z?klVV_*=0zMxDg{u@Lvi0%K#;pf*NOHyfjMdSj$$nT-*y=_Tblr!k!DKE-}wyJ9hI zxOs!vVLJGg?;!KW(~>!EmV%{6#Di98eX2j*thBaiAt?Q8un+1xB%t2cfu9xNC+Y8w zpU>FECl*EX0lKH=CtuZnCy-L9}nN;buU(NnNVTc=W!&Ah5JnXaObZKP1T(rp-|`+_GR z+0sV9mNs&A^E+D~6kD=d+Bl^wk^O``MA~S)Rt@R%{B)UP-KuvsxCjl4LAm^^##;*Z z|LM65Q~-v<%6z(JpQbnJy+t5)U4EeK8fj+R`1|uxFfLb0t|Fi&7Tx}ztl_TeD>L@d z!X;R)=+w@?z}=Qi;ffd0YJVX5DoOu9m-JVm0P9RI=bxFvUv#9G^OWxOi(Hhdr(~vGDDXb5Tdg z>Qp2)`-{v@oBfeq%5X!v#5Ua@$t^paKF?=uFFRZ#=iAlw>B5>u7ukK~jpDS3errA2 zZ$jP!x2OIfedA-Q=1;N#3)A2&oo5N$ncgHlRx6+s&*|(Io@QTm1}P) zZZYe37Wmu;{GOfG+17+yABqv5_3ge;@R%&+i0IT7qDz!_I6vaotZ5bj&&<3ddwIDG zU~OpM!cZ2}9xIw(>9<;Z);lo<*=*U~veQ~?;hxx9VYcj&I2FOD`>c~@OUj8cMI!Qf z26}y-6+TZ0X9q3&Qs+^!QMaB!6m8wt{nnd4YlB^`wYFui1bv<@X3I7XQx!2hetc!LV8JMplFI-_U9GC+uK7W~g(Cr{^<8S&>c@YB zb`mN*O;B<{g>*)8?`#lX(wpx+J zyO}C$qi7IYcA?%)4c1)Nd!S3fec4`eb3A(0utuam?mW{CSGvw~17af0U~g<1OPyGhXE+ zLMoh2=FymU#9#)Ao4(LU`Z@gk{g>|k{=6~^kt^rn2T<~ zn%jMz+F9NILRK5m3oa6DnC^Fco~{3kBPf1G2N#W13b3Nn={4zXjaF>lES>Gchp1@% zsA#of)9Gs2cmCzB4*D0e`mB`CYJfp|-uJw1de(a0G(GEZhKJ$o!u{n!S^d`X17)H1 zR6eTci8I$AkQ8IrCrc?BD){tO!49`8g)6vxB3$cytS}nDvb}rl2ik7sjS)Gga-j+R1ge=*f!Cub_ z564et%bwKtD3NASm8{njIjgj`oVwz*Y>&38g@qpaJgrt^%XXI8JsvDu>Y{h>DMcrJ zR#KMeJ*fez;OAK$YLDGD{~FV3>}Y7#3f;29leSl^J-TcbEmb(BQH*C}%N`Kf1Wt^) zItsJb=5jv`Jr$~uZn9$ ztJ5eW=u^ES5%pFA5)`McCORhFD%XiUX?t-cPL&R*2$0X(>)G%5%yY=7drvKVqi_0} zXt+bM(IW}Sh#$m5m^0R1cCNB?`900Z6HF>Z3R%v=W;++}T-6-e!s7A@byl*g%^Fk^ zySXoKSPNJ^aD_-RYeIL91PMik`4|un4NMEC%vv{j8M6)jrSiQ_HaB z^k_BYK~a7W9-a31Jx3|f?>PojHa+iZw^)Am&4tpMEXE+#r_zOf+!9?!7iFQdF0g)( zOLT$LJ0rTAF@=ej(I%B*LSN0qJ34w}U)g%3mXi*;Eb$?j6tu53+gob3O2zB>AH`idk|PO5Mb=DJE;ktwmBvDz(^Imd?nZVm;XS#HQuTNcFN;|9?JWU66Fjci82m840VS0Eard<F6VrO%S9;ut{u`4}HavUT zDwOYy%=MS=ihR#szBTdeLIz)9<^jafkhoE`O&|*tE);r*7vN~^s{nf zv(Czo%{!~FX`NwOcjlVbefg&K;3?Cu{H>~f>F@Z<*H`sSf2;hn`|tEw8@cjPn(&vt zWtKM@zpT%!_PJNFK|&SlFaKa}ZzSQq1hN!m{?he6H@lQIIHLBKH#td~oO>KS%34c5 zb8l&HP0wIUi@x0~ZKRI!MEsTv75Lp-{nqxHc0r@Bbd$e)lT*T`tV+!G5B=_4ek9^d`b=EieUV_)!EOFy45(eUmRf`3xNOuJaj{ES$_{@c~yfe=G-G+q+b^WHVT2$+hOHmIy}8bMK}2YUgn>2vjN#BXg3dsI?Y zLarr_*-F>dZ!2(b_8d2@o_=Vi1N_^k55+Ju+iKx$Mr-n;ei_X3N%&s@Q0o z)(b68i&Qx>F+GM=3N@m!sGcHK?G~bZZ9kYDB z&j>NccMFfGJ)ww-*|VYrL4K>utdv4I>|&E?ZB{dj80cuLqN9`!TFX6q%@(#lDVcSs zKQ^154^j^RML=uJv6L-SG8N|< zb-&O>-6hjFWl@r}LzQGV11d@Df|$WFH@Bm{U}~1@scF<*r%U+Z{2@|;;wQQQX1|)t zo;1n(mL=Yhd56F+b9cR5KdX_>h~f{~VZjJl5Jy+@BVLV*5KMB!v$5?V7+Hdw;_7Is zrx;902OLkw~7sEuWr&JuG;aG*APBbR&gqBtD#k#V6 zZSf{yBI`ZJOzZrA!bDV8e3tN}R4unQpjLR2LP+X0(ZcpY#NV@zIc}*_C>Z9WS7$a1u4og@>rwn2G{|$N4Q3d~4w$Fpw&u;AcW$ zo8a46)rU)R`z4olnwfWLD9(t6Y$+94XDS1t+WR`YEty4MXU*61%54AW3pgrE!8Xk} zT7+3xC^4;F(4vY{G2Hx;nB5&Q?3PIBWB26q?DBc;_U5yk;W z)u+P0wliNHJr*iC)NLr|gr4E3yZxRIOiR^dwtTFjq$;-ArnQG^*;{CiI#bu9I4Tp$ z?m?G&KK6UI+x0Np+0IZEn>wc|DYpy}o>{eXb%ld zcj*KrQyTlJmNdtLaMV3EM8AFLX8A^kv2M&_tgt98 zxcn<3ODAJhOKRz7)@P-u)N@dV(B*d8D|ETX^fb|G+L)S#=!s;8oFv@Q5?qU$SRvI` zhDed>at23rGbR2mp$gA>)AOF`X))@~W;sG=o^`R%WwUHu__~fS=u&Rr$vm1PiXhKH zr2^O=4#@++YNU1XrahLFVh5r`Pd!Iu_r-q9xy!qf%rBC}L?nsZ^8Keunc|t)^w6E% zutX)rZ!1w!d?P>hbhewJ@y<tYgsIrG)Jc!17QIH=#0PFtd}3b)fwB`Ekkx9RNb~7|>_)Hg3qzYpU+zPI zC)UOU{>C9e@OCMUM)onS>$+_M{jmr8rsN@p1$o6k=B93goFr6n`zW-vA`&Z6?+1ozoDgrgWid3 zL1_4^Y!mYp;oVM^jTd!CkXbYFwEM(Xp)iMdMT<~PRtD>v9VIw~e(FBaY7n2(uIeay zvz~^3jYG*$S$FD^R(ET1xAJU*UJSUlch_Z)`2fC^IW7YBGIOu+PIbcfa1YifU;HP$wz4A*GY`sF2?_O=+_sl@ zIu&*_iS~!iY}<4tWRDZ^sEt^?_;<* zG}${z-Ix)#EEU`(;cf>G(G4ylUXC*!0~hIX5lEL$inL!|9wM_)%*g+?m;!kRK`{m0 zi?QDu)XFnp?n4-L7r-fk>p)g@MH(;ro2&z6k8X2)a(sHY zbJBF7*i^;OyE!&_N_G(0@xNzFhRJvM&r`j)-JKD*0xe>#oZ+AaRcIl zf*M2!mrEgv5cYik|1-}yIrrv<5Z?D|zweFr_q+4VGiPR=ng7h0<(cIGoq=cBFS9Nq zcX!B;s~gzsOu{aL{du^Fh}-UE&tb3rXvF&Cv=?$9J1rw}Q1L#S_w{oo zNX-c4W3j~V0FxqXR)H+*(QZOLx?Ma3>=IHJn3pm5kC z33pOsZDmHUr{cp27p-kw&y9rKS$H)ja3(3-cZGI%0(M+s^izi&h1?Q_-G*}VBb=LD zhaGz?Kh*5&_=do5_(rQ@J*wTj17$Ghp65-*V;Pc53FB5v3w={S|J9~MQZ>{m6bzDL+)s7!^G9Y=A@r{O9wGT5KgAXU!$O0jqAo*Zh;|=Aq z;GTzpA5Q?F4Y1}9(gOBk<*GOA6}YFQ3W+quU%&)t@qZt#D1P2hja3os41<^zx!mM* z5p_beDCmH* zf>&b14}bO!mTw{!Ti19k>=?#SZb?BUvV-c&PBJ)53h!o+h+&wA-{r%5H+Zd|?_CJ* z-9~I4JK}pM-37`EuO<5mr$fQO10OttWXL-Wg8aeWpPzAV9FB{kj^GRk))^oi!v+tw zHNe}mR2F2u#NDFUdzu?)D#6!*@Gj^MXyyTXdbei2kOCX}I&SLCO<$R5<*XZPWxtPI zqr1i?hBI3~%&E${WLReT-i*0tVb%$4MC*DUNYVEUJdRjlzoeuzJPbUKMm2uS5b)18 zV+bT*(^%G9*lCKKjc8jE`T(;{X(L}?dyRGrxjG-&!7K1JkeR(-;F~dO53>dgr^!V8 z`UEorPk+^9lsj&`flFgFzamD|B{l+h2hc0~0&56E9bR&u^m+=zj?5Pc1Nt<;us%0^ z%~&g^4lryQYrWJmHW7*xz~Cng`vitJpe}61`2pDk%T1Tyk!K#!L8+w>hE-64V>c{A zV7Cfkpag6s%c^hvkcmlaTON7``@T@2SmCXT0Z0rB9wl8e0p;r9e&2KbSmh`TC;0;> zvw13XZxO7s=GQVx?595+6#_RwV^IN!p+e|D*yG1}gU}=52}2%xXCA_|uJ*OA;eq0_ z*6_>$cMS&Wu*S}1l%+$Z9=9)};97BP7p$Fm4MtKJ31K4~jvaV&F-X3A=1J{UG&lXN z=_7K}Kc2oW+&dS8XZv6T#)J&yn_q_yVIl^G?(Yls;b;tYY$ps|;5R3}+&z%}rd^J@ zaUqgqr#@m|A?mw#1$I0kOXlQ(I|kP)y7e@vTy-F^U(t`eNBxR&e_hP+=(EzIay;sc zOkFz)Uoub8ov$?`QgkiL&4?5`<RRJh|!~k>2)ydqm34hua{}WUcqk@ZoxUjzlrGtlM!Rww7~@n!z+p!1c%& znaJ1^Eeg9EGeR{bZ;woqKjUx|BT+t(TzmE9R9A3MDdYUl%Z@}e~E1w5xCkKy)AvW4oGp{14Hw+WgL(q?--i0 zhn4{;NT&l*FAgJPpf3YbLME};1JWfFS}4uX1#Ap3sdB#$W>k9H@M(b^?WcrYL(()& zI|d}If3kITAly)otcsrjpzr{2$c$BS54u8USb7`Y(Ah(rH%o^&8rdvYWcDf0Z#$emEIo7}wC5^_y#Kc3* zTQQ;1;2cMv%>G3Nrshjy;Jk<_dR#gbBR14=8JE6t600^6pv|EcT4*l@dRUb}Aj>6rHK&i->6jJ`XqtcsPqf&m^$L=e?Ua?k2r29^khHEWI?CvgO^ig+r(p{jG&{wms zh#Zk}jE}cJVB~!p#2Jy=I#CQr6Y$2G0jV4^<9II+#)xo(IVZ$X7(RrI@#s39Udntv z1rC_x`LS}I(};1{8VpCb$sw~3##CLGI*iM{DS^ho8Xb#nHgi6l*uqeBs~L(8<(bvZ z-p0-F9B6cpL$|k&L!0e!DDv>v6R<=g!_na2=U|s59W#Qrp5J&iaYSP~%^JN6^D7+Y zr_$FP=uh7vV>2@<#m-f<lD7tOf5786(*nEEj+#0zdtClU@|u^Am( ziW#3fWAhdro9`H#xCu-77@MExjLnyGZ2qAa-<`+4D4bw}_P-8;Qg8AyXHW{wml>3D zY`(n1pcKW6L209VPWvtbe#aSr_-yi_u6h>JYj za>PNXzLB>waBy%2NbEOq^4E^~jkGTUbKSqhGa}a&xX+X<$8}@vXGFZXKdf!=^gDT` zBx?LRZ#%noAHH+=68!L2>U+^xFlP=|PnV3RMH1AXe&Tz)MQU;e2WUdHgF zmQy9@$DkGM_#N#d*Y=aOV{ty+XjPZ_&N}D|Uf>O0WZ!ME;5_s=SyeYepK7imS#TO0 zv|qq*Co6S{J%HVrmRa?)Ls#Qz`U-P`#EavxXXDGda6e4M=rv7(t)@mh3UbV zmt&@(@MK1w+b+aYXg6I?y#ZX?(u~n3o+a-WB`BJ7?VHl~&Q9k0GKs*1aX1@&mCWM2 ztsELa#3T;mCh*qhN$T4_#22w3mSe$5 z_~x;3u+jR;^Ig(Jk?ww3<$Witlg#;23x z5taxrN_;0f5`kSnAh{LiRgZ))Y(a%sjq~F8e#>>tIv}&B z4T&fbnKp3g!}{AVhc5(0XR`1(dEEmb!M}(j-+JjaRE<4CFN5ie;B&4G57V19PR5xt zY{fVCXxdB{-FmEYeVwVP*_31Ki+X^$in55H- zNz`|vnqo8TTIk2A@rK^J_AI09_MU~;8NtH8)S{e&`ebVz5BQVc%nc;OmS*Q%^BUM$ zw=)roc2LRVgd1mdPRlr})sC0^dn!fy``RKh)HVsHU!MS5serf|c|0_?Vsyb{m^f*CZUyz>0=h zj>XG?^m-n!ehfu8??4&Mxo2X2DuJcA{DBo3gAV>%!$~sI$4CT?!+InQZO0z0^#psL zl+5l|UQwh_`x?bAbOXl4W^`}O|B~dc_m=)rQ+I+$FuQkRO+avH6i0+w5v)DVP%>CM zbCNzYmj5g?4XuU^diG`A0Ugm{n1~c%@P3HVM@#`GS@UmWYN-)`db$vHs;4)=W9aLA zz|c#fNGSHj8+q!EDHl~OA?1!4Is+xVny#3~Y-T{C-f9)L?^Uf-cTku1f z)_t7jOZi=y0R*XMu*#x1Vq|z@flNqn6ViNJn@cSKHKI1#<4WkPVT@YB3{2q0|r#JPH_7~MlRmvmMSC)97 z3-NI}k*TV#J>59U!RONtxxFlFC1h#~z}R zNqevWCPMFpGzgv2snAQhCDe>^gS{^`(I%0wDQR!cp(>G4uxTC8zs;{kD&_8%XU%jJ z`xADTBzgmfI6IeDNb-?YpZQV>yqZ;_PyD#zCFcW7M7ML1C^Knpa+c;|HX=Jdn9xisYqbw6S(z`VfTQ{+eLEI%HsF643pqVvcJwFW5Xa6JpYbkEJsSjP(U(!kBU|3hXADPVEmVq+6D2=L9}zZVfR zxy!Jt413zzYC}`;IS5H$=z6jBzBdubSDilWLR6XH;2LrmQ{G|9VR8b7kyr-Y+{=^# zF8)cyXf_qKzrQaKtKwseS~9+@afJOa|8LCSa?!R$%-^nrLwkeJ>HKXt&T9N`p1&ny z4E)9X?f=>NTYoehGJ0Ht7uz0jp?g``b`D?PRUk(*f14D>4Pi37!A4K2KVdfY--)^7H@k1KUBGHe5>RpG=v9(`Ov$>zM9NLj%glIpoMIY|%le!u7 zB@0Hisofc3womCioGtwSHl-VL=$y`{bUB#s*i*WbBzL_}fPYlpp?0wLF+ls2E{tHV zDIJ%6x}4I@_;PnZm)DAOIZVp-a#D6QQ@VHIv3*L%xg0`2&(O}4u8~u^T`;1ibiGhH z{y&-0;Z-O;aE`ftTqaHS67k1Z2aO7eMP`i-;ZhE6g2B{Iu0>17-D8}PbLR^t2Hlw3 zB|+R#&Fv<--a`9Eh_5+Qyo=4-H+n?3DuPb%F78&S|D6-O-l(Kzf|u9D1P_y;Em&0H zMtHo-llHL*=xkzVZVKzx#I7$QL?!DuvCDK#?5^g-E-iXuH_Sb;lj$6idi9L|=7et6 zUNl;*?lG8I{EX(6!*^v`#mMR455I(a4xc%(KR)_|sac#ivHojq zON#Sd3Yu|8& zZS51j#J2Vhf7!P73JWnwF&Rbr~FMlDNAhot}8%|Zu=O*pwC%BPsyY(W!^59Ed?XU8CS^%MER@T;gCgD>@ z9_*X8Jg7@BrC#CNXQ*TR_!&&8d-(hr>LI>eR)$o-f?BHUR!htky4K4ldjtC*XF`#6 z`&y)aU6EC|cGMm*!B1NYluO<(%Cg?YB|PhAj>O(`T;;_{0WJ$IulM-UKP$O@*J!JF zD9WkbW68Tro;USP2t^9LI0%0%i8K+Ldeej~jKwD3s=;pz>!j)&VAWagRGkB?I_sUP zbAVN6y;F4#ub9AMR1Z>r7#R-N^x>KtIzS#PS&0al&$rs^DE)md+< z&H+}P^``0^VAWY~s?Gsco%N>b9AMR1Z>r7#R-N^x>bxfqTJJWpLcGA4MO&TqGOi7^ z=6@4h=rI_0ks5NRt_ppI5qgomErBl}+NZ|=5gI47Fms6cJFwVAuPxGWR2ei#DKN35 z4bv};6IRR_rjY*Gz+hDz9}mLr*0QVPaOZNZH*nSCU&RNd<}Ia&CA^-w1(g|19~wZr z8Ou2%Ml*)Y;k_s%85q8vlrzk@O3Hl_V*A0ZCtZ=kN-jNv?PJ zRFYod6G#%n@>(W@<&8(VN3=d`ad0!L^=XJ`eV#bIlPdJTto2!h;^IZWPV2LVFD+W1 zt@2J?1=^_48W>~ozO#Qhf$FK?RZpd%%Ahxx{~6Rj__|+x z*8kYs&Wn~^`{{gvwa>R5K71#xpvp{a#06woquvh=@|M^2!s=dJeEhtU^LWy)1#M1i zeOwz=l^+>97;{hy?zorPs#pz@893foUf;{xT4#YP`BE2guMYp#j9!b;mz1o;2zCt` zi!;%;l_nq!9>j$K8;7@U4<#RAc-B_Gr`{^b-cz4cG7z7xfNy-VW;(_@@4$&e&Ew%U(^@RC zaWCHEahR1^6$jXQ0zqGSE&g?ft%?v_5NEHFn-FI&>#kpce;$Duah8dB$XHx?J^xia zz>4_XxgxFY_fk{b|zl6BWr;GajA*&+V# z;eo_oK#LuJ9vF@PYFMM<-)mKjgeyC_ow%|L-yi$94b?WY_5I9w_59{?X5F@4CD}64 zLir6s*{#OEjuWj*+W0QaABgZ^Yq^Ab8th1Q3#6dp)_Pbz_x6EfCi3&Ve?i^6&yesk zme$!QEdzS}OdL2XDR7Fb#2-$|OsyYPpLzX~J$05rk)$Irih@@wi`ky%hG$}%CO8Pm@OXPm~OzbhjScPf> ze0v1%7+ysv05EmHyNft+b@oX7qtKzRkTnuFW}sx z1&;Wdp}^Z9jhuXf$UA>k=?+R@6CK`z z(p{Z9b#15_9XW8o12m%jr4hC5lhBA&AcaPOg8oMCL1+NnEEz0v$^4upv&tkJuuBEP z?K|AO@fLluP$J7jN607>Z{iwkX7g#8jL59)kDbLR2~#ZJV(_+l5z6n&sK1%(eC2!5 zVBHHRBD0lSA@*hlrBFD9qOy}&bPx%F3|AsRMe_iSl_PL~D z{;{(b6K$g)#Eu};9`v`;U)RC?Hqi*)JbW6CG+TpyIlK&sgykXqNIfR#m`Xuom_m)A zH3%ORU<=QWqj}4huqrx{p~z4bYuOZ~F7qa?^Ww~B;G?Z^n4e)s_sm?&gTS2dsNM)l z08G(1QL}}4Z1K<@O_P}#Cv!+MOrtvD^#7YTPMM6DS9k+EaD-^Pa-fw*bWpMgsGZU^~@(SL7xR+0bA)lLVK)1W~lCc<^a-72U8!vl? zJ-#gZid|Aiw%NWIJ~JP4Eq_(-JDShIQH|x$7T*b*zv{SQ_yV|h-u^O(o_m5Ho2wG> zZTMaI_*8D{fHj$I8{y?31_rr-&+wTZybBq=@{g}B8R|=23(r3BoSXQ5p7ETU_?a*9 zGen1P48&RY9ERyj_gLll0zurjKRxU%?qd!4X<T-(EAvJF<^BWyixU!*(TT$Z~qI6lmg>4q}CATk>LzsKEO%JBhjAgZSH_J+&ZF7#|~)I@#xT|&kktQu>;z4 z?0_~MBhj}0wl}mG*k)A@9J_E}h@TZL$_fs|Tw`G9UKf*9IX+?R!tn{AAHoqH`22Rq zIyQLCLEMymFmxlF{K0{_csjwc<_539`Odt(p{wAuY_F%!(z-ha^$A_z=HTQR)3R*u zpq!S_NqlgS-sZqtlAD8*XH3(wgM)IKLOU_%v|p(Ge!LmwTWalB>m6Js9?ttMA81A4`yBY3~;Q%zb!-fOGFHZ(l z<<9S+G)v3*3o5SxKDgGi=tRx$7u1w{Ps5>5%l`{%%D<=KaJ!cO7u1x0Ps3r3mj4&j zlz&gdp;F8L3u?;0r{VB3E&ng5DgT~^!|5lOe2-8%L}{|pJ;$5p;ZEo}b$|UB>GK-y zFaII>pvs-!L+Ndr?;F3MQqg-F4w;i9_X|~b^T+i!U*G`N+>U>Zhj8}#o{!g`-+Jba zT%wR635>g?sX0l1dlpSaeWdht7LTi~Mv`nTM`I$Ups#b&I-HC>I% zzEW4iS8n3!aj6$CZ`+cKg;IOqa;C;BpsrpBcdchlq86fq&-S3@`Qgh zc42bpDy*+zX(u^!v0BD1ye1)ZE*LrvGjwcV+`-TZu;;=p*-)Hh+#71ciZ_>T5<|Of z8`;q7ruQp^~$2Ga>j z{s6Xte0((`;RQe@5@zf9Q~o^-hrL?S&`>wecXRo}oEN>$i|;8_4c_|{PaXA+|A#Duc<1el zgHm<&={T5hHxByYAjGP#;n0z@OTUbOIX|GP|y!6Img$!-dDaP#g~e&R~*bu z+=T0*@huV@YIu)fi>iHz2YiXUG;ZsjTnt}wgE+E2W*#lBG4z#M z(z&Gznn1ntRxq#LdCLt686p5!<#%8mBlJ5w$1yQqdjA=xxz2m-`hDn!(A7KV<*gz2 za?u7P!;msVYC(|T?&ifiPm;3iP&2aB%q%rCOU=wuvu3GTv(&6vYBpJ_dPOpU16Y!? zeQ_8mSXDP6FFd!yiz%25oHNN=b0^?=)Ff+RUP35c18Vu; z)Cql`ZHG5}R&dgz!iXZ-W<6w@QpEJBaIBst){O=9%vk!U!Kp6@~ zPNv{wPv6iIdEoFku`;@aYb;sATS9-5XX4+RxQ`Vtu*qBA+~iIC6!p)a`jIbn7b+^x zWwqDh3P#T(EqA8?lVt}-E-=({cZTwYdhRY%-cV0=89e8}@MPD}2E&tGOB)PNb`xz) z5O*!a`2+7cbzicjc#p+`qVS<~v1Qox-Nrj~mbiDsKRMFB;=dc)9ZdXE9$7*EKpd*_ zTL(ky<%tu&;=j!HZ{zPDh+|fMYj5a@NdG(;B=|ol?r!|E2J*~RmemrPEzbmhAkYU# ztonjx4FnW;-V`c``8+!Xk8@zSe4Z~pvzQsDeC+tz{by$|Bn(%`UFZN&UtRKJ`Ohw7 zNEoh=96~wo?@@=po7qKV3k-F|_uc=I`0lRJ_ziW%-|zoQ{CC%?JVRabem*D?pNfHT z@1?Wy!O&3{j&vo!xbm6mD#dn&Eg{P$E^qxtWtbdl!2r_wZha)!SQr7221N?Vf6 z^QKN{t-3EdMp~`m%Kk(2#C|4!g(|V~uK922p|ni%?dZq$&d$6EivZA#l(9vS`^2cv$L;ka9-%(} z>!15ONpXv%pto_ktUI_X=HQyW9D}bBGvE4~R0aSLn13 z@tNn9*?nw3h^bF#*CnDK@(0iG2Zn_<3y1WAhrA@X!Binah^c?5+>w_R%$N8B1xcar$B3WL5qtpC06z#lAT-wY$MoSj(_njGItGN! ziilsHBN8ajB@*$2mh)f0Lg zKHBx62rthO$?=Rt{2->|L-XLTTH+7poA?6-p3wI?#*Yko5d1_*1Nv#&!i8} zDZ}wV87GF$bjL5x5y?q*B;p4#ofO(PDk{DH;ABaUKQP4;T92o$`poq5IiecEsOSf= z3<>>1{7HKFobntGlr+%7oGs<;6yh`DYMt9%W-WiXLFks#GUQO_`^)Y;ZQtWs>vUsC%PRHpCPCko%)D;U}2-+V5kwUNFVqE5@(>` zfcSnv+#UINzF%Y@5G<7Q^QidtIWpk~j4k&E@K=qp#=^*yy`iZ_9{5(ugIlY}yCzZ| zp6?NP@BjpxaJCz!&X* zhX6niun~cC;lp0fMfiU?0MHLO8-X@iW37;pt;_#*0z$9b1(EmQD|m$=eM7?UjgOHY1FyCM}k5WyF!?^$Gk-rJ~nQ;MLTu z`|()t*@Wj#rJ|or@Z;31@NH4+vEx66|Mp7803Rbjdrb>p(LNrb{EhG*S?L&NBf>=1 zJXUjiXTV*XkUDR9Ctt>BPuD>zhawiV3%Z)_{j{RFzZ zK=u<%9}t?2l`t(&|qV$qUvu{v=dK3vxuDgOgf-o8|w)m{w%$N#PM>NC%6N6UG? zfERHCIOB)G$iEuK85X3wed?g&CK2=_EoTdKRYb;wXolky>Ta>?)Sk`KEhA9hE6|L)13+Clzc%D;s2zd`vkUGkG%@?m%6 z!|upW?wi~`4>_CM9QD;l0VQTA9hDR?2df&_uYB_rgo4&i1II_ z{A(%y2QK-ROFrz5eApfN+>_Xy_rEnd{~pRuqx=b!KaKM1(6`RaZh-my>_(WkWN$dL zdvbnEIX{op-y^}r`4>=L9_1A~^0dDfsg~*QMYd)7`wd9PH?8jW_q+B)=T`=3U!nZ* zlz+QRzV!DhU;2BMFa5pB?`D5Lql0`@*y8;2DLE_q#ri&OaLL;`}dD{y572FPD7j?^V9^_bOlddzIhK{(eRW`RK5U^G8y? zkMh6kk}v(e%9s9LzY8Bhj?6y_usHu5%Fm|!BA0yW z?^V9^_bOlddzIhK{(eRW`KZ9f`Dau9SjxY}C13h`l`s9h%9s9L<#)5c-}Py9{_z4A z=MSg+EXu#xC13h`l`s9h%9s9L<#)5cpV2`+8nEL0vnYQImneTU<$v2HU;2BMFa5pBm;PSmceB5r(Lp{Yti}20O^YXIQvSDG z@}<95`O@F3eCh91emDF3T|4dkbHD!o@G$}$7C>^kcYeS=3*qQ4pq_Nj54gt*Oz$xq zZNM;v5OwdEMhtz5b=R{ya6V&(=v44|#%-rTnE*vfB0e3gD(iEhS*ET!b-($p$AVMZ zH62mYvF&9ooMB)j|I(>tBDc!$+-uRoU)#GCHh( zeJ?6K_WD@#`qvoo$Mr5O5rrIGi?2){Tz`* zu75R(Kgxr))LH*}NnBm}Dt(UN_VN~V#sfk>vHj_DYJ_bM)CUg;&4`F!o+FZu>tEN1 zKPSD=H=6aYQ6@Zjg!4e-Xx6_@>*$}6iw8>fg!V=0Z#!H6TBG_~e0S5e{`CUi-uC(< z@?))kJt+Q;wEp!2cl=D_iO5Kd^)Da%IqxIoLES3Zfr8Z&O6`~)K1WpT>rq_)N^DOL zpHrUWfw&9_ZG@JN`eKP+o+FYN>tD~oUx)MnBPTj2(}#o}gfFOx?fCc{(M2q0p{5KC z->!<%cKx?mzq8k~Sg_0}BV{^=hOdm$S4aAXkl5>ANHXfJqh4Nu^oe@8p;Ps82A0M6 zxgN9RW!@*%FMH?hFvqTTO6%yTkX5DJu44XM8RW2gp)OQ3(V~+cXrD|&3u%sZ9V%U1 zBVL`8Y;vqk4!B7hYH89t)i0;+^QL~P`elBK~GZ8LSuM%zrib5R@T zxmz)_{DxH*&)KfgJU768i)x-5VgIITo;RTLE=8K4ZqBef8O8%`b4>kmNBPt-8*MZ7 z&P9h^@@2-U@@2-kP14l}yCa{o&m+o@)Gv3GPaU(-HdF6hbjT%NW}GTtW}GS?c1J#E zpGTA*sbB6WpE_ovZKmG2=%7o!%s5rP%s5p(?2dfSK949rQor0$K6T7S+f2Q4(E*oy znQ^LonQ^Lo*d6(teI8MMq<*=heCn8uwwZe8qWv!UGUHVFGUHVFusiZO`#hrjNd0n0 z`P4BRZ8P=GMf+UxWyY!UWyY!UVRz(n_IX74n;+%8%49ca%>Zv(YwF?_9LoC0}NoDqm)tDj#-7K4+gt zlpm>I?kJx+W}|JU-nr;=mwcIVs(hJos(jcT`J8XI)rPL(e+PL&V4BcD^NBg)?tp$?q-J z2VM5}k^1G1@~LCa{|e=!=!%PWxa2$iJ>)z6J>)z6J>+-U-$&|~JIbey*=U)z6J>)z6J>+-U z-$&|~JIbey*=UZ zv(YxADJw48U0HF_Mwfi2zlVIMzlVIMzlZ!T`};`!GUU7T6Vx{Io|Yl^ z*77EmA@`OUk^$n}s&iO%7wxz17~O?l$s?EZ$TdCCT{JIf!fYNIXVqOeSJXUdruXLl z8o9|v?z9oz1yz&w{WOmLD7HSuzUiksX)-tcV7SsveM+Q$IRytN`12@@Q`(Yd+*d2D zRa&F8OlhIg2};wHdX%!+ouD*D zsYhu`s)kouqqIzEq0%&^aY~!8;gY{vrPWFcm1ZdQC~X>P{7+CmMfsW$#yv%84K`Ks zm!h=h9OaePoUOdln&HYTtvO41r8QqtUTMvlhEG$vC`Eati-sw$bkP~gD_wND@=6yC zRbJ^LtfugnrgYJ%$}7E0^FLatUunKl8^3AFmnpUJopy?euTbd(r5Q?7lzNo53^D#! zD_x|tMroPSLZul>QQK&7-tBNuMjN?yJ1gYFrk_pGWDbn*T2;Jx}RZl~TvfpN(gs z@;1)PVw`{T;VV9Y#@s+X&cK~_GY-E!>;9yV-+FQ-z5!E?3@)wPcYB?0-hna*m_67Z zco(%Z#ZPzX9(~f8|eH zg9zETTKDjqB;H_uZ{SU6-Ftac_xaO5nlX9l$8#suF0Gqenm}W8ikKN<7W(GZGpKJ~ zm_*#l#HQ5uZEoZrHGez9&qEoj$>vhkvvXq zP>;ID9V1QCd7FK&)W4gqR{6C(l-6jz%f6s84((|; z6l%HK6#5K*pmvF)PcYvnUhNI+<4yYId*i)U4hJ70yYeC;8*+ z{PFd9!4sF{RSi8AdlEOvdHU8mYF=iZ1HTjKci!Gb;H~?9hY4rLAn>&fk9~nvzVeNI z5!tJDWLcG`V$bKqcwFtCn6>Z}Y_+^LJ}cl$^p$VL+59^E>-&a(0WZhH2e(5H!qWsi z?SrTI*Y^qi5R-C5gXi&x0gvPHxHlf-U*9`)10M&WUg!tsUU0_0zE^0B31x(k~r#RNlfapHb{nk^e_j*{%wL;tFTa%@F$4ykd+SQl{^S52Yuh8&+*6{af z_&FMWiiRJj;V;$jpJ@13H2iNh`~nSMqTvfP{Adk-frj6p;TLQ8UugJJ4S$=4&(rW% zX!vtA{979SNe%yihM%qBZ`SZR8vY^;KTN~Frs4mj;VU(Kv4+1%!(Xl8zpUX;*6>R; z{BJb;T^jyY4S$`6zf{A2NyA$j{zVP{u!jGUhM%J0{TluP4S%YJ@2laT*6{af_~{zH zK*MKg_;WS<@fyBO>0dPb0uBFP8a_|MU#a1TY54vcu2t#pHGHXt|F(wD(eM{*_>(n! zf`;3v^p_fbwuZk!!(Xl8&(rXhhTpHWS;If1;fpo=L=Atbh99os`)at)lzyb)@6qtL zYWQ&){sIj@RKvF^-KOE+)$kP>eu{=4t>Mqr@F!}xR;3?n_%}8D91UNf;jhr}!!-N= z4YyP2`x<_QhA+|ZJ`I1Kh99Ki4=dfM;a}76&uRD~4WF*z&(QFR8m>iYqlSN3!#|WiqV!b_|Ez|8M8n^$;b&<06b-*y={gPnl7|1YhOg4_ zcWC%qH2e~8YaLZzCC6t~9-p;v5IPU`O7ZAG;_-;Hladqd-i1Aj>0#;<@URyiS{1*; zL2>qa()mc21#i7V_rO{1W2&5huEHM(2nqgz%6EU@=R$&&)KlY`kl+K~5$=8=!Af>P zcqSzHz#Zn9kl?s7f52Df4^CX@4_vztUr(t9kGq{F{tW!jz}JAU0sk2I$G|TFzX<%Z z;GYFw3%(XSRtm0N34S&B)!^5GUkAPkd=vPs;BmdtI4J9VE#Pq%*0p<=_=A<~Cy_WI z!O8-|2?{aL2mH_3y&{Be;JAcU;8e z!_7=L?1cMHxVOR`w=|8z^<=&_W^uepj*wtwzTt!fD<>OHNU*ZVa6*EWw;N7KuyU5+ zgaj+^G@Ov&xVw>ryOET8LGK0qDdHHh``LT?_g?==-1_gW@u^aoa$*fqn*xi`B;Q z#=?n*kyqYWc&)srK9evZ!OCk5CnQ*Tz2SreE5BtpA;HS;8cs;C@&|?!60GEW3?K;! zj++PJ^N@%DXaMwn(ECAu4*GM@M?oJ2eH`?0(7%KJ9rQWS=RoT~>p)k5t^!>Hx&{;r z<-Yeoao?K{H^Geyfrdao1;wp!<9HR}M7*mvuyA?(;!L zzX=^Y`dn^fu;$N3@9qyCmy>l)T<+y7t^1bu=EHhK^~d_t8Il(2aYFtm6K8!2$2*Rh>8p^W~2@Uv5E6{Be>jKV28&+?l@`rS`g6 zhUzb?l{P6&!=?fL?C<2PRz8J;2K=TetySt#xkz{j>CX++;e&X+e03Xp`Quml;~R2E zuB1a=aA*UPdxA+W@IfAKU`9r#c&jF+a!zou#jr9p3;uKDtPJbcq=s4_0>;UvE3UWIH~(NPKjO z8Q*C~h_8MXwi$;1cPOnh{a_~;TdzTgq!Lm`^@P^>0C zx=4IdOP}?`1ftCsb7n0J-)cBbY=Ut^3)pL$U|ioa_Z7%_ z41qdpK=JKMcN>cRDeM}G$Ds`^Mbb-s9!M^O%fu8IH>APoTG&djhpl*Y2E9&z4)rmD zjm8rWrM?ODUP$lLyj2gBnMc>cq4at<1n4mLVdg)~{2MK8d*<2ewCf|$tNq|A>D5Y0 z!U;u~)Ah&PB#ChN1N|^XNy3!HgYI((rY#J;!Q|a|B!0F6wEUtQ#m>VUc66l8^ zL=r|5Nq9YyLepD0)i)`pzTR8DA8Pu&Gkaw$ymX20IeYV=FRc2+mr%H$F^KnW`ls>BTO{L4#|1XvPOX(1Oo~?A6(qAckRcXEY|C!Q|(i8Rh zXr;F)<>lP`tx)>1`nUJTY*yZ*&%dVhJ4%0|bcxdE)xSMH+o=2ieSU?~o0Zdi?Rd>Vh!-yKt?#6YW!Qcpm?H{2TCJi~sxhe~kY&{6FK> z@=lWf4wvWfufu;8{%i1m5C4t$hw%TDm&`kEgJ3C!o8mL04p7SzcM85DWy*;eL?B7N*k4~ zR%*Ay4=Mi#rN31gRJu^<5~a0DZTSlc;pfQi-mrIJL91A<2BP6B7D}P*5ts89791jS z;o%Dl4xn(tLl+i&3I`x+!VXv{VD0BKez#;UP_maWtKMV#DGg`c_^JW@&~R>K!@q!< zR#IwJNvS~v&0+tLLmxTp6>``i8vRMM_l{Db-q}RAGVU+(YA+H2y;4 zMH;Ws*g#{ud52(KaE%6}LWw+;N2F8~(QA;#BQ&0%@dAxkX{@Iac3v@X3#i2*rN)Mo z+8I)6VnA~$Y5ao5pJ_Z#qk+czG`6+BfnXO&KQ4_66K& zPfATWDYfFH)PRHLETHi)jX%*?Ok)L&cWJQ2)z%j5f@}>;oiusspGm1}ruVyP{FKHY zX*@$?IgNK{u(h>YTJQ_TYG^8d$y3owN~JFS&!_Pd8h@biPa4Z;yiJ1*va2zM(}FCG zfC^UfRHl+rampYSG#;Yydm2yESW4q98f>$*y#~90y8uY3$|R-Ql9Vb+(42A_57PJ@ zjepSKOPB*SNNEn6_4XzmE(=C$c;O>piYiF^>3uqwK2#%8u!z9l*Zp_)X`W&gPlWU$KX%zU3lR+aivqj1KjPqnVpnk z7G0X-p^-u(4Q*l>T435UXiT6{NCPvFSNLe|GIT6o!^|jZsOc-;7gzFlxUY^kee<@O zh?*gynIf7gqB$px2I6jJ+|7);8F8Dt`&IhfdJOL&WgWytNpZ&e$W|Z?*(wP4midM^ za5Azk^BYhP{xYEfO~HQz{%QDQ7Ezi}+K9Nff6mFvm3`f#Wj8*Ooj-?@?D4qQT5>Y} zDghP`xgj*DsLG&a1dTKrB4_TakW&#u4rgjj`%s?v4c~9*_muuqX~F^HevQ(Hm42f1 z;)CY-ol0L-ddeZ={$ENLEA4yOxKC2LUgZx{c|}SWDLte#Tjf2V^dqGgsJtI4U9R** zm3NEMr<5kB+^;KrN9CWYa=xYX38j0LW~#g@rSB{KvdSw_TBp=fd4)>eoEw!srgX1TpUQtt<$F|4fzn5n?ofKE z$}3m8T4{>P`!A)7mG)LS`AUDMbeGaBmA^veC##%^N`I*|r1T<{cc;=ZZc+M_ z(m0iKt32;r4K9pMCth|?}tj4D?Lf&6)OF!(gRBUD(~k?LrSku z`7f#bc$MQ-`he1pl#Wn&B}(g*4pKQcDt%1p9;G=d?;)k1D7{4GKdbWhDa}xMl}g`L znxgVyGQ8;rRS^sMJo4GrI)F^yOh4Ebco8kS?S-E#;crb zl>SWV7NwV}yb7gnDLq@|Kc;d+O4C%{kCd)Z>QQ+&DSce&KBZ$+UbWH>m0qCo<|utl z>FFxJM&)i)Izr`5SNe+5B$acW(npnksx)2YEmZoB(sNZ_iPEJ?2djM1@9<-a`}5FC z9L`IOn>{pl>VOBm@$YysF^hkXvk(i~WYq^{Tz2@*8=-XS!yTOE%`Nzhk;fNU=^eSx z8{gm^`Gz-r@Vt@dV2bytwP4Y?nA~8ZXI0#d9@HB=ZZ@8mmp64lFt2JrvPSRh zUqsYdC$&JjzbflwP)yDtXQSo4@J;VX6_8>JxL|}W;2Q}d;3OkpaYq4m`n~1bFa{_d zh)*wpmRd}|ciw)E5q4!-rE#;z1B#64U$#b^V~rT^u}0*lSR*E2P9cjcRU;)6b}XJPd%S@x>}j}bVsTQ#xFDt`r1AUq;wBqB2E zdE1y6YeZ3oHRARO)`(e!)`&YX>Ul<-N8XxYjVzvEjhtO*jV!eXLo*&ns%uqQJLe+G zU=l&cGneP$pT}$$rO*kr>^5LBt7 zVe@T!*6f&yvk_B!)?^r|Su5Y4GW`rZWH|BULH=RUR3Q5)tY@rpryuf1WglUX&f@Vc z-trwxa2_l>BWsLbYRq}oi0l?rnI=@3)u=MH*2tU|)R`vKnboK>wM;c4!GC84Bs~}{ z$*d3K{kirWyS`A#0pXGHA`wv$J2hqzYD^7kOf_munYU_InKkm(MW`+{s4ms0E^sR? zoAFmSpchO0Hlj@uIkO2{arSEF90}i%L3ePadEg}ZZ{a(EQI(zblNBQaO^e>SB9Su^ zMwid%CfC9!S_I?v8W^*xVVJbG*N&VPO+je^f|O1{kkVTbq_h}8N@pWTsb=N=|8`ao zLCW+LBqAFHYpO>RG7J}>3?mQR&J>i_CTNx;GHl8#w<>@}D9(F%1IoT_dSCEt$??9| znx@SfayMTXB8-}0p=J!jyL|yl>S{>cU1VKhZI4G;Wze<>OEyqaf9QM2whNxr2#Yb_>$<<+U?)bq*n@XME*{b=E)x+y>BADuOOAR zOkabfvQf+pVs4H{O-Jp29hDs^DrIUt)BB;-v=e$R(Ca z^9-c#D@fnh96S>oJh2uAJi#lT;ExH<&EBXK$HcRf^eUb^6weQl-ZzlmmmNGMm5pL< z5OZ@vxA4q~PF;I@9f9YeF7Z4Lc%F{*osaZg<=~m<;F&0Rf>%7j9}}KG$vGN4J4vtN z`7g!u1ElwLr1vEUPf2B?m>b00oY*ZqTd@ih`L4&Vp9j0da{%xhiu9p(xcy28&t49m zSWQR$1h064KPEiKMyEJt{p=*YisyF4a|6=*8q)isgQujjQOpfuZtm4BJpVNI=NN>_HppU=ni;-S3Eh|JC^?F5BQuz z#2Xb8&rZ^-cy3cX-$#1U+ur`XgQujjQOpfuZtl}9Jo`qct`j`>b%|#`;CTwtHxlW) z+`+T2gC~Zoz!SXU3I3Sy{07#UyT-GV^eUbq#q&L+cNNn6oP(#NvQf+pVs7r+Ej$-z zMx`zS&vTsd(%z1EMvRt{faVaSZUjMlUz*_(hE4JB zxJOMGlq5taTJ*UQ{b!8yCS!c3cy3iZ*CE9#k>Y0^JSCltVr~#~b5ghPyfx!Uc(#u} zTRY;(^tr~LeSzr7NZ+|g-=z+s{TxKGtqt`PydnzTjp$L2KmU1kRElH1@13Mq@oZK+ z-$i;?AiawnJSCNlVr~#~GlrVo7=NA|ow|tn*^cL)F7fOGJWoRUFr~l!s}7$19X$IB zp5PTv@W+JbE!Y>*_50pQdKJ$tisw5>?{cK~83#{EWuurI#N6D!TX?RxDk^oI;JLd? zJbMGr!ARfPNZ%z6p2-fLP(-1Af>%7j9}}K~qf;ESes+>x#dEXb`8LwK4C(!+gQujj zQOpfuZcgqNp0lq!Iy^t`63<@1^F*X?IMT3!P4Q&QO|<_0l059k)2=SHWlllr-S=LtyPSxDa~2hZai zJdYDR!7HBNj|tD2*vHlN``$@<70*qIXCuUgQujjQOpfuZa%JCc)ojiRO&jx z^Rq7TOaPw8BYj^&`lz-v^>d(u=Rm;|yy6M|nD9J1I>j;TXD8`ZJU>=E*CM_3Nbge) zo|4K&F*k_0869Oe`lAJx9UY#Zc8O;^@EnBnor&~a=-_ENcw$>K-goedC-`H+^X*Hc zQXCV{PSUG*Zd5$iAiZ@+@82CfC6$e0ZV+>`)h#?PjZR&A{lxl0_Omd?uk;7AaWZs# zlRuch6<-Kz@dn55-36^5o|fj}9BB^Dj^^RqXaUZQPQh-!yuC|s{*~ct;dOP#;Q109 z`vvoG`ZPLp0YhW_$?%s)%QqUqSW=wwi9$OXTg2y-gd1}wyq1z(7S%<;{KMSXiMPzj|36tCIO3d* zW6k4nq&XkQnJ51XA$M!}!b52u&Oztk>~kK@Js052^Av1<&f6Wcd|&D+K6vO(d`C*! z5mM#k52v{+)-T-vv1K zJp~)s^SB|hWBdFfb5OO0rsW1-Ml-dVoU zh{ejAQ$A7XMq|nHwUKvY?1a}+v9Yg439$^E=Pb{E5PuwL&&DzK@i@YskK^l;!w9*H zy)*F7fsfKW9DL8gVfQ>7bT7am_bE7Mkhe?vZrAxY#`gl_!_oNIap7rc9uCjPh)2g; zM@&lRsc^6IotQvAl53KO1NJ$KzaoKF;({-iDYyv&$boO7n0VKn`vI$iwOX z0-XGxf}dHL`Tw2eg{u#;aoxdqTy>C- zYYrxdQ2w9VG{MMU4P$aGjG{#_Zm)qcs~Sesex+t^6l&&< zsb=n1YUX~WX6{#N=6Ym*t~X6+u3ne`8oJ14Wizeni!|sy13ud*-h#iA7EGL^$6l!vyoe<7R<%r zVY3-e!0}h*wCHI;|AlY*N4^1}j>I}hWcoW10!T0(^aa-7o{=P9{2G7yajl1$xBxzR zV{bM?*%U)#SBiaE`5tUu@<4x#|ub%I;gMQ73DD=_3X?TcfF)FV7ChnnvnAP0z1u?Y{Qw#Oj zBCJ;~0<8h90j&nD1}y_EbCSV|HmhvLlMx9R`L1^)cQ<}?c2ok2s@vtaMQ=~TM#4O7 zB%G3kosGpX#+Pa?i^f8UxH3Kq37%Gz1^Wuxd4%Q)>o9hLl}?~-H*B*rXxk23aT;x# zVB@Y+=pbR6;-PH~Y$q#lRyhyvMWo%{nK?DOnws+Et~(@rCu3?rOw_tg{)k*7I09Mp zCbVysa;7$Nw<05wV>O$s3PEO=ePVC;oRv;Gf{apLWF`JI54%*c5-* z6o1$hf7ld%*p34KO&#ivykAHb6TXAUH6SLzALl)RKRChv4RRYOkNCe#j{DmL|G$yj z0Z#D$HMv%B2LF2v{@@M%cRKh>e!GGHmM?XU{~=@}V*4BL&jtS9B>vwg{&OSnPjul= zyW)?XW{N*-ia%_MKWvIWY>Gc@M}hy;7*z=E8>E(iSm!2c%V ze;e_i6M=s(7yh&>{=FRhVN?8JQ~Y65{9#l4VLJ-^H^rzz27e}eJCSQZOoBfS76X59 zg8yseHc%e%$MIv}4^Hs^3%MQO1pi->YXxWUzsKMY-rzsS!C&&*4g9wZ>l*(9$VSBW zI^cf|@V}Axe~WbkLg z!$htDF$w-Sj}8363I4B=+dz55AE&l~KRChv335BY3I30eYXxWU4;uWz8~lIl;4k^@ z2L457bdCRhWFulb9`GLr{BI!s|3&{@D4Z_`|07!>0Jdruf6A_``M- z_-~3)g$({o_%4KWBZ<Kgyu$VSBWL*PFa_15lHn~P{g8wpd8z_(X|C1c|BMSb1Ah!dY;QteH zt>6s)^9}ys4gPX-ir_E#?FRlugS)^VYMAk#BOkpmdw2FLq5uH4KJ92co8k|f;t!kR z51Zl-+fm@ZDMl4C_%q=j6S)S&B>3Y_A>a>A@UJJgf%1s|Q{=cmQtlM4|e?LVwBDPNg|4iV2E%E;r@&7>t{+0`W+7*B7 zR8;(7Q~Y65{9#l4VN?8JI|}@##;8IDe~cP@8^M(@my`o=W5$zuC^6%we5DU zw$0*d+nv?BvXGK8Q!aTeD2ak57*kfWOln~iFM=_<21aQ$#>mY%viyO?va%WXxXXl# zVNUK{Wg=UVQ6@+Y%EWLB$hDWr(It^3g7lR#eWgraDbrWV^p!GwrIJ3}*~sM?N#DGP zQO3x3ydzm8SK=bqh?Xj9z4kM!CA$nO<~e1wVKovrK+*=da1A7FKo568(grYbAtY_U z7WX&M)^+X#aQ;!3#x!`{09$W>H%<2PXf;SmQBe1cvzaTCmQ@*oKW)0yd+9+*d*nIs@$ z)6>&4)263;=+>(*6BB{N^@*q}z7cc{poqIG_`>{u zzf)EBR^7fmGib6O*)KPlu5+tSojP^u)Vu0j{B+l(hZ6}? zzn1MjB8x3M(tI7sy^hdZ2)%{SO@wYD#Iq@FpCI%_LSH0wH=(-;-G?8=&wcQV=w_oUMxIhvPy-7DI%jc@3#wL+Gu9-b(173H>u69>#0?B%wP9-9hNvguYGa zXZTV4{0x4v{QMUV44}CFizf!Cd)IPa0A#VONE&-cZ4aRv2;D&FUkLpRAs+s0yP43P zgzhBt9YWtB^mF{E^nVV&*z|v^(*JFcKIer%7CVuoaV@D`OXzKc-bU!Xgx*Vthl|^8 zA#{My0Yd*q=-&waJAPF9{|>*{^dD8}KN_UZbparY(M!^JJ*mB((Ax>UozVLTy^jzN ztGC@s=pdnkguYAYyM%s$AC>+u;1`?zV=Dc}g7mpA1Y|MaNgCIY+I589LFgTX-cRWL zgm}N9?NfxlMCeO|?jdv!p+opl=^uh$Z2Hdme4t;;bwMDDIa1OXC$(`xe^2P|34MUj z2MF=JPur&n{VSn=CG$?8K7B1gT9BdMBZG z68aFK4-w*d$F|QB`U;`15c&b39}s#7KPvr);1`#^dtMLd*K%J7$YSu8G_EJL>j~XR z=te>xCiG!KJV4v_IYM70^i@JXB=kcG9|CjKKOW!>&3iNBaF9>9@-b)&LNo_Bo zcM*CQp^p&y2q7NUZu>l;uMzqhp&t?Y5usnLA)p=w@zn1&Nh%9!AN%M`Q z{zgLYCiHGXA0_lrLcAQ%b{nCu6Z$%#9~1g9p@;FK_<0z9wfr>R>YjfG`n6Z-^y!ku zn@H_Vg#LlhKM?vDp^p*z0--Mu`UatI5c&zBpAh;repLFuhF?tjx2Ovi<~#x8j578p zp(_YoL1-hPjfB<{T2E*xp{0a;LO!9>37rn;L;xpA``&sL{jOqYiBO49noychH=%Aq zFCp|2LQ4oOA@n>#&m+``pQrGx5kHL>ckIHL3|8SbpOl(-3i^|iQsa#(z1I@!wTx3F zR3!8YLa!jyMW~C=g@i67w3yIhLeC}iTtZL5kEF*RJG~QCdaz)p(|Zl$yoPZ`2#pZB zoY3WjItg_WT1RLdp+$ri5juy^IfUlmN79=EFFUC-E+%v_ zq4NoyPw2&jUQFmYgq}m_RQyPKr^3rl?*x?|W@%cUuVS26G0rOqy^_$&2)&HZMT9OQ zw3g6XLgx}Xm(a5bJ)6)e_>uHZftQ`$OqJfuAibT8vy*Z1gz|(gC3GpFc0%oh)(~1l zXaS)Ggq}s{S%gl;kEC}pyzKO5sPym&44uCnjI)Drh6xQ5x`fargi?f3gjN$;O=v!$ z`GlTH=$V9O<44k)4KFLbr^AGBcpjga+Zks&p&>#;gtidcLa2>U8=>lJA zXApV@p_A|<>74|xAiasrCrmtLe9H;Qo6Izbxs7qQ5gH^kNN6*m&4gMBwGvuIXceIs z5qc4!rxSWQp%d{V>9HlT(woWjX4>hEG0qs{gA-4|^_&@lMnB7pQ)ZlgLj8n#2=x%!KxhM@CPGbwUO?ytgw7yz2BDewk@RN5 zD@d>L)~63f_47)`xsq`*gffI)O6aA85`+?jmJwP;==p@6Pw1(Ho=Rv2ek8pa@Cwtr z<>}XrR)XZ-*Rfd7;2mCiXl(=9_Tp>i_~)+`?efDvQr$k;3W zr$0whQs-}>FYo!L(U&K&z0#jO9${aPKmW(tEB#M=5y`3Ds=OR~R!<&#rO7C_WOh`H-d^dfD95q&y$-)xo=4AK z>CmIolV=_KpO!qG1JZ#!kG#FooAF&rr}vDNXB~dEJdd8e(q}}utD~QF?0;JFbPhZR z@;vhPN^}1;9eLK_SIhJ0*(*KxpAqgHc|J+)m7Wo0TGnrz{`3Eqz0&RfF_}C=`BzGVzgnJ0&tB^X-(X&_ji-#iI)sbf%`=6FPodddoJdeD+(v?w;W9xezeziQ0p1snyKR7*k z*0KL-$+bjJ!zSBN+eXql>mgmv4SK1ckF4Rx#R~)xj>R4%|?a)~3s&bwH z_I50buE*__Qh$!yD;4XmFpqTHUa4h8Rq6}%UCW_t&yU+HwQRxG=+}Rry;53= zT=4t$HQ%hvN$vmXOd6Pc-B)qu9A$(vsmG2T)A`?vEM8dWOT+VRyzcrJ<*ac5Ec}Gu zHpk82^|%kb5x0P^z|G%LbI0`t+ji;Vn3Qm{5fL3)xaeqEWyKlF%kPO~h2>D+9xH8s zF8B>g@Z|P2|JwMv+f?b*SWN|$C!LMf@^>Rym6{NqH}h~27JNU^yx^kwBPgzWak=|0 zT>mN~EZ$@#cyQP0`mldvg)TTl^vr$sU#w^O|=6|bU{u;=h8ur{jq+kjb z=WqX}@tVS1UaJ*TvyHp|4#9}JHd@3Qp)xlxgu3PX5$a+81zt~_%GB(2NC@W+pZ@_` zbA667HQVyTndTm~V`>)1cYptWoKMvDW#9G0?aQ89hq5|P=h&BhJ5u_;XkXTgwiEx| z_GMoZ)tY0-zU=MM>Z-~YW*?3L`?3eV9j#DizrdIuP-a@4Llia@S?J+8(gurGVyOH<4LNp4@ZIYxz){Eq?qvaJWF zmj9F7zU=KWDx~Cp4A_@FaOV{A$I-GUyM5UWQ5`b#-($eOZ0j9U$RE?lC%Jvu+hbHn z>HjfcU-rNkrgurGVy3-#oW{e-&q zW$$^jSo_d>gtEhQEk7!E+~(|hh|T__BMeC#DVwvG?TZvu z!E3)zr_}x#{?oA(eB37OWHxDsKNl%7YyX*+dv@VO#BqDHl*C&oiMJ5CiO@}iK0)Xc zguY1Vi-hhbbT^^<@T2Ve-3Px~`+l&GcibNBBNW%q>dEK0JzBBHd)yu^8ha1b>9{>w zZGV(@Y1zh1u=-38dMBZG68aFK4-xt-q0bWf3ZbtM`T?OI5PAqds(pG0ezomW^!xEZ zKW>lK8qZK3$L-NVn~vL~g(`@BL;eKz4bi_Jw?~V1<}$W8mqA3w?a>~$M|<2J?Qwgw z$B;eRL|VbJLW#KW4vXq-vMZTOXDr~T(r00T^yj|gzOSJ zFTN+W_nNu1n0aC1@coSocKoJs!RSvL7Yu*1alsY)8y8&ie;OBTd{5(o)ZaBOSbue5 z{PBU*M8iDVdP$5wnp%EGYWx};sP(+$o?kUy^LlviUiaA8JkP6MmfE}Smj5%;TmI<5 zS@+Qg&!O-9`2NGG@mUw{I~VqHe|Na?nmJ^3V%;Km9Gvw9jnQP{X(GKm5?S6SLj{)IIweuXzmuJF~w^?VVKydi(yLH?&W*%<>+B z>8M#ZE}IFq9&LQ%E)Y0)&D@W}!H1h*RQ9cNM-dNRpTz4@@meuAHU73w5gfl|pZKhM z$7j#=B=OJiOnYj4e+MK*B8R^IBV=PjWgIdXNS&`l(zxf4M4fdxqNc9Cg9VXzMdI?r z%WqFjyjA3sTK;XIpD7Y--1BLoyLfxoz4~uwc!!?zeI&sg?jp+gfz;m5&HWO<&+z@w zoUh-1__oCi(cXv7zvuqL?c;ZJ?)h2urI7q;&`9n5q>4fTCJr>r^$xAP3sm>6d+x_s zE{EEfjlJtmi{he$ZoKVWiL&_6Oh%blHvx~-ZhW3-PajsP9(Wag4!s>*AZQdp52Uzu zg(Wm?&y?r06PpuTdN)BIF98EbK@}ghRPnnghVjQkWqfq3W%uJV8m}oM=`S$&~rEnJ<8t9{8wI=CkO7=g{mQg3$P^ zD?e|P`EMA1V%-(+I5_J+$_nkF7fj505HQQ~M?mPzJ__Bu;~r}3ze8J3JMp0xv}aMi z=X@M~mcnDb<+NuWdK$$)zCXF=@M|||9mYv>WapZ>yFks+;j^K`yOj>VbDtos`}SvS z9S#(D&JRF!@0?o@Dq=bvq?DM(zYY;Sj6{vpE;?JJ_5)FaTB(ga#g*8h*L{`ZowfWY zb5-R@?LF%xkVs9e2H{x09K}SbeHJzJzzK^Fy^s+m)_s^2R@8d~ z)w`W6PMlNxvB|{vmzVELO`LzIgj$L=UJO|6n?COv zAglWdn^NOH*R6A6{11Whrk3BC8c#lw*xPe>_aA0%U$T4MMIhl-TcENl$=1ZCM-uz* zo0(evoedKWZwp$FvFE17e|b3?mgFNK5wt;LCxIsh9Qxgt?>~Gn`3@$(@ufFjGQNMM z=lR~ocini&`TMK05yE`D^j();vimjf@Wx==XypOu!vpK_p}N#(+H%FQd@&H&`yQOtc+1_X{r5F&n7C%n4-wefcj1y)9gg!$8K+(xN*+Ch>h@; z#*cjufA=8fDdQbY4K3qmH>D0AY~Q{A^!D?A*LeL1INQDMJTT@p?)gUuY4>a1JhSoo zw*jJ9P)0XGN_T-6%L4);_$hQ+kW54*7tDBV=LIug+jPMRuYE>s8f@|qhd#@&Y-UVG9P*vCGEt8TxTnc8!>@r{q* zm0Uv99pnFU39`~L{*f!hxp`Qe&yT{{@Mz24f7sQyXD`r`%YW6icVO?0ZH>27vCDGx zpQ#Ux*CdeNj=k&tab%v?{Dy|d=Hm13x7^c-=AgTM_aA3AUULJm+V|hz(A;=y!(+`8 zXFfLXcUO5H-Z~zedG&qXu9tXM|CD9aJn{0!8ulMLVgG}T`yV(lG2XHq8q>END$}w2 zw8Z$?%i9m%*}nVnhQ{l;bY-qEv>)EzasD?NukVE)GutttGBcqvGodmwA(=TiYxk|^ zdSKUkVBMb%A8z0M=k~@u8ALp|=SwIW20*(%4lp&o{&Zbv`|vs;;Wecu_2&lSkKcv6 zJ)XCYKaG2y0+Nq?k-}-*GZXOmU7tqnr4sIcuwfo0zx%$%Q@^_?gMj?hO}$!-`Sq^CbpnSdowb$JnW8>%MYVP zN-n<}&BndE*ZnPGqV!G$XS>(+tCy!D#_n~O@@3n)-cL~=jW>^vQb+>d|J-|aPilPSIT!<^ zPWVCUn-8bHc__920el2z-;^Z0jF_KBZyBVzkU9mGv$?vIgz~Q{5_}3>u(^`gL_yb;Sb(!P659; z554o3q<2o8JwBTS81&5h#?D!@>5j2yuIc>J*wYT~VIwSMJ#oW&fVzJc?}-~o8{?x- zu!sIMe$hiWUOyM;2lu=h?FTsq2iLJF8QVqv4*Uxz~;~n02`1Zu%{cY$H zW}^jR$NY_C~*#E#O&Ev0L-q1Y$^5v(sji0tWb$DM2-E->vFE(DE27?_F!sqUF zfA@c+m%af4+x>aU5*_t*ctIzPDzRr5lF@aGV9=>L6;&(ds5>q zkEHfITJ25k{>5qN&AiY|}Gw1M#Qonqzw9#y!74#M{_sKky?!nsMDf*D}uz zc^TNJyGFYSxDUKYB+-JBP~WqY`_WhbayB~5@&6eA&F=decK>u{^#zaNa3{vetM}Yp zo&DHB4xOtDA3MN2H}3f$ejgfUulHs^I`kM-KgE?0at8)l8n_?c(r~Z*-X*`N z6NlE1-PichhPlfRPqfTE`~B-1TfTw*dZyRd@?Ax1tYy!?R-fAV(X;1HG|b)orS;)ZRs-aC?`!)gvzbY782-#%#F7rz~914_gI2>qgk*$@n^58(GnpxbsW~u$|SE`wE zHD4U^d=T-IJw4q$YyFY2O4YB7=Cb+0o&F%=7D_{YzUUV-Be_DpQU$8#4`%X(+<;## z`K8eu!Upmgd>tNszUNoQve{gvGB{Q!?37?2+6aiBs8(|$qfDA4vgKT+nnS$uU?!XM z`%7cRflPU)PoDk7e3<4U{N>8!Qkl$TGlc?Uk8CYus@pSUDkf}uu39J#OcCZw#I;C% z#4io{quFX9vvna|L|^E60LIGwex^7;zoA0L&sY2*VY%#AhciXLY2{K3$%+egR2@^r zqbK65gIvJJ#@431Y9PCgO(Z5@f`_GHhr=xf|`PqMAOyKDL~YU^lDcP5*sna1>Ssq21$DmMaEC09%oqpUsK%Xv{bQ}ak3 z)R8vg_3G*P-@-!}|`Qsc9wVl|U5R!|vo^_T{|7BmsXQl*;D`fO1o zD(LvWqSu?tfqj<6v>Zb&;|54>4TjLCj97uz!BxhvMJS#Gs}>A9N|Jza^; zr0dt|ymoZAUEGd3*O6#*{Ck?6*Ow)Gy3^g8`W(-V?cM42?v`Y)i%V~$+};vJj`;L6 zBd&wf+t<_HYM%mnGBPj$dc8HKZ7my}c-=j1iLQ3H2$QYL(#<_C9{t*S z+)UE1H|3TP{aRbxG{rAj>$joLjf@RQcr_CsFLz&qJ!jh0EWqgJ9_Y`A-S zlf7wI%OLC^$f1hF5f=4AYaaE20y$ohM%HGYj0qb~1f+xp7VT@gy&3wPtW81(w?)c| z3Z#PK>Baa?mP9&AUl>a`R9J_Sy?rq?3%-$><%|MsF@SDIR|`A(bjzi#Du+Q%vd-Xu z4c^M8WotYIG_BOY^7AyXVz~xZ8er85FVWMsp`*L`;`CAvLxis8L|?iuv7sZ0cSYyC zG} zUa?douV^xWiN3-_UtyxJFws|-=qpY1mCJNmE1Ps$D_7{WR<6`(t%RIJ7%R^+$g2(V z8V#&ks&l#u`3i)(G6YwJ;CUgqIt15*;4+KEvSpUPCG2Io5Ld4XfR&LV)FNMfp3czf z^K?E|uU-*B)j3_gTIXUlI!?**nx)Gls6l|v`I==q@|vcm2&ztQO_Nr^HOn3XHRr8~P&MfyzbZGT+}5DnTzyx$S+x}TB`N?F zdDYTo=S5Iea;ugizY4WUv9xOG@>LO3l%zsIhBctLUbS>(O>r3%dk3SC?6O z1^o@w4V;FsrCPdCShZ}q717qyCQHdou9l$$0%}cG-A08A{jo(T4~A^jwf_8h0}Iyr zy<`2AY&kz#^gRr_xB24^_1J-EgNd(?#EvX`d6aoLgc-MH-Q`7SPg!VwtgMc;uZ1C!q&uLj;RIV^*ldlZhq8ed=@ zUjd!KUk`FPpXFf3AS3`I9;E$`vM*cis zWMI22w9KWvZ2#%NpHeh~a8x~5H4ZS2W2lnc2S`r8Hf4 z(|3h5qH&p)^5Y<8WfNu_c*2Pe*P-V(tyr~i`2xp3ZYe`>F+otcLXQ&&C!WSxZsTBV z6Nj_H#=*2B4rh&xgDFJ}&Wfcr4rUv1ILmAtOhn>voP1%95{KjD3)7c494$+c4<|-( zIOkdXaLyEmv)aa~lXqJ_oN2|-S!v6Mldw1(TRxnh#o^fU;nXb-$CeLgb#XX$xpTr7 zhqKbkJLiINIJTTQO^m~_<;)pm9F8q#PA=ncY&mn@8H2ORmh(zXZEA5=tk!vt)W6j$ zS1w$o>z~>l;#zFXLz>CnPAtL{2TLv3mni4^bG^AtIXfKsZ@{{7@6KY@#%(T*?rbfU zvDbqbW7S+wZZKEQ6|*^uUK9uMr?s{VJh1wN){LiEe}2O2*^{l0|0Qeg(RKTJOX>a; z>;Lo5YsxG`!Ez75z*Fr_slBSH_qhBi_R36pcG`c*UZ1UOHifCnM$=h#y!T| zlJ@Q;$i+_B!?2WQEeLaQqGE8b<$EM*+Qw3lO&5-lnB!ZXkl|JS5<*V@U=X6-i9os zgav}4#14y*9Fo>RshGpELa{KwZ7oq!6!2&sQ2q3*K;g53_R9}h4E?ghx$IUF?jIXO z6NVJSurP_EUjEs11uGI*WwCSsx+A&up&wR$MoW2|>caMPiNYAE3}LIkEc@l$-0#o% zqvg`J{6LNcv8lMVSlV9nliXX!dzZvf`^FnG1AcqA&+6lC&Xn`iV}Bq&;*aDjBbh4K zZHhQBP^jiH@{mn=&+9?gP|g&Gki3nR5%E$vqG_)6Hx5|w@E2hOwL&`_qbRTUx<62ZiTjAVACM>3

    9NQrB`9s?Th3fa(IZ7Pf?Ks(g^J*lTgihF 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

    hOs_623<`eY>zh3Ez6=i~oWA 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≫4LrA^2Ds#;TfRZTTTnEwL($b=Z99$06D05Yl=` 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

    ;!yYYadZL@HrQ&eVX`wFz{+?oh54U->6?20RJT6 z-0z00esme=@3!7YaTD-{uQbo;haT<$-t&rjB$NLS0DlAXV0(l9KftTg+V2|Bj$Z&D z#Qq$^f5cO&pYJZ5E*#du|LhDrFh$F40RKtAcg6X4<2Mch{`A?Z|Awvffkxnwzp8$E z(Jo7Xe|X0sLijAoJ)dy4hlc4I-;E!>L2zpKkG$>v5c45_=-lu1+pjTBaiqk0-_FKQ zE8ah(@}zfCImZH@o>0Htg8nr@a8%y)Q33iPjBAd=y}7_kZm$z0f_|3*{^B!ghmXPm zok%#>x4%y7OT$(9JLGwmv+(ac@JVBT)Ghld&85Htr>h?N@#s|sH|xm2A2N7E`*k<^ z^~(l7L;3W8eh_&2in4xecBseE@1wYhnV*apju8Z=o1gj)_RT7I}ZU5;`fVt@xb2&$A#--O%eQK z!nu7vN1hzSGhcvz!=CD4Oxzhs3j{1@+RB&46YggZrGk%k9^6Ik>dalWfJ1=4IsXs= zQn16tzz4E(1ka5NfCtuV`}UxHuMiwUyFP9My>kiT<`#PMVc@6#ceVg#{Phm-E&8Si z{*vMKckPeijJLhE1>S3|Cx!(#59dGYL4TSx?-2)nl9dnt26%UHsxY|}tj+=+c|$$V z0Pw4TH+-W0xf*`;Uc={-gM~7(wLb6?@P9q1{$vsOyaPOLt!sQuILC|C);xcJ1Yke* zz*=p`>%nI#@V;-n?G+OoM6Qnv=wHJ7U0Wgl1;Agk^0DiHr?LO48}#=B|MC=#7e~WR zo&`Sih3d!T=dS}FYt5ew0S{t)0XFo)2(9n_8*9Hd=L;qPFR|WhS57$VZM_v|8$rKn zXO;7O`120IU5dfilR=+8P3`t%&|eGulwDOGqyHy>_rXsZzc)~X|60%wtX2K=qTG*x zM}BvxAZA^Do99#yOEDk2Gy3lyzz23w`XJ=20)F%NTHgcFUIzm|^mN4^1|9_-I7sa$ zFiHhl34HlJ+Alr@{kg!?)_Z1d1|FHJ`Z43F=LnZ^$Kun3@oLof4Z$gnzpzpfH2ie)4YM2MLY~*T=y{@F@7qez``d z&ww7%z|;60>Td8l-r&}IHqHY+uw{PtVbPRzcJ8sH7f)K2

    hJ(CD!}!Cks88x;|>bXP{l{wFmOp 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 CuFe$z diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 567b49af2b..a1a079eff5 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -90,36 +90,37 @@ program mksurfdata use ESMF use pio use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs - use shr_pio_mod , only : shr_pio_getiosys, shr_pio_getiotype, shr_pio_getioformat - use shr_pio_mod , only : shr_pio_init1, shr_pio_init2 use shr_sys_mod , only : shr_sys_abort - ! use mklaiMod , only : mklai - ! use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array - ! use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft - ! use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride - ! use mksoilMod , only : soil_sand, soil_clay, mksoiltex, mksoilInit - ! use mksoilMod , only : soil_color, mksoilcol, mkorganic - ! use mksoilMod , only : soil_fmax, mkfmax - ! use mkvocefMod , only : mkvocef - use mklanwatMod , only : mklakwat, mkwetlnd, mklakparams - ! use mkglacierregionMod , only : mkglacierregion - ! use mkglcmecMod , only : nglcec, mkglcmec, mkglcmecInit, mkglacier - ! use mkharvestMod , only : mkharvest, mkharvest_init, mkharvest_fieldname - ! use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride - ! use mkharvestMod , only : harvestDataType - ! use mkurbanparCommonMod, only : mkelev - ! use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, numurbl - ! use mkgdpMod , only : mkgdp - ! use mkpeatMod , only : mkpeat - ! use mksoildepthMod , only : mksoildepth - ! use mkagfirepkmonthMod , only : mkagfirepkmon - ! use mktopostatsMod , only : mktopostats - ! use mkVICparamsMod , only : mkVICparams + +#ifdef TODO + use mklaiMod , only : mklai + use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array + use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft + use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride + use mksoilMod , only : soil_sand, soil_clay, mksoiltex, mksoilInit + use mksoilMod , only : soil_color, mksoilcol, mkorganic + use mksoilMod , only : soil_fmax, mkfmax + use mkvocefMod , only : mkvocef + use mkglacierregionMod , only : mkglacierregion + use mkglcmecMod , only : nglcec, mkglcmec, mkglcmecInit, mkglacier + use mkharvestMod , only : mkharvest, mkharvest_init, mkharvest_fieldname + use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride + use mkharvestMod , only : harvestDataType + use mkurbanparCommonMod, only : mkelev + use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, numurbl + use mkgdpMod , only : mkgdp + use mkpeatMod , only : mkpeat + use mksoildepthMod , only : mksoildepth + use mkagfirepkmonthMod , only : mkagfirepkmon + use mktopostatsMod , only : mktopostats + use mkVICparamsMod , only : mkVICparams +#endif + use mklanwatMod , only : mklakwat use mkutilsMod , only : normalize_classes_by_gcell, chkerr use mkfileMod , only : mkfile use mkvarpar , only : nlevsoi, elev_thresh, numstdpft use nanMod , only : nan, bigint - use mkpioMod , only : pio_iotype, pio_ioformat, io_subsystem + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem use mkpioMod , only : mkpio_put_time_slice, mkpio_iodesc_output use mkvarctl @@ -203,7 +204,8 @@ program mksurfdata real(r8), pointer :: lakedepth(:) ! lake depth (m) integer , pointer :: harvind1D(:) ! Indices of 1D harvest fields integer , pointer :: harvind2D(:) ! Indices of 2D harvest fields - logical :: zero_out ! if should zero glacier out + logical :: zero_out_lake ! if should zero glacier out + logical :: zero_out_wetland ! if should zero glacier out #ifdef TODO type(harvestDataType) :: harvdata #endif @@ -213,6 +215,7 @@ program mksurfdata type(ESMF_LogKind_Flag) :: logkindflag type(ESMF_VM) :: vm character(len=CS) :: varname + logical :: create_esmf_pet_files = .true. character(len=32) :: subname = 'mksrfdata' ! program name ! NOTE(bja, 2015-01) added to work around a ?bug? causing 1x1_urbanc_alpha to abort. See @@ -230,31 +233,6 @@ program mksurfdata call MPI_init(rc) mpicom = mpi_comm_world - ! ------------------ - ! Initialize PIO - ! ------------------ - - ! First phase - reads the pio default settings from file pio_in, namelist pio_default_inparm - ! It then returns the new compute comm in Global_Comm and sets module variable io_comm. - call shr_pio_init1("pio_in", mpicom) - - ! Determine my rank - call mpi_comm_rank(mpicom, iam, ier) - - ! Initialize PIO - second phase - call shr_pio_init2((/mpicom/), (/mpicom/)) - io_subsystem => shr_pio_getiosys() - pio_iotype = shr_pio_getiotype() - pio_ioformat = shr_pio_getioformat() - - ! ------------------ - ! Read input namelist on root_task and broadcast to all pes - ! ------------------ - - ! root_task is a module variable in mkvarctl - root_task = (iam == 0) - call read_namelist_input() - ! ------------------ ! Initialize ESMF and get mpicom from ESMF ! ------------------ @@ -269,54 +247,76 @@ program mksurfdata if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_VMGetGlobal(vm, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_VMGet(vm, mpicommunicator=mpicom, rc=rc) + call ESMF_VMGet(vm, mpicommunicator=mpicom, localPet=iam, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_LogSet(flush=.true.) call ESMF_LogWrite("mksurfdata starting", ESMF_LOGMSG_INFO) + ! ------------------ + ! Initialize PIO - first phase + ! ------------------ + + ! the following returns pio_iosystem + ! call pio_init(iam, mpicom, 1, 0, 36, PIO_REARR_SUBSET, pio_iosystem) + ! TODO: generalize iotype + + call pio_init(comp_rank=iam, & + comp_comm=mpicom, & + num_iotasks = 8, & + num_aggregator = 0, & + stride = 36, & + rearr = PIO_REARR_SUBSET, & + iosystem = pio_iosystem) + + pio_iotype = PIO_IOTYPE_PNETCDF + pio_ioformat = PIO_64BIT_DATA + + call ESMF_LogWrite("finished initializing PIO", ESMF_LOGMSG_INFO) + + ! ------------------ + ! Read input namelist on root_task and broadcast to all pes + ! ------------------ + + ! root_task is a module variable in mkvarctl + root_task = (iam == 0) + call read_namelist_input() + ! ------------------ ! open output ndiag file ! ------------------ if (fsurlog == ' ') then call shr_sys_abort(' ERROR: must specify fsurlog in namelist') - else + end if + if (root_task) then open (newunit=ndiag, file=trim(fsurlog), iostat=ier) if (ier /= 0) then call shr_sys_abort(' failed to open ndiag file '//trim(fsurlog)) - else - if (root_task) then - write(ndiag,*)' successfully opened ndiag file ',trim(fsurlog) - end if end if - end if - - ! ------------------ - ! ------------------ - - if (root_task) then write (ndiag,*) 'Attempting to create surface boundary data .....' write (ndiag,'(72a1)') ("-",n=1,60) + else + ndiag = 6 end if - call check_namelist_input() - ! ------------------ ! Write out namelist input to ndiag ! ------------------ + call check_namelist_input() call write_namelist_input() ! ---------------------------------------------------------------------- ! Call module initialization routines ! ---------------------------------------------------------------------- - ! call mksoilInit( ) - ! call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) - ! allocate ( elevclass(nglcec+1) ) - ! call mkglcmecInit (elevclass) - ! call mkurbanInit (mksrf_furban) - +#ifdef TODO + call mksoilInit( ) + call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) + allocate ( elevclass(nglcec+1) ) + call mkglcmecInit (elevclass) + call mkurbanInit (mksrf_furban) +#endif ! ---------------------------------------------------------------------- ! Allocate and initialize dynamic memory for local variables ! ---------------------------------------------------------------------- @@ -380,17 +380,12 @@ program mksurfdata ! end if ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] - zero_out = all_urban .or. all_veg - call mklakwat(mksrf_flakwat, mksrf_flakwat_mesh, mesh_model, zero_out, pctlak, rc) + zero_out_lake = all_urban .or. all_veg + zero_out_wetland = all_urban .or. all_veg .or. no_inlandwet + call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & + zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') - zero_out = all_urban .or. all_veg .or. no_inlandwet - call mkwetlnd(mksrf_flakwat, mksrf_flakwat_mesh, mesh_model, zero_out, pctwet, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkwetlnd') - - call mklakparams(mksrf_flakwat, mksrf_flakwat_mesh, mesh_model, lakedepth, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkwetlnd') - ! ! Make glacier fraction [pctgla] from [fglacier] dataset ! call mkglacier ( mapfname=map_fglacier, datfname=mksrf_fglacier, ndiag=ndiag, zero_out=all_urban.or.all_veg, glac_o=pctgla) @@ -481,6 +476,7 @@ program mksurfdata ! Modify interpolated fields based on additional constrants ! ---------------------------------------------------------------------- +#ifdef TODO do n = 1,lsize_o ! Truncate all percentage fields on output grid. This is needed to ! insure that wt is zero (not a very small number such as @@ -533,69 +529,69 @@ program mksurfdata pcturb(n) = pcturb(n) * 100._r8/suma pctgla(n) = pctgla(n) * 100._r8/suma end if - end do - ! call normalizencheck_landuse() - - ! Write out sum of PFT's - - ! do k = natpft_lb,natpft_ub - ! suma = 0._r8 - ! do n = 1,lsize_o - ! suma = suma + pctnatpft(n)%get_one_pct_p2g(k) - ! enddo - ! write(6,*) 'sum over domain of pft ',k,suma - ! enddo - ! write(6,*) - - ! do k = cft_lb,cft_ub - ! suma = 0._r8 - ! do n = 1,lsize_o - ! suma = suma + pctcft(n)%get_one_pct_p2g(k) - ! enddo - ! write(6,*) 'sum over domain of cft ',k,suma - ! enddo - ! write(6,*) - - ! ! Make final values of percent urban by class - ! ! This call needs to occur after all corrections are made to pcturb - - ! call normalize_classes_by_gcell(urbn_classes, pcturb, urbn_classes_g) - - ! ! Make glacier multiple elevation classes [pctglcmec,topoglcmec] from [fglacier] dataset - ! ! This call needs to occur after pctgla has been adjusted for the final time - - ! allocate (pctglcmec(lsize_o,nglcec), & - ! topoglcmec(lsize_o,nglcec) ) - ! if ( outnc_3dglc )then - ! allocate( & - ! pctglcmec_gic(lsize_o,nglcec), & - ! pctglcmec_icesheet(lsize_o,nglcec)) - ! allocate (pctglc_gic(lsize_o)) - ! allocate (pctglc_icesheet(lsize_o)) - ! end if + call normalizencheck_landuse() + + !Write out sum of PFT's + + do k = natpft_lb,natpft_ub + suma = 0._r8 + do n = 1,lsize_o + suma = suma + pctnatpft(n)%get_one_pct_p2g(k) + enddo + write(6,*) 'sum over domain of pft ',k,suma + enddo + write(6,*) + + do k = cft_lb,cft_ub + suma = 0._r8 + do n = 1,lsize_o + suma = suma + pctcft(n)%get_one_pct_p2g(k) + enddo + write(6,*) 'sum over domain of cft ',k,suma + enddo + write(6,*) + + ! Make final values of percent urban by class + ! This call needs to occur after all corrections are made to pcturb + + call normalize_classes_by_gcell(urbn_classes, pcturb, urbn_classes_g) + + ! Make glacier multiple elevation classes [pctglcmec,topoglcmec] from [fglacier] dataset + ! This call needs to occur after pctgla has been adjusted for the final time + + allocate (pctglcmec(lsize_o,nglcec), & + topoglcmec(lsize_o,nglcec) ) + if ( outnc_3dglc )then + allocate( & + pctglcmec_gic(lsize_o,nglcec), & + pctglcmec_icesheet(lsize_o,nglcec)) + allocate (pctglc_gic(lsize_o)) + allocate (pctglc_icesheet(lsize_o)) + end if - ! pctglcmec(:,:) = spval - ! topoglcmec(:,:) = spval + pctglcmec(:,:) = spval + topoglcmec(:,:) = spval - ! if ( outnc_3dglc )then - ! call mkglcmec ( mapfname=map_fglacier, & - ! datfname_fglacier=mksrf_fglacier, ndiag=ndiag, & - ! pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, & - ! pctglcmec_gic_o=pctglcmec_gic, pctglcmec_icesheet_o=pctglcmec_icesheet, & - ! pctglc_gic_o=pctglc_gic, pctglc_icesheet_o=pctglc_icesheet) - ! else - ! call mkglcmec ( mapfname=map_fglacier, & - ! datfname_fglacier=mksrf_fglacier, ndiag=ndiag, & - ! pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec ) - ! end if + if ( outnc_3dglc )then + call mkglcmec ( mapfname=map_fglacier, & + datfname_fglacier=mksrf_fglacier, ndiag=ndiag, & + pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, & + pctglcmec_gic_o=pctglcmec_gic, pctglcmec_icesheet_o=pctglcmec_icesheet, & + pctglc_gic_o=pctglc_gic, pctglc_icesheet_o=pctglc_icesheet) + else + call mkglcmec ( mapfname=map_fglacier, & + datfname_fglacier=mksrf_fglacier, ndiag=ndiag, & + pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec ) + end if - ! ! Determine fractional land from pft dataset + ! Determine fractional land from pft dataset - ! do n = 1,lsize_o - ! landfrac_pft(n) = pctlnd_pft(n)/100._r8 - ! end do + do n = 1,lsize_o + landfrac_pft(n) = pctlnd_pft(n)/100._r8 + end do +#endif ! ---------------------------------------------------------------------- ! Create surface dataset @@ -615,6 +611,7 @@ program mksurfdata if (fsurdat /= ' ') then +#ifdef TODO ! The following variables need to be output as int ! nf_put_var_int(ncid, varid, (/(n,n=natpft_lb,natpft_ub)/)) ! nf_put_var_int(ncid, varid, (/(n,n=cft_lb,cft_ub)/)) @@ -624,10 +621,12 @@ program mksurfdata ! nf_put_var_int(ncid, varid, glacier_region) ! nf_put_var_int(ncid, varid, agfirepkmon) ! nf_put_var_int(ncid, varid, urban_region) +#endif !call mkfile( vm, nx, ny, trim(fsurdat), harvdata, dynlanduse = .false., pioid=pioid) call mkfile( vm, mksrf_fgrid_mesh_nx, mksrf_fgrid_mesh_ny, trim(fsurdat), dynlanduse=.false., pioid=pioid) +#ifdef TODO ! write area, longxy and latixy ! TODO: fill this in ! call check_ret(nf_open(trim(fname), nf_write, ncid), subname) @@ -690,6 +689,7 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) call pio_write_darray(pioid, pio_varid, pio_iodesc, pctclay, rcode) call pio_freedecomp(pioid, pio_iodesc) +#endif varname = 'PCT_WETLAND' call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) @@ -703,6 +703,7 @@ program mksurfdata call pio_write_darray(pioid, pio_varid, pio_iodesc, pctlak, rcode) call pio_freedecomp(pioid, pio_iodesc) +#ifdef TODO varname = 'PCT_GLACIER' call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) @@ -846,9 +847,9 @@ program mksurfdata ! write(6,*)'calling mklai' ! call mklai( mapfname=map_flai, datfname=mksrf_flai, ndiag=ndiag, pioido=pioid ) +#endif ! Close surface dataset - call pio_closefile(pioid) write (6,'(72a1)') ("-",n=1,60) diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index 7e102d9bcf..01583af1b6 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -1,183 +1,180 @@ module mktopostatsMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mktopostatsMod -! -! !DESCRIPTION: -! make various topography statistics -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -!----------------------------------------------------------------------- -! -! !USES: + !----------------------------------------------------------------------- + !BOP + ! + ! !MODULE: mktopostatsMod + ! + ! !DESCRIPTION: + ! make various topography statistics + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! + !----------------------------------------------------------------------- + ! + ! !USES: use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush use mkdomainMod , only : domain_checksame implicit none private -! !PUBLIC MEMBER FUNCTIONS: + ! !PUBLIC MEMBER FUNCTIONS: public mktopostats ! make topo stddev & mean slope -! -!EOP -!=============================================================== + ! + !EOP + !=============================================================== contains -!=============================================================== - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mktopostats -! -! !INTERFACE: -subroutine mktopostats(ldomain, mapfname, datfname, ndiag, topo_stddev_o, slope_o, std_elev) -! -! !DESCRIPTION: -! make various topography statistics -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_continuous, output_diagnostics_continuous_outonly - use mkchecksMod, only : min_bad, max_bad -! -! !ARGUMENTS: - - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(in) :: std_elev ! standard deviation of elevation (m) to use when not using input file - real(r8) , intent(out):: topo_stddev_o(:) ! output grid: standard deviation of elevation (m) - real(r8) , intent(out):: slope_o(:) ! output grid: slope (degrees) -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: data_i(:) ! data on input grid - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - logical :: bypass_reading ! If should bypass reading dataset and just use a global value - - real(r8), parameter :: min_valid_topo_stddev = 0._r8 - - real(r8), parameter :: min_valid_slope = 0._r8 - real(r8), parameter :: max_valid_slope = 90._r8 - - character(len=32) :: subname = 'mktopostats' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make Topography statistics.....' - if ( std_elev >= 0.0_r8 )then - bypass_reading = .true. - write (6,*) ' By pass the reading and just use global values' - else - bypass_reading = .false. - end if - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - if ( .not. bypass_reading )then - call domain_read(tdomain,datfname) - - call gridmap_mapread(tgridmap, mapfname ) - - call gridmap_check( tgridmap, tgridmap%frac_src, tgridmap%frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write(6,*)'Open Topography file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(data_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() - - ! ----------------------------------------------------------------- - ! Make topography standard deviation - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'ELEVATION', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areastddev(tgridmap, data_i, topo_stddev_o, nodata=0._r8) - - call output_diagnostics_continuous_outonly(topo_stddev_o, tgridmap, "Topo Std Dev", "m", ndiag) - else - write (6,*) ' Set std deviation of topography to ', std_elev - topo_stddev_o = std_elev - end if - - ! Check validity of output data - if (min_bad(topo_stddev_o, min_valid_topo_stddev, 'topo_stddev')) then - call abort() - end if - - - ! ----------------------------------------------------------------- - ! Regrid slope - ! ----------------------------------------------------------------- - - if ( .not. bypass_reading )then - call check_ret(nf_inq_varid (ncid, 'SLOPE', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - - ! Subr. gridmap_areaave_no_srcmask should NOT be used in general. We have - ! kept it to support the rare raw data files for which we have masking on - ! the mapping file and, therefore, we do not explicitly pass the src_mask - ! as an argument. In general, users are advised to use subroutine - ! gridmap_areaave_srcmask. - call gridmap_areaave_no_srcmask(tgridmap, data_i, slope_o, nodata=0._r8) - - call output_diagnostics_continuous(data_i, slope_o, tgridmap, "Slope", "degrees", ndiag, tdomain%mask, tgridmap%frac_dst) - else - write (6,*) ' Set slope of topography to ', 0.0_r8 - slope_o = 0.0_r8 - end if - ! Check validity of output data - if (min_bad(slope_o, min_valid_slope, 'slope') .or. & - max_bad(slope_o, max_valid_slope, 'slope')) then - call abort() - end if - - - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- - - if ( .not. bypass_reading )then - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (data_i) - end if - - write (6,*) 'Successfully made Topography statistics' - write (6,*) - call shr_sys_flush(6) - -end subroutine mktopostats + !=============================================================== + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mktopostats + ! + ! !INTERFACE: + subroutine mktopostats(ldomain, mapfname, datfname, ndiag, topo_stddev_o, slope_o, std_elev) + ! + ! !DESCRIPTION: + ! make various topography statistics + ! + ! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkncdio + use mkdiagnosticsMod, only : output_diagnostics_continuous, output_diagnostics_continuous_outonly + use mkchecksMod, only : min_bad, max_bad + ! + ! !ARGUMENTS: + + implicit none + type(domain_type) , intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(in) :: std_elev ! standard deviation of elevation (m) to use when not using input file + real(r8) , intent(out):: topo_stddev_o(:) ! output grid: standard deviation of elevation (m) + real(r8) , intent(out):: slope_o(:) ! output grid: slope (degrees) + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! + ! + ! !LOCAL VARIABLES: + !EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: data_i(:) ! data on input grid + integer :: ncid,varid ! input netCDF id's + integer :: ier ! error status + logical :: bypass_reading ! If should bypass reading dataset and just use a global value + + real(r8), parameter :: min_valid_topo_stddev = 0._r8 + + real(r8), parameter :: min_valid_slope = 0._r8 + real(r8), parameter :: max_valid_slope = 90._r8 + + character(len=32) :: subname = 'mktopostats' + !----------------------------------------------------------------------- + + write (6,*) 'Attempting to make Topography statistics.....' + if ( std_elev >= 0.0_r8 )then + bypass_reading = .true. + write (6,*) ' By pass the reading and just use global values' + else + bypass_reading = .false. + end if + + ! ----------------------------------------------------------------- + ! Read domain and mapping information, check for consistency + ! ----------------------------------------------------------------- + + if ( .not. bypass_reading )then + call domain_read(tdomain,datfname) + + call gridmap_mapread(tgridmap, mapfname ) + + call gridmap_check( tgridmap, tgridmap%frac_src, tgridmap%frac_dst, subname ) + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! ----------------------------------------------------------------- + ! Open input file, allocate memory for input data + ! ----------------------------------------------------------------- + + write(6,*)'Open Topography file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + + allocate(data_i(tdomain%ns), stat=ier) + if (ier/=0) call abort() + + ! ----------------------------------------------------------------- + ! Make topography standard deviation + ! ----------------------------------------------------------------- + + call check_ret(nf_inq_varid (ncid, 'ELEVATION', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + call gridmap_areastddev(tgridmap, data_i, topo_stddev_o, nodata=0._r8) + + call output_diagnostics_continuous_outonly(topo_stddev_o, tgridmap, "Topo Std Dev", "m", ndiag) + else + write (6,*) ' Set std deviation of topography to ', std_elev + topo_stddev_o = std_elev + end if + + ! Check validity of output data + if (min_bad(topo_stddev_o, min_valid_topo_stddev, 'topo_stddev')) then + call abort() + end if + + + ! ----------------------------------------------------------------- + ! Regrid slope + ! ----------------------------------------------------------------- + + if ( .not. bypass_reading )then + call check_ret(nf_inq_varid (ncid, 'SLOPE', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + + ! Subr. gridmap_areaave_no_srcmask should NOT be used in general. We have + ! kept it to support the rare raw data files for which we have masking on + ! the mapping file and, therefore, we do not explicitly pass the src_mask + ! as an argument. In general, users are advised to use subroutine + ! gridmap_areaave_srcmask. + call gridmap_areaave_no_srcmask(tgridmap, data_i, slope_o, nodata=0._r8) + + call output_diagnostics_continuous(data_i, slope_o, tgridmap, "Slope", "degrees", ndiag, tdomain%mask, tgridmap%frac_dst) + else + write (6,*) ' Set slope of topography to ', 0.0_r8 + slope_o = 0.0_r8 + end if + ! Check validity of output data + if (min_bad(slope_o, min_valid_slope, 'slope') .or. & + max_bad(slope_o, max_valid_slope, 'slope')) then + call abort() + end if + + + ! ----------------------------------------------------------------- + ! Close files and deallocate dynamic memory + ! ----------------------------------------------------------------- + + if ( .not. bypass_reading )then + call check_ret(nf_close(ncid), subname) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (data_i) + end if + + write (6,*) 'Successfully made Topography statistics' + write (6,*) + + end subroutine mktopostats end module mktopostatsMod diff --git a/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 index ab738ea03c..859ff9fe1a 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 @@ -1,365 +1,360 @@ module mkurbanparCommonMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkurbanparCommon -! -! !DESCRIPTION: -! Common routines for making urban parameter data, independent of the method used for -! making the urban parameters (e.g., averages, dominant type, etc.) -! -! (WJS 4-18-12: In the past, this contained routines shared between mkurbanparDomMod and -! mkurbanparAvgMod; now there is just a single module, mkurbanparMod, but I am keeping the -! separate mkurbanparCommonMod in case a similar split comes back in the future. However, -! if such a split seems unlikely in the future, these routines could be moved back into -! mkurbanparMod.) -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -!----------------------------------------------------------------------- -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - implicit none - - private - -! !PUBLIC MEMBER FUNCTIONS: - public :: mkurban_pct ! Make output urban %, given input urban % - public :: mkurban_pct_diagnostics ! print diagnostics related to pct urban - public :: mkelev ! Get elevation to reduce urban for high elevation areas -! -! !PUBLIC DATA MEMBERS: -! - real(r8), parameter :: MIN_DENS = 0.1_r8 ! minimum urban density (% of grid cell) - below this value, urban % is set to 0 - - public :: MIN_DENS -! -!EOP + !----------------------------------------------------------------------- + !BOP + ! + ! !MODULE: mkurbanparCommon + ! + ! !DESCRIPTION: + ! Common routines for making urban parameter data, independent of the method used for + ! making the urban parameters (e.g., averages, dominant type, etc.) + ! + ! (WJS 4-18-12: In the past, this contained routines shared between mkurbanparDomMod and + ! mkurbanparAvgMod; now there is just a single module, mkurbanparMod, but I am keeping the + ! separate mkurbanparCommonMod in case a similar split comes back in the future. However, + ! if such a split seems unlikely in the future, these routines could be moved back into + ! mkurbanparMod.) + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! + !----------------------------------------------------------------------- + ! !USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + implicit none + + private + + ! !PUBLIC MEMBER FUNCTIONS: + public :: mkurban_pct ! Make output urban %, given input urban % + public :: mkurban_pct_diagnostics ! print diagnostics related to pct urban + public :: mkelev ! Get elevation to reduce urban for high elevation areas + ! + ! !PUBLIC DATA MEMBERS: + ! + real(r8), parameter :: MIN_DENS = 0.1_r8 ! minimum urban density (% of grid cell) - below this value, urban % is set to 0 + + public :: MIN_DENS + ! + !EOP contains -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkurban_pct -! -! !INTERFACE: -subroutine mkurban_pct(ldomain, tdomain, tgridmap, urbn_i, urbn_o, frac_dst) -! -! !DESCRIPTION: -! make percent urban on output grid, given percent urban on input grid -! -! This assumes that we're neither using all_urban or zero_out -! -! -! !USES: - use mkdomainMod , only : domain_type, domain_checksame - use mkgridmapMod - use mkvarctl , only : mksrf_gridtype -! -! !ARGUMENTS: - implicit none - type(domain_type) , intent(in) :: ldomain - type(domain_type) , intent(in) :: tdomain ! local domain - type(gridmap_type), intent(in) :: tgridmap ! local gridmap - real(r8) , intent(in) :: urbn_i(:) ! input grid: percent urban - real(r8) , intent(in) :: frac_dst(:) ! output fractions - real(r8) , intent(out):: urbn_o(:) ! output grid: percent urban -! -! !REVISION HISTORY: -! Author: Bill Sacks -! (Moved from mkurbanparMod Feb, 2012) -! -! -! !LOCAL VARIABLES: -!EOP - integer :: ier ! error status - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - integer :: ni,no ! indices - real(r8) :: relerr = 0.00001_r8 ! max error: sum overlap wts ne 1 - character(len=*), parameter :: subname = 'mkurban_pct' -!----------------------------------------------------------------------- - - ! Error checks for array size consistencies - - if (size(urbn_i) /= tdomain%ns .or. & - size(urbn_o) /= ldomain%ns) then - write(6,*) subname//' ERROR: array size inconsistencies' - write(6,*) 'size(urbn_i) = ', size(urbn_i) - write(6,*) 'tdomain%ns = ', tdomain%ns - write(6,*) 'size(urbn_o) = ', size(urbn_o) - write(6,*) 'ldomain%ns = ', ldomain%ns - call abort() - end if - if (size(frac_dst) /= ldomain%ns) then - write(6,*) subname//' ERROR: array size inconsistencies' - write(6,*) 'size(frac_dst) = ', size(frac_dst) - write(6,*) 'ldomain%ns = ', ldomain%ns - call abort() - end if - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Determine urbn_o on ouput grid: - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. - - call gridmap_areaave_srcmask(tgridmap, urbn_i, urbn_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check for conservation - - do no = 1, ldomain%ns - if ((urbn_o(no)) > 100.000001_r8) then - write (6,*) 'MKURBAN error: urban = ',urbn_o(no), & - ' greater than 100.000001 for column, row = ',no - call abort() - end if - enddo - - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - - allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! (Error check2 in mkurban_pct_diagnostics, which should be called separately) - - deallocate (mask_r8) - -end subroutine mkurban_pct -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkurban_pct_diagnostics -! -! !INTERFACE: -subroutine mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, urbn_i, urbn_o, ndiag, dens_class, frac_dst) -! -! !DESCRIPTION: -! print diagnostics related to pct urban -! -! This is intended to be called after mkurban_pct, but is split out into a separate -! routine so that modifications to urbn_o can be made in between the two calls (e.g., -! setting urbn_o to 0 wherever it is less than a certain threshold; the rules for doing -! this can't always be applied inline in mkurban_pct). -! -! !USES: - use mkdomainMod , only : domain_type - use mkgridmapMod, only : gridmap_type - use mkvarpar -! -! !ARGUMENTS: - implicit none - type(domain_type) , intent(in) :: ldomain - type(domain_type) , intent(in) :: tdomain ! local domain - type(gridmap_type), intent(in) :: tgridmap ! local gridmap - real(r8) , intent(in) :: urbn_i(:) ! input grid: percent urban - real(r8) , intent(in) :: urbn_o(:) ! output grid: percent urban - real(r8) , intent(in) :: frac_dst(:) ! output fractions - integer , intent(in) :: ndiag ! unit number for diag out - - integer , intent(in), optional :: dens_class ! density class -! -! !REVISION HISTORY: -! Author: Bill Sacks -! (Moved from mkurbanparMod Feb, 2012) -! -! -! !LOCAL VARIABLES: -!EOP - real(r8) :: gurbn_i ! input grid: global urbn - real(r8) :: garea_i ! input grid: global area - real(r8) :: gurbn_o ! output grid: global urbn - real(r8) :: garea_o ! output grid: global area - integer :: ni,no,k ! indices - character(len=*), parameter :: subname = 'mkurban_pct_diagnostics' -!----------------------------------------------------------------------- - - ! Error check inputs - if (size(frac_dst) /= ldomain%ns) then - write(6,*) subname//' ERROR: array size inconsistencies' - write(6,*) 'size(frac_dst) = ', size(frac_dst) - write(6,*) 'ldomain%ns = ', ldomain%ns - call abort() - end if - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - - ! Input grid - - gurbn_i = 0._r8 - garea_i = 0._r8 - - do ni = 1, tdomain%ns - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - gurbn_i = gurbn_i + urbn_i(ni)*(tgridmap%area_src(ni)/100._r8)*& - tdomain%mask(ni)*re**2 - end do - - ! Output grid - - gurbn_o = 0._r8 - garea_o = 0._r8 - - do no = 1, ldomain%ns - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - gurbn_o = gurbn_o + urbn_o(no)* (tgridmap%area_dst(no)/100._r8)*& - frac_dst(no)*re**2 - end do - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - if (present(dens_class)) then - write (ndiag,'(1x,a,i0)') 'Urban Output -- class ', dens_class - else - write (ndiag,'(1x,a)') 'Urban Output' - end if - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mkurban_pct + ! + ! !INTERFACE: + subroutine mkurban_pct(ldomain, tdomain, tgridmap, urbn_i, urbn_o, frac_dst) + ! + ! !DESCRIPTION: + ! make percent urban on output grid, given percent urban on input grid + ! + ! This assumes that we're neither using all_urban or zero_out + ! + ! + ! !USES: + use mkdomainMod , only : domain_type, domain_checksame + use mkgridmapMod + use mkvarctl , only : mksrf_gridtype + ! + ! !ARGUMENTS: + implicit none + type(domain_type) , intent(in) :: ldomain + type(domain_type) , intent(in) :: tdomain ! local domain + type(gridmap_type), intent(in) :: tgridmap ! local gridmap + real(r8) , intent(in) :: urbn_i(:) ! input grid: percent urban + real(r8) , intent(in) :: frac_dst(:) ! output fractions + real(r8) , intent(out):: urbn_o(:) ! output grid: percent urban + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! (Moved from mkurbanparMod Feb, 2012) + ! + ! + ! !LOCAL VARIABLES: + !EOP + integer :: ier ! error status + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + integer :: ni,no ! indices + real(r8) :: relerr = 0.00001_r8 ! max error: sum overlap wts ne 1 + character(len=*), parameter :: subname = 'mkurban_pct' + !----------------------------------------------------------------------- + + ! Error checks for array size consistencies + + if (size(urbn_i) /= tdomain%ns .or. & + size(urbn_o) /= ldomain%ns) then + write(6,*) subname//' ERROR: array size inconsistencies' + write(6,*) 'size(urbn_i) = ', size(urbn_i) + write(6,*) 'tdomain%ns = ', tdomain%ns + write(6,*) 'size(urbn_o) = ', size(urbn_o) + write(6,*) 'ldomain%ns = ', ldomain%ns + call abort() + end if + if (size(frac_dst) /= ldomain%ns) then + write(6,*) subname//' ERROR: array size inconsistencies' + write(6,*) 'size(frac_dst) = ', size(frac_dst) + write(6,*) 'ldomain%ns = ', ldomain%ns + call abort() + end if + + ! Error checks for domain and map consistencies + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Determine urbn_o on ouput grid: + ! Area-average percent cover on input grid to output grid + ! and correct according to land landmask + ! Note that percent cover is in terms of total grid area. + + call gridmap_areaave_srcmask(tgridmap, urbn_i, urbn_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check for conservation + + do no = 1, ldomain%ns + if ((urbn_o(no)) > 100.000001_r8) then + write (6,*) 'MKURBAN error: urban = ',urbn_o(no), & + ' greater than 100.000001 for column, row = ',no + call abort() + end if + enddo + + ! Global sum of output field -- must multiply by fraction of + ! output grid that is land as determined by input grid + + allocate(mask_r8(tdomain%ns), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + ! (Error check2 in mkurban_pct_diagnostics, which should be called separately) + + deallocate (mask_r8) + + end subroutine mkurban_pct + !----------------------------------------------------------------------- + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mkurban_pct_diagnostics + ! + ! !INTERFACE: + subroutine mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, urbn_i, urbn_o, ndiag, dens_class, frac_dst) + ! + ! !DESCRIPTION: + ! print diagnostics related to pct urban + ! + ! This is intended to be called after mkurban_pct, but is split out into a separate + ! routine so that modifications to urbn_o can be made in between the two calls (e.g., + ! setting urbn_o to 0 wherever it is less than a certain threshold; the rules for doing + ! this can't always be applied inline in mkurban_pct). + ! + ! !USES: + use mkdomainMod , only : domain_type + use mkgridmapMod, only : gridmap_type + use mkvarpar + ! + ! !ARGUMENTS: + implicit none + type(domain_type) , intent(in) :: ldomain + type(domain_type) , intent(in) :: tdomain ! local domain + type(gridmap_type), intent(in) :: tgridmap ! local gridmap + real(r8) , intent(in) :: urbn_i(:) ! input grid: percent urban + real(r8) , intent(in) :: urbn_o(:) ! output grid: percent urban + real(r8) , intent(in) :: frac_dst(:) ! output fractions + integer , intent(in) :: ndiag ! unit number for diag out + + integer , intent(in), optional :: dens_class ! density class + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! (Moved from mkurbanparMod Feb, 2012) + ! + ! + ! !LOCAL VARIABLES: + !EOP + real(r8) :: gurbn_i ! input grid: global urbn + real(r8) :: garea_i ! input grid: global area + real(r8) :: gurbn_o ! output grid: global urbn + real(r8) :: garea_o ! output grid: global area + integer :: ni,no,k ! indices + character(len=*), parameter :: subname = 'mkurban_pct_diagnostics' + !----------------------------------------------------------------------- + + ! Error check inputs + if (size(frac_dst) /= ldomain%ns) then + write(6,*) subname//' ERROR: array size inconsistencies' + write(6,*) 'size(frac_dst) = ', size(frac_dst) + write(6,*) 'ldomain%ns = ', ldomain%ns + call abort() + end if + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global areas on input and output grids + ! ----------------------------------------------------------------- + + ! Input grid + + gurbn_i = 0._r8 + garea_i = 0._r8 + + do ni = 1, tdomain%ns + garea_i = garea_i + tgridmap%area_src(ni)*re**2 + gurbn_i = gurbn_i + urbn_i(ni)*(tgridmap%area_src(ni)/100._r8)*& + tdomain%mask(ni)*re**2 + end do + + ! Output grid + + gurbn_o = 0._r8 + garea_o = 0._r8 + + do no = 1, ldomain%ns + garea_o = garea_o + tgridmap%area_dst(no)*re**2 + gurbn_o = gurbn_o + urbn_o(no)* (tgridmap%area_dst(no)/100._r8)*& + frac_dst(no)*re**2 + end do + + ! Diagnostic output + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + if (present(dens_class)) then + write (ndiag,'(1x,a,i0)') 'Urban Output -- class ', dens_class + else + write (ndiag,'(1x,a)') 'Urban Output' + end if + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,2001) 2001 format (1x,'surface type input grid area output grid area'/ & - 1x,' 10**6 km**2 10**6 km**2 ') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2003) gurbn_i*1.e-06,gurbn_o*1.e-06 - write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 + 1x,' 10**6 km**2 10**6 km**2 ') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + write (ndiag,2003) gurbn_i*1.e-06,gurbn_o*1.e-06 + write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 2002 format (1x,'urban ',f14.3,f17.3) 2003 format (1x,'urban ',f14.3,f22.8) 2004 format (1x,'all surface ',f14.3,f17.3) -end subroutine mkurban_pct_diagnostics -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkelev -! -! !INTERFACE: -subroutine mkelev(ldomain, mapfname, datfname, varname, ndiag, elev_o) -! -! !DESCRIPTION: -! Make elevation data -! -! !USES: - use mkdomainMod , only : domain_type, domain_clean, domain_read, domain_checksame - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_continuous -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - character(len=*) , intent(in) :: varname ! topo variable name - real(r8) , intent(out):: elev_o(:) ! output elevation data -! -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Keith Oleson -! -! -! !LOCAL VARIABLES: -!EOP - type(domain_type) :: tdomain ! local domain - type(gridmap_type) :: tgridmap ! local gridmap - - real(r8), allocatable :: elev_i(:) ! canyon_height to width ratio in - real(r8), allocatable :: frac_dst(:) ! output fractions - integer :: ns_i,ns_o ! indices - integer :: k,l,n,m,ni ! indices - integer :: ncidi,dimid,varid ! input netCDF id's - integer :: ier ! error status - character(len=256) :: name ! name of attribute - character(len=256) :: unit ! units of attribute - character(len= 32) :: subname = 'mkelev' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make elevation .....' - call shr_sys_flush(6) - - ns_o = ldomain%ns - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - - ns_i = tdomain%ns - allocate(elev_i(ns_i), stat=ier) - allocate(frac_dst(ns_o), stat=ier) - if (ier /= 0) then - write(6,*)'mkelev allocation error'; call abort() - end if - - write (6,*) 'Open elevation file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncidi), subname) - call check_ret(nf_inq_varid (ncidi, trim(varname), varid), subname) - call check_ret(nf_get_var_double (ncidi, varid, elev_i), subname) - call check_ret(nf_close(ncidi), subname) - - ! Read topo elev dataset with unit mask everywhere - - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - ! Note that the topo dataset has no landmask - so a unit landmask is assumed - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine elev_o on output grid - - elev_o(:) = 0. - - call gridmap_areaave_srcmask(tgridmap, elev_i, elev_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - call output_diagnostics_continuous(elev_i, elev_o, tgridmap, "Urban elev variable", "m", ndiag, tdomain%mask, frac_dst) - - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (elev_i) - deallocate (frac_dst) - - write (6,*) 'Successfully made elevation' - write (6,*) - call shr_sys_flush(6) - -end subroutine mkelev - -!----------------------------------------------------------------------- - -end module mkurbanparCommonMod + end subroutine mkurban_pct_diagnostics + !----------------------------------------------------------------------- + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mkelev + ! + ! !INTERFACE: + subroutine mkelev(ldomain, mapfname, datfname, varname, ndiag, elev_o) + ! + ! !DESCRIPTION: + ! Make elevation data + ! + ! !USES: + use mkdomainMod , only : domain_type, domain_clean, domain_read, domain_checksame + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio + use mkdiagnosticsMod, only : output_diagnostics_continuous + ! + ! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + character(len=*) , intent(in) :: varname ! topo variable name + real(r8) , intent(out):: elev_o(:) ! output elevation data + ! + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: Keith Oleson + ! + ! + ! !LOCAL VARIABLES: + !EOP + type(domain_type) :: tdomain ! local domain + type(gridmap_type) :: tgridmap ! local gridmap + + real(r8), allocatable :: elev_i(:) ! canyon_height to width ratio in + real(r8), allocatable :: frac_dst(:) ! output fractions + integer :: ns_i,ns_o ! indices + integer :: k,l,n,m,ni ! indices + integer :: ncidi,dimid,varid ! input netCDF id's + integer :: ier ! error status + character(len=256) :: name ! name of attribute + character(len=256) :: unit ! units of attribute + character(len= 32) :: subname = 'mkelev' + !----------------------------------------------------------------------- + + write (6,*) 'Attempting to make elevation .....' + + ns_o = ldomain%ns + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + + ns_i = tdomain%ns + allocate(elev_i(ns_i), stat=ier) + allocate(frac_dst(ns_o), stat=ier) + if (ier /= 0) then + write(6,*)'mkelev allocation error'; call abort() + end if + + write (6,*) 'Open elevation file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncidi), subname) + call check_ret(nf_inq_varid (ncidi, trim(varname), varid), subname) + call check_ret(nf_get_var_double (ncidi, varid, elev_i), subname) + call check_ret(nf_close(ncidi), subname) + + ! Read topo elev dataset with unit mask everywhere + + call gridmap_mapread(tgridmap, mapfname) + + ! Error checks for domain and map consistencies + ! Note that the topo dataset has no landmask - so a unit landmask is assumed + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Determine elev_o on output grid + + elev_o(:) = 0. + + call gridmap_areaave_srcmask(tgridmap, elev_i, elev_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + call output_diagnostics_continuous(elev_i, elev_o, tgridmap, "Urban elev variable", "m", ndiag, tdomain%mask, frac_dst) + + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (elev_i) + deallocate (frac_dst) + + write (6,*) 'Successfully made elevation' + write (6,*) + + end subroutine mkelev + + module mkurbanparCommonMod diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 49ce95dd07..09f609d041 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -1,693 +1,690 @@ module mkurbanparMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkurbanpar -! -! !DESCRIPTION: -! Make Urban Parameter data -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -!----------------------------------------------------------------------- -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - use mkvarctl, only : ispval - implicit none - - private - -! !PUBLIC MEMBER FUNCTIONS: - public :: mkurbanInit - public :: mkurban - public :: mkurbanpar - - ! The following could be private, but because there are associated test routines in a - ! separate module, it needs to be public - public :: normalize_urbn_by_tot - -! !PUBLIC DATA MEMBERS: - integer :: numurbl ! number of urban classes - integer :: nlevurb = ispval ! number of urban layers - - public :: numurbl - public :: nlevurb - -! !PRIVATE DATA MEMBERS: - ! flag to indicate nodata for index variables in output file: - integer, parameter :: index_nodata = 0 - character(len=*), parameter :: modname = 'mkurbanparMod' - - private :: index_nodata - private :: modname - -!EOP + !----------------------------------------------------------------------- + !BOP + ! + ! !MODULE: mkurbanpar + ! + ! !DESCRIPTION: + ! Make Urban Parameter data + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! + !----------------------------------------------------------------------- + ! !USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use mkvarctl, only : ispval + implicit none + + private + + ! !PUBLIC MEMBER FUNCTIONS: + public :: mkurbanInit + public :: mkurban + public :: mkurbanpar + + ! The following could be private, but because there are associated test routines in a + ! separate module, it needs to be public + public :: normalize_urbn_by_tot + + ! !PUBLIC DATA MEMBERS: + integer :: numurbl ! number of urban classes + integer :: nlevurb = ispval ! number of urban layers + + public :: numurbl + public :: nlevurb + + ! !PRIVATE DATA MEMBERS: + ! flag to indicate nodata for index variables in output file: + integer, parameter :: index_nodata = 0 + character(len=*), parameter :: modname = 'mkurbanparMod' + + private :: index_nodata + private :: modname + + !EOP contains -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkurbanInit -! -! !INTERFACE: -subroutine mkurbanInit(datfname) -! -! !DESCRIPTION: -! Initialize variables needed for urban -! -! !USES: - use mkncdio -! -! !ARGUMENTS: - implicit none - character(len=*), intent(in) :: datfname ! input data file name (same as file used in mkurban) -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: - integer :: ncid,dimid ! input netCDF id's - - character(len=*), parameter :: subname = 'mkurbanInit' -!EOP -!----------------------------------------------------------------------- - - ! Set numurbl - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_dimid (ncid, 'density_class', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, numurbl), subname) - call check_ret(nf_inq_dimid (ncid, 'nlevurb', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, nlevurb), subname) - call check_ret(nf_close(ncid), subname) - -end subroutine mkurbanInit -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkurban -! -! !INTERFACE: -subroutine mkurban(ldomain, mapfname, datfname, ndiag, zero_out, & - urbn_o, urbn_classes_o, region_o) -! -! !DESCRIPTION: -! make total percent urban, breakdown into urban classes, and region ID on the output grid -! -! urbn_classes_o(n, i) gives the percent of the urban area in grid cell n that is in class #i. -! This is normalized so that sum(urbn_classes_o(n,:)) = 100 for all n, even for grid -! cells where urbn_o(n) = 0 (in the case where urbn_o(n) = 0, we come up with an -! arbitrary assignment of urban into the different classes). -! -! See comments under the normalize_urbn_by_tot subroutine for how urbn_classes_o is -! determined when the total % urban is 0, according to the input data. Note that this -! also applies when all_urban=.true., for points that have 0 urban according to the input -! data. -! -! TODO (WJS 6-12-14): I think this could be rewritten slightly to take advantage of the -! new mkpctPftTypeMod (which should then be renamed to something more general; or maybe -! better, in terms of maintaining helpful abstractions, there could be a new type to -! handle urban, and both that and pct_pft_type could be build on a single set of shared -! code - either as a single base class or through a "has-a" mechanism). This would allow -! us to combine urbn_o and urbn_classes_o into a single derived type variable. I think -! this would also replace the use of normalize_classes_by_gcell, and maybe some other -! urban-specific code. -! -! !USES: - use mkdomainMod , only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkindexmapMod, only : get_dominant_indices - use mkurbanparCommonMod, only : mkurban_pct, mkurban_pct_diagnostics, MIN_DENS - use mkutilsMod , only : normalize_classes_by_gcell - use mkvarctl , only : all_urban - use mkvarpar - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_index -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - logical , intent(in) :: zero_out ! if should zero urban out - real(r8) , intent(out):: urbn_o(:) ! output grid: total % urban - real(r8) , intent(out):: urbn_classes_o(:,:) ! output grid: breakdown of total urban into each class - ! (dimensions: (ldomain%ns, numurbl)) - integer , intent(out):: region_o(:) ! output grid: region ID -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - type(domain_type) :: tdomain ! local domain - type(gridmap_type) :: tgridmap ! local gridmap - real(r8), allocatable :: urbn_classes_gcell_i(:,:) ! input grid: percent urban in each density class - ! (% of total grid cell area) - real(r8), allocatable :: urbn_classes_gcell_o(:,:) ! output grid: percent urban in each density class - real(r8), allocatable :: frac_dst(:) ! output fractions - ! (% of total grid cell area) - integer , allocatable :: region_i(:) ! input grid: region ID - integer :: ni,no,ns,k ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: dimlen ! netCDF dimension length - integer :: max_region ! maximum region index - integer :: ier ! error status - - character(len=*), parameter :: subname = 'mkurban' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make %urban .....' - - ! Obtain input grid info, read local fields - - call gridmap_mapread(tgridmap, mapfname) - call domain_read(tdomain, datfname) - - ns = tdomain%ns - - allocate(urbn_classes_gcell_i(ns, numurbl), & - urbn_classes_gcell_o(ldomain%ns, numurbl), & - frac_dst(ldomain%ns), & - stat=ier) - if (ier/=0) call abort() - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - write (6,*) 'Open urban file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_URBAN', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, urbn_classes_gcell_i), subname) - - ! Determine % urban by density class on the output grid - do k = 1, numurbl - call mkurban_pct(ldomain, tdomain, tgridmap, urbn_classes_gcell_i(:,k), urbn_classes_gcell_o(:,k), frac_dst) - end do - - ! Determine total % urban - do no = 1, ldomain%ns - urbn_o(no) = sum(urbn_classes_gcell_o(no,:)) - end do - - call normalize_urbn_by_tot(urbn_classes_gcell_o, urbn_o, urbn_classes_o) - - ! Handle special cases - - ! Note that, for all these adjustments of total urban %, we do not change anything - ! about the breakdown into the different urban classes. In particular: when urbn_o is - ! set to 0 for a point, the breakdown into the different urban classes is maintained - ! as it was before. - if (all_urban) then - urbn_o(:) = 100._r8 - else if (zero_out) then - urbn_o(:) = 0._r8 - else - ! Set points to 0% if they fall below a given threshold - do no = 1, ldomain%ns - if (urbn_o(no) < MIN_DENS) then - urbn_o(no) = 0._r8 - end if - end do - end if - - ! Print diagnostics - ! First, recompute urbn_classes_gcell_o, based on any changes we have made to urbn_o - ! while handling special cases - call normalize_classes_by_gcell(urbn_classes_o, urbn_o, urbn_classes_gcell_o) - do k = 1, numurbl - call mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, & - urbn_classes_gcell_i(:,k), urbn_classes_gcell_o(:,k), & - ndiag, dens_class=k, frac_dst=frac_dst) - end do - - write (6,*) 'Successfully made %urban' - - - write(6,*) 'Attempting to make urban region .....' - - ! Read in region field - ! Note: we do this here, rather than with the rest of the reads above, because we - ! expect the input urban fields to be large, so we're just reading the fields as - ! they're needed to try to avoid unnecessary memory paging - - allocate(region_i(ns), stat=ier) - if (ier/=0) call abort() - call check_ret(nf_inq_varid (ncid, 'REGION_ID', varid), subname) - call check_ret(nf_get_var_int (ncid, varid, region_i), subname) - - ! Determine max region value, and make sure it doesn't exceed bounds of the lookup tables. - ! - ! (Note: this check assumes that region_i=1 refers to region(1), region_i=2 refers to - ! region(2), etc. The alternative would be to use a coordinate variable associated with - ! the region dimension of the lookup table, which could result in an arbitrary mapping - ! between region values and the indices of the lookup table; however, this use of - ! coordinate variables currently isn't supported by lookup_2d_netcdf [as of 2-8-12].) - - max_region = maxval(region_i) - call check_ret(nf_inq_dimid (ncid, 'region', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, dimlen), subname) - if (max_region > dimlen) then - write(6,*) modname//':'//subname// & - ' ERROR: max region value exceeds length of region dimension' - write(6,*) 'max region value : ', max_region - write(6,*) 'length of region dimension: ', dimlen - call abort() - end if - - ! Determine dominant region for each output cell - - call get_dominant_indices(tgridmap, region_i, region_o, 1, max_region, index_nodata, mask_src=tdomain%mask) - - write (6,*) 'Successfully made urban region' - write (6,*) - - ! Output diagnostics - - call output_diagnostics_index(region_i, region_o, tgridmap, 'Urban Region ID', & - 1, max_region, ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Deallocate dynamic memory & other clean up - - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (urbn_classes_gcell_i, urbn_classes_gcell_o, region_i, frac_dst) - -end subroutine mkurban -!----------------------------------------------------------------------- - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: normalize_urbn_by_tot -! -! !INTERFACE: -subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) -! -! !DESCRIPTION: -! Normalizes urban class areas to produce % cover of each class, as % of total urban area -! -! Specifically: Given (1) an array specifying the % cover of each urban class, as a % of -! the total grid cell area ('classes_pct_gcell'), and (2) a vector giving the total urban -! area in each grid cell, expressed as % of the grid cell area: Returns an array -! ('classes_pct_tot') of the same dimensionality as classes_pct_gcell, where the values -! now give % cover of each class as a % of the total urban area. -! -! Assumes that sums(n) = sum(classes_pct_gcell(n,:)) -! -! When sums(n) = 0, the creation of classes_pct_tot(n,:) is ambiguous. Here we use the -! rule that all area is assigned to the medium-density class, defined by parameter MD. -! -! The returned array satisfies sum(classes_pct_tot(n,:))==100 for all n (within rounding error) -! -! !USES: -! -! !ARGUMENTS: - implicit none - real(r8), intent(in) :: classes_pct_gcell(:,:) ! % cover of classes as % of grid cell - real(r8), intent(in) :: sums(:) ! totals, as % of grid cell - real(r8), intent(out):: classes_pct_tot(:,:) ! % cover of classes as % of total -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - integer :: n ! index - integer :: n_max ! number of points - integer :: nclasses ! number of classes - real(r8) :: suma ! sum for error check - - ! index of medium-density class, which is where we assign urban areas when the total - ! urban area is 0 - integer, parameter :: MD = 3 - - ! relative error tolerance for error check - real(r8), parameter :: relerr = 1.e-10_r8 - - character(len=*), parameter :: subname = 'normalize_urbn_by_tot' -!----------------------------------------------------------------------- - - ! Error-check inputs - - n_max = size(sums) - if (size(classes_pct_tot, 1) /= n_max .or. & - size(classes_pct_gcell, 1) /= n_max) then - write(6,*) subname//' ERROR: array size mismatch' - write(6,*) 'size(sums) = ', n_max - write(6,*) 'size(classes_pct_tot, 1) = ', size(classes_pct_tot, 1) - write(6,*) 'size(classes_pct_gcell, 1) = ', size(classes_pct_gcell, 1) - call abort() - end if - - if (size(classes_pct_tot, 2) /= size(classes_pct_gcell, 2)) then - write(6,*) subname//' ERROR: array size mismatch' - write(6,*) 'size(classes_pct_tot, 2) = ', size(classes_pct_tot, 2) - write(6,*) 'size(classes_pct_gcell, 2) = ', size(classes_pct_gcell, 2) - call abort() - end if - - nclasses = size(classes_pct_gcell, 2) - if (MD > nclasses) then - write(6,*) subname//' ERROR: MD exceeds nclasses' - write(6,*) 'MD = ', MD - write(6,*) 'nclasses = ', nclasses - call abort() - end if - - ! Do the work - - do n = 1, n_max - if (sums(n) > 0._r8) then - classes_pct_tot(n,:) = classes_pct_gcell(n,:)/sums(n) * 100._r8 - else - ! Creation of classes_pct_tot is ambiguous. Apply the rule that all area is - ! assigned to the medium-density class. - classes_pct_tot(n,:) = 0._r8 - classes_pct_tot(n,MD) = 100._r8 - end if - end do - - ! Error-check output: Make sure sum(classes_pct_tot(n,:)) = 100 for all n - - do n = 1, n_max - suma = sum(classes_pct_tot(n,:)) - if (abs(suma/100._r8 - 1._r8) > relerr) then - write(6,*) subname//' ERROR: sum does not equal 100 at point ', n - write(6,*) 'suma = ', suma - call abort() - end if - end do - -end subroutine normalize_urbn_by_tot -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkurbanpar -! -! !INTERFACE: -subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_skip_abort_on_invalid_data_check) -! -! !DESCRIPTION: -! Make Urban Parameter data -! -! Note that, in a grid cell with region_o==r, parameter values are filled from region r -! for ALL density classes. Thus, the parameter variables have a numurbl dimension along -! with their other dimensions. -! -! Note that we will have a 'nodata' value (given by the fill_val value associated with -! each parameter) wherever (1) we have a nodata value for region_o, or (2) the parameter -! has nodata for the given region/density combination in the input lookup table. -! -! !USES: - use mkdomainMod , only : domain_type, domain_clean, domain_read - use mkindexmapMod, only : dim_slice_type, lookup_2d_netcdf - use mkvarpar - use mkncdio -! -! !ARGUMENTS: - implicit none - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ncido ! output netcdf file id - integer , intent(in) :: region_o(:) ! output grid: region ID (length: ns_o) - real(r8) , intent(in) :: urbn_classes_gcell_o(:,:) ! output grid: percent urban in each density class - ! (% of total grid cell area) (dimensions: ns_o, numurbl) - logical , intent(in) :: urban_skip_abort_on_invalid_data_check - -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - ! Type to store information about each urban parameter - type param - character(len=32) :: name ! name in input & output files - real(r8) :: fill_val ! value to put where we have no data in output - logical :: check_invalid ! should we check whether there are any invalid data in the output? - end type param - - real(r8), allocatable :: data_scalar_o(:,:) ! output array for parameters with no extra dimensions - real(r8), allocatable :: data_rad_o(:,:,:,:) ! output array for parameters dimensioned by numrad & numsolar - real(r8), allocatable :: data_levurb_o(:,:,:) ! output array for parameters dimensioned by nlevurb - integer , allocatable :: unity_dens_o(:,:) ! artificial density indices - integer :: nlevurb_i ! input grid: number of urban vertical levels - integer :: numsolar_i ! input grid: number of solar type (DIR/DIF) - integer :: numrad_i ! input grid: number of solar bands (VIS/NIR) - integer :: m,n,no,ns_o,p,k ! indices - integer :: ncidi,dimid,varid ! netCDF id's - integer :: ier ! error status - character(len=nf_max_name) :: varname ! variable name - - ! information on extra dimensions for lookup tables greater than 2-d: - type(dim_slice_type), allocatable :: extra_dims(:) - - ! suffix for variables dimensioned by numsolar, for each value of numsolar: - character(len=8), parameter :: solar_suffix(numsolar) = (/'_DIR', '_DIF'/) - - ! value to put where we have no data in output variables, for real-valued parameters - real(r8), parameter :: fill_val_real = 0._r8 - - ! To add a new urban parameter, simply add an element to one of the below lists - ! (params_scalar, params_rad or params_levurb) - - ! Urban parameters with no extra dimensions - type(param), parameter :: params_scalar(13) = & - (/ param('CANYON_HWR', fill_val_real, .true.), & - param('EM_IMPROAD', fill_val_real, .true.), & - param('EM_PERROAD', fill_val_real, .true.), & - param('EM_ROOF', fill_val_real, .true.), & - param('EM_WALL', fill_val_real, .true.), & - param('HT_ROOF', fill_val_real, .true.), & - param('THICK_ROOF', fill_val_real, .true.), & - param('THICK_WALL', fill_val_real, .true.), & - param('T_BUILDING_MIN', fill_val_real, .true.), & - param('WIND_HGT_CANYON', fill_val_real, .true.), & - param('WTLUNIT_ROOF', fill_val_real, .true.), & - param('WTROAD_PERV', fill_val_real, .true.), & - - ! Note that NLEV_IMPROAD is written as an integer, meaning that type conversion occurs - ! by truncation. Thus we expect the values in the NLEV_IMPROAD lookup table to be exact; - ! e.g., if a value were 1.99999 rather than 2.0000, it would be written as 1 instead of 2 - ! Also note: we use fill_val=-1 rather than 0, because 0 appears in the lookup table - param('NLEV_IMPROAD', -1, .true.) /) - - ! Urban parameters dimensioned by numrad & numsolar - type(param), parameter :: params_rad(4) = & - (/ param('ALB_IMPROAD', fill_val_real, .true.), & - param('ALB_PERROAD', fill_val_real, .true.), & - param('ALB_ROOF', fill_val_real, .true.), & - param('ALB_WALL', fill_val_real, .true.) /) - - ! Urban parameters dimensioned by nlevurb - type(param), parameter :: params_levurb(6) = & - (/ param('TK_ROOF', fill_val_real, .true.), & - param('TK_WALL', fill_val_real, .true.), & - param('CV_ROOF', fill_val_real, .true.), & - param('CV_WALL', fill_val_real, .true.), & - - ! Impervious road thermal conductivity and heat capacity have varying levels of - ! data. Thus, we expect to find some missing values in the lookup table -- we - ! do not want to treat that as an error -- thus, we set check_invalid=.false. - param('CV_IMPROAD', fill_val_real, .false.), & - param('TK_IMPROAD', fill_val_real, .false.) /) - - - character(len=*), parameter :: subname = 'mkurbanpar' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make Urban Parameters .....' - call shr_sys_flush(6) - - ! Determine & error-check array sizes - ns_o = size(region_o) - if (size(urbn_classes_gcell_o, 1) /= ns_o) then - write(6,*) modname//':'//subname//' ERROR: array size mismatch' - write(6,*) 'size(region_o) = ', size(region_o) - write(6,*) 'size(urbn_classes_gcell_o, 1) = ', size(urbn_classes_gcell_o, 1) - call abort() - end if - if (size(urbn_classes_gcell_o, 2) /= numurbl) then - write(6,*) modname//':'//subname//' ERROR: array size mismatch' - write(6,*) 'size(urbn_classes_gcell_o, 2) = ', size(urbn_classes_gcell_o, 2) - write(6,*) 'numurbl = ', numurbl - end if - - - ! Read dimensions from input file - - write (6,*) 'Open urban parameter file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncidi), subname) - call check_ret(nf_inq_dimid(ncidi, 'nlevurb', dimid), subname) - call check_ret(nf_inq_dimlen(ncidi, dimid, nlevurb_i), subname) - call check_ret(nf_inq_dimid(ncidi, 'numsolar', dimid), subname) - call check_ret(nf_inq_dimlen(ncidi, dimid, numsolar_i), subname) - call check_ret(nf_inq_dimid(ncidi, 'numrad', dimid), subname) - call check_ret(nf_inq_dimlen(ncidi, dimid, numrad_i), subname) - - if (nlevurb_i /= nlevurb) then - write(6,*)'MKURBANPAR: parameter nlevurb= ',nlevurb, & - 'does not equal input dataset nlevurb= ',nlevurb_i - call abort() - endif - if (numsolar_i /= numsolar) then - write(6,*)'MKURBANPAR: parameter numsolar= ',numsolar, & - 'does not equal input dataset numsolar= ',numsolar_i - call abort() - endif - if (numrad_i /= numrad) then - write(6,*)'MKURBANPAR: parameter numrad= ',numrad, & - 'does not equal input dataset numrad= ',numrad_i - call abort() - endif - - ! Create an array that will hold the density indices - ! In a given grid cell, we output parameter values for all density classes, for the - ! region of that grid cell. In order to do this while still using the lookup_2d - ! routine, we create a dummy unity_dens_o array that contains the density values - ! passed to the lookup routine. - - allocate(unity_dens_o(ns_o, numurbl)) - do k = 1, numurbl - unity_dens_o(:,k) = k - end do - - ! Handle urban parameters with no extra dimensions - - allocate(data_scalar_o(ns_o, numurbl), stat=ier) - if (ier /= 0) then - write(6,*)'mkurbanpar allocation error'; call abort() - end if - - do p = 1, size(params_scalar) - call lookup_and_check_err(params_scalar(p)%name, params_scalar(p)%fill_val, & - params_scalar(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & - data_scalar_o, 0) - - call check_ret(nf_inq_varid(ncido, params_scalar(p)%name, varid), subname) - ! In the following, note that type conversion occurs if we're writing to a variable of type - ! other than double; e.g., for an integer, conversion occurs by truncation! - call check_ret(nf_put_var_double(ncido, varid, data_scalar_o), subname) - end do - - deallocate(data_scalar_o) - - ! Handle urban parameters dimensioned by numrad & numsolar - - allocate(data_rad_o(ns_o, numurbl, numrad, numsolar), stat=ier) - if (ier /= 0) then - write(6,*)'mkurbanpar allocation error'; call abort() - end if - - allocate(extra_dims(2)) - extra_dims(1)%name = 'numrad' - extra_dims(2)%name = 'numsolar' - - do p = 1, size(params_rad) - do m = 1,numsolar - extra_dims(2)%val = m - do n = 1,numrad - extra_dims(1)%val = n - - call lookup_and_check_err(params_rad(p)%name, params_rad(p)%fill_val, & - params_rad(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & - data_rad_o(:,:,n,m), & - 2, extra_dims) - end do - end do - - ! Special handling of numsolar: rather than outputting variables with a numsolar - ! dimension, we output separate variables for each value of numsolar - do m = 1,numsolar - if (len_trim(params_rad(p)%name) + len_trim(solar_suffix(m)) > len(varname)) then - write(6,*) 'variable name exceeds length of varname' - write(6,*) trim(params_rad(p)%name)//trim(solar_suffix(m)) - call abort() - end if - varname = trim(params_rad(p)%name)//trim(solar_suffix(m)) - call check_ret(nf_inq_varid(ncido, varname, varid), subname) - ! In the following, note that type conversion occurs if we're writing to a variable of type - ! other than double; e.g., for an integer, conversion occurs by truncation! - call check_ret(nf_put_var_double(ncido, varid, data_rad_o(:,:,:,m)), subname) - end do - end do - - deallocate(data_rad_o) - deallocate(extra_dims) - - ! Handle urban parameters dimensioned by nlevurb - - allocate(data_levurb_o(ns_o, numurbl, nlevurb), stat=ier) - if (ier /= 0) then - write(6,*)'mkurbanpar allocation error'; call abort() - end if - - allocate(extra_dims(1)) - extra_dims(1)%name = 'nlevurb' - - do p = 1, size(params_levurb) - do n = 1,nlevurb - extra_dims(1)%val = n - - call lookup_and_check_err(params_levurb(p)%name, params_levurb(p)%fill_val, & - params_levurb(p)%check_invalid, & - urban_skip_abort_on_invalid_data_check, data_levurb_o(:,:,n), & - 1, extra_dims) - end do - - call check_ret(nf_inq_varid(ncido, params_levurb(p)%name, varid), subname) - ! In the following, note that type conversion occurs if we're writing to a variable of type - ! other than double; e.g., for an integer, conversion occurs by truncation! - call check_ret(nf_put_var_double(ncido, varid, data_levurb_o), subname) - end do - - deallocate(data_levurb_o) - deallocate(extra_dims) - - - call check_ret(nf_close(ncidi), subname) - call check_ret(nf_sync(ncido), subname) - - write (6,*) 'Successfully made Urban Parameters' - write (6,*) - call shr_sys_flush(6) - - deallocate(unity_dens_o) - -contains -!------------------------------------------------------------------------------ - subroutine lookup_and_check_err(varname, fill_val, check_invalid, & - urban_skip_abort_on_invalid_data_check, data, n_extra_dims, extra_dims) - - ! Wrapper to lookup_2d_netcdf: Loops over each density class, calling lookup_2d_netcdf - ! with that density class and filling the appropriate slice of the data array. Also - ! checks for any errors, aborting if there were any. - ! - ! Note that the lookup_2d_netcdf routine is designed to work with a single value of - ! each of the indices. However, we want to fill parameter values for ALL density - ! classes. This is why we loop over density class in this routine. - ! - ! Note: inherits a number of variables from the parent routine + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mkurbanInit + ! + ! !INTERFACE: + subroutine mkurbanInit(datfname) + ! + ! !DESCRIPTION: + ! Initialize variables needed for urban + ! + ! !USES: + use mkncdio + ! + ! !ARGUMENTS: + implicit none + character(len=*), intent(in) :: datfname ! input data file name (same as file used in mkurban) + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! + ! + ! !LOCAL VARIABLES: + integer :: ncid,dimid ! input netCDF id's + + character(len=*), parameter :: subname = 'mkurbanInit' + !EOP + !----------------------------------------------------------------------- + + ! Set numurbl + call check_ret(nf_open(datfname, 0, ncid), subname) + call check_ret(nf_inq_dimid (ncid, 'density_class', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, numurbl), subname) + call check_ret(nf_inq_dimid (ncid, 'nlevurb', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, nlevurb), subname) + call check_ret(nf_close(ncid), subname) + + end subroutine mkurbanInit + !----------------------------------------------------------------------- + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mkurban + ! + ! !INTERFACE: + subroutine mkurban(ldomain, mapfname, datfname, ndiag, zero_out, & + urbn_o, urbn_classes_o, region_o) + ! + ! !DESCRIPTION: + ! make total percent urban, breakdown into urban classes, and region ID on the output grid + ! + ! urbn_classes_o(n, i) gives the percent of the urban area in grid cell n that is in class #i. + ! This is normalized so that sum(urbn_classes_o(n,:)) = 100 for all n, even for grid + ! cells where urbn_o(n) = 0 (in the case where urbn_o(n) = 0, we come up with an + ! arbitrary assignment of urban into the different classes). + ! + ! See comments under the normalize_urbn_by_tot subroutine for how urbn_classes_o is + ! determined when the total % urban is 0, according to the input data. Note that this + ! also applies when all_urban=.true., for points that have 0 urban according to the input + ! data. + ! + ! TODO (WJS 6-12-14): I think this could be rewritten slightly to take advantage of the + ! new mkpctPftTypeMod (which should then be renamed to something more general; or maybe + ! better, in terms of maintaining helpful abstractions, there could be a new type to + ! handle urban, and both that and pct_pft_type could be build on a single set of shared + ! code - either as a single base class or through a "has-a" mechanism). This would allow + ! us to combine urbn_o and urbn_classes_o into a single derived type variable. I think + ! this would also replace the use of normalize_classes_by_gcell, and maybe some other + ! urban-specific code. + ! + ! !USES: + use mkdomainMod , only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkindexmapMod, only : get_dominant_indices + use mkurbanparCommonMod, only : mkurban_pct, mkurban_pct_diagnostics, MIN_DENS + use mkutilsMod , only : normalize_classes_by_gcell + use mkvarctl , only : all_urban + use mkvarpar + use mkncdio + use mkdiagnosticsMod, only : output_diagnostics_index + ! + ! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + logical , intent(in) :: zero_out ! if should zero urban out + real(r8) , intent(out):: urbn_o(:) ! output grid: total % urban + real(r8) , intent(out):: urbn_classes_o(:,:) ! output grid: breakdown of total urban into each class + ! (dimensions: (ldomain%ns, numurbl)) + integer , intent(out):: region_o(:) ! output grid: region ID + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! + ! + ! !LOCAL VARIABLES: + !EOP + type(domain_type) :: tdomain ! local domain + type(gridmap_type) :: tgridmap ! local gridmap + real(r8), allocatable :: urbn_classes_gcell_i(:,:) ! input grid: percent urban in each density class + ! (% of total grid cell area) + real(r8), allocatable :: urbn_classes_gcell_o(:,:) ! output grid: percent urban in each density class + real(r8), allocatable :: frac_dst(:) ! output fractions + ! (% of total grid cell area) + integer , allocatable :: region_i(:) ! input grid: region ID + integer :: ni,no,ns,k ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: dimlen ! netCDF dimension length + integer :: max_region ! maximum region index + integer :: ier ! error status + + character(len=*), parameter :: subname = 'mkurban' + !----------------------------------------------------------------------- + + write (6,*) 'Attempting to make %urban .....' + + ! Obtain input grid info, read local fields + + call gridmap_mapread(tgridmap, mapfname) + call domain_read(tdomain, datfname) + + ns = tdomain%ns + + allocate(urbn_classes_gcell_i(ns, numurbl), & + urbn_classes_gcell_o(ldomain%ns, numurbl), & + frac_dst(ldomain%ns), & + stat=ier) + if (ier/=0) call abort() + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + write (6,*) 'Open urban file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + call check_ret(nf_inq_varid (ncid, 'PCT_URBAN', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, urbn_classes_gcell_i), subname) + + ! Determine % urban by density class on the output grid + do k = 1, numurbl + call mkurban_pct(ldomain, tdomain, tgridmap, urbn_classes_gcell_i(:,k), urbn_classes_gcell_o(:,k), frac_dst) + end do + + ! Determine total % urban + do no = 1, ldomain%ns + urbn_o(no) = sum(urbn_classes_gcell_o(no,:)) + end do + + call normalize_urbn_by_tot(urbn_classes_gcell_o, urbn_o, urbn_classes_o) + + ! Handle special cases + + ! Note that, for all these adjustments of total urban %, we do not change anything + ! about the breakdown into the different urban classes. In particular: when urbn_o is + ! set to 0 for a point, the breakdown into the different urban classes is maintained + ! as it was before. + if (all_urban) then + urbn_o(:) = 100._r8 + else if (zero_out) then + urbn_o(:) = 0._r8 + else + ! Set points to 0% if they fall below a given threshold + do no = 1, ldomain%ns + if (urbn_o(no) < MIN_DENS) then + urbn_o(no) = 0._r8 + end if + end do + end if + + ! Print diagnostics + ! First, recompute urbn_classes_gcell_o, based on any changes we have made to urbn_o + ! while handling special cases + call normalize_classes_by_gcell(urbn_classes_o, urbn_o, urbn_classes_gcell_o) + do k = 1, numurbl + call mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, & + urbn_classes_gcell_i(:,k), urbn_classes_gcell_o(:,k), & + ndiag, dens_class=k, frac_dst=frac_dst) + end do + + write (6,*) 'Successfully made %urban' + + + write(6,*) 'Attempting to make urban region .....' + + ! Read in region field + ! Note: we do this here, rather than with the rest of the reads above, because we + ! expect the input urban fields to be large, so we're just reading the fields as + ! they're needed to try to avoid unnecessary memory paging + + allocate(region_i(ns), stat=ier) + if (ier/=0) call abort() + call check_ret(nf_inq_varid (ncid, 'REGION_ID', varid), subname) + call check_ret(nf_get_var_int (ncid, varid, region_i), subname) + + ! Determine max region value, and make sure it doesn't exceed bounds of the lookup tables. + ! + ! (Note: this check assumes that region_i=1 refers to region(1), region_i=2 refers to + ! region(2), etc. The alternative would be to use a coordinate variable associated with + ! the region dimension of the lookup table, which could result in an arbitrary mapping + ! between region values and the indices of the lookup table; however, this use of + ! coordinate variables currently isn't supported by lookup_2d_netcdf [as of 2-8-12].) + + max_region = maxval(region_i) + call check_ret(nf_inq_dimid (ncid, 'region', dimid), subname) + call check_ret(nf_inq_dimlen (ncid, dimid, dimlen), subname) + if (max_region > dimlen) then + write(6,*) modname//':'//subname// & + ' ERROR: max region value exceeds length of region dimension' + write(6,*) 'max region value : ', max_region + write(6,*) 'length of region dimension: ', dimlen + call abort() + end if + + ! Determine dominant region for each output cell + + call get_dominant_indices(tgridmap, region_i, region_o, 1, max_region, index_nodata, mask_src=tdomain%mask) + + write (6,*) 'Successfully made urban region' + write (6,*) + + ! Output diagnostics + + call output_diagnostics_index(region_i, region_o, tgridmap, 'Urban Region ID', & + 1, max_region, ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Deallocate dynamic memory & other clean up + + call check_ret(nf_close(ncid), subname) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (urbn_classes_gcell_i, urbn_classes_gcell_o, region_i, frac_dst) + + end subroutine mkurban + !----------------------------------------------------------------------- + + !------------------------------------------------------------------------------ + !BOP + ! + ! !IROUTINE: normalize_urbn_by_tot + ! + ! !INTERFACE: + subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) + ! + ! !DESCRIPTION: + ! Normalizes urban class areas to produce % cover of each class, as % of total urban area + ! + ! Specifically: Given (1) an array specifying the % cover of each urban class, as a % of + ! the total grid cell area ('classes_pct_gcell'), and (2) a vector giving the total urban + ! area in each grid cell, expressed as % of the grid cell area: Returns an array + ! ('classes_pct_tot') of the same dimensionality as classes_pct_gcell, where the values + ! now give % cover of each class as a % of the total urban area. + ! + ! Assumes that sums(n) = sum(classes_pct_gcell(n,:)) + ! + ! When sums(n) = 0, the creation of classes_pct_tot(n,:) is ambiguous. Here we use the + ! rule that all area is assigned to the medium-density class, defined by parameter MD. + ! + ! The returned array satisfies sum(classes_pct_tot(n,:))==100 for all n (within rounding error) + ! + ! !USES: + ! + ! !ARGUMENTS: + implicit none + real(r8), intent(in) :: classes_pct_gcell(:,:) ! % cover of classes as % of grid cell + real(r8), intent(in) :: sums(:) ! totals, as % of grid cell + real(r8), intent(out):: classes_pct_tot(:,:) ! % cover of classes as % of total + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! + ! + ! !LOCAL VARIABLES: + !EOP + integer :: n ! index + integer :: n_max ! number of points + integer :: nclasses ! number of classes + real(r8) :: suma ! sum for error check + + ! index of medium-density class, which is where we assign urban areas when the total + ! urban area is 0 + integer, parameter :: MD = 3 + + ! relative error tolerance for error check + real(r8), parameter :: relerr = 1.e-10_r8 + + character(len=*), parameter :: subname = 'normalize_urbn_by_tot' + !----------------------------------------------------------------------- + + ! Error-check inputs + + n_max = size(sums) + if (size(classes_pct_tot, 1) /= n_max .or. & + size(classes_pct_gcell, 1) /= n_max) then + write(6,*) subname//' ERROR: array size mismatch' + write(6,*) 'size(sums) = ', n_max + write(6,*) 'size(classes_pct_tot, 1) = ', size(classes_pct_tot, 1) + write(6,*) 'size(classes_pct_gcell, 1) = ', size(classes_pct_gcell, 1) + call abort() + end if + + if (size(classes_pct_tot, 2) /= size(classes_pct_gcell, 2)) then + write(6,*) subname//' ERROR: array size mismatch' + write(6,*) 'size(classes_pct_tot, 2) = ', size(classes_pct_tot, 2) + write(6,*) 'size(classes_pct_gcell, 2) = ', size(classes_pct_gcell, 2) + call abort() + end if + + nclasses = size(classes_pct_gcell, 2) + if (MD > nclasses) then + write(6,*) subname//' ERROR: MD exceeds nclasses' + write(6,*) 'MD = ', MD + write(6,*) 'nclasses = ', nclasses + call abort() + end if + + ! Do the work + + do n = 1, n_max + if (sums(n) > 0._r8) then + classes_pct_tot(n,:) = classes_pct_gcell(n,:)/sums(n) * 100._r8 + else + ! Creation of classes_pct_tot is ambiguous. Apply the rule that all area is + ! assigned to the medium-density class. + classes_pct_tot(n,:) = 0._r8 + classes_pct_tot(n,MD) = 100._r8 + end if + end do + + ! Error-check output: Make sure sum(classes_pct_tot(n,:)) = 100 for all n + + do n = 1, n_max + suma = sum(classes_pct_tot(n,:)) + if (abs(suma/100._r8 - 1._r8) > relerr) then + write(6,*) subname//' ERROR: sum does not equal 100 at point ', n + write(6,*) 'suma = ', suma + call abort() + end if + end do + + end subroutine normalize_urbn_by_tot + !----------------------------------------------------------------------- + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mkurbanpar + ! + ! !INTERFACE: + subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_skip_abort_on_invalid_data_check) + ! + ! !DESCRIPTION: + ! Make Urban Parameter data + ! + ! Note that, in a grid cell with region_o==r, parameter values are filled from region r + ! for ALL density classes. Thus, the parameter variables have a numurbl dimension along + ! with their other dimensions. + ! + ! Note that we will have a 'nodata' value (given by the fill_val value associated with + ! each parameter) wherever (1) we have a nodata value for region_o, or (2) the parameter + ! has nodata for the given region/density combination in the input lookup table. + ! + ! !USES: + use mkdomainMod , only : domain_type, domain_clean, domain_read + use mkindexmapMod, only : dim_slice_type, lookup_2d_netcdf + use mkvarpar + use mkncdio + ! + ! !ARGUMENTS: + implicit none + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ncido ! output netcdf file id + integer , intent(in) :: region_o(:) ! output grid: region ID (length: ns_o) + real(r8) , intent(in) :: urbn_classes_gcell_o(:,:) ! output grid: percent urban in each density class + ! (% of total grid cell area) (dimensions: ns_o, numurbl) + logical , intent(in) :: urban_skip_abort_on_invalid_data_check + + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! + ! + ! !LOCAL VARIABLES: + !EOP + ! Type to store information about each urban parameter + type param + character(len=32) :: name ! name in input & output files + real(r8) :: fill_val ! value to put where we have no data in output + logical :: check_invalid ! should we check whether there are any invalid data in the output? + end type param + + real(r8), allocatable :: data_scalar_o(:,:) ! output array for parameters with no extra dimensions + real(r8), allocatable :: data_rad_o(:,:,:,:) ! output array for parameters dimensioned by numrad & numsolar + real(r8), allocatable :: data_levurb_o(:,:,:) ! output array for parameters dimensioned by nlevurb + integer , allocatable :: unity_dens_o(:,:) ! artificial density indices + integer :: nlevurb_i ! input grid: number of urban vertical levels + integer :: numsolar_i ! input grid: number of solar type (DIR/DIF) + integer :: numrad_i ! input grid: number of solar bands (VIS/NIR) + integer :: m,n,no,ns_o,p,k ! indices + integer :: ncidi,dimid,varid ! netCDF id's + integer :: ier ! error status + character(len=nf_max_name) :: varname ! variable name + + ! information on extra dimensions for lookup tables greater than 2-d: + type(dim_slice_type), allocatable :: extra_dims(:) + + ! suffix for variables dimensioned by numsolar, for each value of numsolar: + character(len=8), parameter :: solar_suffix(numsolar) = (/'_DIR', '_DIF'/) + + ! value to put where we have no data in output variables, for real-valued parameters + real(r8), parameter :: fill_val_real = 0._r8 + + ! To add a new urban parameter, simply add an element to one of the below lists + ! (params_scalar, params_rad or params_levurb) + + ! Urban parameters with no extra dimensions + type(param), parameter :: params_scalar(13) = & + (/ param('CANYON_HWR', fill_val_real, .true.), & + param('EM_IMPROAD', fill_val_real, .true.), & + param('EM_PERROAD', fill_val_real, .true.), & + param('EM_ROOF', fill_val_real, .true.), & + param('EM_WALL', fill_val_real, .true.), & + param('HT_ROOF', fill_val_real, .true.), & + param('THICK_ROOF', fill_val_real, .true.), & + param('THICK_WALL', fill_val_real, .true.), & + param('T_BUILDING_MIN', fill_val_real, .true.), & + param('WIND_HGT_CANYON', fill_val_real, .true.), & + param('WTLUNIT_ROOF', fill_val_real, .true.), & + param('WTROAD_PERV', fill_val_real, .true.), & + + ! Note that NLEV_IMPROAD is written as an integer, meaning that type conversion occurs + ! by truncation. Thus we expect the values in the NLEV_IMPROAD lookup table to be exact; + ! e.g., if a value were 1.99999 rather than 2.0000, it would be written as 1 instead of 2 + ! Also note: we use fill_val=-1 rather than 0, because 0 appears in the lookup table + param('NLEV_IMPROAD', -1, .true.) /) + + ! Urban parameters dimensioned by numrad & numsolar + type(param), parameter :: params_rad(4) = & + (/ param('ALB_IMPROAD', fill_val_real, .true.), & + param('ALB_PERROAD', fill_val_real, .true.), & + param('ALB_ROOF', fill_val_real, .true.), & + param('ALB_WALL', fill_val_real, .true.) /) + + ! Urban parameters dimensioned by nlevurb + type(param), parameter :: params_levurb(6) = & + (/ param('TK_ROOF', fill_val_real, .true.), & + param('TK_WALL', fill_val_real, .true.), & + param('CV_ROOF', fill_val_real, .true.), & + param('CV_WALL', fill_val_real, .true.), & + + ! Impervious road thermal conductivity and heat capacity have varying levels of + ! data. Thus, we expect to find some missing values in the lookup table -- we + ! do not want to treat that as an error -- thus, we set check_invalid=.false. + param('CV_IMPROAD', fill_val_real, .false.), & + param('TK_IMPROAD', fill_val_real, .false.) /) + + + character(len=*), parameter :: subname = 'mkurbanpar' + !----------------------------------------------------------------------- + + write (6,*) 'Attempting to make Urban Parameters .....' + + ! Determine & error-check array sizes + ns_o = size(region_o) + if (size(urbn_classes_gcell_o, 1) /= ns_o) then + write(6,*) modname//':'//subname//' ERROR: array size mismatch' + write(6,*) 'size(region_o) = ', size(region_o) + write(6,*) 'size(urbn_classes_gcell_o, 1) = ', size(urbn_classes_gcell_o, 1) + call abort() + end if + if (size(urbn_classes_gcell_o, 2) /= numurbl) then + write(6,*) modname//':'//subname//' ERROR: array size mismatch' + write(6,*) 'size(urbn_classes_gcell_o, 2) = ', size(urbn_classes_gcell_o, 2) + write(6,*) 'numurbl = ', numurbl + end if + + + ! Read dimensions from input file + + write (6,*) 'Open urban parameter file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncidi), subname) + call check_ret(nf_inq_dimid(ncidi, 'nlevurb', dimid), subname) + call check_ret(nf_inq_dimlen(ncidi, dimid, nlevurb_i), subname) + call check_ret(nf_inq_dimid(ncidi, 'numsolar', dimid), subname) + call check_ret(nf_inq_dimlen(ncidi, dimid, numsolar_i), subname) + call check_ret(nf_inq_dimid(ncidi, 'numrad', dimid), subname) + call check_ret(nf_inq_dimlen(ncidi, dimid, numrad_i), subname) + + if (nlevurb_i /= nlevurb) then + write(6,*)'MKURBANPAR: parameter nlevurb= ',nlevurb, & + 'does not equal input dataset nlevurb= ',nlevurb_i + call abort() + endif + if (numsolar_i /= numsolar) then + write(6,*)'MKURBANPAR: parameter numsolar= ',numsolar, & + 'does not equal input dataset numsolar= ',numsolar_i + call abort() + endif + if (numrad_i /= numrad) then + write(6,*)'MKURBANPAR: parameter numrad= ',numrad, & + 'does not equal input dataset numrad= ',numrad_i + call abort() + endif + + ! Create an array that will hold the density indices + ! In a given grid cell, we output parameter values for all density classes, for the + ! region of that grid cell. In order to do this while still using the lookup_2d + ! routine, we create a dummy unity_dens_o array that contains the density values + ! passed to the lookup routine. + + allocate(unity_dens_o(ns_o, numurbl)) + do k = 1, numurbl + unity_dens_o(:,k) = k + end do + + ! Handle urban parameters with no extra dimensions + + allocate(data_scalar_o(ns_o, numurbl), stat=ier) + if (ier /= 0) then + write(6,*)'mkurbanpar allocation error'; call abort() + end if + + do p = 1, size(params_scalar) + call lookup_and_check_err(params_scalar(p)%name, params_scalar(p)%fill_val, & + params_scalar(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & + data_scalar_o, 0) + + call check_ret(nf_inq_varid(ncido, params_scalar(p)%name, varid), subname) + ! In the following, note that type conversion occurs if we're writing to a variable of type + ! other than double; e.g., for an integer, conversion occurs by truncation! + call check_ret(nf_put_var_double(ncido, varid, data_scalar_o), subname) + end do + + deallocate(data_scalar_o) + + ! Handle urban parameters dimensioned by numrad & numsolar + + allocate(data_rad_o(ns_o, numurbl, numrad, numsolar), stat=ier) + if (ier /= 0) then + write(6,*)'mkurbanpar allocation error'; call abort() + end if + + allocate(extra_dims(2)) + extra_dims(1)%name = 'numrad' + extra_dims(2)%name = 'numsolar' + + do p = 1, size(params_rad) + do m = 1,numsolar + extra_dims(2)%val = m + do n = 1,numrad + extra_dims(1)%val = n + + call lookup_and_check_err(params_rad(p)%name, params_rad(p)%fill_val, & + params_rad(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & + data_rad_o(:,:,n,m), & + 2, extra_dims) + end do + end do + + ! Special handling of numsolar: rather than outputting variables with a numsolar + ! dimension, we output separate variables for each value of numsolar + do m = 1,numsolar + if (len_trim(params_rad(p)%name) + len_trim(solar_suffix(m)) > len(varname)) then + write(6,*) 'variable name exceeds length of varname' + write(6,*) trim(params_rad(p)%name)//trim(solar_suffix(m)) + call abort() + end if + varname = trim(params_rad(p)%name)//trim(solar_suffix(m)) + call check_ret(nf_inq_varid(ncido, varname, varid), subname) + ! In the following, note that type conversion occurs if we're writing to a variable of type + ! other than double; e.g., for an integer, conversion occurs by truncation! + call check_ret(nf_put_var_double(ncido, varid, data_rad_o(:,:,:,m)), subname) + end do + end do + + deallocate(data_rad_o) + deallocate(extra_dims) + + ! Handle urban parameters dimensioned by nlevurb + + allocate(data_levurb_o(ns_o, numurbl, nlevurb), stat=ier) + if (ier /= 0) then + write(6,*)'mkurbanpar allocation error'; call abort() + end if + + allocate(extra_dims(1)) + extra_dims(1)%name = 'nlevurb' + + do p = 1, size(params_levurb) + do n = 1,nlevurb + extra_dims(1)%val = n + + call lookup_and_check_err(params_levurb(p)%name, params_levurb(p)%fill_val, & + params_levurb(p)%check_invalid, & + urban_skip_abort_on_invalid_data_check, data_levurb_o(:,:,n), & + 1, extra_dims) + end do + + call check_ret(nf_inq_varid(ncido, params_levurb(p)%name, varid), subname) + ! In the following, note that type conversion occurs if we're writing to a variable of type + ! other than double; e.g., for an integer, conversion occurs by truncation! + call check_ret(nf_put_var_double(ncido, varid, data_levurb_o), subname) + end do + + deallocate(data_levurb_o) + deallocate(extra_dims) + + + call check_ret(nf_close(ncidi), subname) + call check_ret(nf_sync(ncido), subname) + + write (6,*) 'Successfully made Urban Parameters' + write (6,*) + + deallocate(unity_dens_o) + + contains + !------------------------------------------------------------------------------ + subroutine lookup_and_check_err(varname, fill_val, check_invalid, & + urban_skip_abort_on_invalid_data_check, data, n_extra_dims, extra_dims) + + ! Wrapper to lookup_2d_netcdf: Loops over each density class, calling lookup_2d_netcdf + ! with that density class and filling the appropriate slice of the data array. Also + ! checks for any errors, aborting if there were any. + ! + ! Note that the lookup_2d_netcdf routine is designed to work with a single value of + ! each of the indices. However, we want to fill parameter values for ALL density + ! classes. This is why we loop over density class in this routine. + ! + ! Note: inherits a number of variables from the parent routine use mkindexmapMod, only : lookup_2d_netcdf @@ -717,10 +714,10 @@ subroutine lookup_and_check_err(varname, fill_val, check_invalid, & ! some of which may have invalid entries. Because doing so disables some error ! checking, we do our own error checking after the call. call lookup_2d_netcdf(ncidi, varname, .true., & - 'density_class', 'region', n_extra_dims, & - unity_dens_o(:,k), region_o, fill_val, data(:,k), ierr, & - extra_dims=extra_dims, nodata=index_nodata, & - invalid_okay=.true.) + 'density_class', 'region', n_extra_dims, & + unity_dens_o(:,k), region_o, fill_val, data(:,k), ierr, & + extra_dims=extra_dims, nodata=index_nodata, & + invalid_okay=.true.) if (ierr /= 0) then write(6,*) modname//':'//subname//' ERROR in lookup_2d_netcdf for ', & @@ -751,9 +748,9 @@ subroutine lookup_and_check_err(varname, fill_val, check_invalid, & end do - end subroutine lookup_and_check_err + end subroutine lookup_and_check_err -end subroutine mkurbanpar -!------------------------------------------------------------------------------ + end subroutine mkurbanpar + !------------------------------------------------------------------------------ end module mkurbanparMod diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index 714b46ec76..5b966a47eb 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -5,7 +5,8 @@ module mkvarctl !----------------------------------------------------------------------- use ESMF - use shr_kind_mod, only: r8 => shr_kind_r8 + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_abort implicit none private @@ -29,7 +30,6 @@ module mkvarctl integer, public :: iam ! processor number integer, public :: npes ! number of processors integer, public :: mpicom ! communicator group - logical, public :: create_esmf_pet_files ! Values from mpif.h that will be used public :: MPI_INTEGER @@ -87,6 +87,7 @@ module mkvarctl character(len=512), public :: mksrf_fvocef = ' ' ! VOC Emission Factor data file name character(len=512), public :: mksrf_ftopostats = ' ' ! topography statistics data file name character(len=512), public :: mksrf_fvic = ' ' ! VIC parameters data file name + character(len=512), public :: mksrf_irrig = ' ' ! TODO: should this namelist be here? character(len=512), public :: mksrf_fvegtyp_mesh = ' ' ! vegetation mesh file name character(len=512), public :: mksrf_fhrvtyp_mesh = ' ' ! harvest mesh file name @@ -110,6 +111,7 @@ module mkvarctl character(len=512), public :: mksrf_fvocef_mesh = ' ' ! VOC Emission Factor mesh file name character(len=512), public :: mksrf_ftopostats_mesh = ' ' ! topography statistics mesh file name character(len=512), public :: mksrf_fvic_mesh = ' ' ! VIC parameters mesh file name + character(len=512), public :: mksrf_irrig_mesh = ' ' ! TODO: should this namelist be here? integer , public :: numpft = 16 ! number of plant types ! @@ -131,6 +133,7 @@ subroutine read_namelist_input() ! local variables integer :: ier integer :: fileunit + logical :: lexist ! ------------------------------------------------------------ namelist /mksurfdata_input/ & @@ -195,8 +198,7 @@ subroutine read_namelist_input() fdyndat, & fsurlog, & std_elev, & - urban_skip_abort_on_invalid_data_check, & - create_esmf_pet_files + urban_skip_abort_on_invalid_data_check ! Set default namelist values - make these the defaults in gen_mksurfdata_namelist.py mksrf_gridtype = 'global' @@ -214,12 +216,14 @@ subroutine read_namelist_input() end if if (root_task) then + inquire (file='mksurfdata_in', exist=lexist) + if (.not. lexist) then + call shr_sys_abort('mksurfdata_in does not exist') + end if open(newunit=fileunit, status="old", file="mksurfdata_in") read(fileunit, nml=mksurfdata_input, iostat=ier) if (ier > 0) then - call ESMF_LogWrite('error reading in mksurfdata_input namelist from mksurfdata_in', & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) - call ESMF_Finalize(endflag=ESMF_END_ABORT) + call shr_sys_abort('error reading in mksurfdata_input namelist from mksurfdata_in') end if close(fileunit) end if @@ -267,7 +271,6 @@ subroutine read_namelist_input() call mpi_bcast (mksrf_fvocef, len(mksrf_fvocef), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_ftopostats, len(mksrf_ftopostats), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fvic, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (create_esmf_pet_files, 1, MPI_LOGICAL, 0, MPICOM, ier) end subroutine read_namelist_input @@ -286,12 +289,11 @@ subroutine check_namelist_input() fgrddat = mksrf_fgrid_mesh if (root_task) write(ndiag,*)'mksrf_fgrid_mesh = ',trim(mksrf_fgrid_mesh) else - call ESMF_LogWrite(" must specify mksrf_fgrid_mesh", ESMF_LOGMSG_ERROR) - call ESMF_Finalize(endflag=ESMF_END_ABORT) + call shr_sys_abort(" must specify mksrf_fgrid_mesh") endif if (trim(mksrf_gridtype) == 'global' .or. trim(mksrf_gridtype) == 'regional') then - write(ndiag,*)'mksrf_gridtype = ',trim(mksrf_gridtype) + if (root_task) write(ndiag,*)'mksrf_gridtype = ',trim(mksrf_gridtype) else call ESMF_LogWrite(" mksrf_gridtype "//trim(mksrf_gridtype)//" is not supported", ESMF_LOGMSG_ERROR) call ESMF_Finalize(endflag=ESMF_END_ABORT) @@ -299,25 +301,25 @@ subroutine check_namelist_input() if (root_task) then if ( outnc_large_files )then - write(ndiag,'(a)')'Output file in NetCDF 64-bit large_files format' + if (root_task) write(ndiag,'(a)')'Output file in NetCDF 64-bit large_files format' end if if ( outnc_double )then - write(ndiag,'(a)')'Output ALL data in file as 64-bit' + if (root_task) write(ndiag,'(a)')'Output ALL data in file as 64-bit' end if if ( outnc_vic )then - write(ndiag,'(a)')'Output VIC fields' + if (root_task) write(ndiag,'(a)')'Output VIC fields' end if if ( outnc_3dglc )then - write(ndiag,'(a)')'Output optional 3D glacier fields (mostly used for verification of the glacier model)' + if (root_task) write(ndiag,'(a)')'Output optional 3D glacier fields (mostly used for verification of the glacier model)' end if if ( outnc_3dglc )then - write(ndiag,'(a)')'Output optional 3D glacier fields (mostly used for verification of the glacier model)' + if (root_task) write(ndiag,'(a)')'Output optional 3D glacier fields (mostly used for verification of the glacier model)' end if if ( all_urban )then - write(ndiag,'(a)') 'Output ALL data in file as 100% urban' + if (root_task) write(ndiag,'(a)') 'Output ALL data in file as 100% urban' end if if ( no_inlandwet )then - write(ndiag,'(a)') 'Set wetland to 0% over land' + if (root_task) write(ndiag,'(a)') 'Set wetland to 0% over land' end if end if @@ -365,49 +367,49 @@ subroutine write_namelist_input() ! Note - need to call this after ndiag has been set if (root_task) then - write(ndiag,*) 'PFTs from: ',trim(mksrf_fvegtyp) - write(ndiag,*) 'harvest from: ',trim(mksrf_fhrvtyp) - write(ndiag,*) 'fmax from: ',trim(mksrf_fmax) - write(ndiag,*) 'glaciers from: ',trim(mksrf_fglacier) - !write(ndiag,*) ' with: ', nglcec, ' glacier elevation classes' - write(ndiag,*) 'glacier region ID from: ',trim(mksrf_fglacierregion) - write(ndiag,*) 'urban topography from: ',trim(mksrf_furbtopo) - write(ndiag,*) 'urban from: ',trim(mksrf_furban) - write(ndiag,*) 'inland lake from: ',trim(mksrf_flakwat) - write(ndiag,*) 'inland wetland from: ',trim(mksrf_fwetlnd) - write(ndiag,*) 'soil texture from: ',trim(mksrf_fsoitex) - write(ndiag,*) 'soil organic from: ',trim(mksrf_forganic) - write(ndiag,*) 'soil color from: ',trim(mksrf_fsoicol) - write(ndiag,*) 'VOC emission factors from: ',trim(mksrf_fvocef) - write(ndiag,*) 'gdp from: ',trim(mksrf_fgdp) - write(ndiag,*) 'peat from: ',trim(mksrf_fpeat) - write(ndiag,*) 'soil depth from: ',trim(mksrf_fsoildepth) - write(ndiag,*) 'abm from: ',trim(mksrf_fabm) - write(ndiag,*) 'topography statistics from: ',trim(mksrf_ftopostats) - write(ndiag,*) 'VIC parameters from: ',trim(mksrf_fvic) - write(ndiag,*)' mesh for pft ',trim(mksrf_fvegtyp_mesh) - write(ndiag,*)' mesh for lake water ',trim(mksrf_flakwat_mesh) - write(ndiag,*)' mesh for wetland ',trim(mksrf_fwetlnd_mesh) - write(ndiag,*)' mesh for glacier ',trim(mksrf_fglacier_mesh) - write(ndiag,*)' mesh for glacier region ',trim(mksrf_fglacierregion_mesh) - write(ndiag,*)' mesh for soil texture ',trim(mksrf_fsoitex_mesh) - write(ndiag,*)' mesh for soil color ',trim(mksrf_fsoicol_mesh) - write(ndiag,*)' mesh for soil organic ',trim(mksrf_forganic_mesh) - write(ndiag,*)' mesh for urban ',trim(mksrf_furban_mesh) - write(ndiag,*)' mesh for fmax ',trim(mksrf_fmax_mesh) - write(ndiag,*)' mesh for VOC pct emis ',trim(mksrf_fvocef_mesh) - write(ndiag,*)' mesh for harvest ',trim(mksrf_fhrv_mesh) - write(ndiag,*)' mesh for lai/sai ',trim(mksrf_flai_mesh) - write(ndiag,*)' mesh for urb topography ',trim(mksrf_furbtopo_mesh) - write(ndiag,*)' mesh for GDP ',trim(mksrf_fgdp_mesh) - write(ndiag,*)' mesh for peatlands ',trim(mksrf_fpeat_mesh) - write(ndiag,*)' mesh for soil depth ',trim(mksrf_fsoildepth_mesh) - write(ndiag,*)' mesh for ag fire pk month ',trim(mksrf_fabm_mesh) - write(ndiag,*)' mesh for topography stats ',trim(mksrf_ftopostats_mesh) - write(ndiag,*)' mesh for VIC parameters ',trim(mksrf_fvic_mesh) + write(ndiag,'(a)') 'PFTs from: ',trim(mksrf_fvegtyp) + write(ndiag,'(a)') 'harvest from: ',trim(mksrf_fhrvtyp) + write(ndiag,'(a)') 'fmax from: ',trim(mksrf_fmax) + write(ndiag,'(a)') 'glaciers from: ',trim(mksrf_fglacier) + !write(ndiag,'(a)') ' with: ', nglcec, ' glacier elevation classes' + write(ndiag,'(a)') 'glacier region ID from: ',trim(mksrf_fglacierregion) + write(ndiag,'(a)') 'urban topography from: ',trim(mksrf_furbtopo) + write(ndiag,'(a)') 'urban from: ',trim(mksrf_furban) + write(ndiag,'(a)') 'inland lake from: ',trim(mksrf_flakwat) + write(ndiag,'(a)') 'inland wetland from: ',trim(mksrf_fwetlnd) + write(ndiag,'(a)') 'soil texture from: ',trim(mksrf_fsoitex) + write(ndiag,'(a)') 'soil organic from: ',trim(mksrf_forganic) + write(ndiag,'(a)') 'soil color from: ',trim(mksrf_fsoicol) + write(ndiag,'(a)') 'VOC emission factors from: ',trim(mksrf_fvocef) + write(ndiag,'(a)') 'gdp from: ',trim(mksrf_fgdp) + write(ndiag,'(a)') 'peat from: ',trim(mksrf_fpeat) + write(ndiag,'(a)') 'soil depth from: ',trim(mksrf_fsoildepth) + write(ndiag,'(a)') 'abm from: ',trim(mksrf_fabm) + write(ndiag,'(a)') 'topography statistics from: ',trim(mksrf_ftopostats) + write(ndiag,'(a)') 'VIC parameters from: ',trim(mksrf_fvic) + write(ndiag,'(a)')' mesh for pft ',trim(mksrf_fvegtyp_mesh) + write(ndiag,'(a)')' mesh for lake water ',trim(mksrf_flakwat_mesh) + write(ndiag,'(a)')' mesh for wetland ',trim(mksrf_fwetlnd_mesh) + write(ndiag,'(a)')' mesh for glacier ',trim(mksrf_fglacier_mesh) + write(ndiag,'(a)')' mesh for glacier region ',trim(mksrf_fglacierregion_mesh) + write(ndiag,'(a)')' mesh for soil texture ',trim(mksrf_fsoitex_mesh) + write(ndiag,'(a)')' mesh for soil color ',trim(mksrf_fsoicol_mesh) + write(ndiag,'(a)')' mesh for soil organic ',trim(mksrf_forganic_mesh) + write(ndiag,'(a)')' mesh for urban ',trim(mksrf_furban_mesh) + write(ndiag,'(a)')' mesh for fmax ',trim(mksrf_fmax_mesh) + write(ndiag,'(a)')' mesh for VOC pct emis ',trim(mksrf_fvocef_mesh) + write(ndiag,'(a)')' mesh for harvest ',trim(mksrf_fhrv_mesh) + write(ndiag,'(a)')' mesh for lai/sai ',trim(mksrf_flai_mesh) + write(ndiag,'(a)')' mesh for urb topography ',trim(mksrf_furbtopo_mesh) + write(ndiag,'(a)')' mesh for GDP ',trim(mksrf_fgdp_mesh) + write(ndiag,'(a)')' mesh for peatlands ',trim(mksrf_fpeat_mesh) + write(ndiag,'(a)')' mesh for soil depth ',trim(mksrf_fsoildepth_mesh) + write(ndiag,'(a)')' mesh for ag fire pk month ',trim(mksrf_fabm_mesh) + write(ndiag,'(a)')' mesh for topography stats ',trim(mksrf_ftopostats_mesh) + write(ndiag,'(a)')' mesh for VIC parameters ',trim(mksrf_fvic_mesh) if (mksrf_fdynuse /= ' ') then - write(ndiag,*)'mksrf_fdynuse = ',trim(mksrf_fdynuse) + write(ndiag,'(a)')'mksrf_fdynuse = ',trim(mksrf_fdynuse) end if end if diff --git a/tools/mksurfdata_esmf/src/mkvocefMod.F90 b/tools/mksurfdata_esmf/src/mkvocefMod.F90 index 03d9dddd3f..0d00dfca15 100644 --- a/tools/mksurfdata_esmf/src/mkvocefMod.F90 +++ b/tools/mksurfdata_esmf/src/mkvocefMod.F90 @@ -1,209 +1,204 @@ module mkvocefMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkvocMod -! -! !DESCRIPTION: -! Make VOC percentage emissions for surface dataset -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -!----------------------------------------------------------------------- -! !USES: + !----------------------------------------------------------------------- + !BOP + ! + ! !MODULE: mkvocMod + ! + ! !DESCRIPTION: + ! Make VOC percentage emissions for surface dataset + ! + ! !REVISION HISTORY: + ! Author: Erik Kluzek + ! + !----------------------------------------------------------------------- + ! !USES: use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush use mkdomainMod , only : domain_checksame implicit none private -! !PUBLIC MEMBER FUNCTIONS: + ! !PUBLIC MEMBER FUNCTIONS: public :: mkvocef ! Get the percentage emissions for VOC for different - ! land cover types -!EOP + ! land cover types + !EOP contains -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkvocef -! -! !INTERFACE: -subroutine mkvocef(ldomain, mapfname, datfname, ndiag, & - ef_btr_o, ef_fet_o, ef_fdt_o, ef_shr_o, ef_grs_o, ef_crp_o) -! -! !DESCRIPTION: -! make volatile organic coumpunds (VOC) emission factors. -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diagnostic output - real(r8) , intent(out):: ef_btr_o(:) ! output grid: EFs for broadleaf trees - real(r8) , intent(out):: ef_fet_o(:) ! output grid: EFs for fineleaf evergreen - real(r8) , intent(out):: ef_fdt_o(:) ! output grid: EFs for fineleaf deciduous - real(r8) , intent(out):: ef_shr_o(:) ! output grid: EFs for shrubs - real(r8) , intent(out):: ef_grs_o(:) ! output grid: EFs for grasses - real(r8) , intent(out):: ef_crp_o(:) ! output grid: EFs for crops -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Colette L. Heald -! 17 Jul 2007 F Vitt -- updated to pftintdat06_clm3_5_05 and corrected indexing of ef_*_i arrarys -! -!EOP -! -! !LOCAL VARIABLES: - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: ef_btr_i(:) ! input grid: EFs for broadleaf trees - real(r8), allocatable :: ef_fet_i(:) ! input grid: EFs for fineleaf evergreen - real(r8), allocatable :: ef_fdt_i(:) ! input grid: EFs for fineleaf deciduous - real(r8), allocatable :: ef_shr_i(:) ! input grid: EFs for shrubs - real(r8), allocatable :: ef_grs_i(:) ! input grid: EFs for grasses - real(r8), allocatable :: ef_crp_i(:) ! input grid: EFs for crops - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldo ! global sum of dummy input fld - real(r8) :: sum_fldi ! global sum of dummy input fld - integer :: k,n,no,ni,ns_o,ns_i ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001_r8 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mkvocef' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make VOC emission factors .....' - call shr_sys_flush(6) - - ns_o = ldomain%ns - - ! ----------------------------------------------------------------- - ! Read input Emission Factors - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - allocate(ef_btr_i(ns_i), ef_fet_i(ns_i), ef_fdt_i(ns_i), & - ef_shr_i(ns_i), ef_grs_i(ns_i), ef_crp_i(ns_i), & - frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() - - write (6,*) 'Open VOC file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'ef_btr', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_btr_i), subname) - call check_ret(nf_inq_varid (ncid, 'ef_fet', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_fet_i), subname) - call check_ret(nf_inq_varid (ncid, 'ef_fdt', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_fdt_i), subname) - call check_ret(nf_inq_varid (ncid, 'ef_shr', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_shr_i), subname) - call check_ret(nf_inq_varid (ncid, 'ef_grs', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_grs_i), subname) - call check_ret(nf_inq_varid (ncid, 'ef_crp', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_crp_i), subname) - call check_ret(nf_close(ncid), subname) - - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. - - call gridmap_mapread(tgridmap, mapfname ) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Do mapping from input to output grid - - call gridmap_areaave_srcmask(tgridmap, ef_btr_i, ef_btr_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, ef_fet_i, ef_fet_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, ef_fdt_i, ef_fdt_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, ef_shr_i, ef_shr_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, ef_grs_i, ef_grs_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, ef_crp_i, ef_crp_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check for conservation - - do no = 1, ns_o - if ( ef_btr_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF btr = ',ef_btr_o(no), & - ' is negative for no = ',no - call abort() - end if - if ( ef_fet_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF fet = ',ef_fet_o(no), & - ' is negative for no = ',no - call abort() - end if - if ( ef_fdt_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF fdt = ',ef_fdt_o(no), & - ' is negative for no = ',no - call abort() - end if - if ( ef_shr_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF shr = ',ef_shr_o(no), & - ' is negative for no = ',no - call abort() - end if - if ( ef_grs_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF grs = ',ef_grs_o(no), & - ' is negative for no = ',no - call abort() - end if - if ( ef_crp_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF crp = ',ef_crp_o(no), & - ' is negative for no = ',no - call abort() - end if - enddo - - ! ----------------------------------------------------------------- - ! Error check1 - ! Compare global sum fld_o to global sum fld_i. - ! ----------------------------------------------------------------- - - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - write (6,*) 'Successfully made VOC Emission Factors' - write (6,*) - call shr_sys_flush(6) - - ! Deallocate dynamic memory - - deallocate ( ef_btr_i, ef_fet_i, ef_fdt_i, & - ef_shr_i, ef_grs_i, ef_crp_i, frac_dst, mask_r8 ) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - -end subroutine mkvocef - -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mkvocef + ! + ! !INTERFACE: + subroutine mkvocef(ldomain, mapfname, datfname, ndiag, & + ef_btr_o, ef_fet_o, ef_fdt_o, ef_shr_o, ef_grs_o, ef_crp_o) + ! + ! !DESCRIPTION: + ! make volatile organic coumpunds (VOC) emission factors. + ! + ! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio + ! + ! !ARGUMENTS: + implicit none + type(domain_type) , intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diagnostic output + real(r8) , intent(out):: ef_btr_o(:) ! output grid: EFs for broadleaf trees + real(r8) , intent(out):: ef_fet_o(:) ! output grid: EFs for fineleaf evergreen + real(r8) , intent(out):: ef_fdt_o(:) ! output grid: EFs for fineleaf deciduous + real(r8) , intent(out):: ef_shr_o(:) ! output grid: EFs for shrubs + real(r8) , intent(out):: ef_grs_o(:) ! output grid: EFs for grasses + real(r8) , intent(out):: ef_crp_o(:) ! output grid: EFs for crops + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: Colette L. Heald + ! 17 Jul 2007 F Vitt -- updated to pftintdat06_clm3_5_05 and corrected indexing of ef_*_i arrarys + ! + !EOP + ! + ! !LOCAL VARIABLES: + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: ef_btr_i(:) ! input grid: EFs for broadleaf trees + real(r8), allocatable :: ef_fet_i(:) ! input grid: EFs for fineleaf evergreen + real(r8), allocatable :: ef_fdt_i(:) ! input grid: EFs for fineleaf deciduous + real(r8), allocatable :: ef_shr_i(:) ! input grid: EFs for shrubs + real(r8), allocatable :: ef_grs_i(:) ! input grid: EFs for grasses + real(r8), allocatable :: ef_crp_i(:) ! input grid: EFs for crops + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + real(r8) :: sum_fldo ! global sum of dummy input fld + real(r8) :: sum_fldi ! global sum of dummy input fld + integer :: k,n,no,ni,ns_o,ns_i ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ier ! error status + real(r8) :: relerr = 0.00001_r8 ! max error: sum overlap wts ne 1 + character(len=32) :: subname = 'mkvocef' + !----------------------------------------------------------------------- + + write (6,*) 'Attempting to make VOC emission factors .....' + + ns_o = ldomain%ns + + ! ----------------------------------------------------------------- + ! Read input Emission Factors + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + ns_i = tdomain%ns + allocate(ef_btr_i(ns_i), ef_fet_i(ns_i), ef_fdt_i(ns_i), & + ef_shr_i(ns_i), ef_grs_i(ns_i), ef_crp_i(ns_i), & + frac_dst(ns_o), stat=ier) + if (ier/=0) call abort() + + write (6,*) 'Open VOC file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + call check_ret(nf_inq_varid (ncid, 'ef_btr', varid), subname) + call check_ret(nf_get_var_double(ncid, varid, ef_btr_i), subname) + call check_ret(nf_inq_varid (ncid, 'ef_fet', varid), subname) + call check_ret(nf_get_var_double(ncid, varid, ef_fet_i), subname) + call check_ret(nf_inq_varid (ncid, 'ef_fdt', varid), subname) + call check_ret(nf_get_var_double(ncid, varid, ef_fdt_i), subname) + call check_ret(nf_inq_varid (ncid, 'ef_shr', varid), subname) + call check_ret(nf_get_var_double(ncid, varid, ef_shr_i), subname) + call check_ret(nf_inq_varid (ncid, 'ef_grs', varid), subname) + call check_ret(nf_get_var_double(ncid, varid, ef_grs_i), subname) + call check_ret(nf_inq_varid (ncid, 'ef_crp', varid), subname) + call check_ret(nf_get_var_double(ncid, varid, ef_crp_i), subname) + call check_ret(nf_close(ncid), subname) + + ! Area-average percent cover on input grid to output grid + ! and correct according to land landmask + ! Note that percent cover is in terms of total grid area. + + call gridmap_mapread(tgridmap, mapfname ) + + ! Error checks for domain and map consistencies + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Do mapping from input to output grid + + call gridmap_areaave_srcmask(tgridmap, ef_btr_i, ef_btr_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, ef_fet_i, ef_fet_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, ef_fdt_i, ef_fdt_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, ef_shr_i, ef_shr_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, ef_grs_i, ef_grs_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call gridmap_areaave_srcmask(tgridmap, ef_crp_i, ef_crp_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check for conservation + + do no = 1, ns_o + if ( ef_btr_o(no) < 0._r8 ) then + write (6,*) 'MKVOCEF error: EF btr = ',ef_btr_o(no), & + ' is negative for no = ',no + call abort() + end if + if ( ef_fet_o(no) < 0._r8 ) then + write (6,*) 'MKVOCEF error: EF fet = ',ef_fet_o(no), & + ' is negative for no = ',no + call abort() + end if + if ( ef_fdt_o(no) < 0._r8 ) then + write (6,*) 'MKVOCEF error: EF fdt = ',ef_fdt_o(no), & + ' is negative for no = ',no + call abort() + end if + if ( ef_shr_o(no) < 0._r8 ) then + write (6,*) 'MKVOCEF error: EF shr = ',ef_shr_o(no), & + ' is negative for no = ',no + call abort() + end if + if ( ef_grs_o(no) < 0._r8 ) then + write (6,*) 'MKVOCEF error: EF grs = ',ef_grs_o(no), & + ' is negative for no = ',no + call abort() + end if + if ( ef_crp_o(no) < 0._r8 ) then + write (6,*) 'MKVOCEF error: EF crp = ',ef_crp_o(no), & + ' is negative for no = ',no + call abort() + end if + enddo + + ! ----------------------------------------------------------------- + ! Error check1 + ! Compare global sum fld_o to global sum fld_i. + ! ----------------------------------------------------------------- + + ! Global sum of output field -- must multiply by fraction of + ! output grid that is land as determined by input grid + + allocate(mask_r8(ns_i), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + write (6,*) 'Successfully made VOC Emission Factors' + write (6,*) + + ! Deallocate dynamic memory + + deallocate ( ef_btr_i, ef_fet_i, ef_fdt_i, & + ef_shr_i, ef_grs_i, ef_crp_i, frac_dst, mask_r8 ) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + + end subroutine mkvocef end module mkvocefMod diff --git a/tools/mksurfdata_esmf/src/run_mksurfdata b/tools/mksurfdata_esmf/src/run_mksurfdata index 58b9c6c703..aa5e110aba 100644 --- a/tools/mksurfdata_esmf/src/run_mksurfdata +++ b/tools/mksurfdata_esmf/src/run_mksurfdata @@ -4,7 +4,8 @@ #PBS -j oe #PBS -q premium #PBS -l walltime=45:00 -#PBS -l select=2:ncpus=36:mpiprocs=36 +##PBS -l select=1:ncpus=36:mpiprocs=36 +#PBS -l select=4:ncpus=36:mpiprocs=36 ##PBS -l select=16:ncpus=36:mpiprocs=9 #PBS -o log.out @@ -19,4 +20,5 @@ mkdir -p $TMPDIR #make # -np {total_tasks} -mpiexec_mpt -np 72 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata +cd /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata/run +mpiexec_mpt -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata diff --git a/tools/mksurfdata_esmf/src/shr_mpi_mod.F90 b/tools/mksurfdata_esmf/src/shr_mpi_mod.F90 deleted file mode 100644 index 346b954fb9..0000000000 --- a/tools/mksurfdata_esmf/src/shr_mpi_mod.F90 +++ /dev/null @@ -1,2215 +0,0 @@ -Module shr_mpi_mod - - !------------------------------------------------------------------------------- - ! PURPOSE: general layer on MPI functions - !------------------------------------------------------------------------------- - - use shr_kind_mod - - implicit none - private - - ! PUBLIC: Public interfaces - - public :: shr_mpi_chkerr - public :: shr_mpi_send - public :: shr_mpi_recv - public :: shr_mpi_bcast - public :: shr_mpi_gathScatVInit - public :: shr_mpi_gatherV - public :: shr_mpi_scatterV - public :: shr_mpi_sum - public :: shr_mpi_min - public :: shr_mpi_max - public :: shr_mpi_commsize - public :: shr_mpi_commrank - public :: shr_mpi_initialized - public :: shr_mpi_abort - public :: shr_mpi_barrier - public :: shr_mpi_init - public :: shr_mpi_finalize - - interface shr_mpi_send ; module procedure & - shr_mpi_sendi0, & - shr_mpi_sendi1, & - shr_mpi_sendr0, & - shr_mpi_sendr1, & - shr_mpi_sendr3 - end interface shr_mpi_send - interface shr_mpi_recv ; module procedure & - shr_mpi_recvi0, & - shr_mpi_recvi1, & - shr_mpi_recvr0, & - shr_mpi_recvr1, & - shr_mpi_recvr3 - end interface shr_mpi_recv - interface shr_mpi_bcast ; module procedure & - shr_mpi_bcastc0, & - shr_mpi_bcastc1, & - shr_mpi_bcastl0, & - shr_mpi_bcastl1, & - shr_mpi_bcasti0, & - shr_mpi_bcasti1, & - shr_mpi_bcasti80, & - shr_mpi_bcasti81, & - shr_mpi_bcasti2, & - shr_mpi_bcastr0, & - shr_mpi_bcastr1, & - shr_mpi_bcastr2, & - shr_mpi_bcastr3 - end interface shr_mpi_bcast - interface shr_mpi_gathScatVInit ; module procedure & - shr_mpi_gathScatVInitr1 - end interface shr_mpi_gathScatVInit - interface shr_mpi_gatherv ; module procedure & - shr_mpi_gatherVr1 - end interface shr_mpi_gatherv - interface shr_mpi_scatterv ; module procedure & - shr_mpi_scatterVr1 - end interface shr_mpi_scatterv - interface shr_mpi_sum ; module procedure & - shr_mpi_sumi0, & - shr_mpi_sumi1, & - shr_mpi_sumb0, & - shr_mpi_sumb1, & - shr_mpi_sumr0, & - shr_mpi_sumr1, & - shr_mpi_sumr2, & - shr_mpi_sumr3 - end interface shr_mpi_sum - interface shr_mpi_min ; module procedure & - shr_mpi_mini0, & - shr_mpi_mini1, & - shr_mpi_minr0, & - shr_mpi_minr1 - end interface shr_mpi_min - interface shr_mpi_max ; module procedure & - shr_mpi_maxi0, & - shr_mpi_maxi1, & - shr_mpi_maxr0, & - shr_mpi_maxr1 - end interface shr_mpi_max - -#include ! mpi library include file - - !=============================================================================== -CONTAINS - !=============================================================================== - - SUBROUTINE shr_mpi_chkerr(rcode,string) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_IN), intent(in) :: rcode ! input MPI error code - character(*), intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_chkerr) ' - character(MPI_MAX_ERROR_STRING) :: lstring - integer(SHR_KIND_IN) :: len - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: layer on MPI error checking - !------------------------------------------------------------------------------- - - if (rcode /= MPI_SUCCESS) then - call MPI_ERROR_STRING(rcode,lstring,len,ierr) - write(6,*) trim(subName),":",lstring(1:len) - call shr_mpi_abort(string,rcode) - endif - - END SUBROUTINE shr_mpi_chkerr - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_sendi0(lvec,pid,tag,comm,string) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_IN), intent(in) :: lvec ! send value - integer(SHR_KIND_IN), intent(in) :: pid ! pid to send to - integer(SHR_KIND_IN), intent(in) :: tag ! tag - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_sendi0) ' - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Send a single integer - !------------------------------------------------------------------------------- - - lsize = 1 - - call MPI_SEND(lvec,lsize,MPI_INTEGER,pid,tag,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_sendi0 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_sendi1(lvec,pid,tag,comm,string) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_IN), intent(in) :: lvec(:) ! in/out local values - integer(SHR_KIND_IN), intent(in) :: pid ! pid to send to - integer(SHR_KIND_IN), intent(in) :: tag ! tag - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_sendi1) ' - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Send a vector of integers - !------------------------------------------------------------------------------- - - lsize = size(lvec) - - call MPI_SEND(lvec,lsize,MPI_INTEGER,pid,tag,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_sendi1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_sendr0(lvec,pid,tag,comm,string) - - IMPLICIT none - - !----- arguments --- - real(SHR_KIND_R8), intent(in) :: lvec ! in/out local values - integer(SHR_KIND_IN), intent(in) :: pid ! pid to send to - integer(SHR_KIND_IN), intent(in) :: tag ! tag - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_sendr0) ' - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Send a real scalar - !------------------------------------------------------------------------------- - - lsize = 1 - - call MPI_SEND(lvec,lsize,MPI_REAL8,pid,tag,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_sendr0 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_sendr1(lvec,pid,tag,comm,string) - - IMPLICIT none - - !----- arguments --- - real(SHR_KIND_R8), intent(in) :: lvec(:) ! in/out local values - integer(SHR_KIND_IN), intent(in) :: pid ! pid to send to - integer(SHR_KIND_IN), intent(in) :: tag ! tag - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_sendr1) ' - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Send a vector of reals - !------------------------------------------------------------------------------- - - lsize = size(lvec) - - call MPI_SEND(lvec,lsize,MPI_REAL8,pid,tag,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_sendr1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_sendr3(array,pid,tag,comm,string) - - IMPLICIT none - - !----- arguments --- - real (SHR_KIND_R8), intent(in) :: array(:,:,:) ! in/out local values - integer(SHR_KIND_IN), intent(in) :: pid ! pid to send to - integer(SHR_KIND_IN), intent(in) :: tag ! tag - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_sendr3) ' - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Send a vector of reals - !------------------------------------------------------------------------------- - - lsize = size(array) - - call MPI_SEND(array,lsize,MPI_REAL8,pid,tag,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_sendr3 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_recvi0(lvec,pid,tag,comm,string) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_IN), intent(out):: lvec ! in/out local values - integer(SHR_KIND_IN), intent(in) :: pid ! pid to recv from - integer(SHR_KIND_IN), intent(in) :: tag ! tag - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_recvi0) ' - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: status(MPI_STATUS_SIZE) ! mpi status info - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Recv a vector of reals - !------------------------------------------------------------------------------- - - lsize = 1 - - call MPI_RECV(lvec,lsize,MPI_INTEGER,pid,tag,comm,status,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_recvi0 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_recvi1(lvec,pid,tag,comm,string) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_IN), intent(out):: lvec(:) ! in/out local values - integer(SHR_KIND_IN), intent(in) :: pid ! pid to recv from - integer(SHR_KIND_IN), intent(in) :: tag ! tag - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_recvi1) ' - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: status(MPI_STATUS_SIZE) ! mpi status info - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Recv a vector of reals - !------------------------------------------------------------------------------- - - lsize = size(lvec) - - call MPI_RECV(lvec,lsize,MPI_INTEGER,pid,tag,comm,status,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_recvi1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_recvr0(lvec,pid,tag,comm,string) - - IMPLICIT none - - !----- arguments --- - real(SHR_KIND_R8), intent(out):: lvec ! in/out local values - integer(SHR_KIND_IN), intent(in) :: pid ! pid to recv from - integer(SHR_KIND_IN), intent(in) :: tag ! tag - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_recvr0) ' - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: status(MPI_STATUS_SIZE) ! mpi status info - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Recv a vector of reals - !------------------------------------------------------------------------------- - - lsize = 1 - - call MPI_RECV(lvec,lsize,MPI_REAL8,pid,tag,comm,status,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_recvr0 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_recvr1(lvec,pid,tag,comm,string) - - IMPLICIT none - - !----- arguments --- - real(SHR_KIND_R8), intent(out):: lvec(:) ! in/out local values - integer(SHR_KIND_IN), intent(in) :: pid ! pid to recv from - integer(SHR_KIND_IN), intent(in) :: tag ! tag - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_recvr1) ' - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: status(MPI_STATUS_SIZE) ! mpi status info - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Recv a vector of reals - !------------------------------------------------------------------------------- - - lsize = size(lvec) - - call MPI_RECV(lvec,lsize,MPI_REAL8,pid,tag,comm,status,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_recvr1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_recvr3(array,pid,tag,comm,string) - - IMPLICIT none - - !----- arguments --- - real (SHR_KIND_R8), intent(out):: array(:,:,:) ! in/out local values - integer(SHR_KIND_IN), intent(in) :: pid ! pid to recv from - integer(SHR_KIND_IN), intent(in) :: tag ! tag - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_recvr3) ' - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: status(MPI_STATUS_SIZE) ! mpi status info - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Recv a vector of reals - !------------------------------------------------------------------------------- - - lsize = size(array) - - call MPI_RECV(array,lsize,MPI_REAL8,pid,tag,comm,status,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_recvr3 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_bcasti0(vec,comm,string,pebcast) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_IN), intent(inout):: vec ! vector of 1 - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_bcasti0) ' - integer(SHR_KIND_IN) :: ierr - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: lpebcast - - !------------------------------------------------------------------------------- - ! PURPOSE: Broadcast an integer - !------------------------------------------------------------------------------- - - lsize = 1 - lpebcast = 0 - if (present(pebcast)) lpebcast = pebcast - - call MPI_BCAST(vec,lsize,MPI_INTEGER,lpebcast,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_bcasti0 - - SUBROUTINE shr_mpi_bcasti80(vec,comm,string,pebcast) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_I8), intent(inout):: vec ! vector of 1 - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_bcasti0) ' - integer(SHR_KIND_IN) :: ierr - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: lpebcast - - !------------------------------------------------------------------------------- - ! PURPOSE: Broadcast an integer - !------------------------------------------------------------------------------- - - lsize = 1 - lpebcast = 0 - if (present(pebcast)) lpebcast = pebcast - - call MPI_BCAST(vec,lsize,MPI_INTEGER8,lpebcast,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_bcasti80 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_bcastl0(vec,comm,string,pebcast) - - IMPLICIT none - - !----- arguments --- - logical, intent(inout):: vec ! vector of 1 - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_bcastl0) ' - integer(SHR_KIND_IN) :: ierr - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: lpebcast - - !------------------------------------------------------------------------------- - ! PURPOSE: Broadcast a logical - !------------------------------------------------------------------------------- - - lsize = 1 - lpebcast = 0 - if (present(pebcast)) lpebcast = pebcast - - call MPI_BCAST(vec,lsize,MPI_LOGICAL,lpebcast,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_bcastl0 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_bcastc0(vec,comm,string,pebcast) - - IMPLICIT none - - !----- arguments --- - character(len=*), intent(inout) :: vec ! vector of 1 - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_bcastc0) ' - integer(SHR_KIND_IN) :: ierr - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: lpebcast - - !------------------------------------------------------------------------------- - ! PURPOSE: Broadcast a character string - !------------------------------------------------------------------------------- - - lsize = len(vec) - lpebcast = 0 - if (present(pebcast)) lpebcast = pebcast - - call MPI_BCAST(vec,lsize,MPI_CHARACTER,lpebcast,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_bcastc0 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_bcastc1(vec,comm,string,pebcast) - - IMPLICIT none - - !----- arguments --- - character(len=*), intent(inout) :: vec(:) ! 1D vector - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_bcastc1) ' - integer(SHR_KIND_IN) :: ierr - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: lpebcast - - !------------------------------------------------------------------------------- - ! PURPOSE: Broadcast a character string - !------------------------------------------------------------------------------- - - lsize = size(vec)*len(vec) - lpebcast = 0 - if (present(pebcast)) lpebcast = pebcast - - call MPI_BCAST(vec,lsize,MPI_CHARACTER,lpebcast,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_bcastc1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_bcastr0(vec,comm,string,pebcast) - - IMPLICIT none - - !----- arguments --- - real(SHR_KIND_R8), intent(inout):: vec ! vector of 1 - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_bcastr0) ' - integer(SHR_KIND_IN) :: ierr - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: lpebcast - - !------------------------------------------------------------------------------- - ! PURPOSE: Broadcast a real - !------------------------------------------------------------------------------- - - lsize = 1 - lpebcast = 0 - if (present(pebcast)) lpebcast = pebcast - - call MPI_BCAST(vec,lsize,MPI_REAL8,lpebcast,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_bcastr0 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_bcasti1(vec,comm,string,pebcast) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_IN), intent(inout):: vec(:) ! vector - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_bcasti1) ' - integer(SHR_KIND_IN) :: ierr - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: lpebcast - - !------------------------------------------------------------------------------- - ! PURPOSE: Broadcast a vector of integers - !------------------------------------------------------------------------------- - - lsize = size(vec) - lpebcast = 0 - if (present(pebcast)) lpebcast = pebcast - - call MPI_BCAST(vec,lsize,MPI_INTEGER,lpebcast,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_bcasti1 - - SUBROUTINE shr_mpi_bcasti81(vec,comm,string,pebcast) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_I8), intent(inout):: vec(:) ! vector - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_bcasti1) ' - integer(SHR_KIND_IN) :: ierr - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: lpebcast - - !------------------------------------------------------------------------------- - ! PURPOSE: Broadcast a vector of integers - !------------------------------------------------------------------------------- - - lsize = size(vec) - lpebcast = 0 - if (present(pebcast)) lpebcast = pebcast - - call MPI_BCAST(vec,lsize,MPI_INTEGER8,lpebcast,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_bcasti81 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_bcastl1(vec,comm,string,pebcast) - - IMPLICIT none - - !----- arguments --- - logical, intent(inout):: vec(:) ! vector of 1 - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_bcastl1) ' - integer(SHR_KIND_IN) :: ierr - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: lpebcast - - !------------------------------------------------------------------------------- - ! PURPOSE: Broadcast a logical - !------------------------------------------------------------------------------- - - lsize = size(vec) - lpebcast = 0 - if (present(pebcast)) lpebcast = pebcast - - call MPI_BCAST(vec,lsize,MPI_LOGICAL,lpebcast,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_bcastl1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_bcastr1(vec,comm,string,pebcast) - - IMPLICIT none - - !----- arguments --- - real(SHR_KIND_R8), intent(inout):: vec(:) ! vector - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_bcastr1) ' - integer(SHR_KIND_IN) :: ierr - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: lpebcast - - !------------------------------------------------------------------------------- - ! PURPOSE: Broadcast a vector of reals - !------------------------------------------------------------------------------- - - lsize = size(vec) - lpebcast = 0 - if (present(pebcast)) lpebcast = pebcast - - call MPI_BCAST(vec,lsize,MPI_REAL8,lpebcast,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_bcastr1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_bcastr2(arr,comm,string,pebcast) - - IMPLICIT none - - !----- arguments ----- - real(SHR_KIND_R8), intent(inout):: arr(:,:) ! array, 2d - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) - - !----- local ----- - integer(SHR_KIND_IN) :: ierr - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: lpebcast - - !----- formats ----- - character(*),parameter :: subName = '(shr_mpi_bcastr2) ' - - !------------------------------------------------------------------------------- - ! PURPOSE: Broadcast a 2d array of reals - !------------------------------------------------------------------------------- - - lsize = size(arr) - lpebcast = 0 - if (present(pebcast)) lpebcast = pebcast - - call MPI_BCAST(arr,lsize,MPI_REAL8,lpebcast,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_bcastr2 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_bcasti2(arr,comm,string,pebcast) - - IMPLICIT none - - !----- arguments ----- - integer, intent(inout):: arr(:,:) ! array, 2d - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) - - !----- local ----- - integer(SHR_KIND_IN) :: ierr - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: lpebcast - - !----- formats ----- - character(*),parameter :: subName = '(shr_mpi_bcasti2) ' - - !------------------------------------------------------------------------------- - ! PURPOSE: Broadcast a 2d array of integers - !------------------------------------------------------------------------------- - - lsize = size(arr) - lpebcast = 0 - if (present(pebcast)) lpebcast = pebcast - - call MPI_BCAST(arr,lsize,MPI_INTEGER,lpebcast,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_bcasti2 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_bcastr3(arr,comm,string,pebcast) - - IMPLICIT none - - !----- arguments ----- - real(SHR_KIND_R8), intent(inout):: arr(:,:,:) ! array, 3d - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - integer(SHR_KIND_IN), optional, intent(in) :: pebcast ! bcast pe (otherwise zero) - - !----- local ----- - integer(SHR_KIND_IN) :: ierr - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: lpebcast - - !----- formats ----- - character(*),parameter :: subName = '(shr_mpi_bcastr3) ' - - !------------------------------------------------------------------------------- - ! PURPOSE: Broadcast a 3d array of reals - !------------------------------------------------------------------------------- - - lsize = size(arr) - lpebcast = 0 - if (present(pebcast)) lpebcast = pebcast - - call MPI_BCAST(arr,lsize,MPI_REAL8,lpebcast,comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_bcastr3 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_gathScatvInitr1(comm, rootid, locArr, glob1DArr, globSize, & - displs, string ) - - IMPLICIT none - - !----- arguments ----- - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - integer(SHR_KIND_IN), intent(in) :: rootid ! MPI task to gather/scatter on - real(SHR_KIND_R8), intent(in) :: locArr(:) ! Local array of distributed data - real(SHR_KIND_R8), pointer :: glob1DArr(:) ! Global 1D array of gathered data - integer(SHR_KIND_IN), pointer :: globSize(:) ! Size of each distributed piece - integer(SHR_KIND_IN), pointer :: displs(:) ! Displacements for receive - character(*),optional,intent(in) :: string ! message - - !----- local ----- - integer(SHR_KIND_IN) :: npes ! Number of MPI tasks - integer(SHR_KIND_IN) :: locSize ! Size of local distributed data - integer(SHR_KIND_IN), pointer :: sendSize(:) ! Size to send for initial gather - integer(SHR_KIND_IN) :: i ! Index - integer(SHR_KIND_IN) :: rank ! Rank of this MPI task - integer(SHR_KIND_IN) :: nSize ! Maximum size to send - integer(SHR_KIND_IN) :: ierr ! Error code - integer(SHR_KIND_IN) :: nSiz1D ! Size of 1D global array - integer(SHR_KIND_IN) :: maxSize ! Maximum size - - !----- formats ----- - character(*),parameter :: subName = '(shr_mpi_gathScatvInitr1) ' - - !------------------------------------------------------------------------------- - ! PURPOSE: Setup arrays for a gatherv/scatterv operation - !------------------------------------------------------------------------------- - - locSize = size(locarr) - call shr_mpi_commsize( comm, npes ) - call shr_mpi_commrank( comm, rank ) - allocate( globSize(npes) ) - ! - ! --- Gather the send global sizes from each MPI task ----------------------- - ! - allocate( sendSize(npes) ) - sendSize(:) = 1 - globSize(:) = 1 - call MPI_GATHER( locSize, 1, MPI_INTEGER, globSize, sendSize, & - MPI_INTEGER, rootid, comm, ierr ) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - deallocate( sendSize ) - ! - ! --- Prepare the displacement and allocate arrays ------------------------- - ! - allocate( displs(npes) ) - displs(1) = 0 - if ( rootid /= rank )then - maxSize = 1 - globSize = 1 - else - maxSize = maxval(globSize) - end if - nsiz1D = min(maxSize,globSize(1)) - do i = 2, npes - nSize = min(maxSize,globSize(i-1)) - displs(i) = displs(i-1) + nSize - nsiz1D = nsiz1D + min(maxSize,globSize(i)) - end do - allocate( glob1DArr(nsiz1D) ) - !----- Do some error checking for the root task arrays computed ---- - if ( rootid == rank )then - if ( nsiz1D /= sum(globSize) ) & - call shr_mpi_abort( subName//" : Error, size of global array not right" ) - if ( any(displs < 0) .or. any(displs >= nsiz1D) ) & - call shr_mpi_abort( subName//" : Error, displacement array not right" ) - if ( (displs(npes)+globSize(npes)) /= nsiz1D ) & - call shr_mpi_abort( subName//" : Error, displacement array values too big" ) - end if - - END SUBROUTINE shr_mpi_gathScatvInitr1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_gathervr1(locarr, locSize, glob1DArr, globSize, displs, rootid, & - comm, string ) - - IMPLICIT none - - !----- arguments ----- - real(SHR_KIND_R8), intent(in) :: locArr(:) ! Local array - real(SHR_KIND_R8), intent(inout):: glob1DArr(:) ! Global 1D array to receive in on - integer(SHR_KIND_IN), intent(in) :: locSize ! Number to send this PE - integer(SHR_KIND_IN), intent(in) :: globSize(:) ! Number to receive each PE - integer(SHR_KIND_IN), intent(in) :: displs(:) ! Displacements for receive - integer(SHR_KIND_IN), intent(in) :: rootid ! MPI task to gather on - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - - !----- local ----- - integer(SHR_KIND_IN) :: ierr ! Error code - - !----- formats ----- - character(*),parameter :: subName = '(shr_mpi_gathervr1) ' - - !------------------------------------------------------------------------------- - ! PURPOSE: Gather a 1D array of reals - !------------------------------------------------------------------------------- - - call MPI_GATHERV( locarr, locSize, MPI_REAL8, glob1Darr, globSize, displs, & - MPI_REAL8, rootid, comm, ierr ) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_gathervr1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_scattervr1(locarr, locSize, glob1Darr, globSize, displs, rootid, & - comm, string ) - - IMPLICIT none - - !----- arguments ----- - real(SHR_KIND_R8), intent(out) :: locarr(:) ! Local array - real(SHR_KIND_R8), intent(in) :: glob1Darr(:) ! Global 1D array to send from - integer(SHR_KIND_IN), intent(in) :: locSize ! Number to receive this PE - integer(SHR_KIND_IN), intent(in) :: globSize(:) ! Number to send to each PE - integer(SHR_KIND_IN), intent(in) :: displs(:) ! Displacements for send - integer(SHR_KIND_IN), intent(in) :: rootid ! MPI task to scatter on - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - - !----- local ----- - integer(SHR_KIND_IN) :: ierr ! Error code - - !----- formats ----- - character(*),parameter :: subName = '(shr_mpi_scattervr1) ' - - !------------------------------------------------------------------------------- - ! PURPOSE: Scatter a 1D array of reals - !------------------------------------------------------------------------------- - - - call MPI_SCATTERV( glob1Darr, globSize, displs, MPI_REAL8, locarr, locSize, & - MPI_REAL8, rootid, comm, ierr ) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_scattervr1 - - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_sumi0(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_IN), intent(in) :: lvec ! in/out local values - integer(SHR_KIND_IN), intent(out):: gvec ! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_sumi0) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds sum of a distributed vector of values, assume local sum - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_SUM - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = 1 - gsize = 1 - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_sumi0 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_sumi1(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_IN), intent(in) :: lvec(:) ! in/out local values - integer(SHR_KIND_IN), intent(out):: gvec(:) ! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_sumi1) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds sum of a distributed vector of values, assume local sum - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_SUM - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = size(lvec) - gsize = size(gvec) - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_sumi1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_sumb0(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_I8), intent(in) :: lvec ! in/out local values - integer(SHR_KIND_I8), intent(out):: gvec ! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_sumb0) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds sum of a distributed vector of values, assume local sum - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_SUM - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = 1 - gsize = 1 - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER8,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER8,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_sumb0 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_sumb1(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_I8), intent(in) :: lvec(:) ! in/out local values - integer(SHR_KIND_I8), intent(out):: gvec(:) ! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_sumb1) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds sum of a distributed vector of values, assume local sum - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_SUM - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = size(lvec) - gsize = size(gvec) - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER8,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER8,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_sumb1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_sumr0(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - real(SHR_KIND_R8), intent(in) :: lvec ! in/out local values - real(SHR_KIND_R8), intent(out):: gvec ! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_sumr0) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds sum of a distributed vector of values, assume local sum - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_SUM - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = 1 - gsize = 1 - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_sumr0 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_sumr1(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - real(SHR_KIND_R8), intent(in) :: lvec(:) ! in/out local values - real(SHR_KIND_R8), intent(out):: gvec(:) ! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_sumr1) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds sum of a distributed vector of values, assume local sum - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_SUM - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = size(lvec) - gsize = size(gvec) - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_sumr1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_sumr2(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - real(SHR_KIND_R8), intent(in) :: lvec(:,:)! in/out local values - real(SHR_KIND_R8), intent(out):: gvec(:,:)! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_sumr2) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds sum of a distributed vector of values, assume local sum - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_SUM - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = size(lvec) - gsize = size(gvec) - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_sumr2 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_sumr3(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - real(SHR_KIND_R8), intent(in) :: lvec(:,:,:) ! in/out local values - real(SHR_KIND_R8), intent(out):: gvec(:,:,:) ! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_sumr3) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds sum of a distributed vector of values, assume local sum - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_SUM - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = size(lvec) - gsize = size(gvec) - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_sumr3 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_mini0(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_IN), intent(in) :: lvec ! in/out local values - integer(SHR_KIND_IN), intent(out):: gvec ! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_mini0) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds min of a distributed vector of values, assume local min - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_MIN - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = 1 - gsize = 1 - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_mini0 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_mini1(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_IN), intent(in) :: lvec(:) ! in/out local values - integer(SHR_KIND_IN), intent(out):: gvec(:) ! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_mini1) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds min of a distributed vector of values, assume local min - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_MIN - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = size(lvec) - gsize = size(gvec) - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_mini1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_minr0(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - real(SHR_KIND_R8), intent(in) :: lvec ! in/out local values - real(SHR_KIND_R8), intent(out):: gvec ! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_minr0) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds min of a distributed vector of values, assume local min - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_MIN - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = 1 - gsize = 1 - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_minr0 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_minr1(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - real(SHR_KIND_R8), intent(in) :: lvec(:) ! in/out local values - real(SHR_KIND_R8), intent(out):: gvec(:) ! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_minr1) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds min of a distributed vector of values, assume local min - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_MIN - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = size(lvec) - gsize = size(gvec) - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_minr1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_maxi0(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_IN), intent(in) :: lvec ! in/out local values - integer(SHR_KIND_IN), intent(out):: gvec ! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_maxi0) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds max of a distributed vector of values, assume local max - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_MAX - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = 1 - gsize = 1 - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_maxi0 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_maxi1(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - integer(SHR_KIND_IN), intent(in) :: lvec(:) ! in/out local values - integer(SHR_KIND_IN), intent(out):: gvec(:) ! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_maxi1) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds max of a distributed vector of values, assume local max - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_MAX - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = size(lvec) - gsize = size(gvec) - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_INTEGER,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_maxi1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_maxr0(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - real(SHR_KIND_R8), intent(in) :: lvec ! in/out local values - real(SHR_KIND_R8), intent(out):: gvec ! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_maxr0) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds max of a distributed vector of values, assume local max - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_MAX - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = 1 - gsize = 1 - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_maxr0 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_maxr1(lvec,gvec,comm,string,all) - - IMPLICIT none - - !----- arguments --- - real(SHR_KIND_R8), intent(in) :: lvec(:) ! in/out local values - real(SHR_KIND_R8), intent(out):: gvec(:) ! in/out global values - integer(SHR_KIND_IN), intent(in) :: comm ! mpi communicator - character(*),optional,intent(in) :: string ! message - logical, optional,intent(in) :: all ! allreduce if true - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_maxr1) ' - logical :: lall - character(SHR_KIND_CL) :: lstring - integer(SHR_KIND_IN) :: reduce_type ! mpi reduction type - integer(SHR_KIND_IN) :: lsize - integer(SHR_KIND_IN) :: gsize - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: Finds max of a distributed vector of values, assume local max - ! already computed - !------------------------------------------------------------------------------- - - reduce_type = MPI_MAX - if (present(all)) then - lall = all - else - lall = .false. - endif - if (present(string)) then - lstring = trim(subName)//":"//trim(string) - else - lstring = trim(subName) - endif - - lsize = size(lvec) - gsize = size(gvec) - - if (lsize /= gsize) then - call shr_mpi_abort(subName//" lsize,gsize incompatable "//trim(string)) - endif - - if (lall) then - call MPI_ALLREDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_ALLREDUCE") - else - call MPI_REDUCE(lvec,gvec,gsize,MPI_REAL8,reduce_type,0,comm,ierr) - call shr_mpi_chkerr(ierr,trim(lstring)//" MPI_REDUCE") - endif - - END SUBROUTINE shr_mpi_maxr1 - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_commsize(comm,size,string) - - IMPLICIT none - - !----- arguments --- - integer,intent(in) :: comm - integer,intent(out) :: size - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_commsize) ' - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: MPI commsize - !------------------------------------------------------------------------------- - - call MPI_COMM_SIZE(comm,size,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_commsize - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_commrank(comm,rank,string) - - IMPLICIT none - - !----- arguments --- - integer,intent(in) :: comm - integer,intent(out) :: rank - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_commrank) ' - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: MPI commrank - !------------------------------------------------------------------------------- - - call MPI_COMM_RANK(comm,rank,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_commrank - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_initialized(flag,string) - - IMPLICIT none - - !----- arguments --- - logical,intent(out) :: flag - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_initialized) ' - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: MPI initialized - !------------------------------------------------------------------------------- - - call MPI_INITIALIZED(flag,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_initialized - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_abort(string,rcode) - - IMPLICIT none - - !----- arguments --- - character(*),optional,intent(in) :: string ! message - integer,optional,intent(in) :: rcode ! optional code - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_abort) ' - integer(SHR_KIND_IN) :: ierr - integer :: rc ! return code - - !------------------------------------------------------------------------------- - ! PURPOSE: MPI abort - !------------------------------------------------------------------------------- - - if ( present(string) .and. present(rcode) ) then - write(6,*) trim(subName),":",trim(string),rcode - endif - if ( present(rcode) )then - rc = rcode - else - rc = 1001 - end if - call MPI_ABORT(MPI_COMM_WORLD,rc,ierr) - - END SUBROUTINE shr_mpi_abort - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_barrier(comm,string) - - IMPLICIT none - - !----- arguments --- - integer,intent(in) :: comm - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_barrier) ' - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: MPI barrier - !------------------------------------------------------------------------------- - - call MPI_BARRIER(comm,ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_barrier - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_init(string) - - IMPLICIT none - - !----- arguments --- - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_init) ' - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: MPI init - !------------------------------------------------------------------------------- - - call MPI_INIT(ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_init - - !=============================================================================== - !=============================================================================== - - SUBROUTINE shr_mpi_finalize(string) - - IMPLICIT none - - !----- arguments --- - character(*),optional,intent(in) :: string ! message - - !----- local --- - character(*),parameter :: subName = '(shr_mpi_finalize) ' - integer(SHR_KIND_IN) :: ierr - - !------------------------------------------------------------------------------- - ! PURPOSE: MPI finalize - !------------------------------------------------------------------------------- - - call MPI_BARRIER(MPI_COMM_WORLD,ierr) - call MPI_FINALIZE(ierr) - if (present(string)) then - call shr_mpi_chkerr(ierr,subName//trim(string)) - else - call shr_mpi_chkerr(ierr,subName) - endif - - END SUBROUTINE shr_mpi_finalize - - !=============================================================================== - !=============================================================================== - -END MODULE shr_mpi_mod diff --git a/tools/mksurfdata_esmf/src/shr_pio_mod.F90 b/tools/mksurfdata_esmf/src/shr_pio_mod.F90 deleted file mode 100644 index 106cdfc0ea..0000000000 --- a/tools/mksurfdata_esmf/src/shr_pio_mod.F90 +++ /dev/null @@ -1,748 +0,0 @@ -module shr_pio_mod - - use pio - use shr_kind_mod, only : shr_kind_CS, shr_kind_cl, shr_kind_in - use shr_mpi_mod, only : shr_mpi_bcast, shr_mpi_chkerr - use shr_sys_mod, only : shr_sys_abort - - implicit none - private - -#include - - public :: shr_pio_init1 - public :: shr_pio_init2 - public :: shr_pio_getiosys - public :: shr_pio_getiotype - public :: shr_pio_getioroot - public :: shr_pio_finalize - public :: shr_pio_getioformat - public :: shr_pio_getrearranger - - type pio_comp_t - integer :: compid - integer :: pio_root - integer :: pio_stride - integer :: pio_numiotasks - integer :: pio_iotype - integer :: pio_rearranger - integer :: pio_netcdf_ioformat - end type pio_comp_t - - type(pio_comp_t), allocatable :: pio_comp_settings(:) - type (iosystem_desc_t), allocatable, target :: iosystems(:) - integer :: io_comm - logical :: pio_async_interface - integer :: pio_debug_level=0, pio_blocksize=0 - integer(kind=pio_offset_kind) :: pio_buffer_size_limit=-1 - integer :: pio_rearr_opt_comm_type, pio_rearr_opt_fcd - logical :: pio_rearr_opt_c2i_enable_hs, pio_rearr_opt_c2i_enable_isend - integer :: pio_rearr_opt_c2i_max_pend_req - logical :: pio_rearr_opt_i2c_enable_hs, pio_rearr_opt_i2c_enable_isend - integer :: pio_rearr_opt_i2c_max_pend_req - integer :: total_comps = 1 - integer :: shr_log_unit = 6 - -#define DEBUGI 1 - -#ifdef DEBUGI - integer :: drank -#endif - -!=============================================================== -contains -!=============================================================== - - subroutine shr_pio_init1(nlfilename, Global_Comm) - - ! Should be the first routine called after mpi_init. - ! It reads the pio default settings from file drv_in, namelist pio_default_inparm - ! It then returns the new compute comm in Global_Comm and sets module variable io_comm. - - character(len=*) , intent(in) :: nlfilename - integer , intent(inout) :: Global_Comm - - integer :: ncomps - integer :: i, pio_root, pio_stride, pio_numiotasks, pio_iotype, pio_rearranger, pio_netcdf_ioformat - integer :: mpigrp_world, mpigrp, ierr, mpicom - integer :: pelist(3,1) - integer, allocatable :: comp_comm(:) - type(iosystem_desc_t), allocatable :: iosystems(:) - character(*),parameter :: subName = '(shr_pio_init1) ' - !----------------------------------------------------------------------- - - ncomps = 1 - - call shr_pio_read_default_namelist(nlfilename, Global_Comm, pio_stride, pio_root, pio_numiotasks, & - pio_iotype, pio_async_interface, pio_rearranger) - - pio_netcdf_ioformat = PIO_64BIT_OFFSET - call MPI_comm_rank(Global_Comm, drank, ierr) - - io_comm = MPI_COMM_NULL - allocate(pio_comp_settings(ncomps)) - do i=1,ncomps - pio_comp_settings(i)%pio_root = pio_root - pio_comp_settings(i)%pio_stride = pio_stride - pio_comp_settings(i)%pio_numiotasks = pio_numiotasks - pio_comp_settings(i)%pio_iotype = pio_iotype - pio_comp_settings(i)%pio_rearranger = pio_rearranger - pio_comp_settings(i)%pio_netcdf_ioformat = pio_netcdf_ioformat - end do - - if(pio_debug_level>0) then - if(drank==0) then - write(shr_log_unit,*) 'Setting pio_debuglevel : ',pio_debug_level - end if - call pio_setdebuglevel(pio_debug_level) - endif - total_comps = ncomps - - end subroutine shr_pio_init1 - - !=============================================================== - subroutine shr_pio_init2(comp_comm, comp_comm_iam) - - ! If pio_async_interface is false each component namelist - ! pio_inparm is read from compname_modelio.nml Then a subset of - ! each components compute tasks are Identified as IO tasks using - ! the root, stride and count variables to select the tasks. - - integer , intent(in) :: comp_comm(:), comp_comm_iam(:) - - integer :: i - character(len=shr_kind_cl) :: nlfilename, cname - integer :: ret - character(*), parameter :: subName = '(shr_pio_init2) ' - - ! 0 is a valid value of pio_buffer_size_limit - if (pio_buffer_size_limit>=0) then - if(comp_comm_iam(1)==0) then - write(shr_log_unit,*) 'Setting pio_buffer_size_limit : ',pio_buffer_size_limit - end if - call pio_set_buffer_size_limit(pio_buffer_size_limit) - endif - if (pio_blocksize>0) then - if(comp_comm_iam(1)==0) then - write(shr_log_unit,*) 'Setting pio_blocksize : ',pio_blocksize - end if - call pio_set_blocksize(pio_blocksize) - endif - ! Correct the total_comps value which may be lower in nuopc - total_comps = 1 - allocate(iosystems(total_comps)) - - i = 1 - call shr_pio_read_component_namelist(nlfilename , comp_comm(i), pio_comp_settings(i)%pio_stride, & - pio_comp_settings(i)%pio_root, pio_comp_settings(i)%pio_numiotasks, & - pio_comp_settings(i)%pio_iotype, pio_comp_settings(i)%pio_rearranger, & - pio_comp_settings(i)%pio_netcdf_ioformat) - - call pio_init(comp_comm_iam(i), comp_comm(i), pio_comp_settings(i)%pio_numiotasks, 0, & - pio_comp_settings(i)%pio_stride, & - pio_comp_settings(i)%pio_rearranger, iosystems(i), & - base=pio_comp_settings(i)%pio_root) - - ret = pio_set_rearr_opts(iosystems(i), pio_rearr_opt_comm_type,& - pio_rearr_opt_fcd,& - pio_rearr_opt_c2i_enable_hs, pio_rearr_opt_c2i_enable_isend,& - pio_rearr_opt_c2i_max_pend_req,& - pio_rearr_opt_i2c_enable_hs, pio_rearr_opt_i2c_enable_isend,& - pio_rearr_opt_i2c_max_pend_req) - if(ret /= PIO_NOERR) then - write(shr_log_unit,*) "ERROR: Setting rearranger options failed" - end if - - i = 1 - write(shr_log_unit,*) ' : pio_numiotasks = ',pio_comp_settings(i)%pio_numiotasks - write(shr_log_unit,*) ' : pio_stride = ',pio_comp_settings(i)%pio_stride - write(shr_log_unit,*) ' : pio_rearranger = ',pio_comp_settings(i)%pio_rearranger - write(shr_log_unit,*) ' : pio_root = ',pio_comp_settings(i)%pio_root - write(shr_log_unit,*) ' : pio_iotype = ',pio_comp_settings(i)%pio_iotype - - end subroutine shr_pio_init2 - - !=============================================================================== - subroutine shr_pio_finalize( ) - integer :: ierr - call pio_finalize(iosystems(1), ierr) - end subroutine shr_pio_finalize - - !=============================================================================== - function shr_pio_getiotype() result(io_type) - integer :: io_type - io_type = pio_comp_settings(1)%pio_iotype - end function shr_pio_getiotype - - !=============================================================================== - function shr_pio_getrearranger() result(io_type) - integer :: io_type - io_type = pio_comp_settings(1)%pio_rearranger - end function shr_pio_getrearranger - - !=============================================================================== - function shr_pio_getioformat() result(io_format) - integer :: io_format - io_format = pio_comp_settings(1)%pio_netcdf_ioformat - end function shr_pio_getioformat - - !=============================================================================== - function shr_pio_getioroot() result(io_root) - integer :: io_root - io_root = pio_comp_settings(1)%pio_root - end function shr_pio_getioroot - - !=============================================================================== - function shr_pio_getiosys() result(iosystem) - type(iosystem_desc_t), pointer :: iosystem - iosystem => iosystems(1) - end function shr_pio_getiosys - - !=============================================================================== - subroutine shr_pio_read_default_namelist(nlfilename, Comm, pio_stride, pio_root, pio_numiotasks, & - pio_iotype, pio_async_interface, pio_rearranger) - - character(len=*), intent(in) :: nlfilename - integer, intent(in) :: Comm - logical, intent(out) :: pio_async_interface - integer, intent(out) :: pio_stride, pio_root, pio_numiotasks, pio_iotype, pio_rearranger - - character(len=shr_kind_cs) :: pio_typename - character(len=shr_kind_cs) :: pio_rearr_comm_type, pio_rearr_comm_fcd - integer :: pio_netcdf_ioformat - integer :: pio_rearr_comm_max_pend_req_comp2io - logical :: pio_rearr_comm_enable_hs_comp2io, pio_rearr_comm_enable_isend_comp2io - integer :: pio_rearr_comm_max_pend_req_io2comp - logical :: pio_rearr_comm_enable_hs_io2comp, pio_rearr_comm_enable_isend_io2comp - character(*),parameter :: subName = '(shr_pio_read_default_namelist) ' - - integer :: iam, ierr, npes, unitn - logical :: iamroot - namelist /pio_default_inparm/ & - pio_async_interface, pio_debug_level, pio_blocksize, & - pio_buffer_size_limit, pio_root, pio_numiotasks, pio_stride, & - pio_rearr_comm_type, pio_rearr_comm_fcd, & - pio_rearr_comm_max_pend_req_comp2io, pio_rearr_comm_enable_hs_comp2io, & - pio_rearr_comm_enable_isend_comp2io, & - pio_rearr_comm_max_pend_req_io2comp, pio_rearr_comm_enable_hs_io2comp, & - pio_rearr_comm_enable_isend_io2comp - - call mpi_comm_rank(Comm, iam , ierr) - call mpi_comm_size(Comm, npes, ierr) - - if(iam==0) then - iamroot=.true. - else - iamroot=.false. - end if - - !-------------------------------------------------------------------------- - ! read io nml parameters - !-------------------------------------------------------------------------- - - pio_stride = -99 ! set based on pio_numiotasks value when initialized < 0 - pio_numiotasks = -99 ! set based on pio_stride value when initialized < 0 - pio_root = -99 - pio_typename = 'nothing' - pio_blocksize= -99 ! io blocking size set internally in pio when < 0 - pio_buffer_size_limit = -99 ! io task memory buffer maximum set internally in pio when < 0 - pio_debug_level = 0 ! no debug info by default - pio_async_interface = .false. ! pio tasks are a subset of component tasks - pio_rearranger = PIO_REARR_SUBSET - pio_netcdf_ioformat = PIO_64BIT_OFFSET - pio_rearr_comm_type = 'p2p' - pio_rearr_comm_fcd = '2denable' - pio_rearr_comm_max_pend_req_comp2io = 0 - pio_rearr_comm_enable_hs_comp2io = .true. - pio_rearr_comm_enable_isend_comp2io = .false. - pio_rearr_comm_max_pend_req_io2comp = 0 - pio_rearr_comm_enable_hs_io2comp = .true. - pio_rearr_comm_enable_isend_io2comp = .false. - - if(iamroot) then - open( newunit = unitn, file=trim(nlfilename), status='old' , iostat=ierr) - if(ierr/=0) then - write(shr_log_unit,*) 'File ',trim(nlfilename),' not found, setting default values.' - else - ierr = 1 - do while( ierr /= 0 ) - read(unitn,nml=pio_default_inparm,iostat=ierr) - if (ierr < 0) then - call shr_sys_abort( subname//':: namelist read returns an'// & - ' end of file or end of record condition '//trim(nlfilename) ) - end if - end do - close(unitn) - call shr_pio_getiotypefromname(pio_typename, pio_iotype, pio_iotype_netcdf) - end if - end if - - call shr_pio_namelist_set(npes, Comm, pio_stride, pio_root, pio_numiotasks, pio_iotype, & - iamroot, pio_rearranger, pio_netcdf_ioformat) - - call shr_mpi_bcast(pio_debug_level, Comm) - call shr_mpi_bcast(pio_root, Comm) - call shr_mpi_bcast(pio_numiotasks, Comm) - call shr_mpi_bcast(pio_blocksize, Comm) - call shr_mpi_bcast(pio_buffer_size_limit, Comm) - call shr_mpi_bcast(pio_async_interface, Comm) - call shr_mpi_bcast(pio_rearranger, Comm) - call shr_mpi_bcast(pio_stride, Comm) - - if (npes == 1) then - pio_rearr_comm_max_pend_req_comp2io = 0 - pio_rearr_comm_max_pend_req_io2comp = 0 - endif - - call shr_pio_rearr_opts_set(Comm, pio_rearr_comm_type, pio_rearr_comm_fcd, & - pio_rearr_comm_max_pend_req_comp2io, pio_rearr_comm_enable_hs_comp2io, & - pio_rearr_comm_enable_isend_comp2io, & - pio_rearr_comm_max_pend_req_io2comp, pio_rearr_comm_enable_hs_io2comp, & - pio_rearr_comm_enable_isend_io2comp, pio_numiotasks) - - end subroutine shr_pio_read_default_namelist - - !=============================================================== - subroutine shr_pio_read_component_namelist(nlfilename, Comm, pio_stride, pio_root, & - pio_numiotasks, pio_iotype, pio_rearranger, pio_netcdf_ioformat) - - character(len=*) , intent(in) :: nlfilename - integer , intent(in) :: Comm - integer , intent(inout) :: pio_stride, pio_root, pio_numiotasks - integer , intent(inout) :: pio_iotype, pio_rearranger, pio_netcdf_ioformat - - character(len=SHR_KIND_CS) :: pio_typename - character(len=SHR_KIND_CS) :: pio_netcdf_format - integer :: unitn - integer :: iam, ierr, npes - logical :: iamroot - integer :: pio_default_stride, pio_default_root, pio_default_numiotasks, pio_default_iotype - integer :: pio_default_rearranger, pio_default_netcdf_ioformat - character(*),parameter :: subName = '(shr_pio_read_component_namelist) ' - - namelist /pio_inparm/ pio_stride, pio_root, pio_numiotasks, & - pio_typename, pio_rearranger, pio_netcdf_format - - call mpi_comm_rank(Comm, iam , ierr) - call mpi_comm_size(Comm, npes, ierr) - - if(iam==0) then - iamroot=.true. - else - iamroot=.false. - end if - - pio_default_stride = pio_stride - pio_default_root = pio_root - pio_default_numiotasks = pio_numiotasks - pio_default_iotype = pio_iotype - pio_default_rearranger = pio_rearranger - pio_default_netcdf_ioformat = PIO_64BIT_DATA - - !-------------------------------------------------------------------------- - ! read io nml parameters - !-------------------------------------------------------------------------- - - pio_stride = -99 ! set based on pio_numiotasks value when initialized < 0 - pio_numiotasks = -99 ! set based on pio_stride value when initialized < 0 - pio_root = -99 - pio_typename = 'nothing' - pio_rearranger = -99 - pio_netcdf_format = '64bit_offset' - - if(iamroot) then - open( newunit=unitn, file=trim(nlfilename), status='old' , iostat=ierr) - if( ierr /= 0) then - write(shr_log_unit,*) 'No ',trim(nlfilename),' found, using defaults for pio settings' - pio_stride = pio_default_stride - pio_root = pio_default_root - pio_numiotasks = pio_default_numiotasks - pio_iotype = pio_default_iotype - pio_rearranger = pio_default_rearranger - pio_netcdf_ioformat = pio_default_netcdf_ioformat - else - ierr = 1 - do while( ierr /= 0 ) - read(unitn,nml=pio_inparm,iostat=ierr) - if (ierr < 0) then - call shr_sys_abort( subname//':: namelist read returns an'// & - ' end of file or end of record condition' ) - end if - end do - close(unitn) - call shr_pio_getiotypefromname(pio_typename, pio_iotype, pio_default_iotype) - call shr_pio_getioformatfromname(pio_netcdf_format, pio_netcdf_ioformat, pio_default_netcdf_ioformat) - end if - if(pio_stride== -99) then - if (pio_numiotasks > 0) then - pio_stride = npes/pio_numiotasks - else - pio_stride = pio_default_stride - endif - endif - if(pio_root == -99) pio_root = pio_default_root - if(pio_rearranger == -99) pio_rearranger = pio_default_rearranger - if(pio_numiotasks == -99) then - pio_numiotasks = npes/pio_stride - endif - endif - - call shr_pio_namelist_set(npes, Comm, pio_stride, pio_root, pio_numiotasks, pio_iotype, & - iamroot, pio_rearranger, pio_netcdf_ioformat) - - end subroutine shr_pio_read_component_namelist - - !=============================================================================== - subroutine shr_pio_getioformatfromname(pio_netcdf_format, pio_netcdf_ioformat, pio_default_netcdf_ioformat) - - character(len=*), intent(inout) :: pio_netcdf_format - integer, intent(out) :: pio_netcdf_ioformat - integer, intent(in) :: pio_default_netcdf_ioformat - - pio_netcdf_format = shr_pio_string_toupper(pio_netcdf_format) - if ( pio_netcdf_format .eq. 'CLASSIC' ) then - pio_netcdf_ioformat = 0 - elseif ( pio_netcdf_format .eq. '64BIT_OFFSET' ) then - pio_netcdf_ioformat = PIO_64BIT_OFFSET - elseif ( pio_netcdf_format .eq. '64BIT_DATA' ) then - pio_netcdf_ioformat = PIO_64BIT_DATA - else - pio_netcdf_ioformat = pio_default_netcdf_ioformat - endif - - end subroutine shr_pio_getioformatfromname - - !=============================================================================== - subroutine shr_pio_getiotypefromname(typename, iotype, defaulttype) - - character(len=*), intent(inout) :: typename - integer, intent(out) :: iotype - integer, intent(in) :: defaulttype - - typename = shr_pio_string_toupper(typename) - if ( typename .eq. 'NETCDF' ) then - iotype = pio_iotype_netcdf - else if ( typename .eq. 'PNETCDF') then - iotype = pio_iotype_pnetcdf - else if ( typename .eq. 'NETCDF4P') then - iotype = pio_iotype_netcdf4p - else if ( typename .eq. 'NETCDF4C') then - iotype = pio_iotype_netcdf4c - else if ( typename .eq. 'NOTHING') then - iotype = defaulttype - else if ( typename .eq. 'DEFAULT') then - iotype = defaulttype - else - write(shr_log_unit,*) 'shr_pio_mod: WARNING Bad io_type argument - using iotype_netcdf' - iotype=pio_iotype_netcdf - end if - - end subroutine shr_pio_getiotypefromname - - !=============================================================================== - subroutine shr_pio_namelist_set(npes,mycomm, pio_stride, pio_root, pio_numiotasks, & - pio_iotype, iamroot, pio_rearranger, pio_netcdf_ioformat) - - integer, intent(in) :: npes, mycomm - integer, intent(inout) :: pio_stride, pio_root, pio_numiotasks - integer, intent(inout) :: pio_iotype, pio_rearranger, pio_netcdf_ioformat - logical, intent(in) :: iamroot - character(*),parameter :: subName = '(shr_pio_namelist_set) ' - - integer :: ierr - - call mpi_bcast(pio_iotype , 1, MPI_INT, 0, myComm, ierr) - call mpi_bcast(pio_stride , 1, MPI_INT, 0, myComm, ierr) - call mpi_bcast(pio_root , 1, MPI_INT, 0, myComm, ierr) - call mpi_bcast(pio_numiotasks , 1, MPI_INT, 0, myComm, ierr) - call mpi_bcast(pio_rearranger , 1, MPI_INT, 0, myComm, ierr) - call mpi_bcast(pio_netcdf_ioformat , 1, MPI_INT, 0, myComm, ierr) - - if (pio_root<0) then - pio_root = 1 - endif - if(.not. pio_async_interface) then - pio_root = min(pio_root,npes-1) - ! If you are asking for parallel IO then you should use at least two io pes - if(npes > 1 .and. pio_numiotasks == 1 .and. & - (pio_iotype .eq. PIO_IOTYPE_PNETCDF .or. & - pio_iotype .eq. PIO_IOTYPE_NETCDF4P)) then - pio_numiotasks = 2 - pio_stride = min(pio_stride, npes/2) - endif - endif - - !-------------------------------------------------------------------------- - ! check/set/correct io pio parameters - !-------------------------------------------------------------------------- - if (pio_stride>0.and.pio_numiotasks<0) then - pio_numiotasks = max(1,npes/pio_stride) - else if(pio_numiotasks>0 .and. pio_stride<0) then - pio_stride = max(1,npes/pio_numiotasks) - else if(pio_numiotasks<0 .and. pio_stride<0) then - pio_stride = max(1,npes/4) - pio_numiotasks = max(1,npes/pio_stride) - end if - if(pio_stride == 1 .and. .not. pio_async_interface) then - pio_root = 0 - endif - if(pio_rearranger .ne. PIO_REARR_SUBSET .and. pio_rearranger .ne. PIO_REARR_BOX) then - write(shr_log_unit,*) 'pio_rearranger value, ',pio_rearranger,& - ', not supported - using PIO_REARR_BOX' - pio_rearranger = PIO_REARR_BOX - - endif - - - if (.not. pio_async_interface .and. & - pio_root + (pio_stride)*(pio_numiotasks-1) >= npes .or. & - pio_stride<=0 .or. pio_numiotasks<=0 .or. pio_root < 0 .or. & - pio_root > npes-1 ) then - if(npes<100) then - pio_stride = max(1,npes/4) - else if(npes<1000) then - pio_stride = max(1,npes/8) - else - pio_stride = max(1,npes/16) - end if - if(pio_stride>1) then - pio_numiotasks = npes/pio_stride - pio_root = min(1,npes-1) - else - pio_numiotasks = npes - pio_root = 0 - end if - if( iamroot) then - write(shr_log_unit,*) 'pio_stride, iotasks or root out of bounds - resetting to defaults: ',& - pio_stride,pio_numiotasks, pio_root - end if - end if - - end subroutine shr_pio_namelist_set - - !=============================================================================== - subroutine shr_pio_rearr_opts_set(comm, pio_rearr_comm_type, pio_rearr_comm_fcd, & - pio_rearr_comm_max_pend_req_comp2io, pio_rearr_comm_enable_hs_comp2io, & - pio_rearr_comm_enable_isend_comp2io, & - pio_rearr_comm_max_pend_req_io2comp, pio_rearr_comm_enable_hs_io2comp, & - pio_rearr_comm_enable_isend_io2comp, & - pio_numiotasks) - - ! This subroutine sets the global PIO rearranger options - ! The input args that represent the rearranger options are valid only - ! on the root proc of comm - ! The rearranger options are passed to PIO_Init() in shr_pio_init2() - - integer(SHR_KIND_IN), intent(in) :: comm - character(len=shr_kind_cs), intent(in) :: pio_rearr_comm_type, pio_rearr_comm_fcd - integer, intent(in) :: pio_rearr_comm_max_pend_req_comp2io - logical, intent(in) :: pio_rearr_comm_enable_hs_comp2io - logical, intent(in) :: pio_rearr_comm_enable_isend_comp2io - integer, intent(in) :: pio_rearr_comm_max_pend_req_io2comp - logical, intent(in) :: pio_rearr_comm_enable_hs_io2comp - logical, intent(in) :: pio_rearr_comm_enable_isend_io2comp - integer, intent(in) :: pio_numiotasks - - character(*), parameter :: subname = '(shr_pio_rearr_opts_set) ' - integer, parameter :: NUM_REARR_COMM_OPTS = 8 - integer, parameter :: PIO_REARR_COMM_DEF_MAX_PEND_REQ = 64 - ! Automatically reset if the number of maximum pending requests is set to 0 - integer, parameter :: REARR_COMM_DEF_MAX_PEND_REQ_RESET = 0 - integer(SHR_KIND_IN), dimension(NUM_REARR_COMM_OPTS) :: buf - integer :: rank, ierr - - call mpi_comm_rank(comm, rank, ierr) - call shr_mpi_chkerr(ierr,subname//' mpi_comm_rank comm_world') - - buf = 0 - ! buf(1) = comm_type - ! buf(2) = comm_fcd - ! buf(3) = max_pend_req_comp2io - ! buf(4) = enable_hs_comp2io - ! buf(5) = enable_isend_comp2io - ! buf(6) = max_pend_req_io2comp - ! buf(7) = enable_hs_io2comp - ! buf(8) = enable_isend_io2comp - if(rank == 0) then - ! buf(1) = comm_type - select case(pio_rearr_comm_type) - case ("p2p") - case ("default") - buf(1) = pio_rearr_comm_p2p - case ("coll") - buf(1) = pio_rearr_comm_coll - case default - write(shr_log_unit,*) "Invalid PIO rearranger comm type, ", pio_rearr_comm_type - write(shr_log_unit,*) "Resetting PIO rearrange comm type to p2p" - buf(1) = pio_rearr_comm_p2p - end select - - ! buf(2) = comm_fcd - select case(pio_rearr_comm_fcd) - case ("2denable") - case ("default") - buf(2) = pio_rearr_comm_fc_2d_enable - case ("io2comp") - buf(2) = pio_rearr_comm_fc_1d_io2comp - case ("comp2io") - buf(2) = pio_rearr_comm_fc_1d_comp2io - case ("disable") - buf(2) = pio_rearr_comm_fc_2d_disable - case default - write(shr_log_unit,*) "Invalid PIO rearranger comm flow control direction, ", pio_rearr_comm_fcd - write(shr_log_unit,*) "Resetting PIO rearrange comm flow control direction to 2denable" - buf(2) = pio_rearr_comm_fc_2d_enable - end select - - ! buf(3) = max_pend_req_comp2io - if((pio_rearr_comm_max_pend_req_comp2io <= 0) .and. & - (pio_rearr_comm_max_pend_req_comp2io /= PIO_REARR_COMM_UNLIMITED_PEND_REQ)) then - - if(pio_rearr_comm_max_pend_req_comp2io /= REARR_COMM_DEF_MAX_PEND_REQ_RESET) then - write(shr_log_unit, *) "Invalid PIO rearranger comm max pend req (comp2io), ",& - pio_rearr_comm_max_pend_req_comp2io - else - write(shr_log_unit, *) "User-specified PIO rearranger comm max pend req (comp2io), ",& - pio_rearr_comm_max_pend_req_comp2io, " (value will be reset as requested) " - end if - - ! Small multiple of pio_numiotasks has proven to perform - ! well empirically, and we do not want to allow maximum for - ! very large process count runs. Can improve this by - ! communicating between iotasks first, and then non-iotasks - ! to iotasks (TO DO) - write(shr_log_unit, *) "Resetting PIO rearranger comm max pend req (comp2io) to ", & - max(PIO_REARR_COMM_DEF_MAX_PEND_REQ, 2 * pio_numiotasks) - buf(3) = max(PIO_REARR_COMM_DEF_MAX_PEND_REQ, 2 * pio_numiotasks) - else - buf(3) = pio_rearr_comm_max_pend_req_comp2io - end if - - ! buf(4) = enable_hs_comp2io - if(pio_rearr_comm_enable_hs_comp2io) then - buf(4) = 1 - else - buf(4) = 0 - end if - - ! buf(5) = enable_isend_comp2io - if(pio_rearr_comm_enable_isend_comp2io) then - buf(5) = 1 - else - buf(5) = 0 - end if - - ! buf(6) = max_pend_req_io2comp - if((pio_rearr_comm_max_pend_req_io2comp <= 0) .and. & - (pio_rearr_comm_max_pend_req_io2comp /= PIO_REARR_COMM_UNLIMITED_PEND_REQ)) then - - if(pio_rearr_comm_max_pend_req_io2comp /= REARR_COMM_DEF_MAX_PEND_REQ_RESET) then - write(shr_log_unit, *) "Invalid PIO rearranger comm max pend req (io2comp), ",& - pio_rearr_comm_max_pend_req_io2comp - else - write(shr_log_unit, *) "User-specified PIO rearranger comm max pend req (io2comp), ",& - pio_rearr_comm_max_pend_req_io2comp, " (value will be reset as requested) " - end if - - write(shr_log_unit, *) "Resetting PIO rearranger comm max pend req (io2comp) to ", PIO_REARR_COMM_DEF_MAX_PEND_REQ - buf(6) = PIO_REARR_COMM_DEF_MAX_PEND_REQ - else - buf(6) = pio_rearr_comm_max_pend_req_io2comp - end if - - ! buf(7) = enable_hs_io2comp - if(pio_rearr_comm_enable_hs_io2comp) then - buf(7) = 1 - else - buf(7) = 0 - end if - - ! buf(8) = enable_isend_io2comp - if(pio_rearr_comm_enable_isend_io2comp) then - buf(8) = 1 - else - buf(8) = 0 - end if - - end if - - call shr_mpi_bcast(buf, comm) - - ! buf(1) = comm_type - ! buf(2) = comm_fcd - ! buf(3) = max_pend_req_comp2io - ! buf(4) = enable_hs_comp2io - ! buf(5) = enable_isend_comp2io - ! buf(6) = max_pend_req_io2comp - ! buf(7) = enable_hs_io2comp - ! buf(8) = enable_isend_io2comp - pio_rearr_opt_comm_type = buf(1) - pio_rearr_opt_fcd = buf(2) - pio_rearr_opt_c2i_max_pend_req = buf(3) - if(buf(4) == 0) then - pio_rearr_opt_c2i_enable_hs = .false. - else - pio_rearr_opt_c2i_enable_hs = .true. - end if - if(buf(5) == 0) then - pio_rearr_opt_c2i_enable_isend = .false. - else - pio_rearr_opt_c2i_enable_isend = .true. - end if - pio_rearr_opt_i2c_max_pend_req = buf(6) - if(buf(7) == 0) then - pio_rearr_opt_i2c_enable_hs = .false. - else - pio_rearr_opt_i2c_enable_hs = .true. - end if - if(buf(8) == 0) then - pio_rearr_opt_i2c_enable_isend = .false. - else - pio_rearr_opt_i2c_enable_isend = .true. - end if - - if(rank == 0) then - ! Log the rearranger options - write(shr_log_unit, *) "PIO rearranger options:" - write(shr_log_unit, *) " comm type = ", trim(pio_rearr_comm_type) - write(shr_log_unit, *) " comm fcd = ", trim(pio_rearr_comm_fcd) - if(pio_rearr_opt_c2i_max_pend_req == PIO_REARR_COMM_UNLIMITED_PEND_REQ) then - write(shr_log_unit, *) " max pend req (comp2io) = PIO_REARR_COMM_UNLIMITED_PEND_REQ (-1)" - else - write(shr_log_unit, *) " max pend req (comp2io) = ", pio_rearr_opt_c2i_max_pend_req - end if - write(shr_log_unit, *) " enable_hs (comp2io) = ", pio_rearr_opt_c2i_enable_hs - write(shr_log_unit, *) " enable_isend (comp2io) = ", pio_rearr_opt_c2i_enable_isend - if(pio_rearr_opt_i2c_max_pend_req == PIO_REARR_COMM_UNLIMITED_PEND_REQ) then - write(shr_log_unit, *) " max pend req (io2comp) = PIO_REARR_COMM_UNLIMITED_PEND_REQ (-1)" - else - write(shr_log_unit, *) " max pend req (io2comp) = ", pio_rearr_opt_i2c_max_pend_req - end if - write(shr_log_unit, *) " enable_hs (io2comp) = ", pio_rearr_opt_i2c_enable_hs - write(shr_log_unit, *) " enable_isend (io2comp) = ", pio_rearr_opt_i2c_enable_isend - end if - end subroutine shr_pio_rearr_opts_set - - !=============================================================================== - function shr_pio_string_toUpper(str) - - character(len=*), intent(in) :: str ! String to convert to upper case - character(len=len(str)) :: shr_pio_string_toUpper - - integer :: i ! Index - integer :: aseq ! ascii collating sequence - integer :: LowerToUpper ! integer to convert case - character(len=1) :: ctmp ! Character temporary - !------------------------------------------------------------------------------- - - LowerToUpper = iachar("A") - iachar("a") - do i = 1, len(str) - ctmp = str(i:i) - aseq = iachar(ctmp) - if ( aseq >= iachar("a") .and. aseq <= iachar("z") ) & - ctmp = achar(aseq + LowertoUpper) - shr_pio_string_toUpper(i:i) = ctmp - end do - end function shr_pio_string_toUpper - -end module shr_pio_mod diff --git a/tools/mksurfdata_esmf/src/shr_sys_mod.F90 b/tools/mksurfdata_esmf/src/shr_sys_mod.F90 index 8c51b711cc..76a898a058 100644 --- a/tools/mksurfdata_esmf/src/shr_sys_mod.F90 +++ b/tools/mksurfdata_esmf/src/shr_sys_mod.F90 @@ -1,352 +1,80 @@ -!=============================================================================== - -MODULE shr_sys_mod +module shr_sys_mod - use shr_kind_mod ! defines real & integer kinds - use shr_log_mod, only: s_loglev => shr_log_Level - use shr_log_mod, only: s_logunit => shr_log_Unit + use shr_kind_mod ! defines real & integer kinds - implicit none + implicit none + private -! PUBLIC: Public interfaces + public :: shr_sys_getenv ! get an environment variable + public :: shr_sys_abort ! abort a program - private - - public :: shr_sys_system ! make a system call - public :: shr_sys_chdir ! change current working dir - public :: shr_sys_getenv ! get an environment variable - public :: shr_sys_abort ! abort a program - public :: shr_sys_irtc ! returns real-time clock tick - public :: shr_sys_sleep ! have program sleep for a while - public :: shr_sys_flush ! flush an i/o buffer + integer :: s_loglev = 0 + integer :: s_logunit = 6 !=============================================================================== CONTAINS !=============================================================================== -!=============================================================================== -!=============================================================================== - -SUBROUTINE shr_sys_system(str,rcode) - - IMPLICIT none - - !----- arguments --- - character(*) ,intent(in) :: str ! system/shell command string - integer(SHR_KIND_IN),intent(out) :: rcode ! function return error code - - !----- functions ----- -#if (defined CRAY) || (defined UNICOSMP) - integer(SHR_KIND_IN),external :: ishell ! function to envoke shell command -#endif -#if (defined OSF1 || defined SUNOS || (defined LINUX && !defined __GFORTRAN__ && !defined CATAMOUNT)) - integer(SHR_KIND_IN),external :: system ! function to envoke shell command -#endif - - !----- local ----- -#if (defined CATAMOUNT) - character(2*SHR_KIND_CL) :: file1 ! one or two filenames - character( SHR_KIND_CL) :: file2 ! 2nd file name - integer(SHR_KIND_IN) :: iloc ! index/location within a string -#endif - - !----- formats ----- - character(*),parameter :: subName = '(shr_sys_system) ' - character(*),parameter :: F00 = "('(shr_sys_system) ',4a)" - -!------------------------------------------------------------------------------- -! PURPOSE: an architecture independant system call -! NOTE: -! - for Catamount (Cray, pheonix at ORNL) there is no system call -- workarounds -! exist only for simple "rm" and "cp" commands -!------------------------------------------------------------------------------- - - -#if (defined CRAY) || (defined UNICOSMP) - - rcode=ishell(str) - -#elif (defined IRIX64 || defined NEC_SX) - - rcode = 0 - call system(str) - -#elif (defined AIX) - - call system(str,rcode) - -#elif (defined OSF1 || defined SUNOS || defined __GFORTRAN__ || (defined LINUX && !defined CATAMOUNT)) - - rcode = system(str) - -#elif (defined CATAMOUNT) - if (str(1:3) == 'rm ') then - call unlink(str(4:)) - if (s_loglev > 0) write(s_logunit,F00) 'CATAMOUNT unlink ',trim(str(4:)) - rcode = 0 - elseif (str(1:3) == 'mv ') then - file1 = str(4:) - iloc = index(file1,' ') + 3 - if (iloc < 6) then - if (s_loglev > 0) write(s_logunit,*) 'CATAMOUNT mv error ',trim(str),iloc - rcode = -1 - else - file1 = str(4:iloc) - file2 = str(iloc+1:) - call rename(trim(file1),trim(file2)) - if (s_loglev > 0) write(s_logunit,F00) 'CATAMOUNT rename ',trim(file1)," ",trim(file2) - rcode = 0 - endif - else - rcode = -1 - endif - -#else - - write(s_logunit,F00) 'ERROR: no implementation of system call for this architecture' - call shr_sys_abort(subName//'no implementation of system call for this architecture') - -#endif - -END SUBROUTINE shr_sys_system - -!=============================================================================== -!=============================================================================== - -SUBROUTINE shr_sys_chdir(path, rcode) - - IMPLICIT none - - !----- arguments ----- - character(*) ,intent(in) :: path ! chdir to this dir - integer(SHR_KIND_IN),intent(out) :: rcode ! return code - - !----- local ----- - integer(SHR_KIND_IN) :: lenpath ! length of path -#if (defined AIX || defined OSF1 || defined SUNOS || (defined LINUX && !defined __GFORTRAN__) || defined NEC_SX) - integer(SHR_KIND_IN),external :: chdir ! AIX system call -#endif - - !----- formats ----- - character(*),parameter :: subName = '(shr_sys_chdir) ' - character(*),parameter :: F00 = "('(shr_sys_chdir) ',4a)" - -!------------------------------------------------------------------------------- -! PURPOSE: an architecture independant system call -!------------------------------------------------------------------------------- - - lenpath=len_trim(path) + subroutine shr_sys_abort(string,rc) -#if (defined IRIX64 || defined CRAY || defined UNICOSMP) - - call pxfchdir(path, lenpath, rcode) - -#elif (defined AIX) - - rcode = chdir(%ref(path(1:lenpath)//'\0')) - -#elif (defined OSF1 || defined SUNOS || defined LINUX || defined NEC_SX) - - rcode=chdir(path(1:lenpath)) - -#else + !------------------------------------------------------------------------------- + ! PURPOSE: consistent stopping mechanism + !------------------------------------------------------------------------------- - write(s_logunit,F00) 'ERROR: no implementation of chdir for this architecture' - call shr_sys_abort(subname//'no implementation of chdir for this machine') + character(len=*) , optional :: string ! error message string + integer , optional :: rc ! error code -#endif + ! local variables + character(*),parameter :: subName = '(shr_sys_abort) ' + character(*),parameter :: F00 = "('(shr_sys_abort) ',4a)" -END SUBROUTINE shr_sys_chdir + if (len_trim(string) > 0) write(s_logunit,F00) 'ERROR: '//trim(string) + write(s_logunit,F00) 'WARNING: stopping' + call abort() + stop -!=============================================================================== -!=============================================================================== + end subroutine shr_sys_abort -SUBROUTINE shr_sys_getenv(name, val, rcode) + !=============================================================================== + subroutine shr_sys_getenv(name, val, rcode) - IMPLICIT none + !------------------------------------------------------------------------------- + ! PURPOSE: an architecture independant system call + !------------------------------------------------------------------------------- - !----- arguments ----- - character(*) ,intent(in) :: name ! env var name - character(*) ,intent(out) :: val ! env var value - integer(SHR_KIND_IN),intent(out) :: rcode ! return code + ! input/output variables + character(len=*) ,intent(in) :: name ! env var name + character(len=*) ,intent(out) :: val ! env var value + integer ,intent(out) :: rcode ! return code - !----- local ----- - integer(SHR_KIND_IN) :: lenname ! length of env var name - integer(SHR_KIND_IN) :: lenval ! length of env var value - character(SHR_KIND_CL) :: tmpval ! temporary env var value + !----- local ----- + integer :: lenname ! length of env var name + integer :: lenval ! length of env var value + character(SHR_KIND_CL) :: tmpval ! temporary env var value + character(*),parameter :: subName = '(shr_sys_getenv) ' + character(*),parameter :: F00 = "('(shr_sys_getenv) ',4a)" - !----- formats ----- - character(*),parameter :: subName = '(shr_sys_getenv) ' - character(*),parameter :: F00 = "('(shr_sys_getenv) ',4a)" - -!------------------------------------------------------------------------------- -! PURPOSE: an architecture independant system call -!------------------------------------------------------------------------------- - - lenname=len_trim(name) + lenname=len_trim(name) #if (defined IRIX64 || defined CRAY || defined UNICOSMP) - call pxfgetenv(name, lenname, val, lenval, rcode) + call pxfgetenv(name, lenname, val, lenval, rcode) #elif (defined AIX || defined OSF1 || defined SUNOS || defined LINUX || defined NEC_SX) - call getenv(trim(name),tmpval) - val=trim(tmpval) - rcode = 0 - if (len_trim(val) == 0 ) rcode = 1 - if (len_trim(val) > SHR_KIND_CL) rcode = 2 - -#else - - write(s_logunit,F00) 'ERROR: no implementation of getenv for this architecture' - call shr_sys_abort(subname//'no implementation of getenv for this machine') - -#endif - -END SUBROUTINE shr_sys_getenv - -!=============================================================================== -!=============================================================================== - -SUBROUTINE shr_sys_abort(string,rc) - - IMPLICIT none - - character(*) ,optional :: string ! error message string - integer(SHR_KIND_IN),optional :: rc ! error code - - !----- formats ----- - character(*),parameter :: subName = '(shr_sys_abort) ' - character(*),parameter :: F00 = "('(shr_sys_abort) ',4a)" - -!------------------------------------------------------------------------------- -! PURPOSE: consistent stopping mechanism -!------------------------------------------------------------------------------- - - call shr_sys_flush(s_logunit) - if (len_trim(string) > 0) write(s_logunit,F00) 'ERROR: '//trim(string) - write(s_logunit,F00) 'WARNING: stopping' - call shr_sys_flush(s_logunit) - call abort() - stop - -END SUBROUTINE shr_sys_abort - -!=============================================================================== -!=============================================================================== - -integer(SHR_KIND_I8) FUNCTION shr_sys_irtc( rate ) - - IMPLICIT none - - !----- arguments ----- - integer(SHR_KIND_I8), optional :: rate - - !----- local ----- - integer(SHR_KIND_IN) :: count - integer(SHR_KIND_IN) :: count_rate - integer(SHR_KIND_IN) :: count_max - integer(SHR_KIND_IN),save :: last_count = -1 - integer(SHR_KIND_I8),save :: count_offset = 0 - - !----- formats ----- - character(*),parameter :: subName = '(shr_sys_irtc) ' - character(*),parameter :: F00 = "('(shr_sys_irtc) ',4a)" - -!------------------------------------------------------------------------------- -! emulates Cray/SGI irtc function (returns clock tick since last reboot) -!------------------------------------------------------------------------------- - - call system_clock(count=count,count_rate=count_rate, count_max=count_max) - if ( present(rate) ) rate = count_rate - shr_sys_irtc = count - - !--- adjust for clock wrap-around --- - if ( last_count /= -1 ) then - if ( count < last_count ) count_offset = count_offset + count_max - end if - shr_sys_irtc = shr_sys_irtc + count_offset - last_count = count - -END FUNCTION shr_sys_irtc - -!=============================================================================== -!=============================================================================== - -SUBROUTINE shr_sys_sleep(sec) - - IMPLICIT none - - !----- arguments ----- - real (SHR_KIND_R8),intent(in) :: sec ! number of seconds to sleep - - !----- local ----- - integer(SHR_KIND_IN) :: isec ! integer number of seconds - integer(SHR_KIND_IN) :: rcode ! return code - character(90) :: str ! system call string - - !----- formats ----- - character(*),parameter :: subName = '(shr_sys_sleep) ' - character(*),parameter :: F00 = "('(shr_sys_sleep) ',4a)" - character(*),parameter :: F10 = "('sleep ',i8 )" - -!------------------------------------------------------------------------------- -! PURPOSE: Sleep for approximately sec seconds -!------------------------------------------------------------------------------- - - isec = nint(sec) - - if (isec < 0) then - if (s_loglev > 0) write(s_logunit,F00) 'ERROR: seconds must be > 0, sec=',sec - else if (isec == 0) then - ! Don't consider this an error and don't call system sleep - else -#if defined(CATAMOUNT) - call sleep(isec) -#else - write(str,FMT=F10) isec - call shr_sys_system( str, rcode ) -#endif - endif - -END SUBROUTINE shr_sys_sleep - -!=============================================================================== -!=============================================================================== - -SUBROUTINE shr_sys_flush(unit) - - IMPLICIT none - - !----- arguments ----- - integer(SHR_KIND_IN) :: unit ! flush output buffer for this unit - - !----- formats ----- - character(*),parameter :: subName = '(shr_sys_flush) ' - character(*),parameter :: F00 = "('(shr_sys_flush) ',4a)" - -!------------------------------------------------------------------------------- -! PURPOSE: an architecture independant system call -!------------------------------------------------------------------------------- - -#if (defined IRIX64 || defined CRAY || defined OSF1 || defined SUNOS || defined LINUX || defined NEC_SX || defined UNICOSMP) - - call flush(unit) - -#elif (defined AIX) - - call flush_(unit) + call getenv(trim(name),tmpval) + val=trim(tmpval) + rcode = 0 + if (len_trim(val) == 0 ) rcode = 1 + if (len_trim(val) > SHR_KIND_CL) rcode = 2 #else - if (s_loglev > 0) write(s_logunit,F00) 'WARNING: no implementation of flush for this architecture' + write(s_logunit,F00) 'ERROR: no implementation of getenv for this architecture' + call shr_sys_abort(subname//'no implementation of getenv for this machine') #endif -END SUBROUTINE shr_sys_flush - -!=============================================================================== -!=============================================================================== + end subroutine shr_sys_getenv -END MODULE shr_sys_mod +end module shr_sys_mod From ceb6af19004404ca7a2af7e37f6a4c0575a35cdb Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 20 Jan 2022 15:23:02 -0700 Subject: [PATCH 022/614] added mkFileMod.F90 --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index fe68f560f6..56a8bde45f 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -69,15 +69,15 @@ subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) ! Create and open file !--------------------------- - ! TODO: how to translate the following into the pio call - !call check_ret(nf_create(trim(fname), ior(nf_clobber,nf_64bit_offset), ncid), subname) - call mkpio_wopen(pioid, trim(fname), clobber=.true.) ! TODO: what about setting no fill values? + call mkpio_wopen(pioid, trim(fname), clobber=.true.) + call ESMF_LogWrite(subname//'successfully opened output file '//trim(fname), ESMF_LOGMSG_INFO) !--------------------------- ! Define dimensions. !--------------------------- + call ESMF_LogWrite(trim(subname)//'defining dimensions', ESMF_LOGMSG_INFO) if (outnc_1d) then rcode = pio_def_dim(pioid, 'gridcell', nx, dimid) else @@ -103,6 +103,7 @@ subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) ! Set global attributes. !--------------------------- + call ESMF_LogWrite(trim(subname)//'setting global attributes', ESMF_LOGMSG_INFO) str = 'NCAR-CSM' rcode = pio_put_att(pioid, pio_global, "Conventions", trim(str)) From a7597b5d735306a723f6585d2511d8183693ea2d Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 20 Jan 2022 21:12:36 -0700 Subject: [PATCH 023/614] more cleanup --- tools/mksurfdata_esmf/src/CMakeLists.txt | 2 - tools/mksurfdata_esmf/src/chkerrMod.F90 | 1 - tools/mksurfdata_esmf/src/fileutils.F90 | 38 --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 93 +++--- tools/mksurfdata_esmf/src/mkpftMod.F90 | 24 +- tools/mksurfdata_esmf/src/mkpioMod.F90 | 52 +--- tools/mksurfdata_esmf/src/mksoilMod.F90 | 345 +++++----------------- tools/mksurfdata_esmf/src/mksurfdata | Bin 4027320 -> 4023536 bytes tools/mksurfdata_esmf/src/mksurfdata.F90 | 16 +- tools/mksurfdata_esmf/src/mkutilsMod.F90 | 23 ++ tools/mksurfdata_esmf/src/mkvarctl.F90 | 233 ++++++++------- tools/mksurfdata_esmf/src/shr_log_mod.F90 | 13 - 12 files changed, 283 insertions(+), 557 deletions(-) delete mode 100644 tools/mksurfdata_esmf/src/chkerrMod.F90 delete mode 100644 tools/mksurfdata_esmf/src/fileutils.F90 delete mode 100644 tools/mksurfdata_esmf/src/shr_log_mod.F90 diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index de7574c0e3..2699c3f2df 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -24,11 +24,9 @@ set(SRCFILES mkvarctl.F90 mkesmfMod.F90 mkutilsMod.F90 mkchecksMod.F90 - fileutils.F90 nanMod.F90 shr_const_mod.F90 shr_kind_mod.F90 - shr_log_mod.F90 shr_string_mod.F90 shr_sys_mod.F90) diff --git a/tools/mksurfdata_esmf/src/chkerrMod.F90 b/tools/mksurfdata_esmf/src/chkerrMod.F90 deleted file mode 100644 index cf38ecd64a..0000000000 --- a/tools/mksurfdata_esmf/src/chkerrMod.F90 +++ /dev/null @@ -1 +0,0 @@ -module mkutilMod diff --git a/tools/mksurfdata_esmf/src/fileutils.F90 b/tools/mksurfdata_esmf/src/fileutils.F90 deleted file mode 100644 index 2a28ac3ba9..0000000000 --- a/tools/mksurfdata_esmf/src/fileutils.F90 +++ /dev/null @@ -1,38 +0,0 @@ -module fileutils - - !----------------------------------------------------------------------- - ! Module containing file I/O utilities - !----------------------------------------------------------------------- - - use shr_sys_mod, only : shr_sys_abort - - implicit none - - public :: get_filename !Returns filename given full pathname - -!----------------------------------------------------------------------- -contains -!----------------------------------------------------------------------- - - character(len=256) function get_filename (fulpath) - ! Returns filename given full pathname - - ! input/output variables - character(len=*), intent(in) :: fulpath !full pathname - - ! local variables: - integer :: i !loop index - integer :: klen !length of fulpath character string - !------------------------------------------------------------------------ - - klen = len_trim(fulpath) - do i = klen, 1, -1 - if (fulpath(i:i) == '/') go to 10 - end do - i = 0 -10 get_filename = fulpath(i+1:klen) - - return - end function get_filename - -end module fileutils diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 56a8bde45f..fd83c79932 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -19,7 +19,7 @@ subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) use pio use shr_kind_mod , only : r8 => shr_kind_r8 use shr_sys_mod , only : shr_sys_getenv - use fileutils , only : get_filename + use mkutilsMod , only : get_filename use mkvarpar , only : nlevsoi, numrad, numstdpft #ifdef TODO use mkurbanparMod, only : numurbl, nlevurb @@ -62,7 +62,7 @@ subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) integer, allocatable :: ind1D(:) ! Indices of 1D harvest variables integer, allocatable :: ind2D(:) ! Indices of 2D harvest variables integer :: rcode - character(len=32) :: subname = 'mkfile' ! subroutine name + character(len=*), parameter :: subname=' (mkfile) ' !----------------------------------------------------------------------- !--------------------------- @@ -77,7 +77,9 @@ subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) ! Define dimensions. !--------------------------- - call ESMF_LogWrite(trim(subname)//'defining dimensions', ESMF_LOGMSG_INFO) + call ESMF_LogWrite(subname//' defining dimensions', ESMF_LOGMSG_INFO) + write(6,*)'DEBUG: outnc_1d = ',outnc_1d + if (outnc_1d) then rcode = pio_def_dim(pioid, 'gridcell', nx, dimid) else @@ -103,7 +105,8 @@ subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) ! Set global attributes. !--------------------------- - call ESMF_LogWrite(trim(subname)//'setting global attributes', ESMF_LOGMSG_INFO) + call ESMF_LogWrite(subname//'setting global attributes', ESMF_LOGMSG_INFO) + str = 'NCAR-CSM' rcode = pio_put_att(pioid, pio_global, "Conventions", trim(str)) @@ -232,6 +235,7 @@ subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) ! Define variables ! ---------------------------------------------------------------------- + call ESMF_LogWrite(subname//'defining variables', ESMF_LOGMSG_INFO) if ( .not. outnc_double ) then xtype = PIO_REAL else @@ -436,22 +440,7 @@ subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) lev1name='nglcec', & long_name='mean elevation on glacier elevation classes', units='m') - if ( outnc_3dglc ) then - call mkpio_def_spatial_var(pioid, varname='PCT_GLC_MEC_GIC', xtype=xtype, & - lev1name='nglcec', & - long_name='percent smaller glaciers and ice caps for each glacier elevation class (% of landunit)', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='PCT_GLC_MEC_ICESHEET', xtype=xtype, & - lev1name='nglcec', & - long_name='percent ice sheet for each glacier elevation class (% of landunit)', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='PCT_GLC_GIC', xtype=xtype, & - long_name='percent ice caps/glaciers (% of landunit)', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='PCT_GLC_ICESHEET', xtype=xtype, & - long_name='percent ice sheet (% of landunit)', units='unitless') - - end if + call ESMF_LogWrite('DEBUG: here1', ESMF_LOGMSG_INFO) if ( outnc_3dglc ) then call mkpio_def_spatial_var(pioid, varname='PCT_GLC_MEC_GIC', xtype=xtype, & @@ -467,50 +456,62 @@ subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) call mkpio_def_spatial_var(pioid, varname='PCT_GLC_ICESHEET', xtype=xtype, & long_name='percent ice sheet (% of landunit)', units='unitless') - end if + call ESMF_LogWrite('DEBUG: here2', ESMF_LOGMSG_INFO) + call mkpio_def_spatial_var(pioid, varname='PCT_URBAN', xtype=xtype, & lev1name='numurbl', & long_name='percent urban for each density type', units='unitless') + call ESMF_LogWrite('DEBUG: here3', ESMF_LOGMSG_INFO) + call mkpio_def_spatial_var(pioid, varname='URBAN_REGION_ID', xtype=PIO_INT, & long_name='urban region ID', units='unitless') - ! call harvdata%getFieldsIdx( ind1D, ind2D ) - ! do j = 1, harvdata%num1Dfields() - ! call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind1D(j),constant=.true.), xtype=xtype, & - ! long_name=mkharvest_longname(ind1D(j)), units=mkharvest_units(ind1D(j)) ) - ! end do - ! do j = 1, harvdata%num2Dfields() - ! call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind2D(j),constant=.true.), xtype=xtype, & - ! lev1name=harvdata%getFieldsDim(ind2D(j)), & - ! long_name=mkharvest_longname(ind2D(j)), units=mkharvest_units(ind2D(j)) ) - ! end do - ! deallocate(ind1D, ind2D) +#ifdef TODO + call harvdata%getFieldsIdx( ind1D, ind2D ) + do j = 1, harvdata%num1Dfields() + call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind1D(j),constant=.true.), xtype=xtype, & + long_name=mkharvest_longname(ind1D(j)), units=mkharvest_units(ind1D(j)) ) + end do + do j = 1, harvdata%num2Dfields() + call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind2D(j),constant=.true.), xtype=xtype, & + lev1name=harvdata%getFieldsDim(ind2D(j)), & + long_name=mkharvest_longname(ind2D(j)), units=mkharvest_units(ind2D(j)) ) + end do + deallocate(ind1D, ind2D) +#endif + + call ESMF_LogWrite('DEBUG: here4', ESMF_LOGMSG_INFO) else - ! call harvdata%getFieldsIdx( ind1D, ind2D ) - ! do j = 1, harvdata%num1Dfields() - ! call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind1D(j),constant=.false.), xtype=xtype, & - ! lev1name='time', & - ! long_name=mkharvest_longname(ind1D(j)), units=mkharvest_units(ind1D(j)) ) - ! end do - ! do j = 1, harvdata%num2Dfields() - ! call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind2D(j),constant=.false.), xtype=xtype, & - ! lev1name=harvdata%getFieldsDim(ind2D(j)), lev2name="time", & - ! long_name=mkharvest_longname(ind2D(j)), units=mkharvest_units(ind2D(j)) ) - ! end do - ! deallocate(ind1D, ind2D) +#ifdef TODO + call harvdata%getFieldsIdx( ind1D, ind2D ) + do j = 1, harvdata%num1Dfields() + call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind1D(j),constant=.false.), xtype=xtype, & + lev1name='time', & + long_name=mkharvest_longname(ind1D(j)), units=mkharvest_units(ind1D(j)) ) + end do + do j = 1, harvdata%num2Dfields() + call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind2D(j),constant=.false.), xtype=xtype, & + lev1name=harvdata%getFieldsDim(ind2D(j)), lev2name="time", & + long_name=mkharvest_longname(ind2D(j)), units=mkharvest_units(ind2D(j)) ) + end do + deallocate(ind1D, ind2D) +#endif end if ! .not. dynlanduse - ! End of define mode + call ESMF_LogWrite('DEBUG: here5', ESMF_LOGMSG_INFO) - call mkpio_enddef(pioid) + ! End of define mode + rcode = pio_enddef(pioid) + call ESMF_LogWrite('DEBUG: closing file', ESMF_LOGMSG_INFO) call pio_closefile(pioid) + call ESMF_LogWrite('DEBUG: closed file', ESMF_LOGMSG_INFO) end subroutine mkfile diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index d6f1b04e4a..2866e24656 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -946,37 +946,21 @@ subroutine mkpft_check_oride( error_happened ) end subroutine mkpft_check_oride !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkpftAtt - ! - ! !INTERFACE: subroutine mkpftAtt( ncid, dynlanduse, xtype ) - ! + ! !DESCRIPTION: ! make PFT attributes on the output file - ! - use mkncdio , only : check_ret, ncd_defvar, ncd_def_spatial_var - use fileutils , only : get_filename + + use mkutilsMod , only : get_filename use mkvarctl , only : mksrf_fvegtyp, mksrf_flai use mkvarpar ! !ARGUMENTS: - implicit none - include 'netcdf.inc' integer, intent(in) :: ncid ! NetCDF file ID to write out to logical, intent(in) :: dynlanduse ! if dynamic land-use file integer, intent(in) :: xtype ! external type to output real data as - ! - ! !CALLED FROM: - ! subroutine mkfile in module mkfileMod - ! - ! !REVISION HISTORY: - ! Author: Erik Kluzek - ! - ! + ! !LOCAL VARIABLES: - !EOP integer :: pftsize ! size of lsmpft dimension integer :: natpftsize ! size of natpft dimension integer :: dimid ! input netCDF id's diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 79f8086b8b..050d439afc 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -17,8 +17,6 @@ module mkpioMod public :: mkpio_iodesc_output public :: mkpio_wopen public :: mkpio_close - public :: mkpio_redef - public :: mkpio_enddef public :: mkpio_defvar public :: mkpio_def_spatial_var public :: mkpio_get_dim_lengths @@ -92,8 +90,8 @@ subroutine mkpio_get_rawdata(filename, varname, mesh_i, data_i, rc) else call shr_sys_abort(subName//"ERROR: only real and double types are supported") end if - call pio_closefile(pioid) call pio_freedecomp(pioid, pio_iodesc) + call pio_closefile(pioid) call ESMF_VMLogMemInfo("After pio_read_darry in regrid_data") end subroutine mkpio_get_rawdata @@ -207,7 +205,7 @@ subroutine mkpio_wopen(pioid, filename, clobber) use pio , only : PIO_IOTYPE_PNETCDF, PIO_IOTYPE_NETCDF, PIO_BCAST_ERROR, PIO_INTERNAL_ERROR use pio , only : pio_openfile, pio_createfile, PIO_GLOBAL, pio_enddef - use pio , only : pio_put_att, pio_redef, pio_get_att + use pio , only : pio_put_att, pio_get_att use pio , only : pio_seterrorhandling, pio_file_is_open, pio_clobber, pio_write, pio_noclobber ! input/output arguments @@ -291,38 +289,6 @@ subroutine mkpio_close(pioid, filename, rc) end subroutine mkpio_close - !=============================================================================== - subroutine mkpio_redef(pioid) - - use pio, only : pio_redef - - ! input/output variables - type(file_desc_t), intent(inout) :: pioid - - ! local variables - integer :: rcode - !------------------------------------------------------------------------------- - - rcode = pio_redef(pioid) - - end subroutine mkpio_redef - - !=============================================================================== - subroutine mkpio_enddef(pioid) - - use pio, only : pio_enddef - - ! input/output variables - type(file_desc_t), intent(inout) :: pioid - - ! local variables - integer :: rcode - !------------------------------------------------------------------------------- - - rcode = pio_enddef(pioid) - - end subroutine mkpio_enddef - !=============================================================================== subroutine mkpio_defvar(pioid, varname, xtype, & dim1name, dim2name, dim3name, dim4name, dim5name, & @@ -428,9 +394,8 @@ subroutine mkpio_def_spatial_var_0lev(pioid, varname, xtype, long_name, units) integer , intent(in) :: xtype ! external type character(len=*) , intent(in) :: long_name ! attribute character(len=*) , intent(in) :: units ! attribute - ! - ! !LOCAL VARIABLES: + ! !LOCAL VARIABLES: character(len=*), parameter :: subname = 'mkpio_def_spatial_var_0lev' !----------------------------------------------------------------------- @@ -452,10 +417,9 @@ subroutine mkpio_def_spatial_var_1lev(pioid, varname, xtype, lev1name, long_name ! ! The variable in question has one level (or time) dimension in addition to its ! spatial dimensions - ! - ! !USES: + use mkvarctl, only : outnc_1d - ! + ! !ARGUMENTS: type(file_desc_t) , intent(in) :: pioid character(len=*) , intent(in) :: varname ! variable name @@ -463,9 +427,8 @@ subroutine mkpio_def_spatial_var_1lev(pioid, varname, xtype, lev1name, long_name character(len=*) , intent(in) :: lev1name ! name of level (or time) dimension character(len=*) , intent(in) :: long_name ! attribute character(len=*) , intent(in) :: units ! attribute - ! - ! !LOCAL VARIABLES: + ! !LOCAL VARIABLES: character(len=*), parameter :: subname = 'mkpio_def_spatial_var_1lev' !----------------------------------------------------------------------- @@ -501,9 +464,8 @@ subroutine mkpio_def_spatial_var_2lev(pioid, varname, xtype, lev1name, lev2name, character(len=*) , intent(in) :: lev2name ! name of second level (or time) dimension character(len=*) , intent(in) :: long_name ! attribute character(len=*) , intent(in) :: units ! attribute - ! - ! !LOCAL VARIABLES: + ! !LOCAL VARIABLES: character(len=*), parameter :: subname = 'mkpio_def_spatial_var_2lev' !----------------------------------------------------------------------- diff --git a/tools/mksurfdata_esmf/src/mksoilMod.F90 b/tools/mksurfdata_esmf/src/mksoilMod.F90 index 74dfb2c3bd..8e580cc9c3 100644 --- a/tools/mksurfdata_esmf/src/mksoilMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilMod.F90 @@ -1,80 +1,42 @@ module mksoilMod + !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mksoilMod - ! - ! !DESCRIPTION: ! Make soil data (texture, color and organic) - ! - ! !REVISION HISTORY: - ! Author: Erik Kluzek - ! !----------------------------------------------------------------------- - !!USES: + use shr_kind_mod, only : r8 => shr_kind_r8, r4=>shr_kind_r4 use mkdomainMod , only : domain_checksame use mksoilUtilsMod, only : mkrank, dominant_soil_color - implicit none - SAVE + implicit none private ! By default make data private - ! - ! !PUBLIC MEMBER FUNCTIONS: - ! - public mksoilInit ! Soil Initialization + public mksoilInit ! Soil Initialization public mksoilAtt ! Add attributes to output file - public mksoiltex ! Set soil texture public mkorganic ! Set organic soil public mksoilcol ! Set soil color public mkfmax ! Make percent fmax - ! - ! !PUBLIC DATA MEMBERS: - ! + + private :: mksoiltexInit ! Soil texture Initialization + private :: mksoilcolInit ! Soil color Initialization + private :: mksoilfmaxInit ! Soil fmax Initialization + real(r8), public, parameter :: unset = -999.99_r8 ! Flag to signify soil texture override not set real(r8), public :: soil_sand = unset ! soil texture sand % to override with real(r8), public :: soil_clay = unset ! soil texture clay % to override with real(r8), public :: soil_fmax = unset ! soil max saturation frac to override with integer , parameter :: unsetcol = -999 ! flag to indicate soil color NOT set integer , public :: soil_color= unsetcol ! soil color to override with - ! - ! !PRIVATE DATA MEMBERS: - ! - ! !PRIVATE MEMBER FUNCTIONS: - private :: mksoiltexInit ! Soil texture Initialization - private :: mksoilcolInit ! Soil color Initialization - private :: mksoilfmaxInit ! Soil fmax Initialization - !EOP - !=============================================================== +!=============================================================== contains - !=============================================================== +!=============================================================== - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mksoilInit - ! - ! !INTERFACE: subroutine mksoilInit( ) - ! - ! !DESCRIPTION: + ! Initialize the different soil types - ! !USES: - ! - ! !ARGUMENTS: - implicit none - ! - ! !REVISION HISTORY: - ! Author: Erik Kluzek - ! - ! - ! !LOCAL VARIABLES: - !EOP - character(len=32) :: subname = 'mksoilInit' - !----------------------------------------------------------------------- + call mksoiltexInit() call mksoilcolInit() call mksoilfmaxInit() @@ -82,26 +44,11 @@ subroutine mksoilInit( ) end subroutine mksoilInit !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mksoiltexInit - ! - ! !INTERFACE: subroutine mksoiltexInit( ) - ! - ! !DESCRIPTION: + ! Initialize of make soil texture - ! !USES: - ! - ! !ARGUMENTS: - implicit none - ! - ! !REVISION HISTORY: - ! Author: Erik Kluzek - ! - ! + ! !LOCAL VARIABLES: - !EOP real(r8) :: sumtex character(len=32) :: subname = 'mksoiltexInit' !----------------------------------------------------------------------- @@ -129,78 +76,60 @@ subroutine mksoiltexInit( ) end subroutine mksoiltexInit !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mksoiltex - ! - ! !INTERFACE: subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) - ! - ! !DESCRIPTION: + ! make %sand and %clay from IGBP soil data, which includes ! igbp soil 'mapunits' and their corresponding textures - ! - ! !USES: + use mkdomainMod, only : domain_type, domain_clean, domain_read use mkgridmapMod use mkvarpar use mkvarctl use mkncdio - ! - ! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain + + ! input/output variables + type(domain_type) , intent(in) :: ldomain character(len=*) , intent(in) :: mapfname ! input mapping file name character(len=*) , intent(in) :: datfname ! input data file name integer , intent(in) :: ndiag ! unit number for diag out real(r8) , intent(out):: sand_o(:,:) ! % sand (output grid) real(r8) , intent(out):: clay_o(:,:) ! % clay (output grid) - ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: Mariana Vertenstein - ! - ! - ! !LOCAL VARIABLES: - !EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - character(len=38) :: typ ! soil texture based on ... - integer :: nlay ! number of soil layers - integer :: mapunitmax ! max value of igbp soil mapunits - integer :: mapunittemp ! temporary igbp soil mapunit - integer :: maxovr + + ! local variables + character(len=38) :: typ ! soil texture based on ... + integer :: nlay ! number of soil layers + integer :: mapunitmax ! max value of igbp soil mapunits + integer :: mapunittemp ! temporary igbp soil mapunit + integer :: maxovr integer , allocatable :: novr(:) integer , allocatable :: kmap(:,:) real(r8), allocatable :: kwgt(:,:) integer , allocatable :: kmax(:) real(r8), allocatable :: wst(:) - real(r8), allocatable :: sand_i(:,:) ! input grid: percent sand - real(r8), allocatable :: clay_i(:,:) ! input grid: percent clay - real(r8), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer, parameter :: num=2 ! set soil mapunit number - integer :: wsti(num) ! index to 1st and 2nd largest wst - integer, parameter :: nlsm=4 ! number of soil textures - character(len=38) :: soil(0:nlsm) ! name of each soil texture - real(r8) :: gast_i(0:nlsm) ! global area, by texture type - real(r8) :: gast_o(0:nlsm) ! global area, by texture type - real(r8) :: wt ! map overlap weight - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - integer :: l,k,n,m,ni,no,ns_i,ns_o ! indices - integer :: k1,k2 ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - integer :: miss = 99999 ! missing data indicator - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - logical :: found ! temporary - integer :: kmap_max ! maximum overlap weights - integer, parameter :: kmap_max_min = 90 ! kmap_max mininum value - integer, parameter :: km_mx_ns_prod = 160000 ! product of kmap_max*ns_o to keep constant + real(r8), allocatable :: sand_i(:,:) ! input grid: percent sand + real(r8), allocatable :: clay_i(:,:) ! input grid: percent clay + real(r8), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + integer, parameter :: num=2 ! set soil mapunit number + integer :: wsti(num) ! index to 1st and 2nd largest wst + integer, parameter :: nlsm=4 ! number of soil textures + character(len=38) :: soil(0:nlsm) ! name of each soil texture + real(r8) :: gast_i(0:nlsm) ! global area, by texture type + real(r8) :: gast_o(0:nlsm) ! global area, by texture type + real(r8) :: wt ! map overlap weight + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + integer :: l,k,n,m,ni,no,ns_i,ns_o ! indices + integer :: k1,k2 ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ier ! error status + integer :: miss = 99999 ! missing data indicator + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + logical :: found ! temporary + integer :: kmap_max ! maximum overlap weights + integer, parameter :: kmap_max_min = 90 ! kmap_max mininum value + integer, parameter :: km_mx_ns_prod = 160000 ! product of kmap_max*ns_o to keep constant character(len=32) :: subname = 'mksoiltex' !----------------------------------------------------------------------- @@ -505,28 +434,11 @@ subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) end subroutine mksoiltex !----------------------------------------------------------------------- - - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mksoilcolInit - ! - ! !INTERFACE: subroutine mksoilcolInit( ) ! - ! !DESCRIPTION: ! Initialize of make soil color - ! !USES: - ! - ! !ARGUMENTS: - implicit none - ! - ! !REVISION HISTORY: - ! Author: Erik Kluzek - ! - ! - ! !LOCAL VARIABLES: - !EOP + + ! local variables real(r8) :: sumtex character(len=32) :: subname = 'mksoilcolInit' !----------------------------------------------------------------------- @@ -539,61 +451,41 @@ subroutine mksoilcolInit( ) end if write(6,*) 'Replace soil color for all points with: ', soil_color end if - end subroutine mksoilcolInit + end subroutine mksoilcolInit !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mksoilcol - ! - ! !INTERFACE: subroutine mksoilcol(ldomain, mapfname, datfname, ndiag, & soil_color_o, nsoicol) ! - ! !DESCRIPTION: ! make %sand and %clay from IGBP soil data, which includes ! igbp soil 'mapunits' and their corresponding textures ! - ! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod use mkvarpar use mkvarctl use mkncdio - ! + ! !ARGUMENTS: - implicit none type(domain_type), intent(in) :: ldomain character(len=*) , intent(in) :: mapfname ! input mapping file name character(len=*) , intent(in) :: datfname ! input data file name integer , intent(in) :: ndiag ! unit number for diag out integer , intent(out):: soil_color_o(:) ! soil color classes integer , intent(out):: nsoicol ! number of soil colors - ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: Mariana Vertenstein - ! - ! + ! !LOCAL VARIABLES: - !EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: gast_i(:) ! global area, by surface type - real(r8), allocatable :: gast_o(:) ! global area, by surface type - integer , allocatable :: soil_color_i(:) ! input grid: BATS soil color - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - character(len=35), allocatable :: col(:) ! name of each color - integer :: k,l,m,ni,no,ns_i,ns_o ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + real(r8), allocatable :: gast_i(:) ! global area, by surface type + real(r8), allocatable :: gast_o(:) ! global area, by surface type + integer , allocatable :: soil_color_i(:) ! input grid: BATS soil color + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + character(len=35), allocatable :: col(:) ! name of each color + integer :: k,l,m,ni,no,ns_i,ns_o ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ier ! error status + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 character(len=32) :: subname = 'mksoilcol' !----------------------------------------------------------------------- @@ -705,43 +597,6 @@ subroutine mksoilcol(ldomain, mapfname, datfname, ndiag, & mask_r8 = tdomain%mask call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global area of each soil color on input and output grids - ! ----------------------------------------------------------------- - - gast_i(:) = 0. - do ni = 1,ns_i - k = soil_color_i(ni) - gast_i(k) = gast_i(k) + tgridmap%area_src(ni)*tdomain%mask(ni)*re**2 - end do - - gast_o(:) = 0. - do no = 1,ns_o - k = soil_color_o(no) - gast_o(k) = gast_o(k) + tgridmap%area_dst(no)*frac_dst(no)*re**2 - end do - - ! area comparison - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Soil Color Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,1001) -1001 format (1x,'soil color type',20x,' input grid area output grid area',/ & - 1x,33x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - - do k = 0, nsoicol - write (ndiag,1002) col(k),gast_i(k)*1.e-6,gast_o(k)*1.e-6 -1002 format (1x,a35,f16.3,f17.3) - end do - end if ! Deallocate dynamic memory @@ -758,41 +613,24 @@ subroutine mksoilcol(ldomain, mapfname, datfname, ndiag, & end subroutine mksoilcol !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkorganic - ! - ! !INTERFACE: subroutine mkorganic(ldomain, mapfname, datfname, ndiag, organic_o) ! - ! !DESCRIPTION: ! make organic matter dataset ! - ! !USES: use mkdomainMod, only : domain_type, domain_clean, domain_read use mkgridmapMod use mkvarpar use mkvarctl use mkncdio - ! + ! !ARGUMENTS: - implicit none type(domain_type), intent(in) :: ldomain character(len=*) , intent(in) :: mapfname ! input mapping file name character(len=*) , intent(in) :: datfname ! input data file name integer , intent(in) :: ndiag ! unit number for diag out real(r8) , intent(out):: organic_o(:,:) ! output grid: - ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! - ! Author: David Lawrence - ! - ! + ! !LOCAL VARIABLES: - !EOP type(gridmap_type) :: tgridmap type(domain_type) :: tdomain ! local domain real(r8), allocatable :: organic_i(:,:) ! input grid: total column organic matter @@ -871,22 +709,6 @@ subroutine mkorganic(ldomain, mapfname, datfname, ndiag, organic_o) end if enddo - ! ! Diagnostic output - - ! TODO: there is nothing being written out here currently - all zeroes - ! So for now these are commented out -!!$ write (ndiag,*) -!!$ write (ndiag,'(1x,70a1)') ('.',k=1,70) -!!$ write (ndiag,2001) -!!$2001 format (1x,'surface type input grid area output grid area'/ & -!!$ 1x,' 10**6 km**2 10**6 km**2 ') -!!$ write (ndiag,'(1x,70a1)') ('.',k=1,70) -!!$ write (ndiag,*) -!!$ write (ndiag,2002) gomlev_i*1.e-06,gomlev_o*1.e-06 -!!$ write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 -!!$2002 format (1x,'organic ',f14.3,f17.3) -!!$2004 format (1x,'all surface ',f14.3,f17.3) -!!$ write (6,*) 'Successfully made organic matter, level = ', lev end do ! lev @@ -1111,38 +933,21 @@ subroutine mkfmax(ldomain, mapfname, datfname, ndiag, fmax_o) end subroutine mkfmax !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mksoilAtt - ! - ! !INTERFACE: subroutine mksoilAtt( ncid, dynlanduse, xtype ) - ! - ! !DESCRIPTION: + ! add atttributes to output file regarding the soil module - ! - ! !USES: - use fileutils , only : get_filename + + use mkutilsMod , only : get_filename use mkncdio , only : check_ret, ncd_defvar, ncd_def_spatial_var use mkvarpar use mkvarctl ! !ARGUMENTS: - implicit none - include 'netcdf.inc' integer, intent(in) :: ncid ! NetCDF file ID to write out to logical, intent(in) :: dynlanduse ! if dynamic land-use file integer, intent(in) :: xtype ! external type to output real data as - ! - ! !CALLED FROM: - ! subroutine mkfile in module mkfileMod - ! - ! !REVISION HISTORY: - ! Original Author: Erik Kluzek - ! - ! + ! !LOCAL VARIABLES: - !EOP integer :: dimid ! temporary character(len=256) :: str ! global attribute string character(len=32) :: subname = 'mksoilAtt' @@ -1219,6 +1024,4 @@ subroutine mksoilAtt( ncid, dynlanduse, xtype ) end subroutine mksoilAtt - !----------------------------------------------------------------------- - end module mksoilMod diff --git a/tools/mksurfdata_esmf/src/mksurfdata b/tools/mksurfdata_esmf/src/mksurfdata index d0ff3208aa25d77b546eb7595abcc35d87a0f2d0..52b7a49e8ab85ce3c0b06aed76db4ac4d11ea0d6 100755 GIT binary patch delta 524222 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Ä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


    4V|}Wuinj?XReP>p z1d-*hS@pHvV!PjvTKK<-WG(!I(@}PS&fR?VCM$nKs{0>1(zE~BVPAkiS4T=3j1JrL zWfEdbSO&mYU%Wq9>eWjbQudSF4i4cWk0R|=PDstxbtG!DWeAQRT-9Yi;WExuaNj|~ zJhrsb&=ZD8i4BuqZn0i5XBtCjZImio26nH!%jn{s+7%^`db5n^LD1gF3(tr{D=YZ2lb%8Gb@9Nwu#6LNCs|66DM>n$lJD(Ph*&N!?JQ9l91m03Y& zX6#Tzg?YWLUCE;bIo?iU6NXClIss}rLIY8GqN6qHsVX(SKXMhR1>=%St6qaNq&D3$ zpdcagwnIo_XNO8HNmkE?O0RO+4U^*kZ-f^OlRCLD1ODZ?0#tt#fV%6vt;|jOy)89z zmH6KtY{T3CS1Po_E2;2Rsi;X_u_k#%UzG}9P%(PAG?_f^<>As6At!~+8zB`7o-XWwyrzGz6#M|N5;d4TFlP0`SD_=O7 zP*IX~BMAF!l(a=~024aDZJq1o`yC8N-J-V>skEPEjQQM&~wu z)1{#aZQGm7bF9?3T}^=T2bq*nnXzeoRc$zLaBawT?IXlEeg29zigpowQI~G8F=M3& zVb=}z?pP^fgrTrK#`({aGM@+OGHaj!4nz8&PdlD=x#LW*?hB)9<8WOZK9OpTorjF_ z7Kr?Y9^<$K48%tRNcYJFnJx449Y;BEem)?&?1Ny$v9}9L8z;4Ex4_ok?GT-!!a!C1 zU>K~*tV_f-aHUTDcw{9+;zX56x5~~>F3&H-H*Qhbzax7vPBIDAZ7gCuZuE_t!8VPT z7KV5xt%dbC9b0#h6Ij}dyX_Rr+i{&6PJ?xxAnnlfWOpY>BZQy!vE+$TERstmO2dR2 z``CktSmgmroCI((8#qa78{H1PWPX-@D4htj+<+-%>D!|bGBbTRB9$``GBbT`C2zgn zGl`v=Bz0``e?@LGxeBsYt+}cJyK2^=X6t0Bp|2TDIT~)kq#8HoI@#2Byu*c_pRlsY zQX4--4)+{8k!|%^-kmj{BK0HQGNwqKDroxuYUb_~seS-&=3G9E-kR9VdD7~$C5aiQ zO5y+KTE1N+&mq{tNy*gQs2lc?xSa zO)}KOK2YSTbUl!$idvf9Bg2>Ka8Ppi=E^{{rkw%c^Jb-FaKRr87(bXnQ3 zdBQ(S_+hSEhO5x83F;fk`lLu7NTJu)xy_4?x5R9SyRpvAdEBDEJr$J8H>Y-DrXXC1 z7M?1F1nwZ1b{l_g!PAj2^o8;-=8372-eVL%a7hYeJs{e4fM{4oXq^CdDph)|12tpH zeA-->y%^#-2uj?_)*)1r!{%XoeKi zq9Jg|MVJm~%D#hXMV97dbLngSsI=CXKfUp^YpYLT4`)cRbH>A| zj;U04j;ih>AFw$yq3+>8x9ErQ=UaH%wMmoN$1^2EL(rXo`z3Stoa9tRHAHT_C91v> zgmPT3$?PF&5gsb4_FAaw@v)ljpr)Uyrcf|Tn)Ygw_uHcfb4JYYsY6JSZZn~>x-C?5 zn5!16M$norXde~oNzmV$E4bNPxRETH$Y#x!vW4Eem~*xi6zNAeT~wT`>8fD_6115M zN}mp)wrdkKs5vvwkqX8Py$N%vO-e|=rI^dJ@uaAyc$SApUMv|3eMCNqEVbybQHK61 ze_p}UF=o&UoW4JeDA;=4JY0Vq(a2Lc&AuQsJ~}Ly*X>KO^jmD`T*)9T9?#~^mFl;6 z8;Ip?Fug$cAC~X)q%L(2jpf$&5mW{1GsM99*0-&+KCNnfySFLMrZdnj`dI#q#?!8i z8q1E(hxIif>%)I!xwpXuOagKdILGkdZv=MjlQC-+RQQ|bULmS|xcrV~0sKzit>kz3 zT@!JnZ0>iG!&O6zREu!G(^iFMZ{{ZT>1ft2O? zZl@!&5jwe*$GJc2t>Ta;a^bv%e~YI{wlUlx!NS5S98&lw(oRD>|6yS@DMMd_KRxht ze1Jo>R_)V~6&Cgg(FzNT$>nv!!eVmcZm^IHSlIrNtV4!W-nElI@63Qbg|P+; zrRHtdj8Gj}A-S`%A7D?=ZoJ~npw>CaM=(MwHhFTCk!lTzI`Z15jEkP7>7~tkp^gRV?MKn)=QZ$=K z-IgLchewAZT0RZ+FP)g?RzA*D5}FIZ+X&x5I0zXO_A`~FFGJYfRC1ldE~b*WJcJ!V z?s9~!K`Vt#s+=+>E)V{O&WZmDt&77anDOr_9KJ5ceS4+Ajl7x|of7Sr8fmti?`}(xEi7Q2)VS4W zJxMFgk19bi0=sq>o}|O_z6a@55l-*Y@L;yQ=5S>AvWe>?L(m)rf2Ik&AbwueKIa}mWK?VFf~YZoCJc@aWe zU_`H6&8zpK7*)H#WOg1iM_-tC+bRzLVtK2E81E4w);a&Q-PIlda{hjZ%vW z#O9l%#ubSPo2uj#Y?9&yZ(eU8^U8;TxDv1DOYcfK3MnR#5{msE5UMs4s1~WW8E+qv z=(|~prI4R3*|r(Yxe~WFV=FUM%`tDmeu68JyG80OgsV9>w}6lcH4(EFgt!vctzfym z3vDaV;$3LlP@5}}u?>y75~bUuS2WdG;C892q52(Xc@WlG?x`{+6cVrhAmmQ!}KWILRSm? zR+An65HG2C5K`kaxQ_DA9V=@xX}8p+g1_mzu{7JQa(;C;HuwwGMED-5Uf_WaH0bT) z&rk5gMUfrYn|rWiEnL8k?vd_9bKmUa&3*Gv4PRh+ek5!Pn9YoB*PeUZ!?0J(i`IC- z+Zss0>LP4)pt1;SJe~RMmFfhRwxfZ+m_Lu;i7NowvADgG+~nzPbzU?DPCv<-@DRi1 zTwoxWr39%Qe{wsvcyE=-(KB^M;+h=!6-d+KPEX|?ZYZiEH`}dZf^_uBZDnCLqgIuL z*@r4Ldk6YFZry9kjulAR-L*8d<*dk zj~KI>*A9;uvzpd}3nE<}5v7^~v%DU*j_M*p)1%5slCBNA`iUfYjDQP2JY^<({t29i zV-oB2snj^)hCf_4eZ!>**S<%!nXl({8&O4K&= zfHYH6_ZpGZzs_T8RDDD(DRutFoj@ezq}+M(W5<)f*i#!u`s(9YL?JfX@qyPusfFe* zwzv?`nPUmsQ1JML-7Cbqqw+DV$3dxa{rtzhH@_v(_a$PH7J^SgDdyiHH1vYh z%wsI^3;~=kfrP<3!d4!aRo*+70tmJ_u%F8IUIKz+4m_%IT<0hb5`kF&TQV>kymQ@A zoRYzX)9)RV#7MI4cuQr^X&Od7r!k&o2jK|gquZzx^@Wt;h|Ff7Es4wFgqOv9w0n9r`i1&yX+KD$24qkMKvl$(nA z>>96)5aqLLY&|2&XV>{W%4gTB6(~)q=}(!a;(Usx@hHu%%V(l~3MZS2F|~FpA3YLP z)71Jcgfyjo4H*>nHWl-!bvLv}Q|r!XjHcG@Kr2nDTcRQg8~vB5^>ZCft$Uutyt=q_ zxoywqk{M@_GHidGkVXl@w*zf&ox-r5X3hflMU~taRdQcc$$e2J_eGW57gcg!RLOl& zTm|<&M&2)*0elu!J@z6 zBO)zvI0e}7=H+OS;KB+1hIP9r9Z(ht*fMBSu_^U?0QKwN@chS!c$qTvm-zE*JRQRY zJ|cdGxNAf_f_TM<*sNlW&`en)Bvcs@mjJW8O}JgV01;Xwm6A9(@I0M6#HtHr6{UK68WSzd2x+Kj5N@dk$ zU+~?h(E!qf&Q!>!b#!s20BW?CNz%il(tkcUfv#Lzm@6o*W)rO`e1~ z(DBQn2CM+s-a0;$x4xCA2QZrcdt2*B8+!GryGG$nPm9=h-$_@5wTs#QtLQYLGud}nrAYtF7$zOxp<0^#tw)DsQ?1?&ghvT1 z;d{yCahtM-eamvcmm!9p-+sD_WuQeXudUbLuF1^i`{wT?5p^kOXM#96w^m16q60N&$CoFRK zYk+A=zkY9t&+b5qm3pS%xEH@f?&ROeE&V7yRIcAvgW$LBA^N8WR?c?185ZMu z)Q4|$M8fdUAM^xSSka4gSyGp3`*+XcTM1Kp& zyqWZy_c#S!7YgHkUFVjgKZP7l9;$jU1Y8&5Py{H`hJp-i4!sY(Dj=oV#s=a_yAbZv zvEibk^VZ~qEnk{5*W8rqrp5gi8n&Y3KWWJSooKKi$3;W-FrtC_En3;tk<(CvXy71) zhBArM&_x6d&(V3w?kZ?trPrmW$UgrCJ36X zEYHJeK=6Twv6W^o``*JSx^KOWqrqE3^fq5lV{f5TL3_NfcTcHq(GNhB%fxjXkva2z zDBQ^K*gy6n$36Bo0;~RKJn_OJ5i6&wd)a$l#!a;W5$4NQ?VR6Y@n%Dp{VwEd*N*v( z)eSa=2t)s7reNbhVMRVWThrL0&52(LD|KjQtPOAMa6YPpOk#NKD5TJwdu(4stok?b zL^}=9j`<_j!rNG1KOQCFF6qz+l}xE^*Y^LFjq)}Q588FxS-vXLS)9I-Jl^U!baqGQ zUF=71V@JO+f3I^Z&hr|~xhre1l{NM;HmJQvC3@N;h3GAu=%J6;PMxuyFyU`@MhBwj zY-A1mjLn#zud#Zs0}nank(sgY?dFuzy-Xz))jNW=+{X68QeY`mrYcx_QL{C6D!_K_ zcs%Lnn6sXZ@HHm%_rrl%d3zrS!n=ePDcj}I0~b$-~AE`<4%3(ShofSg9U#X{)6dn>?@wze%o303~sMdEPY5U2ez{@I%A{S zAF2Xqg$hV(iU8{TQdI!2;|4wO-#RVzXBX>(KH#kPdYScaHWBMRfTghBM#1`$vmOC3 zJ`sf{XT8I_WZ4N1sdG0=vLryCT0&3pA{RLFsc8rfO=OmianWr#<`5FMvCDqOHp&0L z#WnMRDz3Jx*g${dAOreC+2wyr>6NYQjK8sdO>R)|6l6Dl`Wr*ho5WhiY}|a8U(47P z{qJ@y<3@bJJu|@AF?0v|Np2SnTuu>1GoJ-ccXxJePaiet+TO8zJ@XGV2H?UmRKw$4 zaq;VbK;tqEV|N0Ljqz=Io!;03!5eyGgl0QisyF6p)-W;17#p~aBs9b1{MO#Jnj+(V z+t~OZ*#1V?{sxz@a#wRDcihNs2f@nmc8hn-l6#7hm9Dwxp3*f_c-MSgvx<6Vc&D+? zpX2ROO%?T1C@VAeHr{TbkNTs@*7y<*PMVlh_ zV9oYOncc4>L~oB{p|y=cucAEE>K@wy5$to}>9!!ugaa#~dWlL)t-ws+2&R17*&U?MMo>em#TebQ( zfuPK7K?ohrBadTpewH*m_aEfy6QAd+^g0m1G3M)L>ktR-ibv`tx|{PVh;BO}a=Jf9 zjOaGpVMpZA#H8tEsa)<5WmVctCjJxMtHd0 z)-TdH#aqb7ov2%l26nBpQRhB%75?cRXAIJo1SW*mVP0{@mO^O=i;gpn6G9uXopHvH zz^5UT+~RdM@6Z2MB7vX32w_*^jB8s_j@k0*F7T+cwc+`u%)eTs)EH&?v=G4Z8qRZS zl=5GM*tVFAq6UZBi@F#GV+>nulj4mh{E3TO1B{IYp>(y)cc5`PuDM!m%Y5A!?d6%? zaFUzp@X!Xf6T^*1s|gQR+bm;@J|49Ro@9A!wz|hJ>Cxv&dS^^g;|hWI(PX2qM#y8f z;weU*AUtKZ^V5tA-8Jd9elv_|8l}R6K)f>3SQCiv+V0K*x5)21*XUi1Xn8Bm*ijI| zH`w0GFqUfRZ>E!u7+bQXi;esb_LQ)lT5LS25!!FCt+W_J-G%%OZ2wZ@a=~+>&75l# z+%*#Gk!KtwG`!8uZ4Rl&!cQ6dum;PGlQa$3s^!Ml5ZqsGyr>DYm8>u}(r7|$_f{HH zxjx_AfB{9Ave8z!$+#LdbA5#i*Eh1+Ta88mYGPZBok&gJZZ!@QNeM}o{iFnF$;h>! zNSpQBW^6%fT)54++`kH*qAV7+-54rBDT&*Sn4HwKy}iSDK_gt=WNWj_7*b7$%eVF4 zZS3tX?8>)o-)pqI?Fz3oag!T zEi%{IPPQ5L%0f>Wzt%ipzn?PB(%fg0P8(ln?%O7wF^=$}J7vE5#`w5W*XJ)8*Hsfj zH`~TtHFov#&O(K*thHHRrwf-=+=UpxNsqr+5ZnxEbX3VH=)Kyo!NP1GB zr$s9xWzkCfX{f$>zx=TfTENC=J{(a5 zBM`73o*RR0(`(3eY6u-4v$O!YB|BbAJ|y)1&4$G9)rEogIn=gYl>gKSEq=1)8)bBo zTy|KN`)k(O{6geN4P1YG9k~#}^Ez_6hS?T`%9C)r*mm}FJ^4I^CH3XY!u{>Gbz$;& zvLjZ#h5Wnl@we=G3;CLmx5M^*OL?VM81kiUYLpyX9gNrtqUGP=FbdetSa}Cta5Loe zvu*Aq z&aA=6e*8YqW_5}d%~YP{GFgN$99y^$r1k@JLaH`u-%BcBq4%e!n_#>--)HGl<$29cuEI^3Cl=L)x2onmISV#+0FZJoYy=@Zk39*e zb~j>9pDn9c_%wNO=$|XqgQEDF05aTk*%$FLg&%;x1mfOGc7B>{4%`DQ=V{cZ--;O3 z$5yg)*>bRM3DUUoo$g$9`pjO*`c9VzbPOSM-h7~n?un3^PqJ3W>zicD6HJdEQW@>D z6)|r3hL+h`>h$?(1-m|7j%czEutHAlX{-Dp5<2q*t9Az>3K6RiBO-EEu#PEmJy5e_v{XU16v4ENKq#<1a#GVP}Gm%%5 zEsvbXGM-(4$aJ}X*Tg?F^kK-hY8&E-dGb3$a9KIkd(x@Z0c6qo;0c;Pp*l^uiPtlq zin_&(VNLYq;KC2t4>RS5zE5(2s(;L%zvi;H&dt35PM|&05@wkvM-8k_ zWhx~80&=tHf3=XrALEG=0+Ur~-$2r${Si-9fti2RO|6ISYh4}6OC2Eu{UQD=w6LK0 za=Osg!q(20>kIxCRy1Fhf*$860(LaLQw{&{tDWkPZx`jTpXbZ1gzY)3?gBa3GY>d9 zFcB8FKn@aSTnsZc06`IA~N4+ujGC7ht37 z?S{9oHhQ>NX*lv?*&le%7I`trx?dst2jp1v-!EprE`WQnEM^I5Ab7-LHZDz;^xf2Q zjs>?W2##bA=F6>xr;9kfp|=((^j1(duV?uH=&p8>v(&CVwTMkxE(b9wT@I-8?mtm= zxfk$fVTFnLi&)QeIk>}MAkhz`PDN&ggs~fjbB)>rWLvad@$6|?Onq21LFkTNU}08wv-t?Amv-SzHEK=$Fk|s2dBM_#EEtRq4)4 zF7Kb9EAEiwJZjh0%VxVX7B*W7Rr*)I*YAeD8~qo@sH_+XudF$nh&gJjoOw;HS<24@q)BFuNQB>b&~TKzMPrK z;xpwY5rh7TrOQpk<=)N{mZ;9iA_BHT7GD3SNw7!jc@ARj({L zw85)LQs?Q8kUCG2HPO>~%y}lMG4^6iR6=gIkgd#;Tbc!=9N(bp!;?M9fY^tZ#xLo4 z)+#?hA|VG=u5-)yi-?}@LtXb0z}AG5vl*2oG)!N2ou%X!)`UhsP8QF4tpcl{-XXAz#vG5rG(Z-1M#=Z0^Bhn=# z90P)}hNOSco`6)W+G4<9k_jitx?(xOQ?M5Zs8#;~o^%iv*XKGG*2d+%~?n+V~+@Fm#f}Qdcd)$Zh)0-;_`2UDE%T!%X6&SCP*oChayIF2O?Db zRuJX+c&FQn7s=fM-DMRMMp2@ zy*;d=x7Rb?a+ZuKo}gybugIuD8UM*YJd{``i##{3=6uNCdDN8gr{Y~i3}E=0^5c2r z3!mUgqfaJwOM4DKMWfG;09mxx@I*g32)p{zBBwRT+f9eCvchQHB&3Ak3SS^7e78cZ ze2QJ$U>@7BL~ddJbFM4r7sSe2*tNG1l0?eu#YgwdOD(i&zp21ELpbE^RUD`GDCPOs z=CS~*yxcWsXCGSS1M$P>AgjWu6D<~fZ@{eDzIYNN7vMO!W4HQrB;=zOpVkOnW3#sL z9JYO_{7T)kvz2B`5prdna%w4V@i~BJl0AVH2y&3EWv;B%81rT+$XN(o$P~Bu%$ddd zyaVUddKO#%j@+nI4L}v!NV4n;BS&0D8(=ulZn+nE(XK6V)iH~<6T&X~da=gF@Nb!M==d2nQZrt(oC==)UFrv_ZC z@Tn(L$)`rN#{|KO>?CJ49Us6S(-R^7zf|vP)lWyB(rHu|*Pag(LsMy(X!1$~vJ-M( zPM}|%1tsH}QR-THWI=UVF-T*h?lQkZ-895B7~g38PllZoKm*^mDXe@sNZ+5r{8wOf zU7rFo@Y$HcB38(H-%O+|J{fo}$%6^MvO<1SkW$#EE96Mwr|HbG0_zC-bXIevoE$W9 zIwaKsC*drCVew0^6z~FvGm-`9LaWPtj093Xe34DTbIB`*~Mrm;^~$qgFcpGrRLXFRhn>fV{i zr)k`eeG8C9{|%m)B9imhtd;}n`t6zMhHJJ{Yv49)U3MlKHf0tXp(eLfxYCb6uwauZqnCzdX^6UJ2<=A0ARnYFU9 z(SOo+D{m4_$wXJrDm(iZ+uTnMV0G8YYrSg%Zc4u$XZ5Kuk$t{SZeRP%1oQ#ac^n~V z_<(e1@i{nw>ED%Gc1Z`6`b7#t-Y781ndM-)S z~%N74H<#NRgXDhNux)jpS@!g4v-nVQV>%3lW-ToEi!LKDb z7c0GQC+~gMsLp`L=Wrg?2}b|&L2%sRy!SO2$KGErH);O+*neQ@a+_neXwhFr2FdDc zgm`;`KO&zSyJmwNCglV0AA8>~9<1{Qxw$ZKESt1Jt`pG?h}NhMRQ`$Xo!2lfk^4Po z^{EFCxhN5#u9y$4mMH(RtZ0L56n-1SuA;Q=^cWC^FXAAu_#7R>YHXC-dt@Tz*ioIC zH_B~BnhC?IPePDDo#2Y%;7!ic)~E;oiTZGaY7-`lJ>H_10Kk|RpWElUDf3w!-QxQY zYo{*Gux}jbB5=N?maih6ne$8C7DQNm9*kx;Hp)id^P|ZKKBuRAcr>fINlx;af>hb} zC~emc8_kAok~{b`AM@PY^BJA4zqnJ;=Y&8Bq^4>cvs^g0v=3ZF( zvRGC?-Q9cdE{bBoUJwPvxF{-C>|JAGi6&rIu*P*ojqR9djGCBOqsHh3EMP^A1$&Rg z7+u69*lXPPGxsit#_#X+_$0K5FIs&if16IVadAS*u~iTCQRjXUc}mj_Y)YC~e^+(GIKs94*x z{KIHYoPB0Dco@7KR1RryFU-+=G>8VTF$m>a0hRqZrev#@iFFrs2GR00VDipD#w0pg zQ)Rr$8%TexF;s888Q>x&T{Dj~>?LOwu@G7LsmjLk6hzq{o(WMTpzw7D!$d;@u|HAL~Y{?u}TMg0IPN$N{I zet^})_oZn+80s|8^?k2v(7fz}s#VvZ3|^Ds3fjY#!WCP(*@y1^V5qKV&e1iraFjs>btFNzTyQpGu>lygr`A#;&f#?4rF+^+4fC;9-LenOSgJc%tk{*BfGva z^55eFHI)E=tD&t5+M=OVlxIAgrm%0lA-rTm<6R9s+Kadicog5!OKE86++M7q^VqLu z27dq5&>YR+UetSoVJ3gKC*9hBo|@g00yY{d1b^Gp)j_VvC0I}E$ykpm)f~A65ikS1 z6~mM+vL`LtXsFuV58#q~V@e0{KklIz(~Rpla{WCVoJ6*($IJzWE$S!$Hcb|O6>OV+ zYY!^7$Ombh87kF@N0z-_JNz;ay|~Cj<2kK9VCr*jHN=XYw7Cau+++ynpLC~7 zAW-^ncQ}g4N8lO}fp^X9PJx>Z6}hKWeY2rijcyET*LO#tcxX3QFE|VzZL8N*Efa}A zser!PY^YGt@uTX7<7~g$l8?X{KT(`M2H+W34EVO6}K29<1ChjN1lL? zd1PB5d)66;lua`-k@@7Y{PV7Kehc1_oa;(2wqSy|tt%O}Ldl)DtsVWC4oQzn$LkD1 zNzCTQw55g_hKu~y@p7q5!!C|{LML_^grKK7wgCC)16{Y=hcUVy{+5TjK*Rp0^(1wrLM&Ir+*vdS-=~UKuu{8~B z0g~hIN7QVu!2~LO_Zqq*$k=Q6tjq%!+L~gthtwZMH$=_~>nPWS^lum=E4>hyhZM{V4L7*6lYm;tJ{JenT8m)ehiEy^zKp zF!XNvq`q>vgT}1|x{h*`#e?Rq!xMb7Qa!%H?)!FZW8^JB*$a^oc!fJBjonn9qdDH3 zN*^>-1rt#R4HXb{M_{;r6Necj1!U>aMc8g$M^LF(&MfQ}b90=yPhT7~G|{hOU%GMi zdNcz{c{iPhHD5iUn+FZm%IB5L`t8O|XQm42f{SO_0=hf!V}}eq*vFiWhYTy+Q@4$v ziaCa0>NCw0D1UmGNnzABc}b3;3&$VXCf_@P0g^%dj^TATcUw+9j!#N{eH*$g@5L>e zanjJZNr6ia<&dGu!5cBm!_cEtIW%d(rD7;N0PeFROY0fD_lk#tgrpkG=pFs|5RuoX)DMK|r ztRn^F8k&}UOHSXOQ{;rz@bGBsJ5XA#A(2VwcCKMH@BNc(J8g(kgmB~xjDt`3Ne(&3 zzBWNDq2~>odG4xw_M+h_7Z6b0C6@JKU%SE1@r6ymU#Z{Z-Okg%qw*xEi#&YH0Sh zoqTkZ*~xD=X!+H5?Ia9YMRtNiO_`n4_<+2xsdh5xnqe8g;3t}T!(gV3*A0Ghwd;7} z!CGJES3^8L@BSnsPnAbn9!3@Zz)jkA8wZ8oylH66<;sTN@g2?YoahqHCnrhwhoM=M z^Ddj2g$&hZ#vxWxD4VJ=oB3GD*UgMBwwcZ%&H2O7$dLQ4M2`GjB#|k(l=lZDl1s1D zAo%vX=COQlv3UfXSIy(ANLq3GUGva0yu5VPJSs#|g*&QwB;7GAbr0S?f^r>(vb6lJ zAwaI_Fz6J?MCTh~Irn}gG9NI3%`Y$v<+(%hvp)?dIlt0DE{SYDK&SsUL`NQTN#sDe zB8luktfWNpMJACSlziRH#>|_rPPDKb#TVim>miz0XsFQWkV`Jb{pIm3$VKTd8;kOa z{mW&Rr}&rohv-zHp^^AjC%Ut}SV}#>9~@5?myO(xpoIH|&TspiHVj?uT}5~uBIpm` zu^tuqz_6HKwOu~_z!0Ix$^8-QT8`}mh?xdIHr!%jYV(ANDO3LWnc)=Y*Tvr@rowcZ z_rg#uD%&Nd^2ksP#~-nhVu}u8VtVbz@^v%o`LKlyJ0~y7(cJN)r!NfQhF$Mk&PP{@ zEXTBqn!SYO?4q75$fU6^4NZl&WYT#3P3JBZa^PZyfQ51 z!+w^3e`TnxG&Sfo>nx*wmIpfxUJSBhr12cbZIfH@##>y-Hs00B_$@b`I#VqCqbU_0 z&W&=PhLo3kco>^=+&A>K#%M2Fwqkv3r$*D39I$=OKF>LBu9KU18nrxM5F)qnHtyv- zSKM@FIKh^$F+>jYHTv<~2Dz@kF~L2h@MpX`_Sk_hMX8WkMmCa;#Y=8F@!)|=&)8jn z>>R%2A7{58mK6vz6?bMa?oiq_zBM~r>&tzBWWr^d^Y)RMdLM&AL%Y1F&fYC?q9jpm%kQ`Sg$nwCiOpN)Km6X zf<}%t8;9}S7p!C!f9NHRu4LTKO_oC|8*lUc`D>)DYOEiy_FAN3P59&#wfY)$sA>$+ zPXi3!6Oseicc}45*fgJ9qm-(~gx2<(IH}UZGAJgeCDRw)H2bN@Ng5neQcw-Y9=^UB zi8X6aa5lvw#1P~&z|22!`f1;^n@;vZ;xEUcITR9Z>=8en(NoT&=>(dXh%%CcP=M7R zZa4HslyT7op-s~Uzt~}2#<71cBV_y4QDx3e+#7Z)X|VCs->Dx<-|Gnzve!;O`y zPrvER9}i`{p?v*{O1YxlZ~;+9`6NP{=HL~oTFuxfF%>Ddr>yo*!c5&C`0NjJcHlCm?Aljp$tJGc9L-N@bfmg5w3hP{#PFO;u4=FM4ADAAZQ4SFHtlWv;;5|B zxJA&>1ERI%*b&SAoQyS$b^-E?v$2n2M`E7r6L4jyHj3dNO)ACK7%n+WM{5{smEzyP z;%$c=Ws=FSrm(8af+%Cns{{(pQ&27A@Nip6CEatSR3&vi zUs6fY(^MrT7QRu^eBiUc9L+!HijKH5X zL(bBQI>un!P_mU{uV?y8dAkccRAD(w;C6Fz?7t^yppr!pDAU71s8SAAobeH=PBIpX?Ws%Gxy-N@UddWwoi!1U7*=4_h?cVW)^o?h96Mi zq}bjL_{}tAyBL{;C}U&_LYpRum1B$)q$-Sf{Oag9h2}OeRuB62*lP7!bXT9z#U8^a z!c&ynz_>JgdP%|ixKgU%KRd}Nbd?8yS77e+x{P7*-(4#IP8lO*03- ziWoR_5=9?FC()Qj##SlKSdL2{bv`Sh52-}Pgd;`zaQjx(hd;|bn$)LQABjMDqmRqS z6-L<5c&ng_-EabFL}P8C2M|M$j({=b@2EM&#nIASC-=nk|GL z($cn)^*JoLy^i(J6}lSxGQ3G$je{z_U`uk{ug2L{t^-E?Rbv4E@ z%vOoUaAomsTNRBh-o4H!yC}|0G#)9<7VW;BPeZyHMYd|!*3CGcE42)xZR<3TfK2wh z;M9j7k<0Wj{={=}^5I^_o_fq}W%H-TWUNn2m%mCfPUPGj=_6>^r$PwT8e`n<X z#;gF3=v^b+C?LydreS-Hw;1sbSw_i=Pu(RaA2!}~=dQ{9ju{htxQp_(v&LsUe`FVJ zykK-P%uN@K&HQ-p-Ppoq{EBA`*#0n94LtN4+sPkeS9efFo{$gxVf>!s4$2?jF?w^{ z0r@kB@dWQ--Hn>Rc!8QfEKqB1d(U{%1J4{4?;G24hvkp&8yy@!d$-*Aq46rm?WBmu z#vlaN$Hp(QAM560;|5meyeFvhXIGu-SuOQ<(~&2}NG_W^o*Hj(+v(O*Zw4K!_mcLx zagWE5V&3mRH~z-BIQPPMocG>CYhD`9Gue!PWt^<6<$m_s_#?+#_v~0_8l&OX$|g@! zEPBx%D(nJHPw+BTV!84fZ&L@3TP;8GF@4IpmdMx8B(=*bS{#1N&lKv;t&lg91U95Y>>aupRj@WXhGr80UI=RUSrF+KO6es}xC(u6+hno7c zURR}(X$b$qNMBSk1+)IWv686`gFmZe3a?OtYB8ZA0!=HM_9@-bRjmtwN`;vu)*b7G znZ^`%$EL3CIPICdyNc-rhZ`5D5Z@lObtZ&Xd6>IMQb7LOk;UI`mnq(!KC%zy2`6Mo7!=F zzkM>)76}C%ma8Y47IR!jd4D$(o~n8g6cb6KhM0WmaBmzxnHOmAqlh)eKw8}sP3cL& zy-XkDqMPZxOn>?JfPLB9X2;vHzLWw>nS$jdy-f%Gm;!r#WE#Qosg>y1$EFHA7USRf z*mMn>2KLE^Mw)hM+^q*j;C645M4QK%>dRM?z`SSlVH`fTg-T5@Rgf)XOoMp$1uiTZ zSbY?BwG&K-;ItPPP{zvO(;|g?EyNxZVv}-Q^BPX9QSv+wy{a0sA zx4D}%^&I4Plk(1)u5-W1d(WGedh-1aQ`c*zo#j#?c6J_iW;ZwpYtFQOpt1O{EL}H+ zD4Q^%?wI}wV2dKG*iVAx1bd-PtHU&#^IL_IR=c-T|FQvH%?B0(#JTIN?!P$oh4tmz zcTL0m_^o-A;42v9QBO><0sJxp?eq|C@Nz|&G{UqB9$QgHaouvXC}4jRTDMse267(H ziZTcpRpfpa0lPVn`(3Eendh6lpcj>e1pe-GiVqX2acku9VL~K?o+Iz9DqP~ZujTpG zg%3Df19+i^AmOsN=QV`*0O2Ux;+e+YkT|Z+qE0o19syw`V4uyRT{VU1zzD$N_C0S_ zC%bLd)BRk_dQxLU$`4mZ3#tS$V^O_A5t5&raQzCer3 zmo2yAfA;jKkd(UW=Y{USD94PK$3{oQAY-?JfUI@w^FrcrQsjt94AFhXaMoh$-}Zvo!FL@);KLHAN*8sclnKlBQPju(%TIk>W}+CeVqd!cp(>bzwbv z$9P)VOep7*l!x*5fMfJX+S5#^8Nf1aURFE)>F1887tMsa+-GvlXrVgiJx(bojgtq( z2)}r8)8z=O;N))#HUvIOyZ+w!)`yj&fjomOoJr>>zxA?J-BGTPL9l zA9#$mbP^JIw`1hpS%^X?x9Ti3;<@%TwW}Z+`s9^-?Nu}-W%JYg_I)U;t6-)zU4{By z_#Wov&~+qJqF}-q<;@ZWbK`FBEep&b{Ew=b3=`@60{Xd#q_z}GhV4hx;G0Y<5`}PF zGI%6Ws8>0O;XMN$PL>GNFJZ~BBeA+L90tDs7^mxuqk{qs(~`*2O)#U3wVP0%OQ4i) zV5AFu!-CF~r3N>E()j&N!l%0+{EzDOSutDeYhD+Y4BL;Wq2p(`;sR`aMnk)Utxt>D zLZ<#QOR8)=aIwY89Q%|Gb_ZLZlB2uOF(KjD2uwxi=G4JDu4ZmYK5@<*7D;{@;~XOl zorK($_O8Kr`itqP90y=k&uhqtK8_`+>9diKzG!b3ICKG`j?R5(P7k40$_ganZJjON z)*KwszY3{1dpm2qt(PU3L4))ypN{aW15Blaz=m z-`R-kEvw+7apR%nsWs^J>+U^33{aNjEvRP2ZKHloomq&rjh*JFluJ`>?IxV77)a7=EpGZj0WY_m`jJRv1}fZYOE1DkJi*LI{Xn)PA&f8c18q+d z*7658P>*DxX{~DCH&VUYo;@HI;ovsq8LYfHUcZO2vj@7%Nn%&$x)OJsD)RdnhNhSnC|ZX%Uy&4*bKZ z|MWZ7@K?`c(pq}P>e@SErvCwZtM(_PIBBfVg4cgX`^E}&TY?X3FL z)l=90fg*Abh#a~0*@}a-`76nS58lCIU}`*0XzEhv2j5caIH60aeu4erT+3RlwuEk0 zyJp=yx;;)97+_z6KBiiXHfSCtju)EpHP;Z07b@|6zo)G6m>sdAFwd=N^y_$GU8$z4 zabd|2_!5__YEa5J!6NUPAb4>BrB@Zx)33Bs?nFW4&wfJ>CknMHvT7I$arQ|TYz$23 z=G1@v4KsO74Le0o62z2&NMem>Hku!A@7E1qp^~@fCt=?2)UWy$m^RJxIjFqgB{X`Y z3dRJ*6sn_CeitC2=Uqa+TT)%8eiXxx)Eq@RDb&TO2N2U$4eHa8fdhk+L-6rptK-2^ z)*LUT58qfxcP0rPLk!GUEL{ofK7y##scDTOPJPl!>Nr{G&7Z^ToXNsZT)^lRZ<_qi z=QKJ+5PfO`md{2*`Xp5-PdieC5v6}x&f41YlF~ur?V84)Q{7adCtq(leUU1(0ztY0 zWVPO_@O`d&wex4OdNaNvEpBDtmwiPwrV6+DoS9T^n$V6F8!}CZ(=qFdAGkS8kyh}R zw0D{iguZ=Yn$XsJ+cHMs;R*_$F4Q%KD77S)VGJ7k0WRLY+v)K6Ip zSV6E0VHpyRi4l2DySFWE73jLGB^B`LdlaQGX09}2jOH&ted04OqX>U$vyG3ZlW z5XgWLaO&$Q8A@X2QCj)AU^ZHy24-1Ky-yK=czg9dDNI(_M1A9Pp&`F{5rxdg;{voX zYPPV6hhF=q36^rc&|&k#GeVc)ZD>(H9J!FX*#wcRNE2+rkNh)tsyauAz9%^SEz^cBNFEdLgj{LeEAQ{ zSj=A1<_G0rRUN)++v`24QI{?LOsj({>aZ%S2CbYc?BmZbW|f8N&Ht_|d>$=N6B-$f z#nyN`?Okg;mqriLg!cTyMJmsKNdKl2mqwH438qra{_!OsX3t>QgHs=pMw{me2E4hT zp#a{16JD8pR`h5;PdV$bF+X4A5>hUqMzgQN?4IU%ll0J zevu$>F#(^yaYtW$%G#QXtvU9I!H!K+Fj#uBsPhbd12GeVXDKN4R*hM+$ZH9nwo1u$ zmI$|fU8Bg_i6pKPs)g71kV)~NQ-2s{3Mrb9PTJvWXOD?*+-tyxG;Wn37D-WFwF(cn zutE9i8o}Fx|1F9B_+I#sAD1Mz`$2f6yqk~TCY0ks$9G{h3~-Sg^bwP?^Lbhe41<@Z z|Bji5$8`*FpZ_EnnlO!H&I1(Xt2EY&tM^v9%5uoS21-YkYxdU9&9QXAOJ_kETTiky zGo&m%`bmi9R}H25+l7uimq&B93kUc+BdGn)!a}~&2>ShJA&oycoIc$l4CU_*rfWNd zR>7sB+1mjvk02&>t|b;zqg1EfKA0kR3LpEJ21BAp9oc`=k2}#m(=ZB>h1x}8pafYE zN_k%zfv?#E64aL(j>-3Esw|XA2?iJ=+|;3PN4@UdU`NR5W;|l1kdp%!;@lgiA~@Ou zA+iYJYzc&hD#8|qP`(I(?E)&IU{w)*WC+g-TvdFbBBUsFbWE025mh{Yj%F*ON)OJ_{5hbJTLSAd*iD9Lu8MmK(Lyzv1YD(4 zVaE-k5ejYt&G*1q1&jhb(Ww&8R@sgLlH>SYm%Ii+P|(vPU^_Ky+L1Lwh^=eUV(RCm zll8k08xmtn^iUta(k5qT;wT2U4CXfRtdsVkr^Dg|rL-N;+^lXWB36)}|zvhy)b2L2|barf{Z-EgYJ~?=fCb1ag$MUIe zrVxg6Y=pL;r(VM=3R^Z@pZuIwWeGL-8v`gYOQ=`2@X2sBr*+zHZ3Lw2 zXzIckGC4BFxdVQ!Y_^jX#<6_Xwv@Pi+V7{zV9l4!+FZ9z^we zUdPSR?6({EkR4;2rQBJt4_a4+mDInW9dIHTPKCE{zP?N1aiNTU0n2)rSF(8WU5Y!7 zG5H=1J1$5yOW|deTyGBoT#`A&mi)8JNcL>q>vX=clNd!z(mmRJ9AawSh3*{}%6r{{ zS!g?yqWhRG2su zNU0};3ZIZu7aMHUN1Wx(|QjL>%)48P+eST7?AGi#5z)moqr5s>h>Mor)iAFZ+ME{(`u#-UClpqJ7>;vMeh6obHBS^#mm zLYb;zkD{#6g~7WB-qB~y>`}%50c2oZ-Vpliw&TFu0 zx!Q#*ObsdqfvFFR z5(-nVFc)#uJtsFlgK@O>DkvBa<5p;D6Qc399sLl+^2L_6bFJ;W|BOb;5sBK04y*r? zI{Y3I&bMhx1?Mo&JVWAnp%QnNtmg$nD(}1y)8q`$@#3fS;hC)CV)ZI6&|)$6@hHa; zb?t_;z&k!|lYznDih6l#;ZoYN-qzildS4JKawloR1tAto+_NqSefXd@WV$HS0r^fB zg~s7OgHd*)17ocdh_M?T5NGR{8fTTvtbdKtFQP-Ap(_`K;oK!^bqRB7+*i2xl3=Y` z64L|P`Hy7okPIr#W}Ys_iE|!`aURK^^*7@`YQ{b2_s-dp`uzyT>2ljM*~upk?;AAa zGW6@A=y$&dEx0UHDDy_Ym6?cfWYS5RdP=BlZf||3Ll>Sb>d^5Qnd-ZGs2w^11mDqp z+hP!OpWs1FuL$8ym9vniTzK$1HpHA_bcbz+>ToodGejclg z1(mML=~snr9B*k!rLPO4`O&fR%G;7ZdXN-L%8)PCcB?Us~a~b%PJ(Tq~UIy&GM&5;jTAN}FE@ z6S#B=dx>Fx3w`$zuUxlK!AoH-1WDsx2@Sa)>8Dpf{gHls1+`{<|Pc(1T$F#2De zY?vMcI}G35V9&QnX65bc-e^$93}WoYB_E2Hx$6|eiS4=d^aUq|X!`ttBR*AoILL`J zcy0~Fd5Bx}E1_mvPD`88ynF*2LstDH2WZ4L9L`DY;VG6!knAaj2BI!SXfuc5{ve0P zHoEU68tDkb*s8`kFHv7^1v=IN+YM{Z;a3<76!|#@d`H#1#Neu%SY-!oH^5}nx*N_q zPck85+^VX|wkm4KcW1<-T?FTPiGD@IcY2B8f!`MK@FmWnaqQW`>a7B~E37o~7K6Jj zFRmV2L!AnJM`c&Bqz2$CZAUN2FcS+M+#K^ZzF~-m%->` zs)AVZ5Lp>NDz*F9#7n>Y>Ud~&%vT{4a^dgt z5rZpyrEui3zF5q|(VVYk1FP;aj2G6e;&l9N7OEmcv zf~EYwAPh%>0-#C0VqI<%ZS#fXHmQ<(?h8&`akHNoqFcr6507`vm^KEwaz64Cs{(7W zpIDpQs22RgPi(_qt46i`#s2){YP7^(JW!RGQ96?*L7I3gRixfJR~;2#Y|6SZRo|1= z(lo6YZCDTJz(5@8TP|r=oNXyvi?xd_;VRhdIJKT`XvNVm;tm1gU~V1B0b(;g_X@FF z#bke-IFI8N(egksky|J~3>4%1x&3mK0S)B#(Wgc+2Mfd+o5WZyTTU^dyOUJ&y+ zZjZc35^HkYZaQEV*D}vx0sUR_DT|25l1w=-RQ!N6hD1P2h zVV8N&Jd=j#Rao32k1kB}RBL8D zn4U7Br;fG7dWxRju8^tVXmL&7*LLX%gcUuhTosgSi_Hv0btKjir}NP_=vp1|yUN~- zyqgQzYWIyp8+xfzP2cogEl_jFzCOU_io{MNhmLCyDhd&S_h4*k!5X2f)RJGVjd?dIkQyZo7$*`R1 zMHSbxiu=f;kyxKU@;}+MK~2Rvd_o?5*;KT9xnxG+&BPF|B005bCWaQPXlyfa@*5Ss zj23IPaY?GA2=mu7m*GqjicI!>nq!;Uit>vzH#SCW{D0Tn=@_x_{hDL;Sfsh%nv41T zr93*`Lj3-J${ru{{eJr&Yt@pr;(gxn8_jMfrWIRZ#r7qvuu1z8Ryef1IO&ZQ79{)! zD`b~{NN8O~%PU1gaF2_!LJBvYHMQ;3B zXV-|Fi4oboi#U`k%Z9|aU2T3c?MoKRbvTnOsRM11+b!Xa^WPq*(_Q|)B*vS8I=yHB zxZU+%19eD@ErbmKSBnSg$i)9*puU$VPU4^a|DvfYdWnZ}EDuR-L^ut`=$4 z*r#}KzQqRTHhq}Mx)e(%`-%~9u7UH7eth#|nZ;%&nc|-AQ-;ZZsn9oHR18+lF4AGE ze(xK^ecv9$m-iDFE0e9aEDK0&F(?)d;_dp2cHaAze6_#m#l6RC`sNSBC|=~Yi-riF zfh9)q`UAzWZ#w7CgG!9ze-3)@DDIp8`Fna{?ZNLI#eLr%#nT3h_utbCfmL!WSUE&| z$uIbyYgV7(Xjbqa)N_P*uh?z28(G3_jvOgg@n!QXTbE00inV&AIQNZm>W(U*oDrk` zgK}n03VetytfBQuG+}KJOR`43~E;>RDl9#76(& zF~(W!9aG1MOa8BqF?Gj^i}sg<@ggGJkyd;PMACe}L_)MC})e#u!qd=~%vk(}LBkJQqyIVDkWbde|FL z^~NL=UFOQyviy-$YnN!CUlxf+v`ZCQ1-`&pvy@gX78?|S>H;)!DMjuU!}w}TDPW0M z;MFa^1czBm!QrB}IGnzSvIrci(6=}o<%0bu4#QmeB{_^-1`Zd#;js2X3j7irx z*I%d{?*4+Nd zuYeV4)85pzBaPC&7Mm4;SY6}O)Vdm^k^4&V4}R!f`R+<_J(n5csnU#bW$ah+`nrG)Mk@m52>Tv#IJDQK&y#pi7$qZz=)X$ksscXar+-y004c^i5g?Hs+-!fKb zzQyY2uH?U1UFynkv6|vazRPN}neu_PjMW+B`vX{=@rKoh)7AKUS>3B-s;q99PW^rW ztJCFWKfvSh;|k;-)`?$ofvNsjLF1ku#s*!xCNq^1Hi(tNUC;-rtiE$4e`hk>4;fxT z#MUww1^TDTt2c=Kv5SY?H;JM)MIl!(99hqC48kU{qIQZ3V#dF93ia3|HpEt+MVmxy zL3O()@7gTx@1HdzBU}NH z-x0CAUrgVaKDboQuHna%|2E9rXWx_U+gL4Q{$0!0W90tZSuM$LYWY4{t)-U=ds9nK z1@KNSwUg=E&!{EvPr2s~aRu96_H3spa-YiOWl`X?qu&s|I9fIBw9zy=9sOc7g&Y)X z^PNXi+k;{dolY0W@yq^{+hj0iN0wlAoGOy*BV}G$@llNNq$zv>|;8Fp$pU`4wQd5ENVDz0Bz0@DRe=LnW{4cj}NU?&FUX%4JWB0bI-Otn2Xk+g0@kx{}`^8S@lp{$kZ%EkuxXODYR>1gQw> zi14#o=w&zh@C@v*n>_mroG+J13(n&6SR!pipiNXNPzI(^iFD>HKBFX(=A3wfPq;6i zJI8qF@)i#XuH=8@AyGwmi-*WARQUpU=qy_=FdjNn!bR}ViH0H2c6!6Z)=sqWB6#RT zhc1GLOZTxxK>RDPgUZ5bwMAPy(89}NRlN#TDpKSK0esPcPG5$Nb&wxl7K1tLtqZs+ zmJdr%Yv^O0>U7J4Gq3-o4L7VQNZWVyK^)2Z9 z9Wjz?PNf{;1^(GXIp2XsmTd;}xACf{9|eWlHMg6|!FNR;&R@+csBPEWZ%Wk*#ITU2 zDzeg-CG5aZ(|BD%x+7va@0h;557;%+n$p|?aTuTaNPb?xs%Y}BDlRmU!~SGdL@HUV zir*qB>MvBGLR>eQV+yCH->KqL98&lfs_=eHK7Wg^4UN$3MjgB6 zN+a1)2;1{-SX|YGhO9M}%ciLyr7jiO-jJr>$2Y)+wE4c+mtXK$4tOB8(ga65!wk@# zm5q*_u}WEYVU66cOZ%NV>?p6Ne$Pa2n)6f?d0Z{N`Kf5-aaH(J7A_l0G0zaDjwL%n z|JiTKV#vus*_!9ed(*3DVkQ4kZ}KEHuf=n*3cK2TKCN(C+8(Te$PQ!`AW@ z=;3ozX!)38#L4WHBGmtv#>*!5Cu z&#!t;{;$N^3Lxf{*ug*jW41m(XZO0g zwd_QNrmw{o?DE3tukqOx@Pn_#dD`@Uipi|vmh_j((|D&?lkYW_HaNx3eCM%?rOtf( z*d<-1R($l>CErM_=#o5XIq&^~CUcUDMNX>2k9t9coYaH=$B$xOln~vQU@)*KP7eW&cP$){IAi=$)`@T{L?e~zH(tS@U zn1VG@0~RY!A8DiySR1!#q`q3q8&TbSL8o4e!Bo#vs>(g5ex6br{<*7yL!MGKit#~d zKd+)#hvFC^#y@kRUT2A?u7ufJs)oa(6<$6n5#LfG{@7cxD7vfYBZX3-FDmKjBUMpj zD}5xzK=%1aUHQif)pAtRS8C)+1k*HMNi5ln)qm4yj|vs(xUXcvF~O*M4}a-}ywy({ z!1GdBxom*c-Gk53(I=&)cz(Q&_LP<`)g2pJ*Ue9#to#nd?>n2v9De!^fa+#Gfyc_q zhG95DSJBZjQhmN2RxXy6s`@Yb6{qz*N%qgtoV8GcvQpz3WU1@+8jCXu0yR!JrBIfz zX=VbNmCGpf{N~rC-)>}rh3q26ey2XgB zUP*2BU}KxVTCnMxg00N7OE1+imjg085Zl*9AnOq;==l0g?FW^Wf84XBtRXYMD6V=T zW$Gn?7L}9A`u3MpDqSSnRt}<_PZ!EbBe=gQHV8o){S+jn@~b?kZZML#EG}58=`Oq; zL8B~^Ud|7eUUU3bPR=hc#o$mE52|KX(B&V^(l3H8)qSK}WbPC#PC{xj8OzXS$4XIr zs=J&MEA8O0wqf!IQX2$EKake(=^pf1E9s)UxA#cW#Yw^PV5`)eb6@8(lIFKYa(|o@ z%6VG-u!z8$60A~r*{hAz9mgB_kEG0ase(KuUiucNNN8nqJITYnoO+~vFg};C;V5Gr zVvhTrD5`^09YYEY?;u&-^Ry$$x1-cX<~vHh9M0C!c9I6W9|;&qrMgOHuMxPY@BFh; z@;99%oVUEJjQpgt)B<gC9;63%qFR8Iaj5!Z|I(LwV1?h@8duM1*?E!4WF6v*cW z$-R0?3%&W=V7YLhG~I)XqokoyQiW^1YP+f1DPcdjL~qsXmb0z4w(A_>v9kL|@GIO0 z)L@uYfR#b!;nF@V!uex31QsPPA0e4I&Pw;DNTPggq=XwbqeJ8epGajiTz%OyS(>RS z7auaxZErMwGQY#>^Nd=EInt`it0zbqJhxKrIayl3VGsd{>s+{eECntGr#n5GDy88h zlxfqXWUekfns#c7-)H^KvL=rlhCuWlA+iU~%B`KIs4WaP_A2fIlohC>=Vvg*&Oseb7 zM~70A<>-J2la@=PSa^H6WM-k?3h8qeE?yy3WnuOTDZvztbF?zHg2u91pGNrQ|_X(q-r_Q^jFvKVC2B}X}QWtki;jXwGyhj@C z%?+VBhol+Y5LtIvYKg;lXrDtWD}QuMvT?ZE7>P)^#&M~DZDLY#YMhd4;ovbPK}l!e zr(E%0&PZQi4KzcdW`$Bs+}thw#a&TLeS1!-#c`MA^XDZa&s|ipye~<+xeLUVF*l%B zmn0+NtDi_^sK#Zf2X~&~l<}T%oGpkucAUPuEY$!I2zuGU;@mlvO88Z26P9!<_1?QG zjlzQ3-q)m+Y9Qd8IjJ9q!?q{?Dt$@4uEBXUxPe@*jeH?b`kjMc%Djp8$H~opmtMMa zISL`U{T*pEhhxq_wURq`K&6hRhslPcSJ0yo|j4iR8x?<|>?>eF~}URO5@EK`J{b>m>%h(C5+= zoX^JM^1pT9_Al7 ztmso3nBZx)xMQKIlCb%hL)@`GRbfH)H#aYe2WZV-aI00MpS5Nz=Ub&F9t4;pIQV9B zpxK}2R;VQ*jq=o|w0R8xkVY3AsQi{7d?~h!xfI`hIYWny>|z3$w~z^>hKj3~EoIGZ zIqpl9;4Hm)Gq+5QTg#b8A)Zmryb?D|BM{_qL1qYIDP0aWf5|OTVT(e{`#J1Y>{`K$ zlgs@5=tM(v1?nW2mvjE~w_siY{JEleurAQg4ae0)mo4zOrfH0UJ0S( z1Or`Al|1iG6>FM%a6FBzi4we8qGJAhc-o>8pShqO1%4<$n3pqZnmh2AKGz&zHd2+^ z=4-sum%QqjYw@prsc{|i4fYPMu36@|SMr&9=I1@GQ z-exiEtS`HXV_GWOncoiYVA(0s5RbmMn$bLrNnhXoEVb_qRi2@(z0F1hr+S<9x-&}I z=H3eD8_&oOdz*D!Fbd|s06D8Y-VzbBo6Sb7Y4u{y%H{i-aRvDqYS+(PlRGI->1W=` zamShTo^vOt%0P2%1ic2Df90CXk%O34&y#(yxqR?NU$+)GfzN6?vM*mVJ^a0-&qIF@!bsB-3v?}W3%ro{zO9__vAGiGd%)Mt76`z{2Pk!zxhxjM zE*WNa_rwy|FGri(czN$-Wi=i5(Y|jyiEy{&5{BXS_FjK5 z34fo>@D1PWk-r&lZs7@Xzo(cvuFO7PcI3C!zR7X~8wk3Vwz_tYU=1%eDS4BUu@B~1%)Y;wY~sSPaQLD%EvoO2v~Q8Q9S%zj zTx>RR-^vk-%@aj#JZ;)xZh*T?=J{I6@ejtyuXdQ%ao*EelcTEP=3CiZ4`-m=l+E3= zvt8UkG?#7ED%~6z{JBzN*(q()K2exy8+i_l%$P-ArJD_$ja6BVZl#;ky;GTpqQ06e zf0tqY)xF$kmeeP(ph!D?U-;19d(DTa_g?dG9OS5~C?Kq<+fXPvRd!+2x zYwqJ2jLcY^&iJV{tsUzBThli3d3>7IZ3Oi>1iQqLdKZo?f=PAAy0F zy#Q?tAI=Q6`{I-Ab#?)>haSUakHhA1Ufv(E_8T&X(~J}59=ef=0R(=c2&L3W`tyXj zi8l&EE!vOdS|`m3p4rz!kGFs4(s}h(AIWsy+}{f?e4k%4pWz14@$1m} z01Euoyuo{*B8L_I<^8{!*L!Pw__}4W*<5^@=KC%*?vD8z@9s)Hcx!8Nz=L3!$>WI)>aq)53H^1lvvxv>32+Rby=2))_r$8&>im8 zqS{)^CGTpi0a4YeQ0V|m8YaZ60xY{YQSPO)gXlfbx*J_pQ z{leg-KJ8;+!SX(q@(6bJu{1(Z*vHb3J53$>T0%ok``{};^eA1a8J0i|yl1}R==57o z%k%qM4)O41T?SbGLC|TSr3Zo^2U=cpG4kd?mNLBds*j83H0|ljbYh65DfXrLe`pZ` zuK2i3zYQ065q5p+A~pWda@qTg4`i-2pOPyKwe<4P?`KJUPZkvQrH|XlbB9|hafW?L zUIYtRp3;dLs-4K0C7&8$x##1Z#c;F}_tSx~mae*kK1`bDm7w~C0~9vS66LLs(VpHb zj~Hjk)nK01bc*F>0BVG-$Js8y`EAXTYou6Od%>rTpJmyH`BvoTmgY!J`P{O>FN0y; zg5wBJm+Q>7EcMoI^>N$9v;>)3H_?R!mZia4e3)O4xAJjm<2ktYxX5GRtNa$4@dYl) z-AZe}u(T7`p91o6VcXiO|U-zSado1<&S*>Z=9*e0_=sRTe|CvnV z5@b&Hqe4dJNgRdkwbbJG$5GF{mXM0+9Z;3+h}B-(YCdem2`$Z)eXeN5yf|90*J9!~ z<30agi;@3x0G-}zsmvc7Kri-Ms_*AC{`54xcs!NHXImmfq=x9ahaOkLZu)a-sAcJg zy4!yy8|bfWi-r9(DW~M^&qslTL)b-nWr*&R>V2kC^gfF@M9J$OT3RiyFRzB$(o<>D zKFd-ql80X3K6WU7jNUnwO#5LEsnlSW?7Q_0n!rlc5UZG2- zQpN#`kx|z5I66dkRnt?+DX2bB4PEK(XHmF%dj;10H%Q2!=J(P>sxWOQCG4hG%XbUy zG?l^+T0$Bq;9j9I2$S_gblo&hQ<;dnh5n6DclhA!1L^2GZchqX-c?uL*;JZ%(6R_J z(H*i>^g-D}{{+@MmP&OGS(*Sk`jEwfVCf-CBxG~ukfkjG;jksKHX|B#1k9rGy$*uW zWB7k)h;B?hmC=ibVb)%*Ds^G{C8_fI!xqs4Gu>Z~S@Q6Rzv&mtuXx0_A4h5e4L@PI z!;P0apTvU>9^?1qT7qfRDT|NKI3Enu-84z#6K@C`LdetOmt&-q-wT@w>q?UmaUf8Mf`Z+)9?owr2$y8+zRhV=;bJa1FP1jlGGz31U?7p`t{L7YUtwCmCaR`qoE}HzMCJI-+1zpU ztcv{3+0EyaTJs%lK94D%@11*GgK!zc=ccXe(QMy1vaBz-jlc(}=_2LLa6n!89=Ct{ zRo)+*ulRhSR{h}o&F6qxaTZs+1M2Kq=b3)}t!t`p#sL;`_yU!-4Jn@&t%3Il=ifH&->#$NUhoDdZt5QE|2eEbo<3M35)P);g7G2m|dj|9Nv7p z&LpdeKRVqi_j%`=*-;-KfVF<#C3Lsie%@IPZxOhA-dPS0QCvSd8~FFN_QEV@(?I*V zx@z04`E_r=hGz8wHop$wz*%O>uyg%9o zexK!2XBNEo%X{3m@ud#1t>j%hRoS1MQLaALh_TKH6ts3cjqR;zjbnXTpHE-^)$X6LuKOsTpRu5~soFm~qw)OsnxCC9`7YHgZ@qo24UR(dxN8x!D?7dWj;U%F zZ~^~Z^}OILns*24AriOO`mvai+s-6=zdx$xArjErnt<=2d0Fs!>JIzZH?>?i_TIe5 z)Ip@+$)SrEa4q>ZPGYMQ8 z_cl7f6%kj|=`DFweR>h4zfz|zI!gv%Le{goqw7ztnLnnMHPhKu8WqceX`J`|tnPcA z1yp&jvrw*uMh4t=<6eWc3k&Q~9lXwxfd|gmpA@b~vO@tR8~Uj=&$Hflwy6h}ex27D zP+>RuvV3N7@8k*2Kr>hDhX(F~*h3CrZ5Gznv$bVPAiaKkBm4|U{+NnW?>b`e%?H*D z^Kts7PiTm!OU{5?Uz|z4v;d!djfk)1^tRrnW?gdj4YJ3R-Tz=KQm*5bA*#}(C{6g{ zR;x;W6>`}bnE6_2k$%VT{JEdyQsxZRpN>>51uHia>ZG-=Dst@*113a6PponKQ!1I9++%+Pr=bN zZZBTU$`$)A?%mlPf1FL;uf9a;?0iGItCd%rfi=5ZQ^>J#mbDdjBc>wRi0O%I__%KB_Akz|e#a|Y*KptPZtD6SXEAr|OnkMNx7f!hgSXFM zVoj|tvG&bj_of?IC$N&cTFC)w)~~pA%ceg3)fo_gv&EXgU`si>O2$7@9J}eCtBb$l zvCM9jBIokMoIENZ$(cD-Vxaf( zHdQ&vIoH1vc6SD>n5~(xKfOynQOA>i!+CHP0XjdvwtF(CeXVIu zd#&*v=ESGUnP}&fdlYV*DqNjQw7cu9Sm<-iBpzQVjO%*y__od{Tp*HgS79-pgt+T0 z*r1htIoWAu!7MX6apjNe;B6k)BgvZ$S9D7_&QeA5W##rY>(rb8r=-PfRQK-UYX7mS z@jLELe5hXd9d}MXRA2s%(|enB$tqIp?(_B_BPKn%X8j76ea+gkO$FV zJie#OKX97GKRA;dH*EkCudK(;o}9Icu@(2mFw(xbZ@eS6s6!8&^`Xp_49UByaDg4&mC=E3DJbD^4T5x*!}T4Wf*zQ`6MRu)R&O+fq0q;)nWsUs3x}1doI-S!koOW^^?# zlL^^Wu$mOSnIUz-A7OhZtyPmVx~i0U7lxL%Y%AcL zZ3P5T>>|aoQ|vnF92CoDXXd+G*BSxe++vLoaKpCpWj0K!Oukd&fm|}lWY(K@mC*4kp-J#g06g!n%*|cV}nSwVd zxQ>EflW-Nqu2Jl5iXElca*FYuSxT`(6q`>m-ZL{Oc7S4&DE1>P6I&lc!95flM!~bT zm2UvWc2KMr#m-QyE5$yeSZj*$A&j8d#}unWvE!txOtDRtWzG%=rQlZ-45r|E5*DM_ z7Zl4&u@5Phm16rSW>D;XiruSYpHI6ecFVQ`-l5o4ihXWdWPO&W%<2_?;px_b;uA`v6Yi0*pbbJU`QS4ocy+<)Vgexh=6J2UjkY_rdf;`h16yuprq8Lwf0>yZu<0-}y9Y--f zgkvbSfF=_|F+PMN>zMX&nwu)f$B>2b6yu_N40*um6ywS8A$*AjoJz4+8jug+%M>#o z#<2e40{9qm@I?wvCgCf#6~F_Ir5JC;Jcy&aTMzZ%fwZ0 zFa@J1IE{jxN!XuaZ7DW|Vl64wn_}Sv|`O-L|cKH7RxrRs`I}dZ8?~vas z<8}@=t-h1c+vhtA|68w4?DJiW9$p7W?>+Ra&p7P!-HaYy;z4gWde+03eZI%g!(%t} z64A?I_pYLcmnGo)6Ft0Oj9%7zc(j-K`XotQ9scx^D0yEgzmr`;Qap35+;;bPGZvYqqMbKAWY=;6^0qHEBz?nv+R{S>`2 zcJCm1W$oTc^vc=23+RQ|y<6yo+C9ggl?^-)ht?lGJi14(75YS8P0o^@Y%pYKTYtUIy$d?%w<-R{jnub$moie7!Yw+g)mc5e%M z4ej1u^uq1l3G^DF*F4TY;A`}85!eRA`6m78X_?1$$S-FFJpMbh$a++<%R6ncDjnde z>DYfm^$Tz<$yVeBzPoxh9^a05#FOR`#4&^ovA5?Gleb*s2*Ub`MX z<&8_$v&8)p?D9=wQxC83anzLMGUMK4O1uC5RKvAL>F{gnbfBwyz128qSC&iNX{qaW zaHp=b??I|Mmo6?cRL2s3nfCar>g^J)u8yCQ72ZA{#DpS%`yhff2K77Zz2DZU?cfW+6Ff8e6Xv&3O3Ao931BT;w5$1=?cg`+9{{p`NzL(RTH>Urc{#@Z;Lsp z9>{qEepK~cuKY!Ok#XhIl$x98;Zfc{C##VzR~X(A`j*R80`KtJ<8qbs8Lhl7S8(3u z$e~9nHD!n511LeR%07O-EVQ2L%JJ($Pfxe&6(7Hr3oJX}`2{LD*fqm(XugUo?W(GF zlywEEwPjqH@rGUWLsgM7uF?+w`6{5CtAWoD6;;j^;?vzikovxiE3e<+c~+f#&F86m zWn4WSzbB|}WnESAR)n7AT;&{XZMxLOvaZUGXA`U{4e?$5h=mYbYGXN9K(_d~c)|7{ z<}+xn`mUVoP_~cez_BwTK4ktJwK2q1-Z5p4`Z>f^-LEbJ7%y;+3JP^aI}XoQuZFtn zJK|@nGodc!xG_t`ly_D0TR+QAn?Fl!EbmJ8DdyQ2=DO$bTQtLR=TI}0r;_X4oDZg# zH$Jf+W5wq?JzWi{>}rzjefW|OV~82kJ=-d~^7&+odl{a+@CRVUSJhR|(Quk7Rn0ZPaVl2LuI6gvh>ca}t6^#l zV{Mf)R+X%dE69Lv)#mE1K>wVVLX9imSuavs%dz^m>H@ruAH1F{&$?dq@q2rUr3!gx zis$_ru1gNT4U_CDA5BtAYP(iA3QbbA>$qyD#Con8KD{keQZ4JdvZ!C{VCPkzsEXBf zh5O`E=jyqhb&RuFQ5~u4D(V+K!77xa)dclhUDpQ3hcBx4>$$4omwl01!zYJ@idLy- z9f!tSRT?^iZRfL&92~6Kz|}X`r!QDX5HFYE_Ytb77d⪙CYQ~N5@)+v3Y!zbz{|{ zaMXBZtU4O*YUI}#0qi>WSXI0ccEU$v)JKh6?HyglsBDd0*Bp2~@Xy9L+QFmkG{4cF z+D%-3K6o!-lL*%XU%%v`mcNQIOtoz3`X*;}n0y>_8+AF zx@!8|R>k|cN~?CAu<-4ELv^5&>xARmp6d0^E|=fBp0@7eo}NRUT^oJ;vPIeUPd(I{ zL9T+1iZ|8%LD2W;@5-i5c6AlP9O>q&=;N5*P0btV zDyjl|xWXKGcKqx>R{=G!hiklJeOK#bE};JG;R^N}(AAdJ?@Ghey=D*NiH>qz_VLTz z*$(FEtgtP?D!v!i-<^(XdT&>4e4D<#Jy&~Ud#-rU$4{)*?Vzgl#kLgeVCzbB@bvBL zTI1vQLOa`T-HrxX;eEI*cxjqq=i91T{av5r3~7tgz`DL;$3ENE({2DxV25uTYg?K- zJgu$Gh;x){{csBc)bc^D%zhVJ*&}RkWsOh>?+wS!s^`f2j>-4CRt+{?<<#@huFoBdnkoMgu28>z&FtLa%~WC2RYdg~ z;i}^EgOyjob6|uk*vIivQ+0EstDU1yQ}x^^R|MW&j$nw|KFXDa`sLI&Q(WJuFJds2 z^-WZc(XQtmQB73$(YVO%YfPJPcB-qA-_*wTP;DElgjgKw4X4zqSWG8jj4Q}5C&kV- zqSz~Ttg@e{ku90gNL`F|mGV40*456(KW8|cvjfa;@k}zVui>8M<6N6F_(jySbDP%l zberI6;p1@BwYIvT+C9-#K@GCzj1AAK%1v@@a_p*YZG92-V3I43--6nh@q$tJ8*_!)xTc6a3VmSXY2wZA!>#Cls3vX5{qh5-0-N(D>C(m?^@^K7|Rlmi%N@Uob#ZcE1TzOT6>~Q&36s(!@K>~EO8wy(KZkpRI~bMN2gtM zzrcEEVc*d@IM~PV_AQ`ZTk0xVJ2Y4ESOg5C-(z|bv+iluZyynN7cVs5b(hDBA9!6n z#{;+Ll}@)sn>eKe)p=X z)(iG;zp6{UV0ZWx*G<^({Gy)i13U9C>f1iB+g(v{ePMepD|bKGzL(Xhez5yrQe*qW z-sDxK2f!}iRr>}6edOqMQB4>a^qOPe1yx`W;`uJ91A`DB`?Kml81|l@RG}fT-9IVM z5ZI%CR0D^?{`S1eJPfw$y!v<;?CIxJhvBflPE>x;u&X7iccWoXJByz}gnjV`b!P^{k+9YGo+hJ$eEl5>hp>2qPC7P!se)sJs^*_`MB8OJPGt_OnAo7^xw6*_HF8Z2 z!UJSDpU1o0V}qQIQ+3sEu|c&RWo$dYdTv@!9>>_as>igTi4Nl{^~1Cv(^205IOBP!3&s4`(toSxnWRVsBM4em|wA0bxGqqG<-i^1aj;~trPgIfDtoRmn z@-<7pRV`U;={>6B5-Yw%6s0LgDN|=xIHLdoeALk+0DL`Sw*>Ag)(wflODlK)zl?3#8g2S|HP2p#^erAuW(93u%F< z1++kZo=*#;$$VNMugs$bawmZnNTUQ=An(rg+}Rft;P04W;+<(h2OOVGQs+(vU2+_o zsJ=XfL!57-iaQc?9_bscYh<#GNN6z${K-^;V;cF@XP=Ge`6 zYAdD--lm(sV`e;z$1jgr9{hRttUrZk8GIk)z%M%4Ki7~04<_+T6u-i;&$lk8HSN6z zH;Cu*;E3!>+B~&-=a4@h2pyb=}mY1oUv)P z_;6pt`T&jZpWmvzncQ`XcJ!-c*uQ(U)q0i`@3OPrdbZA*&o=y^MrL<$M}VKIpV?j0 z++8A*;cd1WleCIYMhf09Wxd-5&;Q`-!115A_OesS+pK5o#OJ(nW-)(*Ns1-JP zGHOK3-bfPbv2y*r8J+lX!xgAHyY{5^)-Lf@TW4EsQ|IDYJ?x#X+40*W(1d!Ay^gH- z+RfmIn3{~cE^YB1o=fBLpVz(I4uxe`p;_E3{StR&GVmJfxi_utDX4zS;?8TX`p7yC zwJ>PYc61zGu{`+m-dzKAoNt9}avbnHm315f;lLAzoOT6Y8ZrodYhQeC?`Z3F)Qrzq zJNiP#rt#S`T`AeLH}+3Jl7FgWbt57^d%+CeQ7crupSyOmg;`SW|A#yO{)g5+$T0@d zsrP+y#ai#YvhQ?7#2vO?$A9BgGMTfhtlDXB-Un}3o0nge&gy=~%)Qjw1HLa72%&?E z4;A!BT10$xh}$hWm3+yx-fT9z_V>kbQ2V@(Y`m*!!e0((=f(N~?f9;>cXr`BePdcc zzYO|R2Xt=+ymQOMd0++G*vGTIy)Csz>8aSsFXHUmn<3PD)1GhbAu#D+Hn0w6Q)`a# z0h{y7R>U2|ySn0QdKX&LvQ8gtSHcc!^DXZrcrX26X)?ywF6pOgWpmfho)snWf;QfK z^IH}bm(5+%F=MgXo6Q~OcsYx@o6X%nZvggjT)raKp1zlHB0dvWC0iCXD!Y4zV@hUq zKf7Bw?qu>T%HhuB;|RnX339sMay0Z+4Rg6a&pk6^B|JrI`p#!A&ZzSGyQ>$i2^+7y zXTz%vQ)`zb15e_@D3nnR@OOu|OU!^lk6@>d$sHb_?;BXy_u;wL=KBiWc;BOzqvl>a zc;HcRrybm#BKYZ};HC`9=NWggX3KC^Mr1e>arA1$QE$YKOOA-RD)TH~T)z1>d>7cr zu@JyB)S-dYb>B`>3-?^Vl+%a;s< z$JPGHr;>$JKI+%p?!e4nb;xXZx2{lm^SB#j&VbeJy*gh-<#E5^_adI2kIVOhQAuUZ z>t5kFmaJCib;V8yG_S?_tg*i-Jj*Y{%1vdPyf#J zx$pU~fZOd8;QhUv(GKrwNCMk5Fa2|cGZ8!PXNZ{kOBV0YnV#zf-5s*w6F^O!?n=H9 zI0DVp6sJ2hM`&cjw#{3H_lRuV)(BOfI^DPYzQyU(Bs|jiR(vMuV&w|zn9Yjnw#`baaIodCtm=UNm8+DiWW6Rcrsqg!l}c4A zsYJIsucLBx^)jMrhTEM(Z3=c5P^+!pDfIlSR7jzyT%nq!$cJxs$X^;|QJ{v+%Bnl4 zjzH$9TveUL*lK-g6e<{uLSI|GT2}9Os~3fyqe=xeJlLHd-v&{&3@TNvpgP;Es3w8F zRjQY(T3SskTe*~47ZZ}v^JN)#_AH%xO|Os1?h@Zu2ZTf=?=1fKH1M1KD{V#mf5m5+3T5k`;a}Bd79b2FZnk!qdgywa}Rfz zJz~iJ7V{#r>}c|T#Jt0-K8E~H%HgaF9ZR~)tRG2sGh;Ic>Wrg=mzaB*SzjQ3OXhs$ zHD=g&ir*XSx$&a=2Zyvp(kn(wodAVl$)XLJBl| zg}9OFT156D<{!)`MgAX{^?h@R zu2cUL((Pe3{nWNi;}CU>uRo)NPTPp5pOURuzjiz619uSTF&#U}{)yRcmu2IQ-B!C} z7{zx}LM-zVv*jN0uVaq#?1**W$}T!@R)y!dH}_moo%|V}B@SSI$(&Pz{1=#YYLdN(d6n6?7WtPjuQJ0t73R7r!gA;`mtR&7V@o_59{Eu4%0IQsQ$wk+NJs7wqDR z=>8|QeYLuE?G3?OUWTTzMNXbjS_53-2`$qKrI+f;w8Q?ea!kQtee8Diz~0a{`&GI_+1VhVs_ECU<%vsG7m9tG7E8?Z<+DT zkNHY^mU*B3WiK?g-V13Mt$0f|@QqF(&xp0|&HV zRBxQGl}8QR=FZ~D{h51=PiMylig#yjW#<2g{3Dr%nPoPT|7GTRW}QvsU(CF{NuA&3 zzF^+mNB-CL6YCxzUS%#hNOtoti1(RqeMxrfL&Rj}n!{vw`-&KQgjnz>aW%8)G25Tyaad4jl^+2(7quQKDmAv@SJWxE?+TQjn6|AE7Y^&Datp7w{_VZQ3Z7w(*D z@-cT_wfzfs-eSW?$3%~g3G6p;NZ-J*1BVO=?A150LZ85X!$%J78DppiU%ErptuNds z)zUBAPS3()?pi+270h=mK^}n?|NF9h|AIpK+Hm1A~VSwl=(UU|^rV{RR#jIIMqQAB;9^6n5DtJWu&B zKB{j_j1}!aWO%QhLjrro#Ecx+YjjLsB&GO!l>e|Cp7I*lv)2$xwBGz&9iMKq{``G> zthXf7UnT(W0W$26wT1lmsGy2HmAFg>_vBlTq&G*d|{|A_;KAPDV+AZI#SryyP2g@?;*oSSv$bmT`7Hi zajIA@&x;q`owE2C>g#Ln9zc~O8?O+4OLEs#iPzoF<)e+W4qS>qm3+e;u0Fcq&gY4` z>E80p^g!QWw9;s0(8_uOeame>W>$>vXp4$7von96N&XAWBh0PL{&Okbh*^s1!#q2O z;#--oFu$2k{xw9?c$ppDnN^wDn2Ga9@cJvnvCQY0Zf5dAil1P<&y4YqKZ@C$S=}aX z37zc7!Mweh1Woo3D=~{RvoY`Nrg$Rr0CT`W^0#HyW0qqUWcpaNZiz1+Ac6A;(VzL} zS7dvcCzzixS26=nQ(kuF-BV=$#5}_MnE57i=l31yp1>M(tiQ#~mzg7(U6|p_`9D(r zB<3Jydu9V>S!Q15(7q%4_w6xc;HVgTI0Lroa=M(WV$&olSeNNwUcN^D@0i;kQf)Y0 zZj$-=9g1&ae!zT#xsW-XIi5K?vXec71x<;Y>Jk@KB-ScPJeZR>`Yw&LB|F(4X0~Y> zJ$=bh$RLWXGwTB?p!=WHPT&bl4y1AXidw|Ulc_K{y5}Q`t@EQie;?QLb^B-D6QwIq zo&F)9b@F~zmK-PCM6q=a4Ep=Hp0C>-_>jC=hw3b-*@;fx)-}ixRE;RMPXDTZAJ_AB zdp(~Ury{7%?Kg~98j+(!L!#I^do}p`xSp@uNBATyz$fpZmL?Tk+k*I@S!!GS z!s+S6B`+* z#7UEg#Rn6=<{9T7NOp!k#Em_PW4flc#V_pN`LS`+kc9M@#1r^x0u|~sj@V%gas7zY zw)lmaq8}H>`6mhKu?Fvn!LzB*@;IU~gP1oqwJm<(s+S%Ux6gkrAc<-5H9jPF7gM1` zMO2H3{T8IQ#V?GU|JS%Zz9gi_>wIo>eTNF&ev^3b4dRs7Q`_Pf?ppqrIIVw4NRNSh zl76t73f)*m3};SxFSRXxVb;IIdHqX5dJN^&a&R3DbZjkgFmwEx)VBDAb@aHY6_CWV zSew_aec8l+13#hxn=_wf=40O7K=Iwoyc$hicxycg_A_^HCi`9HeCA+gb7nqf&rOss z)OB?^?oTw0+gnI*ig|>&SL3H_*VU-&s&d@P?DQ$suf=pT4V$$LBk>d7Lgv-2WD9lS z7aU)@)zkT>a>F7TPP#~fvCL@ZKxQvy7iL>#3ufbsovfE_J%J%1^@^Df3U#&*?q%lJ z%E0ag`Z(N6Z7_HioebFDIV}}j3;Z$kW3}b^=m0X_zv5`#cT`X*%pdl z*Nb2B+HIh5giXmd4el6qI6+vEZK3$J0uObP_w7a+=r!i^Okd6ZKahz1f~`;u(oH*5=cu`Lw8t{1=L1s|rm z!VIwOTW70d{hj5B2`w#PTTJOLpB_JpK> z2*odXvc*E#V?x;j!V5eh;WuBJG>~3E7pyr>dF`1Gj*-2RDe;zU-#$w5Ur(jxmuw4H zo9tN4oTgFyQs|*j%aaWd${rBP1_|YyFr^~_y@2>7PvSxuKq&db*}u~s5Q?Amc??}R z`**cCCM2j*#^PP;m8K= zL~XM>qk9L2^t1~L6JH?PcH%$r3&n3Vr#$~!#IQKxkwK~b$g_rSmq!YSfCG)PVRCj+ zo>Is|2TwL6Ti|)h2wcgtPsF!Vqv&H&Qxvn`8n$j+NOiMnFWPBou^7j{N`s=4xY%j& zGS^|6hAtHQpEA9Hzw4QDgZmhU2qYlX{bD~UAJy?ZH$J3l2D3ygjhvBrbt>6sm|rm^ zzDu)PXm%a8b$@v+kL#I6pcZ(B?O$I?J+U7&`zyA$YkryNlMxs2CreB}Pv7G7>aMpY zZry;q$y>01Ib7SKD7ITM8!)Rf-OPeaKjytDsrR5hp+v;(8?e2c=wZIc)VJt0_RnPM z1z$|Vuh$XXkSSg02DBRsTQcivg-Wx%Za!_%tTY&_`6p<$u8Wy(KEB|PG=zQ9@au)U zrjgfH_nW%o|JXM5nLn-F{3$0K&iS>7rcr?%K~Gtz2mlEqS?=K;HE3@nCWCvKZ&i~WP$)T8b0DfWn)f9I#dw)Q7 z7Pc?3{WWtNb18E?Q*=#tkv%My#AkD@c0S+W4+0{!uyn4l*sufnMas=p0bX)l?7|l5Wby;U$*$QbmEdH zoWuE3iKa1*9YdKj_R%gL%Iv~y&TOE?t84a`dsFK_XIuAgu>CmyWFX<2T7mgu3wgk9 zn%#o!+L~YLK9<(`|JcC4;MceKapTzQPXb{)^HR+G%-efX@6rowf5Y6%{FwPZ^EGB1 z^981i2h#c%M>kHW&#b^K!PK|t8TR`yrH=6W?$i?(|D!s*{v~jZ1xJ}XnCrDdud$uw zAPsQwz~gyV^M9+^7fsFam1axfeQEeVPs1-dp(l+zb8Q*{5&nOsY5dy*y!%ueg!Aup z7AWRiX6#cHGK?2Ee^?s2-jDOQ!#bBe(D88zDdLhRY{B^rnAMo&4yYROA=}zyJVPht z%+tgi%vVp5J)1c+9Zujn9Zq$zAEF-#56%)8Hg+hchG+lm|M?wQ=r0^he${G!aCNnP zR!EkLv)E<5QOo+XzU0&To6LTE4~+fi!>lz}-J2B>8W_!SdS@HGgUw1Amud)WHfA4o z(ObkG&892+^`WzCeu)oYzigEZ9m#&{n?wRa|UoG-GjAyK;H>xd42=OaEh<1QJ zm2mc}5wDf2{=|vO+PwbNd1uS8QoA1eWe>`pZLa0Z=C#%QvUy#}zhM0fg%%`cD`*c| zy;jiy_BM)G2HnCNVtwDL^(TXVDjSF+A841TmdGxB-d^@gX(@4%{PsKo9a)}kFIE4N ztI9!=35WAm>!a=FeCt%D3I7Y*Z1&;N^jSo+KL_o#hr4aEHanT+49ze5FhTRnF?^N$ z5f2N?IlPnwvXkXxS)uvmc)m^kR42p0)mpOb+jW{>2HD7dnS^YWllQs!W%i#+zG^i; zq?);o(3WA&xH zEwayL9@TkQ$T%_&S*Ge}lhT1|@_bxMxq@U$g}m&yGOOE%qaS@Uu|S)1~9YV62$o|2~Vl!CwHC-6k{IG!iz(ynh*NZ9{Z;}$@=toZUBv=(KIy2U+h>OKq&dG`cXll?ic&-iTl!NC8SkY z{6d+SQ0k>;+j{GjP@znQ3ilTK<1|LgwEb8`_03V3ToV_eh5|IR0QP<$uW3b%yQ7`6q!rV@U8RQ~dun zH>9j@o&W#V05eh+e!{x;`unF7_$LEe%Q3}xwEj~#ta!?Vr?Q`ZLcIR}=>%jz>t4*r zQGG}B=r2xj$o3Jgc!*(5$J5@AFf?h!Ul0SSV4I~`EwlIoqVF$K_rUdi? z;+I56JPjoLg9{07vMs#Kwov?<-ZUg2iM5u~K*g34?=2&4XFkXA|COEXdN}`byhQ`F zeDm?#{|5QDGUqb8YD{AN^XwPx~L7r$dA-~L-2>+j|}srfV8 z!f)6XieJ}@U-F8sqPoIdY=gA^Gq6K=`+X7!#jh6-zvK=7kaWVHYzy16Eo|~3um2`m zKriq}Km$Bn@A%M|wchJ}NB*a#$-;mqC46NItm$=UCT>tRTw4uUnwvF?TI)<^96JBS=F-I}KXQnRjNGJIxFVR5B z>2RkNx6c3PIPsMC@xn08f9xXVZDpo6(BH-F^_Nz{+J9jH>$;-XpYW(It$#h?-?mc> zXw4_Zgn0e`+XJRo@8N{ZbWW1=3O#9D27Gwo8a8x@b>UKBt3txe!x_8T`=wP@;$c7H z9A<0gH<`%afO(&FqVH!=ykjz*p*1*Oka;@;#ZNFd5KSY29mANN!zfYMjBQ~ZwuR-{ z7K&fji(m4F*gBkq)Om7d;{h+0r-_RGW449jkJs|VZ_`=?sT_Y}SJeug3#AFnVoH26 z+hdthf3RlPhixxHN$}Sa#4nr_LIeKRlDM0>fZ2;#p80zV%G?p&IKZbLF{UZ2ZDHAx&^~E-aYmN?@ zEs5!|WE#4({9Mm8q;NWk5A*(MzUWdD=U-~aKeyA`fVBMfxYqeE6ZqT26nT37Og;&F zGj}}&?e!;u5}GiFX5Sr6C#U2KPq6)7cj4e%;pdI%)dpGkE<= zqOd3@u3bnIn89qifb6H`GEFy!?PVr+CTa;XKsWaPTii0AHel{Dq8Y@Uo*H$(ZtMBF zT|%pOXekY-)xq~wXo>%;eUb-~I>R+vCh+QNYeG2xg6$4I`m0g*>$aY++a`dY>8jlMfo}h>?3~=^T6KJw#4VKpJ^K6`28yq2sg9chbgwi%d%hR z^kY=#Ip+1FscngWV*7FAsPl-u&yYYE$o8qzYa~WUpq5E%8z8*ZJX1 z(nT{1-{gCa;*f-&Zcw7mh(E|L^ksY7J@Sh!@oDVWdE`FjFSs8@o!So_WJ^M3_CKP^ z`fwQ1^@d_ry_4DHq+&qIRD%S&iW*E73nw#3V@U+0=nNk5udO0y;I{e8voLTlPovgynY~QF(e#^GTHzZ*l2XtPnO9J8BY}aCn zE%AGGC|_syw&WKUY0K;Xi#8O1!;n^OZT2_fNTr^_%AK`hVo0!eW=<#HZ!Y zGpLSG^l!3XSjOZ59y5ZdyRqf+zKNV119*)|PH zbaFsvnXx1ko*P5<7^c_~FUNkJLtZ4Eu#|0^hOuQl1;~NdbvSVh`*oh4O!>ljYzHyL zmiR?J$8;W;hB_GEush&n%YnaqOtB??JeJ}*1LDaqJTa5(flRR_UYz|FO>01L97-Ue zFqZ8?OtB^Y)m+NgxpFo6g}vGS;{)=GjksxzZ+JMMbNo6I2&=LE)mrk4E%A8v>pZuS z@`cOUuDY=*1;il<_dg=PPJ6caPn8I*9H>?t42d>BEFNWhgy!xyC11BKo%KVv4=1oFn0CDg{=#5Y<50-$GQq7VFDJ7b z^IjzRAH_YL4~Kk{(;U5v0>W}^@7+m$u_Zo{{W^~xpnT!`YzwEceJ?dlLvt84RN`y$(WnQLs~AZJe`!O62c5VJ1xPcFDy<8$XIKR+`w^E0j| zl)T5%I?2{wph7d4<2Abz+u<6+*iO1b`f0a`-G57MH(>j5w8l4P<>+a_*qa7>rQuI2 zU;M%8=&ok(X^;Pxfp=&B`w1;hCoU5Zrah5Tj~_@TVDA<+Wqe2;PgG*adp_nBCkd`< zJRh9eFSbt6>Ha6QO+yM4DNO?w)0jIXwO?$VqSO6BX&l`*hWXVoQM^c))WSf3Has5x>|v|0Yh$ zMHlF{6sXBxl~+e&)%r9M@r$kVuW^%vdSY6(6d1+>j?ft2nCgjNY@H9|CJXe0^lT|` znDs|BUTH=X5x>|v&GZsbln`s*2NF(84T=LSQ=)3ZOJv4sP zjwT|0vT^=NK$tq=uW`vsi=xloo(9aN@#W4b{MPv|4xJ*@{ZDF({xcqMyTPPj za#(*l(~Il*x-I&NTz~Q-()#!5O9M+lY@O-F^?cnHeQh4EUSE?2uE&lY{N0qJoYuc2q(>>xl?Uvh@y9td zG4YG7^HH4Fzn+kuEd@g6(tu$ax6V)P7h7kT$wEEwq_zyaYyl0pLSq?~+Ap@yl#U3+ zep-q?$E!4;zs8T2r1rCI8WIqSQ0%9r=w~gZ0q1Hg_eM%T&OdSJ6rt{aQd{&xc);Nr zv#-QNtn*(2wga}#^x}HHZi~LDH6Z?)r=Y$53V)C~Ahu2s>i#FSMc<9b>-hmcTt>&9 z+0r#c-4?$vy}0D1MbU?><@H}-Ee$Ljvf=Tz_=S4D_@9&&Odj|?59sp|4J>T3`SG^+ zg?hgD)1xT~Qs7q}@VdtGTWKQV7h7j~aV_68G>0JtKH~v*XiWZ$CL(^Zb*2}me4PKf zP;4nMdm9ZnPvhwwsr_Q>6rJw3ZEO8KHju(E1zy-m15VVqeNSq?*g8d*(r>T-ln!eh zre#ZkxV<#sY>h__r1p!gQ*`j#;~RQHdbSjJ?H~=fOyl`Osr_Q>Ty~JxzaDr}TL#{I zmK?|8wz= zGe|&eo$1B(eBBm(6CUq5&|ZI5$NFo0fvDT!7p51NytF9#_zS%L=kmb9;+JS5x-EWT zdU451i*qmV`d`8WzOJ$SFEkPHi>))gxSs#eHnjmhV0*2`de>+o;ul+IdT~A9)E!cw z@l6`AEYo{~>_yD9Z1E4^yjFit(?}=bVO$D7E&X`{zg(vc5PodiIRB|*7-KnMphjQK z*5hKUBpN{M7ujy1`6XV~@>}aq96B%ZF<-}&czSz4&-=SQV6XrGa1YqyKlL84uU7bP z({0-2gPA3m-~LAa+02H_-*1t>{9Pfh{~&eCDMoQ1;mYzyCHTR5L>q4;&Z_$6;E0FXPS&Oc}7X zpE~aoy4*Zah6L$xBv~+P$n$;#9-PGv5RT8_$4pWZRO+qY!gI6f972m+4Y#g z%xEY1hn6C?`!{H<4=J>uBo&sKJ}IAJ-NnGv`fJ6=E*d~wT$EUl`F@dJ^!OkU9qUgY zaCza!`}47XZXt@dW_B$|_8$d^Gnsl_u^;5`Mb`&$jLx5Wz_gB`yo_bEGxE;wQ|Df5JQ-$28I!@c(8H;O8LzKkNZ~#=MC2 zHQ6~mw=#!1eatsn(s{ih4TiG+dJD?)Fo!WWHYIq!M!Swi-`X(lZ}p2SV*tkVY6Z4nCNIX|=+ zUFkA2zkQDEb<8QuF3hsbj6~Cr1Sup1#4m!t=2Tc{uq`~t6AbkW2k|%LtN7T!OaUM_ z#*U7U=bg6X@6(#tg}I>(*+bcuI>NN-iJ$A5hCV=A1L*_G!1-IzM0CnPe@`3}Nw~s$ z;{TM^Iq`owpf;X0{(m_Ed;I@!0(_hBq=!Jxl|Vl0g<2w zD1xV@Odu_q5_sCeY30krg?gUmH;uFsB(WFoD#_Dr@eAv7{#d?132U(}ENt62|EOaa zC;3na@3E~H(DNnlAJIDhrC@seM+2a~u9FS4Xs^Gt5_G@VDGONFkB@mzNnE$ZFMO5r zKW)oTyrE;&F{Wtj!L~4vZDC!ub-kW1d4DCZ|Gx%kLgMeCO(ZQ_@}HO{7uE%`g~GJr zx?gP32_Nv;FLAL=ap?S>1)lb_C#EqgF@2c3+EM&1W?yC_ro^R==-F=?BG}l03JIsN zEgZnMuo>Gz@#}i=OWu!sN9VLnoc~AJahbWF`C})VPraHEc|f7~g=zWq zxa2+H4UxFm)|UeHz<)z~#`I8m144^72p>Y5>Nk{lgzd#lv4;(&`23za)yRO*VP;-M z{`7cp5#?=SPGh!X1~Rw4LU~1)$xFyS|2pw)W>=zV6kx}_<&^L}b35}b=F7}6%+1Rv zzW~#-ltvF`dV=mx%hvsRoxiiK@eMgf z{{ijs|HBEGbkh6>TW;-mBiZET@xM;sD%bg*`6crc<|^iE%n8i0J-E|?nbt&b65+vT zfG4nI=;RD#Cp(AP^VexR@n0gx!39UNxr*p{DQxQ@ZJreQb_v+luQbusxL?Q%F)}COYkz{oN*6GkGTiDr4J&JePt)3zRW~op+OyTz8X?xbG&f zD}6UPp)6VmT6wezcasAVPegn>;wuoJjCeHS(TGPQZXmuL@fC!%k3>AN z6k>=^Mm!4fdWZ)i9*B5gg}Y|*IwV9RArc8;NbpBOQaQ9xv@i$}uZMUb;s)Z0WiV01 z*CD<#1k=zBbdYr#8)7`0`Yo&*i$(W%ZWUHoPFxG?Gz#aIE*7DIirI7Hdtgg7!6oG6fl0`>BsC<-K^Kv)43MS&wI5Lg67 zQD8d?_(K~NcsKcKJNUYy23kTF(Km!yw25~R68xX#PmK*I&h%2J)gt#@@c?d_M zInd@qTM}(Q^wpu?4{b*@FLdM3vY@>RZ7|vvXd}>0LN@^IE_5^6hPDRcI%tO>?v8d9x=Cm`(KbTwgnlEm;b&TlXm3MX z8ErSTZP9*$E~XRy%ZRoL1q!3UDu`>K9fY_u+GPmGqh&=~3~?E>tq?zlb{e`tX!oF9 zf#whW3TVU7ws%%L+lGdk3C(a`wZVDN8s`Jr_EsR;_DB$I`|}{$_Ld;p_7>2it!R#V zXfH!w4*J#57DZbMZBewP&=y5o3T;uerO*~dTMBJw+Ba1AhI%u0+H1~6o{+=qCjMA5CtOZfhZ8! z5QM(qNNm6;OlmYHG!_@K7tmfrn}~)(?2q^n#MdF7fOs_GQHV!PL@)|1X#|2uNI*g~ z5+adM4+-^9pdR8!5Klln8u3WP!w~mJ+#hj)65g?K&00}(e6PaKan0c{d=h=(EW zk9g7;)Efs4;wwxftUy8-5|XT0#$X~yNI*gq5~2`~LOdxNe#8?Hk48Ka@j%1_5f4Os z9pcf5*F!uIaeu@Utw~^#iI`+G;(>@KVG>6$iS3wV0^()@5)zPLUGFD%L9iILLpuZm427l>e9+hH1|Rf^(1-OzP3Vt6AJ`W) zq2CU@KeSPUP;)SjzX5UNFkD&Rfp|5NKR^&IX%)n1{%9-SM=`YR?;#g0@m&-{Gtd%N zqBz=S=!2l&3~ghyZ=makb{o2v(ek6MgtjW$Ug+ARU08`@HwNNNXsc16Cy%zIL2?`Ja`l516slxAX>r-5G~<#5G`Rjh?cMndbH@J zs0VF(v_GMnfc6V?L(qPKZV1{h&<#QR1-c<Anm*Lt7o~y(K0(DDVTs-O&z1+!F0D#4XVdL);SWFvKm<4ny1$Z5za)Xv?7uMLPj) zTeRKKhNJCRzX}CZ6>sZ(Y8Zd4{aT^VQA~14MST8Z5Y}*Xv5IfK^um)0$P7Gb27yK zXzL&jLt6oHAleFu1JPDM9Ei38;y|<&5C@_qKy08zLwjT*t|^nypA1d`r-HHI%iwe{ z4x9D)jkxPxI7^*f&25gY_g21BwR zPu>o`k^_ky4I@)d z1IrdZp1cJtSrqj;8%FPdmp^``dUnqk>7sFUt0|R!&ca_$}#K0Pj zk0;*+r!+gB9M#P*&U8DT9N8Veh&vh+?qL|C#$qC1ijwiorJ*5)7@_6!oFk}w~!0#=71_t*rjM`tIF!&1i9$4TIwh;6` zf_PuUs0c=akzZp2z?dH~0r2u=4A>9$EldP#`x_<#2Hi#-FabOX=D2e_*);ka#sc3H z$-&_0>?d$rYZ#exok*Sxs$wUSw}7v@P9)z2CkLNMu08-?9}h->1xueuo&l}{*MXrS z$OFq(IFVd$pkeF=$ALvEo=9E+ZUXm%ld7Ib_8(*zC90h;lk1_gG!hdSjE``&Mq#jS z7Zd~+_k%qIzkb{w1;B}eP9&cMmk&XKq4>(DVTgm{V@@P*2lI}`1i%l$Fg)q>g)eLJc@>fg@t7{Dj7Zms8o}gjYWy&!>Cwj zlw*-vk&TLlM$MR1XryCN8_Q}eEG#wjONB-?CYc%KSg5Ex3^3q;D1#C{M6KWZM8Erb zUDtKr|J=S_-|u^!wfA28v)10{%$Z^4R0)$ih?7C)owUPk7b?UGUk^Sk`{DRrhsCf= z)8@q<=EhLdPTKB2EGf^jxgIzyg>X*FVX1^eUOFt9&uLoIrwqu{v@xF@mL&M{_QR3` zYl;qw3l2PYSd1$)EgohfpuB@Pu<(z=+{^JG{D33kgX02^aP!C`9ib6cK?}6q7j#5& zFuv?_M8dK(?Z&G)hARgg5kD-r;fPpYU{4G^BKdG4biw?a2=pTD!M2{@aw zpb7e*6(*aGaL1`>d!QTMIq`_Z+coWg`G`2|od0ptk4OoQm!Jn8hG8o;Enzka;qMkE zgew*t5yMMtnng#%4!19(KRo_C6Ry&<)h{6sZi6m(2>M{anj?~wt!a(#k`N5~1Ys|0 z+EZW9{xXVYeubh}G;K3Xf#;zePAWMfh45YIhNs~Lc;_yJyvq3tlVAh1!kc#^0KN)c z@EG*L5nof895ypF!OKeN53``thH)Ch4IlaDh-j-d?I4VYrf;bL+yNbM@OK1;Z$du| zav@|5=Q%V(AGE{NJx8Pnx}gUqevg3H*xb+rNA5)cbV8dGBeDzuFb8V6n$`v5q4fs@ zKreK_lzj+*<4!SCTh7`dPRa6T-7CC~$V{lwC)MIela+kZM@lN1c? z0LtMESO^QC8+O7AF!g6LUB?743C5I@0bC37VFz@wbi#zgOaKd^mdC5&5d=X8w7}q_lon<}7i@)o zXsJZVTbfn@%`oX0!r?Ah1cx7I3E;ah;%y#|a{>X-_5y|#;|z4dxm5^&Zm209Vpoj- zxD#67kQxNQJm`WUwFrQTFe+cuRzVZ|9xj9d9{NKQEP*!Yf#1Tg4V?dfVZ?9X3ROqR z;q%ZAcf&$>5xSwVo|3~g(C`jdFqi~m8%O}!VLt4H`(ct7VelOo^)8iyCOEzkVbB2` z?{favW0c@XXhIpxfngg7^d}wQ+P+7*HztGlqul6mJo>0u;D2sADsDI@^{AA5z>+<3 zR4%|Nj~|tVPR1`dD*Iv7Q%AY;IB}chpe#jMW1r6}h^GCT|)wH8_ zCi;l~Ow1|*!RA-+!x?LiN>qWS{k4w%F!{}+;(-g)Q88^si1Vma!i$AR#riRucF$4X zuTjz8j!IY|oA=mJvBT$Tj*1UX^B(1+)-5P$Ix6|_(rG66lt(tSks-XQ9Y36Vj)~wE ze<18Lu5_JL1fKbmOyKT-N-=Kb65OLw3gL;KmEwm{eJaJgja#)VDy0Y(^sAJx?Tm}6 z6bm#CsI*B5#$AId#qc@jX>_Gz!j;1-r4qJ{tdyuCO?%u_DQ@_|bSBurg=bc!Xgf9S z&j%{S1Pu>WiWBy-;QtTTgES_9+vnql)eDFRe_vQB5yhGoon0yUa8|ahQd}5iPC9(S z`M4P&U-F+@-%=@d_{kwA_=?k|3IT8eyZ|@XR7y+bWmrFrL=IN`NU#(l?xA2R{mQFKf$z}a6O6N`(p;=5zwgASkjCG=03+I?0a4uqK=ChI{F`%9B4Hh7dMQLJ}yyvx#xpU=)Uo| z_@FiBxLC_riebm)0<=QY4_w$_4z!G9JT%?L_Q}6=(1R8$k^!k7b!JnWVZgC!$BG?Ek;h;^& zMJwku0mi_Op&9o6kc8onu+WBa5yK5fe8dFsVQBb;3k^(yC!iH>DWK$V=*P!pKb#Ex za4C%XRns;=6Li6a@Eml&4?dwHa3A!+DTVYu$ZG|(C1Fh6f+AS`DT?6Itz-auZf7sJ zDPa+nfy;JKYIw~~))WSQbzDl|c<6yEVAvtf3K$PNVG0~wLWSTGSO~X6H*6_6Zj%cb z!*`MKZ=C-y37&ygn7o^{f*(N_JPUpB$FIrYcdq@VWDMVe3*oeH=nubyE_mIy^oO5) zNB;^=Ll^Pk2QU*}{XLtk5Tp8gGKL@RC4>TfBA*Vz*~N0FTi|Q3FRPhk80YZZYl%!!4x>cc8JnoybcRt8+5~z-kADG`i;2~!yW(_kj-n#KUQ(aZq& zA=GLp@r)A^4}%t*5DUEasT1OW&n!M6F8HGDg!tit>=RH4K2C!YB_fx37^YEQgu!-du!07p#P1Uq2yXbu0-q!ql}VWFb5P^Pzbiap3`Y z0b19SU_F=aH%~|kEX||RHjGE#rquA+_b4^2ETeWK<{S=fS+$i0DN`_ z0=&E-DMkPc{SpE2m#+{2^L8NsKJ+yL;P_GmG;(431_3bm+Y@5T!8nOg0vo?W0Nn3F zKoe`U2LW*H_XvQC_aXrHFGB!)6Na5+)BS(|_$pio1NI>R*6&9E{P|}Dz~WyK;NwDd z2m!F~?Gdg5zxYQp$Y-;_gVzN zl6nNdO^pbE!%rdr{>O)aQ`~E|AOP+^#U{zY`1RBYDS{uio)8c0bLNCZv~opjJ0T|6 z#A13yx62lpm zwr`b~VX5uPDzRg%xT;Eu;4S^D!~?%IR7pe|Z!m^ci3ye@REZTvO{fwlynI@fxZ#FJ zszmd%B=f5z9^U>;l~`cV3IxE1UO@o7FAo8*{38Ukb7lPu0nqkhF#<5Aeun_K{bvNg z&BqXMmMdU00^oK(0^q@m2!L+~SBo2-j;I#x94}G>t0f+$##W03dPY@?175tfT3m39 zsapK-@q4Pp(7|=%{%SFIaQ=^(SuJ)P`)|izU@! zg<;F9#R+Y81i-6SBcPM}{9FXU|Ga?!c={a#!0Vj|fEgbnK=*G$zZIo&^ z0&w(mApj=rM*w{87X)13_5F7Qz&lSM03L2Y0DRnw0Qd*gE+VuM0npHd0O*HR(0#I6 zQZBJ)eAQ9`9nDPqC)b0PYALs2m`_zpQWtkHt<_QnBTh5nUj%@q(0!&_jDHiLty+qq z!_P!Qfc9$H3Qgy#Wq=l-8O~QrWI%xCxKJ(W&~gcZFuto=5&{FbORbiC=$2~fg3f>% zu~~uwG;2_eltEKSjl={8Xc0YXBo}(ZYQztVdeumBNPuP!uaOeyfaTEIyGGJN@xx4L z=~E*e&<&G%z$WzOyjYM2Yz|l2Q)Q>>pnBZyzPGW-oOgyO|6lw z&~B#RwTy=u&<}HA#B^JY6ks@~*GTXH0>XG`nt@Vih8fTai(nBfgDzMJ-LMtfXHvQA z@WW)NCD(`@nqfICf&&IJ;Vd$TR#*z%HjMD=S)&Ii5i~(7bV3(&!%C<<$WlN93^ULU z2S6=_fY1U<{c#9c zhTu`m^Bf6|M#yq1IVQlSMZCaTBv2YV6WaSv-$R3pZF$#5r|Y9fk@Ya~C33VcOIlgMZn6WmAOuc^>vGXADUQl=2t zMFplZZf}ivp<^HMr!nzQER~tKZ5Za?IIU(d@nK3llfaei`ec^i1ebz6B(rt*vBS@?iK>iX548qhSoMRox`4JXDMMs2NisXi96Y} zu;>Eke`YFy|74DC;}pD#rhcIuCA4FX-s%+t%NVp^0z>QgS{b>B z1WdJ30^N7jO5!slcu%dkVf@5eNwrde`)Va-G5x35YNZ3iZmt#A5){p>mE5HScmM$z zOgOt%qL)#^)LQXF_uN`3eHHtRSwHzw~Z zYiniUS{x2aw+_C6Qk{9VQtW_l*GlGkn9rKNfuIewGWkt1co#u=2-}F@w^)Mr$mnen zdB0YC(Eb5J6q!4zL_P^^Vu?0Txeuw_JB%-2N#EuCH*7}XMgn|HM(+{e6Ec3EOt(-v zX!@*{Kh{#JZEQj(6MjwwHc{#w>;v%5}=fc>L~3u1a7F6Drjk>gx?b2WUZuqM}TH3F+1*UNUcId>L`i(eDQ;+d<{_G5(KQv4!ua0-a>|6BAuv4;-L07g_6{33!RME+=3Y zr_C=+{1@l#uax%hTFE-d#F|G;ZjJ*z5`2jM!5-NU{h=Po{f!BGdc^!YOLdt?A}dI! zw}*Gx#Jk)h8xJ#IUyn^JM^JR7N1~6SxSvOS(0a8;wpKD>e~(y?F~Kz+2|v!j0UjxY zj_W)!-~Ad!)=yyt(+> zi8l}7XNi}F@N=C1j`=9Z@GL}m2LYc#`5y#)8s(h?d=7eZHhqzV?TVy*uo!B>gbBteLiOFu2pra9Jnq+AQs zJnP9MAdt7MlqN7xGb;oH1@bu^nLyV@DiKV-_dSvq5~#(0=#hn?^edneJpwi7CkPFr z-xe~45!*bH-;;iyQ^{U|ntdlrdKvwSJ<4j&VNdH1^s`a-<1eF$dbXL-{=>KfC`V;`;kbcN0P5%+;K{M zHA1V|l+aS^k)kMs)O#e`)}Mi1cI7oFI?1lSmVqrS2{fJdNbvv$wy~?P3)CEEJu-P9 z13Nr?%^G3nDLM3CWa$iK`jqLtq&YiSF&)s#B6VJFL#*d|sa4YSL>LlKXe{r4op>-J<-bTrn*U7@M zR5q(lqHm{y_B!!E|EfCKIF5?ES|=%YP_fr+lxRGqSzE`KJPGhdo#ft0fVbOHh-c0-5OuVH|!V}4OJL92YXPxBTL&d&if_o9TyG{m7q+;J9 z06M>~lY%71??d1u#@i0m$;kT%aF7h3;rBWzzMqC8b&@$5LB}cO6xwSj*^)^AvmaB+&XWlm%LOstX@(chBwu7 z?+8cLi$~|p^-?gGL~g5>g%%PUS1%*yQBhO9_~&u{yY8-+;zwDFiS?5C7|QOe=jIWm zQ|m>09OcvNr40I$>m_GCnWfarOzTA_VOy%eP* z8AJbDWW1Ej^2s=Z3Em~+WdweojG=iG89z&$0y2J%@t=@!CgZk{F?4Sw;pGVZoP=#F z2(XikpC`Z)1T`lbtM!0TF*Bm zNaVMA@j}O8)_4^qudJ8!Y~oeba}P-+YU`x~y6fx3R`Lp&Hq}ekt2li1d_#c_r|Knm zH4~hvm;KPtUN5<8nBZK!m|r9F&U%T=WrBkf;reAK4&P&>zgG3aurj7=w zfbKUNB!342-foc8oy6JDAcp^t;l>8>LdORUQdrEAe%K)CUoi3J28sWY1PdFa1KP}= zHAu-jMkXR*q;Ctq)Vh`-){5RD$$c4Q)>e&Nj z3}|Ez{6Ih-dte_Eo?;LDh@dm<0qAIF59}vk2YcWrCOpp`IDnu_>;dThi#_l&71F$t zR?dV$UWxgIcs;z*3f;ZDQuHhH_3=u^K^p=3dim=X8TRu^7j#5<#dU}b26!d=Hw0Yo zm89PZIM^%U6$l*a6*qJZ^Ge=fDt42Xzx^O6-YWx+;veG`4|Lz+m4Zs*jP>#-82a7e zm6690V)BX~I_~yLvF!u{?)7rliqc758CQ*vDPI1#vlqHysa=$>l*>M1@y!BZ7EY zCeyw_TG27DBwQJ!*{i5TB!O$aQq_-%>Z#P#OzdUvL?P@X?fntf%=l{y0GRvr#6;5cjf1i5W(}K8+GQoQWeE`LQB#u4t6f5kcJlM>b0S zNG7_fQ8I2qc~qmAV-a#~ql}Cr@O6z67LU^F8^sF^gB!VJV}j^L88?Os-PkA#6Ub~B z0&b??$VPG9Lch31X}y)WqZ%dZHYQAHl*F+JxfOx8Gyb+lZpDH)|Hn1T{yPXTzEL{H z6JSE47)%Vjt5KpSFdz}-cOm4SM)5)Cy^T_SH$o>iN>L&LCNc3nl=!|z$-I|1_cu!F zL^7SyD5fOhO(o7GDlv^j?nBsgghA_!MseS7W8ln2DV$76lN%*%3IS#@U@9elkc^=z zrBMo|F<>_BW(3TkeL4Xjq8(}v(>{XnYb3(p=%!Pv+zI0gbyG*tx+yK zNc(*H*=93vAtj$fz$Y3d>meq33PGs|c)C$49!A)rM$zU{0V_*lA;98BzDP`frHzvP zDC3t=iN_fKY@<}Akzpol{5TUXhw~Y~0wD_!nneW{66Xaf@C1px*eEvtlLWL;`lrZr zCCbtX{8FQIJxwK6G4V4@@G?tarIfEw!o^JVY9n_<1YAvEXjsE$T1w#8*h?Ao%VjSu zW8&9I>{;ThMfh_hnaw7$`36W4N-yvb%*LEt>r@Oc8i-6+XfOspCu{sjW$ zv!*W+_#HB4$>KMXu^s<=WV{l=9}svIfj2cuLN*C~*eI5liCfSpxvwDXW6qLSiCf6T zISAXrCSF5@J|pvSuc2%kyEvB#wl_-p>jeHBu4Uj3cI!IUa3>i#n79~$>k0e?OZ5ih zzG@Wvn~W<#SRNDaYLuL}2>dk@zfD4=joh#x>{~WzJ`;aOg*G5$4{_hYZ~MMclHMhQ zy=;b!Ok76E-(#YEWCra&qWpaV?I*wol==Vzos{lp&hJeKE9dLy;+iFZwtjQkzJ1DYhi zg3VMkut|cCP?|waVm-=4Lz<+jk_m2TlDy*th-s3HDh7^dl9U?y-_#`IJoJli5<@*} zKAQ1fgx}1BjR-O}N%={HjBS#lX2#z^oKuW9HA&`a#^2Q>scnqEr-^S$x1;3VCP_Ps z;-n@%lcD1z*n#5v$P_weFhM7ri4bT=Zjv(ShUw>7vRO@hG(%-z%mos8ph?V+Wr zNz9kwKhq>z!&?`=g3%VmuN_HQ{4?HRM%Q?1TXMC&dY!>rP7ewM^hR$)8%u_zeUOp#Qrkr2{$(NZ>juvzbH((hf5R2HQ0I4gz0~ zLO2=v51y0@&~=PT7#I-X6U!j{!9Hn)t`HxeZXpaNLoL)N3t@Z@pX9@$Fdt7(pnp%F z7>3}#%*W#zNG#mPb028$&G=~A`}o8eZKFekk7qT|p)V7`qALgh{Z|rTXs~AP=aXz` zy~@X@WR(7DpCsN$zbKy+KzDzi1jo?-8lR-Whygw+gYnn-_zNlH2QnU7uV*|gGWaBE zID2D=kN5v0=y-!qMvf$tcpNt|0OrCX=!6lY5Cko-5?Wy^^gu0^aie__3C&}C5(6!8 z9CSl7^uRP2e>3s*c31$lTYS9#$FSe(lXB?1jS@lYc%O7Y(*&PH#j(bT2!#G5N(Y^j zC_OaaN9mzOCL3O!I8#c>)LLpzLtZa5B_9w%d11k<24pNydk=0f`dDhf>teNqhF z3vE8}V|bqMN&INm_DP?lL(@|}DTIFLg+=M?g)sdun3{h^bAV^%~mRvK>K2! zq(H+G;y^RZhpwe0q;nYwL3bvVfezdAKDmHlev#7LOi5NU5p=)glLVdFY!>Kwm5E_d zj!&#mTTLeV@ftGG+jD)gAI3YV6g0f)lL5EDw^=f1-9Sb3<9DeDG`~khpv~#@Ns;c@ z#IA*Q=!d2c+10l)(MMzkU2r5c6c7;FVKOvrW)DE^WA*@aL5JS{37ZT$3K0YiTUaV1 z{XeBYw0uT|jr#e&mCd0yY~ysfjX>Ku4WZ$4GK8igHYK#|pfY0#ypwjwm$@VZT3`-z zf8mpj(7DSeCAz0d)W5lTv8@ z*~fzbDDf}s1?W1&CLG5^6$FItN-6^V$5be!v*hXx zk!P93ll>3tvXv!v>NXocFn&5{j0Fkf$ECy&zChkPef6J_9nT*2?EztA;dqL-e%~GH<1%a?=cC$n!G4UKW5p+Nk z)KbY%KZg0x`Y;*l$B#6NM{l3oEFHQZhD|~U901LhW{IC9F{zpu~SV@U=zQhthKg@!rYy!ggmkFrz z6$0vfm4MKYLqO<&9Z*}%8c$_B9H4UzYpnA%mKYjd=k$iwwOnVQX&p)mG2$Hrgc0jG z3!wG}YdDSLJTlk$HUXePu{WR}=0HzAn+>`*uov|9ci9Wjw2`$pQ_=TWYiNI;%?X_! zu$iIRNu{A?+te(<(;4_7yBS7&)GWz53n;D5%~S%KU?FtCO6Y>YGYIrCi52d%9LoJWQHO!z4Mf?A{`4I!7cNc4RA zhqv%$Gvf5d4~zP=NCh-s-Xg6!BU&VE0q4KtiWadhAkdWzfbPf^@$0;*MN$^h@#+?S zy!YoQ+C4-mfxEKMe zm;h#H6L<*&Uu%*5uozx|rq>C)lt9f0Tt-JzRx&WoH zWAiC~-A=AWIE<7bkFzqw?!7}KAkz1JnCTu$;G3=%2&&d!*7SRtTKo`t_ zKG<>S6u*8)@L`0)Vq3#0abx72JS7)kg71_VRuZ7|l-O5s3=3g0bi<7E^n(Q#=$DNU zm;}Ah3WF~)F^q;T*a3Yop^J%MW-0$>V(5g0(3ah!Rm`uT=*m`!d6f)d3M}r|%CFcN zculLs=P<#*R&m0_>s$G;I)PxsYJ}fJe^_=)t7vPOcpGtEN65}r$%kpht^D?z1ioq& z<606cZIu$}h5ogi{~6yh!8&&TQ93#ZT-hpy^_0A(RV*;U(<()<>{Kg1x#qO%r2S3K zXP5-@E)Wow{YjiWChB4w%nLj%9+(h(nqNj!v7V>J2a7L1E#|jLq~B>Nd7Cv!9)^*R za?@#^0K@SEr$u|83}&AeE3B}b=0QJ{e%@)Z!0ZL5r4W`qby_NQK21L-nJqcZ?|q50 z?6mmx<1GA}h_j0LF#E03{4E)OKI38WJIrJIhzU2ImK4|l9We4e2EaV%hXpXKfQeu{ z%=_T9WWr+TgcWcElzt!ZDy!;Hm)#SX* zIwKJW2yEvVI#!d@aY&8QsRO-8dfFCMhuf#x}7-_lP#}Lw{VGSgYX8 z97Ff`HgQ)I=bkn()iA--Hi@W35H!LL=zw|C+QbJ7%=kUfHk}5Hycsm;Os1iZOlP%8 zCMaEO*y zkn~{+fQ!0X@)P+Ri7VAzI>h?c#)aF8nZIPrF221NXIy1xEkaE)JLmU9bT9Y#0>> z+QoV;9e!;WH%vR&&huD9ve|Jw zvw?s*8{7F&N{AMGl4Aq?nh`#Tz%T}8Kr_sPnXni-VFla|JDS^V;>U<=VWPowgeDky ziY0*w&;gTS3Cw^Vm=0gjOPp5?P& zg!HtX6(2^y0oE1Mzn|fA^BZ$9`+?;)0Qf7yuKG5MUevPEY|DTz6IqVL}ta z??6Zk!eL$;!eMd;m4T6$&dLQ?AqX4K_>gnrfQh}%i3@uBoD=_e8>PGQ9G`B{G3uPy zVZy+3QUZgc&q<7l_Ly^gNX3AW=OiDdjXEcW2?V<393M8ZmbWtwCYa8N4+baFei!j3 zo|6<yJa8FT57NXN$r43ig}lS~--)H!iN z?;<9E!As9c)ICi69KvDR^XH@pX1quon7#5GAKefq`^#={b5fgb39 zVKc}a#>3)2&Pk?v#9(2Dict=+fKa1=s<@(>b2eDJGbh+$kxr09s+> ztWJKKMLR5n2@f(}Z-VO)&AHPDzG&a3PFL?UXE7 z039&<;Z7-lX^(XBE|>muJEa^(TRM3tEdA#p6c#^<&_#@UtWyloo7O1_`tjqPk_0p6 zcS`Ca8x0s4x?=&#VcL@fhS}+z;)My%p!698!6aA=EpVWiao-lBA{;_XgJ zTZS;jgfI_ogdMO1Cgyia1uTGm-4DZ`#lL|{!#tP-%b+b2BjO!O2#eqCl=$b^wHuiL znqVd@g5@yy<4$RXkxT@o%-Gq<_kS@G z{?jQDS#*TaFc}(Q8k`Kh&;mPP1`IA{sbD1B2%}*UEQb4G!WU!?-6iaq7q}pO-^nxO z@c-N?!K>&8qoDg|8zsRo97pLZtd$Su5cnLMV-2PL3t_orc-eWWTnqc37w38c4LmO~ zZy+f8yo9}pfT8DkQ;KkCgayzHvxm_yk2uf-(?*=<@m&bG>Ad)0q%H2el)OdeumWa7 z9}K?#JkRNZX#{{3&l6DR&hwH93-%HSCZ9Mjg)rgtd2zwut9h6!^iJR*pfHUm9fv7O zozK%rVK7f6&4iIWvD60#dU>>|IiHDnW^N(0^9WoI^uw49YVh9Jp@D`A>b||Pv4Pfl zwSwbo^3NX^ndvEM5fh8Bz*}bvj1B_}^S!`TDu$l(~-LqBuB;(kS zQhFw)v$fBa|6p4tANSI!J!-ZzGv+} z_CV#{7aJCMcCng1**H9eZhBHEfD;a7Y;~ zp~^hPczZ}NZyIJQ#}xXH#JpEc*pDoEQ8nuwvvJ+7BBmP0gp^{&sYCl?Zwy>%SBs|_ zhlfV;YFD&MZJJ5~$=D;5XR7h;kd2sw)sCOY@-bES6RO|ORlBAUE;*EkGAPe9&uw%aRKWH2g5R!K}k2+F@*#s=Z z{3c#apKY8GG9ZEnk*ZM@)Z(pM)S=lZ$i{WGikL%5%P=F9c@8CQ#T=~y4zmPiHQ_K7 z$xw?A$4(4vnWc6gW;bN0i@G;il{~~PapDy`$VmAxLo+ZP^VFInu|orTs~ty}>P@RU zt{*N_0Y@3rLybBbduyOtt)4s@J3cVqp+41Ve^af0m>tq}B@ah=Q|-bIiH_tU8Ormp zaY*Q7%%VKi^AY1+A$i!b%KQjxR)sl2wO10bY@<5#2!qD;-N2_=FP?TbXDxN0WYZdM~!1bw?^><)1&H%M~(M|c45DAOznEqI42~v zKhFVCi>qUA4Tx0c$LLv(XPZZ@e#|&JH24}Grs4T&&tt|p0ikKv^2nfmYS81x??Xlo z(9fp{p4b}$GF8lc63@c(#b7mkKB*O82dZ5jc6!MW)#BkaZi!ac)WzN#=p3pBEilF^ zM_p_f%VJ%?(5=_8XGW_H3n*&^_Wsdd?O9;FA|Rx7AWu700S(L&uZA@cu6(YV^aPtI z<9eP#pjP7|$S%F5Y@TXq;5xAFG1d1;S@(~F&(3CfToD>R zjEkK^4O_~{1neHlyp&TQ6?39md^+~I!2EpGzSQ_(Xx4CgZc!UDDAZPLPP{WDnx)!x z`1GR@A>&5qD>%K4((U<7tzO1nD93fDs%wj#+w;KJiT~`b$JLI%W3N=H{@CzF^FznuZsL!84s7LJ(6?@x1_CV!0NAyEnW0n)jOGCihD~un7=En2o zgiy6*1*Hlf#h205pg&@t3wTO7pXWp?$1_va{Xy|J>)6q_! zn|YY0yUkL}JJq31Mz2>Z^?u=Fc-U&UnSgn-8gw3SD(0)*W;W(A-Mn6zdc_5YY~^@_ z+H;<|zB5!^e1SCxPv8NpYS4v$)?m7h)2jVEYp{`qN7N48b5O0kfTs(ON%g&mXNRiO zJ*hYASNp|ydcHaQo_`j_+Px^H7h@v>g47|sbA}4I#EiZXYPy{nC*Q)0qnd{+z^z7I zBFt7iiE5ATDN*ZnPx!4ol~oP;6OU81>z;Hxk!q#x$x+k)#8Zx^tK00tw5q;cG1eT9deY4n?#kdBlOES2*g=fAFwi2F_ZnFTh zms+oT%P~_`o!)PIw`agu@>Zk%#xp|)%ZI1nA2T!$v-4)vp3VHF*s1D}-tl`Ktl#at z+NeQ-XRQv_4o^q7nTJfI z9oxMki@R4Ow?|w=NCB;JZ`H+-2-YI38w0leb3EV-7{bU4>3}sLh$U;F(M=j&v3O~_q?m->7FV);i_Htyr2e!f-`E5 z-jL4A)?Bqx_qf&cP(0;$Ca5~yvs3NRJtObdQ=HHPPoC=ABksnxia6VH@rI~P90nxn zVBg{4o=G=@xrVX#baNzTfSM3SKa*Qrj&BHWK`DgEkmSV5@*Y;vpb=x7~_v&{6gL=i?7-*lWRysI6({OdF zLp=$fiE*5@u|>gGs|#EZF&cH7Iv~)9~n0{V1a6nj8nW?``h+w z@RC|Q3y~>ml+$=uk1p)CIrpmDuZX)znXZWo3%E)ZIeA6NdO+Wt>#vEsGvEq!=$g1& z18!EEp?ZGAOIRy*lnS_x zWbRe-u8Vsxu)wYc74Qn!HJeDQbbG3@3}kAfau*=EbPnIWQilf8HFup_znNNQJj5Nr zTdI9C>s5^1rqrm9jXOiqQ+Y~~T4{(o8u$S($e&QWjSuS=;~j%o`9Jrl*@Z|L_lU;V zNv01*LNB!g1a=%$%eN3~++4l{c}VTr!rEnESO2Ekb$cuJ@4u^IpBi6Ors%k^py;-H z)kEXsuIm{Yz_r%GGt<6W936LcKw#NrYRwIC_XbQ>hi)MLeQMOuxbFf#8K)L+GrrO@ zn#)r9WBU2O@<#Uh1ZCQ;-}K|zJV`Cy&h8nPMhPEL&D)K`d#7XnJ&(=Jze+XlhuBE< zUQFEmfkzgom7g15>Ye&Hw@aDb?boV3r?^GQ9Tqn(@Q_{2DP9$*{W}R+^aVGa85h^@xJ7r zfBMyUV>+kqzkZE7eEr|VK90+S?&{UYd3lgEOt=TBcR}8IO?|)}^93FJ?&%X(M zBJK_kjd&&SsZ}AlL9Yh~?%O-zm%GaE-Zx=Y$SZ-m=bvs5Y1}_(;ZJjQp3oh@KlpzH zn5_p`7aX)_@ZJdr^$6YVksy(A=CuEwKqCHBJzkocGb-+`&;q^Ba`mBZw_-b2sg_Z3 zqkBg$LUeZbSdZFKHF^MViU*w;-CxZe9TyUsPP6qj_2lTd@x8JMSXJP@P}I&^QIb`fSreJ$Wy&;rcagb@3wnKFXm-CuX|eVVyZ_E zP|I$PyS`64evA57PPqDXRNS=z?P|~cWBRMMTjN587SnDj_}{6P<2V27w~Y8_T;RwX z)V$Lq;=eU6cwpob#2)0G@}i`sol-0^|wOQ~Jk zfA6E$Ivamco7#D6++DYnW1BB^_c76?|I^pWi{J4-{QA0g;dftBFWnXw+bf#mgba%O zry6dI8*EF(w*UFx=hHV^27brCep4V0{{26jEpT#f#JwPKYb+zJj=@WQ1iaxElwi#K0aL7WgPhSxVYfZ zbdGNdQ#rUFX%5TzA+L@zZ;w+B4OGa`GbdAdCrd&_0| zpuwRT*p2_%8?gt4t2*6ZhCM%A&HEO+75n3GUBKYb$V{H3+FQ-uMVv(JANedq_oriD z{MXLI9?_@UUyA*39~H2hK3?p#ebg}B4qwjeTpu-kH*v;cZ@FBp)ctALL;I>Nx}A$X znMU2&ya{0sib=lMEBq?%odorqoCPp#JN4D6*>ciRQnJ^QO>-Cu$2zE(~6hQd20 zQ1~t!%LeFZ=X`^;n6DKJ2ZH)bN{u&U*vWnT20se3E0Uus7>D? z++8Qe!{$ ztKL5m|J66C)qC_6!LI(-F2MdMRyFJX3hXc9yJH5gc%P6({d-|kd+eWJ` zx}Ar;c1*WjhW%cG>bVzx2lm@HtJ|=9N58~_ijCcRo=|m9#9gVXCdP$@PR4)BZEF2q z3YvkPf1BE+k1fEKv8q}3mt#MAyXsqp-GRODc6FO>4_L+7F|K=&60u+Z*G|W78`r%^ zdDtm;bf5mE*pJ+y=1huXQL(?iqx*~q&*rZF4mIciF%z(_9^G57PwyKM|U51^vRSo(H zyA^xyRy9etBXc<6wyDKG>2a{DcdAXgoq_#Xi8`eB*@%6xM2($F?q%3g(p|?^?1Wvq ze_${DPAqaY?~8Y-#Rv3Q*j>BTrUS;I|GZdcaLlKzT%rf6_-UL-8*zO2wd(sboy)Or z`9@99?Jn$~-_&B=9=V3kaF3`>x}A#sOqDvM+qu{;wy1z|>{9FnZE94xaj3GJ3EYY! zyrX+JM83wu!8_EZaj8ldX*?%CMShN-@8>|*Td%hd$k z_F@NKp%&|QqF!Z& zhDL8@q^M+Mmy%tkb{ZP`n2|3k6&Weo)sc~+k)ffXQjwveo<@cWM!jSt|KIE^!tw7u zAM`uFd1hzknP+DAcJFS$`b02pFj;ZPY~YUmq&W(cBJjcxie+32zHboC0PA&m>`}|S zhhc639>x;POftav5uEeEkK?xUG3b@xkwX>Mw}Nq7@)7hpVhy{|F#{-Cfxp~NXJD zy0>r-QDqBQ6HEJ;eFpffOf6u2KKNVGJch$p0-bl$#P4C!3Vu7DUIFVP^6{JIw1$~j zfh+FgvK_3U7A8A^FXC+^YnU56_%ogC>?gc`^xJ@+Nq?N1#DgbIqchAr z6I`0kxd0rH!MPfo`84Nt@S)kX`2_5v-^R^?Idqh98d#jqbqDzU=PCAQ=;h$V7xC}~ z+yvIzXbt0#jR^e3Tu%WndWBk;ZUYau)8Kk=33$&NG?8&VxG|qzVeIz~T=!qRT>{60 zgG%TO<4o|)yQ$YnZ~^%3gEWe9HMsv#Jgxz^gYP*(n;AzJupeciqm0wQkGGKKR9uv| z1DxEEOn1yQ-7c0RQ5`@tkRdjKt$k?? z6B*ZoO;&n^vEL@xJWe|q$AiCvqZwy{*UzP14d4RsrI+xq2wV;Rc?Hd5+zw8An>I6! z{x5#L9S_DBr-A?4LYgyR2Uz}yVi}i%pDLvpjGMr_Kch8_LkeNDhxRc}0aqWO7REO4 z*h4h7_G#cjH<88-c7U^cQ7q$fW)nm+7&n2J4W>1WL$+e@ZlisS zQ^2?2K_O!sI7z0#=fNf57vg9l<9hJHk@N~~^D*JqdJM${r!Bbk8&3yk% z98xI3ENfxy+}X=~8wJcWjW%RK3;7*e2hiXR<{`9Xp6Q@C>tn3sf71B*rb+q=a0ne; zV0uD~*p5B6+Gx%K({yn;xb-j2P2lvuIj8PG?6h-sg5$1pW}873btvp@0|#nO(%c26 zY2FP;*tBXQaVMs=7f*<6zbLDoRxdP7ALzFWr(Y32>(6?D7gk{WWFvY5t$|v$;FiU0 zFPIh#EQ6-=?y}2)T{ScTS_8eZ*3_52eZe$MO!@>~^`@8{(|AJxI2ZW>X*Qb&P+^YA zZ76c$GQtkwqUnO6^i$kZ4!|$-ljc2B5ba!KIwv|m!^rn?ZG6cjYP>64 z=*lf8X~)yjm_e+ifn{jnEnTfif))X-j2S&A-9lk6o6G~Upj3CW^3&iB2DBmaIptsNxB#C*rhkKrLD*o0m=FJG9Hv*rB50ArXr;px zI=l*O9fmy|m@SSz4L9qIzy|1PJ@ho_ZO}7@(J6;%syL+zV?K;Vt}+b~?cm~JG<%gP zD%c6GL)p%_h(oz5Xtl#=`zq7$(Yk{OsBZbpj_oPs?x96PYv`u2<0L?Q?Qr?!J!Jvm{0+sKoQ3J zrl5wvZ!smirPGlv=jl+^Qno2o_3*CVu`-p=suY{#nZ|1L9{FbI%%gKuk48gp{uezF zx(~MX2vhCZ2(Wt6pa(+FWjbCd_{)N3yNmUPx3vOkN4Ip~Ve~~w51?LaO{S6Q5K3^6 z1a^ec0fDQuh?8dm0uPT4@L|K8i~MTjcQ!U1l{4M|-F+7=UTcaGtHDAXXWEeRjHpH6-m4~ZzQ?>B$rJkOA23y1 zn$4_8SRLA!pju`BgxDITCaO;0oziGE5mJvP->)XJPU6Ins3s~;VMNBTM6$-W5`Bv_~vDgJmO`^Q^O2ds8?^pF;;GaBc=?PGr1aTRd6OsHWJY z)4Ct#2Jsir^eLQ$U*N8(G<_S4H>7dnhL2!eJDnS({E9};V7%LZ3YMh6iwKM-vCPoE z6|qBHgLati)EF{<-yyP#4S*!zC)KlsF9@AVg`x+L>`4n0KzsLQ}ZqIUV2RAI_ zT+xnEe39{fJZNh9%CwgX_rZG^FY|oA4xEygaIOKDzd|uz!PSkgDjJnm!q~Ws8-!>z zLc(&+4dBd`jCWIR6)rA{yfnfFY>|V{W}QF_Pga@c8ZveGJ?_U(y$uS0r=<{)k!@Jqzrf9KojBzdjZn0YMxHS3 zH-z=o2q9mo(V@8XNwEZ4MJ0vSqmOa@G(yG!&Xr)FD$c1vXwX5<_2ATRInU}3UsWrt zZw2FHMW^A~++d9mU&BrO255waqntN@?Z-JsglL4w?-_GCnPSetm&QRDo|Bv#!0o3wmxN(x&T?kk%GlkU6T>w^ z)dkLhw`v5xUpd!Ue|VP7xKkq}_0Te7@O$+=v}_XwqlacgvnzUN_E?S3*h6zj_}%hz@fzon zyWsV|71n3P!FRN|!?ahl+>Jr{N0BM@A1olc4kh7TJ_4gEoTBgkHhrnjy$7?Ac52OE zP~dfw&O0$4p`hiN>+qvZUaej{;az<%f=I6aJNw!$Cc?`1>(1J+z2K z1Vj(bZw#hL53Lni5H`5#s^e>)vGA9NRB5PuKqD;g(h_{kU;89sn7bsU#rfk9ULIP7 zGJLjV_{M;}n`rZs5+>Nq=4bT@4`Q*RdA-e6dNI)atf)&t6*tlLUgkYw71-&=+3^rs z?aw)NJSNl4jQ4Bf0u_zSeatvh^x_5usn~O&x5E1Li5j7t)&!|TCq_&{3>tZ%guWEp-D%PmZMA73KVOD3NE)6R{XTonfyxEyZctRsIbtbaY zF+#!W(TZnigv8E7{Y;Fzl8DkMZVt>qUG1=Ae#$%P4&jb^KdK#Uj*U@~q?Xedu}3OQ-`G>U1)UGCym`w`qhN zGh0-Y74k4NamvdYp)!_6j>eP2j9t+ZtP^-I2otKfA7j@#oZCmg zf=Lm_?VG_48axj6&ZP*a5!}9JEbJrVxqZAHV|_1Y;Wf;>k&Jg!VKT&d8x za9`wjviUiE`Z6{>?|sM|MROlSx*h3U+WC-qu9)>YCg5lq`H*>z=mt-@pYxREi2g){ z_0?cAy)psj2`g~Q9Lr6dV4nv#N3O(GgUSWqh9s^Bz5$1i<7@}xtpKW;t-NJuL%Qfe zI+Y4HS2%Fohp<~1ok_(>=dX!yvwaop$KTMtoMfJBNLh^q6MN~YcK=KpZl0skx!mz2vEtya&f(7r?ILJxi&3@t!67eZ}CDz4R-(eXz&C5pDU>$7eUiJm5Sc4)2G-!kQ zQ}3Xk&}FTfs70bquOxO-^DZxDRN7oNn>^kuwXn-r{Ql)J^O(^S&YBG@*ahJy!l+tLP96F~t* z?CLm@+vdFoTPL0Q0JiOCv9g)CZN)hZg2Z??cdFfu%dz3un~ytn&4+Mm;(1KjIBdtq zojQ4&d6g(!KqdFk^b&XsSU8g5XJXDTh?P;CEseN}OXS=PPI-XF?|}KQs6Ls?vo0bc zAL1PG8)9Gr=LT^7B+dm*SQ#GXJmnGse+rGC`<{T!Y6iGFR81L6czN2WAyN_L@y~_=n zuERxzoJ%`!k+zirzJl?T_qlOiCA&iVkU|fjMeQ2wNrG)8!&np!p_{%jzbjU0wL;TGVvc@!$h?=#2XQ=0Ikzbgu{FtF>G-p=3W} z+?D%U(I}ysReq2glo+%^dNt=PU#(E^9UVCgwJXZ%S4C(xp%Td;u)_Jb6-@BTgk-<9=+@7ih8 z&*nYewtnzM$7$Me%KW965QP3|Y5OU>!_xKFV&VVz6r2}!QVFGbrx8kyV66~_H@Gkn zQwL~;6uhZDh01gA-W3{|8(>?6C&I8T7>F%jg1BvZs8(nnKzq)>HgXWRO*n^!TEppx z8x1W9L$4yRM<5NZK-ld*kCRWT)my@~Sf)2O;;?PNq9{7`3z|@VEB4=s z=A0X$73yOc@7K1O6^+t=Wuqf=gX$sJy9SSvSi!uZX!~7s`67&G-OY`&@Eg@y`#nm+ zP=C8tD7+Ut@li`Tg6_A==5>a`C@pUEGfjC)y5ov@otSZlR@g9_0$R}d+$%Uh#26(Z zHbrAhAK+Yir&fqhX1rfpmBNkluCm@w;0Em`Y_Btsa|J$on`x!cR@RS4xN+ehtZ9#N z13wvKnx?R!23#;5I}+l1nP}$eHZ(Ke0$-&wO>yOxzYv8}hG~WDnKb?%^gU!a=1Ydc z`UbFr9{L9^F1ianp0e%6&Ng%d}XG-J=goKs?jS zV(ebA7C39EB2%+2R;R7BD+w`eG(zxo&SCd!1=|Y7n2~QN+Ik<@T2}M?%rV%$D37yw zESj^HRvTcOv`*0|@Fo}+5pD8|-D9vNVV%KtmH1i*TlrS{$F3I>#vx7$X#35vdqiEb zRw&!Vxe6SynX}_TRI-(GY6{{UH@I&`C9{eZjm*7JN$oanP%vJLUkBlwJ^@R^4%*Wj z#zDKdaRPoAU2AtL2}8+5wCFSJyvbenMc>$UhO9{#@z1fBB@e(9Dc9EWX$>Q=QNA2g8|>)3D?dFB!si)SuFV4H!f zA$DND4D{l6&NbljKPV;=A=rrRHgU^_P3Emp@Y$6AU`AY{k$1%I@eX+!o%yGMCd9;k z>D_>Y1ASo$v1pc72-4E{7P8}0Yz+zc)^Fov`IxN(gM#F@9~fMM)TJFJg%uex@@9-x!I(O<08JxSMIpLO9_*_*3^1JQYvd6X2<^`*48D zkxD{z*l>y�q5te}aEv3`u@#^%wiwsG8`U?g>!nYR;V6Nd+ukRn#he4#=tnj z$_+}E;so=E!iKC@;Unxjii?B_4DpgAG}B_&3U!ZTXH7n#M~{Oq+n_~Er&HtL%ktOY zhjh-l%P>1;GRDMxO3^6&K~z@zG&iVTj$xV2Id26VoJp5cU>r1;8)uD&v3(vlsDA?! zcLC=@2cml+U7vs;tjalqi)keY7fgcFB3Eni`%e@wnav1rGaej10xo?MF__CaJ5MV_ z;(;M_%Cn-9%GY>C`x*>69vHF$6>HIaJTQC&E!wb(8y7wbV@n=4@LLC8t>s(;#=F~? z$6)NUfoZ#aBXNgx3gOJU(KRwHc8JDc-=Gy5-#LSm9edJCZ%vE+M=X6CwG_B6r^7&B zzY#;_nwJqf6t|J_D<6sfDu=iJJ|BQSV9k|R`nGK-*40eE)RsvgKEP575s9DCGhbE z0dZDWiDASw^@`Z*hWf7&mxo!0j;_MM{I)Xod$HjF!t4kgSrvO-bbkY9)o^aC(hB)U zIX4}|DdCvH`sPDgeEzn&x*5p?8wSmJ&w;DE4Eq5t{Q99iiAC#LDAv#cA5U30zo< z>x46$ZQtY4@hoSyvt;Wzh4q#n(G~i5Q|ymoU>#247r03ixcL`uQuPz&5slg$dz=b4 z#OlPN6SyY3$nA1}#);!M&S~{%+9k%vD190X<4(dgmtCP-*woE9g>h}hX3o6f3$|kF z=AA~TTU+4xeT|_s4rqqd&ghFDyKb5_k9w3(mSjfr-aUgu0<=vd8s*#NECG@ zs;^?Sb!txO?+D+{M1Ct`u``kL2d+Z(s#)5fIL~z^68?v-i%QN<>%YW06VZl&5V1io zZ?XJk?1zSSXbp;{JoFLw#I6;~{(>{TY15wA-D1u)#EQysf8(^{!}T_BzRG3oxFj;D z_WxiysT_A5?ozo8Z1v?fWgUoVm2(6y!EzJV<1}7E(M@>29J^cJ1~$@~W3f@>{Y~sY zh6pb&VY%N~Trr+GfS8x7V*k>o=&-++3pNd^ zr`-ozfORG!eNp$#YL4|LFQK?Ik?ZFrgaoQNCH~lctTRy;;3epKsX4kpFCj-sgli0J zQ84%N!k6_&okgqf`yuvwgQd5Z5ZC)gjNJcY>`{^J*@<_Wp+8|^h%3v_`tgAF0#=14aH+~wgVB3DtYvyp zxR)?R<=k7ngc6n0BE0b7FK!ceo0ni!**FCKP`Mf0u5$HI?9SGo+ZRV70{YYHOR+x~ z?6-RfZP@X$J+2216t zcrPI_oa@#1!s#m4j6@Z;a=rFGv{&W21oU0y`cc?xFM``NjP??$Rd(Nx0KARsjfrsX zZFIySUDr2_L9o$`K4|6NzS4(=%CR`^kQ;$|{3hu`eZd2mUd-l4F((PLYbZ_kmwphf zTskzDtC5K~L#MzG~}u2-gD+*K}o2wjQdx@|lhtn!oz7?V4=Zb`*3DtwFr zXJXk3oQO$v2R26MfiS4A^p7Ea5=J!ohW21T=`TIo_%z5haga1rqtCM-;dSq?%X1FJ$(I%Xk_ipIyJ7r$(}*){Pt={}92bOs{Sg6+_iheWR3 zL!^-!G3ZGw2*X_0hf4p^i1rKw+HjuGH$R1_aka!sPiw@qr!n>8RI934h|Rmzgk`pu z(Ab$Md=^d^!E&C~=%0hP?@_IC=3qGE)r5O4I&!a?NS%jh9mx_iHU6ya<@2#6;z;bd zPO-O1gIx#iLMsgs*!3nH^Z413{L)vxf9@dSF94}$k zXr9p5ya?~Qj*ekg@h@S2$3)et*oJP5Q4_|+nERcH+$C`CSeAosm~SD&*HtF@~MnXGo@=H+j+Hh zGHrTN+Kz{)SXv)Gi;o^?W=Uc6e1`O+A+rz>iZZ4A(>?D!B|YIAu^CYSyBfT=9~^s| zOa70f*N9WLU{KO%$NwjPs>s!Itgt<68&- z^>D@bKM9&HpJEnB?~ASApmlU&fizq+@4zHoM}4!UsbU^DWj!s-mO_J_;0^1sRH(W2 z0&w8FYI)>2@mC5h1X}J*$`?lH%jcyx#92Erbw8l-3#BcFz+IT%C72&H>S?Jj-TZH0Yt4;L3ptG&x1)@aYs*2U69(YPB6rH-yGmiCBs z;6#!3ERp^UuKfZoy7?S;D_UyDUn4Zj&2%JJTI!osjv*R&uA@|-#RsK+H18E@KzIqn z3W!-SW@CY`J+SZ2C_f@og*;;@ZGT0Qf`u<}<_hgPcqz<{(0uSrWT~{xm!+$a##eHX z-Y(kqcnRralsxjYOFjn6UaZwqP&@NA&Wv{HZ!xU`E}BZCUqdi$09&Tg;@6~bu>y=w z_rL#|v{sz559h7NY2-5Lh#`7E*1gBsG2r_ky7P7E4lxIsHJzrvE=h(`aLJ5wxN1;t zgzsTm;8!@iJ#`NEMV0XyxLo?Lp&nY;Gt5qTp8e}`#7cf8yq8IfR$!I#`5JZ3q01|z zaDy4#KIa@_1m8LvK$ewKoalg7I+y0J#PKV^aapWQ$_<+1E2Yh1{sByq`LyT_X{w3x|^lz~8Wz$%PG}2H6j(q+c&a3#aNf>?Xkamc+Dy*IhDQ2~_ z-zt^`KS^~5RyxFQY zg;MRC(uPpSw-DE!yRnY28D0p@1}!X<2k^&v(h}d4YIu9cxsDqC%`AFsjU@Y)KurG} z@iLTKe!fQf+2A~k<>vGaf9_i=Js~C>f#1&3khi4qG5O$}b6vp`h$@Sr*}G}c(8{6Z zoue&pN%(psV>cap3-Mt54(GP>bnPuHG}&N$)LY?NaPcpkEj5U*M$Y-*S-)~_1t(qP zY&{BJ|Hjz~_G#j5Jci?g*R$h;t1i)0lBSDw;L6LihoHwDM|-bu-T+Q)=G+F>wQ!zN z3wxEz!1k+L5BeVVzjMw3>smS2fh)lq+3|mX{T~$ijx^m+08amtjV10a-R9c%j-=Ii zSO18a`oD9uqZb~-pD2))`R3Na#cdcMUt0Z^=~maOccnoZQ}s`{6xF(Kj4yL`1GI8z z>0tH>!CxyhA1^okyh-Z6#CQT;@=^=2WdLh3D;Nzu7dm71V*e*Vvq8&J6s}pJ)jGQnZJ-5t0KrMy^~Txdp#>2CEkK`S+*)7>=T zBu=ogU3P4AjL_onp_dP&Axjd#@sg(ltkCM9rFJ{cENDjAQ?o%!?V;sCb3n`LR<;OQ zV-KwiTB5~0!K0FDh`AO|CpJKf9_FdFLaXbh#i25vQ<$m4>GBqwwGzQ~!zpU3G{V~s zF22i69ZyR^w0El{(u%E8Kko|2A#q*uK<{=ad7a9RBB{SGJ8ax(EDU#3Xb}#Z4PLJB zAbPO~2PuW%H$puKiVQR~LCGC~_@z6y;=IyQBn=Rw8?bKN!&)Ly0!lc8Hr(g#5V}Rb5n5XU<}dS@}m*QF9a%lMvdDd3|Eq8)v*-~h>NnOFn zW>F32(-XQY0(Gj>_|X5eku+50J9?t z+@3~{e1O@J53YNH*@ecGfpt%M9=jS^VTR|i8=#f{M=2AmJBKKJ#&ZOMpxI~hnUV-z zKHD=8r$Dnj>#1czYv`fnLUUwxt@O;f`OxZmXvNSXp7T6jIkcMR-1m4aEj18rb36^* z&?4t{X^E($4O%T8DHcnk#RNB&s4PB1Y~W`6tok=f_+zP0u-`B6@nUpU zHDR+Q44UH=5=*eErGT?ugE^Z3UiW(~(`l98Q)KVXW+5+P1p=7G-E+&d+NB2sRz)s! zzm=-~4D@LSwBzv@m*o{8uemcX6M2sv&`v-etG5h!wQs29aFSl8&7_Y?r2bRg$S8Jn zErqP|HfXw4nEKr+XMGNAMCGeJ&xH}ta^7@zw z&Ax%ge=H3dnGarGpw`72jSfAncBmA2j(1VEhlAKLs*#tvnRekAVjDPd3!OrJON_tb zbhfo?{8)b?p*f+|fCU^Jbtq$)06nv)tM9CjR%lf{v{}$1-t)AxLCb}f%Z`Z`E1UPL z*BwGr55poDCcTf~QCE-%7?wfH|A01a$D4!(u%j3=o;0OWf8#?3Fgjn2!W&v<7;ROo3RVFbD@Q5n$cO5izFV_wLCR>hF!_M;D+GDa zqj&s&y%@R^dMT@K;j*DO3REB?rSwLIR{QV)rLlF;-KDf=hZG(v{Dw7er{_W0;u-|q zzKgE!z`B?OF8YLGN~Q2&S>S4CmpfU5?a<;rRj&$IXw2espa8n?8Dg1U*(voITZW_? z$Xc#)sDf5`1P$oXp$6y$M==(vE$dJ#w76P2u@fB%yM%H0v0J5T!{ea4>pZ7&3bfP{ zp7o|fE2#IZm$fGcdiH5gU6}&VQ_kKP$3e=xD1unlB?>GM%AiG@qfNUI2#sK)n~pFJ zx{T2{PuF)z!(*)A4HrD;-7ILW-86RjV}q9Zi&7@I44mKSIo+zEHT=q_TPwKkV&`Dyz!n4$w7_nwOGJy; z5~1xHoY+l_gQ2nAvv3MD;U9J3#Q|C5q(du*)&Lgf!Z9=XRLX&Fzut9W5Qc0AG;@bq zUO8)NKg9ZoyG%=P27>`>bt#PMVUz`CFQ!#OixbX!^tcXMHnaw2gcq}Gf|j5;@8JdE zD&{G)?#DAiYwWI#LE%V*@fYDfJ=4f z*{#HVl95)pq&`c^*>Uuqji`av1g(@E7%%2cH?-yAd46hR-ki$4*$zFy`@F~HSm5s{ z53N}#&D$0Mt;**-Kh;BL?Tz~#!&_@O?=ie7Fl_eqESwIl`lhZ*Sc9^m<@o*o205Uc z{XNSULh}po?4%RgtN>$|$R=JD#L58LUWSR+2F|~kPBD&b#Uu@+fX}6oF`3}JUR~u_ zPjaC(b<+}{vk z=hxA5Fh7>?`Oyr$33_U`6-@U(yfqo@+3O%^_8wX^w5Wz2VgkhY@UGs3p>iv<;&2*K zj(4*;;L2M)$I<~UHNta<3ZWH1>pnzIXl*^TDrnZ*Jcq3wnlQw(Q_axghaz4I(IEC> z_7@NKY*qT0;*l0b1tmo}RZtYlK$FD!_}?F$-FDRHvrKiw&Z1N2kaQ z^PoApX>8bvpan%^No2#rhHWJuwsPo!cY5})23kst=UVTEwj5eIinCYXWB8{HVr>sY zzrS!mljpJ&2CWHNLbuqkKnsfPS`veByd-FNW)ZVT>MLe|+ayZfgZKE$!L>5Y0WT>5 zms-@-grC7a=4Y_36IcywGKYC~$_=e}xM#cCpxN(IW0`dde}32S9x~2T3xk$+w^9~v zR}C!?<3@PKRT8xP9$Ff-W@ybyNnS}7wCa02E3rc>i|^9Ru-^c!=w8)H=FS99(iG-ZQRF{p>3H>e zfn6Is&)@JRKu?>{O@HwKE|&0I9D3^nR(|;Cd~jW=XBZSib586Uau$E(&! zFy&E7{u);f`QV@_wCHQh*D`R%6xzh}MsVvCI`TCht0ZZ3g7qBKiuvUj4FPMDQ;o+d1mhPWnH;p0MLJ~nSmN~c8!rJ26%;MAFj zR(y=H+BC?eKP26+6=!+tgi3tls9O3nG{Z+HEPol{$hxAwQt-bGdhW|K^DsVnQ4J1U zOuG(CQQqy~(#7Y=l!Kp9Z#yhSi-`uEP`8+(jz}?L4%m`Q(~sbz5H;X}T>9(?8xC;R zE9cp-D-I#UcX*B(aTDsbGmkA43&Cm2XjzRk+)xiTzmCvmzwQx6=WC=l40(P!A!RvM zRrVbG7FvB&N)B&>mbgM)X)#x|)&QS6v^&sWCpe&oY1t#}PzpLGISow^YgS_U=MPW+ zIwn17um$LZhE+Im($1xLti9s6^rY6{*9(T5*d=l7YAM{+?+0lVKC{_dCuF}z(|?o} zE@=fPz27zSvHJ+iCw#xUuDP zi%xKFr^`PfGULGcJ1F!7cosOZl*XTsMvp87*Y8wkGaG=-O5>GvtQvXQyUurns6FPJ zz$6|BL%I=pIlJh{3CsX1Sht+6vSZu9_T?1*GuX-W6*TE*DLkegY*{gd9ZC6_MD{yVAL{g@&Pt4b$wBO1#S5mH&zqDsc+EPpQS}&CFAWhvmQ5j{rc&IyiaIby);wI z1}E;O-Y4;}wgBwjO(RZX_O*la%W30D1b#{oCd!v|@g$Dv09z_3>XbBMST)$WpSQ`z z8id!4HsN*=8YQGbYlWTpD{hCoMyK)6-ExMmHAtiV zi@>^HxQ!pJxg-UICB@I&l^qb$}BuQ`9*)rWK5*#%s^v^H&+6sO(SD zx}_-pe6aIRejo>px`>%L-i=_Xhn~>pTI7~?Ys7*uw8%;$E=ZDpEx6Fiu7L2UpI&iG zp)R^0y$hpo)VvehQ%Y<7Ew`cuCpSu=c``nA@<$_1DmLgvE(-otTI#Qh!0>#|Z5-U@ z>tFGigly>9UsCUjYzUdnmo(y{B#E`));%FwZ*y|nQnhClH(^zt~Jy@+0xfSqS4 z`8N!06WDTrR)S-qhhWHm;dQYgWUm`To9@s}tDbNm5t`S&EAByB(`dz*JVx|DP}H7ijTf4Y0s2 z;$}K_84XASw+7NRR^GwN_vYpQUkC1g6W7r=nc~mM%Jim5R}dO*R;CXxgN+9d%R#jH zigbs+B?_JF%k?xGbuZSbrYn+il8%Vz0j(Si))06Nx;g(3}X8NiL=Su63nF>+6{IXO-lIXmpK z2T*tmMy?v%8c(ws8>2CD3AC#P&dmfn$CK|>I42*RKZzv9L18R1Y2e(4G}ZJ)*0l>^n5VB3oL>4<=`SZ(<%i8CU=d48)_v}Z`J#m5yJ|K7N9Oe z?HD*BgLkZ&_p7U8+S$r#!$Q&yyVeW}|C4nLYSHb>Fr-#q{CG`*VgZTlW z2>&J`v+x-@`zJnC*~ARz)5`xz$NVcLcw@0gA$GNMK*+$qt;oz+Ol#XPkAZUE*eP3uA{p)aK<1C?!eg9 zg7HoF`5jm+ts^i*L+NSt+1DJlOg)ZPd$)L|X#vpQB)r zwGC{UOH)O8zrTGHB8ly(hnJtSZ5fU6mhTgrpgR}QN^g0lXdMlo=en+X%hxpi)(eOan%*#Yt)v0xl5_tA)(<=LWNGCW*~ofYMcVhOnR zTS^XuJKDk7)wD5C#+v#dTy~7k2Fg+X+2G0_crDmidktLk!dSWg`q>!Qr+dlwihe0D zsH1JYWbAYdHl8GHZ#i6afFl|xsyF)V_Ym}7Xj^X_+zQrRrmMZ>m7*JL7iei8d8&Wn zc-VOH<+*_GpQbm;Cb0mzQ%@s|@+ALOu+_WMX6JGEy2L04iO~}VO|0@`cpF4zZGo1xw|=)_LX%pArnzmr_Sof>&6N;fiD?s=}m-P<;`@q zFTy1ooE=EL`@yBvV0SN?-4A0FGD%sUclSfH6T!wlbhaPD$PUgoQg{&BR1J3arP)F9 zh#0@gI8Hy_rg)|1Zgr1wc>M=^?lE^*VCU>d$AWO&G_bp$>spX3d5QUtAY-UY3XxA} z#q7t>!#G#(L9$ja+NPr^6J5a(@_en>nvSrX;aWQcbI-qMCdU0aUMaSJJd80)ihlG)rN-{YSTJ+F!D_$@tewg$u_{+gf{wb06VOrEqC;Pl_= zT092H0ZwdnMcpeW`-t^RaPb{Yi^jl%x?C(8chZ(IFtUJi&8}l(;6Q)ltLSyoG-V)C zX~sI#@O=_$$b>E=yL`v7?zrvf!W>$fEbsO&dJR`$ukiwfG@}9U*3%!9Lqs?9hGn$$ zLHUrsa~an9H@Qs$y>bNZ&PS`_j+E;ZNE?i6&v0j^n3Q4g_cxg3|H z8)+M32jfDD8ZVy^GgrXoL-L&f`+9IfDJ_~HAM!3)iH3eYjecJt5B9G`BJp!xaS0tw zl?T%LR5?bBegh-*IUP#HsM*2!yD5C4oa|o!j{SP}HZecZl@&O9PV z(!9wSZ{upLz13V#p*8=LB3)-D%dcw1>O92xk2L!c^gezK;_)nZ-5Ls>B3~12Z(+QBDfltW#7c0XKh1nhmc(|jJ&-m&2AlSLIH*5uoQg#z zVjY4mc)Ai2VYK-%gv9x&@{j%z>k<05avhCs!kdiqkIS!%wa|-(()=`(Z3kBls& zeGMw!V#y4dZo{)8^?2KffpBRIw6zVjRtU z0>^0uXWvb08AohH+wP(LPoM)S;D~!V+u1M+D=b@$vLRdVq2B3;+yZdXJ+2Yy@>#8D ze-~{|afLrAAHv!1zv#>yUKo3IMaYutj;G|oTG6=~Rxi6IJuPeTMcpk}t@B+|XR&3& z{sD4IT;b2j5^{ji6mCu;yFAsYB@M3V6u|&Kp9(D=~#?nGGUjC6?CsuQ3QwbYdm!ZQ%Sn zDEJLo@^^wQ(dkOmwd3>T82snokOztFOpm3FZ=fg92hbCV4uOZIfiom-AFq_^b{?6_ z&tZ1xcGwlEcG3Jj-57`bgy{DTd^(J_IoQ$>f>58Qa0u`zicQuoLXOpC-MD=G8MjkrpxC z?-1NQhPJ(lb|iu;$53z{*v9w)&Q8YTXcE(#z_)UM0N1MQ0Jp04PO$M|n)H?&erG*6|6yLQ?f*G5TX80vy}BbPLo?RmwAws3&YQyC zl6CrMh?btB6{5ALXoHyDQ!Ij*&&9{`<(tH6q@9l_?b5e`Ei~~hT#jzbmwm;M?=W8; zrQP|6`82Tc8M?-NVh2xqhQimu!R6rWXKCs>tkSv~96OV?Fg+fe@f@9Cx*c4bP2ub1 z5uugfqD8##otKdo^tB#3F3lIMM_J=hv||bFT90{W0~=RSFyY!e(Yr)u6aDIWjOLY8*M*rlBdRLz9BetJLi*WvV4}~KdFhv4s<@=Z-Dd5Dw z8R!fDFh2YL#?|R0KC_iI8FqL$jxx9EfjE`1;$kJZD3E3{ZUWb;y73I!r*b^l*o)g| zfGwQ89bjv(8T7^~dEjt%OVtS>yBBXurvDP2etvYJXuK4Z>eK@+%hpds!Ru zD*q*q9g3~8ZnVc3JcC~SP<}=)R_(jlg&ft|zY8e<387*A0jqF(jXnuM?R?U|b}FV<^jslJyWW_Au-DqV)=#vY&!Kl|w1;Q)Jp8Uya3c4+iVCmLHW#~*0LGVzlFP6jH8H)F zR+b^E;(tfKedt6Ps}~&6i^4xgm&?IUqigEt@-|V-yoM{8QRG{J0_9*~G)=9Lrw$AG z8%FofWMTjRZ+hPE@LGU(uZei9o(MZ#BDbqoZr-@``{Y3y(b0}cJf5QVqvhq`{8XB{ zALAbV4=Q<_4(*4ltYGuwbd|9UoX&OsB5>a0{Getk-HmJL^snH_YUq`Z)9kM>$Fi@Z zf$6T^mGUIKYY_B81VTwd6Z-`&!GBR?uuLT|OZW_}~%cl%qldLeNQ zH)>*6-~-56C1>H+IQ4?%Es8qGS`Bu-MN<#LukB3F#|Aafqjk{pU55_h8rR>V*9(PP z_<_RMjj4Xrd`Qj~tD#qJrP<%2u%Czm@6onz;rv8!_6Kwpy1yN4|B#ohrhR#GU%Iba zzC|pDZbdX#V}LTf(dzBwdl($zqZjgb(eA@IW*RvAQ@VB-SJ3s~j51nu1e|7o{chK_ zBdl>5zIws9r?Y~Vli2nmq6TkIOQ5?eD7gla(F$(eM{60!-vs-wXxnkTKga-Qe8tP+ zJ<4!Xi0iha@?4GB?xz>BPSVC>a+G(pzh0;~Ig=LD$>T&D5*eo`_&AGIaKkA|KF(q_ z0KRTejw)Kf`3;7R! z3hh;Z;M4VjqyFJ-#GOOd#;<>nU(k3L_0|i`{hp+Ej>)%+wMZlc(fm4uctjucJc#z! zq48F5R{tmI!Q=A70S?4@rV-=xz?F`YApWh}ML)@S;0v+#i7OrDX8v7A!wLCGU&k$I zNZyqWzsX#D`-Cj}HbHcrz0!f7zf``od+mfQjY#Q>I2hjC(Rm5X<`X;LWDZTT&VO~<<)@RBXQb?S?Z~(M+T4-iS723j7p?sd4K`CVyV(ox^dunl6}6@)=I%`aFl6g7Kl zVbHQ#x-`~V3$*yF&HS3ETlo~|#@`Wds@GT})1ei%GF$$sBclzM}z#SW=!osy-+Q-cubc@XjMJ5c4(E|v|7{=7>Z>OS{nO$ zc^?W}VDhED=j2^dBQlbF)kY!2m^0d;S-WZD5y2sFs&SBBNb_}FJ0}Ngf-PZs1awzx z*hAtZXl+3hb6$Q#ECQGJr8p)rJ79cP2R$BTC z&I;9>cl{!d7sGBvXx~a=qdZ--gKZHsyHSn_E(1FwS~|j%BjD59_`e!j1#aRr%Hzj} zMd*ckZA?%?B;yG7=R`oR)@rH$W%(xT%l3b)y$4(sNA&l7 zXQ}rJih>G=NK;XeqIZ|8qGAmyDkv&;uwn-*Hi|K^Mp4mY7Zr`h5{%_y#~M^rj3w3t z4H{$AU@sx@J+pI`YkZ&o`@GNR^YB5>e9!sKnc3NT_wFpXMVOv{TqEAT67j6jEJF$U zOiiDE%-6%kp*WxZ<+DcZt@M2x;Lx^wj?Xcvk0%X#(daS@jSIHX`A1p~C46W`p)czb zUka}Hbo8x3AHKdb9iMHQ|Ef`pmA}ng{5|5KBz{l2j zPH||3byrfmxT5eaFZjRM3H&jZh%s%);Hx+seOW8P$Ij^EIT*`N_Tqx`Pww=?HPg|5 z^#Tk;jcpE=r$4}NX^r@ZDwbnCUVJR%YmI*RGM1pkmY~U;2xWKh^)QzYY4IeD|W^#|Z)d4fMr8?DZEPrBD2^D4Br% zDE9K>0{$48GbGs?!wrS#n`QO#qk|QH8&Y++U~lYV8{P(6v;`l%aiDDumT@DRr^gX4 z!}8V2a9?l456o@xv{(h)4aQdX)3Kai<>kkviyfMp(+x&uEB;^VB~_}NZjMm9SL`@U zwehgn$rzTl+fAVE%|~^r%|YVaYai7I87~qSAX{U_yTty)uZfMs*6t!-1hF^q4dSN6 zkC5>};51!Va=b$aUvr7XQB+|naU6C~hnw{RjVZpK*y*~czlYc#ITG`oBTgYMCN5AJ zuXEmz!}VuT!J&p&f<)q4#CgOrvHcC9k0g#G?oYgxIEnZj@f_mFn^>P;XKf(I3hqEY zK>UdK60zx)h~FcggB*|g=ftHHxACA=a9ilzh%<>B5Emn-@djIxBjk>#(49D)csOwp zGH-AOG5!H#l@}9dBlCQliA#y|i19CysqwSKnZJBYQxn`G$2%1823`}#|0*g}tSOc# zm)M(FS1jU2;%MS8h_i_Y5|<+L{3*n7_tJy|$dP|f@NQ!N`+^IIGm-fc{z6<#{DC;+ zHxaMwDLR~v%p3G0enjym#HO?oQ6ZWfbBKo%;`W z;1S|%;sWBtcS3)IIIRE$e7Cztj$+~`#7Xb50$!27C4NV7T`jSMP7l@nSf?lUBCbLl zLR^D5g4j=Rnl73g4M-4AtPm#=w;)a@jwH?`jv>w_?oFIaJcu}-c$CVx{}qvAA__ohh*o$~0aR~8t;t1lsocaDAO^zcZh$lWnoJ4$yI31a9gg1zb zi0=`5JreQ9#3_G^b^cPTUnUOqWyrjJT@qICLTlqC*69rrR3%ark2yR+92|cpKtM#7V?_-CFZa zD~BAFNsv!mh4>vYK0%=-bm=b|;FoQ@0e|AE#Nou%h@*-5l^xgTCy4s|iqV>HTInQk zBZ1dIA#f+org#nFB4Q6>`vF2#zxNt{mkY7xg$+zT0>O~M&1l&1Cyb~oHX?p8%h@_!ED^tm|FqZ_OBq$+nNUR$o5;h`^CpHon6U)SY zw2l?xIN~tk6k<~XInsxU1{xEuAwd&j-7pbvN*qrdPMlBNjMytt=!*|RLPFhY9U_hm z#t4q&k^fq!e8HN{Cf)yJlMbo*T7{gTJXF7!Z2U>#*K9WF{@)f3dKiP!*73avfB0JG zKifa!eV=juXMFxMe(@Qf<2w=lX!&pcms{)H_+IsiU=cAtT=1U*e!^-W0KGOus1AO( z;Xkjc!FM%{W7t-3^EB2%)7aBEz&j!%LXGmH9{+JljZiH=>hYftIDl%YcsktjG6<9hLiq8gQc;; zMt3LcCTymwutn8{jrXLuJH>s4)zuNUI7HaoSJa_eWL<^L{vfQ^dv5XYk^Z-EWcmu5 zTUXc+rylAEWLFY4{~wCm3eH_cJXhFw8oAtEf{Q4gd4hCpsKafAP4~b&{4AUA)B{iF zHJ4`@6Vt91izBOg5XIO#VtzKa#(%E&M4Ycz?(-++G0u_1{A|uS-(OrEXlL^jiu3K5 z*V#*~-lOEh@q`@w?9ByU_eF#J?9DqBOI(pSkytzVt|8V=zD2~^$=9o%=n&t{d4Buf zMEP_}5o>4PbYfSE=MZZr-y&k|GBe5@W9I+qq9AbX*RnO-6$6Z4ZVk0%mqC*N7b+R1k-aUkh$5aY==O-*3^yJ#RtYk*ig`%WMZp?Eg2cJeJE z)=s`<#M;T%^ho44QvFfHvUWCKK@Nokhl#bb?;TBP% z$e*Htb|i>>E%*y!f8t2eN0Yui@nGT(#M6m85@!-e5$_P3rt5?bJ_7k9=uCne#9fGA z5l55W;fd&A46#3PSK=t*Zp4Yi{4B%UTc9$IKR;OVb+&^9JxNeZ%nzQtg7s6;U@t85 zRpL+F8_T?YIvr^G5Em2khr)UNDAM;Qj;N0ZCcgd$;6I)qi3IUj=7-WO;sh-71Xqa% z5~uS7_%n#u<(cTxK0iuE7#M#6nh)YR7k~r`$ z(EZ#3tgY#Ob7;Mw~+N>BM=&Gl=s^pGq8`79twt zA65_+eONss7 zhz?{C7g2l}aS8Eq;#b6=G9UMsBEbq0_!F-r9!$K7IE#2SaW3&1;v2+kiC+<~BldVD z+FQ?=w;xH4Y!W0AZy=sSypeb>@h0Lu$+bg14;96`K=IFa~UWcB=?MUJf`$RplH zTul5Ou@epXc48y(4&uJVJBhPtBi%)uN%8Ns^S`d4*ot#W5Kp|DIG^|j;x&|D5AhD- zy~K}*_aXC*(yNikzn?gr*vyZA{7_p=jyx=@M<%1FZ~&Rd^N9~qJVF-n!^GLdM~Gih z2aXaO-->m9oY+ed^-u8i&l^l9$4TO1;sRv81c{X3EX5ZPe?;cTiHIZ_enlLC%y+X8o!CZNQaqlx6>(Y?Ia*VNtHk_S zXr3UOHnO(F4ooC$N8E<^3*u44k;FN~?TPOYcMzPWvzJ7|jwH}E6U-lbRNZ`TnOlmZ5|DG+vJIX#zn0G{FjF-XTqY z0vUgGv#7%-i8F~$5$6z}=FGSM!{j(af~&+o5B(IG1d z$DdblC5JT$B8Y8>V~K5vlZfqzrxV)~?|rk&3?z;g zoTh6)j_D)_BHlq9Onj9%gt&}2l-N%%8fZuyOWcTfIKp`$64kNZU zhz3l=e#DK5BZ!+2#}PLrP9hE`p2eB(|INs;h6K%tbBS9JpCXPRzCqlQxRkgRv3&*6 z;nu`~#BGS%AoKQhZOIWwf_B8Ch`%77MI1?-P28UNFmVUsBI1t3?}(#_T^;E2e#+-H1ILMgCag2uJ$--<=%sBKl3F3%Ti6;k!7SphiL;4k6Xz4pAuc7JOYGz#8k|QQNIai7ig*D(|MSz~baH${ zf~~|0iLVkbA}%4$BzCPT8eB{qLcD}Ho_Hy7HgOg||ML!`_fL0K`$m zD~Kani1YZJipciv(*)kWC5K5%;C|dg4stY~n)V4aB+#k#8gM z9g1%v_HY&Pv>b9olVdY+3h@@=JmPPO?+|Y#wssQw?VkMIA7$#I7SM~J;zi3W}mJ9r2_MjS<)PduIYIPq5E z6U0TtCyC3DdHcFk%g@pIxQ#4m{Pbz*#**S%C3w|_5kydpsq@oVBF;y1)u z#BYgniQf_5A%0J6U0XEx0hxam^e6tC$NByjO^z}WOd$RT8Gm)z#Q##ffcPWvBVvAc zf}hMB>WBu}XDofjR>L2Vq0PlN@z#y)mG^3iPMSo#Kpu0;y9{b0hy0L zCb5GRo&O`+iG+?Qz+c@~5>%uFg~XMJvq{gB@gL1e=SKo6(=Aqw=Mrh6dz)UO^&T(bIINytLrQh+IKcTK4|>f-YS28 z#L`8TtKtkCd&oR#3~|*Sa;vH?2!F_pf2oWUUhn1jDH0QkbXegivy zG=?%a_?4$}Gk^He*w=E*SgOr|MN0E31Sx9jo)25n57RWybVQ+*Mo! zDqS>I4X8q0#tQ8*z-p@%?rCmbVWL_g-Wj^^3R)_xu$Wgcsuc!nZeC%tS|Pg%EW!%S zK224mM!YPY{EMd$ORjktPr)klPUcsEdzd2a(-Z+}L}y9S79Fge+6&FAruYq)-?Hf1 zfW-XI10qHOg|&F6daJ@>-gI5Qk!S-nT=oAS3{Z+%;eQ^W|191A@c@-~+KmrGhT2yC z|9-sYsX}$UaAEOShhwe{7^D{&t7;pP8qqeH^2XE=TBqi~4e3~sv6{=LZT@GAVb1W8 z3;xF~7|ce1{Mgvv;671AFHJPBeQca3u?FD()aa*Am@NEbq5D%~M6G2h0+ZE_ z;;MH00e7#bp7>rv{AUY$pBk^SZsxhqj4vhD4rV+zc9cG*!nx8)|5;mAx8el-(Ly)_!8+%Mt7TjN$10Gr-nZXZZ_Zyd)4 zng4umw6&7fEr6G0#?E*YYxNI~(cFci^3RJP{~u$G21gbP-n~RvXHRQ3T-OjgZ#5}9 zRp(OAn*BndqNQN}udyzhVh;J&ScMsSgQ$|14N)JBZiY&$1)pCHV>wS-QyyRP(YRdN zvUyp3c{;1L?_0St)A!yfq9Jgc$?k#8zZdv{taC#fmPGx?o$k`ehD|6}fSn{Otckg~ zBoAcz(!HW)XV_*X*U&fFC$JSvSOt+P%Nw*8k?``GAlHT^3s4@(i>ScGsf?EQg-hu&o z*-d};7s2BpgQMC($$@HWWlY&>i<$oKU}9*F2<_@)Bpih3-t^fBzNAp5gU zaI1nmTRQm^206$l4db4R@S4{U;wZP54wS((N4Z}&62GvAzbeT!f?wE+_;!P^Rj2Ej;;Pfd;{}G*q!qX! zX6adkLwS=vV**^QA_wYo8VK|Py)&+X2GG!19xWXSfep^`mxjDh z5xtCmDau8z$C^Q$iyR>>Q(%>gd;t$miB;vnL2XS!^|-OHRTnw1xp<}%yIN_g%Mu6H zxm*Jus$zGC6JN!@_FYY`sn_b-K$~iEedYvXtI6$HL)c$U9&AWzDiZ(O0{p7W9Rdr( z1*bL>*7<=$`JP>f1Ny{)9ivclSXCXH>)%2sAGUy_)#bQ0iKpm-Eua>2@fTgyTa7CB zda>ianm189-2`|uKh)aW@~eUPQ_$O0j=*cC)vj_aG>2SeAN}eG(asq2Lsxm09h(3n zz2s*4XPt$6Anf*%Q>Dkx^k%g zrz8;=42$Z@sca%t^p_hNHcb}ZOH-hOzZ}i%V70%z(eT4G;a)J;{6#&vB9mY)^sFzR zlU8JcZ-AWDV-5|KjU$5~oQaLsmU^p9%~_FcL8qt0o#~ph63as;f2=@nm7+PF*qL%? z(kXBZlxs`rOTic@*F$R_5GdzKQpr-YTd*8$&0JwbBe|E9n+2yE$@BF7%SA66LYz@H zu^?D%lvnF7tQ6j0kY(JI0w7+NyGW)h2Nn<&ad4D^xiOlrhZW6&3klIvs*N@B*I0ZH|m7@YD?i9FWm$1$QBsQA1`n^+i zRfbD!D}`im3&$h)?eB#$6`F-(zSLZSGQ?vvTHY-%i>&iZOTGfkH(z4@KM2WJWS!Bc z9T!SavQ=Wu_6o_Hy>LEUb~BV66ukHlJPVgQNox*4vu5%y`l!Rg9|L~P+D4Y8bw5LwHu6;I>zi=CjXd5k;FgGAy91GJvHw$HTwA#dbAc0Rq@Bg!+)fUW z-WQwOwv&Hn4WfS&@=Ii$<7~^%#fOu0RmRz})Q3W{|99vWiR*0sGr^uPgX58M+z=^8 zrpYfvbRk*idzOUR<8)OX*fK5T_)2BRHgzz(r)8x7o2lqqThLnC}NWcGF3S);h!4_VO6% zo2t;bgM1}uhO6+K-Gr?cY|pI1w1au(bX}DQd)B{(2zG-e9c2$gx0(XadExuwW%sTP zJOyWwb?$0kzOlT*46*j?2MWEZMa^`#XBEqvNyn$5s|>Ygd%Q)o3KVw4T{#xsc9g$j zDKH}nDFwDh;mK&94?K>-yZS1BG@JVDH;V5c0LGqjN2zcCWb~Bd4DI5Der-Jb))SXE4l2gUOFKCB7u~%` z*0yhXx~*w8Ls=~OPipa@Yy>s8Bh6+Qn@}EyKjUz(jfJYcNd90rOiN66Z}WXs#(`=;<*ElrBHdBeV-z*2Bf}NR#4h-mxy_0`tM%ayuJo=b&$;c$v9394k_HLAhrm###;$yn6_EB;X~l z-!Q=qpm_ow)CVRCY>1OuF}jP;4Zci}1G@Y|iY%clu{6yy(;-P59`3$&dftVf(wzQG)xr1KmpF%Jr5q>==E+9sNhl5~mHP8Xqh z86-iUCMiS-NbKB~A~bXsNzgZ32fc>Ljt0%QbQUBHlk4fdzZRO#uyL5&DbP4apyOPs zisw=-`_{=i&(jinJzs>JphhB&h0`|z-Jp3QuIYB=7@sINh;~~fqWj2t{AS6Qi}~a2Z4nmyfdqvta}t81ygJ2){K<8;OaXvjx_Lb%UXjFHn=6Sy=+PH%APxDZJvg!TB+k~S+% z=Q+=sc~EG<379@suFHCxbH>V7nf}%VQ6&&El4bWUfkgr*koB;!Deqv(c%5fO{E$td zA2kX3v}JgL5*Hh$h3dg$OscPUStNA@$8mh``bi*MfzWZXTbkQ-!G&Z!+SrsI9dak= zJfm!w78>)jkb0m`YjZD3@HVa%x}r(Yr%CcqGSG(oL7{0kC=2>8~Bm9be zOgnK~NE+WEX^JIV5oViV!?aM+U6P#n!-pmc&~whhZ5#VN{O zW3vtOsH4+8P)~wI<2|?9u#Kd-UJQ{F@I$GVtp|*mfGaQIzG%cB7Eh2jGhcJqMBI@A z_q-PFZEuD32(>LA?o&8Gjcu70ssQIF;cBn&PAEUTgTE%>YH#yi@Fubzv6c*ln4yO) z(?XR$P$THm*6AIT^s{AJDC}>Npih&$Ldh6g*6<$@l0K3IeK^FkC*$F92otCJYYf&+ z#{KIWu><5Ic9|@Ru!EJb9`kI=*I*XTp7YGKWm-&fBn|qs9%N4RTxrWzQf&$RQ{*Ah zZLNjyIa!Z&w&mM<_C%fM7F(u;s@PIa^l8@;IVd@5%gXFUXuBTnreM#v>jg{j5z%m$ zaDxN*Op(L7#TZ2Rs|u9yk|pCiToU~8{L_|c3z48L4EnT%S%D2dw`HR!lmI)X$XU|E zs?cgGUK=)o2UGE*OLldU|L5wkewtiY`pOLorpW_?`nwB%U=3kwY_(&HJ7@>a1!cc-nzOo8Zyzc4p1~t&e0DTD{A$I8S~}vZu`dxTsmIZ zsy!L&5v_etxidpoZ6JQhN5N4ONHq9UQ3;BY8Ox^NG;mme%k=X^p`8XH3veO!Pk}xQ z6Py51-{7sPy0G*cd6wSmOW}c9uVI^l91TV$L zoFH{6HZ~nDqLChb2eq=$8w+Ey5RY$%V_EW2L${rx^1EHocbVK6ZwD-2CSTFN+auha zVBB)KgLLi?99=Gt#@qRUfcI8r9)<-V_mi$2hCcy^&f%y~zdr^mR^Uc-@`T`eP`Cm= zR2bpy3S7U>P77}z$XSUwubhX{mDq!+7lixtCHQ6)_FyXfxC#fy`>Jq{g2AihCd?bw zua0Riw25%YfDuxwnmo>jw>lF+P~UTuv%%OK73572jm?5STw z+R^ak202Q4U<;Qw$S3uW^ljBcmp824D7Rr&aDStG%CO2sc+J%zcaz-IaH@vjEj8iw zCV3$n3A1wKY}O5GZjN**vi8t-3%XbPLjD#xL3-*7zTe7yaT`eg z7Tt^epyXRr|K~k%wLvsC59nLtzFQDX$USIe=aRG(L#lz5r;XT}F6w z5WPC+b_l&)VK*8nM+T?EIBaiZ7;_jGvM<~|jCbNsDA3^uqCc3AATA7pI!EPE(yK7Y zLd$vsJBIFj6C@o&tOIvBE@%u<`KWr)7!IPvuGc+|?xRg$`EkTxusVTz`WWbnM%vjF zHlD!yf=`;lbF{d=TAak_2v~?l+7=GKoW$s(aAmxPPF%b{oHg3+yfq0aeZUcjSAv(wm{M={LDV-(sZjw}Q+PJVY*> zZZ0grFCiP)WC;H>vQ_I#mM_nWQgkl(XE(m3STE@FQ1;OOI$u<&3+WH>3(&)h1?DUf zw(54vP3t+B;I+iIt)LK`c_@eBkpBBnK5jU;MtB#lg|olo&EJJbk9v%)aeg7RN9kcZvBVcmFdrK)nw})%Qa#;Y!jI9y|7hZTCvgN zhtZ)oXOhlEv1S$bh+q%0Rney%!P6(}T#~KX<2)hp0>htpYD+$*Ve>!nM9~{k{*?0# zR||x9>se^^1Q!JDlqd2JhM4ohzwQ#qPvyD|{4WSjB3pGl|Cl7s26#o|l4ir&UM#ON z_o*C$-i9xQ(7@L&D=*)hT=UZIANunV3Xl1 zYvm`_1>$U!CDO?lcw(bGmp;V7ueQp3>95`}%1-Ibs=*;UWgPCGLH0@ls{)z!N<5xZ zp4%%&q-R4RSFdc44vvCu2DEd>!5f2;EZv>}!z(C@aiRaNpk(7S2WuRZtx`@pv~yGz zNYB26t7vg2OQ@*iG5q_?m6UI!1&d%?CCr(z3=*A`8PZ>1{@qFG#|);mc*78XHm-%v zRg@Su#GGA4scSE-KMZHxu@O(`Q$tCY{yq+OYan{TSP$hb9@~f2R9;B0E4FrU#{>gA za7%>7+$IV7G|3Z`Og1nrbmKMzcq?xD(RYP38ajC^HT3JtG1*%wW`5AsN2!lyhL6&Q zbvK{zQNmf;xEECCrLcC}@C$CddxKw2KT5Ixj^%t7x7p4z8tHUH@nJMn;A>6nkFlq( zL|vCRl;c==j_fHq`wJ|B0%!jw!9{gv!)9QHpAu%Mqr;o4`14i=NBtBxL!5>0`6=#! zU?<|q_QD#bF*Zi)X313jbjHqV5_8?!$|}8ds)G4skTRCxd8bi`vXON#Uk_1?Oux}h zqzDD)hRP)ULO+3ZU`a!zRG(rL*dFFLQhG|?hC@js<)yw#bIo0BRNA|)psz2PM=drG z-{ivgP`y?5DQGDxb@0TKC@Zzl%#oFrc!oJAD`{ziz7QF&yj;5@{uEZf~yAM3I>O zV3bHO32HV~z7O*1OxRyom)&@uI|E-Tq4w{_6#Y?#U!I9rP7Hi#s<`WS#R&F=n&Aq5 z%;+v~P7i1quDHc)=pnd$UttYZCBDi;#syRLUr4M=oCsYfYe3()K_tnWs?*Px*vQ^O zbGkQd=gny84)rx(3RhOxO88~@@YXoM?FR_q%LHog4kn{qS!w!TB{qr_C&(JmH<%PF zaPaW%>n#dBj;AE*9a+)mH7I!}F)egoYX^O}3Sd|prH1rxf_YXOr5Tg14>O-^tIT5! z<_{N{wxjP82z}swP@y^Obef$;;TXa!s#4Pw;V4VZPy5Q|b%bxpWg1(h4v(6Q$-X{g>VSbF#8XuIt6r=D5#-h6_Nr5ka6v34R zlx>V1o>@eLuV(0z?3fQlRu;gMt~hv_vISJ?hHJHe!Yv@Qn^GgX#aWT(8CgTRC12SL z{Y*PH=5q!5w6VIAiu=htJEqlMeGb-iQ(O%-&xx$aN4sGkRuf0TJ?umDIStR#LM*eS zEa55F*s&;z{iA8nr!DB5RQ)L|~!Fj+}|{v`xfaFHozy zEEzLX^|^NJr_UAW(-yUq_seX@wAvrFEa=nvm6fVLV8=2jQm#NBW`TO$aVOK9yDmaR zcf~a==%VP%F0zIbmL}ivCePY2E!OW6bsT+KlWS7-=k3^Cs$H%?pVsj*p5-Syro}#J zSN)zfUhPfQ8|;}gMamWE<14FIPsLHMIelPkPwe6kr1gQtJ(U_=e6EV5 z`^g&IEy)k3>OJgP%;yU9X1FF&uYR2I(bh{?nct+L`XldhA zsy@h`&HP+}KCKPBM$+kJd#2T%f1QQ_ecCV-r0T=$Sxt(RE6~S>!5oLfpgH~FLL7GS zAZh*KFYIEV|IZ@nX|jedEXj*f_3iCh&vFGQy_AM{PiS~AWxQT@Q&jYZ2fdV4_+UnQ zZ@d@}f$hDOZF-wKBG}N}uaC0XR>~{}>w(HveVzNlKNj{4RQlrmh$@4W?+i&#g*U4d z&J0ol3@I-JA9)FX4^ryt&l7isfWbJL{2NV{vm{Nc(Tyx>=T9H}gp8rZ|AQA!_aq&=J+rKCyU+CzuY zN|F>{fWxDe&C*!|3>u?kO4};H>oFLAPyr^5MeFSVZ^tSlq@fNlC<*It!Ed;dFrT9% zbW2voNBIj3z%M+Es(#y&aHVHo(uCD^iC!zmL6}U1< z*(7yxhLp+JzpKvhell`r7g(2qdGA*J)_aP=r190kcdBw*(z`96rkJIo8gO8mk|Ry@ zfC1C7ntM$so{pbyCER^ypuf2fR82+yR3BKLii>#=Z|bI^|BVlQ$sE(87b{owBm<&?C*501}N)=SU)VBnX^G%2<={Q9M`SK3q?md#QY zNiS+cov)Npl2ZX>eWe6TKh}ZMUn%>gpt>;QYaG^Pb-`&i4qF$0$e4}({r=E+4*F~2 z-Tyhby0+Jc=5v(-sdfO^&%?!D9{@Y&;bK>B03q|0yVBhTP-%gZCv6IXvkR0x(!LN# z{RZ{Hp%A$c_1i+>=|a?}HH4%^%K7RM1>(_OowbV{tK9$}??GPJ2)bq}Gpk3J2LnaW z4})us@Mk6t>~a|j7USK8_yQQYMDdj_m>_crF1gYeLYLx5tY{2xm*U8$7eH>75-NRc z0>5S9hzx8B@ypPjX$p6jp*|oSQkSFtn{a3YX#WZ~8&)VM^-^3jxU@m>t`*m;y}D1? zs{i9e3hVle-FL%xapAO>{>`A$M%-);HG`y$N@wYQGsxeFn{oB#&~=mYy_C=#ta6mb z($NTLo}-MG99zQ99K7=o*AgmiR^p_6EzQF>D+VU5iH3<=l;idCX_@tXB=!UwkUa1( zX;q|+gkhq@g78h1m%G7$Z&6;X$y0^=YgJxaE?+CLwkVJ24ehroPo%hk5Vj3(=e#R` z`rj$FqzOZz<9Es(X~`(4w;k=MWU$+z{3=bJ0*`hmB~s*BxVTgKN_spGy6-}NzeQ%{ zdj&V|6*e#?SMitTEru1j%4_N1CRnr^N3U!z@N(Cm}{Q(~CRW3_l4)4Q;~Hk+xu{?~kd*dMs&@qu!!eV#y_50|PYuuS*D1loMK@&v~% z39`%QO`-6=v%fH-Iz3LbF~Q#e9zVprcVEwt+s8M{)H+3J6#Ti>U6nG zRcM(mhr;sNU)cwhPiB8%?ri8fo$fSF>eO4kI|r37DlTcd^AvTrEgx#JJ=DNwA^23ydFs>n zmMs^B{~dW0sw2Nt6_#(g=vKGfjjG$SYbEw%Hi# zGaV|mjq|@Fc2QOSFGmc%zob|uw_<8_h#smH{+B}pfAI?1W{DNl0eY=g_@4*JGP(8t zWPr4#feajD%S1~|@xNZ-cIp&j+|}}nlussFqF!6UYVVoz^2-?4mVuAkf7YgDC;i`c z);#<&p3EeNS8(o%;>GQgD~h{R&g|W z>l;}6vvOQ2d;{?}(6)OEzBke4zlDd~HhBlzZlV7EJLq*=StIp*4{y1>{vMXyK^y%6 z8r?;E?gL!Dt4x)W%D8O^X}>6uQnh~t{LSI;M*)+6MHtB7_^--7X_7sp6e|~{yOkjF zp0Y}kszAv-{1U^>1uFce$guOi(pM^}#$mDay&J6Kc9I8#mY{7>3%~zD(fbm-+Ozc* z@XZ5+3qAt8A0lM=aabbtsRJ&*E9a!fD+)|~ zgMulopx_N&-g&o%^tX6fwz@UceuuVd8#u@9qBb!0Jz9NRaQT3}eDMVw;`T}h82C5Z zyiTAmL%Sgwa?7xx`dzt|A@Lt1=ZhYfXjZ3SrK0(J}0n6!J;X_8tZw_JMm9v6jgas0{yB3bU2E_A}c$ z;fG8qfr8ZkY(o6>Xa-@Ypr%h9pggQ*LMvr@}gSv{N%6rAF9INtp%R zJigkZ16$3*Jtv3syyUVxfQ;}+wC&!@Gu?6-RPpXGepjq8g()el2`VMX}MAG=We znS69CmzRDjPeplbH7Kixa@~dhj_*fR?nGX7e3zj-wHD|DQ111aJhwZ~9`dPt2g*Cw zhiZYifM5BBIk{!@;F{=9H78NCO99^om@@vel;e7GdD5ryTPWY$210^Rp8lEq%Q!C2 z{8auN<-xJgEEwh4pUK~=^4w45c1N)@eV{`K-+V7XNGRWYKNZwO!KJ~_GZga`f0i%2 zH*dc5Q+XqlFCPno8=_oy@xR0C*oVuV$g2)-dz3$&2FZ<3?)91cUsWFRseAy+Z_kBP zBg!K_lUM4;vqzW9!bQ83NXCS93+IHvQ%W$;ai(p_gv|rtTmd(-by9-_|(At;4M{d*pgkK`iR(l0U zTB2R`7S^;1yKA)vpQoALI_!@0)CPLD!9cAF(6}wy36;UM9ona^@Rr-Jz2W*7Xsv3) zzDTrH10btC+Q>#Qz609H_*RCFXwNo>&?vMm+JRFiwAVUA%PwKD(7JP2eJSoDKNtAg zUdY$!hIA2uCp-{Ofrl7)tp-x1MAe7S_eKk0^Jo+%sm@yFxzS-AaVBduxIQHe=ZRH= z%2UGz)w)n^n2!HcVBPWkf)!Y-l#2hyNHfsqu%{XpTAxyF{TEl#YH`NaOPq0AwgW_*e=G>%)cE7 z8^|2fmx?Kj7{aN&T@QtY81R<-m#4$VIi&cA2huT=VrFN;G8sN=vgF6GJcrnZ<&ju( zkAkp@66;|eaxUyk<`6=Y*053tygDDIIBL_|(1SDB!V1G0IK=fUuODYlDh#XY$U@9t z-wgYXIc|*?&t;-|YrMJH?XdZkqz3_T?s3>e$43EewZ(rFV2=7TtdhhALf@xhlN<&& zFAohi|ME1fiX?pjGsF$V{FC;&qa=6F|AxE}kz*4u=uDCCy7 zVT+*<^S?f(*0%T%TB~}d&5rqY;u9-I^6kv8>Y0*kr0&gNXs~IkqjvKNV{y&QH9|~x zt@$V24@T3sj@l<(jIB9j-X)vbG0E`C{6;Y~VvY{4%9A?0GAkxiCmZQ>5A#>eObwW$ zc9n%S3woH3H8=IwOI2f_R-`G3Z}p2KP07{d4H4>?TGeG8B_=lBch$hPy$RpW50ULn zU*MxUp{IfZZ1@deYe>MNdYieZ7d&roYL1)4?ph{;? z2lY{l)uG;*pq}t+N0S$SEeeY=)#0y2LF)-cXM(J4^CWy-QZmFunS$`?!}KUqU3_3E z^v9s4HayY*lCh|YmZdh_gP#_UUv}OI~&wT732F%4s^jZZcyCC zG?`6-d*^~)s*x?5Atna9i61CpOzUy3lUG;MFnj?B%jk z?TPCI-v;5;3oGN>AYyu%df?k1La)+t;Ts?>_rjK{gHvxD5+{i6jYHB9*tMWA_`bKv z3tx!P@)|DU9DJA11W3LX)Y_I8@y!PZuLU(B_j^qd3weF8!8-5=4S&PIyz4l&` zU&l6iU3`(jEzOOWw?9*MI|%(bsFA9`mlTZnIjD(R#upWQ_j8Z}WBcLy$2STr?uYBY zWGNg#i_eP{_cPVy?-9`V$89_aqWj}o34rG}FjJ%pzVC7kT<(v;8W3|6o98ZkVSx7l z6sO`tmwXdNmp44W8T6YP#XTq^-lX8;5|wWUbyTA*AmMhR9dYs*9~fxrkB`15-wkS{DqJ9X z5Grtj``ke$g->ulJ_r?j8n^cl(;3`VS{4V@0=uEODpJ6IC@w8dl#UsS%Ot^pV%%_x zJ@AU#7akV})mO_nVcPv(P%E{ZT?f2}nfPRYq+wVSr#G)0hQo)`n~x7ORpXP3*>9Nr zZ6an5fqK7Tx}sWm{Wt*H56A5%4(6iEhPz_nfELB6x{rSgYN#rA4uZ-fOg;Ft)2Ssv zT~%pwxLgu6Uo9p;!h@hqs`7W7IQTHAgX(Sqy&h8D-Z1xJ&}!A|3-x{{G0wm_J{lLX z5xoB$cV6BBoORRW5w(ibWD>@hCgC$u@W&s#|6_66z)31@Nv5y)B$N$FST`JwKMwM> zDXN2i0FD=3!9LkkiBCpxOU7^qh)6c2@mV3qlTE4kJaoi3zAMg#ZR1R-d?H7^@u;$c z=<&Eid;!T%gT~wPTsV8<`FPV7KKo+j1RNvW)t>QX!O(O|@sXt%3o(E3aYX@6#+W-1 z*KP~A_g7FKNA5azNSwQd!0vy8oS|=NkiD8K7?LJo!!x<51-Yeooa1twiE(@q?!rc> z{2Y%q+=cTirc72hs>|q7D|PlK#U!3ui#7a8+KFCRJ#0oB>L@iF>#kvrj zj$0zmV2DY_?(~Jw4;Z!&)9H#V#Wt{5^X6HKf$&`OW?PCb5c4->m}4oHS&G;rO;BPf z#zAr!4h?S@r#T#-i5s#fY$(Gq<*p=4@r0%50xka`!B9&v&r&qNVolK3Qru-J>LB!A z%FxwP%u$PKU*6z7s9D&TzHnI+p0E`C!TTdsUuY@5vJ`tmvL?v46zjlo&5OIaR(xS8 z#w|+-_I2b7ezb{Ljmcs)F0c!BQU@e>*}Y&fG-Jw3JIhN?%1Z$d%1DS87+P_grTEBF ztP7Vl!B9(av!z&KDf&XP6kH2_o`Xl>!Ejs(4zS5>fo~tR6r^RPBJJSRWEJ?`liY0gh|l8J6NROK||i z*iy10OR**F*1SJhioQ_UjOt_5CfV=3ZwndZffS}QVmt`#FJ z#WYLtsHOOir5FzP?5T-qmf}H6@x7&Jg5pJZpq?kp9btm-ZE3;2w!Dux_ah?{4+d}G zvYv8A!Ul}0OR&mPd}1j!hv%9g(^9-|DH@?=1>9nOUyMf^oDXuaLhwx6e7xAkIUtLd zn9ks&4=^|epRnP+2)OJR+*A$Y{ELJv(-@pf0hhB(52fBef_IjwIiJSxU8Ud=svKvq zI0g3+*?xklPQm>lGbGp=0>I>f*IW0Tg1g!1@IGAvWCLC?hCwlyzTguQ>a8$M;u8`! ztibD-4-ety3Ow!Le1yg;@nS0x(pQ>#^7#liSK{fbD}<~vjpfr3HmpL7g~cwxebltW z;JHiiQnlC{N>`fzXC=VgHFzZy0MTnrmv91(*E+nY#vRZ#c#x`_ynMZB7|u#yZo#c> zdDn1e!tV8W633Ydq1mQ(R)6(w2TiL4H-HFt+=jTK8sui_uxiq zQHG=q*g2f5aBl++7S2_O*@zbBDjeTvYRBg)=r`es(iK=u>U29us2SW%Z5!t-c<11G z7UwLW?F{jr)T9ZDaMPiq+&HoJdztslIjvK6kjp;g(M3|?)`{lrI;{>K&P?oT zCt2~S>m_=$mkRU$l;0`jKkFvew(ry_araAM7W-@aPS;e4UMIgjU7ARLIs5Oj+3MR4 zoo)z7c2EsJz0>T z5MPl<&+2rS?+kUTwUS$b1~uckfiGis!Pg=|#_FU(>vm zGS$kZKsGp~td!d{+2GXKpJjv7Xn&RsPNLYxZ*U4{+2FLx|1BGwM!zO!+2AA&+V~Al zSG+3vvcc&^|F>*#3TN5i6wb22DP@&#+2C}VKg$NEfvddzT8ZiYZ`t7Vj6cf;r>*`h z8=S)5vcW0*U7ViiyIQzxaGJPU(#Zy=h5m2Z;IzsAEgPJ|SvELLd?&kID6DL9x?+vU zKC73w$Dd`BQ#e;`nE2NJExVk0{M*krdmuWp-AOmi1U+NiumaS3YEW4npu9LqX?waT(=c?~ytH0|KyRPe0C$aOQ zPN^Y(vKwmNIw_y*hI-ZO%Py#I{ok?+Dt*12WfxR8f0kWPA&{~QDx81po_KM+3^B3^ zYQLAuKBwV*JGH2?CUC=K*y*`PGt zpJjv6i~cMdly>>EY)neuDCbdgL%zGXksul_9ik(zIk zv+PIe>(3RQPfXk-da@m9p+Czuq^+LIHl&0!%B`rD!)TTXiTv+OmQ=+CmpWT8L*b!TF$Kg$-A zlr3@|_hX{-7BM8t?qaA#m8`quht&=w7H*LY$L{s&miTWA-l5r zzROGZB<4}NF|n3XS%VL0B#>qJt=q(`EW@X4m$NLxhqElhhqElhhjWVDX?eLU z!|#`K%G-&QD_}xa;s<^pB3X%_F6Wf=#5{^*9X=qLsS?Qwd~hf$@WHUGz=yM}z=yM} zz=yM}z;NY>t`?~vxS@v_9G9nyqk z4SoL(QI$3H<{!&hmd*WH9#my~EEjiK4-a_IsKhQWE{f{8<`_Ls7^i1h#a{S{$Ym9K zt3S&scKBOXu{(b%f6FTNXn&Sf?0NnytJvXhS;gM(|CUwk<~!vq%hLn>S=ODW`?D-4 zzv$1hZoJE%WkERoGdasjZx4T#CESVrENin1{aKb^xB9cJt)_gQ-LaxyKW%??r_-v$ z=Z3}6(E=;Ts^>g^mgUT~{w(X1`~6wgBAb69XIW$%=+ClxINhIRS@1=Fmes#q{w&LS z>7{a(^|~JZEDLcH{aIGn7W%WSux<5cSz$}rC1+V->+H|6!ZzBUWrb~C;IAdt`m?OC z?e}L{VQc=SoMnY=pg+qB+jM`H6}A`sSytF~`LnFBrGF)7Sz!zQWQ8sGd--?uCkt#_ zy<8U9Qg+K(7T7xbvn;TU_GejOo9EB6z_!+(Wr1zKKg$AJ^F4Bw1-60yEDLPY{aF^+ zUi4>KVB6)-vYr;svV0cKGjmr={5t!+b&a{a#bpA1AVNO*;6Jg^o+~+A_TggB(^$qi zhKEmb6g}H5+L*?2u=c?3NBn-uxI{`}X6MAn=eiZ7EJ^Htu3P=Sxls{D!Qt! zblUNFHJ5hB@%YJd>ojm_xB4>Gp1!nOy^1yDZ}~_46uGT#*QHM7imsL`4*$HiqDw3P z4o0$5dEQ-L*9en&ZMSl~Oa{zR(baM8hU4+NF8*4g-Sgf4Q=#~cM57nFeVy`x+%@FX zPefPbG)QFqt6N6rvR5KW<{Hai6(o-tE0TFf@TknhyVb9dw=VJMzq)m-5MPnl{I72E zV+HFH?TWfx7|TSyWg}uZ8m0K1cj+!0TpovqLqGAH?goH20?&c|cyL)G35Wk2u(vY- z{50_4;PaKooIKYK$Mp~_LxRrWQ^EHd2eZNVfipvof~Pjn3Sowx1+NY+TkGVA$yY@n zXaGS=INl829lR>|C*XaI{&(OL!0Grm@H}vNL=}!|q9C6OPIpTns0l$MFA%;GTwdP} zM?3I+#z78v88{=_54?Iqjf8*g*&oBfBf@3-fGe+p>mV431ilIRV+!~j@Yaf*|9oJI zYvu~q6$GL$g2*iyxcoxhOWj_Nx#sF$Zs)==uA-JN4$h8qEBIdUO3PZ6Ueg#hhmtiCv zRmGEU0j9F9z>m_;T=U!#9BUGW-MZT<{okvVan( z-Wt5iF?K@#>k2{lV+1|}y}^4KLqoxH4Ic|W5?tP=3CAtq6AZumBq_fy!88b@yNBZ; zB#0aSB=`)&Uj&~8&Y|}W@HyaYq}#v?TE)f%hfJ^=g83%FLGVJut4JOB0xU7SK6sJg zncyqQb^LR#8wAA=Fhl*o*E0bkGy;5!;S<2O8-6?ZPQzpOL$KQj{t3R%@FMU7;LPY+ z@IyxbeQ?)WBh4x6=gMQQE(E8bWZxk{2XGEhzkp{O{R*Pst033t*90GF^c#Us3S8n( z2W=pTn*?Wo&o>Uv17BqH`-87B`oq9C9;@%`e=G#0Cc#bM`;JW@`hLvzC9c#)Ln?oU zV-9#4I3xN9c&5>RN_fm0>S7YSj06Krf@1JtM*kh~Jfr^!_%x&c4R}GDaoYan?{FM| zpwJ{pk=L1gMpqgKHNn>#{l?%sjeaKh-g15PzpfCtw#gyw30@tXA-xp5mC+vwo@Ml} z1Mg$>Z;3%L#3Z;2e1b`k4?e}{KMtO6^q&P^VDwjj$CjA{>mevM3ATdoF#4Z^?>74W z1B$-Nju`zz;HjA*(lN)7R+h_`PmrO4@@`ohyaPD(PX+H~^gDp(8vSnI+lg0BQ`2|gKoCphnUXMi69Zw-C_!eE&HXPl;uj(2qal|dhg zTyWkpz63r2oVSc`fEOD5_rceI^H%js@G{|{{d0Ev69lfEW{5Y#734<1XDA!|B$S{w zcm!PTEW^-+(M-v47tHGn-d>nBTctN{F&o{c=(m%V4 z7Nmpb%dLWZ3^+6V4*0d;a;XW&*TVhd8~+KjitD=dj^*LU%BYYovrK=J&2KP~pBi|& zJMDbUKs^|24SjydiTYv6Q(^^oX-eLu z(&8C2l*>b{aJ&gmrQp=x0{-?))#r8keem=Co@{3a_!i}{@|(!dA?SIxCSZTv4W0n! z*c!BhUSP{J-u?Hq;ymPQPC{D>W1R-nq)zI68s<7rZ{I>@4s_`Kr$W>Rj+O z!b3l1=z2kL`aDfQ-XFXOoFy9s-sOSh3|#?!H#i+f!5crQ`VzU|-;IOd2m~zgjo>>9 zk{wJ2|I0(lS>kEnmp`nWj_(3LJE5E-+knRH?`-E~v?q~4b;AlfF-ER=oeNq#!Rj0_q zYhN|_PbG3Tce}7r`im;(<*}Z~{TM4dUmo4u?WtJtMwOqW0dV7yej|7m_}{<>Y*Kx3 zACB4JhoIjS{4wwb(C5A8(qua^M??RHpme=DU~hRJ`~W!hzX7kbAvr_gX9Oewbq!CK zM(P983S5%QAq}|=1YJymbHICn%Xk-#T<{@Ae=PVI!>58z0$0b*&Gp<5WHTUO6)r-8 z1t!6(;7h?}`VfwH!B>JaqhEn#V(vq<+azcKUIs3g>2RD4egvFV zHUK>BO|2ScbToJqaQRaQvRfd?G70Vl?+z{*4@V*R0K=Dqj|6A;-3*=w&ffJ!ItH>C zMsNTL<{Jl9Wx(+fT4MB@fv++AOz;wLj#quacgKui6ajG;2{Sw_FI#MVcs(C9Y;F9Jsu#9Su`)TXD>*RlK2RX^xU_9Iz9!0@kqdK)*gHkI7<)#pJw<_@EL|*4?YLnKL!Z>F9yMU z2-<4FTmg6!jN#{jF9y#j(Z=`#_$u(Ut;+fQ?>+Da;Ed?*y5ir5A`=4E{jW&S-59DV zL!{U51&O;N!s=xlh2SfwPf*51tQxD*VQdKu`n$uirIf0PvwMF}xXg znc80}(@q3D%kY89V=mVSu1119!*2%9H+%+ok>L-4ml*yOcv;{Qf97-r1Zi(4 zmtZ4!mf;_R=NkSUc%I>h!Sj#hzW%Grtkj3P=vaa9rr;%pcLXmp{Cx1VEn0wPsN-Dl zEW<|&4-X`Bjo>CE$TR#d@O;Ayz>5rD3|?aRE8t~Y@IaC|eG7uLcalr613b&{Z^3g7 z{|!9P@RMbF?jxOF&e8vxKu}aJ(Ab?0USjxp;AMti3ZC|Easi^?S%y!HL6B<%cY@~` z&h>zNaQ1JmACwO)sCzD4EP_7A39gvLRze^nZaBDBv&A?bdy9*Fbs9Wg)>>EW7nVf)?Pd!6$&T#9Tp*Y*WXVL7z*vmXDRIk+1tW?6e8` zQva1NDum-+;M~el2K`px4~D92>WbSJ1ma(v_QwX#{rrCn zE)u+4euBE6VEB*VlMJsUH={m7(+qD2KEv>i;B$nB_D{zbKu};33@)m) z@B@Yq0Y75+b>NlW*G9@n-vM4dW&{sHP}lG!;7ttwH+U<<-v{qt_&4BPz+=qO5eT}Q z1nJVzeS~@$-UfVt;pc!4F+3N1WHOJru@H<&7PzV46AYgVKFRP!;L{9$6?}%_?*=aO z|2anR6%rH}eh7Sl;WcEy@DW;Mcnk2QhMx_-%yZxVSp@?iSYr~5248RZE#O-WzZZPF z;f3HkkKv*JEr($DF#_NJHiPdo{0r~{h93YwVt7@VV)+PF!idQNH*1Rde{~}`6A9`X z-Uqyi;iJG?8GaLZ2gC0cUdiqM6Zb!1tO@@s2nm|G_?tRb^R~GjE<#PVYd_9JlFHz{ zz6hQtrF z1e^m#V5rm>nhZm&pf9~K9Am*F;B+t)d>A-qKE1&w1TOLK07C@C_X7J~n~q9|GTNc-2$2%Jv!F2)qoO zZKAbABFz8iBSdm57>==$17G(=;JS9}Tvvo{J2;879GA;J93P=p;EV(}t9AiD7y6B`?|Bk9t6;dqKNy-}1h0k+HFKqCbfOfF(!iU# z-6ld+Gt|x;6QRc7`Q;^6JDtE|^NrvF2nr3q9DIr4H-Hxz&Yk21C>S4Ha3^`8@|Zix z>A|h!OOSw^i_%5ld|Jju>^0yr@P&h`-s{2n*lj8zT>`ETy`}zVLtqm;dfWukWiouI zrD`^4BdrU^Pl6u;=VQ9s@*K~%6&r~Pp8NSfLQx(GZl1T1;6?&#=r?54+6kNL#lE$} zz4N6K2`T^4?#G=CWeAasGvRnULrd&1K(S=M2j0|8F&8avs!v0kkOv>(2wN~DLzze0 zO7QQv*?wi88-pTuxp6PYF$sd4oA9lE`{tU_3}iG{{kki_^GpHmX)gX#h_f!MBMmF(YUq0-c#4>o~PTg2Ej-5VZ$C zpN7EYnR7UD!EIX^O*^RK7`xd`5ZK0Y7kDWgupbwI?*nJ#E|;Oum+TOD1!QP3^bL=d zFF4vK7hG^0Hd5OJ4ROKIaxOSpJ6v!)f(&u!)rZ?M|F8bBhLk1XGuj5=oM`Y7Y8P-u zj*o7;gL5F_quXBKteRI4iD91m_D=yH#ZEv1UR2&ff@$EK1MUEy4}K~_{Vn)PaQQPF ze5AV*+!rkLzu%DHkV$Z|?6vZB+2j+A5HH6~z$4&t*By@2!AF8KL+61{1LqX&(w3P2 z7eFBQ58>d$Ze)&&H?X)ev?n}{GWmcA;>}kK5SY9 z-V2;1##3w;1!u{YLw^c5XI5{5=Tkq#U&{Ou1WO>`jEGOeSAw%m?1lbDa2DWK@SWf+ z0H2jfLZ z8KGs+-vQ36d1U5tM!LyB_?%)w)hbtl0&c)Cl@)_p;EZLP1j5LP)_egvrwT8H)l4mj$hyD~} zXWswVLH~OKf;mXQNh6nL<{JkuL%$H51JwHeaiFd71Mp&FziCWH3|}(q;AQY2uB zxxQx|^oRZ$=u5uCF%sPE8W;Yq0R9*7-O!hdoc2F16j}#&Ai)77;AM9%xUGUh@U$<+ z1(zJ!x!`E+zt~p%`?}9S0$xVnpkp&6Zv*cFea;!VaA_UvhJFP4oVp#P{g`o3B~vpr z5(zjD;0ma9P#^jepnnoVoe4e(T<$}{(G8s4yZnVjE~U;lj{6~jbv)t(jwgUGfgMgh zxg<-+==L#pI}&U$j_*H#ZRj?%M3U^a017bPtz*y;Prj`XDj7mvkmnrNMIee1@8{WoVsO$+Y)opdI0`~;3~03QQGob__`+d7^G{b|QI_CdPuH1U7Dq4ysraLi@&Ii|$_g1&WJ48F)X z-U>edvzXRds?Uxb6S?$?Ho@-nB@!$%CI0yYjw`j(I^F_(+UK%QI|5!MWZyaN52%EpmyWqVpxiO^%U?*ej`;>-br_;!zVT=sbE82A==18w zH!7`Tynz{W)-m7N%!VQ9Md9F%1?!maghow?4@%t~uWjuHSHBW}hKM^K#={VY%r}r= zj&blJc!A-!oWL=6P$U)D*Z)u?SYRCYK7r$|;Kk5qsJRuxhPoc~lN^iR%EH6^e+vwC z&`7(3(wcneY>D@PAA&vyt`ESi;|<`cUyciw8PVn7(p|OvSB2xn5OhES`7<03fp-Dt zOljs(LqU&rCWH5ZKKWSiA>b!t{^5o~5Rq@``hzo;-r!Lrs1&5K5&}L3oV}wpxE+Y< zfzL2@D#uPBI9OS$z#7^EJ`08G^sJF)UmKLo*EB;eF)Cinqx&WI+Hn;8@rmnwaw zjjp`zp`Qk>jaS+q*K%yA!w-h|xgioTL;Qh}4&clXe~`r5;hIo)=yO&be(=Q4{|7+8 zR?XMytf8C~4YjR;cHmLik!x5us)5e}XWcgfpCUZ;KZd9u1T&C;B_0l*4=&?IIQU** z;ny1K9^ltQ-xh#NIrCvhszCcc*K(`_uH`I20uE49;lM^>Hu(0V4nmgrD?+;sZ|C>l z`qp~@0=8bRgxC>{KQH8VYl&N-#C%uOmY6>~)C&3>F`tm`;Qe-qLBK}DrITKUbLqr7 z;L6Dm6`@t@7EtiNEd)JqtAldDq98azR?I>4*Q$IO#x!= z69|^V0UwpNkk;ozWF2rhEeZ!0z(H6}^HpiagYRH}J?yhl>)W?7|1W_+W?JFkGMhE@ z8w?$RKJOK|%$BxCOUyeSz7K5e%*06A#q0a_&oO*51l?iiTx4i0xHU8sd>ZsCLcce7 z9Gs1`>v8Oa{?{6UMM%I5)dOD&-WCojgKq~v3H%_2*qz|a5cda^f-^%ORFd+C?q}-k zY|MHqVPN5-)jr^L!8u}H0iFrYs~ z+X!9_`fb7A2WJ6dy&?Dr0)}*4;L^siY<4OPO#{yWXI;(%&jsg?V<0;jT zxk(T(N2_6In&EtBV}>!rS2kuD&Q~_(7|v}t`GHIPnIpa|QeYC4NQRELBwHFX+SC=A z)$b~DmGW!KMTU0(FFuz0`X2;A$*}_AyedZb>cGOGcPa*=JaASGuYUR9d}jP8^ozhb zK=~m&%>TDT&|Is=@hW!+JQJK(IXlrDx5NaBT$-Lp|YAGmDg!qt-F z1iNKyB?L^s?y<&j_Ksr1*)7)_&ThHUaCXZr%8&ja;p@n02@-HT*ap7C7}^8A)9C*S zzT4xJ$RXM&;$GsIInU;!H*a_wy6C?dM&;9(r5(F&q zeMnFpoDLR(rx`;pgV!~D19$^tpD(Rt2*1oXXy%A-t+g_SK8B%8W9SF)EO2I2zDjm| zjhtq&9cZMyd~=Su7o5GUR!3ho&0HnZc-cs|L!bG~5&h$h$c-v!6}x?*x5mVz9&eni zf(#Xua}H<`!#UfI8qVP$Zg}5N0C|=4dmSdu3T~xsje;OINg&S|!DoT9>Su!I8~zCR ze8ZmyFEo6u=e}(%F@g_}pvdrV!B-moJ9x3->76v98x3y_ULt&`j{-~94T2pe0UK$l z;cP3FKGcwMV7xfdBUOF_xU5!AYHTCkMPj>Hg;6%+Kboex*1qGY+yR_XTM}xN! z;uYCOh*xAAp^32Xe$a^WZgHmPzJ1k&fFXJW37Q!GJa{X^*MfI2`~&bVhJOp*UAUD0 zX#4sdf?g&;dX_fS0fuwxU?aq-Ll?A_T4+O@Ivf+B;NP`|gD4!Z5y|Ik!QG<=k0ZeX!(RknWcUW~rH1ndxom{^172NXCPe(nuVX?K zg7+~T6vF`<(GTF;jpLNgTCkml*8|@TUjFXVX%Or)3C;ySVE91rBZiL!uVluFzkydz z<}r7l2#$9l;^0+;1l`bx*tqtAb2j!k9L!I4;9d+|UKhDv@BSjN^F`qD?4r;l;Dze| zIPd0oWt_3|FTsQil;QXp4oY$B(F(l98CnIouyY>xS>XAe`{9-SzF%Tj4H=dT>&vj5 z`lAjOay1Ue(2%I9i=q^Lz()n%On!htODD}C9J9b9W;*aJc&_1_!K2D!j+5f=A&46X zY^c?dQEn?>%g!{MJ)svkA5rnA=|(1T>6WbjNf2;lmbVRak`g$_dBq~|8i)j+?kxjP z2WK^JH2PtX^272D2-1*%4R0?vM>URuhl~SGjH;JuRk8p%m|?X7XC&Uh^`^Vhlh8is8IK%>ieGctKkLF8R=5`Ag(z2?RBfp`XB4f^$a(Z>+Y1 za~S7i#l7I1Q}71u05}WKqB@4<)cqPdhMKp44GibxB-3zCX0pK;Ye`A80rUJ z_a}`U>o^Cz6*wc&4m>+qKjs=i&<6sBs2cb%a8}Jt$mn?EfImq;4V(qwicSGI3#=;(_OK`(Ijg2mv&z$IYeSPni0+!r|XzYP#ffqapPQK1bB(zcY~J(E|tUtFGEmf z5_|!E2wd_Pj$7q6-#5YtGD^-*Q}i;N-LwyQXbQfOuwM^@fCCV}WiiPZ;BJ2oDmHZ zE>$|nC+!V%Z$W37ublFaq%Z1WkMY@1XR>HxaoDE(N zd?@sD!8ya}4L%Z_wcHhayz-;_j5raPfCPMK&6!D_alo0(G~-~o40^r*v%p!f#o%+2 z>`SNNj3D1Q;0$7calmLUF%CGHT$o+V_Lz8snfH5^OXMa=^D32W*ce z#sS;!PGg_#eXsB^XfZ@n;b5O}uo=9}IQRtoh;hInA@x^nhqPZC9j7|DRPl|W8T|%B zX%Mgxajk+_yEHzV{_mT z!?~Mqq~Y9sI7a!==hNJ-IKd>~_Qpwu4~64thK~iGVfbY5IZ0gVd?o}1NdnnT2)@AZ z#o&t!Uk<+1@D1S04FACM(B_R`4-%|5{2=%i!z-Vpy?ndj^}u%;-Wq(j@X+R2_gx{_ zXA<-VKVbM!@FRwg1+VnmxX`9({}%A-M|tq?UWB0TQ9(%f26z+0w}H1Zd^dOp!w-UY zF}zBu`1b>3cO&3N?p}s-pIKIxX-f+JD zu*Gn`FR|TlzF)D^aD5*`9)#>R0=~ep&v3r*almkSLnO4JBZl*hl1hiiCG`Tnfl}Rb z-~QP>_{vIMlYp&aeoaH<=IO<};3)&p$&8aOE$OEuozde-ZL#uLuH86JDdC%>}_k77V=!UIfm^ z1K)tJG`!kbzLCn47-J{K+umhx%o_yW_HG2{4Fzv|OTp_QLtJM#1kUY^yjx8>qP>82 zaJL$BnMT07)rjG|TODRN?^g4`>6mw`v%py}-mNYOT;k6h@ose)60l^vTis$D@Mdy1 zI44-VnLGf_s{9TUyF=h%0_W?$0;YnMe%BCj#jDwqCC)e2L^UEQ>V{aWxz?-^Z#)00{$*+(a z2YjZSXB_Z39PCTx;g7;uLT`z~ilDf$-2FIEM0GbSV;W zsN@j09-JBa4gG_i9g=s=bs=DgK7oTwa7Jh|c=w}*g27eb zxyH`3;A4!PM^myjbWNqHWW4p5fIPq1Z{uhWFF%PuY1PP_B9VD8S%P3DWGoA`-Ju`zTP^fQe9zreE$Uk*F*bYv)oi^onRh?oSa5zT3?;TvEmQaib1 zU7WUH-dkI=NZn~@jf_i>h$33xOyGUP&05&jyr%i2FK($=K4U; z1Om>E#~4GL9nSzi75bbVFEVz@C&%E-C@06IflK_EQ_hZET`d6}aCV#l&Wv()+#Q?_ z!t7Yu%1CgQn3Llv;9*KA{>xXN=RnW^CFA}4B5+ReIBQ-BUKjeDHE#jua{qKw;B9W?%Rg%fc{Q!E=Kc9x!);2xqNS1V`M0+z6O8^n4$9wXNCrV+YF5|yls!; z2d=Ade`Sd4@Kc8s<@!NT{BGi<-Z>p(jUt*c?%o>(d1Swi;GExFPyU{Amk}z&F;Z<| zhtITFkTVQtq|Q}7xcu9}j7VRTp<9FFrmhr^ADAIl#bwZ!78Q;Mdn7jJNfU^JGvfRx z^8MiKWGui!aCR~lV7cKez$U|)pU;%X$~z@Liu@B2un+K~$d!6%4KPFeC~|$n`BCI{ z;LIpLihLfp4hAwX@T16sA*hcC@uSGsgR`^pqsVuHGo$<{a)GhKk0L*3?38~Ld7TmP zqsX5c&W|Gh4BikKgy5A^}Uxk0Or;r(=E; zc{(`9KYkQ>0XQ#ZQE6m;7+DD}f9k-@k0QSb0qd9_MgAC^b;*w+|6n*jikxzRMuPhM zC~`e;UI@xRirfwY)+IlR+#Q@5;zyA$HJl$sz8aj4`BCIs!0DJDMZPx%0jq!?MScRD zRltuTuL5UA`BCI8#tuJ<{FSl8k0Kui_un!L2S18jrjW(E?)qD2b>vN4!+CqHQ)!qnbCFN)%s|J=y~@U*_iv^ih@^&!ZFfEj8A-UFPDTZ4}PXQS%?ek(W|-I?G8;2h|3gohimCm~=R z_dtRb;H=9&;9Cs86nvNAmx2ER&bl83UcDb~%vhIWAUL(3hKL!u0sKtEZvwvvoEiNa z_(*U%j)UI>-T?CtcQ*vHAz&5U5B?-LGx`wtE9HiCBw7IeuCenZ_&0_>8-u|0*Amn5 zi{K5xS@$c!&je?qdmX$VI2+xY;8z>|4tQ)T1a!O|f(OCr_*3xb!P)4(1m6VCM)xiF z*Whe)W#9*u#~kbUzYtU%ppjr*{sG?1@XEck`<-ccb?`pmtou6PSAuI*O8;vF!9)m{ zq2}N-4bKFB1e_V|1pWdz9iIih9-LKkuIGMXW+w!!f?h~)5S)#!KX~fJ#|$9S?goKp zfYZ(u;N1+5f)5fNu0KpL4uTtyfOUT(_)Ks%y2;=Rz*(|s;L8lZ3w#T>_znKuYzX#1 zK*#gI{{&~Fn-AXj5{(2K-9N#z!MU0KDeykvtg`2OiGM!<83h6BY#9>VZ1`&MdklXA z{GZ^A&?fL#z}dD+z&FPrV2(b5;0wb)2R{JLjP3!icBw{!j`x8#2WJ)k44wlXW2k?F zUYYM@85O6-<3j8~8Hm>&I6>_!2EZG_0 zjScSx-UXZ)jRY?9|4SgC-3nA0zPBvjXraI5YGZ_$}aU zbWeca2hOT_2K*^-RzXp3@$b7|F$B!%3MANW47~>agE6!L{G>q|2|CyU-rVqQ;O7j& z{GWCI2?UoR0UO;e@EgHdvc2GU8~!7Bp>g~R_$u(mI{rELI|Ls7&Z_wo z{5x<~!B^mwuFyy@qu+x!5FXk;4gCy3XC$DZ!{Gf5uh>U>%~-=v29JTW?(2X*3NCF< z`(I-SUV?xbY6uFa(^9 zZZP;5aMtk%@V|kxDz5>bYxoV|i(^J`GX$%_S@*YrzYos3ybJtmaAxRU@WX~b2%a`# ze27H(i_wok&;|lJeiHm#a8}K8;Fp233SI`!17}88gU?8|6Laezc-$Cz8+?V~+rYOP z{wetP;H>+vz^jZLA4<%D?)$)H{@)A&mh5LFINR{U;JM%|amBvchOP&vg0s=p z0e`}C-~QR?8beTw1Z;FI!Arnd$L+!QfV0t^34Yk{bHLL_iDNmue&~M}K+qNf)_s5Q z^T1h`gTV)ZGeaZ5#~FSN_%v{4^oG9T-*>+UAfV%$k>D9{R?ThTZ-BE3?gHNl&Wzp* zUS{k(2wwF{%>QZVF$h{-sUaeN68v1lp98-foOS;)_)Xw!bgRK*Hp9;Z-wV!+o&)|z;1Yj2z5s%H zQ4J9rU4QV7;H-kd;C;ZE(GlPyjh$=2Cm(Ca*Z&O=%so~h{ATcH48IM09XRX$F7VI6 z+34;C{{@@{dr)|o|JNFwT;j)&AQPM=eiFPVI2}I+J_?+T?q%?);B0iO!RL?0{GShp z*Fo?!5-_B1gRcf>-ERXgG5k~TJ%)b;{u}ryn18tMAxOJgBf&?mKZCafXNC@gpKW-> z{@M%rgEONigGa&H80*9!xCH{%S!3|~!C7Z5!Jh_ag1r{k}{3xtR34@37o1WS>Cq5Bzp130e{hrvGp zr{jvU3(;TJzXPY^lfm8C@-`IwyE+h@a#Rqme~rOAfODvB34Q@MBh()Ja&TtoOz;VY zpEE%G`FR+#mb}a7Jh__*>u{F-L&!0%zo|0pA~kfH}PZf-2XRhbTni zX7DD4-v)k$;dg=e0cQd31-}Zs{98f~LU1z#%+O=tvkZR{{Bdwb?m6(6!Rh#A@Xg?e zT+FS8;426ix^>{cgEMq*gVz|B+|9Ouw*Y5`J_XM<{HwtI^M51w9tp;Pvjjhb-v-V` zcNlywI3ri_Vr^TC3_ltCRnLb??J}ozAb1Z6=(sWX*Whe)Ey4c;XXM&n9Cr5(&l;~0 z;?_=X9X-!*Zs8mN{y&>(4L|E*-8#AmoHcWSB~uf&T-188{k=dlvi^a0J~g2Vaq7UoIGHA$Z+5*aE)J@DIS>0;l8Bz~!eJ zv4@m1Hzw3<2M56GqQtD%)RkIg2duCL3Pq(&M++ z2ExPE%8pun-4p-y%s8uxoXI0CJdEyRYUn`v1fxvFH&9t&Mn)|!a*(A;U4c- z!Rvu@ulT!38Ir2xX7SHWg0MGRBKBg$Rv4Z)eA)S5aFWE%ajx7^SD zx*Gv^!RH#zP2^+1nIZO?TfiA=ZrA@iI5Wg5en@zjdr`pM>x+zo0hb=X?%C!xu1bzX zRP_DOw-cPb?>g|(qx{rRJ2yeF`=}uB+b&JazBQ*=&$QLa4p@R#;2b9yiL;IVeV2y8 zvvwgk$EU}Yw<`v(j<)jL2@3qG>c^I>(fsf#OuuWvnIG1`cEcICZ@@V?v(p?h`fnxY zCsbO220O=`UJn6pA6T+G4QKCr z6ucH9&Cd5s;>F21^@p#7m;qs5+XT*Xu=8&RXIJ3+8ebc}9TlDXn#PG0{bh1sktrDy zP|^9&mo6NRKSbY;b|pj{_M3wj_X<4b z^4h9|75WSeu>~`JuYj}fcZQ*?3F@F2^CvcdH=)mZV10g&WM3K@Yv4-=c>Q37{$d>W zW(iEmI4oCrU2A|>YPPVN;Iuzb>{Lp;lb6#tHg%mQp@>QD2j>XS7(Hn?D`6%0DF`;p z{4O{fJ!7;>`O!Hhd)qx7zybcB;4Cq(EH8mG(&euwy=fejzn)|qWa3)4-{|x8q$(SdBgEH}nt;=B)Yrb- z|EI4hZNR9rn~o6xh0}E5{*n`ip$LQ=*s|VCZbOge;{N3=ww4=S2>V5_!%N!Y z6Xb_g|IsG3&+(CM?nmV@R~;E;8#-(fFhg}Vt07hy3)Tjl9hq&kD>yGvY}A(|acNuZ z9pfNi6|gtmW;om2TySQHZSDzhMwD&tWpHLRv^hWhc>@BD;hcAEH=Lc|Yj8SdoBI_! z4H0E;s`|D@j`rF68Vi^5J4XQ<_321JLu|a~g0lo{yaNp9n`R>n=bLHQgNxtb-|=O< zX%O&g!&ls9gEOQzqL)2p9PkyoXN{fmckaM>@fcK7{QF+B!5HF8fZL5BzSQ?6I2$it z4*ZYN=bL6njD5bDc5-Zs)(t~C8zpN5&gzSMUEIB%c$a^NJR|FVn|e&SHrYglNWXj_dP-?_7qSgQk6yFTw| zgm~@XcreQF_j1GiT)S!Ssy=%M$BDV%jP&Oi01Lqx(f>$BIr5?-g%by^V(4?GN&6px zv&J~Ad};JKto*7xaZya3C#1ipndT_T!Rj>d@=Qz1_3bqqoE?ILXJ2skXpX`o3_qM) z$na33cJ&g?1QS;u7;Zjd5pZriXAO)5XXcs>)GE%u5mk&S4kL5}^clIXqJO+d_Yv+3 z>9&Uagf1GYfR5e!n$Zl@4;^F}&QM3d*(6vsgAHdDUkhG7{a|%Wg@7gCwPv2-td1q% zc(mqN9h(j3h`bNHB?>mwM<|AA09ZJUIzi}e6z+Rj?!8(C{C&J>;91+0XW${l{nUR! zd8D#>VMOav&|FR}1s-g+rq=R*E3_~B2Z&V%y{}#OLon*&Hgqt>@mx$Cs z|04*V8w&T0W!Q(>CODpTI)VN&J2AIJ_|fX!4VPo#+9*GLzIg~RClni0(oLvpoZdT?yUoF=JuHkoeuqCIKZXA zodf-q$pwzN3xYuEIP)(d=S*-J5|kw;aJPXUGL9<;-qhv8ah3+c-2?q%V`ov|Bjls> zM({ck#PQHF6(QX!+(*c{;lXq+E-Ie~efeFA2b0^x{=~q%ocbw8^i(U+`6l_RnV#Au zwob}v5dIzOImAa;9+IB*aIni7xk7ljs9vZ3N+B2z{fqC@rVcX`l~uTSP_L&}4@&EOdmm2=JEQ}E)OlKBt8TsE$Xume6CA0pC+G@co!~G z;ew`i!bSe>N0MBB172YGkjphj^9}zm^cNU@gX+tx)unKN%8A2JWLGk;23}|kH4D6{ zOEU#H9r}xmeh&DOz{ABuBQgMjr6$2O;L$IWGc*M}{#7z(B|raw2AnhR`+|PDbF+@A z2!HWh1VI#nsOHD5053i^fymwg&$veoErI?n@KSKr^e^C%*~d7RG&ST38@5&zLXZzb z%|+m^*^zrSK@_|Tc%k9_!QGr>2cy8F;IuOlym-!Ebn-yK-yz7jPYsp9@dEPul{2F+ z(hztt^f!aY=O!0m4|r)gSO3mWHbRN>H31FPyh6E~mu#ptcodwW?gm~A&Wv6Xcr!N( zZHv8ZOamk+{ku9?h7#PJm^WK`=VGKQM!H-)C0zlYvG^P;ty(6<4CZDhN@|XGQht8FEadV zI2aEH9G4G*PcV+t(zckRQ-h$Hn`9E?AVC%)k%bKP7ap!$^);j9SAge% zN1%W36peJzDXL%WxzFvy#KbvLFL&tazHsWh09H!>s@f$e*R%9G3083PutK;mRvfv+ zNbR<&)zWZ^{fN}=8%>=7tG|P%?N(lfrDY%Ma24JKZ{SVjPw#Dp@pd-!^Y^KK8g5m3 z$)9r3i~Z@#eC#ne7?Q6QR(dpGR>pYn@!+ggUuu7upJ4bM;CY7667CC-cH=0qFSVUj zU)?_x5~RC~B5i)3Ay_-Tq#|ng3k@P;N@hmlzg&x-wyr_@zT-0o5aMw?HS}XPJ|MYeuMaqj2(lPR9%nJ(V zsvv^8ya@@)3YBvLd@p$EJmtA4*<;jyRJlV7Tn1k9uyVGo_28v{ALYyM9CNf?1imig z=x`;t7utgaSr4e8LR9|G(4S=Lm>2WkQI&iObr^OcGhs(INrt29l^UXwXH<}f60{J0 zbZVx${{Nj$z;lF$0+_12B=DxL5WOP;Q&-0zC^dpfCvf2PLz}23|B!=??qTr48p=yi zm5fC3GHujo>*ZT(Vjn@k(fkD%%5MY*mq3|l@zrd%%n$Pfm zpr5b$N55WL=_)l;VCu4N;PO#~SCePcZJxyUe;FrAxADU|G4}qc51t_R`M@7=-}y)uap&f+MuWH;na7xsQL!6#Dp_-wDP5f zw*@aU{NlvG0{L2Gc0o>qljyldqW(rtQSaL2nT_$M6%3a)VXWHXF#79)T!X5Mt>G~s?pC^9&>3% zumlMj82%b~hT-pkXBz%Fc$VS&g@^b}^>KVK!R+OAnh6rV8rmI;C&3w0?#%4 zg1}{Bc9B(kZ;RJl@3HY27@P7#RH#YM>({{xwdtSKS`x(LN6Bv5y1bo{G z_!lSO-yP*`(5&?I+fhLhubN1oFN0)bJ)N$n^Yk=WPdA5C-#f=>?Yf>)n{pJTsG)rD z+#cYH-9Lr<*u*Q|7|2iH&jfR^6-ZWkNwPU!2$wX_WVMlO9n2L~QqE9+0XtbE)J_)k zzXf-O|D?R9%Qu3Bi{meMtxM)#(L zrmDqATr4~c|4(SvGZ4`c(2uuL{oW|j&ETbm->=>t*V9rxy{4zF;nevnCOu6}R)Wc2 z!HdBe)w+pYQn-}1dg>NVvEJ8eB+86(RJboksUH~Rh@u=ff){_Lyf8?eyA?bSoYT|$ zVc)e&&g3HHwOyJKn0#eG%tA06CKVctsj0FAUP7@hYpYoca0?_M^uAKE^B02r4EzFOXWrDNX;vsj2>jQ?d%+X{ypq zPXqLHm7Z=6r_M9R`6klTMKBVxDxL_up>s`iau`L?knA-ii<@LSkt}MG9SYuJ)yE%y zcyA)y4?U&lYePzdw@mOd@Velgz|$hh`dz^@4DY5q=CX|7d?bh%-beWHu0#IU8ji>P z+Z?_CQP_ziqc?(=2JWwL=xYC$q0$~&vWPL1(NlRGe9{RrGy{$cp&ugZ{WGLR5HO^3 zk)Y(*1fu^iOJMjD;AMuhYTO0?TQ%Vdn`Q*48<%1D({PYw_;bRKR|Wr9L?aj6=*#b1 zJp5liRSgHlaPa@NYKnUuziM3XWyKN(g3ZvFoVG)G&Ip*ResBBR^>5B*t2e<$qZ z8~$Ysg84@9?Fk%|LBA0C)sdk?C(!>h=r?u6W>lzhoenawjYd!%f)c~)fbTH85qPQL z%>$P&5SoH95-XJtDt`c(i3G(a!IvoUM#EV(C5CrObpEFd(A~qSVL!1NuB)HP)I^TF z${MiCgE%&h;%`)(p;9*$nMv!T4JZ|SZs4+vT1D?iG?jCYz)snJVFzQ%OWd7mitap&WBK^2@iJdj@+thHUgej zS$QF{Hyk_y{XA87H!E-FG9bu+;65bCNLNF7n5`{MOfQt6uhP?7dip?5U+U?naEhhe zpjj+wsTPWnMK;L2rX8`}l^M=Fu*s9DDfgtG_c8_ur0!*KS%Qp3k3Ql5}|ch+c{2_S27{Ur>AMvB z|E!?(RQ`Y6K)e4>jP~Vxd)VlvuLhJu|BvtlX8)f&DBB7BA_APh7cTR@#NAKkq>ujp zD-%cH%x2=`@X~LLd(Nhy?eN0cRPydGi5az%D}j5_rWyUygMLGo(Ljg&(u!KBY}!F( z%JnoHy_DB>8ELrYLU2jq#iw!_kMh1F@Ey@4&hHTltCH}|0b#oEFe#}a_hxeNLAl?w z;O)$U9hPl=D7rj__pd!CqAPM5G+!Q6>$>ihCc&AW)&<_c%}?}rzFVEd(iJ&%WA6pl z#JLPDDiiDx?z54Gi#abGe+KxzFgZ5_{ z^0$s*`hsZ<9gh-TTQXF*WWTMu;;)dX`_YzRSF)& z^7Bv-+|{plAm@XB2%cYUNFaPJ_XBuJXLY;_bzWO+`i$l;l#MHLM3AA*o=ihl75)tFHfx4hfSU3TU-X;n_YL|FBcmO`OSZ{& zDj)MS2nIk9>7N|)E5Y;pJ}x z!LRZ^Ni7FsxR)tohoO%Q^b+rj#HJFR8u}@B?>!sF*M>0Mh8)bD!6}x7oH_MM&&3$ zlYJjNZ_y=zN5Q`Z&#yf!aIS}?+{Ccf^8b<`lnv9cmIgiNT7t*@CPq0Tu-KI;V}0ab z^22~`zFBJ+ign5sbOJVv zwh-i=J18XJZm6E*Cu{VJg4DUIz%v@i))YBP;ov6lymPgo79*o~dmcK$Bl52nlA?HF z#3w92mLp|ZLc3KKYHJfy#!hJ2q>*$3KS#i~*aK2rj=S7_95XuLzxYeGxRU$mkvv= z#n-@#`$mK1JOu4+@UlUd3YW`N8e;MV1kpA_k`nv^{zC)p36Ef=*J!dvqIC6`pr020 zFF$Ppet%6JD>0zCOTeRpwKb&qNN31@V<5=;cXEg(dLFJTcR{0g%i!RIP5wdfqB-c^ zDC1M$(YD$}(olPEko(^Uk|P@a@7xaXGXL`*aztTgzjApZ@W{|0VC_}DMay2{c`f6o zm4n!wn%KWernH^IDb@>GvoF>GQ_Jn#FyZNb-&SscCPNKOhW?}f)wb2Jii#frAK5|e zNQH#sdGLO9FA9H;%2fWk@|ZjOQ%x`j4oZ+<@a;W<=Fh6{c7hk5@7sh7YUl(9!M_{Y zGw|7XY*Fi0Eq>mRXy6&)|MHDg@S=Ns6OvJ#<7!7Q2vyk^Dp_;;ghX*9oe18wb#kok z1b1`1$)gq*fPXkn%U+7+R|K9nT-zOU@TT&ZJFA;k+0}6TH4;R+YuhS8tbQe5rktZ= zjVW68tgp4T=A*4N2hV*>Gg=5c+29R3`Po!U=cdB(2ndS&kKM>Y2YHE!Yve(~Oo)GK zt@-@`$$HmG2?J2^E0I9jfiHr7R#|d>{|#R98HPaQ_kHj`SE~K4u(Mxz%*`68HF0A- zm8ASl3+|Rj11N)`THwVMbp&MqTM73ARulskZxGK4Jl)O8yfN63DS9}%2Rrz~CI0w# zPPN!j*p6<}F{Tva5#U8_wO_{3Q?94}{wsoJ7WD6={*T(~3Nf=-3Z8eNR$2+lRIFUC zrOmZ+SlAsR@H5<1SO{XFexZYd817K}HKexv*BPBJlbCvo>;6PglVZ@RI4n0*EViH-JYr=nxnIp8@_`t)77- z{QooLzsDdLf_A7QgmY^=4_&$h8bv=Om;GDtlGio396S$$ySKFL`QDWr^={KxO^^2o ze|N$t)Dk@RTdfO@PG>2<&=pP9`9gl>kk0i)f}-0m3m}5v4kKTDb>PL|fAKsNB?gVS z|Gj28(!&3pyAQnhBrSdhs&}8f!6d88?!YN}PYZQdNIST=(@qh1-dP$F_W3uJ$6Vxo z%`)5DP9!Lt8V$B-=m+rJ)p}9kw58HCjbY?RjcplnbSil6`&#WB7Q2x5@dZ0(HqZ}( zqNpFXoVya0aXWZ)sFolLk$8am-z7)xAK)1;t3EUIJb3YP~kf@Pl>g~vcazM?OO1%OOnTZ*^jVRM$@(sXBBAG$3t4@&H{H|B#(~$!KV(_ z;!i+RxeYv{igv3E@C5j(0h(*xV?VE4HjR9o8(fwlj&C7>drT`_rOtf}p8udW_9z_e z*K$<3LkHDaW?I@Jm<>5Be?LCcpi$l6B^MfT2E}szkye1c|l0|O8CG0@Zogzw6}Y5 zAF2;t7#?gLT{7wj-focgQ9d9WsJynzTco`z4}I?1#M(EdCESj5*Uah>JfDNRgL{Sh zYx^QhOtO)$dC-4kllqCDq=J{h(}qR^h%0uh!1MQM74l;7uJQ}r^t<(1-Lk5t_!J59 zwu}fM4YQeFz}wI45%_;oRKL=l4Dl)cU($+-&Pu++?gXCq_GKYSsU~!nfEW4~mE?$2 zP{GyU#nq8zc)A7rp|)Cut5n_PE04Jat9u6Y4iYRx0@qhVpO4V50Kf5^ z!Byb-6~+c0h5khFqDQnp6?)!9{+kEE@+=L}R4wwycL^H7vw(73pc zYTONto4~V5lcxi-z{@6T*3wYKh2W*@v=;fG;U(~lxb{nqK<_Azxx!j{70Q6){~$q0 z!Pr3ZQN#*=*CN(yuSGu-mz&n$Wev6Y($1yemBwgus8d-TTm@e8hp)REj#koS2%=|b z$=ILnrGs9$nxgWa2ajK>C1zc`30}My`Y6CRiG^?H)E|2o;!`T?^ssUj%~vgnydS`F zuT*oa^ESf$&10ci6zU26q6e=I2I6YQ4ffnuZPPK(aCcrCWFNLumD{Nin-7gF|F*mw zX)RRaS@6il1%ANZbJinUSVSo5Td2JW{hYogyh-v*q z`nxhDoH0wwoNwlK*9s3YTC10bA~e29;PL8XLXL`%uj$nPU1L<(NCgS<&vXdMLlwQG ze7L*;t&`d~3~dxasD$+efuw?Og`xb;$sPV%@HiSV1M-KKFZ~|9z7}`7F&N_YwYhL# zzOP5<^_6q&T=2r$8mRF@2B0z z$;GemlUb*KBaeRye^}I?|7jQ&U#J4%0eL-)1=U&LuY%cb5?4!dH;zdZV8gx0R~1D^ zO+veuJbckB|D@t-He|eLzKwp1vc76)Geq5+$n9xfuN@$Fb6}K1@Bd8h+~pnozZKWX z^_FK~wr>UIv{~A!lP4eYrtwzf(R;lu^_E=Mm2|XdIq`e zI9fhT6J8>Zw!|9lkjKca9GM2>$JYPKM_|cYrJcgw2QGcRt-BUQGeUf;3i8TZ`Zpsf z89VYl3xA~MASpSwpoOyJiF={PtS5EJAL8-jZR}86Bfn84u{!^r5FWyU4v!!zwliKI zS6s(sm=ejaFx)1h-&S09Ih-Fe!^fsRp}fDRH#`ngKEMkf#>9;0U}ExajD<0!5_l;Q z`jLag1{z1QzLsOyk@XU3r}qbwr%HME3KI;khtLX9-6Q1jUy%*`jD>~d_8tsLit?|4 z%bU^nqF*ix)*3~P(11DC++`HC@aEAYM!r^#*5G5TUncjj!Ge?Ikd%BLj&fTmJ#rIo zvEViqL?`1|+(+JqJf|)4-*EE5474wnvmp9E zHcZ!TAP+CAhJ zbM$b4-1jK-n-Kd|a}oLIQ0tO;Zs@*LD6s%0JbNp$?x&pb^&?r|%C2@|v9-hN@?qqu z2hc=4Qw`3+>A{jACq>o#$57*de@cw_-V$g;6V{<*jpEv6=0)jfG3h%T`I&^ zE?@-^T#|Z{$C#Zg zc4!p2{}XgbP|pk_-vbt#^!pOIuNGoiCl%$rHL{?FUK#dMB)$-1C^&|{k|#=eSH%?h z%MaYGJ2jA@T}FnCnzfy-c&AfKa%%>B6=#>bg3Fr#+V$0n5*(%BtdRV`)!f$q%EU(Q z@T42NE9Q{ZZl4;ZHN<5`QJ;6omo--%Eh=9dqp=X5MV5arqw@!r|6U7* zm|(w3el?k`D=ch|dWBz7lS)n+R|=>P?WiNUT3SVcu^OAn*;32PH*wrKQFHW8h#pE_ zln9FO_O892KQQPNTn9 zS)AyEDH~=x1s1`~#1PEAFsoG}w@!N1`N+GcT?gq%?%M%7%=irj4~qCGZ+|DTLgIxk z+Q29svY0$p6PvXZJM=brvG=^x( z{p6vCF?Y-g5tLlVZWnLtz6SZS!dfy~H|#@?#Wq!-x|VU&d<&{Kb*YKDZF6>;wem|06X81JhcSts!iUF+&940^=Xz~+g1MA40S%Wk|yvh_$ZawGq@)7cT_2n07u9?}tvmnIlFE$$}@CvlV(K7%D!X<=O2O(G9d-l>5Q3D7&wk-y!hv#y_8 zME?=5DXvCv^g2o;ZeX7HSaTn_`vro?$Kd*f+mv<>Bu3BnQ zPkvKjX7de)DRf12Va@m7K+U&npkT168JtLockgMhi;{8$R-f7A(bnFfd4=5FV(GL5k_z zPaar_ToI-If#k!QE0@US)p+w>7Wj%GOWCY2gWTjjd_e9$G(c;Jsefhr;s6Vp@4|ZV8naiDJXv9+t{@uX&lU1%Y4>;D@+v%JSM++Q zHhHvzH*2<$yos7C?r!wRye@4xD=b`t8PXW-is_2$wD}w*+!L_TqQo-t_%VgR{ ziM$zk>>CWf*@N^noad5^VI#<|)JTh(2U+l01DxwQ!3GwShd1YFl3>=V<$Z z#ZJX_TqP(GeFhrMO7tgr>Q8XN&Rff&u}#{&F15%nr+M=Za`zD|(#r~Zr4$!D0E>CMia2S*X&R`&tP$Q<1r?!Hp6jur8 zB^E@xy9)i^f%fa<;YC9<_A%GT$YUA9G>_5~adPoB8Ze&t-pDV3hiqL-h%=H0RoaRD zin(em&i^Jn5!!^1ao9j5^3U612&Qsg$|65Ve*Ke9T0w1g?F{*$v@_C0-`1wfN9npEgiY43hyvkm@XobHlB>{m zHzKsDU$m$Eai^nh*sQHX$WPt{-VSz&iR7tI)F{YUw>eyMSYTa52%BMii9D9y(JD+t zt|brm^A6rFa^E}*p3OOXlss->L#7`ptSnWYWkI4V(wB+6>yb(4_wPoY9PM?WOYUr7`*g?*@|!cVG-*RVS91~h_Pl)lcoBvE+>hbi zOsB0T48fy=Yi`QS7^8+e8l!n_?m%CL({uFh^mn@!ZJ zP1J3myf5uE*Ix2y2~4LL^&d0*<55zN%pU>v^a2Z7uglV;a|Q}B-hn6D*6F6f3ChL7Bviq|I(l2@tMRSQ1HEtevb7E1RQ5!))NNQPc|)E5JcLO>Xl(7}J1yI9+X)TcsV_Uy|~Q zC-td7InxWVM}=3zhsmQz*irJ@u~Ql=r33H9=#?kvD9Fg=8}2ou8oJ*U#0&CVv$2@^ZI&i@W@Ui=yOt zDvEb>0ob9Xvl8e@Abk)knWR-s{dMYL(-YizA zO70AU#SSgbB2O(tvN8t`{Uz7gHrtzRr&7Mme;?Q$C;KqZD2k$iDC`#Rkozn2(8R|M zZDj+6o+qx7gatnfEA+PmSCGpt%BQvHgYakbyWn8*2I0F!>3 zORi$%XbHqfZFVGwJZ~xRa^$nf!+cKDrpK0%|GgO*!WjB7xICihkNCBz=m0CkhIH2+ zNa}xuI3>Au@c^%j3&qgUms)0P$ysc;GI=OJ8cvdDk|*Y={k4pRXmPaAiv5|SINuv#THhG7WD22_LGOz zk1)wklop&KkKNTva}%^T$bIUUYvf1%U;Qb!4jxK`d+Pu1Qcpw4^$|t8PH^?hjGkVs zV5{Fjk)M?QS6=%h7fewu`ICm=bIrw2GBeZYev@df6yndf6z;S=6}IHLf1 zK83t#CW5UJ_a3v!efDTAXm-LY$mgfsT(X`#HL;JBm&0o^*lrf=E`_Ll3hj#H;JgX(;SOhiu$jC2gPd*;HYVAp!5dXcNP`Q!Ak@3z%evz5=|%a(2E!dGyR5= zJL(4j<;P*elgPvRw7GP;tBd7Rrlvwa5Su(g9(xrdWK!`4Bi{k?CNe%&TrIy<4p8Fg zK`g(Qsqq&hk#YV1z7_n4wSpzoH@W%_;{CFJ(=k=ZW3PD=SxfRz7PwhVdy$LEGJ534 zM+fARFLmJf77UcR;4&ee#GLW7UNM;`C!wYV#JY*9ZgZ+2)S$=&;1%>xDXA2FHS z@n>sLtGN85*1>tIKn-D!sQji@r=@AD(|fGy`wq5*v;rZ%pnM?hsLNMDKB}yb4Sr$G zL^ba&?;5$N3Zsm%B{#u4Zq-4$4Ih`C>f~YE&MF*}^{r<6fRC z{$y6z)B!vBNi=1yX~2ifU>4NZBg^w-mJ7Zwi}jwY=|WUsJBL^;zQ~&(E|Mqj^X8{w zn_*vrr5J?8Y`!|VZE=t}_;-TW7jLGWtL)AS?#@wKh0O}XA`9|nmdi5rmai(JX-`93rF?w(5H0CWMTLwl+FJQS zv$Xr_N~!`KAT~sVa~T8fvZ*HI;ZbmiL;E_B+sUC?(wyh-LmoTZU-LMp^JwxwS?D); zYli0H#nO3824A9##mCeV?8BSn@dE>(lYBdQstjT!$zb@3JWNPk9T&_0Q>ud(K8Uf zF^fqAJSgTrk5qn%vv8FxQ29aZ#4IS!{(ekF8>V&Eq!K6FVe;rZaEOnCa-KXi4-F^i zki6S4J9g!?mwIGwJk5fNvOqQbL0V$EofQHj;lLz2)RlZu7}M-mT0EHC>4sGzK|YDx zU-CcGPaUy5EelHKmA8`dP{!;_-e!el3(R|)1v|;7b7SCVhkhitYGYL~>E#-^?_nfy zvu<14dBl<^jhG3ur!{1OS}&7tqu~Hu+KSx2-8)~pOI}0D?;Y7ecjX6mXc*QXUpw?}t-5+)wD6JSYRFcm<%)fgbz9`s$5X6UZhV%O zU(b;FgWNfbkTEe?>|>}a&(Jdiai`?UAJNG}wH}Lep;u%Ueq)7p)x3uy6(YS0 z%l6BjvUP{D1L4VD# zf28|W;S1K=SHs)w%epvE;mCm^viB7~K`#Rv;Z=)9HzW5wh~9+grS{|^=G`3(lU%R1 zv%IVA!;}y4g)%hpOCF6Q$GGGVk-KS+fjvpy;S!deF_eD?ypu@e zLXkf&Nczv!W zX32k*JT=0*Gu}e(9K>{T^Fh%!-$+$<>x_9PedriFQRRBR>=oul0x&@>v#0lHMe;WLKHfo{P5H0+ zIJ?OpuaKt_-nsu_B&WDc4LexeIPEI*LGrJ%RvD4&XZcW~pt<#Wz2A{Rv2zzkM+vO41R zafZ`!ayN=4Aj*cfkoOy!rOAGd^B(f}enfVvA}X9Dx0{WSppFnO8@|Yb*zeo`vEibh znkR4S$!{vN`gqS)luflK|MQNHx{WbtNemz#zb#vnL)@Z_Cx0{Tu7V)Bn|AMVL~{{& z*vc%K^EQQ2?=n-d`=5}9cVN)XiLQg>-L1~L6aUbxpUFexXfBQUCo;*(EZ4QvXRy^7 z1@~FBsS0`MRc~B0B~NBy9+)i9IdZI2X1Sc9EROM&R;gmpcOUs%w_vFl%VwS;5C4ME zj?>B&iS?p`*LJ=eXB)R)DdY7UT{?^rkWj}|p{>R`8i&`6#H}_*; zC$o3$$$k6LJ1CVu#77?LoOX0T-Xj4$tEhh#cu*9}&DN@)ERGfyn+6`hrZhl1R*+j$ zy&c_5Zujsu{1tiXHgGeG&yv^gs5&IK9g}F;O%{aLdUtW9zfjY=s+gblii-x4Bc-%6 z-&%B0-{ds0O66#+Hg%6AkI$#Sn8v1=n!&~Ln_7E9w@uV_EXL#-){Gs;@oI>}w~0L5 z54j@Ami8I>N04fx0_t5NMb@fdeD|ly@ z&8AwAM{jGd$p=MI(3w0`3=U2)6o!$q=W*1bLCViQ8gp`s*tG9U9W`6b2m9;^6Xn0Q;-)9tm%ecxm0aABc*LL2hoIbAeK z7C=E)BY$g-1|haIlKlJ-SW<_461cnu-VR+$u;3|HNHm9uM$ud3@vS4#a9uRKkv#M| zd}!0R3G(F8?pn|x|C!txrrMQzEI$jbvtXKenH%&Admk*0-{+l{t;j$86S?>GqNq^# ze~_QXJ;+_u)06VC_PLtqdD2{d9VrXcv2f~(g}Q)aEvB=AKMO8(nI{%Ts+U)LCKgwF zD@#|a#P+`>FXh7HHR;&%Y-Ul~J5>Ind~6>^I;FJx!b-PtL6VjnBS z>R`+g7ApKmUNw%GI7;~|f{RQmYsg2Fho-^xN%AS={#W3Eo^<__Kx$5~;p^n#J~)hyQoh&$c*g&z+KH8r$MmdFO%Zd9+S%}D$fH|voSb4$7Lg|ws=cnf$XOl*Z;_`aW9Wi(`9=Jmw&HEV@*DMNf=Jkl4DG5ar3Euk_KxX2z>4`K@Y0VRsv; z3!+s}qjlt1RhiOzvR>dkwnAo2984bP+v5GGCGID`uMkG44f&Jgp@Z0A`njYmC%499 zY|K7>3wS5-YrSq-#XnS(lm%)wCAl-CKg4A!diW7E{7^|$sPZ)@L9mhfCM`{EMkaD9 zK%yPFdj&@_ak{cU`Hr-oh8a&D7=p1i(fpLrf1tNkY*O!X@Sym;6Eevpn(_fF#M9o0 z@Ev)Q)6OgszmvPaAb2c}VWDqeSc1ppA?mM1p42}GBBRVib1N43>$_Uip~W4@V^@*d z%xW`?Jp2f_37#qB#YbU`%%$YjLQ?oWI7ZVk!Rpt>7#wP2X>(26{E!D~uy@Sx~+6Mdc~6Q=q+WGd9bik+fQo|jy& zz@dc@WCN=y@5CVQl7C7bPc!T^d1|kcmyMbnmG@ivq(@oxO&0mz_O2}T$-{mGmcwyx zPwvjZTsImWqcJ#|63$2W=*|cF!G;IPqo1H96G`*QV?X!Rf+jFtC-;~2I%f;H?*%%6 zPCEcD6MG#@_b>}ivO;2gj&2}DQ*Mw?KiEO@w+o=7#lFL^f0nj(-X^(r)j6aMqo*Bt zqJ~OyGUSb~2D2dk3MPN5G8%Y*Jodmq4a^jIhFrXfeCcCHmy@S9VnvBVjaX~=^P@HK zDT8hK-wqZy3!o@KMMo9aQ{faPtP}lp)i@=tlZUrs)WW({zLDfGY)^DYmjmRr$s4D= zM)nT!FYZOeo4n+L%lC;)MV}MJplLiSJXIU{3LTg3B=;Rh!%;T8l)U<34BoTc6Rsg| zkoE*of;?4A872oQ!07me1=dvrdV+K6I(cHCx8d^NBRUdkzZ%v`auprcy1}}OetPt7 z^3WB8w;m+fzQ|$0l*-6DZ_={I$&2y+HSBqXc#}LCN8CF!V6)^ZSwtHkS#XgPpOJ^g zft$pdlpObY?#|Xt4&@QkpKPGpM7VSUdBGoGS<*L1%g0Njr)A0AOBgJZ3L23Az~7ts zl7_V>58OGTxJF@GFg((`j$HPqu-uMd+hJnn8Ohb=+U7mUL#Xd{$|vI9nA~bO-|l8n z{!4QI3m6Hr#GQnGxrweiQH#QS`EW5Sgwjrdl{f;2r23=bB<*NKZWV{4^b#aB-c9bF z^k%pma(_4Fzz5`ijG3t{h;@LXq%2aOXUKi?a`gXCWavNQZSwDbLD%17Ci_rwbw(@1 zeTz9P`C7^AJaCLP{gq&fO;c`?-^JUgX^<#!6sE^AkssoeuSV{S9jd$JXAhc_`+9oE zs1LaOeFYy1jISoL!iq+i6{R>G=a7dML0(TI+0+~4)(zxFrSk||&Zc;M&KefqWW7WLX~O1ERsInU+5QX?UH!tS(2o4Y04CXS zI%I(4c*oWKMxs74o=K@e@^-bnneYYjz%0yvi=KIp{5!k=NK9srcaq;{L(eG=RRUb5 z;O*Xp__QogyIec%?txo>;+PMG>!WPo4)TySLX!YZ??@g@`>DMFRf~nF0GFC+*Mk*8 zd>@WeN!JtO$lcq#yR?wvY9jYoLJ4O_j;>;H8Tf$QcfmW)_L18QaqNc<%3tqLTxqOO z=omU*Im_$iijnHK%WU14#ddtSZZM?(6`~EfH5wg>XP}@Td7>FIhgrVHORloJdl!=L zlhiYl@}abMAVnsh*QoV<1;xJk=Bg-2}M|CyD2eWnYvw2Z3m)tpskqJ{> zh&QkgAVTk?K2+Dplxy0r?Q-Yjq<7>VR9;17~JX=h~SlKTdY z(So1WgZwh`L^I6iL|*Xq*BEpJwtndD*& z=D$OWBjky+-SK+OwTj4|#+k)>?4Y3a0cKx}LG_K{W7%^m{*65IdrXecifCn`_|MV< zdgoAHeUm9H@HV zVO~C{HU)3!2IPe`zDLbZMcb$-#$Rj=ksl@>{ygT*?KI#rdAuk(6sLT?Uuf{dYAof> z!A~ESjVx#?=Xpbx+a=*joBI5c>yt-3oHRR~{*+IK=)nAF$R#h_5w1T?Ju}JUyAM?%iYL2O>uN)N@R7m7)EOkfFnL$OX;i z?oy9vO(E*CApfuMls^Xv(Y#HoV&sByRDBj(<6T_=AuU8}@>Oa1>TYtEm+4bw(9XT& zk7UD9E7|;9@-u1A+pN%BM6NW=ELmYQgItV-{-aUuGsl^8FVTI69N0U@O6g*Cz zIPc9cOUbRSaIXo9kH}MxK;8uLUh-na)NGJRb2A(M#WcW&3eda|7s)$4-bqWE^Kki2 z!$V@CH=~p$kF|HTd{qA{giT&Vzln@z#S6*8=BhxanvN9t>gSHSlDT*~h&(*ayC5?<3DR!>AeLjhfn$tK1svpgNlQ?+tLRSrEPj!(iTP(udr?4LfLy z9nFm#Ybj^kWENYzVb5mqO!Cww?BSy1FOsin(p8f~I0-EAEUYCSs3pBVw6^pgdR~Yl68l)qaKSB4`LmUvRW(hP!$Y# zjMeTY?{gV;Oedd6F8Cs?6!|>zco^;#`BAU}e27R)b~P~v-WyrLy$kjUrine|(Ke7z z>RLklB)MJ-$}9n)KmLS$;y0Kd-HbRf?y5+>dBfeh+9L%~yA65r0}OkJ&G#XXPk|o6 zW*#*BC-5lLh-Wnyk+H4h%~#7Pl=vPtnc&_)9{!LMn@aacu5G#%HqmF|sFD8%lf+`@ zE=F=%WtMAE_#ABgbwhjIi@rtBnM&kur2X7rJ;il8xPuab`&?bcc&QJ0BJIlIICB5( zoUQEm4D#p%jJD05zd-Kt!PWpeCf)=OiXSU=(1_27iEXTKqzCeo*$5vXcN)NBCI=_U z?HS(m@h5qVPmuZ9QR{c*D)V`;K5zZrpmafuG0&Z=gdC zZOwNcVc|MGp@&gZncUw>9g^4l_ig3PSrGmO7PxGnSL8ybOc^;Wj;`}Y?Zc+pHjIIp zB2SY)$jw6=+V?iOvl;y|{oP95CGAnU{gP`(MfpbUaa44i72Sm31n2Ete5fsT$=5$4F9CU;9?M9s7j7wC!Z zXu$Bw&9{v=0Xf`~T)TKhK zl3Z{4)Z5V=KBrkV6;(a$8?yEWf zkBCgn$}G}#GG*-&Lv(>zC!UpDMT#glR&%pxFQvTr7=wwKDa3n`oGj_n9V`y>Erlj) z9wU$Kzzhko7gtm>@`PzL?T-11mtfk_G!vST$IBqFO>}kzm*=eSLBEV0!&zZiOK&oo zMDA4Xr@Inh@I6JI;K@Lj9bG{luyDv~)wsBd;b|J1llzMyoZ@V$2YI*w?7xO&pn+!O7nATbGEFu4$`2OUZ{=u7ixqMd*U4)# zC1RHbXbB&?ut0HnXQ5xeZcYdnEs5on53S18#Khr7@K<`K&8Cl`E7#ZUe{czuz0 z69F1!!zoq>@54-TSs_nkT}L?qOaBGeM0>J;)ogNycUu@&`pDx05F|F`dywCfc6(3` zdAR%_-Ef@EKL{@OeZ#Q$ng*U=g=BxY*sQV3$nEalhCd{q&mS_$WdmQ6i?qkc&udO0 z5!v1`vq+PhM)z*$HiK5`Dx4E)fy*{=8e2bdpp*1nTNZB~(OK*3z_{&8?kt6AM%_5_ z=b9nUmf!@NN$!sg)OyUkSVaDFeXK_(*z0ZJBSfOOH_rFU0<|F2O}pTBgoKthahcqC2>!6y%M#b&h4?yH>m#p49(xSj>^$0%2fjcIn*+gtn(Nmevr37+>9SG}*YjS{iz=%t`P4jGByarsRx#?yI&Lsfe98f%80hVCe97Wo_Y z1@e1W$y(&0h*v(7JigSMPX~j`Jt}XgG{YHSh3#oqaA!%bR|>y(rC3GzKRP4wkFlel zlOG6S$orLsWk<*@z1gh!?@wf$WkKj9rk2BzE*$ASQ_kS3H(>a!X%A*+lK<8Vy8sNY zd~B0kq}|dx%J5x7b%zoK(XWTd2Q`77$-rW!<{~n1W@gD?#8fW8%*H;hA-CJPx>}r- zHL3BHc$oyLTq$3F%zgZd6duf z#wp)|eDegHx!uoIu^V}E-Vo@a{0MSK?+InJxGb2=f-=c$O%{_sLB8=dgoAqv3RaT) zuEXLa<#&)<`G#p?;{03kqw6v6zf>JnM^qP0g}65jW!%I>3N@do6*1gJCC%lf;i=xZ zZ6>)&m(i(%AkQJ_qPSfB^o){RA5kU~-1=}VLsS%BizZEGd6_)5m05!gtRlDf zVcU_^%?PoFJo*LYIgw71$EFQH1wR%2#ezhI9Ie8pqAEfqWcezDR&Z&c0t%XuH!F)R zR38RcyGZq(a)R|?ag3KY?xnhW$x{uzcFZ8RFL_t0#pDltiiyA6f}&OA@g|TrnRch- zG6QCd8L>4u=2HUlTKT2Y}1tl(d@-CbNP&9;w-EpPnU8CDG9+ z8(3o+h+tep476S3{x7_N_M_&kEFx=rWfmEIp0d#wp*z6hqIv0r128H~UW(kG7t_rw zWsS(Kis(yhm!T5`*RIY$0trAKxzmUhJbgKj4H8>{s{kKF%2Wwet&KfH6GFUJ0X0^s$@ z#8=gbHzpgjJUN-WdqN7RbSx4@>tYW`}JY&n?|DP&Q zKFK)GZ)GYMK(sFU`9eqZuf0#?9Ad9xmQd@>0$($nO=B;02*+j8<$ z+O^Yn!R1R4LWl%YVFxSJ?CN#LVe;ueVH}pw9jD2yI^4vOi-Iscai2HRDv;ZEx>7PI z{_p+`9}D8E;BS-6yP67}uyHqeFPHqQ2_1BkRAd$A5d+8hB>6jh=gdkrTrg67pv)u{^q*jzLa^Ug-a9q@_gWTbZYH9ti@j@(x=M{`^ME5sAzZTcfP=23pN3G5CmwzU%CN#EHq>xB+1L)0#79KaGO#H#kD0Lt_~&2^IXs(Hjpg~)Q%;| z+rpCMeW)n$wYQ_=$-}!b#v#f-pttOKreo*+Jf&`bI7^q0qhF%rP6cc%1o?a9fg?y0 zE(7Ej~+9h4{vB-YQ~|p8=OAt-nHOhFMUk82l3c7~2WMOOp@z6iLB6s$Gjb z_7T#r!;ao*_%qZ`zdPiW4ym*(N4g(l|9%!ED&C{J5-X1$O(*v~fx~oj#`S6PP}+@J zi^+eVjS%lf53L~&yogASDfKGSzGi_x?dbQc;h(@0DQ>JTk$-y@o>)N3iWZ0G_HV?3 z<3s;NJ@NvNV2FEgJ!m5N?JCmZ+|wFYcVdN9+B<_rMP?3{`FARd0}mqL%v7CEZdHP# zY_|Und8{SUyy5GNeBrTLGQoarlUz;7Fkf%Ui6M?^c@cSPxI8O#j+O82052EIKx+l$ zSz~3B^9H=^HUO_go~oOpfsc(fC(lFU#W01@I8DjR(GpCc^sAUp`R#trGxS&f zE&>azC$W^+CWDZN`d}j4?9g%Yp%;+3&lkf`hwjBIKHvbnK#A?1^skuGD*LMzB` z_n|XpifsbV7S-#*suOJZ7%S9Gd+*m}a`z+n(QN9h$nyR&yy}#KGejPoAc?d6yU5Q+ zFiobGMmzn;?SgbR<;NR6e`1=L{>~zQZW(e;Z64*n0G=(}v}XxcvO=H|M%g5ZE#!MA zW$B)2nX8M#433-RzKx7l_V?D(w7Wd)*6&)7HS3Yvzp#1Ax0BrZ|2%Hi z9r7|Azl?ckHaO#`D6k64NPYjePPM4ckF^ zXRJDUlI{E1z;`Tg$9gC9InzKh1dh2~y>uCPBId$#RyDL-mHgB~$R~<`XOXW>cF>@q zN_>v|uO|zV6W|GB@%`j4Ou+K;J!Ag`^3xX(8sll%8;a{mwwn@9R6tXMY2r_kE1w7- zeDW9hZycwcAdGZM6h6$R6lFQT-6f4u-(45H%J(TN!#kEdc?Sl=Oqj>WYw?U%6J1MQt0WiKvENO~B}08yk;mI1d?o{n?UKt(D}SAB z#zG)Q$6;1T1ikA=iacBfXYS1Ukx`CO;~<`G4qi3#*h84ve)8tz<=S%aFmHtDZWL`m z1vOdJ=U(#gaD<=5jt0r&RWPUlHt>?+zan+GT8ms5$)o?hpH>atb{0H&I9rSUnSmMy zOodJu8khWx;(G9|QbJUr1iMzeJbYp&;1iSP>ye-5)BI!DwY$la-7$Dhbrj^1S6YUi z;TTH(jyt&go%O5mQi@R%Wrf7Mm|;HhkI3y^UVgyH7ssB``1~Syzkd)lrJ0N})Q>!< z?ca2@4%dF6jkfi_LJZb5s~0a5q(FQJ z#@PheEOLi^53%BNlIyFwlf8kxit>S6*y>}~KOzrRL429O-bWrx^v6taIJ(DK;4a0e zC+VD<<(U5xFdkV^hvHNP+hC? z0;>wX+S;gm(?|q2$#1&z{k)z3o;7`SG5uof%rE5DorpY#e!5AXe=z*Fm-59c!&ocr zRe9CGWv+dMis+pdtg!Va7PztoqWt~j&WG@t>F6`$tp<5Jw3uA{u1+_} zs0@`tSKnkoAk)>rV#C|X^JHNdr;#VgW3$n)nS&Q2CGVHpXcQ?K$Sl{SEsOmXknv3v4>Hy2fje~e zgSuL9Hj672#VLkY=&wcO$*bP#0&Z_>!A;PP?c zj}hwTK=e6QaAMv~`x}z$oYs6HR5MlVr2MF~*JvCfx4WUEM*m52OE1InK*?rL&$3`l z+J&{e)#0HJkK!^xUs_O;-1-1Pk))ox3{SgxsSml+1ktM(H5FhJA{Qpf+!A7WY9e5M%zY<|InEA7hVd-uxX>T;8eU@(rLCJO7@knX{QS?MvQS zkRT77fY~Oar^sX9B6G*7u|!P_U*J}+*|j1~CQGlkWN|VJ#R+<)8+o|9*JPJGIu1$B z$7aToC;m4|lK}Zd@>kj;H%%vh4!onVzC*)N4(ke5NN$6DaaPzyE=nPu!{i4gk5s=< zr%dn|C5ooML7F_k^QocgtXd16vG<`R)8)$KzBoK-F>SS0T#i|C8%%WB<8E4BMCweD z`J^8!r}CnkDYi9<-1;5)#4J4X46lLw6QI&p$pe3TcMKns`|Ek-4{Od&{9%;x_dRQ{ z6E`GR8_@~7kVBZ>MX}oOMB6FtwPej&s8E?a@q>3P+DNWXI5eB61?N(KPsk4u4T_-G zud*OOMX5vH;Czle&bPTl8GY->ed91C&C2z8WYSc5#W<<|1plN|&-%zr=6<~jx51p$ zNi6a{`m_=G->cEPT=uRTx#;6+;$tuRlRNwcuMp)Q0GAn~1pI<(@;z6oK<`nPvTCds za|&bVeIt?arTNz6TgpD%wUch(y9~7R8+mdAW{5*G@~*^R**_bM+S^Usnaz19JIh!#7!wD2Z_Jv!}J|!9#&0menY| z*_M1~Z+Q6*o{1hn?r#hO1U;I2g=hWM&ks(Q@wbG6HTWK|No;T}`KS7g3_>&|-%UQK zHHKsi`BC!Jrx?N{4LVQ0^IVpeyj&a=^3~S{$wxXKb3o{tDkzXYxQA=*QIv|?$;I>V zjM+AKl3eYmPVpK9!%qyQ{1N`zF>;&`_mjs?s~Az|MA*|13zDn2l#wq{T&08HCQ4Wj zdUumwlE(vHQ+_4SIE$$fD-2t1kPH5{o{uKp+JJ*R(|g!fAH1w^zVwcM2U&pExea1f z!DC{havHgN%$r1?Ax{?a&bZ~|fdQBhW(I8}x31^v&W73LFTsb1POGCy&d6le<~mX$Hb*6Wi}Y9{L4w&H)hjMHa|v zd8X<=!P%5@pMrA73@v%GF*!REBTw!3?rL_EcS*a`|1kL%{1wQzsOKtpS#jeUX3IcM z+hVuNpw%(eOny^GE}_9*hj%7-KERgKVa*ZbHg_foI$}C`fd}DNlOWzCk0-s`ppU_a zh4n?iunvmte|jroL;Es}z??d#8F#04!c7aqPqsXQHCw6Qcy4Pi!Y^DWpyeUpP3ZI3ohR_{q3-;kqgCpehn$gid) z*${c65N4ahr1pa0L2L?=Oek-F2gR%N(fLQ&$q!i}>UTA<>4Y8R;k)5w6GcbK-S3ds z3-Eq{E9AbkyF2pA=qSau_ndLHqTexBcb13-05p4WQa4DHZet<76@^KA(p1k4@XmB?}Yz?{pdrk>D z<#Tc$k1+h~;0f@c=-0HpMh#hTniYDSgV(2$izWzz#5puzR+x(9ww0qLZOZ$|qmAJ8 zSUD85BOfTbNFaA9A9IcDYZP5Xl=^AeSaSak9qA7^p$5!fH5{Y%J2HSZ>St&#uR zJCApoW}d@3Y))<*kz8-{sw~lVFyh5I$jetaWn(}R^h>^Gu+#r1vZAjQ>@P#^K8S%0 zFj3r2o_G{`%mUVdy!j?f2_OACocx13)oM^e2=kkLb5wy|cotJ6z6~A?FoxbC7weE3 zl2o}SPKk&`A4wsHliczk^kKo>+59p z%TFFUjwxaMJ1A29DQW&hQ(TSiXEPt?ftg3rUeNLs#bOYw1RFph=*wsAH679c7 z9zF&uqrhShxZJ3TMczJdP%2gOax;{E_6FXKc!sArGy=xcced zTIBKX)P_?gC5H}dDGSt&B0Aq2pgmc^KOGjN7$EnP$1Y-E(Jdk7lZTpeuCd`Ld9)ql zQ?=V%{ugI~c*Gll-;z5aG+I;s2Ogj{qn$zRJ7^uEZyLz?C1(| zH|?$bTgk;bOmGwV3C*<%`Hy~))b|ppCjI|?I6)TXZ3Q2Ms=(JF)~X`8zF~>EfLPR` zd~yJWz)X_X9&c&=XQ96yhI)6nGt`=eed14Mb$}wIqxiZY< zIXbfkj*%rGqejXZk9d+e6yPB1xziVl>)&Ont4i55= zJ{{9e{%R5%NU*>e>|GjuAx|EJiZJE#w3ePwt67V3@|&`;OIjdxQ4(?i44g-niqXW8 zre<&wCEN&fn^`)aJXsD)bV9D8>JuTqHVFCq61}{NJnSNEnDt{Dxj%#hWUCDH>;`Wn z#AggaDmuanP5|8Gg$s)7rTZUBM2Dlx4r^A;gt6901dN#lP07RCaOl9zfSxtdEha$V^aC+PB#Iz-OfW>qeN_;SCiT8eUU_ns)`0mX zUxP{>>gyfR{gSJ27iF>G6l&zg$^TBWLOhtO6`5%MlRSGqqSoBlQSdHUJR6<0wxx+f)e>%01dK&Z$k^~eMDFo*qIcIJ`$t|JJ{GQ3i9wI6f&)-a1f z_>q!VEmiq~HRE}(#W6LLMk4sT)=^a?(q5sOw=LZC*x!qF|IMDYs^n^%!zFVx_tUy8 zB`>#{E7P``BPeh2O=wBVKMpSUfIGc&cwwaE0(tsrwf+;_Zkk)|&9mQ<$Nzhan^b*) zJh^6!ZfF{h!V9)TxBV98eVpB>Nghk_sDWYI6nuo3$0Orftk9MfoF6b2CQ4kxd9o%- z`2cx1=v^(JP+X7EGnBBN@@iaeBr-OeZ@~kUJ)HJqJ15CE)b*x=8{~o07%httRaWK^ zHHwK7XfsZ;n@Fx__jK>?=SMS!_mf;@5hrcYoJ~F`jlWGj1s8PC`u+M}AwB{Riq#E~H&3wO2UbY& z<^sXFeUbc|txz|$BzT7jz8v|{TM-#AQ%@^$>seQ}DD$sh9@nW)dlraM zII&@CD&Is%o_yZBy&FmX))W}%C3-aTOt@;xmvM&?<9DdZInfY&ID_CYfTd;95ya{>oVT`>?MZJvt zVT`@$P%e3@xAzcq3i)$)bd>&=AFNM8%##Hwrp3(ZNiqCk0t*+o+F>fbW9JqqiX4A5A{)SxC@DBAE z^3tR)I?^&;wi6bOI|}x7vG2uT5>7%^dBMhsFr$U zv*wVZ*fzh$!0tmHI>q5)&HE%*VX~4(!X`I9qU4pvjM?T}@MY@wxu|!fHjq0D5ju&o zFykP3ybupa+2$GY7CGqSCZ@k@lG~sM5ek0JncHN6j&Ytqv(c{b zqk>4aVcKGP>P?=0*C%fg50+fBWzAQC5`^$Ia+}}Y*pcWLl&sDvQXMuS*9BTDRl-7ICOPAa^H(^X$buh z&B)!d@TkeVJ;<#eIq4`rQt}EaQHQp`2WCqXIvuWQP@Su35BXZd!7A$6kclkCvEZp+d$&#y4 zna{_^O-9;9c_)YQLKF9shwehdKI%WAIsXq%-j?nGAKW_;`=X_^HIqDa4Ew7vRrex~ zr@bp;Jo&~R-hJ16a(gurp^u61b?_0wEzCuq4QynEp|?TN33m5K@|?x(HF>fM3R2{$ z*(+=t*GcdcI-$lN_zu(7`eY7Lda$xry2SF3>-QwY~+(jEe`v> z0=$t3cZ8w@3pTRCdlg`;IV=Bz;(Dn$`G4Qen{PQcSS$G@=7(vfTrZfH;sMkDtqJ7T zP0UNd_-s$^YXY+!nl~g;a)mtcF-HH%nNF#AS*{%H`*Y-OKWH@(@~+Wpp?6`*ZzH!l zdYyI%t)0c6Yx+;HknD>ZDQl=xvK{K%*l8*NX%Bkkqh1Ifj^)I<3I zcu@GNdc$cBE5znuKG>|Vko; zEJ)4rCZl}4;h`rSWC`QuhUBrET$wr8UC6`7!F_Ca7>?coM0vF_`!Aps7UGKnNN59JSMYluuW4c(h>UMIgGTfh{ zzRu*SBM96m`3Q3RFs7sN=Huky|Dj(2$}a(LBockGk&Ch6_gLZT>o^5qZV5V|xXM+* zvy@mgB1`*Z0$p>B{Ms*wfTLW$3iN}CvHITpQ8|sXPZsk|pZxt{w73cG(6}n#*&_T62E<_lt!05){B7=UO#nGmpQ`eAq`d7iY__VgsT&CI5r@#OwO-iVw5 z9u!j^#x!|>A+dxN5*B=GQ_%*~fQwY)P<{{j7+zoZQ~or$RUY%)q?)VbzNkt~a?SCv zLTQ=l_3D3xJ7CU{dWIL{;>m`)l7~J+N=Q;qFLL`L#>jZ?Uc(oR){?qiwdT!Wf&XnL zQ8o}EKU1r{uCRfF_Xc@%B<7$w1l&aKJH%+Eo&)5gW5}WX3!tYLCD(6-wp(~pVWGkB zgxG+dCd#8iP4eUwSZo1{mgMf2Fd)p1-u-_Zo`_TaUh>#qeQ(pq#|kr9kQnYAiRCjM;Fe}a1`d^^wOw59greFOvrr@!T@Iu}X5C>T|uR zekbMKosO0auzTNw*BAC*XxO21ud#wv9&5YJ4wZ;BiOEYq6^0_?yJ?qh+DfhyMA{E- z-$NcRh$V|bB_@!6o%SQ=)5%2@q$1;w7r?WH6GeZcG<-cP#F~Mdtbc&~r%72_vNYwB zu;ULF=jOrIstm6Xl^zB=5>pXdKAK;T+;;(fOwo_+CD(p$Jb;F~mXA<}j zVSmFz4K51Lu|l)$n0||SCNM^Rk{gTWv||UkGr-lvCjUIrdz~DoBP`x{yEnX31HaJo-?s^wW(MB2VDZ+!ZRI-W{1HlI5GDpxaK9CJBD z-Q~#LkKhC|WowcrZZar1SK1gp81hLr-&=EiGAKBfGEwI9B-?t7JXQdE-xSAtK6zUQ z1Bc`-#B%b$o#;b?dOjjQ)xbN@Ux0TKqC>9kRCQ8a{H|JIP(c|_b{eLh#|5NysSu_ zhBsUmtWyQLYX@1?7w{gioFR95_tTw9aOCp4oVMM()3&Fc-@!#OD(XjWzwgb{_mju*Gho6``8njVJn*RL=yGyr z9*2M(`bcuUt%|?ub=_W8u&1NpsPP1OI4v<;B@cXo5Hqu{%smX{Uq+*gci>N5@^AtE ze51)oZB4_SLYB+A$JO)VKY}2k)L@QOa4RDvyI#?19>|S3=~IL z5Zi>YG?VlUxy1*1!Z1Lj$Wy%P5v_)Tn~|JNa_K8Mij(1Wgp66jYmvu#;$)$ji+7TX zJO~*dN2o7({0O*1K8`$G8IBFHTaSX572-C`T9a{~Rt5Tu=_>OrxSdL@5l~`of&5f* zb-C2vcA{1rrScyrU$QOM?P=`H-{fvPgq_X7DKi>Q@c)M8!gRhKcu?#gh4uMUE(<+a zAzmAbQfy!>`H-FMbyq&GhaNp<)VZ*W7*$Hndlps_6bgcBjou?b=18YR~()Dom_16Yj8&t{1SQM zXV~HZ3u`QF+}8?|Y&>}*aQWE%LR1KG9DA^WyE{jVTI|pm!*B7PJbsvbHD7OBiw!(a zZXbpFO#)vfxxUo-nOae0W~F|ygB6_r*Veg!IaOS7{3h84%WH2!*j?0R11gHtCD{kN z%e|4TKmh>>hzi!4tO5)B%sxa=U>6^spr}E>Dfn6}3er}B4}$d*gAcTd8l^2DS{ENJ zrBs40l!~;Sne!j(jpqB{=Kki)nK@@>&dkldJ2ytdNJoV}0AFufd-MtLDBjDcMt$G; zWU)4u!iJ947y{mTKIxAL{UWlDLPBIOc_Ic2W`ci>D}zg*=tl645^`xSD!LSW0-j2n zj!T7A;M(7;-QWq%CyD--*F!@CKYUUCk(DqBBXG2Rb(hE^1l6 z4H8}N&5>yVXxYKJh-t5mX_DNHobRig9fy%K_Bu6H1QKV!Q}@!yRDGdO9oe1SK%G|Y zmvbKH@@j1KTGD`~t%AJg52PmmK83hT3wx|XJWLNfwjp02L4FCNUUz{f>uMxXPlP=R zu75{%s21J{ep}j|nD@c$X%EvJBi^9}@1;@3*M0J1uP4L16R0nE0q4T-O=h${4}2P2!+k(6 zsnK3zExV2Uxu2+V!c;E}cKjRMc5}A z84w9a4?A zheU#?T4vAp-~OwlvZ5)z^b(&d1eb=+f<)IJY1}Ix)hS*Q zmN`_#7lTK<)CTP`RnzVV?;b<)3Gl}_m+@wfHQu~P^88QWen){r^`d=Hq`yeb7=Z(h zfG4nVVGITIY9`aS52p&XfER(MUa{&a2M@^o`1vfTBSSS3G>ry|ih$R1E-kphYC${X zyK-s$5`~^Sm7X3N9v-yCdhiJT$}%G4#Vq_=By4(`Msx!dy$l{mQUNjpPdfnaJw<&@ zMW!R*;bV|T!5MtMmsjlNVW~L?kGeRQ*H_Uwq$r7jd=WBq6Z2nyIqc;^<*`P|N18W$`9D2l2K_fTw5J^g9$m1C^SzP;dE!qiVj^d&`q0*`)e zZI*AqwT;4HUVbM!M88(*(TlME1`N=Ka4tK_>((eT8oc1o)GU)=*<^727x0rCx;y?L3iuA6KbxpQICi@a1nNOsh18Yeis{JwNav)x29f)UTwyFKv zsP_6X>x6j`cr@)rd6nSp^Ju&e#%0wn1z*FrQO=NG#I5n$`8TmV^At778m*vuX=|XO zYcmz8M(9>>&o*>5c=%1hxn&UtSr)~BI{dL27E-z&pF_U*`!Vl`O)Ah+-vfnm;kt* zCLbcsw}MTxqa7I{FI%Jaotz5~M{z@4jghsG?|glZEK=F`Fu3lbL8yZAHmQgIonxKo zv?AQY;&+f?7k2S#fdvP_y}4FJDXEAzIrcGA6>=;j&qeWek)_b%2KOHPK~xask3>T3 zDr;ODt1=YOk3T6i!EErrSNNqBya9aR8}xhO4KQpm=fZQ^J2XsHMIYdt-kqCGu2xHp zC!wg<7ZiYR!PVm)@W@#T6KcBo7(BI-!i!q@p8yYhNBX^}Xx1&{q2P+Eg#G`2m6rzz z4%`?}O;8FRSWO;^Wy);Y<=~!|Xmsh|A@Ee%{+ElvpL()dDp;%)k)j7whAL_sH6w3k z+r>+GcOtnvhYVNA?}JBgr}EXx;!ALEZ>wX^f(H)~?}9@H@Sny+l_uUs7A-LW8Il>)1%k*>3!bPUJJbT=Ht@(c8nsC>Tl*Eb{u?T|3teVA__CuS6ko(| z2&2=yi-g!S*1-6s;Bx(%g2X+mDT;etR93&mX!JaqTvI4&7^lDybnA) zS_EG1D`nZ=kr42auQW80<5u{p@Eq}tw|iSFe8@L;G$W=vpcbjgfj4&4HYZu}&zlR4TB@WfHFQ(bB81CQ(@b5x)`4t^|c zS3AdTWL(#9iV7*1?;-BeJT_9KtiGHr|Bw&1YmhH;h?a9In$&|QHdv$29pJGHYscCE z-i_`5bdN76g*AI%NupM-(UP{*NO~sP}L%9tcQFO!{Av6{?D|HfmecuchyMS zQdl590iGO7u2%so0e*5CRZX?+QQ|+>Vr#A4D|0E?-g%rxVG?V#f#BZBVOeklHVzeB znouT`M6NshI*bIKj1r%p)l;vsK1K=a@mgr{iM~HW5d-u?+ zb}M}HGBSjhB0j*kAA(2ECle#!hryEvsV!6xKM9^+dATg|-;mE-CS0XHVvCnTw?w(x z+%$I^f=e$=fJApQ^*J5N!r;+s!cwCLdTYVo97f)#1-}D4QEHuN$UGrmuW3fQ~s}M zXT(6U+;^Dg+8S>vVT;69Y$Q*iGDs;&xd--0JUCa%^_u1@I>{+DMFa#Rp@UrGsD z_z*@IqRV*jNZO;Jv%ouZNlyX>EL40yjkg%|FO?iZ8oS|u(RDG z^aDnIeCMae++4OM%XG0FS!OAl*xwuy??@RRIapnfk;h)?F>=^jy4jB%{@QTctN1>p zy6Lu+(V<)(*y||1vUId5@vntE$)#r#ZmpWz{KTKz5neSL`h=VR`+{B72!v zDrA9_ahapc%hmQ6qgiFH>0_-3T;NymqotJIu>`0dBv{#g}(>=xz zHZ9w9vR|I$Y0FL-I$L(qSi!1J87_9cIL$w0IOC6>HeR&x(l?$p-24zYBM$4TO}E`! z!K%*~qGr>-Gu$kE+Q?+%&KSDQ$4>l*+v4+4x{uj-CcCdxp2lZ=YkcNd_mMfOPkEKL zu%`8b@=+x|_PEW=XUPmRn^oDkYkcfVoB4{Zg!Q+ZjhUs~`XSCz1U!yL>i9Ol?e;jB^YFz3!uS}1hY%o$TA%?wtLogAvH zWVboYYBt`%Tdi=OKbxI(m^n7?|8LAZ=9%Zu=zl?Q(zMVu)iWlI<60`H{2hJ#dafmb z+r?}4Gkdu_4(&T`($p)fr;g`Ye6r3%*{2z1KVDNVHI(IMnz=WYS*ubd?DGkDrK+8; zfLcHuthnFLNs!E>3fDc*Q4+ZzIIFY|$;I=9q70FtZoW;_ffe2|JNz7O-ve zc;E2knYjZ?tPb`Gr$Ff0JTq^2X@C62*?nJzkb!Wu!8~z7ZDCFlBrsh4XXE#?A^VDaQ6~6quxKt zsV}2*eHn>)*?KOP6If0-z&@z=SLCQaY4I>;13wLHRH@U&X>Pp}=v4d2W zgxN<8{$ghjUZLKT$FCsxCx`9sRb0d>8~wUV%g1b+PiZ@+v+ElD#l3gVZ<4Y*=d%YJ zd3CjVI@jupC11i0Hu^`pI(HH7+(kGsK7LM<|1vv&yTt4WcZPb^VB*y>nT=Z+;T2b> z1#I`Yi;LLlh`+$m{c0KO&MtPZne6Jv%3A#A*}Gq3Gg`Q^7j9(_@}q4i`=G@?#=dzX zbG7o*d^Ww6pRU=$9^|Jvv8StK5&9ax>s+>X+{L}vcddSRUSccpi!Y_wX*ieqrZ*eb i=D(!(k^P3uv!jz;*XAFkKQ_xR&sSmPz``?%3;qXLROOcd delta 529926 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%0A?oHf=6pKLx!c*+ybM9BcIM@n;P|$kxsl@_ zVXDa>YS7-?4Y8}*BX*#$SbQM8Y;W$N8=$uCV8+Cd{KkK@*6HHaX`NVf zAN6u)^W7SlH?m`%c_41XQuECp^69FmMHeF>T_x4J#9UIRtEk@o)tsW!RUm|w)%nX% zg4hVqw%j}%`(`jC;5HbymgNh_>aH`NFX$)>r_adLaXU)IE_RgFGuzD{U2!Vik)!Y~kLr8Od@HY` z&BPmOR~sp(&3y}F=Yzev2{s#RydQqh?9=90N5rvmt@49DorXb(Ok3rL+WU;TsLseX zIXV$jcYnT1fFyubwx% z4LXWd4@d5!(PT`NwN~Z-ZYDxnC@9*=rhf4Sv}n&0kaIHTZ>% z1(^25D+5~4ex!hY9$I#o5g zDh+hH-PFoW8C7Vn$v$4admm-GDO23#g8uxo<7gx+#;Zr~5o?(D(MY4xPT$RuE*q6( z%O5P(uZk4~eS~4toYPdSa_%&P2AdR*+UvObGwfUc5bAbJU2cZPhO0*k_6?@~U8w6Y zwc`vrW>WkOxQ4;xz2qnlobmuT|J^1&JE@-b zZN7%_YZu?=p(%X~Y)l`gf&wcQ00O|Vd&pH*DjIfisp%dHmX#@XX}?N;%1U*+G)W~V zvr@&fnr9;%{#a9mpFeiO&(SH=%B+-ciffoH$Xw62>l>0D=aoK4BzacoULfV5&RI`( zeq;H5CG1^Cq_v;0w};s?q|kA*GQsynUVr4I{gFLaFbIU;0uMmMif@+ZGK`3wB3P;x zMr=KeMk>lw!w&AqlwE|=%Li~}lJx)i!uR4HfJ#v_wrVr!qRvJzG5@Pi4MkDYw}X30d<9n`<_MF@2I6TufP|!}NNs zxKi4oW^=> z^nv^ZR&o&Wvp13)LEj*Ph#pgp*Ax0Hl`NESk9JEEWMR*^ymhj z^=QCTunOtrqg!pG3U%u<(BbpxVb# zn)od|b56a=D!;q8d|!{XC0`IzPNSL3SOais zZG2)i(1G$wX?^A27_canDW}Z#==qMLo4_JRZ)bN8M|(`7^zw=~eoGcFtGJU}d7wwV z<>-zu$=2eMm}7s$jh!uZ=I0=}sV;CG*Mcm_}$K4)1D ze8Fe|ceBHPsS5bpXB_?)P#nIEHE3>q!zc>zQEup^byT97GDNqS=2ue&mbGMa!rWh3 zNBjoWS$MJNh{rDt#Km7On{FpoSV^NM% zmnrAzusMMOYbu_)`3r$uH?gLo^IY;bN3Q@zWMMLzIh*NPPm3H%%W5f}WUHZgue)0d z;DARQ+z=1}uC^ct{AMtHs}0k0x#@s9K;M19(U0cmpzqJiLC+sV9qIx-o1>T11$yFr zj-CRHusv&T4!Y(*+EWkcSseYjo}#N)>K;dz14f|z=j5O>`)js6m+{=ll0VvPL1~R` zNuLV3Of4SD$2Rd-vUh zsXxYWb<7y9-oVtqit*JMxYja-S`zH(Oua;?`!n@krbhRzgeLRuJ54mv3$ToK9s>yL zzN4r8(|zLzn#RG(Zw9D5d7*#A^zFN<$xRf!ZangfamxB(Nqkb7Lqd_TG%>wwjL>+8 zB!5USW6l|yDjt-&i|;=X*NwA^;oXMKe-V?#rcOnMl8zc!OxBBu-^62N&Y+)SGZBlo zpR}Q@1pIn};9~U`kKVozw7qRf3R5D3+q2ic1MI7#cp0fGvhKoCNOS&s3ZQwDSg9Rg zUp@r}xq?#4h7y=VQ)ok&;$aZd(kXQAA8F(idL5=1?YhoW$f>C^I&W(fB>4$C6{X&5IODFU8vv#s- z2v-!Hd-O%zJD5HAl&Sf&lfFqjpF@*y0-I93@QDlT<_cK!)&)ydx?))meiRI%eG!TW zmSJVG0P9sElqy)(QS}VQc?QQLTS}@AS3&E0%F}RGLSR@b<{7CH_i?5T>S%4)?b9WJ5xsp z^)kV}%hYT_53(P^)KwyBMWoWD{CMtJ4@BX8r-(LY^fy}se<@1lVCgRb2%bO{q7)xz zAvrM%Wk-{%St&u&q7=!}mpgF^YU>D*N@rYaN(TWH0Q=U8uPbvNxrC1DgZ?8ldcpvNheK;Lx4+|~nb$g{n71kqR`W6OU z(`Snc+&!EZKr8~S$`HJwuFUx!6VrtTbU*?TB7yLn1hfvcy@OKPG>qrrCIV|ik%za< z)$9&RLA@c7+nkd~-(!^Wb}25As&rC34GCOVFHvpPNr}}JM{m^AWx(;CE?qNwhPezl z)zhWlb#`%{4UI+&RWEf`dKnD75j!`Jr@&rH@fHp6mV7Mzlc<4Lv7mIS80Ljag0}zbRE^Scx9UoA3quZgzpx>nDv={ z4CGJS`zuC#@c=TM+y*GM3bcdS@iE`%P+!GF>*5tR8a4o}wi_>>A>GJhpz;o@4qXQ+ zThXy0Xr)Snl{#!4LyIAbmm!t|&2cn*h*B3HjJFR_%IgBuTSJs0I($!fK2&kX#|Os* zrI}}a(cLBS46&UCKB5TO$4W2lb`=_&pj>dN#vqB~Sfrx4G@urVip3%#>xjr}m2)`f zD$~S7r7|WUY)M4t){M@wAd0dQmF5;74Ikhzg%Q>!u_+viNT+apiX5gC#VVWlVMmD|Pkl*O2E3<*Yt+HD!-bUg(#sqMIX? z38?>=QA&({|8J^w6e`-#mKX2*b~JsA(!?%>w4>`|l)8pCyl2YOj@-v8H7y+JcML(! zre}Kr(7KnRzGIbvc5pyj_5N7)E4ekd`=GVzKVG?jBcZrhD4L8Dl~#t9-0;>`G+?4a zOhTXI+KQYfDRFjbLrY4Wq--}tapcP=s+y!^8X~#m5=AbPbET@0^m4Lt-Oz&Tnzx{f z$;vPKLPYUXl)upZ1x`g3deVTYN)>(P0$MgzDK8b(Y#9BT6@i3P^DRPYnM!^*nkdQ=K66xaD<g?>%B^76Pg-O4lg8H zGkZh`B8CI2)wM^|@cqEMR=SryiFygza|{3354o`y!&98RL-9Ul&=AFbloruG9il03 zloHjS{lB1jZ{|R^A409*<2kdW_1I0<-zYJ~i$EQ;#|!_lMOtbazTr6ZX4W~V!Xb)& ztJE&#{S$~O>_9Cu0~VRJS-WVGs*6}S75S0jr_eb~Tq!cp&aN8K1^ z`J7+B;*Pp5(()n?)>1Eww$$_Vy8Ay#p3hCP-CgxXG(N%S$-HY%vQ@mLp)pUpd-f!^ zkF(S(qR+gizMN^P?5uBhUoG~l#i?MP%=`Ul!g{0~wAS(|zrNiAwcaL+S6+SGBkHux z(o28ufqHzKWsXko@He&JVJWWf@`y(5uq8lTXs21L3SS|&2!6V*~jzv3a4++#UxarnER!`^=Q(2JLt@S<4m;o8(C-6;{Y?|Wbu zv}t=S>lv-O)zVY%@CZl9ST=F{Vf!r}%zm%^mYodfdB8G7e<_yM9IzzlJI0cGx}~zd zQYvY7Wc%TFMjQ5f#@t`GHKdKXbJ7}qd4Zh1~SZWl{ zcst)Aof)(;vwNde)?UL?(q28a*);t-8k1qM=ri6DWmvqNBER;-)`1x)l6`OKNQPyI z?mg8!WT~8gf;!*f;B4x1$TC|$x}*B_ki}K6@78K(M6g-8~srll|Q>jyyK)q`;^*CjzSMXgqRtD1FlC*h~J!_Y%Y^aqmu%lLJr`7 zCpQ1`J>`2UX>T0GpSCnEf23tyB#>ML`3OxrKzI!NRF;d%_IC(L!H$&L>MXi(+Ok5I zMWfGHnl;w`$AjNk1oPng6Yjx_W;q_%P$%#pB?sVv{*`+$5gs_5wN!Sy`Pe3Y>Sdnq z&)TZ*O=@=5Ql&umiv2Mv{g5V{wbaz7N7A0Nma^Cf^4?j?r12FZx!0_UL(!^Qgr*!i z$nd<63{BgWhG!clwrFlwVO*4x*7z}8OXbbtKUfr6@uqM%NZwjL{ekD(VtaFwsO!bbs$N_b#l-^E}_r>-F0|?wpx9GjrOUDR*{mC4m=8 z{xgAu3j((oWdg^d2nbw-s7xTXx{1KBhn&DIL|`*|p2?z;F0Ia$KEu)>)@&NPawQDS zyG0$?R7R8=;V1bU&87)#@nxOfry13V7_e-fH`u|;x_Wi5JhGR5h4YM+rSog^(#uOK zOTVJh$GTRQX5X*|S9D2f!RS=BNGP~0&o=HV$X0sg+WVE95{}8k76>e(HG{@n`jyVd zmK=!u0#=sn$n>Z|R#pXuPG%N-RTtc>bx4Hl zCdkZx#a&&keBmu7!)Rc0wH|=aw~@*%!xns3R_c}RY}-{R^(wn`6-tfl{=b#F0`n(Q zYF)7Eu)0C_Dp_^5P{IZIE#qXRK7pX2)Y^#3N;T38iHxYCdtg_S8HZRYyL?Tj?V%_! zzm}{9%1`o7G|wlsC7RUlA-%Lc(B*CncMhFK9gB5R&b3GQOBg()I<6LL`L*stA*nGt z@wKjg?Pb*C%5jA}x>ObU)MDWdO8cI!l|NNj)R0oM1G@_hC*h- zyg;+Mham#2CfBv9I{~60q^xG4?=$KoSw+N1B(92!HFMakuEVi4S@a^f@Fv7!ReLGL z9QfbgV*9_*MG0A5*^_VJ@xNjrH*|pw*W7#u>xKMNq*AlC5YE_9VA3U$6mP()?xtrW zZ|ItJA+q7nXkHifE|6_sorgUYlOn?K-(XN&ukb0w>dCPhg>Fp{t0Bj#W<-@p?CK3& z&FG;c@D3UOaq_jj=<7z3i$?i!Pp7l%%$$-+Y8y)%GH4 zd-g4B_^ocRd--8>;%DD8)3>^o!qGT({9D~94SH*$IfsOVLF-+SHMyw^6SQ$`)J>hg ze@zh+Sl75}E@d4PO_#uhyT}&Z)ET_Wbuik-xD`6;u8!@+sk*f6Sad1ZGu&8d3(tBI zyBYQ)%24n=n#qVVqm)bX0LKI)iYl?HJ5VZq0NXi0*sWw$4?~ocY3o;a8}4Z^5x9^)zGX|l*BRvD>h?9(%R_7{n4?+Q_wa0InExGkwm&<)K}q5p1LQ$i!x@P4 z{^?4x0x__nZ@PEj^h|+|;YN(1m$3OTe8#1j?F$qEO~v63njYbhIcQ3~fj+Lue1KRf z9xULl&JX{Ju76h-KeTxOsXN}G?tA`R-FFcv>b~s&Av3L2?E-wR?mvTQKKTN8TitYZ)dRJ!7lsvKmZCZ8q_y=9R zwBCea!v8~gZ9Ne<)iy&ZVSAU?Hkpvj+Ik4A>V8TdudO=eWL-;A;~%2-YZ=_odnQlK zh-!fhCtcn5Lu zevTgX71o5CQ-o^Uafv-D#>8+?Bn!Hy3r#!u$R52ozW`SZM`zlT+7~E3mlAB>VLVPS zec2q|6R__V#feF9$7RDaiQ4}zm z^GUh3W=1!1r|k4ST@8Fx^3FY7+omBA9b8JQ!M4w2kI9z-T5FBY${%~744%1ijm z<$c}S&R3}or>RpDO2E&yh$b5*_3YMiuS^;aL#yG)+=V?HtPqM~BleDDsSk8Iw=G@~ zF1Tn(^fxSk!C>LQzxG~`u>=}BTvP7$zd9pLp! zm&5W3DHr&BWopYf%A`lSA5|AwmB+eB;cOEY`&hRm_##M2?tqs6Y95VyC16{$d>vN~ zi|uBPd|1xPAM11|vulu>)ZS zhSxBA*tysUOpFiNbn(Imt=TJ^u9iH`&$X~RrMd?4U=ekO^(lo;e-6XV?$GHGwy#vT zVB+8~(&-s|$swt$Ls=)mx1!T3xPh8 zt-Pp{XqHm~iRPy>Tr_tYDWaJO(WE#st7+i4sEgCQx#rJ0y)Ui7@X?8*SP{9{h8}pt zR99;Iv$uZM1;}F4pOicI#pZ0+&#;a|m^0?&zhW&*bpEXDXWhg}?VFPXxr?pn=lM{9 zB0;yhn609eV^uVmrV@$>E6^aq@P;Hpx4O-2e;ym08gA0;QbjgCGm&p+1=};1+>|!?^mIdhrB=bI5A0Noo^q^{z>nI-K zB?>O#1?6?|1f`(Is3ms(%7R!%>+hUwGKc^@598eV6BJvQ{HUS!!4nMB69F zS^011lsy}<(BE|pI_@Q1clJ3qSlyoJIT!)Q6_}hZ8eTQ!hRqcwdEXTe$RAE zNIe^$$?7@zOjiPcKBrVlml{B&r|%v$*jK5^WRX<1qIQzIZswk-}dM4U!c7v_viRbLdB%C+p`>J%b}ia&HtNv z4xR;BHBi8z9&<}l&uup0xh`hx$B_>Ggj2Fry$}iXll2oISF7l!iX2n)^SqfuKc`>( zOFt62maPg}wJkqP`We7RztEM(A6Jyp_qjtUv4EVFV$_mS+VXr&)>@)OUY^%d5N&@P zWNTi+&bQTOS6=Eu8}Hz9jKgLpnR!L8p#=1rU*G|3n?Q(Fz35L?=P%tNd?M_#zjSdy z(eTiTIaw~)yTKTpljBR9IOexT8m(Oi^=`s^{?>KC>x+cHmHp&n%UH_ax~by^q4Oo0 z?xAEiY%%e5z5ADFNp1iZmhC9 zc0hW)(glg`&pIfZ;k1juo63aOu|58jEqbNf9QY};Pkz@n1YW_2|7!BjF|ih9y2gTM zEjIZz2E{FG=Ym>yYnLQP#IAkhuA#3E+|p<lVEIlka-ZC~Z2;H1I=-U4&+zUQ?cH-A zB%vW?a)1V&Le!ef8=n7Y!U zjsGhN6HyhdRUH(3u#VNMA~x_WDJEa?qs_RE4Xh%zss6Fj?;K|JWCz<&MT`>G1+wp} zh|O@ax|+La>hWC5H+Zg)wZYzLtEuvBNeB2nr9AEPd{1>MFHL+gd{tWMOHDN2e!Ax_ zhBO40Bgd>hjU2xHbR2-(!`*3HDM$xgFt=5+l5mtinr6Q zV>_#f&HRS@!7m1ZPnoH0pUSJ7fqpEQxMIxcB`!!i>HGiUYVYbwu1dE3XRf~VRJh6j zGPpX3xXjgBSY_nt zx14?JD@Md`RoGd9w=6O{nSh+x$$qT@J2QFy8|=KTAllk~!Up+)ok!K!GC#1h{C}|1 z5>DS%vcid-Q^oADpUjR|b!T>p;D#OS=$Ep-)x`*ZXLcqb-*)LkmJ5FH588t2Vzb!w zkL=5S*95&BU^G26tNYfDblFKaY$k=6wF!t|Q?y256L81PjfRdQ*r>V@$3rsV)ng$6 zVnEdMLdp?%4#q3WQ8{X8>{P=Qj`v*%wd5h=-3ejy{Y9N-KTpJvn^eoJJrcrp`ioJK z7zy+2glG-f}!p%oBu>-7Pb9 z;%7p2DrvOF?U0Mc}Kh;vSLS%aox6Lznj*hWB^ zn)SsQf^em~B_~wuuA)NUH574!GulO=u7XNW_#ORtyXGl75==k92OdSqnN7tpg5Z&8 zx!qiJ<0bF45Pz;#oj4^mTNiX=6mpLhYYIYiq9r6=T<%Jg9ZV1(xcN~1F@;onOg_-I_7sP?ss6MG{lujz zI&k+~65KzV%HHBB;GrJ#RACDIM2-!#3FQdh|_~rs|nzOZIL_eX` zLAmbg2ie6jXydm7a(L|k^BODG7j_+Bt;dS(h1mz#)UjeuTp64{Rvcda{u0$iNO~BV6o7CUq->8P8qkwFXn- zS=MBVSj+!~RertUZjDCQ!iv?mCmS&ZX1CvJ$(4`uD}q;jPo< zUS<0g_k6&wj>eX{CUYQW|ETq^v<@yk%vn275zX#Guwk8~PlzbO=Z3vqQ7|V)g?BAL zn*YLvUBwx}R&@zt^usZL{4^FaL)1y0C+XBua#5mb%2^t?@JXq-BBMz~v<;Xc))Gec zU^8ck!Eu`wb)u2}2NchU%ERkVL6b>;Hp+^7>>b>f>Ag>(eUn3KFW#)=6u=6dVevw$QqF1W)ZI{X}LS8q=3fF5m_ ziy+ZdFNFtD^HSLdNn)RXD?O&T#2jCYf~5=Ln<0=1MV7ls;$lHqHWxSTh#|OJXvr+G zgOHlf<8K!qK-KitFK<$7KBNk!&a=B^016E~)LwYRv|-Rq|Q%Y_V>?;^U+#dWoKj z&xl|$e*p>f%e<}0{0NID{vJK-4_jdvwk|x|VIcY(xypC|TW?2=tr&ty8l~H8;g8t5 zd17lEaz+R6I&SIkfw)m6Ogd`0J%@nvd6twE5&sTu!Gcr8M#AgEEHPE=g4`WD7Rn0BGq>A`FZU`HmF2+}Dipgz%jMDfxFzfiWt_C}uE)Mc(eh{SRQzORE= z+tRy?fo`Fkx_L?lhXa^2X7kHtQ!>TK`F z;yWZ>-Fh)o)w-rK;Tki*G2t2j2tJH9l_%pgi|y5WG~w#X^OM?I)oli_s~g0LX`T$H zBC5fpU#*r+y6{UP$!x;waNJ!cppHU^yiY19z%C>(T19c#Jgr?70|35Q-tF1B$W zySfyX_hbbd#X!NM7rU`h4Dt%-Criz$uF{X>6UYK{MX|by_5nYg1&>EJ)RY~CbJ5@>MMY!REe3hidHPTR#{NMIYbi=8RFw_S|ady*SH zeN=_17)1X*)?JX&^oy{XNuHK2JH!uFUYS$LnrY|sL?wHDc|3WPK4|RC7=PfOxI`S$h)w1UMz-y7h z>!5w&4Po|l)?&Xnjw)mO#m+v()9LI%el8WgIF&u#FB*lLQ(4Oc2ur52xfGU9WzsQ- z=9dD9=BEQ-@%dDyIfxv$X)^OZH;|Kl5IMfnWI+{B1hTnzP+U#?0KL}gKSDfM?jc!3 zZwi~)4}ntPaXl?N2|Yy}Mv7cRb2jI&nD{RhaZOYd@Tu2^OQDEZagWuVx62`HL2}{qV zVRT&|Jb_)=g*lz)Q8WW1+*F82*Q4S!q3$#irBP_Yi-V-o5Zsbu)b?Cil$Wm|#c~8h zmK~Eza}GCJ(Xw=06qWi~;1IjmohT+ja>?F4E=!h-k2T9jVdR4B=4?{FI6`PYja|qW zjb2MCJIryp!}LCYCL;?lIR~v=(>!H&0qR4k%LO1fTG2GOf#^cy7!^&UQ}Lb#Cg;8> zQ|d)*NRdoPg`U_NN`X#b8qL`^MPk2ya-sEk)PhU3#RW*!(Vfbi(j2Alod9WX=#lr_ zNiu3Q6^9HQO*;&-IlF%nBTeXgtotdsUmZFnzE31I{1Wv+2+hyJT(}U{eF^S*Phm{t%M!s)(bV622bKT3r>3d|J%l-pm&x#F6#WR$qgE-aCyA zq7X{hOW|?c-Sv$_^v%DfG6`o8mYe()Yb3#^87^f&e!D7LX>) zuw>lAx>|L{^7yuBZ0YyeX**5Pvb8CL)5YFOEA_baIJ?}`Yw^v&pt%D z0#|!f3HKz}%wis+>~bggx)WUEF>n?WPIva?p(wI#kHtuDrxClkmH7#ho>jAn&1FO# z>yMK&xb}z>)u0p=WMlVNjAzl0QNg}av7QW-BTI(Degx7YnUa}K@DV5Y?;l0_a4e@b zz6|&aW!NOcys?W;>6)J^arzRRCF8Ghf^Ry(($B!jlyOEl!JC}m5+}I9FXB?B`WYNu z`2~D%$p2RdG!T$#fn3{KC-{3OxK=rE=F2#vo#3rbu+0f>`~>*vGX7L2c%Kve)Cq3) z8>sPn0t)9;K=}@6_3w_%E`U_2a4ZLuIBcH>sVsLr; zIX1FBkgNalIo#`&8SLuEQUG&(Aubf!Co%I2aR$C*%Z;n%OR)()K+E9~PVg2PzWP#( zb7Z&p3#cNRj?$j#4|Vctx^YcZ94OGmpn99Jdsv_p1?NP(Z*A(kamS4mQL+zUiitxA_#Ilzlj zLx8-HMkR%K=T^=(o}Q!59w5)K2dkvIxU+&&!c-_Uot;ogU8vzIf)qzCv4cazc2xXI|=YM@V+(Ua6bQDBQ& z>fnH@Rgw6dp;;C1I!VU;s0wfu_=b}I0{QHTS`yg^cd4NaZE^?qPOh%{5#rv!esY)U z$QTVhP}4-Y*2x}d2|O?LKuZ(Zd!DH4nTHhW$ZuB_`CF#4Aytt-K`v8R73C+$vKBni zn$yg#^L|;@e5gzD)LywK>U&47Z$LHFhYusuXt1W5%=xiu$R97~ z2YVrZoSZ+#OU_^Dh5T`HewkB#GjBP+k2mti%K3-AQC@*xcuR|%rL%OKJP_>k0jXo; zHXi#(5$viLBoV1WZJ2butwC+0<=VcaG+4`HIgL}D=qp{OG=rb?HvWdg(^mVTRRzA~ z1naBIO|6yqq_3q`HpkgonBy=R{|7Cakzq^iK*_`h?L9T5{jRDZmXVV5 zS`dnoEF*)YKv!XX5}O?&;a?lc`2L2pR+VN6t1Z3D(>KTk~c5%)?f>wv;(qizs>=+Nyd(`%GJ=;Mwzyv)WwJLHV%Emlu*v1 zDnhXxnA7GVy-ziciMwK)c=jgJ5=`ssUO|4$LA;|pQUr*$Jlp@VC=oleZb{xo>-?hj zth|xbRB&m}YBiQxH>T?7XSAkMN&00({l1tOt7A~2#`a-KAYDF-x@B7_zzEPa|u(^P)RZ(=sJ;VUOn zFeWE|HI;O%S_>)2e_=TO%puGR$atyJWc~t1kEOH77See?9B6TFb7*>98>vm~f8<~mFIeZlbMWnLnAv6e114v}zpd0u zn)W6W=6jrpK^alSX>49wX^60VH@nqVnn+E@wu2B;+0=GYu+XACThF4aTOGaTL}g)I-4{E32X;Zh{EQW7q`7UzNz z4Ys~veY_)Fp^hMP{C5ZGp|EH>dk`VjC;V!WQY^fC??@@mos?A?ZfEz}VTj%vDOC;p zfLPN1tCGu+QUj%M6IM4$>f%2eCi;R*^aUE8fu2>6&gMi(27H%hO_a1m)pq=wLOyqs z_)V&2_O3N6+@&-F^kqc(0~AtXW6WJ!BTr)s7|(`uk|dv*;Vv-+A`PPsf2xaAUsZi1@h5)-hWB{aui0O*Qf*9xg5sn;g!f*Y)J;`=#6R#_US(g! zOF@{}{1h(@@t+1cJ|{Uoha5kF0*|D#!Cj@Z&4yFCeBzf^fAKOm(vC6dTZ#Es3Dzvi zqaV)5O=Z1|(#PIYNP7XLb!q?B#{M))vvEK5^aN>@3YR=p=`N)cS=rqsA61P(4{;>x zS6=nd3$iKxiFXj}YHvv|teD6yBud@k{h5*+hml%OY5p<;r0u)mE#F*o$V`^x7IxbY zl?;A;-{hq4X<2fs#we^5_mz4P+b#P^wd=NkYBat}0)r{^i}fql_$B%kYkXG*`tqFh zfoOGBKdFNQQ>9=EgeefFO2JeC^P7IsNdM8!{c1obTI&XE`4~bwfB7-_F4$G2qa*nwm zVmo7Tp1GYsj_m;9nmDeN*MLNqvH(YkmAr%|%WoOdtr-T-ChHF_;~W|HLqv=diz*HM;Sedlez!MUJb9cmjbXATN|i2!Jk8$TLs_4plK%+c zntSXuMsx|4&mNEno*v{{@iu#ZHzZuXUa_pZ?QX(DyR{4Nn?_TYP_uVFGG&>aLIJb) z9>mcz-wC^B>ao`}AkVftft?(RaSrzXY^cb;WnLqs+8vP^bDRdEvUpo7)Z;8Qtsin_ zsnx)(mu9UBaY${3X~5pNuo9cll}#QYH78kZ7$FVhvKt}A{@(~6{D-~NuR#M@kP*IJ%Vm0!LJ_;2+pu&BWG>ts& z>`~HY!8V)eM@t35ggNZ{(ULxJ_M9m$1rzW%N`JXM(i@PiD2n-vkv4Vc3%Sz`6+b_~ zQ9k}hu^#|&PvKeU(QS>3t?V-zEu!l7fiC9TU2y7fp08Eyhr9m9Nc|g3U%ncLAs+X@ zOW?uqIl=fBs9EcYTKVcI1{EckKLKH5$4ZNZ{r6e+HVTmjZ5XWTeSkQ9 zezG?5cMyGTRu?mmccd1=gksj=9clj9BZt~!oIjnA@hVW0Q56Mn2C^yowC#EHLwlV0 zU|qUI4wuK_E2-wF1hcMol~}g)6dat05~c4Ckm~G%KzA-15A+%HQlr`3r`yO0EJ@^UI|(yrT<#X!jr}lD+J?I&7rrZv6&CMj zKfNnOA=+q?G)maHkL66lN)A{@Cn32Tdp=2O8$tUG8DFL!O(z0P_h3qy+CgZ9%uH(p zP}z^k%(U(0y!G19ZfxRYsY8SREAn|~WVKSWvjID5R-@*|Q>6Mn6VQ~c{$@<7af7a% z`7QAZ6@LDLnWjjsePua3wrxkY*?YN>eKkeuOT2|ll{!|?^#5vR;Z&)PKX2wzE{xtB z-^6~_?7g`wJ3dtk{Xf@IZJN}ldK?U+3E6=1$1Oq4T9)Y=3E%Hw>!wL{0+!C`=wj05 z@TVD1t2zr?@Y5t+?XZXVQ%_>f9{PW}$-6&cc=zSc-W;#n4CXZ*(_Y`XtmSm6jS#@Y zrfk)8>HWy8-DJl6&%LKBImr~Cwsafk`?N+t>`>e}* zQcBCOK6BKd$;^Vy6MhrIuj{B~jFQ@#Qhi#o^7o`&QuMvGE-4YQrpOH=@2_>SpE7B; zOb6wL&C@%wd;Yi%?d|x1!N0r_7H!JiQGU4&Q!dO3QUIK)7Xm{ zlEIg9HA{}6fQ-ZHCrOdb9!*6fs43>Ks`NXUR#;JX7MH&I3UW;9OZ<5ePpkS2PA4Qu zQ6V29=Ay}>Spxcg%V?;3cZW)KXDjL+wu6buPBz} zIeX4>s@go7(h&@_c_0VH2(0S!Q`j=pBJ`G3?YThFV}B(cuEYl^rqFw)^!~u}+uEZC zb4HBtsl!Q;BS~c;O%!vOs}vhcsnr~*y_M7nl=`f(jGMKY8%g|RR&$n=CH%UTZJZ?q zhD|4&&I(TE48<^#D7A?rl|CRsZO^9Ez{borOWHdj{Q=CSCMhAeL^hYB?~-Hfi zw`BDPl1}LQE|Wfx>NKkjyt39-bs$0y(suzp%WC7EE2NN1j^US%mSK4QZ6cfefz-Yi zRVEwUh6;oGLa`spb7o=XL}FnDo~3p|iHO`lD4HeblmfXW?Dr3_+tq;S=1A>ocmcDr z)zT9%J*)c93GAIYQc&RS3EU2D%E31XaGVdH8JHt=4w-`(jPG-33dX1F0OMQVy3+X6 zit#0GmVJ%=9g^TH{`?D1tNPhHY}8yBUnm(L{vOMn4K80giChGQa&VmE9)5@A&aLn_ zO+AAY`*8T3hAHqnPjbm?@QWs*N!i@*B-U39ElerG{Z3mYHER<$sTt$hw<%I;w|1xj z=9&jl!CW<&^Axio--A22@a=B9Eu$VfxtYV93$P+nm-mb?s&XX(?xI==4)va(y zwy~t1M|l3j!Y)vT_8fm&@wDy2*;%tX51?XU`v6v0SY!^b8x|IsGx9zwNQH?dk7c(~ zr8@fFKqP~TMF>x3kIADa8C0vWtY#Vvipt6cMP?*>uoK)q>MG8wlH%)Qh~jH_minO@ zm^4SxEV-=|K=T{ZU{JN$=`^Wn+kwF3jx3L!rFUUaP;ad4&7ju~$Vbpl4q79ys+)~r zq3O~qA$^{u!F*|uAUs=ZnV%tD=5J{FW=VotNS|vNxLB&I4qO5`7o_8HbPF_k#G9c< zcl5I?TPk%B(n8a5w7YQRk|{2wbW2lAVG)6J*c^Xo$N^~OU^;=vIT-yRz|=> zqrOE$#9Tf;;D8`?LfZ&Wc$5gRXwen z>~xQj&&Am%G`f1Nl=`+$rZWxLF~Y&&0vcBwbq%lTM8{;xrSZj)+sQdMmU3yFapZE{htDR6RQ7Dqg)OK~!yOjM0A57;z<~#B9(4v8-i%tGX%x;+(TjyIs$_ z%Fh27jR0jD+=JGY&H7mCBo!?{Kl)=)XK2k$la&kYCs-FvM=&;p&S=C4au~ou*GrLp zBxsP)<_(+xW?C;bt3do}z0|NG;M2eyi^aZfkjcCph$=HaU%ycEkwh`M2j!4s7sgsbc$EU$5(Z35aB2ihjo=7@xBMx&0%$jwqed<62~W~qzL?V-Ia5KArB zWCP|C*J8|t{3`JvH|G1P)I{$J`SJUAr$G-2cL!6Zxa3X1+X8-%@1#%R6^oQMZ+$AY z7A`80I$OZObtN);3*LS^B6(ZzdaYQ=X}4ACRuN%ar3r#9g{ih-N2OfBn6gbut-w%i z$GdL__iZWSkk}-OJXgx(QUuyMv0XYgS1{<0@2&}6^JHV0y9*oq zHI>NOT~h6UneA!NOXAP>@x(2W?b+*HShCj4V52^h9!7BA?Cr&U^N;mkV|jkO?sPDl z5%p(V?ro33U@E+&uq(zcT0vw zf0QT_qv>$^3Ff$R44V=TcU;ty6g|6XaSnnMeF87iXCKQ0=xS zzn9PiiC{iKGAlUB1c~E(^*d|%g>)#*F+plwF+my>Mv@ zuOzvD2_Js!%3QW#FT6+gWcJHmsbPx;e(>G&O_O@v3Cwu(H{dq40FT$adPMTX-E`x^;O0!fUKM+OzYdtl$sRPiIRO@eC2Sh?n$Vo9gwf*setvQ5& ze%m|j$|3Bt|ID5rlA5Vrum*>bT7#$77u3ILfFcU- z?l;h}3uWG0yDy-K!o9_CR0>x$44p^+Q;EaT80vkt8t_7xs3g-NsKl^m;(j?F)=TlGz5IxcPZ za)YDBe-V$KiB%t6eMxHKjx!A|h2Vc$J_HQb5w>){sj&V7C4y_7*jM4YR{;{iFi$+8 zFkD!G14G~yiOm^!t+7445T{|H@3Dv?Nem;~jx|;Go3h%}Z%XkjJpwlv8_`;srZ1ov zM`YPWQv1McprBoRs)3%RALF_VTl;(LMv>GjumSSmUFym~2m-5Gs%?ol0gFkSkbyZt z0iRocOXUmr-1;I1`P`Z)k161DYrHf9$miDBcm~Ml*0~(ybL&-dD$T9wkC-t9E;OM| z;~>qg%Vwc|3a7;sU}Ei3_Rcs|O~Bg-X=42rGH62GE2e-?th=H;noxH_V-&Untu&!- zj*2L3@Lwj@uQW8V?r|2g>Vn|amL8`hBW}T7XklMU;{{>XK#TnhM)kBE+2B6ElKcEh z?(-|T&#&Y@zmog>O78P3xzEq7;6A^S`+SA_e1-db2lx33_xTF<`3m>>3itU6_xTF< z`3m>>|C9TURXO*|z@0`eBHzy^HOe z`|QX?SZ!8s_T-{eYglifn6y3lGZ9Z*hl?j!SQ&2HKZ!0$n_2QY!qm0gmUu%M+_q9W zeV>&^H&2v7;4TMlyq;gQZ1Pv~zSHuru+`|;Z)$__m2SLo>^C*Jg#D&pdOA#e9gy0THtUB8Y|^!jo`qk@ilvVSvoAQ5wKyrkt@BLG?> z#N^SFwh@{jh2~u`d3=?CZ3MA8i@hp!7t$ZF8Fw zt-8QIzahOZ^p9t?zm?{w&a(~QN;P!fl-N6;iH$np64$B-TRu7aqRlkO%qwE^=X*6` ze|{@XuF)My>GxmPRe4^C$zGKJ1J)GG?`CFmZc4X==VmtG7CKG(TsG&H6z10+qonOS zR7-Qe_2`hy&*W84Sl)#_yd}lB$5QsFZ&=gsq%g05F6cviIa2zX{dx<7<^1oY+U~sx zr{p?rE0@9q)|vhAoz%g77$r`<&Vp}a8C0*crO$2YI{uVgwWCWx@k7?+j$}xSE?o<4 z#Fgje{sb#otUl${5o;WNZ+o`)Kw!qC7e8L?J=ve2B9HWYk7E}bUTZqKq@Tdo%C%!X zDE+}>fJdre;cTT#VKJb|};^Eg&HCjeH4YeIzJP|GcZ?>qbtj}GkdD_#CvUro- z_NvN+y+Tp3E1@seehO^fPWt`FoCMD+c_V*c>yoWCA&1k4y7qvDm^_?`0BP!?aAL%^ z6N;6SK~+#-ckRO!(wd%33|W(7@P;cq*iMn zjy9H|K?LWp62nkkZVdZstTDo?UMMI?#wFvpxyAPC1oJD#6g!kza*CxYf{@49s{7Jg zzF+c5pkv9s`GV!|`_g#R5LV*1Fu>J=v-Cjyp)T#rkBz>f6|EfXyQq@-0S*72r+RJ`d>EjTD3ly{b zDCpw^)h5Q5oN*aJ{*lIBy$)OH6AfE=Ni=q zfLS{fPqb4X?HG5nOI7uCw2e`cx>H8fNGh3B)2a@5!m4=c#{_OGv6rn3vlkRo2h3R& zjh=4nw2h^C>O1&mzgp{3Q0_I1b5~k#6FcXruU8W<3OUiO%4MQAbE1RGSyyj;ZDGkP zHpyE*2>(L*(p%q@?X9M-(sSmooba%WsE>DX!s$Au!iw5$fw?8vSV#nxOk}c*^#v-% zJ2oU+)s69_pKZ=M=H{i3>pvaGVdbL_zS$!=%#XY+>&@Z*!WE70nrIH=bgRZUw*`mC z3VV$iw%*AF=BRbQM8UF?%WZ2{!dkG@FP*enqwgbL`n1Ge`VtTT~n+?QyHDJk{x0bQ4a?Z%y=0v!`0rUJ$=fcOMBb$b!?xX-XHgjp&AZ% z!3C(#{Paul$@Q%2`i81C?2GF9?g;*>u5Y3Glr{0!=crb)qyGA+fXyVKnKAZntzFz? z8TZ}Hss+IE*TeERIE0n6iYvLpdX^ag8{ecTIqi|GWVvHbc_eqtmAqpPR;{3Z8QO8; zt5uO>}jmurV`TEu(mNlZ7t@edb3K{vc^)gx&Ed~ z=)KGGTMPYkFTtfA`!!duWAmc)8rPyVQ`m_peW1E9ATGTQ+ZCm6E(F(Mx1;p$3hB6l zvZFpIU{IZ@F0mSm*Xdz05O8`#9ri&-{hF4PV>BJu0UkA$);vEZ5@q6(+khezv&VfWnAa3;7#{*&2yFE^sa zo}%v{2-%w~5o!7&HT{v)=cv9pYm%ks|DdOcWnz~8tV&q3$r83mAM7f)Y-R%%>z4}? zHd}0q^@6KP$I5c_8@C3KgP1Wx7pzy#O_}+obPEYMQkP*O`$L5=@6k z3DAbv{{ddNmYxmMSn#lwBKU6zEvOO zCgg6hJl(19Pnq|Sgx<_hP!_)`=9FD^RD*OGyQoK-DS!9Q$N3o{<53w zMbZ-jJWT34h?&&4`SX?=8}M4cPe?z=JnZ^JVdO5$K)XJ`O~~72ne1wq;~H4|Z}|vb zqN!;efC%a$V5xuUYgqi<4YjHYFMngT{0z<67+=FtLGzmhk!Mwenq@rI5?9mkLM8lS zvqXyq^b#{0DjE8#m}ReI2vfoLm*@?72sRiD>8e$hpdiCkL1?jyeHd)GOyS!hhMPj- zE=zcA!z3~!wym+@neg5XwxNmPj!?eKlG4=hkysP8JQ!b&d8;BVO-ZGa!yQN$K@HcS!1i#Rgt+QncN zh7@uX29$71aI7Ifpi0}u8E!9`*4|~_1l05?=nJ}`Ky%YZC%F3yl;5mad&AX zt_dq%%6iT)1dB%zi?J7BYi2K?SWUsvTuj(a>TOF|_6$RP&zVT2+TLBt@@5!9s`eu+ ztR9!L`!ftl0Q6)kfvZAuity_ zhwMO-Vd`*KBx1J&)0wc_iKZv^lk;C*fygvDe^Cxv9$ScI4&rsde7R` zmyu*re}yM#-cNPLK8p4|B`@uE$veaZlxzFJxK-C`P&;3hS%1nbP!Ur*^ zy#ZbX%4)Z&%gu^W;NxNd6^ru4xgyeYDbBK^ZS5~+7Cp;wqlr%?N>y3we=n9LRgO@W z`)`2k-nPZ8^K3(1p8~{8>f`)*bTLbsZAkKnM9i%1xR{mCHnfmD2>+DH;DRtlQ;<$v zWyf7KX@57dhz|_?>#i~Zfm@^*5UC{%q1@Pf%JZIOVh27j#CkSW@}+;;jv-z6V-agV*HA~ex`+**YmfpDE|LXoYy8j+|Lm)o>}OTy zE@B_fHMA7QEn+9;8ftj-22M6igcZ*<1PW~zvFCFQ4Qsh8sZjF#=dyW>1Shgt{kV`t zrx*ew`2nNgT{vJ=n-1C!KZGr=(RCkSX|#8t+;G^n(m(NnE$mu?`H)QZC&)2r*Dqu% zQs7<^7P5yaAh_;A<~a`pyDQ~vsShd${yj@3I4_G69Q_zw< zZWi-dY6xV<<{A8J4f!XkCg%$N2`qCFmBoIZXQ&ab2NL~2>wCzo5HU8waG+7GMz%@q zif0egDsr2pL-7Y*leRRIMWq_L30pInDb-L{NXukjq=JRfnTpJB-IH0UZdLcpWW}k5 zRzmem&O*qm40NJw-tQIhrX-g2kJA){C)iI|)%P=4Vw$0GqkaEEn^#??ogs&I9`<0% z*R0OTV4Knm1BEsj>_r+#(PXe%=>|#oZ2^l+H$(~t7qB_$XnytrYCfR0xy{%GL;&x^ z^IwyCQ+o3DTP4^};(M73SV_8}Q48^(Sel%8-05vUV`^icFB9-7WKr4@iMaT5KI=H& zut}4EER(h?o^gw_VOPJ*Hw4!UM3j1uCqn8y3FdeY`$_wSgofCOQBeuQpXn@YfuXta zWO^jtnxOB)l^q7$V@y%(;vN^xhCPVHWuwZqF7y8)qUU*2-(8JlbKKc7S3F22U2z)1 ztj$bkyA~Mgwi-ya(ThgZ)=jQWQxJ#RVi1YR<~`oIwnpizGcfSiOlN@^hS-4fY3Q$f zh$#X@92`vJBht|Ah*ykAs}ZpcsDULU{d4vVgkn~wQqdx7+*vZNC{FKmlX?PD&DwYI zqywa0onTBpEA#)zvm1Sryyfu&A&VtpnoyVSM z8F~nhQ&`u9NI#syW-l}Z83&=G7x3O*x1zV#79ZFP&z_vDWYnq1s7e|C$v>3q*xiMO zxzQKq(javrX8sG=yNDRT@CoIENQT<+q|qk>+oV0loTJfaBa%$&4S1rP9D!M_U1UhB zSH71{UuD*%Ws{H;gbRD;IQV`7sBF4b{csM8$~H7J9;wLrf^wSS?n#6sk+Ryc5j~bA z=ixT_3LG=xkhfQG?CSZH=RIo`!|G+u~}U@o5d|Q^b1*nL~1r2Ay?KpJBLl)Gm(;Dja${*5NNr) z*q~PFd(V<_V-Y%V2{w6mn8nJ?a819>WRXh@4LY8i=`f81)4{srhf8Vq59ioTkHfB6 z)jO5^SW}O)HvM%s^pzfGmEj_1Cfl^c5bqlWoU-Pc0{VLpJ`6jP{kg=@sHQtoY4AXg zIUHV2&ZV;oxM4QhEU*{<qEG)BT4e0us%ugsQ%X~JZg3ldDIr|F+b>z>;!ujog2Xa(c>ZgzZBnU)`lTZ?lX#m zYtILX;3OI(8ucrmK^_Ix1p1XpP$Di7rJnT-vY@%lNW`&CcavY39y2^<7{1H+pX@rp zkH$SVgPE6t^yC?A-%<>&!%)lrN8WpfMRk1f!`ur?6&A}Xmb-iJ-BnRgv0x)ADCiQw z-n+2`V^^>jEU4>B)FgV;7^Be`dy9Gn8(4z98@r;hEFrPSuKRxG-UZS4{r$er^ZxTb z-^FHbdEAHa*SxM)G4XxDg=KgfYIz15k8k!T=U<_i^t z%L6{b(x=wPsLBSpy#uKKe4$MFPwBg=FB8o~6lQD{ggenaq0cHK7212!8WI9jS{Hq~l3lGL` zti5Jz$O!LPTg~M9m6N<@Hs)q{0v0p%b{czmfEP9HDAuC!A{B79P`w-mDYKk>3&_jz8aKSHA~Y;qsyE0~hdLu-owz}wXm2Y0qfjX-yBAZsI;qu^u1|gD>PQEXm6LkmVQBBFBK|%J`mtMCS5a+RO}&V7SRe>ImzmV z@&<^qKRgmd0l=;(iE10wE~-5~5eCQFFujz%Al)*-QuTFD=HTDrmpz3$F<)VJb{G%P z0I4n+;rsr6uBXyznILdJ>w7T!@!!ycl7A8mg}-G{0{ zHws^YXU&n_NLhiQu4Om6wgOgCqZ_?i0jnw0jpUz&>a|XG{iJWu?F8KA8`MehxY*q0 zu%!^ymVW9=vwjvT8JKrebM>j&%!V>-x-MPm#Lt3>Z_t$Erk1GXBc)u>1zT<7PRX4bv=^nEqJPhIkrz_L3 zKh49r+Ui0#R|#Qt?1opJKi$x~fPc`?Cb{uwXa)5V?|5hG`HK)zu%U6T zhT1yQvS08hp43@wXxTW>vDItFes$6K{Z~V?bY(l!+h2qfeoZHux(Yotxf5+zC6o^8 z)ydUCE-M9CkMG1-k1EU~H#ZDsfVX0p)4lFU)mIA@J09)$A>WwOLHyeQg)vRNh7;94 z!NJ$acJ-K9z_8V`0btWj#IK5NGYsiS+gA&9`5GPR@oJ%5^+L$9hX>%7dFb!*JTxBD zo^@buG6N3yFU0bl^dB9l=^7z~-`;^ntr5x8 zHD4$6@*M_HE-nh_+m3dv6J%p!mWD^Ji;#I_+e7xOQyVFpu5vr(lSlGtZ7FFz-jRIQ zmKLqY3~^{%+Pxl1Zqkjh;Zi{##6KHkaXa7yv@jtV~H7j%{aQaUAVw^ZK`Zmgq~j$PIYw`ThYK)9yuO7rW-p26Zf2)JB5x2I_?sN7k%hL`zaso z5#87Yv}fepCB!3$-z|*c9?+rPLO3oOf45s`%>ARp>=7i6U%HJF_6p6x{Eods6!?3! z7e$_sHAAQaz9we~u}B@uz?1r8Dv>F4t^c$p7INSSi;O6A9rXx{Er_up6W3BK)h)uV z`(|uI&dfpv!ZBArce<~T+0+nBY25GcyJ4c7$gSl)uW5BUA&GG zh2J>$VwaekJPSgFuV)yKA18LU*A&A~hGzBU}4lpU4+NOjb6xwop@OEX^Zx|pM zWNj8+cjM!icmyAm^rl)a%X@X}7OrEV9k&FTK0hWD`z*&Lkl$>3M}~Ixhc{vcr82G-q+)ngk>%@CnyFGrZLQkL&5G3Zq7W`z`dBavU%hq- zruik>coB`iL`SvY-bJCohj!90i`mJ|YZP(mV><~(R-T>U+)}p0@zD^9is}Ld5c=!#<{VRvxU0c31xRS zKBM`4C%S|(_!w=xB{cZ#tjkmyBSY&uwGk^Qly#xZR4S_Z`jp6gQz<4=#Xp2P!ikS1 za_B*xL?)b|{C#&OM_*=3^$WDmg*|&+S(h zi6y_6{Bs*(QG3bSyu5t(a*5@s?q&9V8hl@L_3n)Q`aI~3hp!Ape%yc5oG+(zXOr*NC|8_Kzw z8Mj_J!x_KgxF4vVyU|{3Yss3}GmY0@^Y+_*VBg{#w^k}w-HrY{Z!e+b>Wq6h&qcSK zX-+WVZ7iuA@-q7I+&bl)kFkaO#1?6IQQR9p>B*2#nuwU=yKiqf@sxr4%-B7D?6AG0 z4Ktee-#a89Hzgl80l0c)N=3XPV((6iqd-m}{Adr4D&dHH%Pi@BF3#eAMC9(GZ@!#y!{rgJTe(*&M##= zl@cY4gLw#}h1qDNpGz8VbJLZXrHofOK7dma${5e^?seaVEA>o9tWBD9i?~BZ1NB%S z>Xh4}u|Lm!%S!I$`@E#W7UQqnSmmI_c$eqrU7_{mjWq-MT!~O^2cMVf^}Irl${R}> z8Uluo2T1|!n^PSmY`Q8}$P{dB@wx35j-&Lj^p47kVNJwq<)fEXS~QYLA$CDP zlyPA|Xw&)O7yGD-I`++EglyLx6=vMR9bmT;N5$K)EaI-Is1A$FXa``4kUXPF{y1NDFVJL5XBFk4O-ewzA)8mkuG_Z}8!`^`~w zIIRsemMOgu;28GMwgS9IsfXi^LCo$SIg@UM8f%8t00Is!OM*zth9Zsw_zV_=HbW`3 z=xx}~scD)>?>cHuC2J+)0)E#?`o6NU6yN(iy{lyWEaZ!m%bZbZ?1gShhWcqgS|5D~ zZ!-eU;}*1yUTYD}7R|>2{yZQ`yAnn#vZsAfHy*L{~1}NKdCb zRg4v?)(6C;vRa5Tl~qA#^Dm3vJe6IVlBco;lc+(MagsRxUn-k+=Do`H9HZc# zy=SNkZ->^m)LgZ1;hs4x33BCT>HMdVe+{El$p{GZo#pI82}GHP(IdpSd;G$81vqw1 zWHN&9GLNUuHH^(B{(6G3o#@L>W4kx}mNU2RvwdP>F}rSlfs7M}mN|1JhO+f%Pq$p$ z`I*de4=1)|W^s>YtOW`@7TeANCmN4z7bA@kWsKBEXw%hT_9ha8htDE0-{R{ zT@YnrXoJwE`y9Wj7&vqiRUbIBv3M!5E%UHR@ zG*J4NUc!$mm1-OREDyFHQ8DDBRy^Pu=}lUgi+)@4^fv0 zV}%kWP~czWe#=r8M;Pa+D>$pyGbZ!=sx)O=1LH(2Do#_d{@Ka#SJRYQjf};4{>2fc zd5rO)y7W1!m9Y`;oletQ8L@TEOlw=ADul;d8Edm8wO*}_joFgf=BuOkHdkyQKceXZmXLx1W7<-rL#FpT?Ux~FXSp|%oP3WrDURSL8J>P@k z;x@)uhIy}zF+^Rg8?T|U#k$uRWf#TJw#Gw6*dpBz^U1TFQDUofE3`9?<_f>Si2He} zM?gAzLU0<69#np9Z`{IjO_aW!jGYab%_{o`8GW{p zuRaO8*;{|o)a_jlVzp>JMuhMXV@gI&WM70+g z@AEzOQtC{}MkhmzJ8x{@$K&GN)NJD-p4DIB4`ao^{WsZ`{V2P(St{bF((4c7N{-v7_}(#k zb6loU^sezZ@3ATa6<2+MioJ5QivP|rp76j!#;*Iuc6Gx)7{TqK6;F*fxXm>6ALGChyMfay zXh%6HHrDoIZOpxMuR9v=Chup)>fCPn?3u9!w~K~8Gs>lQG1M>@s=`onOn4LMShkDS zKQr$32+qvoeeQGPO~ysy3*#|9A(I-uG@fU&Df!AcUR}Dq;EizuR`q5o)_2AcI&QhL z*WDD&p_Q{+n~E!?bf$7@ZbMH~OOE?d`OeEU4Da651>lu+iOu%rtp)$e$5hsxTdB+` zWGca7zso9r(v$$4loU2>%5f`B~53%d8}#Al}wFzw|x{Qo79fjRyL^} zainZgJK|>9q;|xYvZ-De>lSggove37>-X+t{V*oQnN+y3Uis{}+B>6dDinZ1$I(6e znoT`fr#oym_2oO6sj9^k#JYD=iwS#*E6@T9ZVV|vHJ?x(f$J7irrH}_)w&R9b6Jzj zdgJ-BrV;tQvA(M}%FmQ8Z4?C!AsBP-2O0alcQ#N)N93((mDAoq1 z;wrdDq-m1pdx3Vz7idfq6SjU#AXBUss195k^Nv8M_rkcvwVPM{K=@A?Wq18Z(?NKxLv(tosg&~d7*l%{d~dAjjk|mDA??klf;XS7RCudNrt$9l zp+gGLhjM;u4FcXBRL`K(Lt(hRrkQrQ^MQvIVJ7U5$z!SA6ym{mIIJ9>?SizJYuf3~ zRmVaJQzr`z3EKDDIQzOlvaKw)4M?2QN3c7sV-+yZmcq$gWwO7ZKJ7` z; z?rGCqE}Nt?5MVYXpD|tIZYbT(n&x}*8As^ZCDZoe*^oOs_&U79baCyr>1_a824Thi5iB6s19dv?m}YQ(Zbz{@((dgvd>>9@?*WSeV%_yt_oGh3 zoEpkBhpE3Gzag6*dWnJ(_|y~~z}GHK?RfD9-@cSm%UzsY+9MEURM)L!8%6AALhIs1 zu@~pjAuofFQDM6*V)F(vqs?L)p1=B>7L^rS@H3y&UuDHmIFFL$#0bdzsM0Q2yvV}| zRS6LrbGSioM5rj^uC#@rVq8G-akif`mAxc!T$xHwLd8x2GYY_lPo>V4#K^!ofW>CM zY*0NTJ|xp|b{eg%gi1!y#Y*CBe!+3tQ(3IYr6@U-#nl{c0r@se+{%qptX0Loy&8Vw zk1d!noA5tlO1+ZfYiOSnN*+;<6EB5*jfk;ndTzkpL+o=x``=$X^?@-NJKAR1ibmUo zjbmwK9q}{V*tE5d*bjlRu2_)|I!vF}70cEb>!SDQkV+2+2mOJVO3!!iF-9-s{A;I5 zi=7UQkKj|r(DJ%s9qc{5R#*JOILF`3nwc#=27eE&epn7$4CUD$HVPabO>rYNVHh;N{A<#?<(nB$U_dQHV)aE{8RIF>(N+0;yIjLk47=tT>$ zEkEQ0HE$`l=X;!>RV~GO2$g#+#X39}Pf{CEqRDNKS3);(q=5(WtXs+AtlLhd#tOWkoD>D*i(&iO(bOA~K!YmoQk9|w?9Z8?H z6+>`yU_x6ly!;4;_X2o0MMKj7c+KM%~ zW@KsyMp{z?7PO-7S}?I4*y{30w$RQJ_+PI}Qa)Sk3tn564Bm&R&?*VnS%9r1@@@~d z67$(Yrr{DxYHU4rvBk<9Nu=KG!B!&8XfL*EvFXG>%tk{GR>$J425yNyvCb?ONqQdT z93duLMQ)6}T@ar8qFSlv4_LF*(;3p1p29NJ9S-E9KiZoGCOkyc(WVPk>>yU1_y&nM zTN{hFH7nW@=yno4*WSz;XX|1KVi3_=g^Xx{!>KI63=$RyNW8sq2dgd4QajDj$%nZ?j(gE6xuMNw(l%#&Jt^%zrcl>fw0R- z>d8=hpQLdJYY%XtIy6)^+hJ56B208;z0k5Yxw2Tt9e0wBv(i&tC_#Xsq6`;`h~z9+ z7F!2|tV6D>FeJY_NybiM32*cP>!bsb91ZS?M}>Bs#B$Xaqf~Uh^j9z%_F>-9`O;qp zNSwW4AY`NoKk+1O>?9f{Ze<1Soyst=TBCOCVkIHN76%v{1UslgKBlI+xa51$g*57_ z8qwtIKwPhU4(d}?89#O9F*&=zau}Qm^o0w)l)>GUMxDh#Ps7qP1Kl9^1#EqUW^In* zttp|W*kt0rTNZ2I&Ys#nY+Ss38ha~Opnc4Y=Vt)M45@a$Aw{wl$Jmz~K+b>BXe&gh zS=Il`Rx7nSiyoddCP6I5CtsjB31TT6d%re83@uSe?O0a)vW^vy&;~KboThX?L0rjS zT}bo$iDAYy3+uS;=)nYO%X0YadF8alB->+>@p7cZj^tBxyPufmHF7=fBN^pME4~uH z^*X*zOVsZ#7U#<>pmzPmx?yV@zc1P}Dx!>NKRIK>D1bJpm5yJC70u ziB|tMfbG?|i(O5-2Z^OzjjOeqZVVDjq9HE_iKkq^@KreeUL4LJ`h^+~5ydj4u+?5a zH3~0*r@VZbI@D9&?9r6F6Rq|d|3FfchlmY|w*Ce5HF4EO)M=Qxmd*_kW4IXVkthaH zwV`4y{>d8ZKUADhI%H)Xx7aBMM7-p78Um0=AEI*We}-+o6V3d!pQ*wyF_{1LXKFo6 z{F(2)nqCbP>sLLtq7I&^{!XlzTgR%(W+wnqyMxhooNLCaw`QfVGXnqs4?nEHLG@xs zKd_&36<;45QI+ZVa519D+1Zd=qTXp}x(YIn&>fgfr4mJp%n%>KCR{C1mLnH0kix7} zUON*jPO0}cinXS^&nb=FcC&H*yjU*ZFm@-36>2grqHNE4TkRg|!7SG52XR2e#rR%# zoQ5JG7(3<7%c#^C&uD#fN7R%%u(!~^A;mIDVk3UrPt-F>tPuk~tPzt=p%F>ta0JoI z)OMcw=8sj8dqCvKwa-u;q^*#e%x(M;76a4eB(c6rp?8;&I6`b&IHO2UIM-qptF1)` zt6i6nO4CM&y#hj(p^s@6<9}fmJs%;~=T9!BS|i1BymJM0ABhH!_>+_zCSFekbriG`sVXn&l&M+bb3O8PY?5p#d1A@V0++H`3))SmkqD!ox2 zgMw-c$A18#KS#2uOn4Wp2O+=>u*8N#(oYaeQQPt2z#^>xv)W@Wsy#H$u6vb2=f;bj`SS~@>IAU~2+|lJ zYxRzW^K;ef-#mrY+i@YSpCFp}+6(E#1o19EeJX9AC^looJd?#(Ju|Hr{M;oR=a-&uF6y)R%fQwmbwXj&ua5u1E|xm z4k-5U->OrODPs9*noF7vSlUt;8066(SaG&`78XQgCW*LVkMULg88{0{4;)WvQ$(W} zIKBsak~##+QO;BNe35byNNL%sk%pH@rsq?{(Ir=W3qG_eY>1`}f$5=&_=#kjD%PAB z16Xd53!yd=jQc~kS&IlbP6Pn}E^xqmgZBp9#hWIx=ij(w;xxQL6k<3( z!3BW~7y+l@teT-FQVvu76wz#yp$2AIPQ&Uv0&(_A<5ARUnEnk-Oc87I@!wEd3Z5CD zjlgN*I)2A|;_RZOxG!|r@VBXD7vPO(UPla=OE0F05_Dc_y10Sw;7v!Si?Mvqd1RO& zrZEzyW{6F>j`Qu?ruH^5#4GYDMq^z$vf0F%{I+i?(BZQH}2h1Ou}JyWaWHact>45j)r#Y{fw8^&!}gY@sZj?SV8 zyI99qCf^pP&HC6D6KBykcCk7C?Od(Vcf^0w$+43#OEeW`){jpBQM>!V8k~kSJH^iu z1-!eU0kg!4Au+fF)Gcv|)36%@0Ng@Nq!VYm6y4Ge3(?#{c-fJZIZG^`@7W*B5)Xz> z$6cYYfzg5aPOlm6?TwxC?o<9eJ5_At{|K(aMg4c1685#Ym@8HTVomFb@A42`??w=m zVZtoRo-MZLM5;YU+-@p2ok?IfGkVRibO7vNrVICbm~9dgrJ&!Zp%lSQ3p@EeGU5O8w~e^6uh6#C^G zJZ$Nev)_n!eO-e{%oxi2K@1JK--k)@fYZ{8L&gP$~f8ChHi*T!vUS?98oqFm^hjV*cD_t) zgi-L~ls_=>@VJKYt^6iYsKPXkDbJUv6@3#v!F5HItL!plRL{tD?9H3J4c{d8xTs+yCgv4Cre%iVl1j%;S7!UX z%xo>QG|OD#%B-80`9jOQ-xHaWT$w^%W}$1W;S+Vs;*r~1%S{@KDQ&U7b=;Df7sqX3 z$YX;7qF*DLp+%P?s=E0s-4I084x6P*MJ=0H7s=AiL^Mo`4o0+v7Oer?AzD;IbdDOW zrE3ffH^g)C{H940J@@nnIvs>krCBO?k&9`OnmKV$d1U5x%)bfcT`KnY#A*AU~E*=M*uR`%`(V zh=ClJqXeXh0};}=bWy6M9(noa(;HZ6au6H!^i!QUnj^RJUiGZYGX>ypiUMAIuX?^^ z`cpcW4!8f+7gT7c_y%7ZSD%csk`dMeY_W^Amf}^Ic+iu@`fuVF99Nu#Lt+=h&NkJtfB0dXEj!NkXFL|y z8%DROPIJzQmH4zawEK`a)4)!!MD3Mxne=yyCs9weyVT{dST=GL)3d$axaZZ~91U*V zz~|v8+cfn$f=p;#6INo++-AUO!Ej1{fb)ZcG7pPI4X0Svlj{YGCpjqRFb3d1$?u3L zS1F2DQ%d-51i1dPuPte-%Sd)_+T(P-x05JUO!A-9QVFwL7hDKg$K|dVBD07bvAA_I@t2{ab z|0Sr5PY9~_Jt}n^G(ua@=f@!^D97&qZJ@?pDrkJf-pqUu*h>whWyi&$6|GO8yrNeM zDsSHHeBFEF_P-o2b}V?fmPETdT;^?4^UaX z6hI|Uilqy^S9tw96nPR{c{ZaVC&AS<#?`<8#+9K43Vp;>?|cxL`Z6z}GW7;?4@ZqN z%H@+7NUOQsL~qJUu|ida5RJ2K>wzd1Eymc+eQw|NcO+7d2-KE$5dA`WlwC4}&;6Y2 zXE3ikMVV*Ba@=WhoDp&593`I>qdq$YbiC&&@>>e)xmdG`%duFDeJ;v!)VqAcnd=>w zx=vs)_@XYp{_rXBth;serMG9rGTbpLbxw@ND)#Q@#BRJ|rM>6G>LCB*oLD!c7#L-j zH89p%gBZK40dclqsqWr_nKds{hx6#sr)bQ1aRB!_-8(Nffw6 zo)mULEM4@yg3B`*<5;8Z>OmPq^@&s{^-G-lyb%_m$Atdp{Zsndb368;52%vaV2*i{M?S@;*sNLoa^7 z`&~2^yl1<3-w^!~@7ejh`<-LF8+01)dJz1G_d@v~@UGX9>5>@cQ*4|%8kD=DbhspT z;P?X#Y0G7CC||gtQuc~?8EdGo5qC{o&AVNvb=Sl@Q2003#mf4y>+qM)rm^>59{Q=9 zDC3rBP;Orr&vSgjb!BI^_^k(DyalzmBbMOt6{g=EOer^Ar^^Pvg$B z5YV)pH=I%SC2W|9xR@9Sov&ly!8@t@-+1;fbCXv6Eh>dWVVRELOi06)WleD=4yDXd zLBagh%CzXdIEc62B;N<(H2!ua`sM+iDfUy9hhk|iU1|DItjlrRXxbxusM#jgCFW7n)xc_b1|Yj@v@Fo{C-ghu10cAF(nPc?|vsuV**Y%zr>{ zGp+mw!)+S*JQK^}G~O!D#J--J7*qRch^JJHAHRtU;g{Cbpqk2>P|ZzSmjMuH6#|3VzYZKp#o zFz~OZ=$ClKx}NMW#aR#}m3$@E=GIZGS3q4y6JCMyE;p5{uf&mjiA0EOr&|j)?@dX# z4{w2}!?K0GdW&hyITQW#RxH=xXKKU*-26hNP z-C$3&iDvb6>z<_`jY-7F)#UX~yu{t0oA1Qt+%HtsDVEe3Z{r+K%_4d`#i=~ElyW#} zlVLFwZOe+WsSV5#*f6qmld^%AnsPV{^_9C+3W32xDyv6js@PKcKLU~m&Cy9FO7H-} z2AZprjI_){G8A8gp0(e0!?eysYKBX%yz#^v;Z zm$j}I!Djj{mb)XArk9mOudOVxDOA}|R_e!jonxs}p=2yCRcdmKB@W@|Jr#CWcgmSW zql?mQhLQaNh6xz1+^a12Vkmu6UaD#Okfo|owyLn2##L_dcEsM5EgG?w$4!BWYgyNx5BSlNcZ_ucd1iL>8+Q`u~WBJQVFj-H$JYFYeY`R zh`hX&l)x2ZL*j?7HYbUC4ws6zJd-4A18tt$E#QuGJ{+ibxcq%VjQ0cej=TY2TAP0j z)Fq>ACD{OQC4Zp4(&oPysAsj6#_=8Q{r{nv7ml$={5iG zf38{Y`k`5)a_IF}(qH**^M3yVZZlwjRKeE@cVcUMkxj9p21v8sE9cz60?P3p^dFQn zqkzTb4b-g${Wr>4KS+A~pOkYrZ=hE84wk%eJ>s8qc!+dBeT?~VE}AnU|1lEy%@I}@KQO@7~*?31KwajwayW_Ri%if_&xm=!jc|DWa|zBz1>X`Wkk zbuz_gvhw$q5&w~8(oX)OU|ING%PX`7HNtJ&8gy-@3U|3M3ui<&T!v4mW zRc8k7;Fk8%gW1xqa@ax zsZ!7F4+>{p@$ON!)3K9Ya!%*O;Z+&=LRdz$M9mCjx-`t3N#ate7B^GruoUm;_!bY8 zua+@Zr+>iebXW3Utj>33xLBR&N`B00gXv1I<&4#7v}OfZo%Wv9Cn;L|ldSGhGc{J% zq|E;roTezXe}=>3FFsJ3tdtgVfs+eiF^PLlFdK7m64+#V_={97#07n zK8Wx#A~yC;M%Qz)617U|$#!ckUoA=glT>oK1CaF+r%(I_TDJiccgI5|WFxC()W2)_VU)scX0?obU(3poS}k2P z*!x;KtALMcsWy_vZ9y$V9x1Q4NQ*gavstiJlDI@AeXAsL{=?rBzA#*~?9|~@csshq za7xRRs_|`x)8Cm=2^zXx8pXeOq~vaA%nm8Q>?lnn*M=yWJD@%P!S8AQF__V;P+SAO z=XHS!_=wlRgQ-EfG=@)ptn5r@l??oMCH@1Ixw}{;1Kw9sbO5d0jY|4!=*;KkGO-_0 z0UuTJV}H``K_%W#6#E_~kbV@L0fF>WKF@#?@K1P8H#$KR$g3}zK#KDJe90tIo%@mr zWClOyi86AZl+G3JQwW!k6n5Fi6bM5fsB7OxX>vf)aa?bTKPZ(((C?sBv1o4>s>-7U zc;3BfqRFIO56FMr^@u-7|ouapxLCS(*6*m*@Lqr_?YI4?zH_d zXm+O?he31cQ-zLTqRn-sN5`e2RO^@&;EF39k4c3%t_$O_6knzbO+GGFEZ(I6LG`c% z@cCC~+IL*4%ynioGWpmCvhbS2e;Yo6nDUo7^k8ugq_C)^T? z0ilG3pbZLJwL-5uk=H5MVkaf|6#OqX1Bac)H?oe@6oG$7wE}f)!cnBdPUA~TNBa4+ zbe!MxkCJ$X@zDMQ9$L7P|B;9G8o~!WM6{=@v*4kf;yBBAXh#pvfrqx_cOE>neb2+D zwp8srcxX#~&Vz^A&#+WLx*ynDW8t*cqD`%-+6AeiL4&Flsd9t>=C-Dx7hq?tm3bGW zAP#%zHe8fS1-H^_=w_YdbjyZ6ulX$Isp`;mo~|tBpdPoRhZo_XT2h5e(ltKgnc{sJ zb`a3KkQ;Qc2X4=<>)4#CUXhG0*f%PyUUTYtMJmZPS4LjJcOPs-Jb6`;{Nh=$+yQpo zkMZ>Ss$_Hlym6OOJXx+ub%EIZnv}&`pDV%FSw&3?R8*%awY-6fG?-SA(3HmCKt-P` zbc0nCOAoS9QEXmC6Jx3LO;n@-P*LMpioS`8Vrk+{=>UJ~xe{{=y*r?ZTG1_)`-)Ad z#~)I~U=7B`M>tO{@dFZ3&kt&|oH=UFxyH(tKP0S@iy`q2>W)$C9%$D!i=ntXs9OV| zZbJ+u-H{@=Xxe;7`kn9aLb2UNBa21B{B6AE?T0|2I21Zc*>O+u;R^H zVIz-ScR4~i@HcF)P~H5hey__~Q@&WL22$(NknMHJ`~aT;>r(s!sXPDhrLy6H)I=9F z=MAP<_PrVC*lBL+>I-YcK7HyR^k_>d!~AEGH&y&cl6c%69{-PI<#8K0vGB!My2(P^ zIUe#%vKDfTWnbXcqC=_h!BPe~d8U*%Eq*4ID|G68o~-5l@l2|~ZZ8jbE;V&`;|Ecf z=WtuN*8I`>Ql;tJ=csV%AiBA=R291O9H@uhP~Z!xp^DlT5k3s}kGznosDPs{q!#>w zwWj^W#PK9^z5zFgkL(A8oblWC%==v=M&zM;LKyxiLWH5-q9SV)QNZc(aqtYb-Mme5L;jtHNrgB$EI-kXWBHWK0pYC+;VNMH2@?;5w=~yVE=gbT za((U%E#u{82vm@dyWE&HvZcG+-GAz!d|BOkMT6f+L3G|-uE@Qf?;$tkU%SZn@sLBg zS6cD41>%ni#B1r~Q2v#xz<8E;=}PQJf_v$z-1B|Bd4c#mPuZesaF?fCmgaiMrRcS% zTtSP~_mWjJ>FFi6Q702UM6ZU4{mD%NDxn32JM+-kIZ;&`f>Te2eWr&6on|6)!)x#Kb|D@gXcYW#~#XNj@s-v%LnnMVy-8kJFGo8-LS_ zf*Z>9_-rrb%ZBnc9J)h7wA>Uyzi4?CALK(tW8@3&355pH#>R4xqH8QSgAt!1;< zK-|uEzC&@PK}#8jEWaqB%x@((!o9C0l`E}f9PCoNw9=?8t`y~$mR4fh%UDwFU4{|1 z(4QUTKt8OD@}`6QjW-`AD06zsQ#`mPRIIO@Sh`H-YHr$oN|+FC&RaSoW`@-kzseEP zP+8truFhjnypSO0Vx`#resU(3h^2f5fkh}0{bdu!HKtkPWJwt}K*p__O9kbdfpSqD zS3_AjOis}iUx$Y7S<2eI0t?d9=CXFD1}jmcGqo}DG9 zdvFqcJy)*53ABH%e328C#ox#sd0$D!nOl1b#fvgIzmtRbY=KJ7gD29>prP|1`BT%C zmGk5p?)=gUbaesxAi`n`+aP2~QItyzok}I;X$0E6fX(`UqO8XV({9>I` za_#5N+|uefzHC;AbqW>eKa=9Er<;Ugl|9INZSOqn>|17sayxeLzjHdo9FXpo=k-QQn zjl?iO=yEZdfbh zG$DXnt&`8;6rvaFL8!%gxi;dq_3|JNSDvkxn=uUQ26-?}O4+dinJoQyBT9_XN<7>I z;25f~86{MZTEejzB}P++E#QANt==M+<3=l|wlL!yNj|aw8PmHhDdV^CxO4atwm;irg5%0Tv8b{C3D^+3_u)VxXsKaxmgTI!F!GNR3RF zLtJrXN4h-Jn@gaI`{k)zg0gYH9D@URsOMd|nBsFtwsE-67>Nkw#9=v?=dNoxCyvQg zarl^;pkk-sr(E&=r{uX<70rs%jlbn8xUE~h&t23?H98|#<+uw<(plNabLTazRp;eh z+&NknXs$(zf0vDjM?IB`(uv>YPTX0BQ`CFvF}6VN$PtRZAXf$u2nJ;ai*si*Dn~EM z>#)dMt#{TXc?ee6zP%(b(E?G~by@DgaVJQ)DlbHUEK#{|75QAeGUB@Y2ZxgbI%Puw zO_dwj@@seQph`-4a9bYAVSyUxmUHJaHTr0LuyPFs2Oc*<~90nXXg*+Au=0(H9rRMfOhqc{8?h-Ir5ukj3G*-G7C$|4H7Wv6PQf|t3ZJ65Z*1hw}yH_VG~@HNlne$4k2Aey3a5@?jY8J}s zG)iGPp%@k8vB)q06a!sQjXtlVU7_YqoClStgc2TFi848};bikl40l02a{W-gkB8E+ zlDQ?1IrPcyW+NT0V!jIY=$9~aRo=~yE{Bzs%C}b-YLVXn_u#{p<+Nyq@R(c zmN}K1NLy-|y9d1R#VeLp!HlZG^g=P!HsAK-9^$YfGmPZE@*>i_#?$+;FK)LiTjK$( zX<}~6J)LhghlD>x!Cq&q`n`psthQN}rD&Zs)xYx-pxVo1B0A?0qBs`BJ5Im1cgt>o zOt`P~u$p6vz)7s^WR`-@`?8BSCMTnrInD4gmYpLF=@`0d84ZJ(^bO6=(}PY>X52S^ zj_!9gSK&@6#%|_K%yU3^FS(O+xQDqKf;T8TL3l!4JTq@|2uUjJ=z-P4` z%FNMC$u?QtPopJK7pQA5vz0rctn6hD_b~hhVWb*}1z5M2>xIP1=E}n_&E+`XgT8LI zKmfivNMb*8G5DSEer9)1EQPHz*xc01JA;+gwc1a!Mwr`s13NA?eCz|HMl?l1|j+{f^RANMK^Mw%OWg4~qxX4v$8Uv}uX)xOSh2)hZ<>U(=}_K10y z7rc<~H1l~bowBEy8zE(xZeHV;#?b$^rdBGuL%B5F{FAr;CSNyojdNV8q2@Z=KWP53 z?nYm?CVHh!5+9%1my62$Qx_L;Azt6?DU9LO1~qS7686Nrh{}AxWD^^L1;iJusr9;V zqMmcj&EQow%{802pOsT{&0{4T4i@*TxfXYyDtlXs^N+_Ui+?q*;=EH>lk0^}r?_qA za2$3#d7HU||4bJ*5X~h!-P>l42(qa)7Ml>CI#^{UKH?l0nL2~&ZZ`{<)1%5zn!4S* z!+SClQN2YIm1xC$-M#p5mNc|rL7sNHzwx2jyUYja?N0Lm(=eBcN+1H1v$+PV9mn$o zFgY6T4pC<8GI#R~LS{4$XB=itZHD?E=;9+@#-;kZ4W@VdV3!z-_rr>YQ;YrPDrFg= z=a;PRhhU_|eup*&3}Ob`@w*f3y>>3Mhfaf(75mMjyuACf_6zBQ$a2)&Nk2q2fWV=u zPzn#B)T8Flyipix@$avkK5A~^$qiQIGiIJE3NUmYXJ6scd8H=(m0D-bJ-zVecj0C8 z8Llr4xB{K`rcGDOYrOlYa#-9;`Qoa1wKq0Ex$R~1xVTi^%Jvj=$NZyrXSE)@y4`yR z&bt#myo0XLnj-H)i!GEMcg?dTOltr3vP5zVnHEcM<&?(WmI<79Rh8d$)##XyB^)zo z-q+I7KRmw%p+_z1;cJPgRYO%`8J7}sA;ha_{G*z_Zt?oKx3IQi6QXSwrra~d>-Sp5 zS~Kr?pga6kozD1LE_zpH4X76yLR?9@9P$;Z}t+VGurl&^^}_?YY6Kma|5VKbxUW?lkC+k zWjS|cb9GCPV0ft_T`Vk!=wc~_pj{VB9Rzc_SbAWV^r(xaY{|1e_#6;9L|=HSB~SB)$m7RSoT|5j2Sklm$1$lkxt9T{! zD@!>}*stb=v4G{Nov60fiJY0r;Qp4se7rLmj{n#L)GNu-PXC(^ljeCfsPy|mI+SFo z=dF_QKb@iYkFcE5aR=%8Sj(*d)CgOTwOxes+mxxC7-#w13qGynR7)nNV^^kH8X{#( zv8?gi$uMujafGBRXHzWmz5TcNxb0+Gg3PTOXvEi+`9Yg~m|u^x^0BF-Ik@)Nh$G;u z)Mm2G#-+GhC}y^$nY0GwN~4@Ml6^YZL|E!>8G&9Rmz&mg7CYOl^u$uJm)_>pBMjgGw81!mYOA|sk{{G7@yjR zv0{xl306{4s7@MKnL(Y>EKR(VncV7ykEhjXmd$u#=$sC<-J?b6mP&Qzy{Y2n%+{MQ zWih@&yHk+f&+frs>2~egId0=s3fmjjOZQbQjs(Z@yXxrlOS;Y9X{pJVi>2B-Ev7m# zA5jVa&r~j3-%}aXjpi^i^R0Afr==?Yh4ufT?o7aIy1M^=a|u#IVu(2e_vD%qLCjNP z3`Jv}g_`FnhAK`>B|=eUYu{E?DOFUpdbKsgJl0gDs?|`#Rby#OmFE9FXRU?oN<-iN z-ah|4&(3GB^<8W2eTIGRe6RZbb60`F?PCy=uqQgPLUf5;(fDeXy7ot2u@Pa>Dtx1> zsIytLYO&E(#5t>*8n)5pcJ}P1Uf<{{<*e3C?cC@p=FHnoc`e?GRarNIhhtTkMf|W~ z3yU*iRh-2>u}W=ng*mIls@>i4T;1)7yVYXxGUqd9$lT0bA=}Mf%R{OWQ3RJP(osB4PWMFUq_P)0#S-ZHsaUJyEwPX7B4OlsjUvF62Db~K6 zqzY|w&BH$VV4JJ3A98oz52&}+UCn@`?XGqetfD3N zV6xcw&O0#CeP}y-`;V$b6FspDXLV*C(!XTj{7Ih1J6y#w;(qRcJ+5Rtwr{%EbsCTD z%j| z`mQ_Mag**_3g10?(B<-DHQNiG83(ag^N*(JA8bB|-Z5HjJLKx_$7=u4s_bD`ouX_O ze-NCoHTuhI2{-H!?v3)yIPAjfsG~gUh^wiO-*4y2;eKuQyXVxEqpk(c{^!(`FI|z@ zg5hqKfcGU-3OT0^f9X2vZ25y)dd$_<>HI<6JLcNpj6SPA`O4MC@5q^Q*4G&wJ)`m* zcTIA(J);&Lca1E1BH5}Nm<(Xctc`c#>sB+mE?Y0H?n_o>Pq>cweg8cLeXlZojlpBS zSBt)O)yb9_?)nLbFsT6l}EHz!Dycu?@#8bHW+oe7}<(lt z?SlP1z5~$hozN&e+NW6nzByu6rP6SC1Gk<^Q9);1Znf@v*OF|gk59r{KkyQ^O?69l zRlz$27ACvO;;z8XWLMpQKGsf{>1rHoKSx((v&whI)wS*XESPTn#0G`E_m5(Nvo^X) z7Q;s^9jM(HHw3UtA;Ehi$*vwfYn&^K_Xpd+543D_Wx+eZykFWjzTW}16}&x3?LXt{ zX7sj3oZ^Z`L2JL$*xnk}IM%oH`Sc1%X;4@d`@xk*^*oDZ-CMnV7VCMV`tGc2C_d@e z{0CQDU_!NW)|<#$;UF|kxE?(#!sXq4Se^I**Y8cr=bWo>o-L>cC1IEKYcaz&o=Wk4 zcSx0o64c9@fbSRcvfw4vt@fdBY`Jjgy?G9+{s_TCyJ_ceDcPh}opTi`yxA&cZ%DAU zVei_uRoYwTfcoK_s}AB(xlobkd)lQ>y~3q&U!xsd(FuiJ-r|Q;=kqB2g?iz6?4HARDK)zvV3lFSNu3vu<1X=`cYcS?aR4Y zI5*PHEnN)ZQHc%kix+w0DonoPjKh~8SW^t-@b#bCLoB%H3i983D&^8Vd(D)ph^z!zU}Jgi>?=a_N$>@ zSK&(C?cMqE><7CuG#6aa31wa0ul8Fza0ea?^OU za*ds*Qmk`-?58%P6HeFNRX;ez;XMgQBCgNnnx@a~v#ea(R5p(O;Txxxy-oE52+I@#L z@^$Y{>;mgdwP#QgGjL%B)>(yLv(IM5|BTwW4cgu~;c9eZS(oKHgB<%ybhcw+*wEFn z*1fomt})@((utnc+BMXBb-gO~qpM)2J*b9szs5Co`A@n?hu1sPuIWEz33h$c#Br|h zrindWRdEo!!%-UFT=-1|ETg!w)^`KVigN{f3t{6?rC;=91Uuro;}Sk5RxS9^RmN`w zLSfdARdauF6>(3QfiD&F7V)4A-a&(jHMYLN+Bdu1o94heftAwL3Jy|bFXP57yJ~jX z6%>TC#hSnXD|1$*DY$&vn`9lkX`9rv%XlQSO|8D{ipXCui^J>20kpnvuP)9ndzO{< zc2U1w#x3hdD(H$U9Cz=VUvZUldcu`?#WmMwhst@?RTR&umcQyM7=SB~^~rj?#c`ag zq_@W=)#<7$3^6kv#N<|+uDUX(3JmuCxKSOu>Y5$U3A;N37R+avus^;3`BaU#<_gig zy*^d%U2~1bgWY1+UHS3!NcHQk$iR=R-C~Vd%~}WO1$)bV?wNhvg{KeOtCl~xwq$E( z-|Qr0b9uXO^90>=wel&@R`%jNyC-{bYFleB7F8>5x!ez9B2vYKa7^Z(U4;v@kvhqC zPwE_PLv=c(ikX=zW&+22@Utt|!#Z_S#YAw-Z$G=TM?vvUT5X-%*5SO<+FG95yxmIT zQDu;I%&fBxXTtXo=nVPF?#Y~Xx28Gu{srSbh)GNpGv1CV`%rF}O0LQ!e)+{!p};20 zBoW^wj4ON7#MZ8ExJ2B*eTCQYB*d?-{B>K|7nE%ivtX7PUAXoqwDUGih`r&>ifg)+ zIL68v$`_VVH>{I$9Gnssw@$tOE3Wq*_06xiKk>dQa2xkd-d6)};{@MmU9<`nxzoZP zWLW&etJYPx?5oy>jcV6zJmv_@t}fliP0jKWP##na2j<}Ld6K;D8uT;hF zxT@m|F}mDwB^g_?;_}#JjkS1oMq!Q-lket_%iK7zzN_Trwp(Iw(eWPGV1>5xy!IPT zrhsmEkX&zSW89XsG%weok|K)$OE{q8c0zIQ4mVQOClUj7hc1^ZQU ze1^MY7-@IHaqqBC)S!E=C}e(c4=Kykv3suW&e&j8<+-U+K! zu+ykidfK1kGr;=ozch_GYtmq!vfa%bhl~3PdF~aw3O~vO5yiU;b#Wwc*N544U=n~ z!%5(X%WYjyd_VP3%Q70SZ0l^F0nc0?&sQ0ZJU)e9$%HWfDb|+@M%mv`@hNU4v0g*_ zJ5GUSk|_JCfZg|2x*C=6((&NX}L(7 zMp`z~=91!?XvyLSh1m7f5`E5|c@rO4>K1y+ztF(s-f= zN&63Jdq^8kdD}=+q-`Yag+C%pYwJHDaUO|lNgPRuD@mJ8+EUVnk+z65-ZO8IHi)!W zNaH;-owRKLh4kppGt-!vdbtmn4(q1I3GihB&Ye^a(!f4VukXD^7PO5*bvqT@*8iH;?WCpv~SK7^x4t4NcHBaIK?@JQ1>PUTXGd<;3U3~5}Hk0B4}CXFY< zhj0=NSc0@EG$0?smq;u6K*Rb=2;yVNVj&XaDY24m1@VCSNaL+2PugHAnwzwNlov`` zf71L(>q}ZG(t5)(an;L8VmA^E5<602X3|=dR*bafq-7wjK50RuRVOXwzI|bfAgust zVWj;|n#;1xgrGnY3zB%7#Qc<)leD~~-6Ac3wCtokL)!IJnqR8C%cSL@JYUjs*_Ii2 zk;H5y`jD83ivB=aM$+!vR*;jl?@7B?$G)!rM%u5o6?lrYpJ7GgPTd{*76=ELCKBYO zs4oy@UH{I)#4icoiLh=g@e`Ou(A(`>7XPhRC-BR{=;3v6^rF$TKIpL9w=H^ji3h!& z=vfbBcKZ%T&-$t6-M;bYS#J}^ciy6hmnG1913kQ8jNVH0tgn{c?YrR)Zhx}b-Cb~6 zA3ECYdkj6iJcHg@^zeuey&LFRAEevu`v-c~mw95szePCkraSZsqKEH&MXw}!dF)D|7a(JO8D`lDCI?u|jOtlfJFy->UNDtcjdZwY#MD308<=;84_ zdYjQJZ}$$|#qDneyZa5C744oEJ?l)^?fWZwxC4V;#@{0x)_vjKzPZq|?!@l)4Mwl3 z-3vo6((ctnFUsyUL9edeYmZ(%yVn~%+$%$F9C{7VYnl)cG!lJW1iAtVzH@%}TnjM1 z@XJvVkN>`S)p}I1-8*%m+FQ`5;q3d9%2desPu9KkMf4!?AJT&g>Zm->8|%5K|uLyCGc zzjbcoC9r+h)T=?p+%_qHggGu*PZRf^W4)qvsnMj=!;i+tQXiepMck2m)NZsV^&lvH z?y4GF#ONB_6s0dOlDd;q*RA6AQTdBn)84%xRfS8_{zzq~o_4{js(w+UvvbOQwWO#K z;(Yar+E>&lTKyJ2B~5p%t7H4@M>olEJ$gs{u!MLs&BjBXl==z3Ms>Y}PfG+F4V*t; zR{evG-gxoiNU-s0fr<3QM1DMPXti9~)*p z4i5M3k5_|>8$sCyKJYAwS67M|Az2?dhQ+I(;zq-)*vXU=Z08hd0|%ac40nvI_2`tV z|L~`+a>Mm#NInViHk+C1ft>gLS#_qkk+;zKvp$Z?8z0U2(()+py$LE;2_qb@3DqlM z6vJ=Y^(tW$$LFM`moQ4^DT^4|p*3WO7VzvSVMO@&Wt(R`*_A!}JdclI%=hsdJlC>= zhRjuOg&5PFSLdiwZlkh~TlthW$~sHhG}K3KqdeZbu(6a;&p9xJw5~P{HNK>g$1icV zRVHxYZ1s9cqr0=fY<0gR$`};d+NPnVl`CBj=#+5d{$ol0>IJQM6hOV2bT9+}(Ip3bCrj{|P`o%)Pc#$*Jt}@0@=e0ytwX6~4 zd_PgWSk_R^T!|`As8Pl5$P7Dd-3-+_)JVa*f?J0fcb$HpykxnvdtOrQ${Wjb6oL7< z{SYfL5I-Z5t%A`g>)xpt`5=Z^G1b$xf)VJG^}Q+Z?1E?d6g8ouQO5b=6!m^ZqlRB) z2yo|{qOMmo^5X|1vP2l8oy#Vxi4jJmv&Uq$J;Lbg{B4p7tz@)vE}f(%Rl?MIOtQ1; zPg2_|;R2H7xN2M32o6|t0qgEt>ow}OSdCwQrCx&9IpKn5MP*~5kKYc{$_m|SdKyhajVN}P@>`tt0RCD&QSwUT^ZDdiiYGVJje^G6&Y1GFL z@Y(@mY*tW1YZ-<8=8Uy!Wgj+H&97ywbAIuHYFyi>;uBznR`>C@V3(@qygJ6JQqNh^ zc2;v{XYo`WqnH1;qp_d%;T1FdIzlDSXwP$zcxEH(Pb1;o)-&_V?)Eo72z@talVWmcRzN>He`QXij z7aJIV`1%zcX!$Dz4^-ElHIC#2V2jAPE*v8qmc!|*#CYv-Me^$coneC*>_rmJmd?5djgHS#+v{G$5y zMSe<8BdZ$I(J0{ec^CV&&sV#s*E`}??~BfM{OQh~p`DBhKF)QWRQWzeVU^U`2zU1E zq|81>KIPZN80$RJ(K?^=sW-Y9CHcsQdma1*+yr?!F-yX&qAHUaH+4k^O zG|1u~A8d=uuM}y{R;p|-4g*6X|%AmrK$5ojI|jF&ZaRB zwjfB=?rUWB%N%2mko=rALIIx()&P;tkKa)%`(hDx{Md7#uhBPyU&*F+SgEF-S_6$b zKF%9W)PzA;RA*Gy@kUv7eUP!m`AK87cCZoV_flg!c6MX+**K$+at<*n;TK#HSKiZa zh*8qV`DG(DZ>Z76Ii->Mai|fEx12)^Ro#XeS*TxDjWUhnYQS(zqsJ7wgj|m=lePe(%(`hl;DO!YAQauREohOu}@+ zTv5&1bho-X!3a^$j5orpt7B~7ooBvyun+vyGn0%Uzb+IIW(O3&YnIqY5q_D-d!mvD`(cz%Kx~A) z3)b$pcfqg-gOTc%!|Myx%qd0>yr6euit)40J{3IO$mh8?)iA8j zs}!GR-1phzfp3J5({HkxpI{WrfbR!Ub6+;{s4o(X`Ksu2>^#IDQjHUhj#+<+rw2b? zM_#oi(YWorZK~xnjkV4Ors^;YH}Tu85zeXDmyIyIj)eXXYS?U}K(1WlabFa#&rQ9F zZ_=%p;?0%I%5UsBKilZ*hd1dpf6dreEUpMPs7BS1&JNq@j)C>q!oH`qa)6J++bd92 zd)+7=WItzV-Ia`L8=Y_muO(LvDTh}#@X~ko+995WuN%V)IgdWGJliL@a%}i149}eT zZvDv4|s?ceS53*7|MU@ zXgoG+nwUNFWY3mbA;&T~%a8NSuOD*N*ST|-XG)Wh{F$7=L)D^~kguGLhj>P|2-%y- zIpL0qY#&muL{#4}Oz9{8X>0K?rSar5{{B;5LQULqRe^%%^4kBV-fbUJyF_vy4lIX9 zF%;Ma4<`|L90~%f{H8K@2#G5gbvv`8agRLn8qdm;yLQT1|E$){Z*+~os6J|bhmiN3 z<9=0jJBHkMj{ikPbqeWQIQK7Fd~bWdAtPrmwX;*mJI>ZWtNxust~-0&Qk}Ylta7fu zsrIJ*Xk7`=)kdK^`E~%P*LSA!T^r{nm zpjYy$guc+#Mdj`X`}_rUvLEb57u4wfu;-swr3S#heNOEj0K36C^};~d%YRV$2EqR2 ztlB#WcDu8x&tTZg&Zq)IU}rv~JVRi&Nml)a!uEXc$viB?H^8~}kjgPJ3dYCnU=m&<)3BgyVR*! zmcCsreA&`>s!p>leVfWZ$I`c}Q*$gmNiCdf>DyGNS1f&t%0JK2lhmnsmcB_Xd^Kd7 z^Z6~R^L)&^_ePa}fu(O!rxsZHXKJCc@;9nZ3$6T5RsPp3{WEpyHB0xXg|CN1IPVyq zgRh6g`Z#BAQ03kTspx#(rQpcx$#E;Bp^tOp$DVC(hSc$QzPM6lSRGQs`BH8bxjH0| zUwm%+yzlasedN{Mio_Db@{gZoqqB!mJRy-y3I#e3S(;{`G|7cG#PD`uR4DBw4s^G~XW!y0({L=Une8vqn%Omm)=a&zv}PKPrZuyD46T`6 zBWcal!x!gRYo=iwt(om3Y0c~!PHU!K9Ics#!)VQHA5Lp#*AQAW^@h=!X*ihH%(fx4 zW_AsvHB)aet(k@cXw7UNNNZ+SKUy>O2GE*m*q7GK!b6_0pF(hJe5$W{=VnM9=h-hj z=Wd1!#qT2Z^tAms&GL%Sr2^9#CJHt8*e?Iv2oVK`o0e9BQm~)zfmt`bk{DNKTAc2{WC|OS-F7dWoV_R{l zWAVJ5^|M}C@k1lX3G?236H$q^vceHPIR*DkTH}2>m&W3sx6vE6bmJLy&DZ^|pJP`h z>-|SQZ(G}wU#-vN&SU=gp>-T;V$go==s0|3dGP1WzZ%&IzCZcNad6XdNQPs#?>Y{< zjPC|niN3WjzO#3<^-AfE9M+D$kg;)MwoI3cH|~M`6SNk-M~>Ca=)`RKGkE7MQqN{~ z*Lt>f=12GcgPk9=%Gw9nD?^=p-^YK7_3kSBUR89$L2S$Ew@#*zIjhpX9rot!f6Lmu zyy{YBcTTgy>((Cdtq~YX2Nxe3n1-Yn~p8om>NF->wW{ z-rQC~Vy&_;>0s8i4rXI(j)_5|^2k;s?87^^5^H!rwx(sBKG?3c+pW#Fyo=zyblS?v zm{{v_JCdeZ0M9eP-3z&t1d0VxfA;&mHb;m|1P`bN9*fT_*g(Ti_}D zpL{ptczo)u(*8`U;xq2)&Ztak(=%@6^!R$(W_4%6_lK=gU9-90ac0P>`nF_t%%F~CcULX^yAy-@Psxhc6DHR>O9q~%g>llUO6G9aZ?hOqym5GH(x_bZ z69X5(!oIKX|3Tnvbn&G^mZQclTTFN;PO`-*kBH+QiX)wBYYumjXTQT)8J*!&^pR`P zN4(KnFFB(VDjl(W34up#_U{ZA(Od6lh@N~U zi+AdD&xd*4?Xu!StA54Z6@A;{2y|3Y#ob}q_r}y~-L!fA*qDZ`9edTd;_jdQCg5~x zR6oWsLA_AI9rUc%(dxOzP3t#^X&sHX?nX6g*tlhbm}i?k*W6(R>UQhrVxEg_)w+KD z25oIUm95U8V0N#gZR2{ebsINt*wo=wSzYczmB>}URkNt}7{ik5w{kpS)2L?~$oP-+ zRVSCbnBP2X%N|^?52~py_gl`0sw%{A7gv2l+}Twd!<|pfw0bXCy-2q^yR%}rdd`i2 zt(IpxJnFpFTV?h9LeM*GM^(bdXmJgxRnnbJwSe1MxuWVH;x6v29HCwY11eW4ThV%% zW>oj#u1XQ*tEgnRI}qRfaNG{6qVC$PiXZ!M7x%AR?a|=M>Mg?^=&Ta1dP8(pDX(VO ztf1C_0aYqK5?rZ#MYY&)=W$kvP`}zyl~lo!R#s(I8}zMGp={++YJ8c95-MhBXhzRW z%s5Mjv(ut5H;3aFW|rw>7h;AnqnIt2-I>Ff6Pa_FZ+m_UcR!b-#pSxzt33|K7t9Zs zbD5)mjix5>*O3fl_R-}8L*|#T^Zo(|f%)z|XgY>VM9_DMz z7nxm{b(pJ$Q{Jo0am=2~=ZIw;RoGFKnVETg7!^3d+%l~0yqwNJl^o?BWBxIo#AN0+ z=2B(?a{#j$vm7%g^VT@tI_9xNvNtl9GG{VJ6H7Z{+0lquj+u{{GJ^_T^!U_sHwrJc zudww(BEJ8X=?Wsd1#<#(g=g3ZcO9p>qzmaeyAt~|Pcl8R*U^%JrWF+cQ>U3>#^&Qmgy^S6FZ`3*J__YzG< zvrXh^vzd63*>MZmPs$@)r`%S`Tg=S4jqFLxp4-X($|mmeRo_95x0o4slHHGakQu&< z{I@(4C%JEDdHy4JLwkAWD@lBj`8{)aDe`A6P3*_q$}CWZ{KJ^Lm<7s`zg{WzO``jg z?!nc_p2GApn^q@(jvB8zw~2#$6p5gAM4im|KmM^)p`9gDwIW>(-v20L3 zj;qFT>)H0<3*HuQLu>mTj`QePe{L3!NQSJBIh_ z({IS&?gJfa)k7R`j2zyxdt7k85y9nq23z4hdJPtw zz+SzSk-P~_bFZ&Y1|L`>q?#P_@kgfyI+Bpv3 z&9qfB`Zxmcz47kc_zI+1C)}YGo%Vac{d|Pb5j)XIB_@L}p-m&xkpRwA-<@!mP}RM7 zuC7~TSe6`_;Kcip9CnV6=k(X^U!PGw|KJW+5$D|aw$gL%_F3?KN55Qg#{zAx+E`Br zyymVkuc$M?zvPI%!(&IhFv4nay#}e+YwmnisUO^TLWsJiNQ&7HSU?|~z+Tpl}Fb?KVBs9Jl?UAT}owMREe zeQ?cPKX^p19zzEA91%QdvM=5bAvokZA8Nm!< zW@5&FOL+sC?V0tN;miU|C$o5Rd%9DU10Cz{?)StC%%jZDnM;{B&r{rK=04^p%q7f3 zW*l=+ui<@q#SZK@BF-Mp0bBk4Rav9LdpD`zTg>N~O_(*A!4Iff9xpq=EP9vn0-0Hv zKFptgBmE-t8|KxP9qbw0dX^Yim-uT0@eLQTbWY+|Tra;r+1a15X*#xMCdUg-qS!k7 zJN{bN<8}K6PawHC)#+EnB2J#(g~_owA5m9ZLm0V~9E9QrqGe_8$H?9p|3}q{r8J zPwbyfh5kq+cAG(rdnvUoe&I7yAER66zXYVm-}sQUf0GJDzD~Tokhp7pYFqrmwXgnJ zx7VKpq{kL~Zfsmmh1xD7c3et4^LA=m{K67{)@l7qKzfYllQb)zy)9SMfJ;~L1XiZD z#V_ptC!J3w2}qAG^J*#m5e-yf9dZAM#BbK7w#6@8r0XUpNobZM>Uj%TpThifGsVBboW|^Cv!=rl$&Sp-=9?%%s3(?T{oY2;-S5i| zj;?q55+$5q9%k-kZexDV{Fu3#`R=6-)+^Yaq>`bLMa-^+JK6`g39}M2n3;unqY%Y? z%^dF{yBD(=vl6o)Go=K@onuZfL-tUj>1fZ6NT$JjhIzd-B^<9n+{}EJ`7(0^vpusG zvv6a|%gDSEP4+RHMe#c%>{!H{%(Qolii!%$t-_;2@r7+eDDmuI;&W`jGl=XF%;wBv z15?LIdUf7Zw^z6UfQT%)I{s`M+n1ooO`r#TK3)Y56-l9OBUV zwH@Gaj2lA*KIOv0*zV12%go4nH6Ac*v}a}G&`ib6oa?B7(3frD-496@US?Y;em!6O z61VAw+qiW)vYrB`F>5iu z+(~}nZnlLR*%q#5TPS`#U;K8Qb?eyY5Dg@Jj%{IOwuL3w7K&fb7r(?!KTP8Yd%(7D zovn`bS4ZPD9!MzqqXiz#lei5>soo3BYRun`kbgUK%8`!t_;_m~2|@_=grtBZieKVn zi-oesgt7;O4Zozi!petCa_9y0gdE2y?vt;GU74AfqOUnddRu0*Z^;&xWm}ldWJfmU z`BRi26u(|T{1PV{Ae22IlnoNfIblji1igUxB~Emq3?P(v;nm-1gM{Me{M-&b@#^oY z`q0pjiam>Uvd@8MndO=JnD>K8Kf~M>+)2e|3=32%hK7#GkbJGXdV6`vN*Th}b0;aO zyZW$NsgXV6%XPO43nRyoZ9DN#{6g_}Yff=PYZK=r62k|j_9M<3s7-DuAPFoq$co9? zMXf1elA#YAJlW8!@#iQaeg)4y^7XVrA1P+POD-lZw5qwFC+(cHIDz$Yy(mtne{Ib!$9AyhmkoI`;sX9;f$7KTTby3qoYusx z8xSXN!L2E@D-SWHKoZ*@GM6wHFsCucF#9n(GNq2rNa*$rSO^E^V`gFMTlCvxn&6L2 zz2K=d{CXY9J21Hu-GFZ5#5K&fv_c7N2h67lTzU2JJg51;)oeZQ*sJE_3mr%!aYq_{ zz3|2~;y%{>rtbJ3+onGAr?po-<%E}V{2N5mF_#@LJ!PR6IeuswdA-u`%LaC|b)0|V zNRQ8P!TQW<%rNGZx9D7Iz+AkD>@LiL%#Cl8f4oKO{IAZA+lwC&;I{+7Pu7rs8gu(< zviq{#m|2Nggn5tSzF|t0IMaB_I%Yvm@J}N#V;X+h1HbKf zx;=A^<9{HUj<4DA1=G8i3Vy--oVkj*MAH{)c3I6X%C_#$W&3gd$v{GraF^JoCxSQOvg57BytMGBbo(fa%BlZ8z`2UQ!Dh_F50rb z2Z)W*U>(h0MY9{3nxmX%OJR2!{-SC4B~O?yjX2Xk4M7tBk7+vo=>al7)du1GOW9Ay z@HX>0^BnU@CwP+M52lf~{c-*_Sm!dphQ|dwqD!1`HODVuD(1}n>YJBBH@E8f9c|c; z-x3Eg@0=q0D)WnU_$}A*oa$shL?0SiGE4BB7YAW#4*Ls9Ez&!v9FCudkYD|@y<}DV zEOuy?YFF50y+h3Uv%c%p`b%a%zAeZ8^I^Wh{+t-Cs9hrXFuQ!U(68A~qeadM^)uNc z^AT=jzdnh9nqTxi?9a?2%E)WkZ++FO^=G~H&H9r`W;V}ENYx^o$o0?3~tNCTm-O&7U(C)Cmf$Ty# zRqwGNemOfFW0JLSBsRr8ld^5QXclp3}ln0@cA!(nR;P~S3gY; ztzri7K@nMo%gBD&02%HMmz52Wyc_J7JtxC{t;LIej{JG-Z&0?5k_>bJ>+`Lg1@Lal zZ1$;Gty>zWSrS*4M490R_GeZT6GPpV=5V@9ST=AR`>k(lw*F+lO}G517K7>HT_z!N zu`H|krE~=QWm{!tHOJFQAp1<})zsoeuTTDh_SZ;TbCiOuIU&2fiB<3MrpP{*c`W2T zA>+tAWPz$-^-2ZXJ2_at6ibOXE^UQYwL^QQbv)X0s7z8ui`4uwn;7=X)(Y)2>A?Yr zc_nm=nc+O$YHmA6T=fI7HB)SftHS<*%G9_;BOD?=X(V+v~%6*f*2$^Fou&)lqoO6@S^&;QC0?O=c@*ag7@||0!uYo-*N2@i*$w z1ob+yL23Eh*SGS}sN--nupJLsk!@iR+d}c{`Qi_%uRfa}TG{N{pCs^`I(}?f(f>jUapA~rDgJ+&xgM==o&W#T0NycAwuc@a&t89z zI;`dLr1sw#P^(Yt|49c-FYf6l#Opu3!fEL;pmo<}_=sM^VtWt5{TGMhg9JJh!sToW z7qPv_b68Oeq8fd~IVn?=vnJfPxe)g7CALrkoWi-&5rH^Mx_7`Mce~02WYK-AJAFyBS zzod2k|7E}v=r5)*plpy{U;NLn;M;$zWBs+#*nn+eWwwRl*Ym|MapP7|ec=$cL0bPk z*dc7owov?f0r5-Rp$}*v;a0YVAG0l7{sFK5<(i-uc$h!~JXr7eT$r`q7oR5oQ`6+c z@lVKaIPPh=>sy+jQ1Z=JPLUuKLAS;KwAAZ}%`_e2keLZ(p!96Xmw256c>}||w4uTx zwvF?TI{1=F4oJC3ftQ$HGHX4yz{5O=uX=^@W7A=AOSjJdm6s`@8dFc4^JD6Q71%DQ z`SrXfvF-JjR-pesFo1Pk(d&PE>A?ok`qu;gY5S1@t@%7MAzuIg^nmHrdoUq0os%TJ zLQks8fDbNQg9iuXaZJ-8jt)mj5awlj#}V?2EqWsRbzVG1@hh1vG+XpSwjW21IuE)1J1QWI zXS*6xY|$O;*ZEvB)yc*D^!wDdty^c#WEOND@lt~DWwskJ#TGpW`*pUsOm*@wH~;w1 zw#Iizz;qULF1SSr!d7f&V~Q>Mmp3V1XZByofA|;T*kAabqc|j>J_qPrai0=}z1S|o z6kGK3_b6UxxTCAJ-Hux+;S}&@3h@?G0{XE1kZR?}p?{e3+f#wh+dZCb*dNZ!!@Sj& z2WGy*b%Y-Fr^Oi3O~)#}Yw?>Rxde4MzNDYodT zi9;j~pYxPB^Bghxht&2OwxgKW&yp_oGgrtya+zo{#TLCj`)yhaTO2;WQexcC#QnEY z+i$Qwo&9Z@V$Z!x@$H#@nl1Xl-zd(aePIzt!+Rv;VIKNDwJrKm_Up8ssvP~uYpNBq z#A5UCJE+VXnaN(vgl&)iAfOKmI-^Qb;t==anTh>pLP+1vT%z$gt|ROnVp2kH4%B(y zAiWQ>ltw9Z-9>R}@e9^p(Ky89nd<|~mg;^P@SmdjPZj!`b?^l-+A;ax+NR^*odCxF z$0s1?%>5d4QVKs~yCu`It??Za5Ws@YMs=x>FeBS=({3d4LCwzd4{j zfNo2Dp-jw_jwGaKO96@3xqC2e`J|DlS&i+3apY&)bV%S77Ie;dff9sKY#$#(ez8TL z$$p&&##6j-vTd6VM}8K_f!B4|K0b~TbXK2Ce&J7($bN|_w&;!6ud~#2BMr-yx3Bd6XbL_X^oBFvS+V9Q$=<`hfC; z+t-lYi77U8(;DBAj|H9ItfNGsV!IquY|$@&Nbx$OJmeSt@d?=rKB-I{aY#TH4$x`O z7XQ@5u!vw4xhr(2nZ0;7+bi5yjO;;7u|*GJzs`&Xk=>Iiw&;1tk1q%10AZ!F zlqd{fTX>@k>B3!X3&pSJi(le4*m zgc7gYR-W~PzYiwxYiZiGlJF;%R^RLi{k8P;Rungwxry14`B3-V-5Yv5hxye`N)XOu zJA^5==-=(2c%9`BkYDJ>w($IZ(mS%BX*x8ALoaaldrA}@VtYDsB(n$e&18zN&J?>5 z+ab&xHgS*#o~4AU%(G|6ev8?e>C(9J2Z|fT?86MwC~=Rab&}=0)D8df6UkoUH%zfV zWqYZ{Ic&$=rM&ZZh?{SxwwJK|I9lU7uK0Ji;0OtLJh!EzrQv1c$DS5j832oCM1zzL< zCukgAjwT|0v2~`W>+xjcXo(;N-sb_=XneOKO+@@+>r78i6>ps_sT{DSz-b=vjK<%p z(nQ2Bw$Ai)E8ad^^+d6yK<#QYV3fuV{M~fo7hC6F=(Jk&1l^Vb|KR}_XTTezA3$=>_Ns zx-I!Lc)(d2$F`ygieGG|=@3U60S|PEON)}fkq6wOv2uHwi1^9I`6q%fb-iA#%; zKad9;qVYm!nuzVU&VO;}ltkVCq_*S-b)f-+HNM@Q*S`ps!}`;ip03C1w&Z`u^^+fx z)_?atG_VL_>r7AA<8@o|-{kQY_u=)wm>tFV+ckAt{KE8fiA#%;-^JtsyJ@^Qoc4(L z#nzdguE*=PDFw=mpaH`)P8glqFSbs})BWk#rb7axzUf-g zsT~f76d1q*4%WCXp7x0N#nzdgZpT~azn&|v=a`(R3r}jx0QY%7#{xblm@{5`ye)oHI+7^%(^B#Wy-ouT)tGxx zYCqeiLj<8Div6^d{3|@*b&WIMp^1m};8_=V}|5|;HEiFh%3+Ycvt@ zi>)&~U5|fYo7wqQ0TY?g%wK;de_FQq_i)^Y ze@)YoPQU|Q3O_A}@&uY{EMVI>|Ec3}oVZ0>wpU{>&DM3XZ{JLve~RtZnqT4*Ex)z? z#G$hhCkAK*(%S=4N8 z+rmV)g)*)w9TD^b;+MEG_h^fR#n~1XWLubnZK3!%-*o7S61c?YdHXO67qBf%WLs#m zEfl|=FMf){`B&6Q0||4oEp)OiyvYLz#jod!U*ZCD(>RT@KSJyL7sst!j|lJ|(d-1x zmb~hkKTxwJ?nchk^)0`>{`P9ZQq7hE!k0CDsAjj+>GN^%hzR9lkSHuGE0S$o*s{urMQ2X zrsMAxlnG0IWSP_xoKQNot;ek`W$8FSKPpLqLz(TFi{0d(&O97K_7?_m{Xao#eMq5O zE-EZDeNqnNyhbHb=Ra4B>~TejcZ(3mF#SM#eZ~i+PLzTFDExT;NcLYZMEW}B#)4#b zV*Xg*@%d7}Yk}wK`XG+4@~2Kn>ljMB@bB*dzCQeGd%)Cok?esfyi3P0i~U0k)asai znj@`&?(#8BOBes;Cye8G(;^E4$+ZcH4@Jkf+~#kSNDay`=_1!r=gURWO>t%39bW#H=3G!dQm z8d-iUa_Tr7zuFGGOH|`Jw$s`}|CQgm$oy9Y{>yy(BKI#&fG)EC-URp}`%g_^B%dp- z`D7NBXIq$+?W`tu&huF++`_hAKoa#hiGNy}QZPL}ZQ-=yU*ip9nhrfs0(8IFq6!udxXha-`%Si)Xx3+u2gEWoy&ug6Q=V`-iLj};#AOTqM*UY*D3 z_WIL>TYORq)6#Xn*peqa%=JWn#HRHxg7AG#xb`evyM=q$7A|31XtFKrkVgK)cwYY! z_;)D<)8n7&>ofgR0B?crugrd7TDtBRTk=fl1ZV^4wj>HK^V$D$Gde_lm{pho%rkud z;B#govnSDXNPrZQ0^*m1_~tZ_up8ULD7J+L+d}cD&d2#Df&?b;J)wB!XyzQ|U}mS5 zG@83_%_F%XhX|c_y*g;v9^u#k2(%VRSpn#OrwAv zFL8g1*7+|5)8pS70QL1e*+7f-`b#T7_lx~#0qgovfcKQ>x-EX;9X{y`x8ohc=v!e;KB(omhGfI#Bcp`s`*7}pguXtdg_=RctbzS1Ray`+- zw!RZ67XJoykBe2CE7!`TKFc4Lx9-xxv}5`WA%-*WvR~|jgGj&GL#N7BAZ)N1_Zs=r zVbhIW?ts# zx5%H5>Ce2+1E(pYFWfo#S!~E?{S}or)%WUD!YGzt{0w)n3 zfd+Y!g2Li6lu0f**q*;m+lhaXrAP zqCTuvYIT|kkDD2`r{ZG@NvO<3r#-X3+9Ycx%QB!cwmrm?;0nuE+RRe?PRijDcT(0G zcT(oK@1zVZg;oYF6s_Ey6bJMq=!>DpL+=JX26_zi80g8xph1s^-VJ&r^l<3m(8Hl8 zL63*t4SFQ>VCW9$4(N_@cg&PI2#7&II06C?aHAw9R2r=;S{M?c2Say2PYyvr=yRaY zfj$R%F!W?=k}gaHdOY+P=rPb^peF~z4?P}wH|UYj1E2>$4+t|MBA^=r!VwUF0EaaJ z%rOlS+*-AM^S z`=sril!j=>k=GmTSLD5fmKSX!^2;KBBXXOfeT%$-X!npe6Rj}XD&*EgJJ1G)vNH-? zLE<>HY-sCHpg0PwLvmfTqey-p?Isc@q2)qbg5(Nl+mPE5?JV+!qdC!5AU{9yS0J}4 z+8*S#NAn_Y3|bbng~%<5wxJCUWi$$Wjl{lacaXdYEe8rLLUI_|W+XR9JB`G_Xn!E_ zWwat_Ymi$T?I3cyqFqDot7sXK|0;4_XdffDKH4$l_C)&`c~j8xpe;3#9D%k2$*s}O zA$bPcT_nyxD~Prd$<@*JA-N;kk4PMg_6*wV$SsZb8FHJTeS_S1v>V8aM+-n(jNEXv zB;>}RB_nSrngh+8gXCbewMdRcJB;L^jgim-z8Gj|i=PA07B>gc7B>UY7B>aa7C(!D z(Bhk5VC42j%ZB`!$i0WWacK9DHxBI{^2VXvL*BTiIR5vLI1cR!k~^avKyqg^CkjkL zftyGkj&>8t!_jUcc{til6c~3D&LX!Z+BW32M7x9BF=$@o_C@m|w=bF(xqZ>R z$nDz{$KQ+OzGz<~IT~#PlB3bCA$c&`X(V?=JB{S7Xs40f740+%bVWOj+^%Q`ky{&W z4RULvokMO8=^3wVP;EDi+`5RZU(1jIuRfPQ!={Ltq>9|}DZdL;Bn=!XZx4}B=~80g{99nc-n z9nj}MkAWTx-2wduCXs|mCSfDYBy2?t0vrf9j7hA;EEgkSC<2BeU?_C!R-ju4XdMyP z8Sz~Z(-nncF@f$F;CXCS4-DK36Yh;VeK1%*2}D zeX;^KKWN97<5Gk6>$|x5LCcHwE^;fQ?LuB#vyTR) z?I?1`pm~uu1}zKPLgbc2+ko6?w6BrZ7wr!6rZ2nK8jdl)s zaVGv{M0*vrKyq2MqeyOvwhhU3(Y7JEF4{IE*G1cg0(H^0A-68tI^-5ddj+}0(e@xW8f^n| ztDp{+rI zFtjzu4f}tLoex-3_51hF#-Gs8W|5JRP9r7%02bLYvze4=Xj3WCNYSX!v}RJGnZqJO zqnbq?GOMYS_@|mhNoF;R3`=V&Dk^^l3>b(y1eJ`spVtw8&-HwNzvsH1$Lm_J`+WY~ z_xrv-pR=8f?Zo3F=Jw>VoVh)D6frlBM*(vqc@!`=l1Bk^BY6}sH!_v~6filGM;?;{ zd1Np-kjGXg59YCs$$faNV{#uJ>zLe!$2#Wr;jxaneR!;9?j`2U<8djUrDU#AeR(=B zNd|`78EW8RXQ+Wk7Q_7vP37TdxSin!9$AD^cw`Yu;gQ8$g+~^16&_j4Rd`sL?_sWm zhw~-2(=zPk&<0n)S70`Ltz(v0UdPCxVKsaMz6sxgcDRPX+T@q9abU@UIIz45abQ^q znQvJInQzI3%(uJ^nQwV#XWx|QjiI_Mbx(Tq5O6v@`eWUV>YH<;hw6Im+%-3Pg3eYl zRZ$jq=MCoVhs2PiDE4uO!~{LiLtk0KA+d059Dhi1U~2U0sL*j(RXAg-VMxH+;sgEkkU6&4t3%2MFi*cHw2uzs9$2Hdm92P4Lqk;~L1FnXp zaAL?|2}$OAx!o8D2X<#1T-5WhIN?**9F}s}&%n6pit-qYg%9^SEa`9qv_p5;VR6BS zdLI^LhN9dbjz9S7jfW+31|OIFa5Ii*xVtX{9#fR}2hsuejv!!)qTF{E!r+Yi4~v=q zN5_V7hounyJ^ircb35|uo=5O3MR|7-LQ?sq<8lJSI_QGO-#jc9e$L^r;|KQHKmvSd zumgIuk4q9Z9u~tBWW0v}X^K(_t?=<*aSXqPet6eDGJI0ucf9n&DKH;e50U`Pt46?6 ziqgH2fH2RG5SY=55cuFZ{6Hr(KCLLj+762?0plxOnONa_A!U*e2VGqzrEq7TGEvf5 z%l>7&P?AApnPkDhTg#*nnxGrHVF#Ra8{_6u>S1M)1HI4%?};uGA3OpL^AzQy+sh;w zj=7`ECOH_p6A|!?qO6*PV>oLX4&kmj9M4x2LmCd?hfkG>aREz~jsy7VJo@1}Yng=b z0ZH6K1i%9@6W;iInKJdQ%a3s7q$t6gnUKl-H(c8 znWBul?kG=L?DFuVVtQFoO8Os_VmN5PQSrd1VaRg!#BE0<3zm#LDp8z8vG*L6WVjyY zz>rbQgBj2VYhZX5OFQugl#DVe1$cB z;;5vJOD$o6{Qu%!u~6diX8^!lhA95a?2)!!8dl$ zzY=AOzCzJTMfn9f;0;9tfODZAeh0%}SCk%K9~Cp41=HaUXomsc;1E6nJ#aG&$x)QQ zU@UxSCzXM_U=AEo%y_sS`fM0Iz9qmaMOh9L;8~anQ+H7Tco3Gu`@h5SYED;Zg178O z2+V`|FywoL!)34o`eD=?ijwvN0$@4Jfr&pN0J@;fhY{yOK(3+`!UPzx2LaFy3t`|- z2!NR|N1j@{l-|Ema<~kp!&+#E38iEJKZhO|whv);&K?*GJun$Q_#2xPZij{N+TYpS zFcWsbs^4u##khtSjr}NtZ^2A>06Jjk0ffPapdYS=;qUNcQfP)De;^EwgLb$Q7Qe6EHl`2a^sGAdmAGCcsgL5ComD5Jn!Rv@joryobOt zmI7wMbl48_Vfqn-!{e|6PB_XEtYtI9WH|H~0-)_fjAD$Q+tfdE(pL-G~n){_W;X)qOTf;q4jI${3`#=}&oyss!9!zfqim^uXSpqg=;P0ce7|U@8o)K^U9~ozMx( zKj8e=*P?7arH4_l5L#gG4hF!_dmIzThh#AHn52Kiar7}Mgop1uCgC5m>5`9$;$X>U z91}BKF#DJ|VehnKV%Wf|{xkBQsK?HjE5O-ACst06y^1IkMWibA?uHc@lz`H$uTL04}E`3 zvNluEKaPo|kj;DKn3O{G#4(B8!W|Jj$HbP8QCE9RJg`qQ0k-mg=xHHCIN~(z&~}zU z+Z5&YR)oPv&QTHAvx7{wvsC{O2yO`|7eD+vs9a2+k$LxW$%jw%ESC;g(yLr7pEK|J zaw&w#;pH|_zTi7(HCp625~!>`f#996h;Q629dB zmp8Rsa-exyx%lAV6xzSy`Cv8y;2(2nhyOf*zalD~RxZgfKC4_j@P#Z}xrBVp>-BmD ze8c&;0U>bSC*@KKe?35eot!S^2q@-kfM)p1iE^>R6K4qk`?k^lEkCU2D3>gFwA*nB z*~N=cuj7&mAGr0n6vL?#k4xrvigM?p$E6&;YfC;Z;k$XtoO@i7q2-z5Vu#L!$E5?_ zy6m`Qeb1H3YsbY87q8*?2bN~-aq+=>)-&%%0&XM#Jh=V1m|cppIo@?7U+Tw=z~tE>?7c7C&UbmIV1*CS2J!O z=f6Fd0lzT;hC}5|0zm^zhnBZbh!c9&oRAJ^&BM{}jC=2d@ zzrsxT7j(cO8wda&hkp1L4F6M6PC_%>vhjpi;lP3uoc|b!7%sR7`r!M};3flTf^9Gr ze*6ighI?T#ocJl@VHpfR$W!rV1i{Ke1i?jHNdR`+&XPj+=O-lO5U1T2EFtXUJYkb$ z4E@)X5{`yWxD=MdT~Im9X$7O;?cY!#_&m&npF;<1hNW=uPBMnMFuY7r&OkFvDrPC+ zCTNG}U@`plTN@c*MDHTwBP=O2!H2(N0{jNr;my050JnY5czEj%1UO1XU;@0sg&A9a1ccpv!NaS zaG1RSdz6tWOooP&WCBfaeI4WB!3Hvb=F&J`X8eVq3PpKGNC3_cJSjPFap*}Y zhRrvh6d!ziz)1!QC zLX3BRLICXXGXk2pqJbu;D?tFP-HQPD`#uD~qWuVf@BfK_X8unI2N3{Q9YO%ql_3Bw zIf4M#|0n`ZaU}#3;PuB40N*}lV+}C6l_LP2JAr@}uI(xj0E;~cfE(%%00-A20Djeg z065BrfYW5!gaG&l%z_)6Pl^-vY&j_&xb*Z%F`VHh)MrkL8BX!DXQ0#8c2XP|Juk8w z;rvT%#R>p77VSFSm=qVlvMcFot0vTcZ{wS7kqMTrTF2l@s(n{K>OrM zvB3S)D-Or;nu@6f+E2Tq)Lzod34v2%w?&>j;4BRwJN; zHMS!Fp3X-A?Dr7@U`7D~wDxTXfGdj-@E4UTMgYA22L!-`y$FDde@6h^cMt)WILnSB z03NA9fDPlxS_HuJ&<$U!L%`o$sdy0p{ct;U*H=nZC!40BQVO8Gk--1(eBi5;_0ZB( zDdGQeWz<|LdC+i*fWmy33*9Z15~Ao7=jlqxhW0a+VpDWF#d@|oKfXS4mt59WVi=hE_=lbi?p&&`>4D?mETNyGn*$ zjle!t5*w;h{C%rrR1fC$tCC!3hYsk6El@F5iP956kyT>2hW6X4#1n?U*ec1o0Y4*c z1h^4};|OpQfhSZ+JG4JkC8h`_z+~u5tdeCgYZBvb#sQ3newYFc4_8SBbigv`fl6Nj zTM!B@FdjN!7IeZq=(1rHVz}XMm^GQwX&o@K9~n%k5(~7z_0S1hpkXSR8>t-3g>F~@ zW0R;*e*!}@bU-_F!$PP$!cssZEQdA+MvK<*C=Lfu0hkM2umUR6s-zRf!mwKq2osxSAyy3Ew2{NE?Q|N{a7+?~>6dxE9Cv!uP8ra5P+BC8ZiarZV@D z$%ZQNnGvvwy>mYqeS+|@2;5vHnemLBz*!E z_?m=l50TMM0wm)2TS_#MjK8arsE2X<0~LUdJylXmo+;?gW{1g=+S#5|1b^% zJ(5yJz^goBJi=0S^N1H3ulDdZ8;3nSGXEF>uklE1If8n5q#dSS=aJ&$oR-&nWZ4M< z-ry1QN&JUu8Vl@YW5#w|m6y#qXUSNv_AQ z?JhEF!13K4@xjBNYA#3NQerFxVSL-#Zk zwo>Zp9@!5qk9j2T91b6+y$y%65Z;c%IS7aLG=!gL>7GLP1^mrL_(l9ZgYXXgEkGbN zS`q#inLkg(FLD06GCUIXHyJJVh#$r-@kmi80hf8C{2v^%MBD!*!xgNxkl|}MR`iPT zb&mw<^on&g9EzcUb853pv}>lLS)fxQuM z$Rm~;$mFO;BEy+jPN|{gB%AU^=2dzms}Djv9!a{1d9`fH2n5x$siERyNp99F=2ITY z?#sN>Z0deg%I}c~BlFIA#OA^9oTuddnRt=48$hOidnEA|CjR3QLnN6fHR6SKeT@{} zN=897vTPuNyVc03L1faSMmnI&P$NZA2n(y>>-Y!=uaTjH33OA9_@KF8jT8(a-hdiO z9g5$9H8zPDhJ(R1QVw0iY9ucj2g7Uljy?|VtdY=Ij_LEuBoFRkHQ%*;PP0*TB&SR>gJX)mjhgh>c0r;-oT zUqL0Iy_!l|^oq?`M=2+xuz^xeAz(A5gznRnaw>saDPp`nvfK8g^b zl+zFrP|G*W;Z?PK9S2@rEBiHGQ!Dlv@VZ(_dJNuB%e5rDsa7gd^ql|wYQ^z54Y$-v z+Dtg8R-$IXA+=mQ!kAidrouaFC1W<3+*K>4Ib=4nRyv_&bgj6apnpuQWT&wd57bJ+ zlL$+w<=PRUiM8T}Sr6Ar-qR#9rB;&DN$k;DiI{66)9JP1nM>x6*Gj=WDv??%>CeEl zT8W#Fqx4$ofcE*dvU>rJthJK$EJ8BK_&FS9lCc#b%g7j-v&eWMLbA#Dd6puFj29s! zmyDreC*cf)yi3Bi7f`;Ij9(&bXA4nHR2OdM?_<0Uxwgp8qoGZ`;M_*OE0 z389~n@iOK+$@pdFe?`X7@(md;Xa2WjOrqA^WSqtLA4wQ0Ki7(_U|ncdZm<<*XN#gCbHt}NEFV;%oTa@xrt;~O$0RPnTcYG8o zbj_21&Cv-no zC$4P>SyU(4+Y!3BP7*#Nk)?GK`Z@EL*NGeYSJX+~7tDXHPLiF>UsWd&I~bo^Cmv|? zyj3R!U*d30ouq$-fV?^xT7)CDPW;fZu1<=+#=(bmlKBm5>Zp@ZI|;n0PLyIY{IpI= zpk+&)z_0jgU=NfMu!%hYvs%~#`$*_4d*C-t3&%P3!0!Y+&mMrT4)(x)6#va0IKZy| zmp$+Y0d-#KfT=-V+5IQ|AzsOH6EM^(@dufIjhDY}k>Pb-*$?f#y<$I10)4!aREB_? zy%K%|e@3rVKue@o9JZqb9ORX>W0Y)&m%sfWDB3G6&^6pE&f^4%^Ge1E9GSfQ35Id^ zc%>7jj`oVHfN2p#8@&}xJ{t%CSfcq}$!sK(=e#n?hp^|pqBJ4s zMX!`V`w}l7zcYWCR}xP#Kg%nI7UsX|l`?2t$@nt}&%ys$+E;sRlI$n5H_4!t32&3} zIV!M*61CyzT}pZ$for`IcYy%;UP--(@^xOx?I7@nUMc>I%s%#t_Y#6O5U`U#1@Ir{ zeG30Ya3K`@ZiPyK;@%E*0sINXhM^BoVt2rR044P+7#N_~zlK2peE$yy2Ppn;;Z*^O zaW@PJP%J;dZUMa4W9ho%s01Nb<9IKn?-9T=DMEV&DAxT{?i$AZNg}-h6vH8}q+A=o z%QA^x7r^KL$Gj4FeSng6g0<<5<4Uh=zkxs=N_8WFYuP+~5LQqBO$ckmK?Dw(2yipP zTM*Ef`Da+VehBb;WxkR5ZC%|z0kQ?iz6IyPnm-68Vy}4eBZl~Q?&m~)cO>qpUm(V*Y(XI7j8bM}* z5O5a*2iJ?;#K2+ovioiv$JC2&Bmr-)m#|R?xf6l+BJi$yF2$HXvR?A{qhvCR{%N$&CSWqc=hRE- zbo$d6H-mXkQSuc0JzXz}j}vGvf@UJ%nR+Rhg|PYc;!dRk&$1-5ng3k9*rJ}m!NPh; zO2fe-D)A%^GU{dfQ)KueYy30;7sGTMWFllPLYGp)c{qBB3Oqw5%j(57ABQhf`UPZa zL)f$U&8nCE&ryjL1h(S;RhD2OmCUAs&lBghdOrVKgu~ZyoI$`GHq#3@Ud3j5k%6n( zOp6Kp2AO5zC>Q0>@D>i15a?~@EhSSsd*vmBtYI%K!|^*T;mi2VtCz^-1b(kx6qeev zmL<)?Z$1gHpnV-mvtFU&12TRU#UJ808^<5lOW;Z}a@0%g>p0$6FDW?)E8r|yh2u{N zyc%Jf*~M>Ap)G9UHxagtP5c%Cw%5z3xAFTKv@`DuHtQOe&`Cn?5co?3zKdVmSFBYY z6Thw(%X>`x24!mryt7`CRUCgy;CwRLRnHX*!gjMs*Ae)8D)a$De#G&5+FkV${viqM zVJ|?>Pn7&40+o>1$N2pP;ST)lW&Q>#UCO+Tod4E+oZp*J_8aFnH0)=M3J83FHUES_ zf3PHRh+gv z@aG}$mk6q5slMX;w|F^ki%`_S=J}eyKGtX_nKai+UNHe$Si4;~I?IIbC}k^4w444m zO8Eo*=MnlN{T(E-hyF`s`V;+~RN`m)|D|%j(64Kd{d?&TXb@8=f`b~wu}|9+S2ak; z?_}1!K{EEEEVMy92bkEiK@$H&Sg!^tc9Yq44H9{XN?qT;>pBj@8>F)g!F?Je{V175 zG)UPoD$}n)%*P4Tzd^R2!2c}`l2*a|fejL0#k|`ZB+A41Aq^60t7TwxgZS%M^H?0z zqx=p6HX>+5gRE~th^axcPT}Al9G%9&=mtqRivx3m3~gop*ak7QAtb&*;@T1XU;`h? zFm4V*e!(7!U2x0UfXiI%hT5q!hzNLj`n0 zKlH#5VJYS`NFnq;*&r!Opki6TlIQ{z*K-Y$0}Tst2(w@jbi-2Ufgb3G?a;o4r3(mD z9Pc)W6DoNPQUYD?*&4(eh_RNnf_9ZP31UD#%Apy?L&Hb(!&taqYlj|~`f-DV2O|Iu zh03-D@xoYVgXCVt@t61uVSW(-q4Et&)QvbW0Xl8FSi9~_*uz>ucPVRsHI7d-h_MIl zEe*1)Cjomlis>4J8XCn8-Pblsk^u)1jbiD=F-(KjA&t@kjYAtH>RJN9c<3C~D9fN5 z+O^{`v|ksf@Z0M~>ALJ;ey&jpZ=gS;QQD#5 z#YPz#PWzHZ$%W44jgovL<6mhMLm<)+pJ~1Ghu}%0>yfiE*ztiutBM8{flYU<3nm z8^sD8Z#GH=%zCSlKedvv9f8pKexsE1rGFzC^rJGH$P~I@f|2oG;J80RUXpKG_Xj0X{z5vY`wkGLp3k^oa?^2Kgi%I)i;;hyJU4;@8@{`NVQ7 znRWMZ(+T>o#=$`PLw#a}u|0j_hSqC*5<7@~1M{K37xSUzI-ev((I4jHQ!Z zZew6?pJYJy4L&J@{&1hf4W_hxe3A!aZ}RaMQXE9!UeL7+}Q_w7_)e zT1ZA37m*Qkzer`EeTh#>p=BABfvF_s*ZQ-35_lJUg}nkjuMrqJSNg;ZZOZFpqBZ1@ zi8f%hPx4{xTa*eK*Z8DGV;*Z}LYPWLpz(bw0xcg<5$O2HCt2F@$81`d1zphWU{gb7 z1BpQw?1aXR_`93)KMN!BZU$~*4?v}WJpf%W6=r?HCWH1*5d@8!St@8QWc)}n-9m|B z)>ifgG;iZ=}(elZnO>N_#K-h018$i*V?K8PNT!PjaDUpHCdn^E-P1y8dJn z+Ati4a0uN;DamLy%Q4mnx=&JK?YII*&``yiLpv;hsnt{jx}h7IJ@|o6*a2f}*v$9g z9~z-jhd^lbvSiRw&-tH=VQoMWOl|bZe(3l4!~@;Ulv3+Ig(EWpT39ORf}^1IG^ZPM zo?%l$%URYQI{cjX(BI15f!1@J6=Udcqf#2%5ds|-IR6tctbb85sC1Gk|@S2pR?< z2xh?!sNBZ*cq%!#NfKbz5ClNy&?a#}%P<5$Pc#Cc(H6@@ZNTs*iF$wmcMu5r;WB8C zBOr9&*(AH6^)ALkmx=KYB4lKfjDm)Hn#2NAVH$M7OpT+OBp15xMF3RpLx4sz0-()} zQGwwcLj|Dq{w4_-M=8fP$x!HoW~jtBNfPwHbglmZ1Zw@z4vh~sNde4)#n3RWN%liO z^k_`LZvuWMG>HjXVPXR3zwx0aNu|LLGodpP#n3Sk#n3eg#ajQvD25&jg0=q1P2z{v zDL5Wa=2M#_0=i)=G$*kaG(OTK85$o&AaqV^5+5`svxmmpC^3d%0?KBPA+*DEXnl+f zwd0f~?o&el<4xQig?3mDJ+K8@W;TiP5P@MBw9aB_pfQ!Dfp%ztewYSRXOpPbKZitZ z+5ilP*6;+GLMJSR<}@;eZs>=WCz~WNk-#t?P=gHaCWUK5Gx{3n=A8j$s5$eU?%}H;jk&=b9uLdaMM1SqljOjn5MR zx?mwpT|@xrhi+)k;4Fc$FR*!`8-`9Ifft)>+{_0@i`f*=oyn$v#wF|ttsQ1)?Jx(r zmU13LWf@BXV_#-TpkXyvMwP zgGL9Nc`AW6G)bh!jZ{|SCMp5VFcaEgA+)(L$}lViOiUsG90lEQK2$zwl6+`~<X}SD&N%3XF75avn-&@?$ZQs@q#vf%P{CB@*RhFbvuC_i z7}^`ybaNzXC!DTH)umiDKa(7l;2o8jnc+MzSF zSqh+~N3-nK*t1#6q218Tuix?0i}BEXZ8N`qhhfbUHIH%EH}k7^{K9OQ)w@}WY#6CG zG>aFSZ)}#K&jc#%Fad`3X_hn?coTtPHZ0bTBbvnr~jVOGP62XwgIEX*Ruicq2?v$i22~-LuoDwJWCY}=0(m*A{a*AKMa}3?E zeex*@c?myLPVuXE0zY+1GGWmRr^Ex}mYfpfGBRI!N>ZWmCEF>!UWcPsZ~)`88SpX= zU;@m8R+y16)DR=kU2n6%-P7}!H)&M!X)T`8Rr=XZ3Pz?h*1K=S5iu7hJhCe3?rc(w!>l= zcZtBSvzDC%h7Opi9S60DF$Y1tTBHM}!KhUTyRJp-FfP1Bl-2l;Xb~%nzqv&mt2zI( zF+4Qn4Pn9?2#IUqRwxAChNHI-;%wo!-#GlTMVv6{>lS|NO=i1VBnNt-3uf#lz#4Y{ z5yriPprb9~hh-Hl{PY?DRV|VQOPX4w6sES*pU0XwF~Z+Nzy%z_lD}}YmOz)72=kQF z;)HSf)8dB(SDlt(mCSma7Gpk{Tz8sZJTra}T!-+{r@2uK$4RHf4Fjj0=6AsenR!|~ zFk{wfiQRy}Cr?YJ4Wnf4X(`nB3l|x0wpTqAm1qVf;JG z$Ke+^@>1#|O4?4~om40cZKO z8^@7nC90BV&Rfrl1-frLD=z4_4Ld95DvUd5fbLOe#Zir;v1i5LAwc3;@xXW(QbUF? z73NJmE5)#26799{VcKDyg?5coXs;vFsb?ht7Qh@BpM*ddH;Z;J=YRIRv!XOo$`{Ux z6=r7<5XQZMQXgxTcUGJ*>qFQ?Mvk-m^ontt&Pr@Eg0{m`l=8E)k_?N!fh`2wg@Due zg|RU3JKA9!%z|E6dYbdUefL>0o?%VDCm<}@bCzF1p?ohB&l0E<g~`l+usG zKX3>mVHQk+g|Gm+p|_e!v=LC}mz?t)8~ozC$R;1;=Vv<{-{+U&e{7UEi-vz$n^*i| z6$Y&G3wN4Q0^jmWvJ#|tx8ooPmize|aFCLB!Y`>XveGYhSaQiPQ9Xiq3)adqFIS1TWl1}X91w~7_! z{Xjd6`>|Dg8cSLwHiE#vv`Q*WgLYT|i(y%5tC(-5e}AhuVA_FJal?#1TKNPuh?`He zim@-_VFJu{w~8$jqX@$RBM-GoIrKuM9|I4!N)#+9Yn5c^J%VDGbd-Rw2>P_+W36H^ zBD@>{umommJV62)D;Njksu0j0ztyc`(OA=JlN`;cYvordK}ujf0R}Lz5#=xmcEAj1 zyoHLu1Xu*EungwIcIbj(J_5l!Xo%#vi6wz?Fcl`j9GC%}Ft5o*#u!C3D7P}OnT(+m zT3}cwC5Df~Vwmx7tN3A_;CLVcTQr5Qh|hXk__9&Gf+Ez=$yD;J z!#+7DNiYstVbQ1O#GxG*5>Pwd!o0f?v<-nU4JN{Dm<|hIHY|aTyMt_s7h^XKW!uk5 z1#E{MFzmB)5!5pbLez`*Krk~!Ljaxcnh@cK}G9~qxUIZQf7WnfsxIVpu@{~!z&1hh%2 z8HXWlVu#+)HgUm>UTu83#kk&WVu5iHZIS~62ee5C%oy0lhg6Io+$QNTEvAj%|6|0* zweevS8Qjf87&p32iecdW41i@1v`JJv8INz{LnH)FY?E@BHn~j<4QNDZQ_I( zkJAtHX5;rk`k!o*1Q<5AO{~y6AOA3LVVl@|7?Cfad>jszv`H4sScW5*ZENGR8yvmT zCgubtyv{MqgU0a)`v8Y9vH*v$XfuMLr3|5#Ab#S=F)TVtVw0JFtc@Qq1u32yDmDc_ zb!|5BV<=}R>C_-47UsZI=!AAy4ojetgrl}LDTF20wsWgbGP$muFQ2jpZfKVd7$4a# zQPZj5z;^EW#(3!0jt8|%>;t*z!YL{Y|G#Ur6 zeM~!FQbq9t?P8h9xP*4G!?cImxxXm=6FG)qliMXf6=74`#RJ=u5Hy?iN87~;(_lWd zS`qX_km9moq++BkY!@f=Ko5*xgrGD6!gOeS6QNHr5yrx>x7xV@Dw#kh474NUX#_(P z^lxqFO=%FHhPO+|Tm->nXx-k5rg1_u+)^X*qk^U--J zh1nmU7Y~ecoadHoOzb!>IrFJl;stKW#<+!44Zm^pJr*LyuiKO5by{Nw0>9!(;mIRn^pu)LkJ8@ zz95~j3>u!p-}DO-3G<){hRwJjiLd~s!tBQ`NXBzE9Hm^~T`m(IzaZ;j(+^ja@S9!z@i0=M|Z0ZfA#FcW6OTdgz>(HFn(QaMy0vm;^(XGY&>TFN}rlFdhbe zX=AN0!oDPP7zwjr5zL2iUy(Uuh?A|r2G}y_g#>(Y{o$!bi+<)EJtV#OVt2Z zh#si#Xj3=-5FM?Ls!|Ve+{e;(P>g)Z`@jChVWjX_)~;Ur zWAq5Uyax}Td!lFQRCNW=CqA#Pc*ry$cs<`gopssn+kGfA zN;rQ0dG+8!roln&*z48VKSdAHHLI(BioQ?xnYs_?uV12WNi+=zD&bo)E7jpY({or| z_%q}7s-}siAy=jF#=>SBqkcCc=H_l%V%ao&r?&naeV6VF^|q4eL3-T^wRNItaBvte zfU#(sL^4U(+tfWJ(c^R*)o#B;$LQ+RyMIA#-#68}A0}W@Fu#~o_xuvQSofED_ulA> z`hlOS2Q8Y`tN0XHo&78Kc-^JyN~53F>vpR1N~6!{AKSNc#=huioqkb`y81T?+NSRN zE&6rc0d?~4(J}h5XVm_Wm{tcDgmM$qf7Bh1m?rdW$L1@O+JBU#2DR4|Q<%DZfAl%s zQgy?D=%{Wq$MxjK8@<#q(}#yb8#H#Bt!j)iNw@_`;np?2XtA-RjM_k9p`>Hv` zbVqO!<_)XWB`Kzn!Fkx>Yt(O3Oe4BSl3p3dJj3;RoGsFcotCHGjU5yj#Qgzp=ty3qLMc=HRDUZHZm#6BE zGjv#uI`TN@)smW>W1cY0&;_U6#64Gfs~gfxKLrhq&`zWDCr$mjY3V0%*rDz@Nt$=w zq8@ybJPK%fMeS8VwM~)gZBMav18-(&ZdIp0Wx78&5!*OO-SCtt`m%>?j?2{63Op!x zsC_DV0!X-H=a{EW*Xn{=`trHInw(BB?UW1a$6YPd6;*gnOjY-#v!gO-DpzZ0VxfCg zN5^!FpEH)BT2*?D=Zt>5I{GI4urzheT+@``G$V;v)h6tq-Pk{<=6R+!f)e|4<5AT; z&$KDH9rNj(>XK(n6N2IgaN7`dM-9GDs5Ld5Fq_mBwb7gPPxV&EEFe?wE!_S?om|I> z9@IzOvcPnEa0*448L_iwf$4c&P}!~A#8w?sPij%K)p_;NEA>+ssQs->-9C_;v8ZDj zqQlixtLf_CGLA!^RTt71+=-p?tU9kDdZ6w%bxlLGO+R9(I%c71X;5SoHw07HG-_vU zj(VvvdbvJwjk@J|JjUIo?bi)HPLW^LeZJ_$`tbMFg^NrZgO?5FhLBs;8#Acac5J&k zzB!uRgxRT?G5Yjv>V)R#!97L|VJ)`BYvofGsFRzc!_;4zqp#DC*{+^wj-JUDyZco1 ztZox_cMW+`9eyeLx*jk6JZA6Zy}%lMq3$_Fy87?c))!2DyC>nOfaXWOSI4|a(L1q= z)VVD@Q%&8k{?>xeOX_W>dA8l4t^)e#8nyX!^i2JXMs>oO=tuS4&Zq}7sYyx^Mtg-G$Y81y+WOQmX&$(D)rLY=;gXs)g^wO`cA2>ex4!^tFv39ZwYE2 z&Kus)6d7mynuG)AWIA|CdbzdThtuHt+$hp2~CTjy4K5`??`r zF|F^lat>U7o{+Dqx1DE3`;e{~5hJ+w@SyJD}$4vFn*-;cfQirtCrzhVzH@qEeiKN^Bku*+4$D?H8R zVkWBnJE(LK=0}=2Naycr3A~%v8+DJ?ITSOm%S^&-(9A(PliKSqItyr7t(k*#6fZ}U$IlLJFeKd z*z?DBjoFRuxnj3qC&hQQM{ogG8c)Fn2PIDFJXf+|HFGHDiY_w=)1{e%bkfyQK+9-#b|B;SW4_#F zwqx$r%t5-pFSi88b7qg6sIFMa7MhQ}q{|MIU~nAA%EPM8u3eO2zo_;PW=1Y%X_r}q*+*TdwN_xx?=l0&X)l_z4$>PYcRk%D z(KP3Zy$rkPvfa0PHW3Oq4w<5^T4Q=8cxVD)o>qIkWBMt$9lPht>T&F#-Q%@NINmkg z6Woc}^CPw9UDLea`4hNT*C*=aJX38@(nH$mw5NN_efp^1)Ftnk<^=^N@{2!p;ngv- z^e-M($FDWbRAWP9LUj4+-JvnlbT#Ul(3tzUuss+WGfqFYO6}7l=0*L~2DN{__98ur ztJOyJw;nMw_0w9^!98Oh)cMqfJ!7Wn=blr4>lyQ??vUF5nwaPGFaNFfU&rg#GK+SR z(sWJCEM22I-Vmc|R|G)6Burh}D`u~5n>yy&m_J#gUf0De*4_kM7xT34qS~tAPjz~j zrecaZ{A1J7;G#!}K3(1MF&9If*v~zt&bvNlgl?_6;rf_yx@xuQdZfRj-qt(jF5TDa z?B3{j_GxwY2C7mvjm2M}9@OmkWNt{eNFB2gKe^bCy`WyYA!a5em>!PKz3R8&Bow(q z-LQ#EpU&xQ^=!?a)GdvrNt&T;mpwPeJgxsJ_j2>)*VVAcxDK(ay*@F`2+qJp)xuA> z>@C86E??d8iRsIr`6=AHPd$E9%rSjGUe`BMpY@Mx&(qy*W`$n*Nu6*rG92obn~||v z?beq?%5bam`o@gbM;}tR_Kg{#f1I~LTUd(iv$)%BncAmc%t~E>x}hJt_sCA`R?~I5 z;EdT^8;7c^ws8@>8+*U%-e!6%C}Iw`y;Ebio4yOKz#Me1+PdAeQgsht^>fwy&rH04 zKcSttx?4DLZ=ImFer9?;coaF0oTYBPg)@Em9QDL4F;D3qO;>eaurpJhFxW1?8GJI|}DzA~*2Dx0e)$J8;mu@Ba&Sw*I2g0|1ouJipxrpJOqpCR(K z>g2Cck%v7zLOuSqX--fl_Hotxjp}=Vs7sd`Yf*<%e&?(>W;VXh|o<^TN`h`QT=mROi*x= z*8Q4#Vpz=Rky@zr94o8-GnCd|M7!a?wP(}5pLXLabwG5?E5S+6QIA#X)@UTG$9Cna z=d|`ntD>a7sVWb@7_Z+)DLj5{6reDu&+AV9k z+EaU|eTK!{qS^|ad?)pNJU z+&{vL9eb{8jF~>|pH|aO+O7YsJyPq-AgOce#yesL*hXP1ZU5-x0ygRnjQeBUpW}X>%s%9nnT*Y2zU6$E-`M}#eDme` zwk`*2|EGg89AsU*lGOjr!T&=**bA)CU;i%wrYjlzHvwT}kc0#O-~U;eINIma&gK5R zJ7S_A)W#KXoZ9)Hv#d?-~Z2~UfQHQCb zDH$sEnZC);(5O(6&<{2LkfM^Ik)dIkp`p$qBSRxYBmKS3Jy&6VKfgU5=<~eJ`}}*K zKljh>?g94?AoCvR&ETmD2QNgq3R}US2hb8`lM22PK$D`3eMKkuk$;F? zFKimY%e&HpjP6tR?+R?8;YI-4%O39W>W^9tf#Ack*6Dsw`cU(2i-Rl z9_&Vs?Smc--l1?RII=rkt%jZtF6mA`Fq>-dut3t4gImGh_TU`;2KH6yNzXGq32X|X zgXM61@*{A(1Hvg;=qnb37xt!KnPDAxmVrB4vk2!S3WtNw7`TIN;GhS%O(uAX!iC^> z9^f|B;FF5p4EFEG?SmKNsq}u_#tL59kCyC5qf^0+3Om8$`_l=gmxIgtQ=bE=0JVLSHcl{MUng7?guQ8PLwq4Wau$dA#`f zF2O~^Kt94(lX-}-8~Kkg`is%fI}YN$PX)iJa6b6Ja`1(V% z2kci29`p#W^Yhf%ZtP0MBaPl-E%fz|Q0K$&R4cgU5qkJA(uO;54}KUu&vYC3&@fud zI1}7&IPGCv2!4Aw@0x1x?+Q1AC*WF@bxrV_IQbpHXT24?e+0!@jUnz#Fq-x1eU$YDZskQocyTnXWrlX}?$IoB z^dz{OmCk>GhLnR_CsF4k;6|`{3XNnOyaGqRI_~U)qrq{jXf5MZ@aJpkAme=S<^RxC#?|1UkEl--xD}jKLKCY{ zXTw`?NC~~hI3C%&-#R}vb5FUVV_c;qbwhA$9*)BIn1yUuXEl< zKCx(fJoxE-+>z;Er>yfYQt}b5#8)0HeKk1gbLw*}s-N5$tq8Y%&N?b&{bQIyhPUx9 z>;1I$7;J6e^#|x6V+Z&d+(l+w27diC_4x|y27hx7-(P_BIk=tHNJ|)7!CzjbonJ-u zql7qQoDL!NIv)}F;04#IPc<4*2|lfGBY61VT-UF{u|wt%`POta!Zwc+@}21Ot~VTn--6%JoKYslvf)@S^d5 zY4dSh!^eYbXy!QMzz&(fSA;n78fSd4LoouuY90{l5IE#TGrvJ$zPWf`oDZ#K91R}U zg$^=K1<%6D4%X&_U!$GlQO|0iwFmX7fk`X4Q!p)I9KIIWgwRf~HVOPb&7T1C9N_Hx z={z$j2M@y1%D55Sj3tzr2fxF<=$e@T-^2qq(OQO?Kz!fDuo!5kJ`<5&9dK+o%{+;8 zzW>2-l$J0#8WOZ*tCLQGt&~r;ZB^gDx3s~wDtHMR#VVE${zu_z@XKSk-U|Lh;c&w7aV)Pv5_nRaTuCtp zY#ArlMl1&hCdfA0MzD&^Q&{EmaOASl{O?)i!Cj|t&IIQ_$+%xfgMiZkgu|xB(c6QK zz2vD^3n5}E%|DHVns+e`r_pA{k>I&cakhicByo0v$IRed3EuTI&HMrO&ESA%I2$$~ z?QG6AaP{+?9pC}@rsNFl%fQFdXd+`bcy>D1_3z6&~j9m{Dm<4ADGYC6H#4vr;K)q$Phz%68ETnWx7p_z=E!Sl*# zEn~w*^!QhFkg*N?+PC;33+w>DS4Vx$g3G|q{6Z5MyTSYZq$S`E`c1e+sd}9LdCK^p zXhk5rGo5Ef>ENU<7d2tL<`Ml!AimtZwvta%^jB@feP#*tv{SUSPj4qh{bR6l{8 z%w`6e8CQahxQE2J8GL;{tz~Q|!1gSQ=pbVo_>mmC%Gd!ee~4n zGvM4Z1jc#edpa1o!HfN931fXB4ys*gCu1vkTu(aBI34`+{nXhFE(AZ*pGGpS1;0Fq z<}=oOh_3(!(`Lqz;O~dh3C4EtgCj|G3G4*FA4_J&mEge>X(r=l@D~ajKEjt{lelgJ zUy`{WCEJY}UG&FzIcEblT%hyM8jX~1H(JHr(4v2(bI%%I5hIImwxDn+SaX@{;alM? zg^R$|3LCcJRQfk=Qvh}<9K0Q;SPJKXlNz~=z8IIkoVB@N1I>Ka_^Q@-2R0pJ_>y0$ z07S6ycUH?K9Ze6=xjDvBI<}2h{2$oTfv&DK^`i+d7>|lgCAbKY)^!Z~^;T6a@sZ2`EJHos_mTGZ^qF#VUCq=1WW z$=snD94MTn5ic62Yfb-U&xV-i8K3GCfT}wYY{JG8jM)ckyudaDYlK!$2lH`*=dU#5 zOTA*sP<5|1yA0UbpqZf6)5IKOcY1HWak^Lo&FMwA<{QWB44>jqjd+1hY%uktv;{`D zF8nj(FJj*ZdF?3XparzkSUy$Id?mV$d_>JxsEj93INmT2Khqlv_~j6q@xgmOig!i3mrOmSHl;}ee(@(`|T z7j8hfk%vQAO{2cX$Y@t9mL?uri)<4&D~g+lBKGu9m}CjNdjIhc`f|LnbjShf)3ktJD}L z&-({_J<8vkb+h+3XiU3GC8Kaw@lfdcNE)AGj1X;Llfv2H_(=K;dPF%mB~qz4(y&U` zKud=f17;s9{@l6*Wo;6raM#eOL(y-(wjW$^%;4X^b(KIoCKrB^LdFN=7SIt!FS1 zhbdMGb*PeSkP}wg!n5$NYsos6f^B6L9iya(uSbWBWPv!9PbC^qa31T|C_28$ct}jS zfF7_?$Y$dqb;B6;|9&diV$`S&kI4bC%#F%F&N<@}&I-p-M4|DJ3Xj=rHXfkT4`HjH z#N#V}L8Wb+vl}qsrqJ+@VOvF43ylZFfXkROPx0tlaLjbZd;Joz7UlhhhXS6)`a)}$ znftl^C^8OG>6#mHzcU#q&8s8xQ3K$1wapT;BFt#q`28CXDb-IHy z+kz*5Ipe*Qa0sUr;aZhYmCZcA`7h%GG^Exzkaiq0&eJs`A_3bP#V|*Q(v4cg&N*xx zE@p`;L6buzhmFfc-wsHp9ze zR6=qd=X$VV1LxF^Dxu*$&Mn~Ljf|K2;V2+Da12X(pVe>V98&^mj~QPQ6Z}+ydowLM zW;`MW`>TYgLMr(h+yKt`h;vydyl}pVb5?)~znnKZh32(_QHYTohh23^s8 zDr~5%3_{tp&xnzMct3sxT{#7>R)C#{WY)&_Kr?9ODR}iXuIJ#@RbqC8Sn!c7g+rb7q?nm3 zI_DIQf3)NnM)8|-LNBCtdXbbQd%eZQd{Sq|je+0#-W^$*+29 zb>S)@>>kZM2&4HPtuaC+WZa`Q8&yKVJz6WOSapx4k~88q=fX|> zY3;wp1G=!0s4F4@SfBNz^jpRXo$n|N5@?~k&+5HQUwA_@VW%)It&1^L>gqhB^|L;na)d5yxFeNk|d1a1O39+7%Jr+aKQ;L5~CG7T;BID4do>K7R z7)jX7>~2*n!(b05(0s>4LJd7~X*K|NMOu`YupPM#-8#~da&L$io zI?I|i&8EU{GA4F{Y2*{=(XLG1>%(SL3&Qz&+TYz2OLM!Le%6IQi9xK#reb6+HurHY z(wjt;$aaHj(7Rw2p%QbaVv+Br1S+Rt+};VaJcUK*P9S``O31qtNS=WSekb638V;I>uZ)_#olQfW922s!hx;)XG2-kAbF>+;j! z7ic)CfrIJFAkzh1(R|E94?6>e7)^(CyB8qG{}oa75=I1et82?yNpU(|C1n1uh=!L@ z#{Y_Fc?D(suL$o9lri9clo9wE%J^RqVGB{l|B8ru9cBElh}cY&G0?M&{STw%iEp3` zL@0CThoPnybis>MLQyzdIOK(I<0I(edT7mqC}ae>xNtEBqmgq;7W&P^_>dY`cPyR? zV$g2}IuVV2D_e?*5Xo&bmZ92%DPk0Cy&vMXrK4eMqw^zRTlpsX_+f6Fy&UsvDC519 zWI(9TCq^TaA({3vb`{Wi)P%}q+d2J#zgnx{47V5y)b4D*1kGK#*d zFlomy<2mxRKo-KaW2qz#-i=+2OdrE8Y_u~DhmfO>!@Is~U>|o^TNQ7br>ljQg}n_G zJ6X%m#o-J48n)N$YtcUJY1m#1e+QEp+Z49fnxWNWi^BF=`G0VD#rA{kG_AwQTGS`O zbXXU^4xNt81lvdJ*Q29p=R`!;0Z&i68$I2IS{D-f7W)b+UGk3&JrI)zcTK0cPngz= zb>P#}Y0(t)M#8%|Q<=fJ5}fKSUuS1bPc0oLaiJhf(M2`_qR+Vah4Bdtw>iyT`pn9@9><3C_0 za(!kXT3?7tz2q5P2d#y6K8@(Y4>1H@X&;^D{SnsLjP}wzUF65`-D~Z&7btWOE;?Ef z5s1APLuuz>JcSzntSMitD8f+BbX|ECdtd6@TTwnXWmHb?pMB2sx^DM2_%e$nGB3ip zgHH;2En_>DilsDsj%gCLq?j^w@x}16^LfE_qEEoVl@b#8EOwnx0Ss01^U zhRrd3qs{yTCll291x)amQXHOE@l^VqaC)vsD)BV5{Izntws;rXLnG%RS=xWmjCDMj zwG0O}@=WIaDf;(ao~#aBMf2w)S;1!*J{x(mbQhKuY#gaHRBl7mZp`5Vp3HX-CI@X! zN3t4VZ6QxqxEDQ+{UqBbOWB7Lv?87?x*R7YbmCPc6F$d43nvvC$oKpwjcLQ z7FLZ(Uc-|$f_KxBY$U7r8XZ*2lR1uKbe{4|miP@u=l48Wa1HbH&bN`Q3F!QhCo4OF zg%0~^wt3`L%FV>#BKsuVjSV&n*nI*6on2%4k1qCGTt!{LKB@es`TM!1RidUA&bdTa z)|x)kR)95RUTboRnWr#sFUztR^&L)uerN2`0!y2?T>3q#@h9ih(-=P2IfwnA5|VDv zIVa44F|AxKID^LCmbpXHkC@o%pXiUZrkzw#jOqr~VZLavUm&}gZJ-z5#l6TnXxZL$ zd;`|T$PFeZCE%sLYK<>b_G|6uuwKyD8!+_3enPKwp>rE?T+Qe%M^p0qux;)k2Sm0N zURp2CQ5R5BC|xOlaf*Q(r)^;;#QnK}!;NKZAm`Xi=z$2vd%0VEf5w@Xgl!4ATW5X% zw^l<79E>drxm)iqgj=(JK`A)IZ#8`;S{tzK91i7-gEk}oGa97!S*3tIe;2DywpNy5%$Mq!?7Rz zSYg^ICTP?``gU4$5FXQOv1?2Tt*!*01~=|xjGBHbYZPzoj0bIAA zHhl@>z(d?P^eBvNUvPuSj@VwNigOFN`YX=mzG~cx=A7lH7OW?!?A5qgHT!zAw0?xv=7T2E$h=$&3e51?LHGsouVja>IhpL6dp4=p@k6Lhq(57>! zXk=eBEEJn8($zf}b}N5^>sp}Y_ob5aC}X#Q{lA|~7g-to03#`kvv)tW;5(4^ zyI~wQh#SZJ3}dU28`#3sczHSJzz0!#3myLj*MfPp;tiF5H{b$ zU5w8#;`TL|*6G5+)woN~H2F);#lM=?iH*>zhSRyrs916%%Ce1=17dmv`gAnsD5F|P z9Ya@sN5xuVxpCSbFm^o74IF0dqBNd!tb`^f(5)ucipktK>l%#9p5O+~NOWkT%(}$E z=&xzm&k>IXpqigtLp6hksD<50Oq2b%;7|Cm9$MiH@^41B6h4H>lFT_J3X^XZh5QXK zRMClMToD(vpsd>2JicrwT9Lvz;}J}(ITUddwk>r2Z`hXp16$2J9$z^OjhN3ld$?K% zeo1Cs{0OxW_A)lLY^6{?LvA+N0)Z{9EFjl_V?1Rhf7En*7Q zsLWVovgBCzXbiq(G8S3YLh+k4!wZ()*|KH52A1}fa&+?;?0c0XtJ3lRzb_mqeVL8->`xGzkhv4kXI-(1^6R@=3^dVNWgwmTRAs?>$cOTPRKmAgllP&F!)Mk)AfM`7u>EscO^odQSg=j{C? zYIl(KcVnKaRrrgh^|`4Haa zusPU#fYL%)#oRpJF$)9g7tXQIU|`_U2bPDgT`i>G@dYqt-H!y$-+6@dS+wL2&WW=z zTCd8i3w};51U6&WRPN804CZx|+Ybo~uao}+=KUQCQ_!j#_0&7e{CS6z=P@V#kpl<4 zVsCMk3Lb=gtw14Rs6p8aXoVN&j8qh)rHFydW!|!eyFf73bmRt=bFr@Zan7EH!5F|f zK20qYb>SQ^A1>-f!y{0cT5#HZ=c)H*V}BZ8gah*yV6fwUmKjB~^kn~IUPvgy8X^Zo zcRE`-ITyW*!PS>$M8Y@>cc_?g{a_fU_vZ%9ufj_Ya^9VRE)1u+55YJwf@?7gu~wL5 z)@feH@+x85R_?i{qR_=v(DJbZYZ_k$dq0ekn3Jg%Vxwr$P)w6(l+`>`W>LQg2bW=- zPlMxQX!S7Giczvg0V7~s_$W6pEWxOa<=g;njiXI5FfJO$jYCJl*p|QzA{{umOqN;K z0xo{yJUczugH>?CDAcn2O&p*T&*Pd$p444N!;e|ZaY`|bN=Bm#tt;S#B+lO1m?BTp z{xK*lZ>FqKOe_l1*tvmiCAwrb=fJn&UtFm_2IJTlxN*YcFfMzM8`xK2_NH+TTa6*U zKxSPdxFsE1+;U%zj>jlW9*>01SLs|ln;ZBYM(9GiG65X57K1R8F*;_ktWnxT7&kBB z29E!r%khmLGmdql{wwI#Bp6q{#f`IUFt+D#1Lt};YYpc_LierZ9Gs^XqMVHP`h?*+ zsUG3l^)CM@=6))j?*`18yz@BRu`g`tnJ3Nvic#;Oq<3BWr@;VE&!N9ID1qFKIHh<` z39!8|^YWEI!~1B;Mjp`WH)E}Lt(|J_uM%Uns0B@dVwL&<7LLt|RbC;6ifiNyW>xti zeE)%B)$|cgYzkc=c2>dQA{^*G#FoH({dwtG^9fz>R&+Zy%?;(1erYz-wjt}H^SIPK zhx53&GBNwEwDw)4T4`%Fs4!{Cg+ueDjG8!JncBKRr)>>@oIp&0oMAmi8Gs@iW(^ zm&|w=q0)tuh25?z87vUE2R*Sz38d~t%6&Ybt=Na7kLzl>8IKm|KgVLYU$IKrkEwM) z36vjzBM&M`0uExCaE)BZlGqPnT zRtrfrGHWxxh97C;3iEAk)^WAaOq;XKw?)S{@IWoM&aT09JjFTZ1U&p5PnmmCjXQfg zbIkwv;i(M4`7MUr4{Tt`BmcKt^A0hsRxP;C(5AKK@5K01@IxK>uLFmDhZBXfoHgI$ zr12c*da$9MbNOjBaf!bBS|!9nL9#=InhI2aE>J zZgASKj8Bs3NwY?*I0vU(c3pXo&4$LG(4URxaVacUdh|w2*TC~=@9(Zn1#G%nFTmY@ zD1o$#D6dHgcEMVg*v;mhn*A=VyUokKKRstE9(P=l7 zK;ds#@^31EnnpEVmg%~+mDRBIcg(MU*@7b9GM~KNe5!-+2b%Ejc`_E8f9Oz;fZ^78 z>a@drwnJqT7PvcsqN_L@+zI4d!}0&NVwUzNM!OOaZO!Owf&6!v&xuigVdQew24BZ0 zB)=WzpR~f?xZ>dG1~zf5YC)s%%VG16RP&ixqbt6FE>L4TVqR4*mwBtsaTCK1+gao0 z8~X<5JD2$#G3Fn*(TnEpHt!XMR*VpZE5J4l*R%db6BUlRh2y+dvA>N8q;LgTFDmwe zm*7x1M&%_mbJhxKFFYUr;%@Uku>x4z0oTSTHp|OPuzI^nDwvClHD1DQZ)`M8I}s+Y zL*^S|t=3Bj)wv=n*&q-)c;RhhN+8_ZOYrtl0*N{=A@fea;e*}P?gUCZqTr5-S)H$! za9Rmyz5TtgPOA=McxWR#VZ%0slLNejNY|iBrss6_!aJbA_pAKa3b4D2mk{iK0h3D} z1)XZlr*!3Ay@V8K%E;(?!hAw3*CU-jT{(%BprRYxpm1e(FCnHA*Q@UH5^@x-4n)Ni zuIb?=7y`IWZ4kD|Q}}dGFQHuFx?nWEGqLvJrUeTj{y zd3{HmHE$IwLgDi+bmgr1q?p$Sb?8Ei>aiHGEmi9kPPiXFz*nwJ4>x!T*$R6<;3d>4 z>;{|g1}$b&(GT6OaDIQZMd6GvFCiRP(ags7pqG%PuxS9sKsTE4i}^d9??5jhtUI;` z=iUBH13OfQdkMwe3FG2HTJtN$LGmCt>SLxUS_dk2wc-sNzwR_mr$hyw1E$^!P5E4oq=E- zik56?c7+pTP)cuZlQa?)=B!N~h1S#jzwrj0_iva_Y3-x2@nE}fiq#9>pxuqft2Qts z`|y0y#=zBmXp@(8OP4+t!>{k%;ro?F+Nz6>MLE!v;roGB+A10z!>qfXB05Oli9#GE zox*isZv)qNKaMGGcw4R-%8)Bo)ONf2YwW*tgp%FL* z1O86H`Xt;mK#569L`egcK>k!z>`tI+8d?&r#56yJrVmmAq0_zaP9Yx9#?OFLUGw!4 z22IA(UV^V{V>iZy$*2?K`&B-6tPwRcF&|B?TOracl`iTTj7~F~fb2^l*UC_7xJoRr zV?{8#7WJ2At3=<~7-o_Z$aoF|#^QM8? zqmtUtQMw4XoYLXU{;I##hCV^lAXQCMBS)Uxwl9 zy819n68|QK>Z8mG6)$7U@p8Cp3_D`5J4mihR_QIALS|!fjdg8$R63&)6INp8#JU!Z zmCmWe$Q(?yJAuH}Nc)%))4Ik>NQ~nFZT(s=LGOBFtn`ygTlpU}TH&H~SS(#LAA^n` zFJaJ)Q&OkB>m_K$D*@Yk=mI66joJuDxUMEhKdSI{K1rhse&0)oO1OY4JNfB~xk=JZ zF{S`@OrW{br4n5;*fjA19w9g}QwpU=XGq`cnm1!eLM!Eu$Px95JB~zMe{pW=e5l0oXB>j?a{~h_N4{6;tVzS<)1I zPm06E)C;((du^6Sm+vUTw255Ed zH1=S2E40(?G)O`|{`A|?{m=_=_Q@aU9_5dLL$AMV>`e9)DMMGrEM~C-0lpjSiZ6Mk zJTavhE`FBQKQCPt6L(-~eu0+Hk%laGf=zQV&oFfFd{~W&p{LA49*W4c3TTzk5)_Tq zvKE?<*49E6#cUg)x4@P$`-HRnOR&a3E9eczqv$#6QLaZ`kb0>^(dG35^C4K~hS+X5Jf|2I*iun{SFUD$u0@#N=B5i{fvxA*C z%ikq#T_C;Z6Z{#LyHXS`^1|o8ByIO;h8Xi1{M~`(zHAJpQR&h)U8M^P>*s8Jn*NGp zaP@dudPF6L@4*uAwQJfd(iD|X_FkOmoJF1b(($tv1D$(STHV3A5B+@m0=<+WO%(GH z2vgCq3~9fZT#ltpO{-s%t_LN34i|O2$lZ#XI`EeU&EAnVEtHn}w16{vT)bT>(D=jB zeKhiQsb}BF{a9Kdroou?1%98ve&ixBpC=&B8bpg;m!zO;Sy0(fg|lmIgaYyki2!}5O&*8I`cK&ZLmoCM|2;Ai>6SQ#TZPXhmd#* zjbAMF6=T787XOvS(mP^3*!d*+XGzC(WrwluC9*u=`#}0POByH&l~~D=C}N2u>7u}O z(=Xx#LB312nrV5^qGw*jZC$y)eqSQJud{!F{iL5|cJkNPdzNCX1RsI-QYda2R;gUD za}MoaCiT_r28X|J5n}|u59>)9hZH61zr-T)0*!JY|9EgpDyx%xJLUt2v{?+U!X%kX zac@e~beZ6yc^BD_rfTtQ@6k7@=Kev0wZpIg55w)CSe`Wq}aKi>7{+8pU=u?kxFPjo#;8Xpl{10VdXlTx6In$lkD{4 z=ql+cF%y{aGdHONC*s9vESuPW4?nuty+sJ6adrz;3mTNFmK|V3~mNHS@z(vt8~RF z&CnT6!^PKF593DC1FnVZB(=TT?OlVQJFVglrsmJ1c1Tt7aL%VZmW16N8^G@aV$S<(YD@KTi*gnH>7#7`Q z7z3>k+MNu;kf9A)z1mHWe=hZz#!AS7;8weD7l7G^X-;TqUhdmj%0ZTCMbPRrs4+W? zwE2kABHk^X_pyzsNa<+P?i>NYAH2GuaAUI9AS~j%&L2Y)dck-d7;Q5x#QoqGj;M9n=#6@8SAg$Rbi8OVi zbYF*9$nlYFa<2{!C>3{<#hauaJ}lb`sF8!|%0^_{3f?VqZ+dJKGKo5mwS9<^36k{E zr9&wlg7HiLvY+`L+$8lB%b?{x#A?%bDuQBiM~jPhxf< z5i#J%r#;=|GgL-T&#Q!_!cL91X!_%J&wG+~bW5f3pDV(}bL!&GRAFSKb^ zB+i1SNu`o4(kQVCT%F2ih~{UUL%c}a3Zvd7G3>F z>Kf!kFyM7GTrpvDrwCg48}!|WSmSEJ1xsMgri0gLujLvwdl#Vmd+sL0+1|u(W~1=M zJ~P~uV%H}!~m0^(S?F^JP-D{(kv zFIT71>mNxyrllg{G$PVq#6IjYF$-GcTUZF%70%k62R(YF=aI1(TG89?+qv!hPyx-b zny!2#bq}foH>_GDc$5Qvj`QVKA+xm~SrxcnSS`Ao0<|sq%!z$?c1#N9-ZLEXVa*x&o z&9>RoPV*bq7HC;4PkdO~z~8(E3c*`E4Z~rW0WDcsPYf`OfmZne%`L(OLkhUO5c8i- zY?XTG#~nfM93F{_TV|NYB0r=fFkD;#F8j!Ry9s*xR-A^O^D%m$-GbE!&3h|6r)bOz zLL=_0Y*Ws4X2T1UkI20p2t8^0|J6;<-Ox)}+EVD2IBLIVI+kB0^ri~M_pB;&`3S0mUUks3>?UZM%Kw{(_Z9Tzk#^HlX-+8g z!Y}0+K$EvioySB&D5}DUQKl5DKmxSpW2nGA4N8Gt{WbbRv1JX)gqBi6+qR=YMd0w- zc7-YxuYj&UeHU(vib;rpwd5j>hctTo_X$WKlYaAML5KUHc?;$ zAqJZ5Cz@M~fsh8a*3%}&1z^W{I$kUdiKqitUGSVvP0$P%+cb7Eq-jFMFUo0xV!)Md z&*^4^7VtBlZkb^3U+zpdImtEfjYv-?ig9CdQHc~ZBn_JTcO}mSZL=*Kdg_&Sx-xkRpf_Kk<0VpGZ57y;W|rXk znH8(Kh6|FbY|ivs%zPY)aPGCX$<4G_Xi3d&ZedyywB67W!0f}cG-%Dxl9_-H(;U!Z z{!+$>qUAvgzm8LPvU851BVpq3woN z!^&gcoW{NBfS%@c$>W?XkEPdK;>Qh`GY1qyYk?*o;T5f-8QrT9FL`utEeu0DcqVRu z)(Wix3E78Ls1;g~_y4Vs{x5W;&NF=&v}hmCMn*%+^U=47Y~UwAY{svFcVWI|fh#*w z3FA_*)0fWel7>e#gDd>n(y`WgUq_4m+q4*H!O$}NgY9@$AFw9MI~aRWJb` zrsYA)>F#M)46OlLu57iK8&*KH-*-pkS}n`)9<2ddQlO_@E40(lvg8bT+JF|UB0W6q z4A3g>(V`YZj1KZNjEA^4-UR`_pT6Ybq=(|UY@Nk zfL3;oRt9ZAK!~Sd6~t6%cUlvQ4C|ns4k4eiB*_V1~S)ra?6b7vtS{l-` z535)-w6H#&S^_i&v?ik|#B51+kmu|4a7g>8TY#%NZ=Eh1(Uwa)>EIJjYNCw90!lH?+`) zJPU4t)(TB%=MdjkEC*3-nhE8ELaTjPaS|H4Oik1F;EKfty=G`z1DW$up!r5C2MX?( zgUm6Zh;tyW0&#Mu$Z;<()2P!9FJcCWXX%SzlQYc2vESZFUx~Pc;dj$dhO1vg2C0W} zT`lLpGH8HN@CXbs`ApiZ!XR_7t8Nyj`4{7UBpN5jJ$N^c9lApi*F1{G@0I$Fi3Qh< z_GrYhJC(2_F4uau5~zb`BSMi^Hf)j}rO)=_+s|Tf*qAmaMIpWdntd!?*~{+kfn#GC z<14s*Qg1Qp7Ea9`Bq)4qoOLdR5SK9&e|=c0^#M z)k8PLv-Cqo1>eRA$~ezqV1nj`)_xdRq1B9U)7W)KBDC@e6!*E*uY&_zG2s%srS^ai zi!6gsFGu#3Z(!CV?4CgWpQDMvf(Fkt@Px78=!A9&Gaw|%k$pQxBcnoulVNZmUo!h6 zEM())4Y4$V&K#9O$h2Qd5z|x}A$<~U+AqB#HiEM!Q_umNIs~gVLaYrtXkxy`fSop) z%k(s`;R)Jw0AH@ufE`cJtpm~~UAmV>sDA?f;LnwQRU!Q#W@&>)ER9x+P2L)zc{YU{k*NLXc*DxGeQPsnHtcK$K zI^FzIiV%g48o{1P5mk5`A`x7jNz1EPcYq7txWrzC*pGgw!gr~~z9=_~dF&N2%ugfa zETt*Oq#-&xIC&X{Hha!9ls-Ksy{!xM*9e&otg7t0a6EMPl@!-E3tIY{%1Vp5sA8cP>)ti&*(G(8X;gM4xF?k6JKpl{aSiP zt#fvP;d|_ySd}gHb^Y>NP^)W{Nl=y|OqHoUx^C=BbbRd$XDAgl_tvZPuyJ z@$aSCL8TONnnLB^!>a1!X{w;-K$pigc9T)7f0LIPJJPrjm-Zo!1#Bh27b~mPcy42j z7wvmf@}WT|rLnsBZWu`)%k^J@=QeUrN_t%;v^;1P>?J>4sp2FaeW`}#y%nXfm%MeS zuHQ0j}ImR~R>e(~BvjRvI-t z>OPI&TcXTn)~d~N<>htEhPXn+1*7upTYA3#jrB+UDyfKBa}*wV2J!YQ++`J#VdSc+$ zf(;e4_j}~24?;Z-(M|AR8(9AZuTv(g5I%S7gxf@@l#m216Lz_Z9qtzWfUiE@JS{!s zSI6{YJbg0PFF_Zhd!p=bsP7M`lO3E;LvcT#PL<%?Q?%^|w8t8(5z6Xlz!_gzyi~3)rAeZGwX+D0O5Q5J9gSOS7q59r% zMibqvgJUwm?yEHGES|w?1edkY$+OY`zu-_b`UcM^2k+~}Obj`P!D5GwN6zEUNqbeI zp)YDQg?#EI$u9{kJju?0(CakuoD|}Eu3p**BLhnQFZo=M-tj93mwm>K;%R3Do;>;D z0uCyg2QX>&(&Y=%QokIqwVd1JaGP}(@mxYH^x6Y-;Ueq8ez2(^AGd@Z$H2COG|CO# z0j@kqbKL0uYH;Bx+T}(oBm1K@mni5Gx;7o`Y@li2h%&I@GB1mDA^Y6z+T3MWllZ|K#a|<<#xc;|3=C81R=5yUIUl>CdQRCAj%d z+V(TL%lAR#^*2x7O6Re;5q*4H3ZjT#;OcZ1`43I|1HkjyMz3MF!sQ!i z(Xg|1qrSglXr!_<-FccE?1Nwlr1`(%VV82~m4US7SKMKBgAG0YKlOS|o-*<_M84q| z9Ex2qUHu1b?|ND4A;v>@29b1G8tR_|b_Dah8U<1nM0KTAm!(c(IZND&wp?b7VhMWD zF~+`w;J99N?J|1H2DXi$p}&Fi!G)t}>2GjoGgv>7&in@Z;0W}Hjns``E7GyDJJ)^=H?!p<<8 zx4;RuDqIe>E9?e4X45g`EBZ=k&2x0^57siU^LZNDgmIJ)cE6yMhrLjx9s$1Sxg$7# zVehZS%uJ=@%afcVu}aVy8Gq1UvrCL}XIxeAC%6)9&B30hSj3ybg*kNQPt35$At)q=f|^mYOmOoCUPw5torsN;mNrXE zMZ-gAd7;baFR8DWU;I!sG3Y52i>XFypR@$i6D^qX<O+@X(0NJV zG6Rjeffce2ocP2^+X}plj$&X`4#a498)?N|*mZgca<5lm@hd z9pK1#n$yabf3R~L?QKP^gGZotQ+b8*$y|;KJ@Bt|d$2V|BUC)Y^#r-P?WWrzK15QX zr@}74&h6^Syq8UpThilxbon+}sb+@EMKif!@_dM5gs81Yp+ifX8bU-hA zp61*}Lp7t2b{<{6&DsEV&R;jca>&njG=|!%JgF}&`3^^&ZYs+NF&(-dd%&qIv&1@Z z;ZoNjmF1?&ukKOgxt=Gerjg#3p0wh+)YEm_%Q9Fa+Tzd^J7}o4<(O!A9F~X4M`xKM zI>GiMv`}Z+AV$W+YsV?b#}X$xz_rI|j*kT^F4$d5yL>DI{93_=A9yLPqgrB1AtCo|d<4#MeSfFSAuV96Ek!+@%w0X#*QN($G$*Sw6G( zrKQmQD#3a`UYlU*d??~RA1jhJLXPyKlgvDF5{l|XK>-#_53sv)d-L^&A~X?&kTqQt zS*gL@Wqks#bvX2D*crOet^f;m-~iWlp$h?MuWd3Wf}VzUw!}pgf^FUYKY2aQ^NMD9 z!7jZU?doh9D*D>cqV9C9GpcI?>wD19E|#GYPH=4xo)=5QK6mT&XpYxx>@UYWRnF1` z(UvaolpAafavkepk-WsXwsKwT4X#7yug+Pm1D{7KaO`Gd-FUtb8m^ljr z_8Hf#P|G%zU$`9uVjeFPn?rnw$r0Yy5-U2P$1I?QeJ#_(W^ll(bfzyxd(yM0j5-V#TJnv7?|nMHO(|_2&R=AockGfJYwZ8Q@Km*!Ph>9EH-Gp(n?? z&WvJBO4qZ_%VjEyw(#vo+Yvi`&Ft zOCxke^cYL1m+PFgtz&C|by3#E7I<`_1Y!3i5_;aISKCHMonIo5JU zYzCXK33@E-?Qf$FyD084tUi%BsOUZlio>i*0vGP%3?letZERV?7)cJVPEv`SQQ*Caik3Jd9eQ7sIYe zu?wa7lQCL8wOPLRD<;gCemp%I^fQhwpFUw(AtvR)0Rw2%6ieU14zOVWw~4;Dj6{B} z#}BIKYmUVJ0p^nb}i|M5&7twmfoU+=@y#vCYn+Pc0|$!@L)H%GLqZ> zpHVoEALbm$&9@3&H<;Un^UKR_%PmifPUw+Qv~W2)nt&aT(3#~Z!*CS&Mw8D9bbCCw zc9_f^(!uWG$<(pH(o6p0JRgE)1T9^Gb)cF>j<{2ZJk)DeV5m1k*T>MA6_}>s$56;f z>XL2g8({-mM{)adRFZw}9#_>n}D zt}%`V>&H;vw@`UI)5lQUThN{0!m+gQE!3kLY>1`Hj5XEZIL^_Ggb8&6w_ zw1r^J1X{`TI>r+jM^MvBG*JIFgvoSsCC*Iiz;;_QYYW~-bz%^D@Y36s-grH%-)c*L zZTxZ6hvu)s;qtK@OGj-w!gxFIYRmoFd|-21lvs(d{z=-f3e9K)M=GrU2CKr8G%d%{ zR~rpZr@%Y!=e*;7G+?k!gXN$22IXdQ-c~P91dVdt5?Cp5z6 zFVMBs@SYW1`yvfkg9SVX+&q^Stbtw$uAE2PnC^QL&3%=wt+5OZi3e-mNS1TIb6(2w zv_r?Keq1in=7XI}XlX8{mgZa3X$@V@#nH4DTvp)PyVf$mOVoT1zwM&SPBzcL?p-|7 zB>aqo&9ilu-hK|~Ru|X#i7Y!a6^kL;UG&a6w7-^RvxoMs!_?KEhQ60>u0x%Zz}R(g z)OyPN3-#0e6S_7(Pc?XBETF(S>{pFg0qyg-V)WIb}P? zPHIcj3cE_4Ml@VNn-q=*Yr2wzyu@@cekacI74yNk3j)4h3rtt!MzB+1{YCgp=8z$J z6djFlZCB6gvpea&Zrrg>{r&cxK4H}ig_e;@<2PG^#29d1D$Qk_4Bnket2bM^i<#i^ zRNA%~v#J>EJC}1EIB6dFY=Q23Nh1`e(NM|#R>%e7|bh*S5LiH?Ca}|+QOz10ygKMj)%O_YB(!tF&H0={M z`M_nhj6~PbhQZ%L(T-iW-nXdU0 zh5SaB8ApQMSMbOaj^a*m^Ho~7lijjtMn2amXcv~Mba3-^nzjq0suCR8k+$t(<^F~I zyVA8?XtEWozt1(`zm{#H*!&O9V@A`NJxE|}#rc_)2JFS1heEJ^%q%wS@vZ=N*QVP` zxB#}Qa50T2yAo9=-#~Jm+KXeKsK13PrHOQNA1Z4FH&3Dg<>=}%aPoB8P!8|Zfpe$R zA;y~9xW41MUpTmFIxo*eroA|UHhm7~*`OO{(9q8@ty;nQXIvLPw@kv-g<2~ZmeSA) z%L2b@uyq+v?91=5ovN@rDaLzg1=|XjbkKs={%2~mLg9b7Q6oG3?n#bAmNdNdQ!6+z z?hae}QRrb5X@#I)PXi9apAHteo<-t}jOpasa2RK~e&wQ85I*F&;Y}`kE%#AHr6pao zbwIT~qM=_Pu@kH>qJ>|;>DA!ct+WfepRczT&ja(c)wFh{r8{*xV(BJYp_gG4A3?`7 zgKazM4C6wbR%kAxm0u!HH@MbC$G*flwB1K5RPLp?DzF=jOa5b3ta6PVwL*HuodOPi zk8LuVkK$4`(ieU@OhLymA~M0YN}2^8TnSG9g4@T-UEY4(w8{q}CwjgSc9s8+wReG! z>5BfoXP;bWB!nbH5-|u8VuZ{&6Zb(71aZIAB?yAhxZgrTwN-Tq!U|0_F4eSELZd_L z61Nr&Qc?{~2~7!Af*=Ta*FJllB)rf6dEV#qdFK=Me1Ge=*WPEJ>zp~~4EbDO8$TX@ zdM@OB=Cr)JgD&UBIB>rd66lnPU@RC1T`z_7bhNL5RSMu>u@ zzi%cLr)(AaGRc=Jrfg$Q$UMA7*uy~==?%3mVd9baKFu4tT*7r_H@*+^f%T|6<>UJt zpYh;xK4ft9RXBbno;ZWMJ}lquC2l3|bvXpT!LIF~vmg1e{BW?if%EF+knskOIu1JX zs)yw+1BEy_HzdR`8^yxw56fc*iR$NaLt3}ZMX{uHak+K~&1Vzeaodna#!Jsl!C(;lE>Z$tZ@cDlX4goAZZzzlXH$TY}=L8^z@=I1c!0dcoow-(WQt zKLqfoi(^xOaa9pl%>w+AgtRuz#`lF);ylj^)C#I-yiO`=`J#?@ zF247;S=kQnK@nW^Lyr1;qBVb0|qY!njg;lpok>V%bB2XWR zdMwxRP)wRw-I*UAM5CUGdN$YbSK+3AVK1$?5w3pe%kwSAc=SKTbUW6`BzAoVsS zVoXHQ`93ZN zRkUQ(a^KO?QA_);(#I$EFlw<6ip9ZImHN4;hdspQjYf@kvIw=DV(t}}QK>yILvi<` z;_~)YjBdUTy1d74kAy#J%b(C}!eqShP}Hm?6?4ESjTHCGMxvgAx;EuO=#56r<0&>S zA;9LVA&nf9QObP|C$5Gxam>Q^XI{XAt05+*5_}(4Rt$}7e{ZKR-9jM_+k&%8Sn$F?-U?fj7at>cUiy7`WeDh_w~U@S*%c@?cMF2TMysHv#0 zagd!#6i@TbGURQ+?s(jgaY%)@DWxE7(ABrHFcrJs)F6 zzslI)DzRjYMPp1|p0S?zVNY>vp273`srg4|^Zfq{pD#97gfX}JltcY}NA+(8?{C^N?#YR|mE2MAVbbRm9;1T}hDF*Bt;D1Xc`}vMK-EpyAp24`a zS>-(7t42O*?W<^!_;qwKYUXA(zrREJ+9iYq;tJmSQN;?5b=1{oBgfDKnXxv#v(;B~zdPGR2mv>0l4A+Qv zG!N9m-q8Y3v%aIXM{RdV!rKWWQA~fw7>(M_ceMGarB%^*$5)}2T1Dgi|YMv~y}oseqyTX48Upe0p2QpT+)WVs=>xq~jo@~AvZ4_l+~F##uw zLVDWi3r#q*9UkF@S?cvxmir;Uu~r4a4!U7swANyad}vBgJ5@!Sk2Bu674F$k!zYj~ z#EZ4wdl1s!PQToYlhW@IUMr@Ge>@8Lof(!Z{2<~{`6_z$z||)qA2UN}DDGLKE7jFc zxq811uG-Tcl^>?x-0l24`H#x8N!7nZ)iJ)4gU)w3d{c%Wxa_UC7_NZU zuS2f&EyVX8YaW%W&#}SY^A{h}GSq|CqOL09KdyUp#+i(|x@uD_7t0{jlVd|$R6wv^*X%2W8hBpDu;hn!QAyJFpq)Gp2`e0B}~ zFGe;4V<{NZ)(k$6PocJRrfIbxV{|qOzY$FylQXjsi?;fcwBxm@NGR4 zb#wgV@=ML$*0WJB+x570`RwLz2MRF|ed%$zR7D?zmNL{wzJ6T3ieDG!4pzzB-Y}>e z9&VIBE_boxk9evBpG)R`j;ByGOYm4Sk8=#_jw^*DjIc8ga9ob>3teHqof$uQ<9mEu z;ypWa7iaq(xcjdDqKSdUFpOTRN+VB zVc0=_kz%&S6u&|2c16^GLL7h`j`+^%Fn@S5pfMaF$JO5M7#m<3gjsCw<0d4 zcsF9}pTa+!IEi=~aRG7yZ*VCI!TF-XM&d-`uZeSzd4orYL;n)|8*v&k&-V{8{t~Ck zrNq|jg7x*q1mSNjC8!C#Nhn1FZ$KuFx*;m`CC(roOROsp@!7{I`hrCr(7>4Mr0eQG6kBXhNZ= zkVFFBgswL5H8I|Gs`4pfye&lKKZ&EBi?yPJcs|CB*x+m8G-BrlVgh1Hh2M)f;S3u1 zYS(~-0^%UzxEELf55O$Mr4+XkyWLjTV_i>TBk=&@VB+_Pt;ErS6LgUzOd~@S@m%6K z;soME;uXY6#OsLDh_?`D5bq$)BHpbsu75cs93Vph@loPp;$Mh$cf=Iu5W5jyB{mY@ zA`T}0m)J^N!kMrCktDn(Llm)NLov_dh-(lhBJ+jNi#Uh40kN@2#G4V%e+XpT6gBKGhS-aQ z60O1;kwDi-#DgiWCk`j}B#t6(&}hU}j_ zJ50>4X61Z}n0qc#N?b$Ciln)Zg>fE6>`I(S%rD2}@twpqh;xYfytU`;+m90+s7VGRaV_Fu#O}niiTN=Z zZ(s$nCvhrqZQ=}KemKYd#)+amewb*_7p(#^)FneA8N7*g<3$A@;$UK5;uzw3T76lHz6KL+?06!wOD+I z52xevpC?RfE*2tw1j{*^D)1v$-a+dm(II|d%DI3zh&YY>Er=6igx^G*NAZ@##>pZc ztj>QF-6ja36&b>aTN6i7g%IK_Vl%OIil{FWFQ@tn@j+q>aUOB#SP}{-K^x*SGPEU* znkpJ-N1R36p4b>G;vI++iLFPV!I-ACd!-$Z#t4pN*4t&=3Bg*aBmSSt9Fea}(kaSw z^6fI~v|z2&5&yqS_|eyFO8A|xMfl=#oxg6q!}s6e=kKt@*E)P@^#kAGhkPZf5`XhH zchz;|YgH9PCNbY!@Yi*JQEDIh=5MpA0^i*5m$@!{Q_nn|WkFp(bA5Im+W48rG)P%$ zRik{X$6t|4tZK=(di)g*htMq<7sE9_v!C6X`S_5?Hi4_{;@l_jH*+=_&0e-}qdCqH zxakM0T4fiNKT!EIl~<^|4f~pzzjJCWw`*l?E!!qEH_wtF(qst+^$Xn@rANU2Wb~$4wV7D`w`HSqo;386Oipd1j!I-|J_A zzgC-@!nOdD`v#+=2jd!ZO}|;O6DGt_98>Y--B;(RQ)QzL9=5<=3-VuMZVy&;yG@Lp zGb^Uj?Fg)|$)qOZjoT8}m=o<15+nFIL_Fll8?2VWJq25D4pKRiN~42_C;lnQBv(IH2)=ZR1wT7r8prg{L6YQp^@^kX95@l96 zHM~!7FvW{ck*|k{7gJf_hk5vp+vq+7j}YoX+6Hq>g83h@wdRY9J^mX;%ujf7o=?n= z5V*F2n8!G$6Z0bk&c+tvh(kL<$fG!46nPzw+oC=7WG5ew2om@a0XHNP^CJS@sZ8SP z#Ak@L9eNqDwnGoTBO1_l=!w)J53JAg$57l;Wt<-?NT^MQgT&e%y@1$@;`T+N0d0pK zOswtDqlmQ~dLps5L(e2ucj){GA(sSgk6ucw?a{sNiUy6;fiU6*#IuPT5+@V$9Xg-l zgT(&CMZ|oEt{x#6?}-NZ9-UW+B<6c`&hv=_h*OFA4xPu(5NkX1LSk))?)PQv)^_Oe#C(U&7urD5yYL4`KmXc z*h=x8#GNUgL)?Ypg~VNny&j7EVZ?)o6S`4?BoexlA@hZ((1UmdaX9%i$lsIr6mc)& zeB$23#l#WBF2!p81YI8#_y`z}Al@l5pi6XIavmBf+6pAyd|UWLrpige=D6hBP7 zhB$|Kt>6S*5eZ3TC?#G;?DAZ6Xg#qn@do1MFGW0=IGExaiNlCD5f35;m2upoNJt^W z3gXSgr--)@mk@tO>{co|kV+g%{5kO;;;qE-#9wgc^F5t}G%}na-bP$Ryq(yCHpM%L z!-;ni&nEtoIE{E0@fqT;kk$Qv2?^Zk5Z|j?CgMZLJZ@|w;y+S6jrcIJuC0h4As$2>I7*yMe4IFu{3rPQ=M5H+aFW>C zP9!{o%%|WCB{)m*`^4qQd^?dwehxgJuDz(wh@*%l;w<6>I}(f?LKWaPQ&Ur%i8DDoSS)mb9^3A$=1;9tewk6%Z|ryz|Ix)LW+g6hNt#5J^d zC(!_ZWR*G#iEAR`pU!F(@mdtmR`cWdyOU5x4SEmd-c4l@4X4+sjs z7jY?ZU1F~{BJNEb%9+o99}=R-z^}r=KV2emJ>m>vKjJi+qWZ)I6gLuk&}Co^h^@p8 ziDQv@`?^LXq>{m(IGeaJF+KsA+jUKd{fV0rM-cNLam7DfB5@#bDseO7gF4#(Hzy&N z4E%Zl{L_^Zw;=Xlq5~%4FyfZPF~t1AnE0n#Mcj%wgSa(u5u^Qo2nimNXuwQtC6JPv;@ydN689j^CJraIcNFz|61OMr zB{)GBLqcydL{WqM`bpk_bc(MqAo=;6NyWSQ_24VIRXFaa!7cIz`1}blo6Lw{55favuNNA zv9+sUK3u%MmX8q+Bfmr(MQkVG_J>!PPl7!e(uf_1Gl?CEbBLXY^NF2_J@leOdg4%G z1Mwi@Y7&k=??5yOE@Vg{c16ZN-A>}_#Ak?W5El~jhuLwz&LBEa6M^UVCH6(;voM0V zUIGcrN$?}iAg)iGM{Fc6A#OnIR!ub6kl0Avhx985ftxE1ko;?~5O#397_ z#Aae$b)FyRzf6L^D&Sde;xJ+haWru#@p9re#A(EBi4PLDBhDdiPh7~Eum2rLC?i8h zVz(M%1UeD>6I+Qxi8~WV5_chvA?`}Nia3mTCo*qe*NudOWav(uP27XHkT{%J=O#MX zlh~KI7jZCgZ{lIZ5ybP|X#d}bgj6#0CC(!5M_fo8N$gTnbf7c)@x+6O z(`wTGe=rGIWEeu6Lp+qYka!reTP@Ln;l%#LBZvpJ=I2s$y7!1fDL#@oB7uZaB*YMp zCQc$AL%fqXia3XOEO8O>IN~zm@x*TKqQlX|31K8mAR&%;BJm31NyM4NF~r%#lZgw7 zrx2GBPbK#C5FLmWoSZT(Gk#Q;v$M~AvXGm20tSnMx3h6(_|7pCxb3bRM<*< znBrd$7Zaxu2l)#BHsUC%zn!=}#di?L6DRB>A%lc3iSvke5qs4W4SYr1o;aO2n)qwt z6~x~VXA*x)oFzJ#pxaGC5gEQC_V5!8?ja5%-b)-$oI#vPypQ-k@qXff`Xb-=#JX;r zasFqLFp>-hh@(`4PWJro=Mn!%>}(Vr_=(uq9htBHhe>Eph9ks@ z+<>p6#IY1VM!cIii#VV7II(jBQU3&SF!4#^k;uG#-6;~{$#9xDjreEcGsM3T7ZaZ$ z_Gl;?JWCu-e2zGg_*deB?zI2UCLxmy=ZUR7M8XTiMHIhC?A1ubbBM!jX0F}PvW!$n!awgExtd#J7m8#D5bf3?reCgyqEl5N8nICO$)ahq#2eh*%dc zI&habpsC<{#8DLgS1^A5C&PU*q!Rx}oJstEIGgw(v3-DOpqSW;_z`gg@nhmB;wLKO z@}EdT2^n@1KPAo~enwnE{G8Y=P;{V_xIOU;;%MTR$o#Y53gTBh&ey*T63WPsOZ*xc z|L}Gw(ZCyu2N0JNhZFO&6MSbDOU&M3=^eI1R`>r|;i3V1G8lUbb|j9cgigeX6n7>r zAl4IGdx`o6;)7Jb8ZsY&VqzCN+W)6f1y?lSpU%0tNKl;;1QFLD*7X)~o{Yb=Qakmc zopRAmwPGIV7@i+IV)EYPT;@=?Qse1h9jQ{lNyu(YI@usAM=4X)cRe(_vSM1g2P+t<4+X+Z; z>&3qo#Vcf~G*THrWiXWmk-}F*WigeZ{e^C&GLFjmR3=h+hRPf&OGVjSryC#=I8*6H zWhj+VRK^UjP5IIMk+YrEX5Fy1rYBzE31@H8{lvFHf46OV+xOc*-2X z65;$Q^FS;boHmbOMuIFY0iaaAa&3&W9iIAKT%A^TV#Vc4g=`$}cNJi5_s_ zwAov!Tj}Vg*Xai0KekV;Y@E%%VHA0nqMXb_2So@UA#e6!wW00LW^dmr?YkLtI&b{P zQdM7?2gLnsu8SRAiGE-2%C^>`3ApiR)u^ij$1xT2f_yBhPSL+;dd!Vtic%^XTf`iz z;ddGMkMYBHymI^DZ;}y(m zg=kIY6~0s}q`5KZK(saRZW4* zQKuYpZI7x=zO}$G4@lsK|8W8N|8x3J|9_qS3zgGv>+qX-ay51kzREW@!{SoDIgu@g zfq$8&NRcCK$Nn22R{G$LhnPI`a*PuH0t1W$s{)wdUM5 zXEK0hcg(X58B;{mX*#6eG2>H%rwi7-557g_(Ne@rh%Yh+^75-9b0=xcOeiWco1~dD z!RxL$*zosE;qN{R2HZ8bW~uPuU2{uz4-VWlk2Y+XBclE0+Ungiuaww#kbd9nufI7@ z=nvud`(|r>&jkW!s2#;QU3WjOUH|#%bo}2(VE)gX%P!mW56n*__A|ULHushi5}?;3 z^C`X|t%%nuH*b=f?1FE~&GGDu15M?cOn>b=5zc_lO!f{sx>w-B3{kqbc3^STk&Jkc z5C>LL;ed~stgs(#N0~g1>EjNF8W$kYPWI9NNO%JJ*vSJWX0vU#ldDPnVh;*i36<^_ z9oTGYAaMac&DoLF$`Y2JsB}kd99iz8rKTh6a9mifLz#oTNP6$AZGofQM$&)uyU_2z zPtLNp!R1eZ)Bc1T&T?IS&l`fD0MjETR$wE&952nf3ET8?B6|W24e~90hugyZ99*km zuIzgPs968z~ZoAFSx3)HGE zzYdCX>Y^_0L)=8^K0#m6R_-E?iF)>Bg#+5vkeeAYiD&BJ{Ti}Q%b9vnvw1a9ddBOS z;-%9?;Q@x-+!S0All3giMQa8Q)sUM8eN$ayQM!MrXIh7I;yrfh*%@-UyMc=vj^!od zE;S(7P3|Twbc19V%Q?+KSS1tqc1E z_jF=iD_-KU-i2ML@W4V(?CxFSL2Y5Hr(933)%_4odCJXL5 z%p*W_Rd44~p&HroMw%LK?8d{GM+;$91YasW= z+J|_N3l0tCo@^KNYbbY++{VG0hO)`fXq+(59tS@+l>OOi__v|l(2z1P|q|-gZV@thVuqIY#yHNC#xMyi%XO zN%V3*02l;%l)LV&uy(_*~5-~2HivD(UQCsc7@8b z^y|M6?o4RdM()hsKy({9iEaDpX&ag8o9-0BWALV}?5+Qo@C7tzCr1Q5{Z2${?G>f_ z7>P}zr9N|^uGVCU1yJY!Y;K2J@b@x=^9>wnhxy(R9)JRjMjqHFq8|Gx-?GYlXE5KV z5=*C$!}nxCP1`OMq9t8oM>0id?g8lCUao71|4DGo!!W(Q+(+^~3`g3_*Y(+lh5j4t z>>#&bcWswC;2Lh&mnG!pC%~bTJck{FMV;irpb6PR{((yOa=VIE?%-lwt!nmc^Lb(U z3_i8WA(Hnc$g;{iq`1p4p|f0ONWUz?4Rc{?7wnfcS8&|#u%?UbrC&$<1on23P3$#X z?;>XyCSDOP-5-$BRhA{cJh<3ZUMM+UgWh5CEW?d!B0l&pI1`5be+iGnODGF!n&lK) zYB;e+Peo|@GqRu-r-Pz!*;U`juB*C}+6QmKW#5(=H3Zgh6Q%ptPHg-%Engz$+wa7N z*A&5e9?-L=JY90F4TpNlmrbv|gl_Q`W$l*E%+8{1%#-4EwXDwUx{nB6h97&$zJ|;7 z1omnG1-)eN0pIxv_NXsP_W{lo3rh)R805@aQ)sSHSZWV;X4Na2NyKZSYfW@!Aq_=z zJw)`zRXG>t^_D+mrSO_lDFj5|&PZ+qQzCHfUj{oOrZnBjo_YDT;8Dv2>X{7Q98`3n4jshbo$k7ds`7W0M3Kt zz}{(Afvhw64^#|THu?`UHwp~Z42LTW#c0T46DaV5Eq;(ZjIl%T`(QbSWkAOvazwK} zW5U!WBqB4-rtP-YH4ny z!!z~^8R}_<=S<&2r@M+{Ak7`-P|7Y=7;J4v$lV>J7SUfV8zVFC{qKvE{m||g!r1W% zf?G|5)F?dU-8o6{cW^WcH|n=y1n!5MJZhROa5LDAm7DjQIz`|GDt+Tv#n7x;tn-`A zm=>BdRakxJGB%Y4A!)JSJjU{<@|>x#cq|^>Xin!?*fv(K+rl|k)LcxZ@3P89Qm~Pa z8Ph`br@@`Ea+u^A2Q9|QT@7t#h^qKWap5>j{fM~hOxTL7pEXOwx4`jnxHarETi_ns zKjY+o89QqGEn1$)^tI!Ko(^n@VSYQs%)%i`8SSp2B0$EVg7SSxU zBuebdL=iG9BMWMpB^xauv0lqX=r)zUs7=GSd@j0P9Ix|hWzUvS=m@NwhCMuTL^zMbchhjZA6DSSX>tPl5&BJ+6I+Cx5T<2R z`hHNEHaS7(x6+=aQpn{bluehLvTHW~_vKusA8|oc-3@Gp?A>p7j=&NseH|PsI#@VM z=T{v+xKpUdZ^G(}nl=sh(c--`dm==1VSy0p3%tQ;G$JIgu^C$~yn&lu`#vxMZm1g0Z4tmbS!wF4W z4P$2F%G)JhWI05o@BGSaIhbv+1Jgpqe^G;|X`8IP*?u25u=glZ;Xo~#=61nsTvS## zFfBIk7G*&V`&2qpb}`JmF0^^Kp!zJihv7VN{0$g0ORgJv@rD+sx?fcGpm?@lnge46 zA`(W~eZF*HzD@9HQ0iVVXO>^O18Yd0AvfX7Ec{fe_2ddXn1wU%CRI&`nzQ9E*$$g+ zHm*oPA5gpwYY|#jP8QT~h@Ix)_VFJkjtvG& z;5QG~ufdYwRbWNz_gq6eA^Wa$teAtzb8rqOIkHt0Tjok0)U+NX&GFmp$m-gQ$TCQu zCr^kxO*q4WDr|MESl-j-==^p$GA*>;ku0cb2NOHda@3K<>qV%!0Y=Too;NpWjU*r% zMiDk}h3)fY%fR1=9b72m#mbDOI3@V<``3|a6LC|U7}T_hNx_C6IkNi{x(PuGpB#$#)_ZIqYA5r?GJF#`Wv<>H~1V3cW z)5r(%7RiBzCgdIA1J&Yj=QWWy4LZcjL#5HawoUQ!Sr+tH3z2i7NtC`H@k4L1Rn4EK z^V{OgIt7c+Dfo1W+}5zoEKpM5;u6`%uvro8ISfjc$p7jC+X(&>iW21J`oG%>yaK+7 zcmS}vyTGkrO_aB?t#BhzeoqP*3+eZ6%(&ItP&}<(>K)?~7X3;Ppzm{Xk`w zK=;|A^c>3AkVx&5O8#P9?Qx7Xq2PVZ6kXL+h^85g8Rv)$uVB@uI88(6YMAjUPK2@$ z{`^$lVHmzh$Z?Bd#VWa-zI&qJn~=Q<&sBW|?yKeH`m_&(dIr)~%WWmL0`gbOJM{ja z2>D}Ju|{rh*sw-mw5tyI|iP5V;<=Hmi3EHtvGi>+#cy|2MFA zJvNpEZ`NaDWzcs6epZh87QWbkYA!tB*m*Z}N|rYmE`KK~&)*CA$#NS!A5eRvd|5v~ zQ^@Dx@kY6q)ax*G+$2xK6Z*S1;mH;02)KYeN*a6wrUDM#s-wcaAPc-wa3Sh?Qt;Oh zk%FHpGGSf{&fn=j3-wR%-;6m2W<%U&?7_?PLhhCWu3NANFQLa49Gq>rLcR}$TjaKE z8`S?y-f2krQ>fFf!}-tfoU!R9c%{l4^cQal{b$Hb#o03A4iuwoh$|9u%sp8BIX~O| z0M2}lCk$FVfS0`N{{Vuv;siJs3!lSdxVjblu+--M1)g)$$37SO-(XF{CFjr!4WrZK zfXLG?315lQ1DtV_DNc(nkFTBL%$}3u069E2JG0ujQxcxk_}Zz?j8SaHE67ii{q!}; zM7ICHZkrq-O>lz#+vJn_7(+L8)3puiZI{E?2QY5Ce9GYMDO8IW1n-dB8Nz%8H}Qix zJLEO&U$EaPr?JcMKUjCkW2I^Suw$1zk{#Rh z6{E8>JG}f3(Y-k=+at%~ zq&?h&DN11OUfk%$1c6Hiu0mL5ot9g|#0+^p%ZD2oSR=9pOxlMhJ5RyweTbnZn7$wL z?S_*5h{l!>|2;;N;nnx}wS#joEYFlzN%6r@>wvt76~meX@@gr%71aAdUWFfhzxe@s z9MKxD_`osP3Lo0!QE2)b3#m&8bUBD>GJJ6m)!XnI3n|nLBM+gv5)K_gH6QByh^k43 zxj&+s2$vDrC1~{%s{RTj{e;6dSAhpV;Y8-cdx!B%d>0FxJB*kPmLrJOLt)nuIaZn- z3LZyMz6MK=qHJvg#T<9RsAGsOZ6W&@x@NY;AF)6=55CGmxnn!1eH?Kwd~h6B^apSW z3#mnWXm|q83&ysG8Cc@{I(7o1_n`Voj0Sdq(I+t)(*eH261Q@%P{s-Dbqb@6JHnPz z7>(`-cd_JOYM#a^D}?0JxLOy&vD5Mw(y&et^|QQ`Wy7tX@dJR>iWeOqX2Q*1XHP z10QAMsjD{K;8`|qe7=F`^N2p(A@@AuD(G@So{lFH_hBJT?*R=iqIv_?UPO!xhjNa` zVOkDi>z?pe4&n~z{Trf3FZk&<#1A3x5^f<+!2&EKyWVi_5>9oO-r#*12Vp5pzKqc< zIK+!`(C4D5V+4%IMbqL4_y$YdrM*Czy@H;;C!6h5B&2`J_F10Q1*_5TZmF@By_%t@=^HWD#~vC zp&U^f*B?e-Lpc);U&G4I_){r=;`)K*;6L#@xZQ)r7GR^znlImUl;%!?Mt{qN`eRdt zegfPIaSK^}u`Qwyzl3b@;ZmW$qSCXORQcsu&U~E*{wzq-Wx{h6{`^Pw)sI;v@T*O? z@%zvA>jn955T)n0mFKKiVEv~O3*0P18=?Dc*@7dwOCv}jV1+)4`h5+9>24`BM#xc;Y;r#|(Qm<&dzX!ODBMXM1!^!=v|b zKXDC8@5xz)L1%>;a1KuVi&KK-i+|<)hTnb_x?c_)xGy(tk$zrqF_oUP_@^YXGr$8H zj|2yH`a(q&{eN;WerMYDKl!*c_peXPl0bA;kuV%yYfixYRB+5QJ%^Rm<^Jj z$}6R=*TMJ*xEeDudJn^_aUMb&x#ho>r(kIY4T&pe<&Ahk;6RGf1@~9BKbbO-;U=Vu zopORb2M2rQ61xa__R4yx>i~##P##GOhr<|08c!LCtyo;Wwqpz1c5a$CpK7ALs=}npJJQjri@~SgP-I1 zLVPvc3KwcB{n3sq~s=VB={Aq5E+_>i_#Ft@N-!V zR>Z4O5_Ecnu^tpUt65OfEIZK>!I-(HsJ)d+18SNj9W8?y(?Z_8s3FuQ>ulkQ5^g6o z?qyrwMv<7lZ66VR2A{W8_L|cA5{?$7$3Dh7FU9Afsr}1apg+pkcab9IKL8fCQ@r)2 z0fKkH=ZJ>Yg9SPdh2!m%y8Rmr6?}H2C=H$xpJgKBs)hO<61zA|goX?!3u-gRljYz- zogTm3{C9+ib$bt*x5s9*bnQmj`n6Y593}j&{B9Q<;Im_dan?9WmXFCOS8{^>hQ#iZ zqe~PyP>Uu<3JxBgd>uidDPzf^o{$xNPDM+p#I(>jtsT^G7QmgZijTBpoXtK=>A<8R zF}AMVl$ESSwJ9P~^97>xSZ2q*uNc{#3-$Z#*u$A3_9y=0Gp@D`W@+fxL-9%ILKrby z$c7*IiCEF6d>o{sc1#Ne&L<0M6=QvWp+3)!O`R)3)#i}}H7!d9uEqL7J7%Wpo3%8k zO@@O#ly;J`0G{?x9vhm(i|XB%!lQ6yywraw4C$%t&0?nEviT`mF-2uKMOW?Fa0>mWSy0m~#b~)@&$LkL3d(|-W+_68 zw*y2n>JvPD#ROr-%e&4Ooi^*0?@m(PTy z1YTlNeVtT+FQHyv96aw`0`EZQzRDbZK?NSeXn&Us5#4o2lpc7pv2xA5KU?3$ku4|B zpnbw)Ky4cJGHH%Z-`kOCA^-i*yr1$Op27OKpR!yZdQ8;#1Uw>@Iemu^4$q=Qzw{;NwT1(S?({^<2kc-Cq(3H_#;wjuD?dcPoP?Vr7PPA{rW5Xda<1T zN?g#aGs0WAoD`V1#F;9Uo5+N2iqe%YLuRy*MW^$RtvU&%}Khn(>1N)f4WpoUrC z>p{4ZX`<;OWDQch684bUbdl1XsBE&7H+j~HX|caF4{BPIsY~>~IAU6O>NaEsv7-s7#)-MBmey{ZZk7ABHKd@s!ZrVahCh;#E;$8%!9k zY+)IjM&Pk{1~ea`e69a5U&Qv?{u-ft=_ujP5-uOBr0aLx68b}s$0;N6Y{dF;$~T7M z|AgxC2)d6~nj1CI(= zQ$d=b1n3JZFk}L5hyQ?i6O?2_btxPV0r5U1JMf&S1mcILP7{@6z2qchfc%L{TfC&M z&Lm~0p{J`*=hlGJlN5`j)PgsY@ZjJ(ccCwZZ(@`&QY&AmHd*;z|8YGbuZCYH<5*mU z$CH&z!3s0F0Bsp-dCnbKUasp-^conHNYB& z`KHx?%W=y4Qd2hwo1yfUhP%N!UViEZ*Liuw4Vury_yadcor&D8CfuE=d?o2?!TMRs zQt2ai@SKfPx7!`&&c-9A%kJpgi_BI3dG3vFO!=aB+ zU)&rbR^a@q)&h>MP|ipnwty9%;B=R_fEFupy63fojFrk?Qiotz`>AqJvTKFEcdvXe zd4|B7Rp?(E0%umEUvGwKYtVng48?1dU+cu36<7A^>^+=V;}&>z5Ap*UF0ECT)k&-f z28p0Q245>MH3>)dnFYev;n{_xv+(aarIFO49k{K>Dc{r%_N~W}C~XJxHsHu-oQ2?I zrIj?M1B_3`5joKT3V7M1BaGUJ{!cr?n~muIuOpn=gk`@@ww0iq)Jq3DLBDNEgZc+M z^;B0XNA-Wak;1+iW4G$+bisIA%+XG;b{j4?K2|8+rr^m&D_FPVay-upm$oZ=rQ=rk zV29F1^6LsmcPP`OXk`w8Y8zy-PGPjKmgGDjNo z6ZHH+nI$Fv1V?{B{nSt3V^cnsMjo;4v?(T*K$m%YO%V6H4Q&9?UzdY?3Zsx79d@J4@;MedztGk}T!?3O9dM zf~34(p++`tIe&R%vt}!8n3r3&SOr;KZ#HqOPInsb>BLLs@%OyXD;^0(E$Z!9G1Ovt z@NpDN?n?Dy{K_R4jc<=U8r6~Cpc*TdT$I%%ce^TAF1c90a!$aEi;8>2t(#ayT~_z0 zRVtTNtfI{f*n3f_a^EFJ-d;E{g}QJ$t5aFIaH6qt;pEFE8r5al##POlqg1)k68+i?R(p>(S|)OXHW7T_ z-kP12Yw7>7x3;@ExHpqxpFyw7ijkMGmlbbm<}+AvS=l4yJ%i9(EIU4jB3|x%4k^E5 zX()y8E6QbQe<{@aLpd%5y?_EwWuz2V7e2j($22v3!S8P@ulT_} zUVhPF(``kD1%-ILH?fiW-t`}R-=eYlej9&Z(gfeHmwpO>a!aI^#`Z$^m{ zA{U1Tl9zM3L$6XSA9ja_ zyqw$vl3!pa2lRq=FR={i1GjkT6$zib!jcVy;4*AzO6`Whj1s0y|R zua)&K?E{A6Ra5xt!yitGuls4ZRd#1Be#EotgCz?VnxpbiYpB#2b<=P-Y_OOmX#_kr zSnf;KZ0Ow2;s*0qt)-W3CpRRcFM(0w$Ft&V|Vm4TYD zq=v;&+CRqjQ4RcfDMe9ekDH~5INQj4o`r1o`3HG8sct~*!f zle*Od)n?P+XAjFA>0BJ_^~7@GY)Gk%rQ>{9S_jLWi(rbEB~Kc+1j6cK>AMvCys^CY z0hD@Mu1cFeg3CUZ!oWn@o4C2-w|w}->cPGFz9xxOohx2G{1M82YoNdv?P>4W@2K{S zs`k&&9uDwdJ+x=NV^4|T*>kGeGtlmZ7kKzt3Z;TA-Vh`v0Z8>wn(5w7>Wj8Z<<^^&R_7)gD>ZZif%? zUT_&qjnE$Tj(rv$LFw({s@m(I{j+>%=WoGFB1{%HXxZ4}=$=&7(i|=0??8BC%$W90 z#;5&x#*C`=PH6w>2@GyxDQuSYj{WukZqKP|ABgsESZ^5L)be*=!8`uv1G&Grs(%vt zgKEP20oWVeg|`QL+8}OsBUK&jC1}s|g7`q3zTZPEZgtC5PjFSwM)X{70G~ADBm7Rv zjKMr*WL5iawC@RmP0jfTzhhrIgxlk)+E1drdK=ggg!aUD>@$aQds0>VHMBeQfQ%Ms zPkYDy!7y&msA_+N_O(Ochzadk@7Q0c_MEDAr=!@J(QvLMUzRUGMlfHNs~YN|q2(m_ zBN+4PF1|gy?MLwD-AGl3Hw5j^WV^CyS~Tm!By=&(cWhXJZg=0>pS*0sy(u* zeGJ;$t%5fpXpefwUSkx`9#>(vFli3j4}S*LWXoTY^$WPi%i&+bSp~}t_{0DUmZ$f_ z$DvqyAA*T(xSj>w+F}`W7W~^`xhos&+GBa(65QhDKiA-R2P{1cAgv>oF}ES16P7pr zgV9zj=RSiDow0oR0(`qz{<3q|ML<~>OTN^{8LoB3K!PhA3d1tj9a6es*~bUwb;t5{ zBN);H%kfP?4##p%3-IWPWx5Pcc=<A-z`bbOfKq<=$ zhAgnO;pMsomhtsn>rT?~S2Z>mpEX#G4U(4N|NW)KsJT4x0{4ZOBDk)t(?W}}p=7ne z*i=hm-TB+BypqnY6N{MBp{3-YV+@}sguh1jGSxDuRpHvN);j+7+-~y3_h-)T8yq|@ zS}{#-6O50U*@}Uu{ISh?De<7l!QVo{=axiPchgo&2UgS8ajWHXhEEpA|H3kuxf~qU zS#1k_2W=g;SsF=F&zZJyJ1jwxYXm)00%H*~ZJ&K<+2zL0+q(QM z$!%Q`$+cbi#Zp~jS8V^BwS2%_GDeH5A+b^h%>LD)xN7&f@s34-?N>_+m%LFG_491S zzgj$9S%%H=s^uHz8Zfq^e!y7Uk!zMuYe*A1lh9hS!zh^7UbWz z%ylX3SP?3;jsDM4OOhN1*k(So9A~c111e(918mkumX3P79w*_Y2e*IIvG_k+nmYGnZ9#^#F!e*$V1}w%23->oo|) zS(I^2oW|wTZ(GtZw5uatiFP6&^h;NxL40n-h|yr19T*ztARXugw@snxuG%Rmj2-M` z`>bW?U-ta-?m~0uSFYOUU5u3-v6y|B_@{L(7KQk9@^4X zTP!VUIPB2(n8_O+goif3D|p;`hPK3O0RW)N$4x_FOz%)5e_G1Y-l0wS(^9bXGX$aa zprq5`Q&WEH9csc$633n}HFDt6J^18=sh#@vJ2;DP9l7ec0KSe0ZNff+RwpTX8D^ZM zIzK~bpU{?e2??FyC#7XQy_wSg1dmRdLeyM)A@G!`k(vvyCVbQ<)Wn~8(x5L+-M4W3 zl&P!g+79~DrsnF~zoE@((|c+KeEdn9e%SbCIDXnROO3vOHb0x5s8M_*$#0Q34PU_6 zUre8=(I0`GF^w0E*?V)KImh_SyMBn0zR)}F8% z9r$pL27^P_@P~2i8ywmfKeUVW8J{;%b3mvEEXg)KQ0pv&ZRbq^dYWi_3`OUm*q?OU zZ|6Q%f%QtD|8F>AEAT-^xv*4wy9@T=TSu^nfoEo8;Zo_LtO@FHu@g{v16{@hiF!_q9x0?1C9J*rqR*mAV^;7;ZwN>Ba?e*XM zVQQ^fUc=2lOd+a__sM(bnR==3@m~2Ud8QGryaz9Dh}pFT`sbSJ!Gk3D_zWl&`x+=?(siy(hGd?5$TQKw+T2+%b;dH zjxLw*9_+x0xGdv6*uy7=cE@|JVcWz|erv&_e5@7VhrCTfvYx8@S zhs9v>3|M*{Gv(CBXW>V|*%(}G^57;)4qVEGnm0_%UHRLvabmN67i#vz^?lS0QysNd zi)dIk8D|*Y)Or_7yg=4EC3G!b3z;(|^eemr5f)6v-uwvrZc@%`aPuavB|PW5((vrOvSTazy0CJ4NF|!Lp;$5sdh~VCT`)yR1~shD^CD<9Tzo zqsdfpSZ*-zm?@mZI%{ujEIH#b=vZp!x(4rk$vyZc2SbjfCI{P&rJiTw$ia^T$5Kby zr0)dXe@Go=qYv8XqK^x@oJnm^_wVoa-fmj8(e!Gt`3I?1b1MfwPE3=bbQnZ(0HpWb zQUis-gyS-9nJ99sW7qN2k@o(~$M)XZS{6L~BcjNmjblF|ik#FK^i%3k8(mIk?3peO zl+zg!wyZT8R^*gM>wBe@&I*S7Z0b&|$f<}kKc~*Hnr8?1mdXfe@DIU>QW;gv?I*#Q z6YyjEU=45YDZkxWe%mY<@(bdMyLkIf`E63LjP$nh+qL%A=0{FNEd0A*8iFRE}a zXDG_}Ki$2p&juH|4CE|2Azi28Db)V#3(KRQwD%o?SAA*Ra=c=XFMawTLOEJt|GgEV zoUO3`UX4%=SJ;2&A(Yb<_TO^4!iJ>?<#>hpxAgGD2V@K!9JD?yo=&*b^PVZcEiJ$8 z6KrOLyz<*`%WpG+q~D-ne);Xe^4rv44I@O$Z$GxT)s0~}iqZQ4>1lTdL(V|c!SdTa z!7|d7<+t^M6QoniZx58;hJ)U}L)r88)|!%&8dK&-vyhV-CXCzv%hIr?{`C>Rrzh!fHJzd{PyC3W%Rl7+vGt)QI94YbA#4Z)7sj6Y%Ra78f+$&#?9MV<+nxU zw||!3ULK5zhqC+1Z#S0T{%&t=0p-}qtVg7o$*~g?%7i+u8q(GZ_V9Le`Ryy_wpEb$ zYihhzASY4ca;2Bv9ki~FggeS_n+8)zCzap6ZEtOIIhr!&F|jX4Q*2l`#Egb5gYgTc z4avcjhZkl%Xbz$zJ)W^$PM!pxNhqg4@}J1)Wlnt@dLrWvImi(V$;#CVwj6D=Atdn+`y?ry-Qzz|; z>V{tNWze*4+MV`ZjzhFwEKl_r-vztsrj4{rPDFIBm)6H7I~q)>mv)`Sax!99y|keg ze;l+vFYT`u%K?ejOXNAXH~9X%v{6?2T`({)?FoA;(+jz^5${b7W+bI;vG}E+cm1^Y z?d|VDQiHU+?5(_NG)TM6-u@>z!P}358OHg6|um*pCOD&QJS`rE7yR=OfQ@s$$GCajcxG*keLDRnhyOqEAj$oN1Ic z(nen#+}If9*&e*r7*3EA7R#QK`IVfoknozCW92z)e7Y{!+$8NbTh1*DtjIp1jYy7N zB(2DhKlS)zFlB|zssFY(ShFJIjkqJhXU)<+u}S2hMei5HhtC8xTSx_)RC3s2Pzz)w zKX|bPvNAuY*;4A;#E^p*6I-Tb+Iu;Cv8rX-#r9qfU`%;Ys`R?OLDN=g_XiiOl9z?$ z!LnA;dZS}JZ{M3at1=qJ$uWW8;g@6zzB?#>DdQG7X`H?~;~lf_|HSHy=VcH7;+Hcn zkUjiyZDrIbmU6Zq6r6ZD<8HIsA)n{m5rv|%{u9e#of~4t2e&G^JHgLmp4TqJFAk6 zAan@?vc+oFn=%EEEmmtxC|j%!nNYS^NyH9ji*-*AxO)&qKtyY^iiX$SI!4b0ON|f&4OrHFvH{D6*Y*m!Y?U!b_FqleDstIkHK=b| zOZ!&7^6#>-AS~Zngv(Z|WjiI5tyW3fB$TaIyRMKjnK-iDN<7{uh;EY?IoWfy&_s|u zSE8tmjnJ@faA=!kO151kZI@8?Q}s5XY?PW}LfI&_%!IN*YL5wJgH+sm63PatE+&)> zQe#Xg8>1GQaMQwIvk7HC)Cm*HeyG+vB$WM7Lw1O5*$;KE31vUjG84*vsGTOf_0`~n zi6`5kTJMxlwm}Usg_3PhwFV%svK7h}RJKA1b05A;A!SR{36o~@rl9pMc@oGMK^Y=i zJ~>dDUH&Y)<7MG4k;{&k%_fwsE+61J>qKEj!JGWZOZIh(nCE$GeLlwb;PpD(`+ z1$%^A^|Bve^KLOM`vIigrJDT!HkADUHkADUHkADU%RZC|O>r>h>a+`M7&B%!K-H_$ zI@y1i%>d>fR;la-81s=Rlf3{7O(=T-Hk(lP0-TUg_5!TA2KHquK-x(~C`# zCY0rM`)^rZUt|6)%j<_sD9h_fpGzpq>-OKWygtSJTb9?CnNZfv_n1%?#N!T1C@bAv zOehQ5V@xP3)eB81OVFE5C~M0nOel-St-p{^R)&X|P?mgWNm$ja<^DcOnx!eMEYuz{ zLRo=L`cgt!W$kT3Sw5X&LRlAGWniir*{~ z%8K6_6UvI;Ars1qU(#U-WyPG zvcP9USpj&c$na zS@)ld*Y*|%dqiE_^dN3^_l8yLdimz2k^BjZF7j{xJdeMm5o;&0?58?nd6E~#`eiJy zFTV&UlK^#9^%{7QznzOGdmY~u9=yD|`wvyZ?*>a=?*46+#dif03o=uKf>*kSy5!&& zKB%&p+*I+-^YRr>1uu~)c=twC61N6TU+tb+MP5q=z1sceDxs~xs#m*T>1QL`=Rsf7 zII}k}$(s%?U&-y|eu+BCTL9h^JQML(g3CgXz09u`8$GMRJAsb`-|x8Z$ro~aO@!bi z5_AEd0p78xTOX!@`QRzw%+M0>0V@6~@WJ49tbSj9_5^|v5VVEiUEnjpYl0sDpQqv< z178i!jGh560GDrS_NpZjDH50_WUlGpyTRK#?3rIVjPqK0;jMX=xU(wqQ`+G9 z!NAwLzvGA7y8OyJoxR3ab>%ApcTzd;4&JeyBk_no2Rudbh2ZImKLg&?areWCM%POa zWT*t|z0y0@-T?o&_#zarUYyMK>*AEO<5WCg796 zCAqyif#<0B-3>QQY`RJ?5D8|2%RlXP19(*Nao}^n*;J>2=P5oHe7SHbzkKm<`n^RE z6d(cl3h<3e(OU4`if;oy2%Z4_`@j#Eb8Fu_0>SZeflYD>{G{U5#OJ08&MMvzJifha zq%_E0C|L>mAwhF+x^y^risIwIdw_E|ng%{V@wwo`d?i=}K}7Kt;FAjuHr zSb^6Md^dP)7#I$|U-5C^hr#P2{xtBDiqEy&Px9hBxW>W+i;y5$@fG0hz)=EkEqIFJ z+rYbmvjF?R!-kvoPr(rg1|vaP6@U*@yqe^|G~UtR)YA|=Tk-bbQ^AdX+yA;jFtdWd zc&{J$9B>*K4xX#{IPj(5a^lBccZ081{Gl3R-;`h@1k&B@wFn7{6n_qUtKw_GcYt%~ z-2%QFoQ?Do@Vy=U@zx*{9EM=ON^lCiMDgn4LsNjGiZ=o;RlFnkX>vFI$+8aw-UYE4 z8U!8>&Jv6QucP=R@MOjB18=Ul|0o3Ql;BzL6vYd`yMohmo53?w{ExxI;GD94>A3F= zgW!DB{V^n%1kM5K-{8|#{3;T`R6(waUk`k#ir*Bx&~ouV4RnB@NF}%!e7`bqIrw1} z|0?jaD*g!YgpRI?ZGlbwkAoltf&9~6cY>!>Odt|7W}6cCRq+>qXQ}v4foH4u&kOgB zqNysu>qxLbB`5-4tm1zFUZCP10N<$Me+Ry|<9OHp<=^%?2|<`+88@tt=Lcm{ZT#5YG8?fgFi0pIA%p+@70TyVYtz6QP;oUe>q zz)Mv8kHOD^^Hue0@bnbS|2ez;1%j{$%*B`CD)J&=GBh2$21-yLJPIyvmiB4`K1apB z7<@rFzriNx13{irG!%Ssc>){%R`7gqevY^kd~ZsyWpnqtubO^|D@cmVm$x4B<>1Wl z2jI_x%cI6#-wHRMZ_ID3&EC?zpPz_7r^X0LGHEm~+5C|x@>Z57c@uiO3^ato_K444 znqvG*5&v`_7hld<+p8zy<2S4t*k9x|lB*#|-}dInce`(o^Y_kmDfyO4jdwoicmt=< z+YU>ihhpRJ2CqHOaXzO%2EQMidiI0YdDzDH%U&YCgx~=uDC^&c!9NA(EMk2Z}7PPtC&&g$7dlJ4*?Zbk>+h$Z|VY%L~_ayv)V->FQ4* z82?WvpzFQ_@AX_PKLUQia>wb?7if2+pTc%(T3W3XCN2`0b6yP445$i5LOvcFirkE`vc0A0uI|tK-uq5o!#TjqM*0Nsbntt@7l4a-d(8*W0B-^Q z5AYG-eAiqZtH<}KXcGjX_hL%weGJ|eobkT{@2j}|NosMxFvXLkks8O01()P~J1s{L|pc!tFppm)4cmWn9!wC1?Yl4la*rdtD0N100Rh8w{SM^o#)? zT^`>JWOqZ5qZ0fd_)KugxV`eh7bw0Kd?`4)?=J8HaQ3dRk}!~MRf3a9uwNOdDFcr2 z&`}k?CHPsz{{o)4(^Ub-s{!Ecd?mOEf(&q$;7;(tia!J%0cST~3O*B@o?8RH09-!E zxobNF`4I3u;dAhHN>M5J4i&$e_||x+M8$6kUJ8yX@Vzt$;&;XN`@Z0f!Rd(`!BZ5! z13U~~0|lE6J^-9^z{QqJ`LiI9Hzj+$j0B^>*`2n4PXZSQ*y~g9sEU6aJQtkZFHTBg zJhaqs)Bb7rdH@JDHwEfSAU_S&GxPp0k;G;2y zUk<(kJpW@?Wj}(i2haV)aeh7f2z)U(J$g7<>>F3Cgn*6lHze4o6xEX<(!}2i&WB1X z@EwY$gYQd z>Bc|LdjWzH2-vvRfu96VhoYU}?RGm?w*fx@J^-A0egKbr>f&FI`2N{S1a)NqFs>dA zMIDf!CHNe0PGHi&^T9hKei(eWia*40-#ZEcr)IYzf%k#SDW_(4fj0-IOXq;MQ+yG4 z3iyS{(DUFUEEoT?(Y*=5BqX5gc7R90TS3uhmbdVVF3hte0$y86Vmw!@8gB@Ee?@NU zzZ(Q46$Qcvfge@;7VuKVr-GkW{9$l!uk$Foz=o!~`^&jv41JP+La$QHo&Sb`N0gq)y^zX2Xr{5|l9;`_m)ikm-iXFQi5 z!=?VuKu{DTkaa?tOPK^EiZ=)Mid_|$Gppvh2t1_t<=|n(uQlAv|07DkHJ_;BTx`l$ zoU2?#iXX0l0w~V)L2nP{|13c_BnXMXT;!*?gsM1~Vk3%AL;R@X-N5t9x$A#i^)4zG z*bH#Fy+rY8GGN$VfC&gQ+6_FUI5#$g6<-@K_Kl*55^xKKe%^DtP89L^?1O9ne*k`3@vp(XeXdcn!2hva z=Kl#wP)DXT#zl#Ww+3&l_$A;W#jgVIsCWcC-Eh$j)z^5yIF?dw*{w*;7pQi+)ksw#`Dd3A0 ze-J!h@qd7?RJ;JZU?1lHtb%P2tWyaNfEOwLGx!e0<7GrL9x7J63HW|;H~z`?bO=f) zF#eb83h<+fj{q-Kd@}fH#UB9o{uSE``~ZRkC0GrfsQ6~^#)|(7Jf!#!;2jnBT3HYI zUb+%AbOJ9!@y_63#e0DdP<$A8mf{n@M_BHccfb1~h^PclfM+Yd544B z;+(n_LBG5T+G~XjwWezJJ1)Pw4#DS8bW$l=gaoIdNFLkvnhT!%nezkjBTJU&qwuyf5#3b>AZU6EK$X?SV2c~Z3z(wL1dksf| zmEc^#s0O|coUNT3l6R>1bD_UNeAoYW+MKrVBIq9NVE7l5AV-xrUN(W4j80YjeDLYu zl0SQO29GL!d0Vk>6wOnDp-8X}{r*xY;--`RD49I|?Zx+k)2hVWjGl17RZUOC=gx@% zJ_M|r%s7{!5sKe#Gt|{Yg@ z1)QJZ-6j~B|1XDtt6&$)cXv~=#VWxJ7|`)kY>B06w!0xb8HTgK7lZS&{Q>B)o-pm7 zd%N1e@KhM4C+dT1Pwk@$2=+n{ zj|{B`->>)w;0F~i0WVSfSK+ZUA7{Xi>)=|uZbbFLbt7sEUa=7wRb9a|@UUT{?g!o% zT-vg|u6Nw`vLL7e!FVLld^))PB=a!%x`=BN)U%`#{!)w{@jnx6gkYF@Tz&vPR+ZpO z@EmYXOnwGm0M2ggUEn;O2VUJ2*wlX#1WO^1bwhi#0WVPeFW_6j`8e(iz89Qx#v3Gp z8PH0>TS5PDiErosiC>I&1|i@ckgnh?8TWu>srcLjG8J5Um%X?LWHGpWXtfvD6$`(> z{GU0xoh3j5&gr;bcN|>4OW5lk#83Fr6@ZUpF5`6sXNKk>{$TJ1ZvG>GEQYIK5OC7S zwV$bqbA4|fIM<4}zPA*dC4LHq*MYNOFGOIt7y?ekxJq?YCEy~J_mwL#hw4=@kOkJLiSoiEP0#o8A>hNY zwG()S;55wj%VO|qsOgIlf4|~afR`vf4E(6&(#vW<5f?&Bk$}^OaY%3$oD;IU!RwTa zw;HJDA@F2yj(1#74S`z^nO?pa3DO}*K!#of&j4rDtOp;g3~*s~gwpdq;zyL8gTieu z*NT2bf~iUoS9oVCMgOfNL+5pJ!%MEx69Qjcf?m#&aj95ms0$LTR*JYHT&ObC2l2HY zt`zSm(_{QE*L6rxtQ2txSt}Zg_=gdnQ%5c>mzEiD`lliOX>bllVIND#+Q5TI(D;yR zTr_~iaZeiv5WgMbb3(QfTdAfq^Ni9ZXazn`8Q}V;E!l`tMzdfuZ2bl>siaY6G_+ z{%XYMKsyzDBRI#2xrW4>Zcn>7tGmT5p+CUoO z4@P`GWW(UP3Wi)L_D$o;MgorQT+`MDZiS-hh|k%;T{MjTT@$T+4)_AZ=Ny-79~XVkF>9?fFU!ya`^2`1BAL*>wSSApTaw_t_dhgJ3rVt=V5IG0fHaQf2se#Mg%F zq&QF0Fzm`IKLp-4uI}5wFjxI`zfVQ{c8Jds_X5|3v(9bUbGrxREx#)iwSwU>NT3bh z2|i32o?VGyZbMKd_VN&atkGlIe~2Zn#PA#7b6}W_l=~TUiQhwfZFoO;9`u;0o9%z! zS7MkOBUUTJXAoZ-u6@xt>)2}!z7cvj$CdpR?k!)t`XVIQs|;Tbt_@#XiD7QkI9#E` z#@P|XA6(+QM#ug-1%k86@B@_?=8g~T>L(Dt4hA%qczKy&*tPzb9Ib_*9TIRz=GGBi z;_Zl^qT+uF-W8k^jicbh!0juhsekT48Lbrkh6LJhtyEXX+Hf=QvC6RB%OWGJHk{(( z``#QRsBJ1nuAWe&4f9;HHq1RSxzHnXQG4;+v^LCh*6VD1@jqS7liAuZH`i#xJo#M& z!yGYrQv5JD_48!;@rvBkKX>V9!#umL4fCw~NoDv{4OcbVFn9YjKH?f3J^hKqxAT8( zcncJ1!)w6XL6Hmt_PQHf8y*Lqh4^(5e>k|IXpt3Fy*p;Ch^B4?YL+*{U0Y zF97FEsoMYOLH|1?Da||}9|<@f@Gn8E2B+)xF@CklwoII`Yy)41`21M67JMT(yX6WW z0$s92;0KkWxs~u~mFO7lFJ15_rs_QW9h4J});6eOsH zoN`@4kBt1IU>S(t4)M7xp$oueiP4D9#>i!fNxl+rT|z4wgc8hD@kdtT39f~ez|}V( zqZ1LI`pf?85EsK1zyLoty2UU#*QDx_YhmGI&ed1Izzk)8ZDl_Aa_C1}@x3Jw6hI*F zi1u1liK6x32N9pIV7tIe!TBC>pb|Z9O-<(i+NE4n(jV&>C{wtCD6Koou=R=R+t2o(;|nT@HRHI7>Vl{2p+6l$&uvcFjxt zFApnw-ER}f8CNWZkv|6BQSp566ver#CtYzKIqO=HoBCfPiq5qHyV)9$y)SCf{5$X* z#p|XU&$aNPivI;XS8+46+xdU^2iITubee&IC=0w5Jj5|P2b>?7mmq#FIEP*i;f3I> zp@-wj{vR;^?+5`0mX3JXu#P!oddFQxX`pPxM0`9{JdT*{5T6C$h}jpsrJMhF9*4%U z5OC3H5Jtc#I7{$PjDX9*Lnr{}2V22e0L}x7!C8PgJ`|mVpgk0E9?<+pS7MHIe9DEv zS+WDD0zHX!PdPcpfcSjz;6u)jLcs6&e3~r<=iKl{+lX3v`RGpU9gkWreAwT~xNs@I z{46XQ-2)JmDn)tVCl!Al{IoK#9^6B}XWhRK9$(HcwWbe3kN^S4@KW$ZaAq|A;$TTa zX3LT5&`9f{0NjMP1DxHg{>AQ@vRpM@Hqt`GXGVKo91Kd$Z0VQ$^8d-4VqH+kDD|%jL)SE=h{iTY%n%IaYq+ zKC@8}s-2nO7r*ankF~uXW2bk*aXv*j*46>1bJ<#>sJ#ZLB(~N(aK`6Avea?E>{yQ- z0i>fZR|z-(tX4c9BT1p+?C2X6XGh-}!==klgL0De~St>E#cuFB}@{or*JKMtNO+zxq6;B|EkwYf@= z4Bk%hj^HVZ_WhfiMg-K>RV_!&HW*fsa=F z;jUueJYB{r!P7`EN%1w{Qx)F^K2!0}z~?CbBlrSe3F5lB4CR5-b^Nn`61gGad6@IQ4iX)c$6;HW1PjKW4qcIMEhfcvj)-SQ$tfoAF?3>1;c{XMU z@%g;VLHtZ`jvuQHH|?LZ#7nKBByWT=a1{)MVIT}e_ac5o#pi%i2worY@5DEo!zJ!J zy^Qp(|1ZIqzXJ()RO1mC&d0k_2#Pkqa4tO51N^dAIkg^IUht|K<|0Z(LUd z1MMKFFEb(2ElZ&2a_|n|Aywi`%UgOyn9|Ur*_OBP4nsfN1P7uXzv7ceYZ%Cbq7oEq#;1oE5pc$qv4&W}9omUT|L#+U>>{AwKn zXMFn%GLPwW2ojNi53MjbA6jf&S;_$4=f{Gx0Gvn91g9sqpa6No?PHStxHI0vS1JQd z!8d|4K40{U73Vl{7@Q^MMCK&8q)Ofy1{xrZVjmQ5^gDSw2|aZVfhftM;i1>D=)?C zS9*Sjo@k67sk(NT8ArABav@*|uC!dfOfQUWtDIjohv8&+j`OQ@aAuVAt1vh{YUfvG zI+LXmaDEj5=hu49uO@->QOEh!Or?kOs|Da3;5olqF5EO-k0szs{yJrV^Q#?-bAGiS zycImb`PFG~_65$blFzudCBC)xJx;K?LcqG@{3-*SF6I1c060f>&aXy;b6n&6Dhf`| zosq9Tw)^Koz#*UWtL5NLQ8Lc2id1~gqxOQ+qxCUKI10`Jv;jZuL%>FH0IfRVcjqD| z*u~Zk&Ni_gyd5}8whFwf(z67-FSt4AVXyfRjD~1@!Di@q>VkqJl zfTK#*8)#G>pa&Q1>yymrZZjTXHp`>*}%k0;Fe;(qo(XPc)djYuQ%UWsD!QU)@?+bIKVoE?<`Hs-EM zKO28oxE;Y*f*CN-R~gs^K0p~b06t6^;P?;$r~dlrMPtkL-(efq87RtD1~~FfRR%ax zMwJ1MtaHFQF5QBMVI*kXMrI9p5Oacf1Z{Gu;-|ouE6y!Bs}<+=%tFPvopYn(Y}zE|;a;0G0-27Wk(OP$Y!;CPI{^A>@hRD1>aS;g0a$N$&$1$uNF zcpb&}8E)IW5*$H-=8B&JZ>M;*8m^b8DBcjftK#j!dkD8}o;mFXL0^@iANXL!hl3AO zd>r^_#qS0mTh6V0Zw&;K$_2JBaG&^8#Xmv(nTj68+HrT5;4<{T{oQD|>gO~jg7M^}M zt`hLH#7V_*yuv%HIFDn*|2f`PA=?&@Z`6t9vOPQ1RY7vBz~lLl=8E$?Njt@P03}87 zvI8rMy8|w=J+p@r@I*{s#d(5eu;M&&GfZ(F(HX5ckMxW++_ZnXh-ZK%sRTSTG*xjP zGMcG44<*e}oQIeeRN%J%@zhgZ1%atNo|0OsIR9+za>aQJYqjD$wpFOO9P@I=vo
      xYddfn;G1O+a89uJW;qy~Re1~(yDV@!#WnR` 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 diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index a1a079eff5..8e7b046a1f 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -260,13 +260,15 @@ program mksurfdata ! call pio_init(iam, mpicom, 1, 0, 36, PIO_REARR_SUBSET, pio_iosystem) ! TODO: generalize iotype - call pio_init(comp_rank=iam, & - comp_comm=mpicom, & - num_iotasks = 8, & - num_aggregator = 0, & - stride = 36, & - rearr = PIO_REARR_SUBSET, & - iosystem = pio_iosystem) + call pio_init(iam, mpicom, 4, 0, 36, PIO_REARR_SUBSET, pio_iosystem) + + ! call pio_init(comp_rank=iam, & + ! comp_comm=mpicom, & + ! num_iotasks = 8, & + ! num_aggregator = 0, & + ! stride = 36, & + ! rearr = PIO_REARR_SUBSET, & + ! iosystem = pio_iosystem) pio_iotype = PIO_IOTYPE_PNETCDF pio_ioformat = PIO_64BIT_DATA diff --git a/tools/mksurfdata_esmf/src/mkutilsMod.F90 b/tools/mksurfdata_esmf/src/mkutilsMod.F90 index 653535aec9..77ea3dd75b 100644 --- a/tools/mksurfdata_esmf/src/mkutilsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkutilsMod.F90 @@ -4,6 +4,7 @@ module mkutilsMod ! General-purpose utilities use ESMF use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod, only : shr_sys_abort implicit none private @@ -12,6 +13,7 @@ module mkutilsMod public :: normalize_classes_by_gcell ! renormalize array so values are given as % of total grid cell area public :: slightly_below public :: slightly_above + public :: get_filename !Returns filename given full pathname public :: chkerr character(len=*) , parameter :: u_FILE_u = & @@ -159,4 +161,25 @@ logical function chkerr(rc, line, file) endif end function chkerr + !=============================================================== + character(len=256) function get_filename (fulpath) + ! Returns filename given full pathname + + ! input/output variables + character(len=*), intent(in) :: fulpath !full pathname + + ! local variables: + integer :: i !loop index + integer :: klen !length of fulpath character string + !------------------------------------------------------------------------ + + klen = len_trim(fulpath) + do i = klen, 1, -1 + if (fulpath(i:i) == '/') go to 10 + end do + i = 0 +10 get_filename = fulpath(i+1:klen) + + end function get_filename + end module mkutilsMod diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index 5b966a47eb..569550f1e4 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -117,9 +117,8 @@ module mkvarctl ! ! Variables to override data read in with ! (all_urban is mostly for single-point mode, but could be used for sensitivity studies) - ! - logical, public :: all_urban ! output ALL data as 100% covered in urban - logical, public :: no_inlandwet ! set wetland to 0% over land; wetland will only be used for ocean points + logical, public :: all_urban ! output ALL data as 100% covered in urban + logical, public :: no_inlandwet ! set wetland to 0% over land; wetland will only be used for ocean points character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -181,14 +180,16 @@ subroutine read_namelist_input() mksrf_fgrid_mesh, & mksrf_fgrid_mesh_nx, & mksrf_fgrid_mesh_ny, & - !nglcec, & numpft, & - !pft_idx, & all_veg, & - !pft_frc, & all_urban, & no_inlandwet, & - !gitdescribe, & +#ifdef TODO + nglcec, & + pft_idx, & + pft_frc, & + gitdescribe, & +#endif outnc_large_files, & outnc_double, & outnc_dims, & @@ -271,145 +272,149 @@ subroutine read_namelist_input() call mpi_bcast (mksrf_fvocef, len(mksrf_fvocef), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_ftopostats, len(mksrf_ftopostats), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fvic, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (fsurdat, len(fsurdat), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fgrid_mesh_nx, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (mksrf_fgrid_mesh_ny, 1, MPI_INTEGER, 0, mpicom, ier) + + call mpi_bcast (outnc_dims, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (outnc_large_files, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (outnc_double, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (outnc_1d, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (outnc_vic, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (outnc_3dglc, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (all_urban, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (all_veg, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (no_inlandwet, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (urban_skip_abort_on_invalid_data_check, 1, MPI_LOGICAL, 0, mpicom, ier) + + call mpi_bcast (numpft, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (std_elev, 1, MPI_REAL, 0, mpicom, ier) end subroutine read_namelist_input !=============================================================== subroutine check_namelist_input() - ! error check on namelist input - - if (root_task) then - if (urban_skip_abort_on_invalid_data_check) then - write(ndiag, *) "WARNING: aborting on invalid data check in urban has been disabled!" - write(ndiag, *) "WARNING: urban data may be invalid!" - end if - end if + ! error check on namelist input if (mksrf_fgrid_mesh /= ' ')then fgrddat = mksrf_fgrid_mesh - if (root_task) write(ndiag,*)'mksrf_fgrid_mesh = ',trim(mksrf_fgrid_mesh) else call shr_sys_abort(" must specify mksrf_fgrid_mesh") endif - if (trim(mksrf_gridtype) == 'global' .or. trim(mksrf_gridtype) == 'regional') then - if (root_task) write(ndiag,*)'mksrf_gridtype = ',trim(mksrf_gridtype) - else - call ESMF_LogWrite(" mksrf_gridtype "//trim(mksrf_gridtype)//" is not supported", ESMF_LOGMSG_ERROR) - call ESMF_Finalize(endflag=ESMF_END_ABORT) + if (trim(mksrf_gridtype) /= 'global' .and. trim(mksrf_gridtype) /= 'regional') then + call shr_sys_abort(" mksrf_gridtype "//trim(mksrf_gridtype)//" is not supported") endif +#ifdef TODO + if (nglcec <= 0) then + call shr_sys_abort('nglcec must be at least 1') + end if +#endif + + outnc_1d = .true. + if (mksrf_fgrid_mesh_ny == 1) then + outnc_1d = .true. + outnc_dims = 1 + else + outnc_1d = .true. + outnc_dims = 2 + end if + + + end subroutine check_namelist_input + + !=============================================================== + subroutine write_namelist_input() + + ! Note - need to call this after ndiag has been set + if (root_task) then + write(ndiag,'(a)') 'PFTs from: '//trim(mksrf_fvegtyp) + write(ndiag,'(a)') 'harvest from: '//trim(mksrf_fhrvtyp) + write(ndiag,'(a)') 'fmax from: '//trim(mksrf_fmax) + write(ndiag,'(a)') 'glaciers from: '//trim(mksrf_fglacier) +#ifdef TODO + write(ndiag,'(a)') ' with: '// nglcec, ' glacier elevation classes' +#endif + write(ndiag,'(a)') 'glacier region ID from: '//trim(mksrf_fglacierregion) + write(ndiag,'(a)') 'urban topography from: '//trim(mksrf_furbtopo) + write(ndiag,'(a)') 'urban from: '//trim(mksrf_furban) + write(ndiag,'(a)') 'inland lake from: '//trim(mksrf_flakwat) + write(ndiag,'(a)') 'inland wetland from: '//trim(mksrf_fwetlnd) + write(ndiag,'(a)') 'soil texture from: '//trim(mksrf_fsoitex) + write(ndiag,'(a)') 'soil organic from: '//trim(mksrf_forganic) + write(ndiag,'(a)') 'soil color from: '//trim(mksrf_fsoicol) + write(ndiag,'(a)') 'VOC emission factors from: '//trim(mksrf_fvocef) + write(ndiag,'(a)') 'gdp from: '//trim(mksrf_fgdp) + write(ndiag,'(a)') 'peat from: '//trim(mksrf_fpeat) + write(ndiag,'(a)') 'soil depth from: '//trim(mksrf_fsoildepth) + write(ndiag,'(a)') 'abm from: '//trim(mksrf_fabm) + write(ndiag,'(a)') 'topography statistics from: '//trim(mksrf_ftopostats) + write(ndiag,'(a)') 'VIC parameters from: '//trim(mksrf_fvic) + write(ndiag,'(a)')' mesh for pft '//trim(mksrf_fvegtyp_mesh) + write(ndiag,'(a)')' mesh for lake water '//trim(mksrf_flakwat_mesh) + write(ndiag,'(a)')' mesh for wetland '//trim(mksrf_fwetlnd_mesh) + write(ndiag,'(a)')' mesh for glacier '//trim(mksrf_fglacier_mesh) + write(ndiag,'(a)')' mesh for glacier region '//trim(mksrf_fglacierregion_mesh) + write(ndiag,'(a)')' mesh for soil texture '//trim(mksrf_fsoitex_mesh) + write(ndiag,'(a)')' mesh for soil color '//trim(mksrf_fsoicol_mesh) + write(ndiag,'(a)')' mesh for soil organic '//trim(mksrf_forganic_mesh) + write(ndiag,'(a)')' mesh for urban '//trim(mksrf_furban_mesh) + write(ndiag,'(a)')' mesh for fmax '//trim(mksrf_fmax_mesh) + write(ndiag,'(a)')' mesh for VOC pct emis '//trim(mksrf_fvocef_mesh) + write(ndiag,'(a)')' mesh for harvest '//trim(mksrf_fhrv_mesh) + write(ndiag,'(a)')' mesh for lai/sai '//trim(mksrf_flai_mesh) + write(ndiag,'(a)')' mesh for urb topography '//trim(mksrf_furbtopo_mesh) + write(ndiag,'(a)')' mesh for GDP '//trim(mksrf_fgdp_mesh) + write(ndiag,'(a)')' mesh for peatlands '//trim(mksrf_fpeat_mesh) + write(ndiag,'(a)')' mesh for soil depth '//trim(mksrf_fsoildepth_mesh) + write(ndiag,'(a)')' mesh for ag fire pk month '//trim(mksrf_fabm_mesh) + write(ndiag,'(a)')' mesh for topography stats '//trim(mksrf_ftopostats_mesh) + write(ndiag,'(a)')' mesh for VIC parameters '//trim(mksrf_fvic_mesh) + + write(ndiag,'(a)')'mksrf_gridtype = '//trim(mksrf_gridtype) + + if (mksrf_fdynuse /= ' ') then + write(ndiag,'(a)')'mksrf_fdynuse = '//trim(mksrf_fdynuse) + end if + + write(ndiag,'(a)')'mksrf_fgrid_mesh = '//trim(mksrf_fgrid_mesh) + if (outnc_1d) then + write(ndiag,'(a)')'output file will be 1d format' + else + write(ndiag,'(a)')'fsurdat is 2d lat/lon grid' + write(ndiag,'(a,i8)')'nlon= ',mksrf_fgrid_mesh_nx + write(ndiag,'(a,i8)')'nlat= ',mksrf_fgrid_mesh_ny + end if if ( outnc_large_files )then - if (root_task) write(ndiag,'(a)')'Output file in NetCDF 64-bit large_files format' + write(ndiag,'(a)')'Output file in NetCDF 64-bit large_files format' end if if ( outnc_double )then - if (root_task) write(ndiag,'(a)')'Output ALL data in file as 64-bit' + write(ndiag,'(a)')'Output ALL data in file as 64-bit' end if if ( outnc_vic )then - if (root_task) write(ndiag,'(a)')'Output VIC fields' + write(ndiag,'(a)')'Output VIC fields' end if if ( outnc_3dglc )then - if (root_task) write(ndiag,'(a)')'Output optional 3D glacier fields (mostly used for verification of the glacier model)' + write(ndiag,'(a)')'Output optional 3D glacier fields (mostly used for verification of the glacier model)' end if if ( outnc_3dglc )then - if (root_task) write(ndiag,'(a)')'Output optional 3D glacier fields (mostly used for verification of the glacier model)' + write(ndiag,'(a)')'Output optional 3D glacier fields (mostly used for verification of the glacier model)' end if if ( all_urban )then - if (root_task) write(ndiag,'(a)') 'Output ALL data in file as 100% urban' + write(ndiag,'(a)') 'Output ALL data in file as 100% urban' end if if ( no_inlandwet )then - if (root_task) write(ndiag,'(a)') 'Set wetland to 0% over land' + write(ndiag,'(a)') 'Set wetland to 0% over land' end if - end if - - ! if (nglcec <= 0) then - ! call shr_sys_abort('nglcec must be at least 1') - ! end if - - if (root_task) then if (all_veg) then write(ndiag,'(a)') 'Output ALL data in file as 100% vegetated' end if - end if - - if (mksrf_fgrid_mesh_ny == 1) then - if (root_task) then - write(ndiag,*)'fsurdat is 2d lat/lon grid' - write(ndiag,*)'nlon= ',mksrf_fgrid_mesh_nx - write(ndiag,*)'nlat= ',mksrf_fgrid_mesh_ny - if (outnc_dims == 1) then - write(ndiag,*)' writing output file in 1d gridcell format' - end if - end if - else - if (root_task) then - write(ndiag,*)'fsurdat is 1d gridcell grid' - outnc_dims = 1 - end if - end if - - outnc_1d = .true. - if (root_task) then - write(ndiag,*)'output file will be 1d' - else - outnc_1d = .false. - if (mksrf_fgrid_mesh_ny == 1) then - outnc_1d = .true. - end if - end if - - end subroutine check_namelist_input - - !=============================================================== - subroutine write_namelist_input() - - ! Note - need to call this after ndiag has been set - - if (root_task) then - write(ndiag,'(a)') 'PFTs from: ',trim(mksrf_fvegtyp) - write(ndiag,'(a)') 'harvest from: ',trim(mksrf_fhrvtyp) - write(ndiag,'(a)') 'fmax from: ',trim(mksrf_fmax) - write(ndiag,'(a)') 'glaciers from: ',trim(mksrf_fglacier) - !write(ndiag,'(a)') ' with: ', nglcec, ' glacier elevation classes' - write(ndiag,'(a)') 'glacier region ID from: ',trim(mksrf_fglacierregion) - write(ndiag,'(a)') 'urban topography from: ',trim(mksrf_furbtopo) - write(ndiag,'(a)') 'urban from: ',trim(mksrf_furban) - write(ndiag,'(a)') 'inland lake from: ',trim(mksrf_flakwat) - write(ndiag,'(a)') 'inland wetland from: ',trim(mksrf_fwetlnd) - write(ndiag,'(a)') 'soil texture from: ',trim(mksrf_fsoitex) - write(ndiag,'(a)') 'soil organic from: ',trim(mksrf_forganic) - write(ndiag,'(a)') 'soil color from: ',trim(mksrf_fsoicol) - write(ndiag,'(a)') 'VOC emission factors from: ',trim(mksrf_fvocef) - write(ndiag,'(a)') 'gdp from: ',trim(mksrf_fgdp) - write(ndiag,'(a)') 'peat from: ',trim(mksrf_fpeat) - write(ndiag,'(a)') 'soil depth from: ',trim(mksrf_fsoildepth) - write(ndiag,'(a)') 'abm from: ',trim(mksrf_fabm) - write(ndiag,'(a)') 'topography statistics from: ',trim(mksrf_ftopostats) - write(ndiag,'(a)') 'VIC parameters from: ',trim(mksrf_fvic) - write(ndiag,'(a)')' mesh for pft ',trim(mksrf_fvegtyp_mesh) - write(ndiag,'(a)')' mesh for lake water ',trim(mksrf_flakwat_mesh) - write(ndiag,'(a)')' mesh for wetland ',trim(mksrf_fwetlnd_mesh) - write(ndiag,'(a)')' mesh for glacier ',trim(mksrf_fglacier_mesh) - write(ndiag,'(a)')' mesh for glacier region ',trim(mksrf_fglacierregion_mesh) - write(ndiag,'(a)')' mesh for soil texture ',trim(mksrf_fsoitex_mesh) - write(ndiag,'(a)')' mesh for soil color ',trim(mksrf_fsoicol_mesh) - write(ndiag,'(a)')' mesh for soil organic ',trim(mksrf_forganic_mesh) - write(ndiag,'(a)')' mesh for urban ',trim(mksrf_furban_mesh) - write(ndiag,'(a)')' mesh for fmax ',trim(mksrf_fmax_mesh) - write(ndiag,'(a)')' mesh for VOC pct emis ',trim(mksrf_fvocef_mesh) - write(ndiag,'(a)')' mesh for harvest ',trim(mksrf_fhrv_mesh) - write(ndiag,'(a)')' mesh for lai/sai ',trim(mksrf_flai_mesh) - write(ndiag,'(a)')' mesh for urb topography ',trim(mksrf_furbtopo_mesh) - write(ndiag,'(a)')' mesh for GDP ',trim(mksrf_fgdp_mesh) - write(ndiag,'(a)')' mesh for peatlands ',trim(mksrf_fpeat_mesh) - write(ndiag,'(a)')' mesh for soil depth ',trim(mksrf_fsoildepth_mesh) - write(ndiag,'(a)')' mesh for ag fire pk month ',trim(mksrf_fabm_mesh) - write(ndiag,'(a)')' mesh for topography stats ',trim(mksrf_ftopostats_mesh) - write(ndiag,'(a)')' mesh for VIC parameters ',trim(mksrf_fvic_mesh) - - if (mksrf_fdynuse /= ' ') then - write(ndiag,'(a)')'mksrf_fdynuse = ',trim(mksrf_fdynuse) + if (urban_skip_abort_on_invalid_data_check) then + write(ndiag, '(a)') "WARNING: aborting on invalid data check in urban has been disabled!" + write(ndiag, '(a)') "WARNING: urban data may be invalid!" end if end if diff --git a/tools/mksurfdata_esmf/src/shr_log_mod.F90 b/tools/mksurfdata_esmf/src/shr_log_mod.F90 deleted file mode 100644 index 244314a8de..0000000000 --- a/tools/mksurfdata_esmf/src/shr_log_mod.F90 +++ /dev/null @@ -1,13 +0,0 @@ -MODULE shr_log_mod - - use shr_kind_mod - - !---------------------------------------------------------------------------- - ! low-level shared variables for logging, these may not be parameters - !---------------------------------------------------------------------------- - public - - integer(SHR_KIND_IN) :: shr_log_Level = 1 - integer(SHR_KIND_IN) :: shr_log_Unit = 6 - -END MODULE shr_log_mod From 34bebd72de880427a3f241e9673ccba6a401fef5 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 21 Jan 2022 19:21:17 -0700 Subject: [PATCH 024/614] updates to get mklanwat output working --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 494 ++++++------------ tools/mksurfdata_esmf/src/mklanwatMod.F90 | 1 + tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 | 24 +- tools/mksurfdata_esmf/src/mkpftMod.F90 | 247 ++++----- tools/mksurfdata_esmf/src/mkpioMod.F90 | 21 +- tools/mksurfdata_esmf/src/mksoilMod.F90 | 58 +- tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 | 8 +- tools/mksurfdata_esmf/src/mksurfdata | Bin 4023536 -> 4141144 bytes tools/mksurfdata_esmf/src/mksurfdata.F90 | 320 ++---------- .../src/mkurbanparCommonMod.F90 | 12 +- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 34 +- tools/mksurfdata_esmf/src/mkvarctl.F90 | 40 +- tools/mksurfdata_esmf/src/mkvocefMod.F90 | 16 +- tools/mksurfdata_esmf/src/run_mksurfdata | 3 +- tools/mksurfdata_esmf/src/shr_sys_mod.F90 | 6 +- 15 files changed, 430 insertions(+), 854 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index fd83c79932..e76a512ad0 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -1,68 +1,66 @@ module mkfileMod + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_getenv, shr_sys_abort + use mkutilsMod , only : get_filename, chkerr + use mkvarpar , only : nlevsoi, numrad, numstdpft +#ifdef TODO + use mkurbanparMod, only : numurbl, nlevurb + use mkglcmecMod , only : nglcec + use mkpftMod , only : mkpftAtt + use mksoilMod , only : mksoilAtt + use mkharvestMod , only : mkharvest_fieldname, mkharvest_numtypes, mkharvest_longname + use mkharvestMod , only : mkharvest_units, harvestDataType +#endif + use mkpioMod ! TODO: add only + use mkvarctl + implicit none private - public :: mkfile + public :: mkfile_fsurdat + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ !================================================================================= contains !================================================================================= -#ifdef TODO - subroutine mkfile(vm, nx, ny, fname, harvdata, dynlanduse, pioid) -#else - subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) -#endif - - use ESMF - use pio - use shr_kind_mod , only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_getenv - use mkutilsMod , only : get_filename - use mkvarpar , only : nlevsoi, numrad, numstdpft -#ifdef TODO - use mkurbanparMod, only : numurbl, nlevurb - use mkglcmecMod , only : nglcec - use mkpftMod , only : mkpftAtt - use mksoilMod , only : mksoilAtt - use mkharvestMod , only : mkharvest_fieldname, mkharvest_numtypes, mkharvest_longname - use mkharvestMod , only : mkharvest_units, harvestDataType -#endif - use mkpioMod ! TODO: add only - use mkvarctl - - implicit none + subroutine mkfile_fsurdat(nx, ny, mesh_model, dynlanduse, & + pctlak, pctwet, lakedepth) ! input/output variables - type(ESMF_VM) , intent(inout) :: vm - integer , intent(in) :: nx - integer , intent(in) :: ny - character(len=*) , intent(in) :: fname - logical , intent(in) :: dynlanduse + integer , intent(in) :: nx + integer , intent(in) :: ny + logical , intent(in) :: dynlanduse + type(ESMF_Mesh) , intent(in) :: mesh_model + real(r8), pointer, intent(in) :: pctlak(:) ! percent of grid cell that is lake + real(r8), pointer, intent(in) :: pctwet(:) ! percent of grid cell that is wetland + real(r8), pointer, intent(in) :: lakedepth(:) ! lake depth (m) #ifdef TODO type(harvestDataType) , intent(in) :: harvdata #endif + ! local variables type(file_desc_t) :: pioid - integer :: j ! index - integer :: dimid ! temporary - integer :: values(8) ! temporary - character(len=256) :: str ! global attribute string - character(len=256) :: name ! name of attribute - character(len=256) :: unit ! units of attribute - character(len= 18) :: datetime ! temporary - character(len= 8) :: date ! temporary - character(len= 10) :: time ! temporary - character(len= 5) :: zone ! temporary - integer :: ier ! error status - integer :: omode ! netCDF output mode + character(len=256) :: varname + character(len=256) :: longname + character(len=256) :: units integer :: xtype ! external type integer, allocatable :: ind1D(:) ! Indices of 1D harvest variables integer, allocatable :: ind2D(:) ! Indices of 2D harvest variables integer :: rcode - character(len=*), parameter :: subname=' (mkfile) ' + integer :: rc + integer :: n, i + logical :: define_mode + type(io_desc_t) :: pio_iodesc + type(var_desc_t) :: pio_varid + real(r8), pointer :: rpointer1d(:) + character(len=*), parameter :: subname=' (mkfile_fsurdat) ' !----------------------------------------------------------------------- !--------------------------- @@ -70,15 +68,109 @@ subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) !--------------------------- ! TODO: what about setting no fill values? - call mkpio_wopen(pioid, trim(fname), clobber=.true.) - call ESMF_LogWrite(subname//'successfully opened output file '//trim(fname), ESMF_LOGMSG_INFO) + call mkpio_wopen(trim(fsurdat), clobber=.true., pioid=pioid) + + ! ---------------------------------------------------------------------- + ! Define dimensions and global attributes + ! ---------------------------------------------------------------------- + + call mkfile_define_dims(pioid, nx, ny, dynlanduse) + call mkfile_define_atts(pioid, dynlanduse) + + ! ---------------------------------------------------------------------- + ! Define and outut variables + ! ---------------------------------------------------------------------- + + call ESMF_LogWrite(subname//'defining variables', ESMF_LOGMSG_INFO) + + if ( outnc_double ) then + xtype = PIO_DOUBLE + else + xtype = PIO_REAL + end if + + do n = 1,2 + + define_mode = (n == 1) + if (.not. define_mode) then + rcode = pio_enddef(pioid) + end if + + if (.not. dynlanduse) then + + varname = 'PCT_LAKE' + longname = 'percent_lake' + units = 'unitless' + rpointer1d => pctlak + if (define_mode) then + call mkpio_def_spatial_var(pioid, trim(varname), xtype, trim(longname), trim(units)) + else + call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + call pio_write_darray(pioid, pio_varid, pio_iodesc, rpointer1d, rcode) + call pio_freedecomp(pioid, pio_iodesc) + end if + + varname = 'PCT_WETLAND' + longname = 'percent_wetland' + units = 'unitless' + rpointer1d => pctwet + if (define_mode) then + call mkpio_def_spatial_var(pioid, trim(varname), xtype, trim(longname), trim(units)) + else + call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + call pio_write_darray(pioid, pio_varid, pio_iodesc, rpointer1d, rcode) + call pio_freedecomp(pioid, pio_iodesc) + end if + + varname = 'LAKEDEPTH' + longname = 'lake depth' + units = 'm' + rpointer1d => lakedepth + if (define_mode) then + call mkpio_def_spatial_var(pioid, trim(varname), xtype, trim(longname), trim(units)) + else + ! inquire about varid here + call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + call pio_write_darray(pioid, pio_varid, pio_iodesc, rpointer1d, rcode) + call pio_freedecomp(pioid, pio_iodesc) + end if + + end if + end do + + ! Close surface dataset + call pio_closefile(pioid) + + if (root_task) then + write (ndiag,'(72a1)') ("-",i=1,60) + write (ndiag,'(a)')' land model surface data set successfully created for ' + end if + + end subroutine mkfile_fsurdat + +!================================================================================= + subroutine mkfile_define_dims(pioid, nx, ny, dynlanduse) - !--------------------------- ! Define dimensions. - !--------------------------- + + ! input/output variables + type(file_desc_t) , intent(in) :: pioid + integer , intent(in) :: nx, ny + logical , intent(in) :: dynlanduse + + ! local variables + integer :: dimid ! temporary + integer :: rcode + character(len=*), parameter :: subname = 'mkfile_define_dims' + !----------------------------------------------------------------------- call ESMF_LogWrite(subname//' defining dimensions', ESMF_LOGMSG_INFO) - write(6,*)'DEBUG: outnc_1d = ',outnc_1d if (outnc_1d) then rcode = pio_def_dim(pioid, 'gridcell', nx, dimid) @@ -101,6 +193,28 @@ subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) rcode = pio_def_dim(pioid, 'nchar' , 256, dimid) end if + end subroutine mkfile_define_dims + +!================================================================================= + subroutine mkfile_define_atts(pioid, dynlanduse) + + ! input/output variables + type(file_desc_t) , intent(in) :: pioid + logical , intent(in) :: dynlanduse + + ! local variables + integer :: values(8) ! temporary + character(len=256) :: str ! global attribute string + character(len=256) :: name ! name of attribute + character(len=256) :: unit ! units of attribute + character(len= 18) :: datetime ! temporary + character(len= 8) :: date ! temporary + character(len= 10) :: time ! temporary + character(len= 5) :: zone ! temporary + integer :: rcode + character(len=*), parameter :: subname = 'mkfile_define_atts' + !----------------------------------------------------------------------- + !--------------------------- ! Set global attributes. !--------------------------- @@ -231,288 +345,6 @@ subroutine mkfile(vm, nx, ny, fname, dynlanduse, pioid) rcode = pio_put_att(pioid, pio_global, 'mesh_vic_file', trim(str)) end if - ! ---------------------------------------------------------------------- - ! Define variables - ! ---------------------------------------------------------------------- - - call ESMF_LogWrite(subname//'defining variables', ESMF_LOGMSG_INFO) - if ( .not. outnc_double ) then - xtype = PIO_REAL - else - xtype = PIO_DOUBLE - end if - - !call mksoilAtt( pioid, dynlanduse, xtype ) - - !call mkpftAtt( pioid, dynlanduse, xtype ) - - call mkpio_def_spatial_var(pioid, varname='AREA' , xtype=PIO_DOUBLE, & - long_name='area', units='km^2') - - call mkpio_def_spatial_var(pioid, varname='LONGXY', xtype=PIO_DOUBLE, & - long_name='longitude', units='degrees east') - - call mkpio_def_spatial_var(pioid, varname='LATIXY', xtype=PIO_double, & - long_name='latitude', units='degrees north') - - if (.not. dynlanduse) then - call mkpio_def_spatial_var(pioid, varname='EF1_BTR', xtype=xtype, & - long_name='EF btr (isoprene)', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='EF1_FET', xtype=xtype, & - long_name='EF fet (isoprene)', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='EF1_FDT', xtype=xtype, & - long_name='EF fdt (isoprene)', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='EF1_SHR', xtype=xtype, & - long_name='EF shr (isoprene)', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='EF1_GRS', xtype=xtype, & - long_name='EF grs (isoprene)', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='EF1_CRP', xtype=xtype, & - long_name='EF crp (isoprene)', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='CANYON_HWR', xtype=xtype, & - lev1name='numurbl', & - long_name='canyon height to width ratio', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='EM_IMPROAD', xtype=xtype, & - lev1name='numurbl', & - long_name='emissivity of impervious road', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='EM_PERROAD', xtype=xtype, & - lev1name='numurbl', & - long_name='emissivity of pervious road', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='EM_ROOF', xtype=xtype, & - lev1name='numurbl', & - long_name='emissivity of roof', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='EM_WALL', xtype=xtype, & - lev1name='numurbl', & - long_name='emissivity of wall', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='HT_ROOF', xtype=xtype, & - lev1name='numurbl', & - long_name='height of roof', units='meters') - - call mkpio_def_spatial_var(pioid, varname='THICK_ROOF', xtype=xtype, & - lev1name='numurbl', & - long_name='thickness of roof', units='meters') - - call mkpio_def_spatial_var(pioid, varname='THICK_WALL', xtype=xtype, & - lev1name='numurbl', & - long_name='thickness of wall', units='meters') - - call mkpio_def_spatial_var(pioid, varname='T_BUILDING_MIN', xtype=xtype, & - lev1name='numurbl', & - long_name='minimum interior building temperature', units='K') - - call mkpio_def_spatial_var(pioid, varname='WIND_HGT_CANYON', xtype=xtype, & - lev1name='numurbl', & - long_name='height of wind in canyon', units='meters') - - call mkpio_def_spatial_var(pioid, varname='WTLUNIT_ROOF', xtype=xtype, & - lev1name='numurbl', & - long_name='fraction of roof', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='WTROAD_PERV', xtype=xtype, & - lev1name='numurbl', & - long_name='fraction of pervious road', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='ALB_IMPROAD_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='direct albedo of impervious road', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='ALB_IMPROAD_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='diffuse albedo of impervious road', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='ALB_PERROAD_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='direct albedo of pervious road', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='ALB_PERROAD_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='diffuse albedo of pervious road', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='ALB_ROOF_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='direct albedo of roof', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='ALB_ROOF_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='diffuse albedo of roof', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='ALB_WALL_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='direct albedo of wall', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='ALB_WALL_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='diffuse albedo of wall', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='TK_ROOF', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='thermal conductivity of roof', units='W/m*K') - - call mkpio_def_spatial_var(pioid, varname='TK_WALL', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='thermal conductivity of wall', units='W/m*K') - - call mkpio_def_spatial_var(pioid, varname='TK_IMPROAD', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='thermal conductivity of impervious road', units='W/m*K') - - call mkpio_def_spatial_var(pioid, varname='CV_ROOF', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='volumetric heat capacity of roof', units='J/m^3*K') - - call mkpio_def_spatial_var(pioid, varname='CV_WALL', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='volumetric heat capacity of wall', units='J/m^3*K') - - call mkpio_def_spatial_var(pioid, varname='CV_IMPROAD', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='volumetric heat capacity of impervious road', units='J/m^3*K') - - call mkpio_def_spatial_var(pioid, varname='NLEV_IMPROAD', xtype=PIO_INT, & - lev1name='numurbl', & - long_name='number of impervious road layers', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='peatf', xtype=xtype, & - long_name='peatland fraction', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='zbedrock', xtype=xtype, & - long_name='soil depth', units='m') - - call mkpio_def_spatial_var(pioid, varname='abm', xtype=PIO_INT, & - long_name='agricultural fire peak month', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='gdp', xtype=xtype, & - long_name='gdp', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='SLOPE', xtype=xtype, & - long_name='mean topographic slope', units='degrees') - - call mkpio_def_spatial_var(pioid, varname='STD_ELEV', xtype=xtype, & - long_name='standard deviation of elevation', units='m') - - if ( outnc_vic )then - call mkpio_def_spatial_var(pioid, varname='binfl', xtype=xtype, & - long_name='VIC b parameter for the Variable Infiltration Capacity Curve', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='Ws', xtype=xtype, & - long_name='VIC Ws parameter for the ARNO curve', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='Dsmax', xtype=xtype, & - long_name='VIC Dsmax parameter for the ARNO curve', units='mm/day') - - call mkpio_def_spatial_var(pioid, varname='Ds', xtype=xtype, & - long_name='VIC Ds parameter for the ARNO curve', units='unitless') - - end if - call mkpio_def_spatial_var(pioid, varname='LAKEDEPTH', xtype=xtype, & - long_name='lake depth', units='m') - - call mkpio_def_spatial_var(pioid, varname='PCT_WETLAND', xtype=xtype, & - long_name='percent wetland', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='PCT_LAKE', xtype=xtype, & - long_name='percent lake', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='PCT_GLACIER', xtype=xtype, & - long_name='percent glacier', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='GLACIER_REGION', xtype=PIO_INT, & - long_name='glacier region ID', units='unitless') - - call mkpio_defvar(pioid, varname='GLC_MEC', xtype=xtype, & - dim1name='nglcecp1', long_name='Glacier elevation class', units='m') - - call mkpio_def_spatial_var(pioid, varname='PCT_GLC_MEC', xtype=xtype, & - lev1name='nglcec', & - long_name='percent glacier for each glacier elevation class (% of landunit)', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='TOPO_GLC_MEC', xtype=xtype, & - lev1name='nglcec', & - long_name='mean elevation on glacier elevation classes', units='m') - - call ESMF_LogWrite('DEBUG: here1', ESMF_LOGMSG_INFO) - - if ( outnc_3dglc ) then - call mkpio_def_spatial_var(pioid, varname='PCT_GLC_MEC_GIC', xtype=xtype, & - lev1name='nglcec', & - long_name='percent smaller glaciers and ice caps for each glacier elevation class (% of landunit)', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='PCT_GLC_MEC_ICESHEET', xtype=xtype, & - lev1name='nglcec', & - long_name='percent ice sheet for each glacier elevation class (% of landunit)', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='PCT_GLC_GIC', xtype=xtype, & - long_name='percent ice caps/glaciers (% of landunit)', units='unitless') - - call mkpio_def_spatial_var(pioid, varname='PCT_GLC_ICESHEET', xtype=xtype, & - long_name='percent ice sheet (% of landunit)', units='unitless') - end if - - call ESMF_LogWrite('DEBUG: here2', ESMF_LOGMSG_INFO) - - call mkpio_def_spatial_var(pioid, varname='PCT_URBAN', xtype=xtype, & - lev1name='numurbl', & - long_name='percent urban for each density type', units='unitless') - - call ESMF_LogWrite('DEBUG: here3', ESMF_LOGMSG_INFO) - - call mkpio_def_spatial_var(pioid, varname='URBAN_REGION_ID', xtype=PIO_INT, & - long_name='urban region ID', units='unitless') - -#ifdef TODO - call harvdata%getFieldsIdx( ind1D, ind2D ) - do j = 1, harvdata%num1Dfields() - call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind1D(j),constant=.true.), xtype=xtype, & - long_name=mkharvest_longname(ind1D(j)), units=mkharvest_units(ind1D(j)) ) - end do - do j = 1, harvdata%num2Dfields() - call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind2D(j),constant=.true.), xtype=xtype, & - lev1name=harvdata%getFieldsDim(ind2D(j)), & - long_name=mkharvest_longname(ind2D(j)), units=mkharvest_units(ind2D(j)) ) - end do - deallocate(ind1D, ind2D) -#endif - - call ESMF_LogWrite('DEBUG: here4', ESMF_LOGMSG_INFO) - - else - -#ifdef TODO - call harvdata%getFieldsIdx( ind1D, ind2D ) - do j = 1, harvdata%num1Dfields() - call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind1D(j),constant=.false.), xtype=xtype, & - lev1name='time', & - long_name=mkharvest_longname(ind1D(j)), units=mkharvest_units(ind1D(j)) ) - end do - do j = 1, harvdata%num2Dfields() - call mkpio_def_spatial_var(pioid, varname=mkharvest_fieldname(ind2D(j),constant=.false.), xtype=xtype, & - lev1name=harvdata%getFieldsDim(ind2D(j)), lev2name="time", & - long_name=mkharvest_longname(ind2D(j)), units=mkharvest_units(ind2D(j)) ) - end do - deallocate(ind1D, ind2D) -#endif - - end if ! .not. dynlanduse - - call ESMF_LogWrite('DEBUG: here5', ESMF_LOGMSG_INFO) - - ! End of define mode - rcode = pio_enddef(pioid) - - call ESMF_LogWrite('DEBUG: closing file', ESMF_LOGMSG_INFO) - call pio_closefile(pioid) - call ESMF_LogWrite('DEBUG: closed file', ESMF_LOGMSG_INFO) - - end subroutine mkfile + end subroutine mkfile_define_atts end module mkfileMod diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index b455a1ee00..ded81b86b9 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -126,6 +126,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regrid_data in lanwat") do no = 1,size(lake_o) + write(6,*)'DEBUG: n,lake_o = ',no,lake_o(no) if (lake_o(no) < 1.) lake_o(no) = 0. enddo diff --git a/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 b/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 index 8c2c9b7c53..8a4073e6b3 100644 --- a/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 @@ -95,7 +95,7 @@ function constructor_pong(pct_p2g, first_pft_index, default_pct_p2l) result(this if (size(default_pct_p2l) /= size(pct_p2g)) then write(6,*) subname//' ERROR: size of default_pct_p2l must match size of pct_p2g' - call abort() + call shr_sys_abort() end if last_pft_index = first_pft_index + size(pct_p2g) - 1 @@ -274,7 +274,7 @@ subroutine set_pct_l2g(this, pct_l2g_new) if (pct_l2g_new < 0._r8 .or. pct_l2g_new > (100._r8 + tol)) then write(6,*) subname//' ERROR: pct_l2g_new must be between 0 and 100%' write(6,*) 'pct_l2g_new = ', pct_l2g_new - call abort() + call shr_sys_abort() end if this%pct_l2g = pct_l2g_new @@ -310,7 +310,7 @@ subroutine set_one_pct_p2g(this, pft_index, pct_p2g_new) if (pct_p2g_new < 0._r8 .or. pct_p2g_new > (100._r8 + tol)) then write(6,*) subname//' ERROR: pct_p2g_new must be between 0 and 100%' write(6,*) 'pct_p2g_new = ', pct_p2g_new - call abort() + call shr_sys_abort() end if allocate(pct_p2g(lbound(this%pct_p2l, 1) : ubound(this%pct_p2l, 1))) @@ -435,24 +435,24 @@ subroutine convert_from_p2g(this, pct_p2g, default_pct_p2l) if (size(pct_p2g) /= size(this%pct_p2l) .or. size(default_pct_p2l) /= size(this%pct_p2l)) then write(6,*) subname//' ERROR: array size mismatch: ' write(6,*) size(pct_p2g), size(default_pct_p2l), size(this%pct_p2l) - call abort() + call shr_sys_abort() end if if (abs(sum(default_pct_p2l) - 100._r8) > tol) then write(6,*) subname//' ERROR: default_pct_p2l must sum to 100' - call abort() + call shr_sys_abort() end if if (any(pct_p2g < 0._r8)) then write(6,*) subname//' ERROR: negative values found in pct_p2g array' write(6,*) pct_p2g - call abort() + call shr_sys_abort() end if if (sum(pct_p2g) < 0._r8 .or. sum(pct_p2g) > (100._r8 + tol)) then write(6,*) subname//' ERROR: pct_p2g must be between 0 and 100' write(6,*) 'sum(pct_p2g) = ', sum(pct_p2g) - call abort() + call shr_sys_abort() end if ! Done checking pre-conditions @@ -489,19 +489,19 @@ subroutine check_vals(this, caller) if (abs(sum(this%pct_p2l) - 100._r8) > tol) then write(6,*) subname//' ERROR from ', caller, ': pct_p2l does not sum to 100' write(6,*) 'sum(this%pct_p2l) = ', sum(this%pct_p2l) - call abort() + call shr_sys_abort() end if if (any(this%pct_p2l < 0._r8)) then write(6,*) subname//' ERROR from ', caller, ': negative values found in pct_p2l' write(6,*) this%pct_p2l - call abort() + call shr_sys_abort() end if if (this%pct_l2g < 0._r8 .or. this%pct_l2g > (100._r8 + tol)) then write(6,*) subname//' ERROR from ', caller, ': pct_l2g must be between 0 and 100' write(6,*) 'pct_l2g = ', this%pct_l2g - call abort() + call shr_sys_abort() end if end subroutine check_vals @@ -542,7 +542,7 @@ subroutine update_max_array(pct_pft_max_arr,pct_pft_arr) ubound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_ubound) then write(6,*) subname//' ERROR: all elements of pct_pft_arr must have' write(6,*) 'the same size and lower bound for their pct_p2l array' - call abort() + call shr_sys_abort() end if if (pct_pft_arr(arr_index)%pct_l2g > pct_pft_max_arr(arr_index)%pct_l2g) then @@ -591,7 +591,7 @@ function get_pct_p2l_array(pct_pft_arr) result(pct_p2l) ubound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_ubound) then write(6,*) subname//' ERROR: all elements of pct_pft_arr must have' write(6,*) 'the same size and lower bound for their pct_p2l array' - call abort() + call shr_sys_abort() end if do pft_index = pft_lbound, pft_ubound diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index 2866e24656..92806d7ec7 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -1,18 +1,5 @@ module mkpftMod - !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mkpft - ! - ! !DESCRIPTION: - ! Make PFT data - ! - ! !REVISION HISTORY: - ! Author: Mariana Vertenstein - ! - !----------------------------------------------------------------------- - !!USES: use shr_kind_mod, only : r8 => shr_kind_r8 use mkvarpar , only : noveg use mkvarctl , only : numpft @@ -20,33 +7,27 @@ module mkpftMod use mkpftConstantsMod implicit none - private ! By default make data private - ! - ! !PUBLIC MEMBER FUNCTIONS: - ! + public mkpftInit ! Initialization public mkpft ! Set PFT public mkpft_parse_oride ! Parse the string with PFT fraction/index info to override public mkpftAtt ! Write out attributes to output file on pft - ! - ! !PUBLIC DATA MEMBERS: - ! - ! + private :: mkpft_check_oride ! Check the pft_frc and pft_idx values for correctness + ! When pft_idx and pft_frc are set, they must be set together, and they will cause the ! entire area to be covered with vegetation and zero out other landunits. ! The sum of pft_frc must = 100%, and each pft_idx point in the array corresponds to ! the fraction in pft_frc. Only the first few points are used until pft_frc = 0.0. - ! + integer :: m ! index integer, public :: pft_idx(0:maxpft) = & ! PFT vegetation index to override with (/ ( -1, m = 0, maxpft ) /) real(r8), public :: pft_frc(0:maxpft) = & ! PFT vegetation fraction to override with (/ ( 0.0_r8, m = 0, maxpft ) /) - ! + ! !PRIVATE DATA MEMBERS: - ! logical, public, protected :: use_input_pft = .false. ! Flag to override PFT with input values logical, public, protected :: presc_cover = .false. ! Flag to prescribe vegetation coverage integer, private :: nzero ! index of first zero fraction @@ -66,54 +47,34 @@ module mkpftMod module procedure :: constructor ! PFT Overide object constructor end interface pft_oride - type(pft_oride), private :: pft_override ! Module instance of PFT override object - ! Used for both zeroing out PFT's as well - ! as setting specified PFT's over the gridcell - ! - ! !PRIVATE MEMBER FUNCTIONS: - ! - private :: mkpft_check_oride ! Check the pft_frc and pft_idx values for correctness - !EOP - !=============================================================== + ! Module instance of PFT override object + ! Used for both zeroing out PFT's as well as setting specified PFT's over the gridcell + type(pft_oride), private :: pft_override + +!=============================================================== contains - !=============================================================== +!=============================================================== - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkpftInit - ! - ! !INTERFACE: subroutine mkpftInit( zero_out_l, all_veg_l ) ! - ! !DESCRIPTION: ! Initialize of Make PFT data - ! !USES: + ! use mkvarpar, only : numstdpft, numstdcft - ! + ! !ARGUMENTS: - implicit none logical, intent(IN) :: zero_out_l ! If veg should be zero'ed out - logical, intent(IN) :: all_veg_l ! If should zero out other fractions so that - ! all land-cover is vegetation - ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: Erik Kluzek - ! - ! + logical, intent(IN) :: all_veg_l ! If should zero out other fractions so that all land-cover is vegetation + ! !LOCAL VARIABLES: - !EOP + logical :: error_happened ! If an error was triggered so should return real(r8), parameter :: hndrd = 100.0_r8 ! A hundred percent - character(len=32) :: subname = 'mkpftMod::mkpftInit() ' - logical :: error_happened ! If an error was triggered so should return + character(len=*), parameter :: subname = ' (mkpftInit) ' !----------------------------------------------------------------------- - write (6, '(a, a, a)') "In ", trim(subname), "..." + + write (6, '(a, a, a)') "In ", subname, "..." if ( maxpft < numpft ) then write(6,*) subname//'number PFT is > max allowed!' - call abort() + call shr_sys_abort() return end if nzero = -1 @@ -124,7 +85,7 @@ subroutine mkpftInit( zero_out_l, all_veg_l ) end if if ( zero_out_l .and. use_input_pft )then write(6,*) subname//"trying to both zero out all PFT's as well as set them to specific values" - call abort() + call shr_sys_abort() return end if ! If zeroing out, set use_input_pft to true so the pft_override will be used @@ -140,13 +101,12 @@ subroutine mkpftInit( zero_out_l, all_veg_l ) end if if ( all_veg_l .and. .not. use_input_pft )then write(6,*) subname//'if all_veg is set to true then specified PFT indices must be provided (i.e. pft_frc and pft_idx)' - call abort() - return + call shr_sys_abort() end if if ( zero_out_l .and. all_veg_l )then write(6,*) subname//'zeroing out vegetation and setting vegetation to 100% is a contradiction!' - call abort() + call shr_sys_abort() return end if @@ -176,12 +136,10 @@ subroutine mkpftInit( zero_out_l, all_veg_l ) ! correspondence mentioned above if (cft_ub /= numpft) then write(6,*) 'CFT_UB set up incorrectly: cft_ub, numpft = ', cft_ub, numpft - call abort() - return + call shr_sys_abort() end if - ! + ! Set the PFT override values if applicable - ! pft_override = pft_oride() presc_cover = .false. if( zero_out_l )then @@ -213,7 +171,6 @@ end subroutine mkpftInit subroutine mkpft(ldomain, mapfname, fpft, ndiag, & pctlnd_o, pctnatpft_o, pctcft_o) ! - ! !DESCRIPTION: ! Make PFT data ! ! This dataset consists of the %cover of the [numpft]+1 PFTs used by @@ -226,7 +183,6 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & ! Upon return from this routine, the % cover of the natural veg + crop landunits is ! generally 100% everywhere; this will be normalized later to account for special landunits. ! - ! !USES: use mkdomainMod, only : domain_type, domain_clean, domain_read use mkgridmapMod use mkvarpar @@ -236,7 +192,6 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & use mkpftConstantsMod, only : natpft_lb, natpft_ub, num_cft, cft_lb, cft_ub ! ! !ARGUMENTS: - implicit none type(domain_type), intent(in) :: ldomain character(len=*) , intent(in) :: mapfname ! input mapping file name character(len=*) , intent(in) :: fpft ! input pft dataset file name @@ -245,15 +200,7 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & type(pct_pft_type), intent(out):: pctnatpft_o(:) ! natural PFT cover type(pct_pft_type), intent(out):: pctcft_o(:) ! crop (CFT) cover ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: Mariana Vertenstein - ! - ! ! !LOCAL VARIABLES: - !EOP type(pct_pft_type), allocatable:: pctnatpft_i(:) ! input grid: natural PFT cover type(pct_pft_type), allocatable:: pctcft_i(:) ! input grid: crop (CFT) cover type(domain_type) :: tdomain ! local domain @@ -294,12 +241,13 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & !----------------------------------------------------------------------- write (6,*) - write (6, '(a, a, a)') "In ", trim(subname), "..." + write (6, '(a, a, a)') "In ", subname, "..." write (6,*) 'Attempting to make PFTs .....' ! ----------------------------------------------------------------- ! Set the vegetation types ! ----------------------------------------------------------------- + if ( numpft >= numstdpft )then veg(0:maxpft) = (/ & 'not vegetated ', & @@ -383,37 +331,42 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & 'irrigated_tropical_soybean ' /) end if if ( numpft == numstdpft )then - write(6,*)'Creating surface datasets with the standard # of PFTs =', numpft + if (root_task) then + write(ndiag, '(a,i8)')'Creating surface datasets with the standard # of PFTs =', numpft + end if else if ( numpft > numstdpft )then - write(6,*)'Creating surface datasets with extra types for crops; total pfts =', numpft + if (root_task) then + write(ndiag,'(a,i8)')'Creating surface datasets with extra types for crops; total pfts =', numpft else write(6,*) subname//': parameter numpft is NOT set to a known value (should be 16 or more) =',numpft - call abort() - return + call shr_sys_abort() end if - ns_o = ldomain%ns - ! ----------------------------------------------------------------- ! Read input PFT file ! ----------------------------------------------------------------- - if ( .not. presc_cover ) then - ! Obtain input grid info, read PCT_PFT - call domain_read(tdomain,fpft) - ns_i = tdomain%ns + ns_o = size(pctlnd_o) - write (6,*) 'Open PFT file: ', trim(fpft) - call check_ret(nf_open(fpft, 0, ncid), subname) + if ( .not. presc_cover ) then - ! Check what variables exist to determine what format the file is in - call check_ret(nf_inq_varid (ncid, 'PCT_PFT', varid), subname, varexists=oldformat) + ! Obtain input grid info, read PCT_PFT - if ( oldformat ) then - write(6,*) subname//' ERROR: PCT_PFT field on the the file so it is in the old format, which is no longer supported' - call abort() - return + ! create field on input mesh (first read in input mesh) + call ESMF_VMLogMemInfo("Before create mesh_i in lanwat") + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in lanwat") + + if (root_task) then + write (ndiag,'(a)') 'Opening PFT file: '//trim(fpft) end if + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(fpft), pio_nowrite) + call check_ret(nf_inq_dimid (ncid, 'natpft', dimid), subname) call check_ret(nf_inq_dimlen (ncid, dimid, natpft_i), subname) call check_ret(nf_inq_dimid (ncid, 'cft', dimid), subname) @@ -426,14 +379,14 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & if (numpft_i .eq. numstdpft+1) then write(6,*) subname//' ERROR: trying to use non-crop input file' write(6,*) 'for a surface dataset with crops.' - call abort() + call shr_sys_abort() return else if (numpft_i > numstdpft+1 .and. numpft_i == maxpft+1) then write(6,*) subname//' WARNING: using a crop input raw dataset for a non-crop output surface dataset' else write(6,*) subname//': parameter numpft+1= ',numpft+1, & 'does not equal input dataset numpft= ',numpft_i - call abort() + call shr_sys_abort() return end if endif @@ -447,25 +400,55 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & ! If file is in the new format, expect the following variables: ! PCT_NATVEG, PCT_CROP, PCT_NAT_PFT, PCT_CFT - allocate(pctnatveg_i(ns_i), & - pctnatveg_o(ns_o), & - pctcrop_i(ns_i), & - pctcrop_o(ns_o), & - frac_dst(ns_o), & - pct_cft_i(ns_i,1:num_cft), & - pct_cft_o(ns_o,1:num_cft), & - pct_nat_pft_i(ns_i,0:num_natpft), & - pct_nat_pft_o(ns_o,0:num_natpft), & - stat=ier) - if (ier/=0)then - call abort() - return + allocate(pctnatveg_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + + allocate(pctnatveg_o(ns_o), stat=ier) + allocate(pctcrop_i(ns_i), stat=ier) + allocate(pctcrop_o(ns_o), stat=ier) + allocate(frac_dst(ns_o), stat=ier) + allocate(pct_cft_i(ns_i,1:num_cft), stat=ier) + allocate(pct_cft_o(ns_o,1:num_cft), stat=ier) + allocate(pct_nat_pft_i(ns_i,0:num_natpft), stat=ier) + allocate(pct_nat_pft_o(ns_o,0:num_natpft), stat=ier) + + ! Open the raw data file + call ESMF_VMLogMemInfo("Before pio_openfile in regrid_data for "//trim(filename)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(filename), pio_nowrite) + + ! Create an io descriptor + call ESMF_VMLogMemInfo("After pio_openfile in mkpftMod") + call mkpio_iodesc_rawdata(mesh_i, 'PCT_NATVEG', pioid, pio_varid, pio_vartype, pio_iodesc, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_iodesc in mkpftMod") + + ! Read in + if (pio_vartype == PIO_REAL) then + allocate(data_real(ns_i)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real, rcode) + data_i(:) = real(data_real(:), kind=r8) + deallocate(data_real) + else if (pio_vartype == PIO_DOUBLE) then + allocate(data_double(ns_i)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double, rcode) + data_i(:) = data_double(:) + deallocate(data_double) + else + call shr_sys_abort(subName//"ERROR: only real and double types are supported") end if + + call pio_freedecomp(pioid, pio_iodesc) + call pio_closefile(pioid) + call ESMF_VMLogMemInfo("After pio_read_darry in regrid_data") + + + call check_ret(nf_inq_varid (ncid, 'PCT_NATVEG', varid), subname) call check_ret(nf_get_var_double (ncid, varid, pctnatveg_i), subname) call check_ret(nf_inq_varid (ncid, 'PCT_CROP', varid), subname) call check_ret(nf_get_var_double (ncid, varid, pctcrop_i), subname) + if ( .not. use_input_pft )then call check_ret(nf_inq_varid (ncid, 'PCT_CFT', varid), subname) call get_dim_lengths(ncid, 'PCT_CFT', ndims, dimlens(:) ) @@ -485,7 +468,7 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & deallocate( temp_i ) else write(6,*) subname//': ERROR: dimensions for PCT_CROP are NOT what is expected' - call abort() + call shr_sys_abort() return end if call check_ret(nf_inq_varid (ncid, 'PCT_NAT_PFT', varid), subname) @@ -510,7 +493,7 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & pct_nat_pft_o(ns_o,0:num_natpft), & stat=ier) if (ier/=0)then - call abort() + call shr_sys_abort() return end if end if @@ -520,7 +503,7 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & pctcft_i(ns_i), & stat=ier) if (ier/=0)then - call abort() + call shr_sys_abort() return end if @@ -599,14 +582,14 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & if ( pft_override%natveg <= 0.0_r8 )then write(6,*) subname//': ERROR: no natural vegetation PFTs are being prescribed but there are natural '// & 'vegetation areas: provide at least one natural veg PFT' - call abort() + call shr_sys_abort() return end if end if if (pctlnd_o(no) > 1.0e-6 .and. pctcrop_o(no) > 1.0e-6) then if ( pft_override%crop <= 0.0_r8 )then write(6,*) subname//': ERROR: no crop CFTs are being prescribed but there are crop areas: provide at least one CFT' - call abort() + call shr_sys_abort() return end if end if @@ -650,7 +633,7 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & write (6,*) subname//'error: nat pft = ', & (pct_nat_pft_o(no,m), m = 0, num_natpft), & ' do not sum to 100. at no = ',no,' but to ', wst_sum - call abort() + call shr_sys_abort() end if ! Correct sum so that if it differs slightly from 100, it is corrected to equal @@ -667,7 +650,7 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & write (6,*) subname//'error: crop cft = ', & (pct_cft_o(no,m), m = 1, num_cft), & ' do not sum to 100. at no = ',no,' but to ', wst_sum - call abort() + call shr_sys_abort() end if ! Correct sum so that if it differs slightly from 100, it is corrected to equal @@ -831,7 +814,7 @@ subroutine mkpft_parse_oride( string ) call shr_string_betweenTags( string, frc_start, frc_end, substring, rc ) if ( rc /= 0 )then write(6,*) subname//'Trouble finding pft_frac start end tags' - call abort() + call shr_sys_abort() return end if num_elms = shr_string_countChar( substring, ",", rc ) @@ -839,12 +822,12 @@ subroutine mkpft_parse_oride( string ) call shr_string_betweenTags( string, idx_start, idx_end, substring, rc ) if ( rc /= 0 )then write(6,*) subname//'Trouble finding pft_index start end tags' - call abort() + call shr_sys_abort() return end if if ( num_elms /= shr_string_countChar( substring, ",", rc ) )then write(6,*) subname//'number of elements different between frc and idx fields' - call abort() + call shr_sys_abort() return end if read(substring,*) pft_idx(0:num_elms) @@ -887,11 +870,11 @@ subroutine mkpft_check_oride( error_happened ) ! PFT fraction is NOT used use_input_pft = .false. else if ( abs(sumpft - hndrd) > 1.e-6 )then - write(6, '(a, a, f15.12)') trim(subname), 'Sum of PFT fraction is NOT equal to 100% =', sumpft + write(6, '(a, a, f15.12)') subname, 'Sum of PFT fraction is NOT equal to 100% =', sumpft write(6,*) 'Set PFT fraction to : ', pft_frc(0:nzero) write(6,*) 'With PFT index : ', pft_idx(0:nzero) error_happened = .true. - call abort() + call shr_sys_abort() return else use_input_pft = .true. @@ -907,19 +890,19 @@ subroutine mkpft_check_oride( error_happened ) if ( pft_frc(i) < 0.0_r8 .or. pft_frc(i) > hndrd )then write(6,*) subname//'PFT fraction is out of range: pft_frc=', pft_frc(i) error_happened = .true. - call abort() + call shr_sys_abort() return else if ( pft_frc(i) > 0.0_r8 .and. pft_idx(i) == -1 )then write(6,*) subname//'PFT fraction > zero, but index NOT set: pft_idx=', pft_idx(i) error_happened = .true. - call abort() + call shr_sys_abort() return end if ! PFT index out of range if ( pft_idx(i) < 0 .or. pft_idx(i) > numpft )then write(6,*) subname//'PFT index is out of range: ', pft_idx(i) error_happened = .true. - call abort() + call shr_sys_abort() return end if ! Make sure index values NOT used twice @@ -927,7 +910,7 @@ subroutine mkpft_check_oride( error_happened ) if ( pft_idx(i) == pft_idx(j) )then write(6,*) subname//'Same PFT index is used twice: ', pft_idx(i) error_happened = .true. - call abort() + call shr_sys_abort() return end if end do @@ -937,7 +920,7 @@ subroutine mkpft_check_oride( error_happened ) if ( pft_frc(i) /= 0.0_r8 .or. pft_idx(i) /= -1 )then write(6,*) subname//'After PFT fraction is zeroed out, fraction is non zero, or index set' error_happened = .true. - call abort() + call shr_sys_abort() return end if end do @@ -1127,12 +1110,12 @@ function constructor( ) result(this) this%natveg = -1.0_r8 if ( num_natpft < 0 )then write(6,*) subname//'num_natpft is NOT set = ', num_natpft - call abort() + call shr_sys_abort() return end if if ( num_cft < 0 )then write(6,*) subname//'num_cft is NOT set = ', num_cft - call abort() + call shr_sys_abort() return end if allocate( this%natpft(noveg:num_natpft) ) @@ -1195,7 +1178,7 @@ subroutine InitAllPFTIndex( this ) i = pft_idx(m) if ( (i < noveg) .or. (i > numpft) )then write(6,*) subname//'PFT index is out of valid range' - call abort() + call shr_sys_abort() return else if ( i <= num_natpft )then this%natpft(i) = pft_frc(m) diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 050d439afc..7978bf1a97 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -73,7 +73,8 @@ subroutine mkpio_get_rawdata(filename, varname, mesh_i, data_i, rc) call ESMF_VMLogMemInfo("Before pio_openfile in regrid_data for "//trim(filename)) rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(filename), pio_nowrite) call ESMF_VMLogMemInfo("After pio_openfile in regrid_data") - call ESMF_VMLogMemInfo("After field get") + + ! TODO: put this in the calling file call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_iodesc in regrid_data") @@ -90,8 +91,8 @@ subroutine mkpio_get_rawdata(filename, varname, mesh_i, data_i, rc) else call shr_sys_abort(subName//"ERROR: only real and double types are supported") end if - call pio_freedecomp(pioid, pio_iodesc) call pio_closefile(pioid) + call pio_freedecomp(pio_iosystem, pio_iodesc) call ESMF_VMLogMemInfo("After pio_read_darry in regrid_data") end subroutine mkpio_get_rawdata @@ -140,7 +141,6 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, ! get pio variable id, type and number of dimensions call ESMF_VMLogMemInfo("Beginning getting variable id") - call PIO_seterrorhandling(pioid, PIO_BCAST_ERROR) rcode = pio_inq_varid(pioid, trim(varname), pio_varid) rcode = pio_inq_vartype(pioid, pio_varid, pio_vartype) rcode = pio_inq_varndims(pioid, pio_varid, ndims) @@ -197,7 +197,7 @@ logical function mkpio_file_exists(filename) end function mkpio_file_exists !=============================================================================== - subroutine mkpio_wopen(pioid, filename, clobber) + subroutine mkpio_wopen(filename, clobber, pioid) !--------------- ! open netcdf file @@ -209,9 +209,9 @@ subroutine mkpio_wopen(pioid, filename, clobber) use pio , only : pio_seterrorhandling, pio_file_is_open, pio_clobber, pio_write, pio_noclobber ! input/output arguments - type(file_desc_t) , intent(inout) :: pioid character(len=*) , intent(in) :: filename logical , intent(in) :: clobber + type(file_desc_t) , intent(inout) :: pioid ! local variables integer :: rcode @@ -237,6 +237,7 @@ subroutine mkpio_wopen(pioid, filename, clobber) endif else ! only applies to classic NETCDF files. + nmode = pio_noclobber if (pio_iotype == PIO_IOTYPE_NETCDF .or. pio_iotype == PIO_IOTYPE_PNETCDF) then nmode = ior(nmode,pio_ioformat) endif @@ -389,11 +390,11 @@ subroutine mkpio_def_spatial_var_0lev(pioid, varname, xtype, long_name, units) use mkvarctl, only : outnc_1d ! !ARGUMENTS: - type(file_desc_t) , intent(in) :: pioid - character(len=*) , intent(in) :: varname ! variable name - integer , intent(in) :: xtype ! external type - character(len=*) , intent(in) :: long_name ! attribute - character(len=*) , intent(in) :: units ! attribute + type(file_desc_t) , intent(in) :: pioid + character(len=*) , intent(in) :: varname ! variable name + integer , intent(in) :: xtype ! external type + character(len=*) , intent(in) :: long_name ! attribute + character(len=*) , intent(in) :: units ! attribute ! !LOCAL VARIABLES: character(len=*), parameter :: subname = 'mkpio_def_spatial_var_0lev' diff --git a/tools/mksurfdata_esmf/src/mksoilMod.F90 b/tools/mksurfdata_esmf/src/mksoilMod.F90 index 8e580cc9c3..bd68e779c8 100644 --- a/tools/mksurfdata_esmf/src/mksoilMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilMod.F90 @@ -56,20 +56,20 @@ subroutine mksoiltexInit( ) write(6,*) 'Replace soil clay % for all points with: ', soil_clay if ( soil_sand == unset )then write (6,*) subname//':error: soil_clay set, but NOT soil_sand' - call abort() + call shr_sys_abort() end if end if if ( soil_sand /= unset )then write(6,*) 'Replace soil sand % for all points with: ', soil_sand if ( soil_clay == unset )then write (6,*) subname//':error: soil_sand set, but NOT soil_clay' - call abort() + call shr_sys_abort() end if sumtex = soil_sand + soil_clay if ( sumtex < 0.0_r8 .or. sumtex > 100.0_r8 )then write (6,*) subname//':error: soil_sand and soil_clay out of bounds: sand, clay = ', & soil_sand, soil_clay - call abort() + call shr_sys_abort() end if end if @@ -166,7 +166,7 @@ subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) allocate(sand_i(mapunitmax,nlay), & clay_i(mapunitmax,nlay), & mapunit_i(ns_i), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() call check_ret(nf_inq_varid (ncid, 'MAPUNITS', varid), subname) call check_ret(nf_get_var_double (ncid, varid, mapunit_i), subname) @@ -190,7 +190,7 @@ subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) ! Obtain frac_dst allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) ! kmap_max are the maximum number of mapunits that will consider on @@ -214,13 +214,13 @@ subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) write(6,*)'kmap_max= ',kmap_max,' maxovr= ',maxovr,' ns_o= ',ns_o,' size= ',(kmap_max+1)*ns_o allocate(kmap(0:kmap_max,ns_o), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() allocate(kwgt(0:kmap_max,ns_o), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() allocate(kmax(ns_o), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() allocate(wst(0:kmap_max), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() kwgt(:,:) = 0. kmap(:,:) = 0 @@ -246,7 +246,7 @@ subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) write(6,*)'kmax is > kmap_max= ',kmax(no), 'kmap_max = ', & kmap_max,' for no = ',no write(6,*)'reset kmap_max in mksoilMod to a greater value' - call abort() + call shr_sys_abort() end if kmap(kmax(no),no) = k kwgt(kmax(no),no) = wt @@ -319,7 +319,7 @@ subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) ! Global sum of output field allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() mask_r8 = tdomain%mask call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) @@ -355,7 +355,7 @@ subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunittemp,l), & ' clay = ',clay_i(mapunittemp,l), & ' not assigned to soil type for input grid lon,lat,layer = ',ni,l - call abort() + call shr_sys_abort() 101 continue gast_i(m) = gast_i(m) + tgridmap%area_src(ni)*tdomain%mask(ni)*re**2 end do @@ -383,7 +383,7 @@ subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & ' clay = ',clay_o(no,l), & ' not assigned to soil type for output grid lon,lat,layer = ',no,l - call abort() + call shr_sys_abort() 102 continue gast_o(m) = gast_o(m) + tgridmap%area_dst(no)*frac_dst(no)*re**2 end do @@ -447,7 +447,7 @@ subroutine mksoilcolInit( ) if ( soil_color /= unsetcol )then if ( soil_color < 0 .or. soil_color > 20 )then write(6,*)'soil_color is out of range = ', soil_color - call abort() + call shr_sys_abort() end if write(6,*) 'Replace soil color for all points with: ', soil_color end if @@ -502,9 +502,9 @@ subroutine mksoilcol(ldomain, mapfname, datfname, ndiag, & call domain_read(tdomain,datfname) ns_i = tdomain%ns allocate(soil_color_i(ns_i), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() write (6,*) 'Open soil color file: ', trim(datfname) call check_ret(nf_open(datfname, 0, ncid), subname) @@ -555,7 +555,7 @@ subroutine mksoilcol(ldomain, mapfname, datfname, ndiag, & col(8) = 'class 8: dark ' else write(6,*)'nsoicol value of ',nsoicol,' is not currently supported' - call abort() + call shr_sys_abort() end if ! Error check soil_color if it is set @@ -563,7 +563,7 @@ subroutine mksoilcol(ldomain, mapfname, datfname, ndiag, & if ( soil_color > nsoicol )then write(6,*)'soil_color is out of range = ', soil_color - call abort() + call shr_sys_abort() end if do no = 1,ns_o @@ -593,7 +593,7 @@ subroutine mksoilcol(ldomain, mapfname, datfname, ndiag, & ! Global sum of output field allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() mask_r8 = tdomain%mask call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) @@ -668,13 +668,13 @@ subroutine mkorganic(ldomain, mapfname, datfname, ndiag, organic_o) call check_ret(nf_inq_dimlen (ncid, dimid, nlay), subname) allocate(organic_i(ns_i,nlay),stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() allocate(frac_dst(ldomain%ns),stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() if (nlay /= nlevsoi) then write(6,*)'nlay, nlevsoi= ',nlay,nlevsoi,' do not match' - call abort() + call shr_sys_abort() end if call check_ret(nf_inq_varid (ncid, 'ORGANIC', varid), subname) @@ -705,7 +705,7 @@ subroutine mkorganic(ldomain, mapfname, datfname, ndiag, organic_o) if ((organic_o(no,lev)) > 130.000001_r8) then write (6,*) 'MKORGANIC error: organic = ',organic_o(no,lev), & ' greater than 130.000001 for column, row = ',no - call abort() + call shr_sys_abort() end if enddo @@ -754,7 +754,7 @@ subroutine mksoilfmaxInit( ) if ( soil_fmax /= unset )then if ( soil_fmax < 0.0 .or. soil_fmax > 1.0 )then write(6,*)'soil_fmax is out of range = ', soil_fmax - call abort() + call shr_sys_abort() end if write(6,*) 'Replace soil fmax for all points with: ', soil_fmax end if @@ -827,9 +827,9 @@ subroutine mkfmax(ldomain, mapfname, datfname, ndiag, fmax_o) ns_i = tdomain%ns ns_o = ldomain%ns allocate(fmax_i(ns_i), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() write (6,*) 'Open soil fmax file: ', trim(datfname) call check_ret(nf_open(datfname, 0, ncid), subname) @@ -863,7 +863,7 @@ subroutine mkfmax(ldomain, mapfname, datfname, ndiag, fmax_o) if ((fmax_o(no)) > 1.000001_r8) then write (6,*) 'MKFMAX error: fmax = ',fmax_o(no), & ' greater than 1.000001 for column, row = ',no - call abort() + call shr_sys_abort() end if enddo @@ -871,7 +871,7 @@ subroutine mkfmax(ldomain, mapfname, datfname, ndiag, fmax_o) ! output grid that is land as determined by input grid allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() mask_r8 = tdomain%mask call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) @@ -896,7 +896,7 @@ subroutine mkfmax(ldomain, mapfname, datfname, ndiag, fmax_o) frac_dst(no)*re**2 if ((frac_dst(no) < 0.0) .or. (frac_dst(no) > 1.0001)) then write(6,*) "ERROR:: frac_dst out of range: ", frac_dst(no),no - call abort() + call shr_sys_abort () end if end do diff --git a/tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 b/tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 index 122cfd45d5..d355a29d84 100644 --- a/tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 @@ -66,7 +66,7 @@ subroutine dominant_soil_color(tgridmap, mask_i, soil_color_i, nsoicol, soil_col write(6,*) subname, ' ERROR: size of soil_color_i should match size of mask_i' write(6,*) 'size(mask_i), size(soil_color_i) = ', & size(mask_i), size(soil_color_i) - call abort() + call shr_sys_abort() end if ! find area of overlap for each soil color for each no @@ -122,7 +122,7 @@ subroutine dominant_soil_color(tgridmap, mask_i, soil_color_i, nsoicol, soil_col end if else write(6,*) 'MKSOILCOL error: unhandled nsoicol: ', nsoicol - call abort() + call shr_sys_abort() end if ! Error checks @@ -130,7 +130,7 @@ subroutine dominant_soil_color(tgridmap, mask_i, soil_color_i, nsoicol, soil_col if (soil_color_o(no) < 0 .or. soil_color_o(no) > nsoicol) then write (6,*) 'MKSOILCOL error: land model soil color = ', & soil_color_o(no),' is not valid for lon,lat = ',no - call abort() + call shr_sys_abort() end if end do @@ -189,7 +189,7 @@ subroutine mkrank (n, a, miss, iv, num) if (iv(1) == miss) then write (6,*) 'MKRANK error: iv(1) = missing' - call abort() + call shr_sys_abort() end if ! Find indices of the next [num]-1 largest non-zero number. diff --git a/tools/mksurfdata_esmf/src/mksurfdata b/tools/mksurfdata_esmf/src/mksurfdata index 52b7a49e8ab85ce3c0b06aed76db4ac4d11ea0d6..6f0f01104ea61685041f09aee9202a17eaf2e538 100755 GIT binary patch delta 801200 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¬ynY{qx)C8He%Pw$Yq5o0VDIqqtt?+i2|SCwxXW^2nMrKMKJB6w+? zOaom6o>PnC)}fK-Td+#ir7xesm)$9;I$N;$3!a@KDbH6FLBm(16mk`%rV8+59Cv*` zwg(!~XXDa@888%{xLD2!rM*Oap|(ukghp&XiEjwo_rt$CL~?wQG&C#WQTHcN7`GrVl z)pviK*B)8_)0iRfwl%tXqJy0v{74fGe6)Nr4dNZf_y$=VU+cK5wPXg35YKpparFp% zNcGO1EUzYl=iuqPqomoIg_FnBnGSti-*3DZ!iBL8Xfk`Zu z2721-2oLp?iqR=Q7+#uPzO0>_sa4CKb+1Kybl@}Y^Wo8R#(DQ~8J>9n{{15M6BP0b zs(-&!M2c~&hdv(v@OM>Cut!^wGqF zz;=U|Cdw%;1|J3wf9L!r&8~0xnS|ilz!$&W4ln#6D`E&kOW+ef?CyKAkP1lVrK1t{ zA16sa%`52V-yQ9VUrXBAU)NiKyRJ*TEc+-DZAvtVt&@<(D~qM7uW50%bHCYn^Zrd8 zz34!?&=>xCHwk)kVmr=q=cz&9%T&%sKR;ZOT@pv;VtAO3{%bC-7j8clbYJ=YVLlDA zfo~yy6kcj9t4)G=wi^D)RXx4S$&CGTc%+^bM}(OF0nhbzr+1q?!^rl2T_RC>Uy>B2 zK^PuBqJVt|8dqnl^9X>L~2 z{%;nR#qbZ|=_*n>MfkVy9al*J`Vsj*;rWPUR!gDwT0c(v2PgT^w-)W8R^W;}8o12w zCJjvDLCHu0$3x-fM_HK*IGzO0el91aEc(~LW7XVVtfnz38q9G5chYG5C@OhwUZ;um z3#yTPAC1yk<(>Hj9tqqPukfa1HP^=#zWuC(|7lDOc(KJuPeKhu&T1J-lQX7f4h|n*>HI0YC!)r%*P5-u$o4K73MEKg~ zy)o1uUVKhYq#;H&0-i5Q%5?KG1)ly*>LiSvo8h_E5}`0_-rbfr^!JrENzSs3rA5v) z@SBcTXqrljNj*2d4KMH|^HE%V0l#FfETbpF|AePU%UTd+d9DAp#47xoq(?XNZG?9- zzpRvO@5InxD{ylv&aRMOYM)Ag3|T3e!&khX&yL23{ApND-oErf$v4=2QM-6vW#&o zJTXP;Fhm-s!HZm;r?5Xy?f5?;VhgQ=U{iQ{+R*?om;{d@~Q zV4K8T-%oD3PLf*SaSnfKbhGsYC-BJ_h)OK*2Tm@Acj_x9->fS=xyf>u_I%(Ad*`B` z=rP7Crs?t$c>b#Lp{y33G=u-s+c&tnra1UU8?2B9C1O(f9p~8IT1u3khMQXMrcONC z-y4YI_#}8CFtCwuGu-K0r!g8#bpjWYzBi!~J6^gFK_dLy1%G4j3=o~R*LY-(|p zT1 zOCuOcgJP%AzC$I3G8umK$}XNi$P##s)*@2B+*NhFmD!@hd!fp`3QIp4wromsox9f+TMi8^dPs;{zWn>IOGY zoN6uDBqgYhGZBPu5SIlez$AEavy50B-)y<7j#%I?jV)0-9p$7IC896F)7Lx4eAkZk zZ{A06)nYko-S5T5`~q*tb8NC?7<1qT8F48lb+7XzV!2x^(g)7*7C6b7li{f$!gVh{ z*mD2=>Gs8)e1l=t#Pc~gsCb%$^gQ^L@KRnIciW6dNPdX^h1_U%XWn_S>kB?9(S$23R>?tonfH(#Ib^@~)~eem$z5-WcevKlYK z6BmhNP2T(P*d|wf=i2`%o9__h-xEVcD{@DLjWXhBLs`u9_IG3Wt#3-#A7e3VZMnOl zW!Spt^+~VHq~`Yi$LTbSJ#xA?A7&gE!+&igH8R9Yjkyk{dJi=B_6}b#yWv3!f`LyKLQiB6DofI698xCrB^dfM@Z*mzkN#SC%3prD zRTx7>1o1kO#sabZ0lsc>N3R*Des{tfv??F*{vS$&#_~lmgxoZP7km9<{<&4S1A^!Y z5>nk#4N|^SMwYXs;*N2aySIYY1d8KA^j})q&Fkr>EpCR#=f*tOYmfz&`|lhKJybsP zUZz2cuf>TS=-Zi3;E5+CLJ@NR-%PDTI@IqO`bY*IA2{0Uhd2$if=92Cd86~JGyK+f zdU*Z+iWf6JbIYL}>NlK*_`O5RvJX?{X^)h()*HND2D~sTDc=6?bgx`uj zwcM@idA|H;I(D|BpALK-a`lh>DD5XlPM0~TJDa9f;CIYZ%TIQvNCVSink**|<6t=a zz+N(EXOi9&ywGc$*9@UQ3m%#^#**f{-wMehFrT04Rbv=hnpxV?uCFg3UbIryfLUa1 zBRoD@(vrr{f8n_oWMamdvDH42^yYt-afg^6P2ppImhm+r?cIbY%@@rifv4c$3>t(l zFRzD-;al=@J2%eEnF-I$6a5@^9)N!r_>}Q-_aXwTz#16*ZEW;QG8i;9lBp@2|v8H40w`LxBktE2y*SqXW(h@QVXd`-3y!x z&-auOm&C8R7Cyh4IFLlxF9%WkmzLM|BbNJpR{T<#;hMA8XplWm9Oz!)Yq;s{YRv5V ze*f+8(0^s->prV`kw^r##w|T}7EI>G)*Y(%Z0A8u6Ye6rp&UikTlx0#4cusW_j6=& ztf^{E+2h*GRjqAJ-&_>GspF-edKS75Ub4^CS#G&IsqEk~TDKqt%iZQJHCgmS zu8}>8Md6_brBd`(?cc)f1>WrP%pCBUtRlq@7r6E&>VMi(yXDS7p1<#!g7=3{I7lu| zj$l%r2QSPY>oxP}UkXp{;}TiTI;bF$n=-Wyw*gs*JhDLI7{=a{mb-z+xscSg_YL$* zAp*#x-2mTzz4YrF>}-b@K9g}5Dv0~NKlkIae>mu|VV;y|&`1O(`(62J(FT6wvMyd< zuXsDE{$?rRD0WV_+%3=9BP6hC@oUcZyovQb-;zV^XPOXPhN0L`vKkg`u-uV$-0$$S zXoP=@dkMQXlY@^6{Mnfo;m7et{fV`FGgE|L_m0GBkzlhE{@=idZW?~!V&xw*XdLms z*ECD`T;grSv%llMmt)X~Juex}R}}M?z_Yw97{+VLa)0_cx%~8VH~P^IqrGNfFKO@; zytHVH2O8M7geT3o_as9taPR>Q(i6+?J^TVMCd=2D+F!ci+A05m1XwHM2)L;#`dZ1I z;0^C`=aHoSgSt3A6G4%W7sTKb;5*02en)S^T?!BFEMHS@fal+hdkb0Y+zx-~pI@3= z$qFCNtUJoit!I$mxK>tOeFOC^c(#g^xNgQb!_7!JZ4~N@qn)bXPf9#Y&g*<7b9Bge zk~v+R4z=6{(0=}fJNaQce6$Emcz;<;W0Xb@cqt|+4dLKSxVc^?Zv=k1<-TNkl$XqW z^z-kz0Cw2@09+11_D;!xe$mMqc&x9aIz&e|X4*t-0JkCz^T3{tV>{gR8sQscX}0gz zQaMk&C_4&!MedL0@LXEP9f!Arhqz~M3(_AWg?BRPd9sz!h+jwp(^V=YvX?Zt9v&My z&V!<0Gb=NojUC55h>I0v_*t4Qfv5Qvz8uY7gpUaPWr;80p=--eB7egRVVPm3k{D{Z z*~epqDOMWgNuja`jue4OyeZ=|6hcRMZf)Ev7De5hX1PBbRCkM}Jt%~8oW5UmrfADv z(lw1(8osJqAK&oOef*1A1}}Ay%%|wV8hD|y*ilbglwTk`D`w1ITig)k5v)4?cY8;_<$X9j+qHa`)6sH2sv0sXqGkrE{>@S@A^JAKaW~pylW5#?S7+~O5W9?9;Ab}K z>bcBsWA4$G$w$#h{So&X8mBezV&L7wPvEiV%KN?zp8HcuDop3AeB)DY|4581k_qp{ z-hmUIG`Cmm;!(7dNRFYwZGkVd>kf}UBc-mZ@L+hPM)?|Y4m{6C$)c3VbkFI9$^6i^ zL)GMbbW`6+QRt@NA$V+n6h)k7&%wh7N%B+h4^)3&>0^R<^$WabV7ps&t4nw-d#mgq z*%TBp)WizhDJR>E`HrCu@Wdvms3`n2c&e>*D8^tfRsAA%sGM8ju{CbNYQFnh%O6IN zogyQM4g_!`6Gy_gyF_h`6jE%oXz zJZzh;mis^%Zd#7V&=49F>XxrG33!;lFD6B4@4drAr<4yMBMwZCZ_jUs{kzdGp5y{( z&*c#!_@o-TQzEYOX1(RjtZMe*C?@1(Gx}yP(Jx?UpYJ3>4~J#MXVK~)csMPkXIvtz ze{(#7I1?&FgP!ozdKqh)%#DO6?v=@}^JWS>^pQAFek*)xgK2s%|YM09NRbQE}A2R2(`D|&4u{O1Kjv` zza?}kg3`}YL?IfS126J)M&7qF=1RDkRz6AQ!xOd22avPe?bxqtA(OMZyIgU{i>`rN zcYD4~)6nZO#u!2W243pZ*SCoKpT_(F|L*WUp6FjqZ=4y>-cGM0evqMNzZG$jW?kWt z8zl58rpsW}uT#F>oNu`g<>2yAPDj7^S3hrABX*DQ+NQ;cy}e+2b@BX?^lJm{Qaos* zHMbcaKSDAPCj;h38AsuKS@iXE-VnZo(~%bY;qcr{8DCMnn-0Ql+BbNYN4i#EgKi)GPFP=0^Gd!{6Mv)~PXlA))v za^MD3{_Ba_MEoUnaSbP{B zyGsfxkN(T>>@zYm;@E#jxc#Dv&jxta93}p_8rmYk)v5Gf%l*`wQa<%+{hzkZ1J0?U z`}?yXC_TGWsi8cA2$&^X*eAP^rK6Ncm$r9-rI%0y6*W<@AgDpg1#AHk>;_Q*1q}MA z_=p-&RKOBNKvX0?ik0%t%MFv=7hg+VDAG@D#3LoNuB-%g$!19`I-Uqk-oWbD62RzU+# zkU#YnJgsw0Q(5*33w#CRw4{d>KC#zbp^lAAJGaBLKDK}1&$8q4TTvl>|2ZKnG$R@+ zF6T$AXuKvS2s@GY{SEEglkWTkZlI#SSRr$y zT#K3|w(c(sp3j^OUq-%~&oddv2CgLcxV}_gp*e+wy(<`~o_np)Jq!V8#_cZh*c&*e zP144=y*Vg{`vn%y>DgQB>%q8vo80OEQ;oVW$k)D(Tv3M;>^JgI&^a$^pF)>^dKuf0 z!?fBDE)O9e9;}fWoNlr}EeVgiK5iRCMago+e};xmBlqSz4UH(S!{dHRgmyu~1uS}|JSb%2el)QJuyTBV|0n)x?6oI(du4!b|Xh(I=NMuK}IugCr_24yFT)@ z=Bf?kT763Kq9?eMx&W`Gx}6JBaGuAosYg>pf`r5G?np3sK=X`TXDd zXz*@h@T!04{xy&fXhj3_*g!p1pkuT>M1*G*W0973CHK8=={iZ)>`!hzKMI_?unFX` z^}{vyP|t1T-cIP8hq1dHT;4m0_YG^y1~##Rr%$;iW?F3{Pw+dxNy_gbpEJ0ZChu24 z!RO?ei(#lm`Jc!wy<3#ay(zfxPXxo>H@j)kHLTEx{6Cjt$8Oa`L4Z8CWP}E3$`2*? zF2^95=$}e{yc>e;J!PnDU)*6Tgs?_gRJ2-hHNDdQS(=2%pVeF*zD;yS^PAL@sCo_L zIRu9km-~VgA5&@c{3f|R&dgXqL5^kJzu<|~6_|G>-&{&A`g8uWfnsvs7>s?IhK?mq zjHEoL*8=k7MZ_p6)*_wSC{r27NT);YzU-m50!8#8V6_clS!+$3K4wGCCTsILc#K`Sp z!&6uxWX@`{-}A|>pWr~V($==Khsl1#OmTZeT8z~a3c$^h3JOf9C|G?s5?Ddk1*)TLt`L5)dw&OI3GSG&T zhekRBZMNpDtPct+Zl!3VHB^UL`mj-5jy}c6A0uyeA9g|JVLrRby?g|EhB3Kcag`DC zk5MAw`efoa^4Ob*8k3l6oMp}a4b(fi(N5fp@$hjxI+AB@#qg$RV?XlrV#H6J;ahGr zMrKmt(}$6J?qb4UP9Ay&-te-ejfQ{j%(gqo2i5AS+n!Ae-j`e*=mxo!BNm4s-$|5P zIB@mx+|+3*5>JlRvT@d^evVG4(#*W8XfNNX{57u~W`U2gJ|!XD2Ny`ysQMf&Bx#oA4c`B6g*kP#a76z@Cj5aWg(`$A#%e^)$KfZA(f<#Q94*US~n7 z2!8f(Ts|`uK1R<>);mSMgpUxO!iF!X3=i#eU5DC0a&_pJ_~)UYim?)1ARlVR%ek2@ z#3(BAu0g|sDQ*GzOS}_}Sy|TFEyiBR!4F|Q}Fo4=4JdOFvW zi!MNS@;f@ivI%)`eYx&;yRaJSOvbCd?|9rB1&9Je$y^kU`DJTd3Y2oFmu2n_he!6nVdO~JUAXP z9jB}A1|KQne8`T;L2Hbn2?zpn1o0xdub(pqy-yw;hpwAg|JcqNB6I9<7RO(KPvZ2< zDRS=&tV*VtdR5^MG0EA#w&a;RnOx|np5%S*M)Qri=8Oba=YmJ+CVi|BW(D6=^v|M0 zBIFadAqFoekC9vJFvorDz&i4VJt4n^@-LA`isE`*2r96@9(X2VxVu0Lcyhdj4O$;Z5w!PIw@XL`grMi4F{o*ILoRv zS8Z`TMv(`PSz0ctUxk=#IIkh`klzF@zojr9p&4Vr1FR4q2)`J z-UGD;v&!!^yb1MlJPwn$ou~pqj`R@5zNiLIq@NtG6(t(MqFUs^`j`^tENnCKnCtSb z4&)oBBE+wxhq{uleIJqhyD~^c+9Vc)T!+3l8-6uBk*N-Y?jpZ$A3U*)J$sn^P#=W2 z58`46`K~eyaeuA{|B*abM;iCC#?=Q{LAd77Z;I>uTdg{L6|IDrGqbe?x%a7&x^XW} zC?QY2iC8qe2f1g>BrTbuX(7qgtn}~(n4B9TtmXAd!$_2MTU`b}*Q$cX){u+sWXN1go~jknMwyN0-Q;2!wh$>sz*=zmRG}%(T<{z#1dlt9h2M}| z9kmG8QOj49@ADQ;CS1$V`&G%yaf!NaOj^ArI{e?1+Uv-m##|Jl6AQczux@zSvtHz} zugTd1i+s{8IF>wF3!`x>xrpGH(Rkt!@-KL>Fja}G0bi;gNSn3IZaGS>r~4@uKW!-i zk~w_#2m zX2WHykam5xI*&Zu8zXM^Zucs#r`}_f@GQf2K1mZ^A>VW}ro;TYXlft1&!(p-f6VAv zG|pkNkYCYKvD<4Avdh1CH17fLCc@8R4tv;@OIRWL6c#>{3yR1WjVRTUv`6%{%g4we z8OvhdI=0WqxQRU22O(_o`Eqj4FTo@< zTbZL&6fMGnVJ4N3pG_%;WcnkgdDuWL@*nwqsC@e4Qpt5b@nW6c!;S?hZ~dk^Cg(_y zF+Yq2;oqFId75e9b;ORjW_=lXG6TY%8U7yGb>)e5pCUA-uxG6l*TLC?5+wpnUBfPpkzD!2x*R^yYoD}W zD&?)~oP&J}x#w0S5-;_vBF{|6^oY@dC$)ZgPtA6&TQzTIg^?T3mHRk&?~|u%BcGVO zbeuf&DGW+c{w(=tPeIRP+LQ9S#ca4_<~vM$6If6n3p_GYx=&hlV+HRiG+=^YIJsDa z)0;`^nMI!5fWeM;K*1vN(F@?|@e1e3-<2$=?z+bFY4Q;7F5p!a+CAFNt&?f5Vz#*O`Wtya$qo6JMb*}s16-zENtvo$36RB2k zsE4ycx(@Re4VpT3Ao=s;t>5FwVUh{)U!$lODj?E? z_?A3=0x{{Kp=Zcb&tOEuY@lvkcp|j`dBdWII*}*-c`0odSy;@1E0W!`=r7E015JgG z%Qd&iCo8U}-2zH@o}mOyTT1S;km_PIVH5dZ{3icI^0&z|pJB%tYKek0`G>c`G8`(& z%dG3^F3Jm57bA6LI7rP=Akrn6Ugj_|pWHXZ$p;$whv6&Z^V#Gzk09gJWhT0f+^VkD z;nwn(PPa`#00xC=&@=kU5V%PcEx;HAAfp3EX5sx4pgqeqm$m?8-xj3RGG>sw;d*BqahAtov?YFdG z6yoAma$iH`l(zD~jSa+D5M2y|QmpW_;wm8WcNmpVAS0O={@B#q4j!VPGp1%Fs|iN# z!=G^Q`vASxfIPFbh~p5OUu^7;5y7BljM)q#n8Cc%e>AVL@}(U9Y3$yJx@? zgV}?1Mo|wmkfxqj40m0xlp?owmupGAq^Tw6J5`{Q%UOzu9K?({T4>Y^KJj%#Q!x%k z0eR?d@C;2DM1BRIr?I3p3g#L;+p#V2(T7XHbA)e*b1*j8U(EJ&JM3vT)X@QN@PBOM2ariLmvOk+2t?D6MS@rk1ZV`PY*?( z!sI`YZ~71`%?;!=Tj(D465h$^Vw_{z5(V-!0J@lDg#fu{J!618B)M02rHm44Ph#6N`B)~=a!*_Jha^@KU{O1u?olpXmpmOyhwo=q;Ub)K(!n*5?-ICdOu z+(Yj9+S0`2h7ZXtKFBLd`4iwWXFP&1K{X+&*|~G%?PnUdLf?{Kq7OkvQLZk|>ZkwY z4yDxPzFu1Ir}V&7@=PxbbBJLP(bXdNu{iN~xvu8bukst`uE!dy{{^ z9&7*CY9Ww6qsWIp3V%fCwON`&Mt;q=ai!{!+bAj?hKmw((Q5Ku<9llP=bNM26Xd== zh~^Zvy-uDPgFrFU{WJ1-Q*_Cq{CD8;#OB>dnZ^g_OoeNl`J{0hL_*g97SPTd<6`o# z>m$3XC0BzL)VHRPt#Y1DF!I}!@23f2PRZQFg7i8>Ly(p}N*)bkVT#k4JIEJyfs+e) z>iHw`(5r}OL63f_ziN_o(q1=DZjKxM3*9;Bfq!SSwGQMT>iaJU(V4slxrg^xoJc;3 zT#UfZE6q@vLB8;#QZ4x_k0fpZmtWtgi5q+&It_Y=JduDwVe-x7)&ge--X=dgp;T&?W4N6Sq*xG}k4YOMKW@)n zAdd%s(SIUY?a=>lL+4RKBl66vFe5}WI*|*DkwMel!*GaC@UD)-d(lvJW4RRJe$!cP?^SFPf zt|qVdu$;$3pBVXG=%0tK{Kd%UIpyoNNB&?ug=3Qh9btFDS_?isAmps)AsVv38JW5{WVQjcM zGkVXGr&mKh#2n|j44qBa!Tum!4Ha5}%iBB8h4Bli$j=Iil%50=Y+)Akq16T>UCe44dhAwO_eH%%5^jDmL* zSN_d9g$L4pNx_BFkxS~-riKo1%3|KI$j9Zd7J2(=Xz)!2czg2DRL%$nMsM;Uk28W) zUk)A-HF*hs2Nq0Xg(_U>=9Aw{p1uhUnDu5gxi4O>CB2k?mOQ=-Yipt*3U-p$Ii?mA zd8q#?cM=~MMYmxG6J*bhkcW8wJ<0}tCl7vwh7;72-4UJ>e2i(D@@>g;Z$vb8^vD9) zzQ|)iB1e6mAn%i=UxgS(p4os&8>367kcYp4e30@tl6TKR+|OnQ9wPtz2GwKvNP%{! zuvKz>36A$}=l=9P)4*ypY~uS{#Z~Y$J4K1;L}x0m)`=34rs|#g;JVs4-CB&^DI)hg zheg9fBl{cqrARDhl8+;gHb?3(XFnE7uJ?lt9?<&Deq|}-<);?=U|Nb^TTexyML13A z>jE!qArDu=u!osN_L8S-z)-WHJxm_#iwWa{8gZID`L^OUgfI{EYi)lOktw^&<#0%< zKSnLgj`t<^l)~9*>KiAyK04tItmr>+1Lc!HPdY{xn~i~O0XYuz#E9rAUH~};BHl*qOxKQt7cw>2|fw9qvX*e zP9JU~@5hHSa(6D?BwzR+gpY?aiRL&CJk$XxJl_vgYX|7es7k!@KdWlqaNpg~#VOvKPv1j1DC~NJI zTwT!QzM|xH%4d!`v(W+a`18&z@gulQ&rdiDF33Y)6OEjK+K{{>AF~Ko%S*J$)AbNv zQ4aIflBpLag zDSsm`nLzi17(*V@XKw;R4k><&?U6H>}vHN|<;~6F^HZz($89;yPzMM2W-+_|l}Oo#ft=&ZXi5@_2uo;uAFO3vy3K zr=Fk4V}~oWt+DDb`A_g1kr<76VLq{{XRli7E1rM11%^{CXLO+6XW21f+fy+NJQ?@I^^S0T=!R9M}GR3wc0wfuOYY&5EJo$GsDg&PyO@yH>o;C zo-W3WxQ>VD8_7d)xG+gGUL#LNv5bWoZ6AP-6{W5l{eI30)-)(GQF6|38(|w~19buz z(|8?rlMS>{T#r$EN_ZPOH3p4Dm21qqNSLzAYGO8FRAuavzqZYp4jv?rUO!IT<6%U- zNS>ZcchIVoE}SbUB1yRx%~mDgpSpN2$<;3KRbFfxq-DdvBVy|gY&#CK;09I@J<%1Nsbtyx zi&<*kj7H&1+d-To;i7u)?T_HJVT=#U?%E?NiYB23P!+!g&uyx^QI z&B;Yu^e@dtvLpGS?xosu*HV9xGUn?F3(2Ez zp<$EOSCD(I!;<3F%?q)CJodEO$NgimO|T$18z(bTRZ!z?avyIa6{Vsyd32(4L-+&v zCvPHz&9@Bd1>w1Wm17`URYUutfCX`0o?x+otI1Ei)JKzjjP0r9!QXhopK0JGa!*$z zxD-Qg6?r0nN$aEh(~{#(F#F4N0|~l%2P=dgM4mQ0MV`43A!$+3k4AoqGq$rz(PQDd z??FBCUd?+-|I43=`c>YVUlyp8n|TT;*Bs~sjUqngB1!oX?QK#qvcw4lpfkk9{w1fFsc4C@*qFKL-RtMQ(SMl zJ>Ag7Xt8ru@k_2UV)$$4F=QX|)KTPzI5*KF$$hT-W6vY^Jdd$3gS{AB`uh~RXf{-j zvchgY!tGdXIPpK^m0Y(L{*pYs6~PgvOMaJJZNP$gv$O*9jg+e0(J^0pB`@2L)3=RT z;9bJq02N(M9{L5t>48H;G5J(}JqV{fg&0k4&Ba9bzN zr7YjVC$TPK`y0p;4o_Y}t$Ggx$ZFRk@)}95L#RqC^DdIF-pQtadH}0gF)S5B$*nfnfTbFs zU^aP*AF-v_=3?>_y|Jy|&eXStJlYdOVRCB%TyB9X;Q%DaF?~Z8=sgq9oOx-`msBL) zWy)e|%8A>nV|P-6Ux#d1eT_X3>^7d8{##mxsA!J9&uT`i#@E_as-&Ou9}QR@a|H z;F`B%tQ)kQjygl``wG+6M~64<4W0E|C#>2_uDlakj43%amE#arDp!46A^0g|insOkE4 z@_5QyKRGvzGs$D`T3U~f`ft^o{|Nip2jq#$=P5h?ETZs1cJ`prF&o>e7=8C6dCGO0 zh>QBd3IF-rx!t;q+!sI&^f3pPf{zv9HS{tY7|sflUV@^-wD%_Ri=*8&xuY2h?jslV zoZjE4xLWJ0JY(KP-l1&pNi4qRkntOG&!f&@{);?hV}IeLjSa6vXFW%pi}>Z_q40QZ z9O6noI32u`i0_A@6gxGX6<&D)oi(T7Z%|wtf7|(Y_nLPV53*KfEarx3<|T4*3h{7$ zIUx7mht>rH^lS3qZge}u?){;-ZoSG?d{=R?dMD>;Y9p5p_Mjtq_#4<_;-nvWFwXd) z{AhCTey8iMRb01u_xX2g%)7`YQ){r(u`iRS6KLJ+wLc=iaXD7xs%-sh@*7-VPydzN zQ{o(-I{kF7BO>^$b3fP`1tNJdy60sBe)7$JOzp1ZLGlY+UlScdp11}3s4#~hOrHCS z>VRC~ZlI#OSs>~T4Gxo>G<8#1$Z1^vu|9^<8SY@;?a{40x zJdZf%Ydi923k;~qipAtpc={xl23!xl}$jmwYO(6E2|qBFX#e$os(3$V|eb zAu2026A!v}Xv?YSj%*y@?O?QTRa`|_vv(=sYlYE{vhUv-iO6Y66Q;G7|^!~2(40UtmfU4i&aP|r+qaR+B4`CZ^SBEAhgW_X@q%WIuQMc4~1PO9E-r)i}Yb^>=JBv z04r4SqvPh{p|IWZQEBhpEDrT7)ef0XzpNpD{#^vY=iK`|MxK1xnUP*3U;hT?bD@e# z`STum7v5870jPnk7M0k7B ze{{z|R`BgC*BX56?a$<1UQ`!_eo=c6oG|nE-kSVX4F#>qGrXS0qI`fnG+wQZa-j&< zLCMuD5K}R3aaIVEzt3D}R*4nl@iRQjzz#fVXK#|TX&Z~9yxnS;>Ru%e^LrzPA0*$N zi& z6ZatH?;`g;j%goezgLq7eJYaVD(GW{=S_t>dF07_u*dL+u-go?;cv-fBPz6pH1+&Q z?z@foj=Y*&Thui0wM6LYc4hmb84E&%OsH(2fP8(8?pno5>_K<(#7WFV4-Fkb9-PQf zrJgYP>>%>#(5kTLe#!MoLf;$C%(#gaL@!Q~MyT)_dFD>^*aIx~lZVGbPmG3scb>x& zNy=9n3Qr{O8ghw7K34FuAbr9)#(DPUC*+4^J@99Q{u7x>;Ub>oxq{knA-7!5j9x+R zz0NtlPmzZj;D|0kJ-f-{w_tagrkmdd&k>&M(Jf>BahNBsRF%d?stiLXtp<>?I2vup zldiAQ=aWa3afFAL20g2| z+QUS)$#*J&r(GZEe9oG8eTcKwMq{Pn=;B@*YZv26)F5B#dMf(G8glRA3d;#Ja`LS znV~DcmR!5OgVXirDE~)Cf>v(NSoIY$#?t9JBJg8rVC?XF(%uOkM*iUlh^F}wr=VlWz zQOmQkuxCCi&okUi9m`#vT~8hiVMa%(`z7*lZ?tJ9?rY@f`xqCTF^3F4j=rYZd`5Hm zWzlElmqn|NM8^|M>uEODggm(l^EtyYzl{7>*Vjja9O)_G-Gt|( zaoVnQb(pu%RA`Ci!EEt0?k3FN{58p!P(Pta-@D$9ACTu<76J11?D^6AgfKeG}3Ld(mf#}ktrCUFw-^00|dsx7bE=o|* z&*Z-DFvw)-nq%RilzwiQ5JAefCQmMN8X6?GE_SX?!z9=Hs#GULw1+*O#tOdbXgF>> zLEfhjQyh*JVl{bmBxY=w25liv&By*s6r$iQ^7tw~?$P9;&rQL1eH)A?5PM=F3zB^?mS&PJCin7tKr#00K5{W@ zs3!3iD0tY;eL?1e1dB7BF%o70f88|mg>$R+DY<8vGqL}VJT)E7gcwQ}TIhHDY0Qx* z&1wuTw|p;QBuuWo)V}3KxiRgd|3t>Hy7xy^H&;bYlw5s&8ZViJUQz80lyCMP+<6_% zcz`_oK2sitWea)eMs&xRy$3uZ4*i1DQ*Uu8_<=J zl(T{rL<1fg6efRcuQQ@!dvE((lvp}a|6?8- zc^hIq&(NR>Dtg&f&_W!PdFqFiv4gtR)w`A%h8oC&|<8v0FB`*?C2By_;*VB2fNtTtB6}?;0#DLGtgx z<&EbOaEMtV&Zz=@=#(=NArT58b}g+}h&JTuKg%^qF_#sSdzYdsW`u{6`&}Q)%p|Y< zJVLIR`j>!5gw+INE0eSSS;q>Q5XQZt;`=S;4`@R~vD$O_*2*ok- zG{LT{Cf|Mt8Se#^vjKyf{ahbggkCo;`p+EQ&YIve6y z8!ve?@gOO?B=!7AGb+ol`+C)e4%=?f} zl9x!X)65WOni&Ck`5m|tBnuNZbEwGM*BKsnlBalw!vq`HL_Wpi^xiIV5pwGJh&-$x z04Y~Kvx7>rAaOUsW(J4(FUfTe1~_|AcN#tP2oh_I2DK*lEW&*7av-{pNBK?5u##6R z?^P@q?Yd#+X!4MSDX%L?`32;`I}l$c8{J7BzLD~5_)+ro8{6+F(7i0f% zOC8icV6$3xuDYc-^rt|P(QuXV1|mHY?;@1kP@V#%VmMu_(U5cADBeg zhkWJx&aK`wa;tX_t>LnoP&AJ`eyej>?kD%;DuZOCMHvuJ%K{bA*YO@5?0`tJLV5_- z49XuMPwl|4^kvV!Blmuf^*dS@234Jjj#(q9N5z$Dq`Cdm>+%FoG0PJtQ68kep}IJ? zOcl$;Gy2#h=%X16CD#+NlXD_IsH^pTnp(X#!Wy$ezDXYE^5KJ0@d;*^`92iB7ZpF;wX z|LULZM*cWDWG4Ipa=}9bFPr(2-0PA*3oh>*>*`0{+30t)zcW|2mRxz*!w=BS4DnMw zHl#u~Y5MnXa_@R%Qj?MgXg%^aJR?=es$|a|Pi2MqyzSR)_TW15;3G~&_i07)+JS5g zxiM%x<@@yMrZwC|JzI>PDgVd`s{Qv^kUWfRmu7{pO@+sCq9?;4_?{N;a~Z8G?OAQA@;jqKd92z9RQsg<$lMpCuP# zooS%aTzF{g(o(J9deH)kI03vndI>tv~Ttmi^zj( zosNBw+?oc5#OaXdjr{%K3G&y#BjVQ8NE4Gd5=U7fy#gH!u|m~(=wRw6^uuf)8k0x6 zLOz9Vi$Zd5z`5fKk>7oTYPYQr#~IzzS&+N}ijq{cNO7H-@1w-3mN40u1Cgi6t&Ir( z41?_rqj7_??_ZGjFT+@wSooPdUW=c1(SoYi>L`zhJ)Do`vyB{Cpx5+!oKe`0e30w2 zsehBFT)F=m^6ZQH=q4|zhL-1$hySaBQ~JvE>@F6Bb|X5>>bG8T<*R1fDIq?BPfXZ- za$e#GO2n_SbZce`oi!5qwdbRI!A8(wj$bb!w@#Mpnn})$u8QlC>P?9ZFUj|4IU$CU zZ=8-*_)f0EbI7CPG4>|Y-b=or6=rQ$>RC^o*p9=W41@Gl@CL%S4306~{z?^S(@wE! zbQ(5vCZkkefX=4cJ2Ox#^5hC@ftX+$ZXv1>o{R9oOA|SF%F9 zoEd=8`yBa{N(hR_>E%6=tDO5SuP!jbc!=`Rvq-HeHvFTJ*B{K)Ie)w>epMB;PpZl@ z<|>Ypd=N~6Ce$Z?tTxw8%tJdHD~3M~4DJnFg-^f&St@9>;t2kPGlm&7Jv%9+&B zRC5X;GCNW{sa;&AM*MQVI;TJvx2;{=ZtdbWwTs)-E^bq0ws5vm1XCk_ zPrV|ytwkFwXn=z z-HqJy-C&Z*%XRl7*X8oOT$ju9a^0rpx=qb>o0{u3H8xx=kvBA$>eo*o7&lJ zYG=2po!zE(Hl~^+lh@g8YiGBuo!zE(cAM&Vo9cI)>UWzO@w;vHyKVIwTbX3?{BBeI zZd3hkQ~hpJ&0=;w$>im^ZOwDrn&&n(&uwa++tfU_sd+9_BYAmlTl3tux>vJ2_iC2s zUd{5{t65&Y+f*)QeLqsF$tkWn)&c$6le{-KIq5%6D?dQ<_!W(he$mxq4}?glfunEB`9a zS^2&Edrg9>EQp8s8?ocB0)w>GyGDN*}moHge?Ci60PgYxjGiL&I?H|v`cb}`5z3Sx^ z_44Eysb{r%cjpDRlC*q+h6)ch$=d_43qd zsb`IPcb5{mPQ9C?UWTccp7KT7)4Y;&be@uIC57Z(_NTvOZ@X5K{yzDato7wzvgqBv zWQ85-->22P2h_{m>g9U%GFiQZRE=TkT~8&Kuimv$FLmWhR-ygXpVHJX|CHdpKV|tY z_3jz@B6r1CS1R_}4=8ZAdbwVf=eQI#N>A`O@8;%gCWO10GmxdjE#u1agRnK*0CjPiNeZFYufWAWpYnFYU^&2>#x3)%U@tnufujgsbdHQ$X zm2^`F?>n$Z&%xc{bzf({Zl>OOiGOxM)y%Vwin8)~^X8VdQHH@T2R?6s$AQ(T zC>?bjbXaM>p*`6{Xsm5cM_;x_hz;wE;- z3yP~(Dk!qcE+}q{e+qs7{3loaqhFfk^e-KJl{Qg(s3$_D_|H z>(%_HN9?X6N*Zr18&Q1vMqPN38S1Sg_ZP3o-dg!s@!?jEY7?f+m|JGoo?O)ArRpW& z(AHTaOV(G;%Gfz$OD?ar5oa2I*=S!mwxqD>CZ2fQ)K;IjYP9=8bN)&Q`<88ab?wC1 z5>HN}$vE%ZX!7N{{P!$--`J8)*`BH3o~htV?d-CW%X8v8f#W-YM|8Ibm6dd=5zNAc z4MDl8E-5R?cYt>k2vH&=C2Cj_j35{x!BrA8vk0uLd~J%w(}emTWpcg7@*Jo-dCoJN zB3ToyCTr%~?^q=T)$8DYtB!1=T>kID|H31ikpE{lrhMaktu(sEzQ4SrQ%;bdJ_KI? z_l>jnN%6|^f4j!Gl9I}nd=stQsh(XnuH;gW^&-SZH-RCm26SpOV?+<7G*`9Yq>hkNu-0EK9QImH%5KImRfmcQ?&zXeVS@mU1LH?NrTX&0Q3ZLR`gQ&->w?=*a;==J&8>vx@@RCJE?wP@r05_)vC0? N$52b{55||Y_CUJm;ME zyyrddd+xpG-rVWPd}rsM|H^Kt?B-oQ>&^*(3i-NEv+!|J%knU`>H9GH3ztiIxcn~W zoz(XbL#wtoYT@JI?-Ke3lNu)NQp2R3lO|DtJ|>NyW6$s3MIZ6M+G9sqmrs()mtWN> zy>W@a8{=Qt=Zx;6H5Z5bNUd<6_?nXC15SQ)-MMoXetPAquUj7MasRB34*&BhUp$;H z@ej7ojNdtIko|3ZlxI-fKdi$3LwxnH$+pGp-zh&Ro+9@7_%$O2#q-1b_OkdCsvnOp z8a~LrJbv$(L3ZEx&6NL?YqSh+u)}C&_m8h0J;?4s>|}dX{N53R>~rFMM-7UnM^xD3 zx!sF#d*nQOFiV=wGQKBfkbNb8|22N|6KlQ%J;WPE`|X~r?XfKNCLYOI@li)Z9%Q`Dy+6idzLl*upP4cI zeGW;SZ2uqCA7tOf-#_N@*0E)4$5hz=ir+b5ke%Z`rlWm4O>CI!E{NM>C)+jgDfB&o zb<4)5RFYO>D-xMgPwpPSZo~ll05@F^vGF_&KgCM?8WU>2hwApJ@kQe%Cz5|0-#z}v zF$3&J9Di`!Jo{eEn!S(5HWTwh^EmsM$@VevYmOOYFXlN-9#di82201&lzW0T zJBh8>!d*wXlfBIBWZ6^MO5@{qR{qSM!{gn-N?paH4jfxycksN7V2`LCRbl^w%Xjkk zOU7F8nR1qTfTcFEy?gM$-e$drvrVpy-#dP?eOCOH@vH2E-1a^GzMDs7@oav;R$k9~ zZHYfa7Jr9J`?1VfWQ&UUsEPB))8NtfupS#(^J(!1Cr-A9aqZ7o?m6*ARTbosgY2{ky zeK2IkJ(DYFjMQs9K)Fh;_Z3_50?uE>J+I~O&GGjq&$F*({lDiv@8EHbk6+_O93rZd z-U@pM*FJ}(P;`tLv|&nx{SX^zNPNna$rMVMgmd8x@dhdju*h{R@}l@PC&5L&pn3~f z{6wCVM10ZI$#yn=^VE5EkUKa${ys6w(5>Cf5`V!puZGFuwZ~W3*%qHNZIvBi>n8YnA6tDE$M>%I7t?-i_hEal;W-}8GZSKg6Z!iAR-%Ku zU&Y1HYyU?T(2Jt z5D(9+Ahob~|A2wS+h=<1T6WZAyzj}A?Vs>G|B2Q85$D&i5ouYX*&2*t#?vQPgy!_K ztbSG>EC1_@_@Lv(;gddnx(Q!ZJ)7}M{B2nc-GzVU)49xedq}~feT5HJtY*R^v~`@3 z)3j3LTu~|oZFH#ZYmEq5*0XY$tuPHv8YzN&FI>n>#_;zK7Cz|dv0mCX1^L3});q<%vQ22A}2!P4h&({ammv4n?N%W5Uf&_V4l&SxfI3g!4M4iO3XIrLhEAm_I$u)UQt+p?&Ecv)K3rPN zK2rG9y~~*hUN8K0#uBM5GG$H&ACH#$$w?P;#g;)*e`lHSzGF`pO|KE&>P;2UvCk(R z)KZ7|+)97olYt$0=`;1uGlp%rUgW2HOTj?ndYOgndLb)774f-wpv<(V|3=2nOfNJY z`-(a~{Ad|>+V1R17a2Lpex2p~($x37C7q+Fvab^mV+oeIq z2>KIQ3LS@+be^*7jfDb57TS*vsD8l2NYKcM8b18#3XUt>IQ`{9W;1%o!WHhXg@$ z`>VO!^h44ZpTouoU*7W)#%a@GcOy9S%7x4~@V8|hZ!B4EEa~t`<0Bd4BPFK(6Cx*M z)fP15qVvph(=bd%8a55SrUe3X?k!rL-Zyie86ov$n3nYyv(Dugnf20K&HTz(*t!L) z0XgOC~jzga5$q^3Dcd{0h^&!6ZI^@EmlTfiE`W)S3^7zAZm)FD10kMKj@7E`ww+l9@D!`p;+OnsA?g78LBC@_@8 zSiMOx$hW?g=*p1K;PbV|vPPny>VOCuViw+iI41qu#qlTRjtyP!908g{u(R%cMMBU% ze1Zs083j8i#Z*-nP1WJX^xkS&h_@dLH7sj{S#L92OPs0Ur==5^P$HmWa8ghNA?+C@Ek9S292T@8;e;li~KYxg3ohiz+Uc``VTWrzGC9p zH$KQrz-aolu~@C?*im$hM-(bA8bHeM$+TEL&C)DucsHrP^vAQAc^UF&(ckB0#LxV7 zE*GpdQ?=G8)N)#o`6Pc^)lj*x;M&)EBWLdYHg4&ruX#mU8=f+VYDE*vtP%E@` z7M1sG_16p|IUzE2jWM-Ta1OP@2+B>g zdQHd2Ii^lYFocb-mKsY0pBF_lrv98UW&oyZK{7Uy(^M((5Li&NZ$v z^>#S}{ZWvau;CvtQ{G~n{4&EgP)tG2ZEwPMmbI@`3a&SLGzUeG2{b@_wtKjK$nu#f zEN9xXhMMIgxO5paKEuCkrZ#_}M3K)-?RM%29e)^?j;ERWA(}DpHy+b@U@c}~so6oQ zNzUyt&ivJAY2Yie8v2e!tl;g8U87EJfgE>v89Kwb> zzEIS0lW|(FF*WqX=XPVEz?~N{c6{v)IzhzLrhChYonz6HXn?SUwK&N2y~c9KQ@@9y zAUGnv^~}kkB3Ints8zHqe=$PDh1)M=aT)%$tSgPd3?uop)OYwl82hD+ zoiJhi`7Ol)#?e$N<8Tc4fSHKeq2d8yaz%Wu@Q6a0Z=?ff+^?CLZa6oHYF3!Psjjma znA1V8@FD94I_AS3VYB`POoJcHh-=Mhn=^v68A0BRz!|{r%>;StWr9-Xc=H<*!!5^1 z45y8zlh`vtBP?IhHARgHHjlZ;Nl}OR%r{fx>)zP|E-}IU_fO|?y)pbvtBpqn=H=^U zT9pj{fZ_AtDHJSc#C67W!5LDu+{DO3W@KS=-q~UVjWZ^#-Eko^dE;Wg>LwizyKXk~ zXPf%7%~S^7l9+;g^lzPRf-wAs2x>8cx={+B2owd|wPw9sFhJJJ6_wJ1hZ1(}FP1Uk z71|m}9f9|q9%LqL_|>DSe-tGDEgk#Jh--{OM~*C#^V*Wt)Ln zKMawM^TTCeZpYna0Q1ad&mwA%Pv{Y+LfX+%XyDwZ8DnH7ll(_8X2Y__!|>`M$pq{ z%JM~S9uzucTArHn#BBPYZAZDjwvDd;yw8d#4?2WjIJOU(#^Z_A`OhoYN}puiJi zIWho$qSOwGW(JuB$E+V`dxTF9znJUsLWKFp!5Iy_A4}LcmiVMp_@VdA;Reo(zBWqu zV221gYyuZsC!4q*bm?p+9x`kA-;9Ndcaxr=flcR*mn`Q78FT6WsF{L_yQJeLk#FrF zllLRP-gnf)8y63=ne4s_QPgV%5c~ ze{$WbD=)h8%B!z`_{7!O?hhY-@fC+1aq+4vF1(5=th#>n6%YUZiZjaXzs5hh@oKs? zbM8$e?HA)ez3J}INI5aY3LZ6~4;5+@f1;Uw@U@EnkE&m%_$I}N6NCB@0#uwlS3KZy(IV&mnQdd*Ua!&Zb zf1^5fP7lEMR`s1-bMP0b`pyX@_|Vs?z*(wMFkT6AHl4xOs`}1u5BNVS-dPyIAFt%l zH32a);7_DJ#!u%9s^A4B$hjLxStN@Y5bTkbNu7NjA}q<0PZKNcsd@spS;&kc9&Pkfmwpeq9RQ?B@tE=x))-lKSr;zudIQt_h=&;5H#6(n&K-IKUeV{#hVv7_3IQLP<)tp_CJK*B2}?xq~gz2d~<;hS?8&OmO_E`BgMBWzFP4q#mfbS6t*i~&i92+EB?n!nfU8a1#&4P z4Kj*fAryaS6))FxQkYl#Dph~K;)9B}LPr-42CG#;nc~+dzFhGaD854R7b@PP_=^-@ zY4{N4UaqaA)T5C6jy{7eIRlEr#F3l@Gtm^Mq{LR9fW@8Fb zaEoeCrucP=FIW7nimy=oZHo6O{+Eic9HY+v*Q)}rYEZBED#hQfc%R~{9g>u{a31j zX4Sx}`2SOUmEt!k-lzD#D&DX7zbQU2R-OO&ips4f>za_Me&a-zE$yC6rWQ3 z6N+zF{67^RN~?k=RY8a1pHh5A@lPv0tN4`S^NN2)@%x3B^Z%`?z#3PGf@c+9ruc1& zFIW6?imy<7o8mo+-|pI{A-GDQvBW;n~HB${9B4oDgGVBw=4c#=1u&iRl$3zL5Jf1tN4uKGm6hD{(Z&g z6~9yQ`$MYW165!hQ;32O6UD|q4-Y}?=d`||7TS}rD~8?HJ3PkUM->E|0^;$|g7c|Xd|$-} z72i+sHHz=A_*%seAYSZGz0|3KfvQ1R@kc3sz2XNczCrO7if>Z<-~u1AlB!@xp}=ZZ z{7}WWD1MmYTNOWC@hQcRP<%V{G=7919@}s}Y1P1^_zuO7QhY}7qZOZ3{LzZfD}GE! z73^09V-;^5TZn>jiZ4_AF^Vr&e5K+m6o0JYdHy}BV7zKjsrU(s_bPs(;;R%tN%20# zPgcDDSatsIRRsanV2a|a6@R?qgNmP~_!`BZp!iysr}0l$1$AzLWu2(_u;Qx}zh3cp z49@v9D1L_Gn-qUCcqjgns$iCC(5(1V6yKuwQx)H;c%R}^il43cP`fIaqYBcBKTYu+ zipO)l&L^Yz(-ogp{27YR3oqyY^Hjlp)xfWKYkVOJ<}1ET@e34RuJ|(*U!nMgwqt)9 zhDR0P0b}P=sra)M?^XOcimy_9K=D4sFLHSF?^gwjodV(mieIAmYQ-;Ad{FV{D!xYX z=PACHcpg7iz#plCI@O?B@nOX;Q~Y|xFIRkn;(x68rULJ?&Q}G=LV>kH@y&`~srVN9 zoy_6)4iBweV)-Mf>q@g13?y@|+g4^S91otbm5L6I-A3PiM*1iRT!Wd-We(D3>=s~1 z%%vGW1Y81~V!R2s8*mHb`+&OxCmC-94wZsvU}6J^!+^t#ZwH2fbG3|b0WJd$GQI)0 zCvbrAwZOfAeT**yJ{;J~cn$Coz#hiS35RNWgD7WWF)ADhY%yK{+y^-S0}*5A0G9)2 z7|#Ii3!G*=6}TU8it%{h{=hAaM*|N4PBI>{c1g&pA-j_WnCOQJM*)W!_W~XST+6rw zxB@uH_`pqs2LlHf?*$$L>|?wOcqp)!@lN1jz#hhL-4r5XIEZp4cA&xtV2kk!z$1b4 z-@^i1fjz((##?|#0jC*11Uwoz#ds6&(ZDT??*kqKoMgN)1Y#_R1|~KDj{^=fz8&}& z;9ADF09OJB8Q%bWEO3DFwZP+neT**yo&fA+yasq8u!nJIIf&yxlrymycoMM1cmeQa z;QV*&1HfM34C5KVQ-ITqrvgs}PB9)2d^~Uq|?wOcqXuy@lN2Afjxvn2gkkzVit&UuCN36 z6kv<-3&5uW=f7ni0QLcA7;gcd4V-5D5bzw}6yr_6rvbMxz7KdVaPr%OA#$pXAWjF- zz!f$Cp8*_Zd^_+w;9ADF0Q-T1jBfy*4;)~8E${+hALGk_&jj`|UIV-k*z+y*e{k$_ z5NClX=L(B~&jz*_F91FVIDY{3=Ku$QGmK{dF9J?8o(jAeIK_B8@Dkt_#-o9k0w+UE z3;}U2hz7>}fX@RCGwucaBj8%bCBW6dLB}9+Y_BYcn9!GV2kk!z^j1s|APg#0tbOJjJE)<22L}62zU)}it#4k3xHb~-v@jl z;ZQEg#6}Pop+W=W4Zs%zhZ)}vd~ z;Cq47j2{BN4>-km6Y%}OEsXCAf%qecBoiBf{{-B?cmwdCfy0b%2mT9iE#q5&n}LIj zZvg&3-~i)mfj0sB7+(hbS70yW&>9eb1L0v}Iq=_s%NZ{QegN2Fya4zg!1;ab1Hdi7 z8OAe!9|TS_o(lXBaEkGG;D>=*fJ0+PgLni)k}C`W-VEHpxF7JNz+uL{fFA>{Wn2Q> z3LIp7ppNk4zyZd4fwutr81Djp0@zD9ba3oW5dQ?>;Ri^)_H6UIB;o%C)f&T?u&Ui8K zzkw~r3xHn+&hJJ0IlyV)4C5KVuK=eRPX*oqoMJp4_&>lcAtpwHcojsF@ettGfEyV1 z1AZMi%(xfu8^E=UOMp9ogNzUSjPRSl0mgfQ-vahA-Ua+NaLCKVP7v>a@GyQ0_+8*~ z#yf!D1GX5y0Q_Iz{1>pmR^SY9hVd5Q_kq)l9|GP9oMOBQ_yfYBTniKTf%p&=l8iS3 ze+1mXcmwdqz+uL>1AhWs%lH=HEO3zV4Zu0z0OM6B_ID=m>3OWA1Wjn z4*~uPxPfs$;IDzhjC%op16<3v1b9Diknw@*3I7i`z<4k40bn2FUBKV+@!ZSAP7vRr zf`{>2z~2LxGu{FG1F*&T1>l3g`On!0fN}35mtnjG823DKX~qu$<6cKD#ds5N2sb%$ zElk`80yj5uNyZz2aZe-Hz<2{N?q%e{jBf|VJ&ar}<6D4n?;;mud;>7ytYuLZ`f ziky$}WrRaDxJQxmGO-2~aBm{#VZ0m|_at)Vj28prUPR7fyZ{)tAaeQ7*av`d>miq6 zJOdcF9CB&KQ-N`-A(vu2{(2n$agQO_!o+A)z`ccBlJO8=+)~IjFzyG8TM4-^<6gkH zg^;UdTmp<+2e}~Q13x8Y&cpaEVB8YO zl{4M}j9URYi}4Gj2{BVPJb@NcvA=jw)k@`Oxy=N z1~|!hBQSRKa}A6)0AnXV7iN4rFm~{BwTy28#?E~%$oK|e?AYf5jIRa8Mt#o5ICL2Z z?9k`DOsoOM&V0_pcscNKz~zh=17n9iXE9y?jGg&heh>QqFgE0K8OAe!u@Rq3GoA`O z6*vVP8ao~YcI0y{TwydYcH(nM#zTOy1D|VP+z%KV@3}DJUclIJ&($(60mepqF39-6 zb%e3Oo(nME3yh8RoR4tm;MiRtW`gi?g`L3IVb6IOzXgnq^;|jQ9l+R7&smIL0LDgo zF29?702mwSxeVhiz}Ps?r5Qg2jQ#RlYBwMMH-W%Ld9H;k+y{&e@?4VfMqq4==NcGq z0LF%RF3k9LVC;kEY8l@GjQ#Iikns(`*!Ru_7+(vF{qCG^cL*9^1_B%1IWJdO1H2H} z!+1F`_O)~6j28oAKRahJUI2`J>|A~q%*5?_Lt9MTiCyDR{63emUZ0-SN?!=pKdC@EB@QZ zrVak@C1b3G^qJfQj$C+$v=0IGmx|=1wJ9k|HBnjq|WIia# zKP36PBo9dPH%T__qF|t^e--$DlKe%IW=Z}m$sZ;8lO*>`a<3%!Ns^T0Zb^PG$vu+% zL6YA|l91%Ll!U1JCV?9z`HduZNzy1uT#`E_*&s=SBzH*iYe`~~L?!u^B)3blUXprA zeu*U17KsSFO_EzBxkZw7lH4pwNRqH5YbE)GBtMtrMoDgx%inZ``3u<~XX#{+2HI4hTMF51A#1(mil{1N1BLAR zLN-~*<_p=fw_ORoLbf_o$Tt+S&4p~HklkO%df#!S`3u=_A=^~QrVH6@AzSq>ODM(g z1Mxjic&hTkfGB&<74Iu#s|(qNLbf?R_n)58!T-7~>I&JGLbg4A=RXJ974f^Nax&vq zZY^ZH6w=d_)E#RZ2uL)`;)D}Tx+SH~JW%b)-^`G!H1eBgn?;+ZbD-J7K z+Dwg_?d$qd`-_50tf*BVX{RQ;`w(%fA{>e9wl%OUIIatPG#$?iS_OEoRQmDsev4JHb z{umKIn8l}Ad|Jeh8m7dr+m@u6P+jysZ}GB3>hzu`A4Zngw`f`X?q`l$4$&}0z+eAl zwQB=hmTMaTiw#f*Hdso&N;U`{qU77F*aqJ%WgC1}1slA|O1>&eR(x?<8SY)Dof)Nd zEY>@`Y8-SsV_yA}HLe=9MQQ+x8mI#`eky8sA&-1)(o*U?I`Facmn5bP>^Uty>)F9I zb*{K@kvL!xhdK~<0bMJTD2U6DxM6{1q}#x+&Oy?9+k0ZT`ygN{z1>t7yKtaR_$%P89D5rQMOM>=R$5IehjN&X;xqRi5m2QOY`)t6*9 zUetreT-t5XGCHfH*d;TpT0G8rf*d;a5BvyJi^%tcTqR*}OcSENU+%s?#_!-Sg{FdkXg&tfxlAP-u zb}oGTFGx{e4b&GM2x`c&F*=gAj8+3GsH63cqL|C;BViyBOl9kVwnrK$>CTO~{T7(S z|9H29e++wg@WX%jF??V%iwg0`TWF+ewE(1n%gSeO8A1x;vZ5`5vm86hpg!^;Q#i*V z3ZOocrSB+zM^b%m#Wk(JK0}%{VK}i!lGPp9V-fXVUrt2xM?;~qHPooPzhIy<&si3~ z`MLh*N9bLg^^rX+7~f)_qzJ5`2L4zh%U!p%++Sb9LWx|LD)&blxmtaBE6eW|5g2Jk z<0vJGSDq{FA8H}k7QuO(O)L;;+$tSF@)q`xXpE`oJ=~hF3uJZ8-gY~=N0eL0Iv9<0 zs*`>06!M3t7@>Zfp4RP=_K!jb4|-*a_nrg0MAB>}o;&j4`S7BC{>QC@w>tATV>!=X zJL>WDwRWC9KzI6j-a@bU)1KrA&XWg1a7ancEgNTH-<{lJ)}Pkk2>E1+gh?;$oqGY4 z5JeRVQE`_WrjDS41I~l(?U8**AZ~jkL)vmSR(h(8Gb`f^!O3Z$*HYj9SPb>JKMtkd zi(F}~Xx)uP*7J9izt`qg2nl7d?iq&hC$5RT6WMp(Oh`(vdRjd;6t7!_tO zqBjv{y>(a@$|JbHyTzheriEeF(@PSIf@S?r`sN1sU7iLI%C zC>kNdAMHKmyd`{e>dOaZIVx2yj7Czs6Q9rRIqb5uYt0VM6^_urVoub-inol;y=cV? zkn3`*{%i<;XQ+%S;@-afM<#t#95| zjx{1i=T3=#zf<;T{OT8vDXD%f-t^+?lFHW-_D19j8Sa9C^o*J*yTqL#tMTjXgRE; z7SWisJAU(?;UWL|!%6)}TB{18gNU{WE@`108xZ>+kqq;=#tecp+Dt@<#s%)8&&1p$uhB2<@k=385@y;rpa-1+dLyo8ZfRn!1z{!QC3*Dv?LTE|7m!bD)Bcu9baB5I4`bZ360|svDQ8AP^G4#Jn z5JTM|N5>Gx?#2)R4GLmR4Bao9-HJp8b?-=yA#_2r)IlwxvF;K>YpXei_G?`cE7*;0 zi(sz^%CQAGhRT@7<`H5Dd)Ow1kR{$cLE*6tIDuy7G+E$ntT5~qXPzxPP z$(2!PVhHV34B>97_;N*&F9VA&qmJv#bU*h&`8{d4DoEZF~rU4**t9# zo)9O7cq-_S3aiq}dC0^#F%+O4O$_-c%O}>`Bh{2OG32MLiJ>~mb{#`k2RIP6ArW_b za#&FeRgel@#n3cqT3={-i`!IU2rbE4HRwIs$Vg(SR`h|+Z4vBj!cDy@hAQ?XG9Q&y ztekuyVyLV*hA?(Fh5#srAjZVd_c)J>4SbJJ=Ww=_ePbxc5W1jQs-hOrSeeAoBTG4k zaD&Iy6){vvglxh>Ikq6jke7Mv$|8oU2$>i{mW0b_C5FDBBGow7$YN-Xh5k_$Ll8=B z>pqm@P}2gAp&!oV7($_mA+%R9geMlnm#d0=8CZN7bzEN#_Hkp#?GincMjS&wUBEGP zd6yki3{f?Tp_M+jUw=`*z|t@3xc#;qY5I*tc3ScPs8Oa~2~3u3Xl597ga2ZXTu zZ96f+73(8N+9GUvr-Y4O&(lEBa_AJ?(MOIr*yl6RQbk#F#0gN=M2pYa=OYa%8|w0` z?XL^jvBsR`M$7*yilW6wI(8K;wbC?)L;~$8x2Z%6T9UH_sds;LQX@k?YpVgXonP?R z7Qx*CIHXTSi*JvdwOt-Wv>Z_!Ef~8SEdUfP5M!ccg=lt4L9_m(8Ceru(7a%`G#WcX zq9q^TXz^=Z5iJ3p8r;Z$a+=!`)zUdUO=xV0rKi z4wk3syo!!=MIBSH1V2EqToiQsttsjkSo%dBx8FUzq+c9x(lg<45q1Fy8djxS#LKEQ zazQLs8@E5`A7b-6k-_!q^#nL2Z2Eeh44UObC&D?xRM5t|iJ3CWnwarW*2GM?volZb zNZGDq=6#wMT8!7ucO8E+{nw&SS2{H`XI;h2pQY((g{J!kI87yH(2~sKrQQ)U3^``1 zz&J63+iY;lfQp$K6EpYHWe6Q@i(>|3cVh;CVg_PN%seKVH6f8`o==*QHPHpRrbR8H zv2ux-ac6PN)M{N3Gj&9?MQ}%u0~$T@5hlz$ZV@78))O)@gDe7)Yj%nmm>-Q}jhu_c zq)s7bdO|1{%Mqs6X$YDtl5^R2QD}k&?N!j!y3Siy=y!*7+ojC&N8S<7Tv(N!DqL@O(HS#4|w~n=mSEy^3wsyf`7${$DqQS}AKnC{0-t zLMh6^^~pQ)l6GDAuPsJT>Sxl^8-xvQ`6n zk2W%r7-|xIB!=)@2;8(*#Zaq>q2A{rhAN6<2xE6+2!LV;VoVHOE}AVYXtwzXjv;hG zvlOHj(O8AV(1z1FhEiHr#85j=4IW{Ea%@44p)~V&rUfz7LCC}qvLswa+bM>e#&qWc zipOG7M;(SBl-edu3|&wEkNKkkV<*ny7($_mA+%R9)Ixq5KjOLJ6W}S@XHT)*SaC(0 zo;g;Q%;Z?P^W?5Npjc^;SV@sgp4-jsoGWas0ZXi)jvFg?9IS9-~-AVx@|*UB}8gnhrW>{OT0f;a}-l6e}50p{rQ&OVdS#roVBUO01wI`B^1; zk2W%rSn-NJvMGQEtKg1d6)PFDDR9~%#LBSZSi#ucSOK6|ffy4j&xvM#Mj}zXyNqK6 zU64!S!Juetn8Zr^Y>t(z))ldmC!#HaXTYEwTaaUAKl6Af46%a8VNI+cOTuNe5-Vm? zz-dh9BT$^4Q9z=PHxNo~tKO93&EHN$taz_IiCr0mCRWg1#Y)=slmF706J5#_$)+%=d=rP1c>ehb$IIQcZQmM!bn?x5^M*3Z?iPV5 zNpUWS#j4)q3wk!1t$^fJ<c|BQ*@4?$o+=}&a>2T-6?9LzErN#< z;fW0@Oi=fUK;oKU&jBmv(4|Lx#8Vt9FrFJK0Av-2GFHjT(4I#kp|T67By@LQLIux= zMPnWgmCLu!;!wdO;m$xfBq|hvkum8ZvMqw=ETOe)2QI7RvL-I0TWf?&3?WMcuX#7# z@a4dvx)JS|VI;5y?M=NKPklMGC&WHlbF4~@jd9RZ zVi9eW^n@&CWj%Rx3f7ZhkC5u5Bnp)+#18SlzC3-%+OOU5yAmKMRufE$@6ka-p zcPU23iKXL(9aBR8{z@d_1oNSBh&*v~;~sQJiVaLVf|yn1>a;7!^ZX3Ck#hib%9&_n z&AM%MNYlWr%(t;ZVqa&a;U=_oNCP((c1qZ`bb}N2qHQoSn}ji2`i}JXt{XdTSaaGn zW@+riP6@j&ZC-vFVsWlF6N2N)U5SSD-DN*1O0Igyow4tya@(^DZO=qoZYs+fTGGr}=snuV zh*vdMN7gX*QBy@2tZJuGt1{7<$3@TlL6j_OT;MEgcpe*ZkW|YW>N?BX6K7yq8&kZj z!FcYn20+UiM44qRB4)W5iJ0YrAIKr2+zojS9*B*`#>lefJCT>QfF3N)0IC&X{Fb)T zh-{18ZM1d`!4X`;Wq95k5nM~iL@=_{t0l{tZbbKyU?y4Cs2s~0#8B;WUe>06IkBr{ zt>TLcr2m(A3UgAEmb3U>uTNR? zOZX8XK#iD_PGVi%lZy+2jel zo~<~JwM3yZf?3Z_ePjBNZ$5Vo;7Wj?n8oYa5fgYlYau;Q`g61F`3|^^^D79J!8#yJ!8@|C|=LlzRo(sO=wq<25v0u zl(21S9}D)1N&>$F((4)fuhWJ#ua6*Ui?H`PCG5BL-P5a zA@}We1J0Eo9dN)sHjV=>QrVRl3b^#UeC;v%y(!1--DM=jB0M`ZR61#3q4W?XYu(5N zvw=t zk7u#H99QO6w5vz@w?)`uP6^wJwwEyMD3VZ->6~38{Hn=#d7durjhB}ZYrK3vvBt|Q zp-)#Qp+}P)$saN}&li8VhR!@XIeDmqRO!mgvt&DJ`=>(N>26!`a;Ky7Qt@>;pA!M_~R^L0!rrcdrn4fApg%p$k6{QE+$v08DX&=S$q3rPDKn*iMQyash2T@hCdGJKM`~ zYHmdvbEJP;ge~Tju&rp13B#s6E#vOWbdI~XP>;sllaw{?-bz{H?#+}n?%qM!F5P_@ zjh|e0#?h`n{N>XkcfS-b3h2t+M@ZX)qusVwxNXJV(UPpyj^3k#bekaRk z0UyWL{%g$2!6(44rxp7(M(g@D0Qogq8o&Mtl!y&nTF~X0J?z&R@#`jP5sgg~zyAGL z_UkgO9sC+^NN9^}GWxL1*sm*?$Ip7PjC%+fzebiOUB=hRubsy9Yvddq;NO(1TQsE3*BiHP9mH;Z z#t?RE6dJciGvn41c1<4|e#dodR{{i)Tz2cmLG0EK5AI41xiwY8%1#c5gANvE|qyYnaDd7_bJ{5;AKr zvLsxF+G!1T8pj$rN2?d~SLYV-Q(o^;lI@W5=zaa!Q|~*9Jq+C$Peo(nsn>iqeds?s zTu((M>e`jgp886E_S8OI${|nf=wMI1{_`oJBaA4VSmeuKya-Q_cq~ir7HNjkboI(f zjQi@mpAunXIqu7?Xaj^)lb2Sw3osjsHb9_s6iKMaZq5RXmk}7(4pP>*b{%DnYu8ZL zxONj|yL4@v#!t?0HZBijbvkFK{7 z-)C1xUo>0Q)FK-5$=Z9y5O(#j))}t8o`|*xUOECT*^=z)4a`5XEB^O4E5^wXJNdO! zGuFsCTE;qL?L|ZCyvca<_;NX==*J$7LgUeBW;}XSe)`b8ueu)XN`N4e%O2gMoIQF) zmvYFXsT$VaS^K73Fvp03M~^FojUqfH;?XRpHi?*9FOK!^b=mk zDtEu_2`Q^MUh5%o#%s$dYrM9Svc_vGC~LgdPuVWL_Cy*Zd2KV!@?~Bl?-hA%lJtnr ze5dF6YC-<4FE_ig&}@O*OdJ-i$QV`Vn0`kK#188dO~hgG8XCBQ=aYEyoiQuFq0`j* z$lPMr#6Vrw1R&Q$OXHgF_h((UB9S5d;azr3kGN(TwTQ;%$|`*0QS6${T06LA3lVJ* zyd($uu({YZTbajObFd1h2$@wFS(;NBUng&M8q*006sH^OND8ZPpE7CcH(nb&g1z>X zKJ2yV(0DDH8?W8JZ~D;6S6r_}CF~)9NCo|^4co#+V8)bGQTb@qTsdX z+b~~*=S94hrFV;zvG$Ez5Q}kNMeFdRyW$J~TT$}ZuK30O^@Nlu92dnKVT_BWC~I7_ zgR;g&+bL^YbU$UgbkQqmK;)t&a5E>8oa{^6u-jJr6isRP zS@cdn!31JI&5JtXr>({>yr0A`%Zyoh+-Ufzzt~SPTGvkj$WPJI_~}f(;uturpv!A- zvY&dzPw^(5Xv{B5=tKS3Pt#gE_-O|bZIQ=~K5R4g(+u-lcExAEUolPw)5$5Fn)Lh( zw2Z~FZ^#mghU7~7-;k4n-;}X4{_1dcA`}{DL^I=z&0n85nUs8vyQUHJ)0@prF-5_VF13=?4C(cN8IxX;|@M`+(%XCxQ`33c)p|8$_wZm zv_7)1*l}S8*Kq;JaUs(GuDzOY?k*OSANDks8*$kqcrm?yG2d{pYTD=HrTzCwIjUeC!D+Lpc8HB@xDdJ(M;6 zTSZypzm=3V{##AiF8%k-!+3Td?di_$G5;y@-wLuvm;U>EY5R*p+dVs+w&K5NO8)Cd z@AT6`AokyYs3ZRSl<|sy@?TWd{+qb^te(AA{+7-x=|@b(4h%!M4h%pJ457w>Kj%x0 zfoUY-z_UqBa$s~w6J0?qqOpKD@QB0Nf$=(3S8+ISB@u0rr;Vy?PIh3thqWz|G7elt z$T%>vBwU8x$$_25blMEX>EMc_aE5SXPY9*9)y9WQZ1!PKclKcv8Xrb`0YzTcm>ZZ{z~{ z^*axv^SaCibJk^UMSJ)(0GKTP)Gkj**~jr~yo=8Gb(*rqud|dje%(P?Av#a|W zeQ1!hE|;?mC;KM5+A_I)n*?OvvH(E7;IVkgF^T_*-0Cx#f~#Pj*;V&M3KVn6#gJ2AQ- zU%|WlqOqmo#7ldy6Z^HQaN+=4eydTAZO2Yr&HS^*iGzfU6C+E)Ww4!`*lA3UORy8f zq)uTK?g^pPwoIIOY84&a)gyk~L2TB=7W*RV8lQ$Z@##dg#GXFX+Uh#BD-nXJLpXJ} zf!~jf-}zqup)VgCizh*fB#~EBJ-S>=Y$~;Ar!r1RrL;&A9J+LdJcOCE+q2ao;cO_!pl| zw!`sJpN|-E6&;-q^~p!RV^0dlSA0G=vHUQ5N}uUZxju-#;@^KZH2(SPeY>6cKlZ({ zQKrR){J6w*J?$wIZ+p@-pgkL-COrXxw)FZ9jFq(F0{Uq~eATxDLp&(QZ@6BkVL2r{ zAlgZRAo@YuA;aU{+P27cF;VHfUDfmoF>;slD06rT?fcMsYuY01rnu56J~71QRPp*f zQgIr;RLT5e6ES)*Q_vPQj( zQ=#yqDSDpdb37wOPle&VL(#@&$YTA$Xx_NiC`-E-k+XbF8U`@PSnmzHXxN8i)bwX1_Vl)ghq4<pQ#h!*h{G7nsXvPsICWvG?1W)*67 zD(F?RLX=EX87-2G*w`H)+*PPuiqRG3f*zBUMY4(cNXsmwvWP>Cw#W;{8;nn7*^6T0 zO!siB*ye>qJ`If%|LAK^3T5rHd%~Gb6Rs;K6%*Fu)tQ~5;oMKiuP{V;F(K-04zgDk zemw|`HQ=}b93=S1izb-5@|RHko7n;V;V`xAF!&aSsisjE{M)E!q69(@i4ruRD5+t6 zpjmB^X225ls6)SN%x=0U)I|_I&L^|I&-RhJ_7daiUI34Q1>F!!k9B|{!Y5Y^Sa>TK((_832 z1T1=8Xd-a3Js?z`AM3swwD#-8bl}=PfV5ceYSBPBe&eRRavD&SKo$2Fy|def(;?(W zEE=8O4;myJu+d|sw|@W^j?}xYM zqW6O~kPJQK?U6d_V>;GXdV!?q63+E7%7`&~urixbQO-)5Iu9O@1~0#CTQh)P!P-ET z@lr>U+Od;I*o5Zp2%q?j2Z(Bg0k%yUQS?g7eN^oVGRQ2f7_w^4dBVAZq;ug;GHXR9 zlTPqte?l^MU)6cYt<-F)D7R3QOF4pg#EU&FX*24{h?AX14Cs#dg8npOy1wD33LBG1 zp4oYd|CwEjV0eoJh-oHNC~AkpJWe3y87InlFsZkCN$=UVQ_*pPDAKg zg+!2c5X#clWqzPS&KhRy!Ed0MaIFXF(}(`(Wtv<`@y<&&HBZ0Rc!w%eFe8DgM`~T0 z-Vt3XWnC#{U6Df9;oq~a9iprIZvg0(zYr(7a@H`8uFPp&nV_p9Gz0JGs(Csk5ncUV z>gqSTQp&ngI{Od3hS^5dqrPKRGomUa8MCr9QI)gwt1-xTRAr!5WrFUap^{cr^Yj+Z zx2ZVVh<}~HW=;I)B)hl$wwQDO+fZ>BLAEAAwq~DiS;f4l=>7u+dbSi&L`BXT#!-weMI{TCAS+lGR!oHdN2 zD|1>`CMbG~b=5rGu@POXyVSLsbsb9PWK{{Wsz{-#{XbUK!tscH;z}aS%(FBxD`#mB z4)PsU8E93Rpgkf~(q`2>y)#*2zpP7D%ZynmWnC#{U6Df91K+T&9?=z|jIJzBbmeR` z!il3R1Fb6)^k&0iT{Ta?9L5XyX)hSbA;It4Dc(vc>q;r>iWItj`8Dh67hT=|l0lQj zul47JinE4sbY)KK$^>okpqaL-=IP4zebyEKnB!1gJKh&vDP>(LWnGa%*F9gct^v^% zqKsWxoY&gV(&PFAztL9^+&;1A6S2$Zel78UmkM@dW#M1kBCITnf z18iejf~4*+f~+k;*7ntXtZh)VMN^|K{>O;35U{`qGmf?lw6;vpLV&tjTg}r#z@i$P zksRU$%|=y9*|Lb=5o_^7vG? zu@%W7y0&J-3n*n>DP>)eLf5vvtZR+v3Q@+cEKYRgES;9414mZ|T304$dkdAcT{TZD z!Mju(ZNxvdIaJrO_e57pSyxI~SESJO=`UE${?AYo1jNi>i=hRAp(RDrf1&CFDD*GSI3r zK{tC)Nvo=P`T-1%ywS!il0#I@nzH~(Syf8etVm(j2R~X2T;noQp&m_g|63r%(|9|t`KE(WpSb_XX$W*4jf$>XkD40 zt94Y;x@tZu&rC%d!(HkcHo8*Ex>CxzB89G(f5f_$i>@^VU0Iyy%2~RY*Sa#$x-vmG zC5v^{d{iEdi8gw>)YWTrrIdB0lyyZ4T`&BQb*&Ix@sy3RD~l6dIZGGwT2}^IS0?CQ zM6s@#r~6NM;DKK9hU5?*$h1=DeH<9x~}+ub@hm@5M^{_aiS|{>1rMwI6lBY z>&gT@wTVjF2Q*KoJ~&yVXA_VdqHB#gbETAZrF4p)4zK3K^}L;|YNe5%yO9ltKPz`$PyBoY-DkLw?=#?A?lV-uT6Fq_gia`>Ycwa6cN8HM8~Br# zd83r8z*@KulwI7f^Z&V`*8|cX^Awsef2{Q8XL&qj#Q09fwREf= znj}i1o+z2^EFaL7e=Ow3N-z5l-O#8v|Lb$}GFYwjj#hA6{q?!*Y0XE|_67ZK==$y1 zPiBv?cwgTiy(dqio`1Fh|Eb!)Zcor(zan3s`2H08_>$!K#1E(1Qxg}SYB!a1F!*~( zaKdlq+G7(teD=%|&xAyu*>>Gwo(Y#&PyIacN~*LX@u%5#N{HVj`o7$wBC&1`oed`^ zB<`JKZ$gW+PO~2@`4CcqJ-Fd>R^pYj>_LgObM5n`Xqh?P z-dl2QAn}WZ_VC2g+e$_!26uEnvgG))6GzXp&nVe_R^sw`_6!kWCtg|6y(01KJliY1 zbh8up?mui$qOae+yrkyr#9F^SwPf1aiHH35q|vXgKAfEM3OYfF@;Ch~o$_R@^-*6L z*=xYLiIVyD7!f@@kv_|=NX(sY`%Bu-Ox!Ww>GSBs7a6j^$Mfw8P`CdA`%QtzT!;#{*n{UO!Qr7k1QE*YGUd_dtS-gehh0#$!-2bdZ9g}Mdk-~!oI5epv0Gp4QwOJ~Otn-|wc{rzj$Uq`zPh>4LEo7yIK6uzcl}7A(y@Cgm%LLbc~?p@ zyXkF#G%9P7JE~`;B%82%b{m*@Z@GP#rz$|tRz*vXMM5Ji%kH5Q1^V~#yfkd7oRsMP zWBa2ZO|<> z{Wn@NAw$O}Cako_iD2WzSFf}yYJxPpXzySDjvi~`n)NTp-O9~V=+xtMJb2QALs4zP z3WpyrHYMw%X*N12?eN!^&RqygP?pSaiVUBYXY28Q!f#3a&sWkT9|zA|!vCIcH@QOT zE&^2hy1sJHw)A7d^`#m5j-F1guphP+CH^n$uY2F#G*d^^m|i2VsFnLcWh$t z8Va+LV-s`N*pZ5%6KEWfRw`{ktpjMYJ$q4Q;(gSbQJFa60((a2|KsaR;A+~wfIDlS z(@jcdm81+$2t^1*C{t-t$`C~j|}GEX7%Ofuz};+Y$KYoC4Z z!87>T`S@!|iN4R8Tp3{`$z@5+QqtvgE4;x2i=ytwbb@SvvuDa*AzIJ=vjxd|# zPITrs#YPd5oryp1>yh)?F|%Sb91tN{I#q1O9f3#T>$TL4YkuMDWz@@*dU3!pM5?el z8t;BZszcYOq(f24+!;ixy zXHBq!AjUD8u!?d(pJ=HWY-xfC(Na_H>N29G_Ry*c7DY?VHL5SH$;7?KWhy}59F@gI0jFnD{w%NKd3r15wR#+PsjG-16 zYvW&IBy0GqHeMVfIf9KNmW?4MQO^-$^^?Fy?AVVYx}RgE^`@I_i8ZSI)7~mBJTH4f z|JwLtoYdP|uFb2ek|L$3zqIz@>ZJ;b;Eo(GHGpo8h~uRY7Ha(y`;U`rV#;O36l+hA zDhniyWD&0UOdu9SJK~55l9TZN<#F*`nplqUiUdb|I6~ zOq6Px^rZ4ke(m<~GDmDNQECJ=YU03&QX;dh@)IleHmr%#B*|6`X)EIscjBSjB&oiM znWetx4o8fgB&D*_Nl$;s z%bzEkV+o}uLFRg}ryQ~26lpv>r)hDDum1-bX)$W4Y-MP;hg zPSgyS(N9Y?;ZvzbYm5u2hWE{#DtVjTaO6g=#xU!ukf+#_WK;{gOp~he7X7DDn0Ut# zmrSE@a+@(;o+i~5FvrVS^R!_ttQJp#p_c9Ar9q-*ii{O+(rBmRDU|f6hLsY;Xx<5= z8Y`;e5qcIa6Nn2NsHN3(GJ<>N=rvvH$YCv39=}f6Ehm<)}@)Bb$lreuP)Iz&Nf;pi&`Xovn zMa^OvLtYZh{fSZ_7&OQ7Nz}q!#^y-^Mo^Np2tq31t0X<%D`cF0TvH3X%_0L_SrK>4 z($}n#F(*l>fy!)>pSKCx&6e7jwUD`L-=P)#t84Tk3NEf`SRISvC1YGPTQY+Krnr8# zAmh<&DGaKaV#hh+dDDE||Ots{k8luXM4 zD&3PTt$+&*z2-_C`1Aa^#L+Kim`ACg_MlE-o25wMFdcAtiqt{WWRmr8xAHMXN(C=N zoI6jtB5J?sr>CC=?n`iF2jS1B{zYB zg@P6K$+ggOiR26Onq%}5;!rIklw!!ZLI)XZu<^t4CU|9u80p;-X@WeEuCC!Cd*kXD zzm!&222Hd(mP)b&tDEEAWfZ}jld=7Bp>flfOR;PQ(eZgXt+#eG*A7mVf+co{aA>wf zs*Ziuuqv2$omIx~D8&hshALQ;LHt^prblvwf=@n>Gx(53Zst^TG+QBgu!`Tx(8rEs zG3%*GhKG zoHEVU5*tHXVDwsPGiPg+b<#{h-7N*frjb<~UPlgoQwzMePI6#9iptP5U211h^0z8s zzDt#olvqOHG7kX`WwgMsbg7qs@KC`k?N}|mlTJ2yss)y$(~_2?8@FB>XVL4G3ZU?R z0OYkm;|(NXYSw=PH5)_QI;2TO|I_SF3;bKx%w?l=&cf}b+U(o^G|O*+wKhpH9NNN7 zQmRGm7izPLq?f;AUDyKKZx+omHj}{}eqDy8o25qb!}n!B(QkaYYUs8_>JQtV;o2=y z8yN9Sdv}W@No_2}uo*(nw^4HVQ;UDSY4&qU4o{2RLv40YY;SQC6?1W9WOH09o;%S~%b;6)ODYbFJH-AdI!QKhi{3Trk zCnxQ&9c08p4nc-uuCd-NeHSGQ4RO>ur53i!An#7hiOnFpjB&y}8MLgX=QevJcOY5D z@6n^N&JZhJAX$FdLyEb{39Igv+FQVFfxpUin}3yn*g1SJVM~B=s2S{cO5G=F?0QjL(+th>le>!kJDvBAw(ibUUgCSyO`*ACQ|pbX0mE z+SbyDY3$H3X$_3Lhru~g58*m&aq$Jo8qefN#lY_3$>X%hreRD@&_0Wk6Yf5t2ijDF zduGubRp+FXCxAL=aQZIV=Bju~N@G^H%Fu5;IiZuMq^1J26IO~gG}oG)mKsPV?Jt$- z!m?*h*y)TEAz-xEhz+^ZXDFDoYKa}rN(;cPC0;p8vLQSi&q-0DWnYcZN9{T32#jrs ztCQr<;xNDy&&W>{{qQ-Q%k&bL2?7_6Z1e@hb-W7gZ&byp0!!Vgu$J%xp3p|`FRpJO<%B2t|yCs&p zB-z8LGuZkP^`;4o9OiC)k6-RXz_dDzb1xII&st*cWyx92xkw)A zYUA?N(fSJMaKTw@V@5%H!WA+7ufIYnS8xQK@}v$zbemMs;o>~9TZ2}(J5RCz^Hz8v zk9PC^Jb@*7v|UID`Cpan;v1dd1nmF+B4ntx;XaK}R#(~N(T*Q4`}yiKIRGl-Q9Ji? zJE`pdMHO$KoHS1W;k@J>%<%hFsY2!Xhj<+i9YpM3uN7KcBjlZ1Ve4xYvP{atHP?h( zA6=u}Ki^hpeq9QN8z*t}b)hD^uTyzwD|~gG!igTob^yoTq?n$b z({Iv_AEhR@q)w2~3Vm-$vGU-P#Nm}EDF!aMCDjv(Rmn&gXrtRSOWL)@tGA_*pzOnr zcchl!)fy+>kyeAlQLKKKW{H9<9DA4I!f9D}=Pv2KRTj3rN99KkV;WCG591e}!eI=! zPut4N58?6qG{@$*!YB8oNieZB_J2UTmRmD%_X82*zk4A0a6~&ir18^Qq{2Q~sCmpciJj5zvDBBrW@AixEHyGc(43aJYMh^S!5Fh2 zlO{MhUxpGwipbxRo@A3=-3k$mNv^^|t# zYwW=HPo>$={!g6vOd10Xcj4P-vK6p-(VF``PcNiYLAk%U?Vr+oN z5+qA({!*&P*&X~+@?>G#%CNYvrY0VLDcJ~hXi!eLC#6toCnplCuvxxb4f_;IF3@Z* zVj;~=_x9kMLJDN&?7{Z0C~dWedn;dfmVpJYqyfz7urYT2n>x@q)Bl#{LF5)Rdo6h4 z{aQ)_X)WHQXJN(Oc-&34##V1g-}>yr5pQTiTwU|^E{By)&}?+$4b5bmSEJ)w0V3wD zbcvz1GP=Ff2dAUUVMiZw@@wBo$N8vX@1>QHyc$d2ixAkYh)x(fuE*y^WIa@0`-7Cl z(+3}mX{3PR zWsFyV;(_4r!r+&GCj)kCgLl76v2br4di|iS4(hS^hx8S)7vkJvnv3jLp=Al#-J>*| zSVHzWISn6_kbRn`Vf#`lKa9A#RO$l*5x}pOi`efWu<#t)G&E z1nF(iNP;A2uu8j7g6f20Tigl|18Y{G1%tZ~+7>@CNM!w!jd6+$E@lSph`!6Tv z)_PNaJR?ILyEs$5SSnmdD`@Et8MS}hZ#$r8R&k!1cb361k zgh6JZ1f2Y+m^W^w;BiCf1?kJNx(1#=PFwu0fmx8y4yPMI90bk7pGKf=Aha(B?IF7z zPAdmZ*}3F0OsED`#W)qpAj0_uwIu?cjC)$_5Dsd$bx zrDx;$m`%?Dl3jVRO0Qo58obAO%O8 z>H9P-FG7X;W-u74C!t$KfmeJ*m;eJ3@f$shaa)!bEBaoQzz6ou#7&j-HLZy@ZcsmY zjp0o6tt?Fvq>sz!N4+#h=x{!nyxc)mc}hFq|I_n9;1O=4nptD5}hV zt5Wk+^~Y57tqvAYeku;9)TAg*AJ&<>;G*iV1VUY~UJYn%8sPHplE!)(M%4fp_~e2M zr_j>(NDc7j;xsjfwP53lJI%olx=c&8fS#a8?4c@Z_XwxkvWD8!O9D9sho5?VvL3+7pZZ~eqXZWl2WC(tD~`lT~}`h9Ifn|EpA zsP*G4WAvy=U9w$qT1}{D?LUR02#>@Rk3?N#%U_MZOv0R+P!-;|;;owC$y!XJ34}I0 zv4a&@b0h{@ff_n*vx25z)n0qY3T$-VE7U}6%2u})O$J)SIdE%_4Qmr+K2vZ)ZP4we ztS}K9gEwl!B$(44eQY2dZcf4vHu@HS>R@@>!XRU(SiY9>$a^K>^lM5Lykra0VA4eF zSqH{c*guKKM9w@=qU~;s@iMH6`J)UCaeh}xgYWC;?e&3)*#ESxOV-nO0!G(``*u^u ztC0CgV+M_op1G+#8Se664vp{G3y0BQB#x>_lHK1Pch)04{&NJrsRtvV-B|2bAJkpB zwe?|em5S{;{aV1$`;LWmMq|}KV3y^*Xs(4G+juB)4s{zNqH{{z~>kdavQ2efQb zuR|mqIS>km_zjY*hV)3y=u{^80te?dNCiXt7s}0<{^;KTHi26Q?Y9Py$z0>&>0$!^ zx&Cwfz^i+z)l`*Ity8=|zHJOOSv|^>w+Abx zP^OVRY1^QY7;aB4u+sqCWDf)3_y|;*KyOG6!H_0k>3Co&A4J)uCT?zrX$5P*eCY*o zWtFZd*|#EH@8bMSsWyA6KW=LRwrntEa+|P9=M+EseRF@+od6DS>(IPK@J7q>S^& z)h%HR=7(d9**ybq0Gjo-&7=p`N)9Z$xZM2|U$p__d1N z7>CuCYCk)}0Ei93z&6l`?Tq!;&S(SsfW05-kIpX8T9ZKnJCxrZ$Gbpxn~0IWFzZ8k z6|)>2X5FaEV;92A+)W$c$}t-^{6Cl_5N3mh`{Sh!gjoy9lyo4>On4&|v-Dq>eH})_ zyAftheKF0AFdH_^UwhgOZb8$BV7?m z{Tj=P`l~^gzmy&?3dC^(rVuU|_m;_a8D!bLnz;hhs3e=nixGoHd4#K%kRa^3(D!nbmdHLhX0Z^}2AXTfh(W!Fb zYi@niDUkk~wxcHUKyYA2lxaPXWcSq5ANvm^_8y~5!a!IVU&oV=E2P7Hp|CHLU!~l{ z+7eg3_xQJ=&dO@HP^~Qgw+b?}a=i4ca)wIzKOJUfNjG>5l%gC~TL%{E%&xk!ffpnz z8`W}gV1Bka?hb|Nnr@wht7{zwHjv*D`-H(*7UWFZV|$Ei;O?zPv^%%RSVkXD$yi$w z2Bs1OchZ(03`1n-)dI&v(yY>=F7At@S!Hi?tQtkL%H%rQ=qP9?K{Gnb97@xIsV&|e zO4GszJ8jZ1il!{3#=n&5bE9ARSBbNzkG~u&Cnq3JSd}u+e15)7W$--{904r76%v z6Qg@*Ifd2$i#qeTFGAx)g-1^qh^V%59E>$oOU{b>KAYkwdaPiH&Qr;cU8#Yyd7410 z!l}>&oNJ)p;8R>A2!ommC1Pp2W;Rl%Aw^h4AX_r1o$F>k|>y0$zLD|hQueq zK`^U?t!Gh}yb3sL79lsS0^XTL$hE3~Hna7}Z4$^$oGs{II~#)7;JJSIZ8p?pu5R(&qhxWI7sE$E^U^eh)3vy3d8NoT6iM;S4x*!PzOqv@YdS z=Rtq?W`qNHy3z=mh&M59%^vXe0q-8;BEeFqrp}S==p>pE?WRm5NwEL{P~B1 z{TISeSg7FHh4k#G(5W3gpOJCVA|5t-a1<@^!Xk1j&l$!pCdDIMG8RLiz|sT6UUtJJ zc6lXYTxW7%pQP1f3Wyexz!u#A`3jaV{7tC7* z>*ZbwZ65H`>eOKx4X#)YwFH5q>L;T+^if+OUe9`%=J53hfb2S$x_)D zi;iv@Yn+-2o2pD(|3Bd^Na%#HkIgSG#lMl9a3tWsH0UaZnhW9}_(B?NgY+&qb_Mi+ z%r2O-0y0I5H6WIcsVixLP}BvVt%N+N*p*XV3$L%D)dP{WW;M(a&9ev~*Z0nAzzV#& zV%Qq!!&ZJR#UpFLMKn1DLd$Bbr6!48`B)a{y%shIt-OHg-)Qr`!a8Vflirmt(W{T4 zg`|kEMc6QyPMk8g@qM``^Jwd3^%|&%H5bYi*vZeOxNMz%pldV`zuNF_9ayzJr-Jet z{Xd{q9OIrP$%fdPQmrYk6}NGiV#^NZt2EmxN8C}!P@Mm=!RhW>?YgYJID{W z?e#KbZC>+Z=!ff~H#HHq5jG&>3bv!j2PZ?8gW6W7pB$5U@T7bk_M0bN5p9 zxP$uYKXg}D_8)}CQ0)aiIS94j%kxw%v|;71mZIZnO*L%)Mq`LUT793EvRF1#qec+W z9ZzVh(bd>;Dn=Mm>=eva;`eR&?N)drf2wAq@OjSDW)>X{l`xd`83 zQ%}5*3%lX3T%2-=HlL{c@+DfZ{&NIpUKZ_6U4|`?(G#PuP`H(L3U^%*Pm4{R!6|R7e2=DD10RgJM`kek81BDE>h087`|}=|fu^1hx%c_u_~0?k0P7#p9=%^PJWe=X@~hIr%hcCw_iTTU_eY+CziQB9vO%;1^Iqf=@me z^^!K9-S*;(mx2(-LYOX9F!v?qrOY=VpefyraPecPj<;SB$vd{A<=+CCet)a<_~QK6 z;13b2@yTobDB&6mabmT!?r-=gi+nNQEg5R47tVi6O}F{tlebV8a=g&+9jt<-J8bpG;Nk;PEp7D=9B_^={_&9_x_n<8_mOyM?uTza zLXvPR>oE4PWR1)Jp(s4S4<~$r=5T)_{`EQ~L9DF3p#7beEbPsi52Z zq_l79UR>dZEg0}cKX`^ljfS+^FJLD@waxhCtG?=h?x5TK8x%p#Mr`$6U!&EX?JxZf zmtffj9P~q9lcfR}Z6AE0_8+NxO z)&S0?;ZKR}f&B|`FE9=o-veu*cCF6{__kym$(ZUcb~DzQT}v&+#jm95SYBqmU`Q&4 z%FItt?`I^gb6t_yQP9r7g^B=}t1u5}F$1d@if3O#fjsUtWOUnP7Mf|q0KOXbQh*Al zdujZYl0YLC+V0p~ozM-)W%6a#E-D}$$fuZzKduvx`g8L|^e7zb9X~8GB4S+2`DyS<=5%(@oePpnt+$6&T%jrH#l6tPAsIe%fkgEJT9J z4RLHmHkS>O=vrtcW+-d!5ah!Ixk5FTB|}~>ylBCEq5A}^Wl2=q^uoTDtQ%|?!M%qS z=2)`Yyzq%7YY!#?THBgzy9A-Vw7FL74+-o7@KY_e9J0n>iZyeFr~o`|%^Fb;?FVa? z4KQIm?zUx}dBG=JMqcReG1$K@aghqv)Mb?<7(Wa%>WP96^%!}@^Z@PW`s@=xUV!$s z9Xl?;g8=QWM$BG<9?|%qv4Cc4&*}g?8HyfFMZw&rthWT=kyy}7K&$J(j!Muu1fM#x z4jP+Yw2rlraOHQh@-EHUMG5MLVHGFQIoOG+#g?8)?!R?EiTp7LC#Bm6dRMXRzZ_k`0 zP=c{z2R)c@NnOrpH+5iichM*i|8!%u%?wU16G1(HC1aW&-f`2nkClXhwCu>9{V44~-i^JSx%aTKq=oKi!#)CR*3evIps8 zTyJ#l!A|H0MmlI81<^q`+LJYgoZh(3lkJApLFntn+OoFZrC9V`vA``}Wbnfy&*S9d$A{LL>dx=U%lC1ave_*KU-nZ>2k)H>%%Mrev!m= zeuBq*S$%jDq;2HOasaG?@r^%g12#d}pcfkrjXiKxFH-o!9Wc8WtHlwx--|8g>Bs;U z4GzKhAb>SwX5C7$<6jhL*9v6y#Q>{lM}RM(LIc?Z=oXB31DPF+aYfdfrT1DMN3ew z3Dz3HJO!{#w39%W5w-J1uyzvM=!@q^vTs)V>Z)$FhzAkNZRj`I*IY2~TVH%QihT9F zM%Xrnc?%%fw2eY{;904VB*GbXV~VBa50CowO$UmHCq3r4J(%;rhp(jObfu|W{sALqxhFNUhHZ1GqU zElbx=WqxG)Rkfd{u?@dWZA}6R=2?HtN?@~~Zbj@oo!qWl;MRocjDb}M&PXKT6E~_S zu>lhJhT!;FY#)pb!O|3FjooJx8k<58XR~#%s|q^LA!kReC(U7#B~5OKFxVf-tT_}` z#-?*c?WnmN*#x2@g=Fxd0)Cz+Dq78F3x0LGxPYc$RspLlBoCvKvYugwHgYZP_=W5h zSy>2%EoK4mDFn5P*%+ug0PUBsyB+F%nb_({?z`&I34yq47EP zzRHvfB_b3q(uKmqE}+SIHU*-?F!?-rCmOf>1wQV!Fg$yaCGi69Ty{*V6nVOY$4`a2 zj=`tV`ZAj%1pgS_HcHmo3zu1%1i4`to~IYy3tEuVI~&^4JT_K>!Z7WaYs~a_<)~!% zALX!IOv=H}dJmHTHs4@bz`{?ejJCm`BTw07Fc_qr z|BTV4qtHQGe9jc^?X_!P@FpZK>QfUf3YjYxLvSG*!NqX4P!$6XeZ`QkJCn`5`syt#HxDIQ4Vzc?+>7V%E z+rm=6Pz2-S$?EQR^85tT z_Xm%GNJ6uU*=^}J^X;PfkAz&K^b&F!j5A8f!3Ph<$E9QlQG>TOC}WZ)VX#o_rax(Z zPaBMZKUpW(KNwg1B)^b5czIQM%5UIT{TF=s2tD}x!3Xxstt4;=$2XGP9pdL=YmimT z8VE9lL^=kzm|n++!pPN{wWiSN>RnzQ(fZ z`xhI_ZUDXJ<8>1igx1Pb9-%5sN(H&G1doz2(@gHnftQ-ePoPUO=2sMhHLN6S!F>)E zR1(jPE6bljo{e>?2uQ=L$aiTHO2jVJ1b~!k@=<6!RqI(@PLi6xsOGLaOC~qV?{xH{ zzq6p4692LkU+Sj#2h-8M5$O_tbH3gT1ap}O66kL(XF-kWXl6lg1`?V5E#w~nRU@>) zR&pkQSA@25Z8?$jKU|w;L+_bGKm>lam1jc9B%EAFMMit94ly4Vjl)*;1-kL|!p-x-`t%bNQXVs@aqLF;1Tk;tqBF352 zf!^LSIGh%NK27AcFgpU@H<4Sz{s^>dDz5~H##2oNAk$_tkbe!-R%$LElVH<8yw*Za z;|0-9as&uV2`DFA=jT@P8mVSMU)54Le^L_m(>Qc-=__rr@Kx|mXA*L)0Q~MOWZSll zTp+0vOYL^DA8hi&(d}g2eG5=~vmHm_try;HFQ~TeK*Mk*A90iKs+|dJ9n9)T zI_v6*cRT7KOd<%L6tuSLBp-L4>Z_vVz{RG!T&Cv94Ga=h&c9Wud8+E_i_JRA{W-z& zJIe=uSx65L8Z9jlqdes0kR6CWJ>*~0U11mb5JU~Zja}uT5I00yp_}X`!Iz%s+nr!- z^Tb^|?cs?gJt%$C1BdZ+K@U8~Q->b-ho?*@QA4ncr@R9Ob;nPhva2R;2(3is8HoM; zKrgw4C|O`2mPuQ@2W+ z`1<504*=+l0sgY9p-S*2@imm){#4Pm6PooBAiR5##?On?Zs{d!=ta0l+#Mj#f{Ibt zI#3=e7~?=kuKeZ3Q-Sh3w#2OjSN+gf;nm)98|cv56z=IS zPc!joMZQXvbZ!*33nA+|*BTdu2<}}95rVN8AcwO1txB-;l3X)YGOB>yr!^{FST1MkAWy zt0DT9A9NpLagUS-!7h4*V!XcQlWwWWqDXxI*kiwO`kHULgLisSxhFSs)1mSZp>mZ$ ztiu-%l@CCfJ$4%=`$BdjT*=d6jquGdxeKe)i1_$Q(}p7!Gn@#f^yqN%rjD(#eze@d zI;S4j%Ko&1ra!wxzq->DRhVRIGooounQezxqUE+?SQp&^XM+)PV-77~gggvV8(_`| zxh;P#8A0-JAIjxHCuSq%0Kv{kab8?*l>82QHW0%3Sr3D_P`1`ng=6ib;==dz#2Ycm zNt=F|{ZOnMD~DQNt;_MHS7oUU|NXtqqM^7xmf(fd{Uua^bfWHrIAFBilg$FLak+W4 z+z~Q|V&P~)zm5Uc8$***-cSq~Be%77HRpqUQU~L|!Y2t$e>M~kj3Hg{wnd|{dTFf% zvAHmKtk8v}W99ZxG!(CoC8%wyqscguVsUL%zJf1*ij(Jql;_6JGNulB}belkyZ#PUkd4fzkek6ct6J;OfJ1i2Pw4_~{mlNfh ztW#xL`R$V%3ugS#ovwRNA_$?wFnW@FhE=Xrg0)Z5`_k`El23ZLnZEXP!4l_9mTSX` zinw#K90b0WXgEdgZ~D=KbA`U!K_alj=_kpNB~6iA!b%Iwo4VDPN`{?%Bo(_<*1aTPgpcVu8!d| z<#uqO60V;~?Sd-d&zUr<<_yEyiSl8XQW5Vb>M>7b;!1~0l5pLzNhJD=;dnNQTyGCs zG?_)7CU-d6&64Lpz1p~U7D3!Xx29%O`Lp3@KU?n2I#nq_-$dGyUo~4ES7)ru@o^@O z@vF}CRXkN!(+EGoL8EAFK1Ys&TPBz>hk`}g&l`~}Hw3q6OiLzT)VDmABP`KRdp@+EbT1{bFg8KcVK%M`tyUJ;i7I?a;@ z81FaY81grgvEo~~DjuCD{Oyx@ayM`rj*aKbW8k0$)8`AX{&+rVb$B#dERe(DwjstZ z5amY~P)Og{5F0Plqg$X;gjoyaU>L7pKGl#JXlpN$Z_{;p9>?_2eP5vJQn@|*__Y`V zm+Ea{fGl3?T)UKPAu$@Wm&&`~9$@q`V)7D$5;|m;tI$nTaZ{Osw6HJ5_<}0I+<@ML zClx;Yvl!PbmpxfDWnM3rU4)iTz{PfS_rN1nZorLlWU4$722{YpRN0^Xpq8#kU2;o{ zF$HB8f#zJ@6@up|7+)=oRQgIuF7;rDtsq^V#yLo}Ym60L3q9z(ogBl_Cpc%j+>^z>F2?l9q!0gW*XzS_-F1fMf6Cq1 zy}ygmr>8_O-}6@;(*D#pO4Hpjxcw(Bsfg&`<}rTAA!B~`mt2V#N;_z}>OTTI z?x2`C`4Jx3ADAqG0(-hkg8>_@o zQ3^-k7=G0{zBI=y3s?_mk zx5MNiqegO?#zOBrLC)Xz1vwk;3UYef{hgeTcLX`h?g(;hMsjkdv2VA3qlCj=b3|{J zsX7A6jt~JZZ_ES%EARbIKs9`Ll38FuA^f7F+s(aWAZ@`c|ZaY;xdve0f~90oU_b?gRJ1!sf`pWO4KGp39IqAQqOEjc zs@+N2uDN>^r=BDsO}UEqPg1M8SFyz@dOn?pi%*dnPRQeGsIC#MPwVNTPZX&4m*P*$ z;cWd{4Zb){x>)}Lc05B}&R*s^sCK!0MyQ|VSt8`dNbGS|P7|_iC~gg;o+Hc+Pomp7 zLCMH-B$uL*xa}Ot#qI=JpQjn@#3f8TPq;X0>w=iF5tWigmCl) z{QH9J#jGzB<0w}$@$`{~rWkfnt}3*vJ60M^Q_9kd!p&q~Bu{y5jRsrhl1?o;kF#>A z^Ne%F*sqA*ye-Prn|^jhqxlVIK`d~liE z=8v-+#on;@G;X4l^*vpTp^A|eTI9)Xtl>2GYQJB?;$ge+YBr-VCQpunxKns9Pp{T1 z=~f7j16y7d*blfWhd{Ca}LR#x? z5-_6}e0-BuE${bZ&@IxpnK^j!7LnfWDAv49>C+=P<~9i^=?J~VPR~t_V8c6v<>PFe za7T}2eY~1aJiK;CZ~G05#5O~XyYdhgv`m8ucgab1&%%dysc+*fY(6i~zv_>@B6Q+sg9Qwk|V_u!YO)DHIWb~$Rh9MNvv zGitXf1NS~774RVGKBoZl!)}atuIERtk+{=*=DARo_s_X>c46cTeT!>G;`P;YFDQO= z--VT53grD>lKfWe#3Q=r5_)Fub`)dA1KLbTEYx%Ij_yLt$wDIDX9sFt=^@{v`#k)3 zd(bO+A)C3^3_rb+r$GJf82dN5?1UJc|F_&1rf$Snf0Gz%|B0<%>s8>ZP=O_{g%nS` zCQ&rsj`iN?VV4?-nLYlEd`1XCE+=BS!Efc!%qEt0f8LS}ayh<}=koORJ6hdSy5YSj zZ&)NZWx>?2Z;^Z+Y`0+j55(o`8#$Nxw{%jHwxPoZlE$VF#N}}t>HZRFZjFuD;UlGo zHsBhb_S=BPALSu+{#noa{l4N3AQ-fWC=!a56N5AVkr$YCR@=={;nT0UmD}QzTubJk!We`ZZqE^69k1JNAk8{JN&2*=Hdf@6WW9-L?*Q>7L(yCZeD3G{Zq(WJeZ9 zM5TTqZB0nUTVLcBY(Ev4e5FNF(kkrumG&WmH{*h@vL(x*iod?nE=Qj=So&4KcKIg! z^qgPepj5VI`Gi)vGIOeN44BS3etB8CN@g zIoFn8RSWoUa?%^V#8mf+YzX*%S@C7Qi)d-EfP%_8ilSS7cQh8BFicU@9kRuW5(B*! zA~RHUJI&pUg##R5sPux33vl1RHJ--8Kq_dIIF86XjS>W5Gx51bu@T}Oqw8DONU6>y z5*jW>%5;`KCQ_SYq+GIRIh0$}QgLIN{4ul`v^P*MRp2LQr7M*4N7purv#4=2z|gC~p~c!X0gub!x`DozjHajElr+?UbwVxi9*;DE(n;Fz)7Q_h2-2 zC4QNEV^dcp1kMNHd{<=X zMuBMWrdYFd!l9>|aum7;plL_NRYjp^N2QyUIw}FswHKOo(lznvqzq-N z{fkpqP!Mse6Ny2ke4;_BIeq`3W@n`$^CcRZc2>5r49cu`SL{)7R~kZfLv(N_2KSUP z*LNoh!D zoaCw0W^)M7Rh~*PJn4*|dBtTf4E9nQ3DT|@h;T05OYw#w-LS|@#|np@N_Q2zxSmRu zXj^I^zBtv-Tj>GoTyU$mVlQgwwH5X2j9A{Yj`(I^lhu*6M_9dXaLxX^nk*k#el* zh=+QSa{kr1VG!T*1?U9q=oqb)^p62xC+uA1QwxOiZ$p5u+jiZB?k=TX%lB$!P8f*@F7n>JD}}A zN@JZcf~RloaXU}Xx4^eN9p{3Mp`>o%gmSM?r42aK2Ny%BVyr!03)N}*&rl+B4z*|# zruf3e7MK#I=S-G3q<9gg(2PQ!qsAaoj%C!e>mVfxHaEvTgLJ(5Fo=MhqngHpmCG!L z2q_t?oDww3fD4<_CpeykEAA?o#u3VXHB%6w98fbWhYCf!#i}7KJWQARaDjnG6#q<7J87*xNrwsVhdG0phcO#bcCV@}js%@-EX9TXdM9l*i>`Nn-*p8R3bsB#r$S z>G*6MWvW~;!c9EW>8cS{8&8?o>qa<>XMArM;a8q%cGC!>Cg_zuoi6Y3ufragpwxvO z4tQ^Z(m@Qrg>K|!QH|?FvgbF1X#a^c371f2_e8~+nZ&7?8uam9BGgL%PDO%)!W*6`EH;>&eO}XiyCo^7Ko!)G3sVtB$cetw*;fc{;Ni_KKs_ z-vm$b^r{)QoJ#Xowh6A}>DLPQb1E5=0}X3CP3a2_O>ycps&F#Lf@wNqGK(iW2%r|- zV3h&~KBmH5$%QYS;8B zPtSB@Ld!OOr-KslJ|!u!)@_brC^c?sthO-cEoiT~ws`!lL(2R#a`{=@z+;n@Otxrh zq}G0}QdO$uL@&`0aJ8%M%7Gq?1-(y@LQ{PX5oa_{Ii*r?Wu6kDW?IkJxt4eHl_hG) z%muoct^Pt{tzCSiHgKV0F7a*nQH#j1lV!Zb)5bD3UQ8+7HcaN}D26W=lOvEA1}>rJ zjez@>&~r;b+okk;TcS_O((_OW-}2}35_&G9bf*Ds=c$hYYL-*j<2Ef4?UpO|ncvSJ zXqc+_vC^_1*f&*iQPEqGs&frRsfuGgw|M?K&nLRp_Mf*kX&Xcrm`24%q6aG8?0D%9 zOhv^-$d+EnQ@@7w1qqrlRrO5M!Jn5#Dz=Dv<)$ftESEC%Rw%YW^G??liie8A!WEon zgl3nON~}>np`iNQV=EQ<@Qf)wT}jTB%c%Y;C58D;Ct>}m)WIoh$tC2kBEA26q7j;| zCM$0^!3d}E%(=-%_?~BKOf|yLHIx|=Pm4vK38aO3r?r%EpKgTv)+!BE(2v(D?hsZE z>#tKfs|CZ?5!ywB?O*GZbhX4gT}fh6;Sao(u5?pNY}ZqSVwDhyiR+bEmN`8#b)({f zP8*a)aH~6pZct{x-mdtJr%k;uY9pn_KKO>GFZ?iO6Qz}V;U}K955S3=b(7ro%`~(- zfqk`EnaC0-6TXF1D4jBfTa^%IGehNoJzk$o{AAextb}G15fSQdalF53Ki>GKlSZ`2&+F1BagA z+rOyAsr%@^L+4uJcaUp&Kv*2wp}3TbfANER6oX={ltvz<%1%IYu1FtW>HN0_`GJ&&HTWdFcwVKT#3b$q`@j|yk6mb{GeUCCz zlnm0n*!X;pGKU4xpuawbuwbw9hiEiR5l7P3_A33zlzyPYKE*+CPLT z9Z3?6t|g7;s-2@%Zj0_GbjJ?|GO3L` zGZJrP>KS@g?9gv*dPosrwBuoAk>KM$sD91)@nNz|4$mP=nJwTI>(IHGrF0N&e~K44 zn`bL$nGFq4lC48Sx z8uI2xoy8wZI(bCt0-m?=DphFIinhAHjx_kF(uMtX>jy48L3-kFpFWUy_NZbl8oB6J z8tj$h{U%E-NADtUp>yZ_DkQyr`tFp{jy29B^xo6f zLf6x@rd4H@ZIH@8elYK}vK?w)!PaM#j-rCTv!Q;ue)Sn830hpnx@Yw@rwqiG4(6Pt zny#17?3}*l4B^DT3pw_j5)Way`1u?~66!GLs1N`8ukU$f5=*)G11t6-G+v(9qjAAN zoL>HML7B%kT=;y`2VN$-dU*y% zT_)epHD&i@B^)}Q!Noo3zSuDj$rRgPA*ZFX?+@JvNn);0(6;LIkJQ6tSXZwo4Mepa z-G1U)DO2=4?eXdkXJ*kvK%j-%7W`9Cw@NU<2x*v93=?7`Y@#uA> zzK~#uSlvlC$o8uo$IdtOEFP$PXKU6CVsSn(blnYQCkrNwd~W{7SIy=a;s0P%vM=?n zQWL#H3~R8oV?Xf!u=XZ!RTb|a@Z}yj=jI0HMv6+gQEF0Ht|=(!B`=CQl?$eYl_|Mp zrCwZ6uSim9W2S|(IdkUZ-&I?&%fI_n7vfo7&}mQbq0@gGfgMcAWyB^Owv*X|8pO9ynj5>$*ibXR`JLi+86d)3O-mRa66TlWWcb#gm zioJCnN|nB$l!d*80d~3tdmIYonT{s5|GX~mNV(td?s@1o(c@fZ!?x7)WqNnU@8C*YDG6vAKWy)aL4N ziWg}K)#42zK4 zXw1W3ma@WFm=CG9_4|2J*r#qo*sXB?z^{0M-{X#c|0gNz#5)l7oG)1Z9Vu+TyO#E*MT|~Eh~jP9t~RH&=u;i(C~&Oc=%y}^g>H~ zzBHasWv5Ggx(l89gYP@-RtjhJVQj`8iStx5N`0PJ1|-F?8>Mcten7H*Ey-QhgFj?# z{(+ib`izbFM>4SPALwKI&sd{-GGW*~B+OaD@?}E0-+dpv9ro9!?1KmJ1w;Dj*$;f` zdl^4i%>F79DVrOsD$a&m#9DZ%()_E1!?fCB1M&hdwZ!=A$84@q6@`B`Qr=k~vELM# zQqNljxh5$r#7CyQ>qB{teaNh;8YXye$WGV7NOn$D&l{7H+0UBH>T9B`T^F!=kBAiZ z$|LGAB?kh0u8R7d@!Udori$8A45Lrt(_!=#jHs&Wb)&zHb*ZMqZH;ZH@ZzPftfq#0 zDN`WOR6n(4dYu|-Pj4(hOW6u9G}hd8cyHP2t=44A9#v<>k~8RX+Q;| zKS@DzOhtCr8M@hIHlmi=$(S*NeNjslM%>9-YP?aM!J=!+gp}Gy7?8k>byR5zFH+d4 zV|a`-vX0uv_?4Aya^CqAOwbu?b?T}ejgw}xzID~^g7Kw_cv6*7SB*AWrn8nz4Pt8o z)H=L3y;u)*ES<)-*OQgrtEax={q{@@5szo%fTl;@u2PLz@#u=@{?cE4#~419J^GlA zXtmhG%O*SqL?3^^c02E^l>%>8ABbK{z%kG|qIKfsS(aBHh&sQ|>Nn7-eXocQ@O;n! z)aJj(4mj`pAR39a4#1s)DQtRx#G4fW2AWS{!3||Xd_yQhAzE=$L)B)SJC${9q*uIM z;R}{Ejnwazlm&6DaiH2NeO6=jY45;Y<4VhXvl4UQBRBhIUDi>Z&rza$VSsJy_i?@*5J%_eH@$cU*Wxs61h`8H%|4HnHr6qw9gyJTg zpb;cR`(cne%J}LSGROj$-;=6bTjAJx`cz$?CsmAI$#Lo9pH%02DT^SGvZvG`t;*NG zF(i=IAG!;q$}nA)wLgqwb6cw2jq~5&OBj*$A?%9 ziA=GQrC*TA*kv^H9Rw4tZEOAZtCFJ$twCc+oT~-%Co*x}e$X1s-F%&`SXiYtd$1B8 zze{*p=kRs;F}|l&cw)fU$){DDGW4y|Pg9ULHuDi5Hmi*qD4>j!JA`xFsKbo|MzR^b zwc70YVD(uSK_rnNk`}rP;(m-ShyxJBqF@MO+9(nPH)g9=^K-5>unC#J@7DGiuybr= z1(DQb`F+%?COtdLeg=#^Gtw!On#^y5TD7Wv-;lMKji`aHp71PWm-H$N-2$fY^}ipC3WiuNbd>2vIvJv4DC#1P2d{c-<)t6PwvqtuF?Qw&)t?kjL*iwXfp8 zP`()P!E@?kL7lryO4iJ0frP-XkDimS^*&#N)Umcv-fcB)*bAC~*S$F@^LjcbOoH0PZovOWK9 zr`AplmgdYh9vi0iQSu?*oG{hZCmBt(xBkezMUr|7@61#EUA!{` zL`$B66vl>gqszhiIo&pgp1ojp-2ytW7vJecT<2 zC7huj8`NDDUc~9$p>1^HjZFA79M|`v*~{TNNAF7<%fr>W)dzrjQdC0H&_zj;RtYCw zK{y7fML=^e9BaJYhy+KtvHU5)YWuM}%MHTWTM=p-Wow^OmKLeht&I=pM&t=|K5CtC zTYN5B@>B%G-@XrP)I*1~TtXVr1EM*O8sG1sKC9IJ7|y01YTGUr)aBB7^Za?|&97+u zWDu^o6>z=QjXmBIis0Rw_3NqEw?o#qxTo5&<|udS$Lq1&Zm@W7^@P<@2nf~8>XR<& zc8Y3g@QFM3!C~ZJXuvEMOtDj8Z!5bjx z@t529H}(dfFZCebi{SHxKI$mt$B6RDM;adis&L0X=z~$KI_{Uh5%F5IE)BdKz)g%* z(a01RUe2+~s`ix=a+|*DK=05<@IQPMPF9USiqorC_f@4Ap$Rs*JFr#sVqf(|rAc?` zWr*yj$~Ag3@jAeV{V+s@LMlJ>Q$MTzRH)8&0g?vycN0_u394X`yB6(vPA{=&5edql zo$If*Q#yoIlor>Op##wNpM-KDi3W>O#Z=vBAQ-*c)k9i+RPo$tH|`sIb|tM5;_WjC zq*ios&c=8kIY^gYf62SwU<^_T;Jy5b)@y@x0pTNxhoWG`eLWZg8u5?!fYk^Aw7#?WxSh|8)L`y@u4Q~i~WI{O(&Z~l_n-bJ(CCxN}a*j->+uwKHv zIF8MKN$p{r-HDHdLLdned!3gt;ut&eK~XI8W{MVLbR(f7A035Z_Okj+bpxuYFenaq z1&TuLIOP>LSYHyX!JoRr+T2=)bp^1FzXEBu>EI&V=(oIU)FbmldOJEhjjh$P1+7EW z9?HV@QjTYbsPduI*Rlm04+X2&+mYukfXy1J-^R-r{K%_p+*bOulg_Os!}R;#NqGz( zhWi_yFZZ&lIILck9lb`~d?E9(%cKT2)lGVka)*K zdlNIgVM!bdd{Z5*j6x*oP2ewf$A1OeJu1WBgYZA`nLB=4BZ0r!Qyf3<&ST$#{1cz# zxOqa2F-SNc= zK=98z?xI^O1^Q_dapR*vm$q6hf!CgdJEe^)w$<07tyWJW-CD|Zt1~N|gti)ht0yO` z?M(9sSW+^!2GBF<4<@Uw&!qPg^hZ8-hyKT-Z2e?-&&D)jmnQ3Ln1lEvEG?#b;mizW zEr`GQuKJzQwV`xxgiO&z{ktYkR+%zIeNPz~P|CLZnJ_WFr{6!O35P@P_tf`{$qm^4 z_f+{<0Ee_u&ujWVZlu>|U%oG!{M7sETgs88ap_SXsMu@~@Oc~?IMr>Os$v2gpI2bx zYBhTD-+;9_12_DRscH?y<}aUaU=Kh|RytLGbmJ>uXKFT0ooQTOk9{*uZ7I5T9r^as z&1q^!B@`96nXYzLrXn(Sx|*O^mcc}v?$!_56O`wcyGwL%71qWIiC(J1##kj+>nJh? z1g==IcCS|lX2zp9N_9vAtORnzTN7|U1^2TPa6i0uDZ5Yi+sx2CA>B=^Q!;jdPMCof z*|aP!{o@%bjvRgWQFdykbm2CcrDDt45fBNQt-j@*>j%T6%XY8&?1$O@*)f=eAYIX&S(~B|nBf=M9s54)LLS5vQZGAC`e+`-O6i7`sr-R&qX%OMfCo z9Rw9x9>+fT2+M+#UZw2DJUG0*|43cYtq{%Tvg#W03-x#Yf>*_b*H_faPkiCt%6IOR zu#Y~5I~JejfZMq>EB#n5a;kp#6U*`KJpjfV^@agol%I+OUW^`%8{ zfSoQYVUriDp+fNAoA@zK?9avOS3*BNRlikQJ}6hWRX2+~e~4Gp(tli`w(wGx7MHLSU#SfOrWTh_ z^9JF;8#%?^#-(sN-vgQ2E3y0v{Q_#T(#=7k;RLX4D=Rd7{&`SJP7I}O7me7TD>2lJ zxlzI{uT(n-6QCM@XRO;Q*kuP${RjtSv1XOtGBw2KQ_s-tR=CZd&-PfY-}YlSZsX1C znX6&-ExeBApw-nL_88FLt4ml zn0P5K^&2vDFPD_t(c*S2E4%@ZdFZ#0*r7`$Y+*W{kbnNI&eW^&qqHaJep}pk+R9LC#TAYsgm%f*F%e3#Ir4ufcFuy_2 zs4^rA0emO~&}9RP{&F7T+ft<#`J7E`;U;|^PLWbLN10k6(=#(MS@uekq{pR^NdyMh zr>S?9$%*J8`yLTX^@*El0S*Sh(g1dOv$|5r z!PQ4w)b@(^SJ)K2#jUGfBEDYx%AGIkVe0A;c#I#RK51-plC@9Qrm=Z-6s=1*gQnu&%}btfynon zYJ(@ry~|HgUA0%b^S$g>UROP4+=?#Q=`UVI{hEc+-FZN`J6ns&(uZwT4|#j{UJ+U1$9APd0Z4x-2~?|7C~j zg?+cUbtnt1?m(nrw%WA1|0)nkN~R}^NjSDJ$5@Ar%*HS{U==p5W#jSckpt|}9ISRn zAt5qHeM&Ud_$vHOmvok+KI)|;;NH4ibptOoY^NG$TzHu6+o^UHnLnt)&v9o@?NSSs zb;w(Nw>m~CKxFD}b+Bp<<$|E+P5uKx$dQ|;X30)5<9#zNlNbO@V{Zf$< za}1_1-TLd8I#)x)kdZw}2VQ2Uw|d=Hlj-9J^JK5a_Xuj>4vX7XZ({!o|kNc^90 z&>s07Z;Jn^zROek{iU{6yf=WSztk+A(*3yFN7S*)z)$^VTaK&ejNfLmWhc}j#v$pf zl)?vFSjgTEos?ftebdhNZ|=bx^qg=3K>s{q{O` z=qe=lx_VL6Jy&cV3@ldDMBT}9XXLeF^(m1hMQmPu{)QTEEM38- z-hdIFwSr~bP!qXiLT{=mwKlB^vuk=PYNj6u!KiEuiq}OVnqju3+O89Y{B{M4c>By2(v}H%g#; zwKvAG7fRIy;uiKF@(Jf+DMp30xb@~g>M~K~XJTXDQ}@(Jkr!tQ4!wvWkKMyK4@rM| zUyUvwAY$&T-2}AzYTqYhE0MX54X(A>Mr@KKZ^ds9)VZ9* z&@wFT&!@1{We@~vT3kiDt&H9jmu~dZ4tpDm=cga_(VBTH!65VC5iQg>CxzA|5rW)d zv575xWfjfhrR1R4&8pfyZ)4T@Y@44JWjy{Kt5Q>Y*Vx_0X4TY28%w67U#+Rddl}>A zvf;I~e#Ve@*^jlfJ;r;})8DVH?Kjr{C;`d?g`;mhC%VMnOGqDDPn)YK0|4Y=eQlBP zrMKC%2HJ3C5fV-{(B9%F^+p9~U5qvy*b$(Kq3D+Yt(}sOELuY?SxCDIyPk$Ye`7=K z9p#5NOIXwlyaw8}k=BL_2HGHPXf!x4pp{G}dIR_{(z*XExTN72_K)glD7V zwZ^h!V4yacHi0Y&)C&ZO7Y$iip!SM!{yS{Q<63vcZ&Mum>Tzw35{^jAC$tg9n0WT# z6I!ei3Z=O5gtklZ-;9UL&9Qmrwzj$5TsSeSC^n1nzV_Byb+6#jEVj+@GTWBGo zVVV4_-o+LgS3njWq>U+`uyzM&NybU?v)gpt(g# zqg_jls~U@K2~p1jprtLL3I$`?wU(M3mv>d5tBs)*h?= z*K7I+lZw)7T5HeNUxp+;D<{=?V;W{_d=j`SzHa-{w5ar(t+gsfC1-P7dRZH-nwQCx zj?Q0*g0-HZmfM1N1)tGQXh<<+VN*PvuYgb7XyX+HN$K03(`p)xO9run?X(HTU9qft zdu^KHpB~3{wbwcsn~(UkgZ7dre8x-c^_$i~yKc-F&c=4s@0{}zd;KnV)IRo7nx@C4 zCv?`{f}Ms6uDzgL^HLn<64rNx`WSO`)k1js)1lfx^eMob6Q*4?epH)H>Zbi+Y#z;` zyK4=NS~MHiUGo<;e=SZnO<&y|$01Q^)-^&~=;Sp0XoNP{OBn#r!9CHx5lIg+Yt6h& zQ*~JkjMUyS_6}!xky@Cb*-V}Z+4@E8RpVw09M$MjMEcN+Xto8QRkfG)K0Z)fA~tfZ z?4>;}N`{EfNU}4%w6V&q7fV>5Agsd1TC~Sils9BO&&F*;2V8H#?I&@2#0f008g|AW z#}}hCKVHYsDD7k8z({r@N>=(zZ&bPrxZmonz2ee_2m5FZlpKJ$(nl*Yj_bjWMQhlH z2bc}|YWI!zI{jH2imb02kCjgRD>n+;~?#p@$Ki?H-kl9c4M%%S_uIC&tkN$ zN;o2a#h}K~h`joemQJe30$$dZD~ph_{bdb@OQ41>uV_oXly#JQi1s6$v5+!U3lkDM zDf-g&p_*OE%ZN+=bC?$7B7`cjS|=qiGme>KwY{8J%@LYrRHh=S!ANbNVE=jfRStEO z*1=08b@gV40yO{hVXtYSLK|1Su8nh{>_1v-rQ8FVo};w{QD!D~fo*|^E|1naD}h_% z(w}-myJJ*RGvm^mjL|w8ISa94fiz|-Eb4fzC7V1>t7mM{ge@GWy==T3$SzaZwGrzX zkMOs~Y$b&k8?!PBziZB3c?V%xJ(f=4tY)m%c)H(&jid1M#_VSb``}%S2?!_DXR{_~ ztp&J8aTw?)_(a2z2^x<5XU$lfNm_g3&}QjxOwz27?w1<7JX!0bv<0*m-qmu9@4`Ls zF1k}p1J-DY)<96{=ObSI8azci$;H|JJ?(j8bA8}2Y_nnK2VcR7@1wN3q>o1#pu6Y; z%|@kI;8YA=$C2{GRCGqaZDQC-H&4?pc`Hq~VY~25tsn1<^Ji-9utT{P+cisQZ@M;H z!vZN7nHnz8>a%8v+7#p0HQASm^8VRGZIqYszArv$BU6&+QcC|C?C*IprJapvm_eh{ zd`y@TQ2+V5@>W;b^x<%lcTCa>mD$_yQtJW@-xZ2Bu)WDrk`wsRKMLxRbV9h^Aqz>@Rq{w@v4tA0vt&zFoGDJ?_bg)k;;&a2nZZ3mX z6B~~&*Cq(PXJ2T0yc9dK4^P!XMX&pih4xYX(|4q5CZiGnq$(y{&sro8 zU8%M34pw~(%#(-xKU{m*yUjs)o$vT#Jmcs!UIxlXIA1cSuXb=qbn29dVw zwN{O4UvSWroMYY>>W9?;tbD|iLW5}C<2cWzuh&`_e?8B>rf|)9mcL$mLUunq+auSE z-}f3*=Iw|}|Mq*$-z4t+r3u5JaElhB*m18@y4FwQa8t6hu`YddG#*9Rj^UdWqK__H zqxaF+EWF;Ijgi@_Kg5@pdT z0PF74wu`cJ;U_qbwZNTyFjIKm z1>()x33*z85}y;tKF-t1s{i=5d*!gIzazYw&EEJOjkq|Q zFDulEZ@3w`WP%hE|h$X z7S9%Fy^Tk0Gd|{ zwK>KKo7mYxT?Svt4-R%Yjj@!s*(%{_S$G;^c=tzk>a^so@fmHua_>6_voy#1Q|ejm zh~fvVC(dfo#uh)YHs@r%ap$BAww=?48#|`4fb+T_e-eUx_dK-4y1^m7O?dUZ)iYctU zj&&QMwU-Uu*1TttGF1*=22%5&&^1SF~6`E?mBMHscB=L(+f~SF|I> zPrhM4UWJDC`kGa}hVbt-Y$S!BuVLG+X%;1Fjl+39Z4DN3U8^PPixtk2QP=fmdR2Ve zVDoitpt0i$R;?Jl_TDO-T&W8!Ub3^fSPn=RinVb{*-G$3o4zL8z$$?^_`95yjW@9R zh}}uYQ`ccFZ)%GK7dU68#*cW{>+DUfi%7u|h`+tt^>1y3G798Ybj0Ip$KP;S1gu~k zZ-JTJsqAA4$E31L6xL2<-EJe?{v}&_8#u>)$?UgvrN|{l9%JEmv}XmLU7}$YAwk&$ zk?y~PS)s|t3?Fz4GZuctdfWwxoy*yxyE?1COJ~saySj9aah^gQ=&=VtqQ66XMH#RQ z2BJe7!y6;8L>n%u!?FFe;9psy-8QaU#+H_%&kS42926RsvO)g<_}b6d_Y_8d#?*TV z9ZT4-d+1XJko@4DHo5vpd@xyjEh8y$75l+YsmI2~;KMQv@9PcNO04{Q-`8i9r{&83 z%ljbcyNKPruXQ*6^a;LYtkpNp-bEkp!50%AXq}DUeagOjpz|6k*Z*o628*?*zgd~q zp0gBNh8}nTDXC@fb@X4nSTV`zEK)cG77sH8D8;+t7Ed$1ri@?YU{$B`kHyHrx{q`P zboD|u!|pgX%nSKG`ouve?>Atly-YGAj&9;+L!c2E1CX(+(X?3z)5_B3z!&kTV(Kpv zW{d9>%u-Ar8{2%s>Uo=@m8&TZcKQIgvwE948b42A+mLFEOkvf15Z+zLhEuqDA^X9{ z)WbM*AuI9GIr&0%yjWT{dlU3DFM){ES*Yq;$CEV{dlbD%LX{PbY z65t+SGRe+bAeWd0CX<|^Pbk7OIPekEZDZ*IW~pKtVq7<$eM@2Q`OH)mVX=+9PT|Kk zw!5lnkg=nU1ynQDS3*I&Lp9T6MZPIbkq%{Eg0@IVScIr` z?pnm#isTGRo=(Yga}ce@6=rT8qTwP#0cCiVXRsqWK%_b-bs|qSp>0NqRDVPh#`Dxb zLc; z@$8)Hn1|>(kzomC7|k=JA}Tpri)e<(V9lT$@jOQkqLM@&qIn`m0cCidXRsrBM5H<> zbrerEK$B!K9M4yFPGrD)N@WR?d4@nlt4j6}EfyK*!=DN7TX_yM;`c;y3?)zDsj-Mk z!lM!O+soT-3T2qeGt5IYK%_3A)L5RHil{8M7SUjlA%iju;~8=g^%Z#XtcZ6OISMF8 zN1mgwJck`oi^$-h4DERa13E!1K?2|WDH|d(;6qwv2?KbBKtvyvJR=$}GPI`*{dk5@ zk-&d4>c;WgYVnT`Mvyp$ul8A+lQ62hWgm&stViQ;Gt~`65RFL@e z&k$IiAqdfG`*v7qJbhu4CM&rBw`WOC4p#XkzopDc#&tA zhp0uQE}_)kJT(>3I)d(6L}NvU49Z~P8FKEIS#`pBNS-2c6i|+6o}&;^Ny3ikJdwdc z8J^`C3>c>*G!vq!B7;Ao3Bf!=Afmb=AetsJw5JR&BZC#KkN9qp97Dm@ zJcm=T&NU$}Nzj|pp(2MrqG_UzKtyGKrb9xbMTTHRQx|YP+9N7alIL)U$Y4g)P>)L@ z8c{g_#UMIbWQavH&noH|jkuHqJ^Y_2a!f(g0HX-jLPDTFk?Kjd8HFiRd6u3_aMO*I%+9cXU@3;=l+T>@mK*&H^u2>@Qm(9U&0u>@6-&9|Uw3Mw-1^KMG!kNtwxQI<_JtXqlyD6p9qz!dzj1!h}$2~5%t zTcSTNfT{ao3p~LKU{bHVfYp=j8`Ftx%rKRg@GOwS3%vjE1s3uGnB=m;tuAfxACeu$ zOJF*ESWK;X0T?C!qX5QV+1mG}5!*0W{znOCfuDH+m<|tHU@0#EgU6+S)dB(hs|LQo zOTYqhDe<2L+VcXih#t0pRpTXKB0X%0qf<#vFo+(uz-nFqwo+vUtd(`ViM#~t%*sks zR-ijC0Q2Wz3p~mTz#OtZY>Cq!5Zjot9=1RlFA(!T3Rqpn8!ImX!X7>S-GDlf2?7l29lumu+L0^MN$KWvFnyaX)5hb<7o3&0Bf zj{;V=8PCW|z`FjA5^eBFc*X-}4s?DEoIP00YD?n~c}20aPf4b58t=;h)S8vUA|%noi`& zignFdS;m2sk*vV~m9Z6NB#TpI9K!1+idJs?xYVssPO>~J=B$|U&&kNR_8~IXeg=_J7N%XFN9v8Ob>PUm3Si zMp|l!jH10Owj#}c_Kzti*})=bth040%KQyvG|$*gM)+(G)e!WyArpEB)grH-{j{Gy>}TKE(~*{4SR2^MEZ+)i7~?;cAlK?pAAjL-H7D;N z2f$Wx!J2J1>;t_04d#(KG8xa;%U!aP{!Gy4&RWWY#i3r*Y};k8TV5J>sPqsR@tL#^ zKxxc>275Tc`)i^%_8NDY^+MwB@X}6fywB&E-}=%*scfH5V~d4Q!Xx>b{gtqxVMB)Q z+UN7A^R@xEiQCJkI0#GfYVtr@Y!`JLk+$>ZeTn1%9L=4diR29-XQ$ozo>v6NKz+ziXP7;(MZ{bu?hWsOZDK{&}*F3AR*xa(vY%7ek?FQ3CI*UYYv7MpA ztbYSXs6XV6+4iTs`5sEQn{B&`8iSqe6tReD#Otqun?-WJx}OsC3Kj|PN4^*)?$IYJ)#_WD<^U@$GS@jJ(OQnR2^&b z4kF?TeOZmlpidOgV>$E!DRfef3PK;2?jiJVC337hoXDe5sozg=krNG$+$uHwsY;>G7SIzo^kNCUv4rk|{K{qzFua&=&~gDIEDdiTrhpm=)B; z8sZ5(O+v@g)(JfgwZ;qR8HjRqF+b3Sp2xB3$aDCWCvu|UiaevLKlIPVgCmBQMFM&% zhi+;mhL`n+J)pn8$wTNHC339$oyhZ1Yl=W#fG9`4@V<`RYUf~e=!N{s6FL!bg?Z>SOvQ2^|gyC-h>}nkJw-5arO1-qWF*FvnrO(#Ldu z<%yhVxFYZ2jvV6;AJbO}=s6sEpoHGZ6S}D!x{iE{L=G>O6S*JI5fd1(Z9?-W+p~JD~ zL>`S={eI>HV+^7k`FEu{^3fctjy#rM<@j1FS~5h$6?%h8p>G#LFXqU@C2~Jc{eI5s^Lr>sWoTCP2GNp&u8}gE{nx5_&6w?vA`oLdQKn@<;W8x@(Dk?Be%j%5A}q;S3-vu z#R=UHXz~Sge?+;^2j0dOU}|N=>c1?F4@537v?zLSIUYD-U(?KFk-S2^@KvM7}W31No3|J=Dc|P(p{V*9koZwMGl* zOAzJI-}ze?`dW@v7kVnc@d15G%37H-12^R|4Ly-xTI+%QutW}D zHrii0F!E7rihy2#D2HBlLx*lBu(NdNh5X7>=tRR6`8Zlzc?dl~AWtLY*32Uk`l!7g zLVv~+`Vk2oPidUUi&1NuK<+@4Bk$ovZX!pL6S;w3l_R(69wZ{-3VjPLt~{VO70`3I z&3c+?)Q%sW4eIu4`dvAaw3{B8GI5KZoAH34OF1^w@ua zPDEUVo5<eS2BI8#@fBU@c^s>bJcnO-A}1QI$YW_)NHVvI4X4rs7$Ber za_B)4`oLTdp+7;;-I1S>$nh-Di98>*rU>K(h;roZoXG8j)#@A>3+b|w*@%d^LjRf; zS03szL?935$lFTf%W^!Bzwwnjax2{F=OlDIDRn|GMy+WAx&u)Tefnix=qBv{a~ae5 zm8Z~&hAZ-Gw6>~%+zNNPfF8=Bhf3&Yvpt}vt#F49rsM{beGpYlY0H`N2VT_U$)r+^cBFlsFp(A(?K zt2v>Y-Jpl^D^H;l4Oiq-X>COlh&}z)Yj7fXmI0@KRx~BbDcv8eMkN+f{usl^Eh;~?JPa_g-|mDatETcW!iq` zTs?zjWFgkoCOBv#XYH-z~o=vGNl&VX?s5i4q8o*{K+*Cp42Qh zv#%lCcA=b~%ynQSEOQ;2$dVk9gEw=8Kg?pAmS=wy*dZ)D`Mu+_{zrP8A4!D;H5VG2 z4%7bI%nVK>F&Hv&(!n0#Q0mkO%?H4rJ$q?gLy>~V{FPGL&e7}^g#5s#lThS7Lw(Sp zw`Z;pop(W}oP>-1W$xxQ@&%2+3N&aZInglv3L0%eBgyCcjZjO$Q`P~LH75_uw;Ans z@$9&~0vB$NaQb%1te~&^Kld5*3jC;oBcD+PS)0l$I4&wEKm`mH-0_J=?OqeZE3N4q zugQSDC-j`Yf>@*52(iZaqb95UO;mNqr`CT^yTYke6V#$BP>X$BP#bL~+zmOgx|{zU z+AU7ZUl5DEi}}~tQfTUUu~)w5lrcmte+fbR=m)+7Vh-x5l-YZnVpBme-W492exPi& z(BD8W0rV=65cY4TH*SYz1`8Sq|3%{kj_GI`aoD{AG4TdrHBPIupp{aARx^nwf%v<@ z>RQ3zVJ`d1iPh%B%z{{I1!4^(v9&~OH6vj){|{gRoYnwAD^1WU*S{wvvE4-MB~I+j zhX0m)Q%*2e5X`9nuDhg{icI!LK(A6^MYQ5H#t0hu6=*b(G>Qq+-cK>8@C`u2X#1)CEONBZ{u zEo>`o7&6;7^BLE+gC;eLZMi>I$_N5Q5F~i5RdEaVPog&Ypq zA7v}FH;kb3ToO47Jnex1vDK(T^+-nb7qRKds#iZ4)nmU{wtw;>!`9%(@ZLxAq#R5u zVHu;3;Wb5Du6?J)%V3Mh7fZ;HJK5pjk17qzpwYy>Cfrem)X~mVdc(+`f>d+TB+SCa zk+yU0IB>#@*=oB11fo4TX8W%vAcrKMjONt(XU$1<)*xm{sy>$jTVfuUeWD*MY0?&4 znUku2PMMRQTgHPImQ!F`Y(kch!yvVomrP#EOC}dnFw$X3s`CQUt(K&QU3f8{KD=0R z0g<$AF66-uI}eg+aUHTB$w3ss2C*H%h-6Ozvld&#+OQ0I6$~IlcvXwjs1Dom3|=@f zpIDDu8n2d1sEyEkXkph2%t4JruT$7_`_1qiM#WrG}$*;?P*jX}p16i$Q4p z5?tByeyw9LXHwn8_?cDcWp2Xpnv*xjQtlbKAQfu+Y1SF9+(K{VaMgUXEzjJHGm>jJ zVf^XsZ*KB43g#BpG3ORFt(rdrPNBvRa!=Q(dT7Q@gTWhZHGQo;ZFe0*R?cqNu*uVM zw&w9jGF1UPGT;7m8^sWn)FT+pN@-EB-#?rRE+Uh9w~tJE-aMTJb*m6P+n_K2$&x2;ZTM((_ zm=pI;uKT+0^_;(bU-rh~1vR~on#*>YI~^K-2?+~*U$!hX`Mx}0p`Y)|Ll*ku_Cep8 zmVs%=3CFZW>oUT=M0ost!Y$pwRV(P?Qy!UOHq;kF^UE}fMt`t zOqW7$M~|z#OZkCbd6)W+9u>gdT38nOwh1dv=_TQBi zj2XggJGGTE*k^1ApbNaO$}eAKGy);(?kq9rP0O)gjr8Kfp#8BIy=V@}b50>-`r0>i zB9mwN6x3?Iy9?69(DpOcn6#WLlt`P@5@vD1E7q{#VZ+4c_>i2U$#6c094=~ssWIeE zQ4A;`_<{)8PGVEKOBaUehNb$UYrGTVK6)?j#6>10NA%uEQX4)|RV_wOMnASR*~PnZ zWUk%Wm91eI_`|9ei{31?&i>&Z2z16->ecAZ<)Y*a6h%;j{T~6cdLXI@hz1k;157{V zfXc@gF6E-t$YQZQu-Hn3gig~S7iDvV+e#s#$QgxVzALJVK@H5Cl*1&V(_WF826E-m zWKJ+lVGvi-+4Vghw^mn$erlAy?VDmnqjP}o2ilrSd~!up5xv*M?J))DFf$0oXJ2s+B6We^KA|07O?m&Wud%qVd?-@03Pod~ zYJ1CHNRoJ2W3{K(8LKO)eo2ePVla`GS$11KU+97NoUJ*#=_nHn;7NQ*ZGU?c4O5An z7)CtZ-h+>9wtf5e@W+;?EZ#&6USH3x=%!AXKhMF3I#W4IE0AhQN+dmuvgJmK zf!`XLjS|wHE;2gX?Y$Gc4UYvI|AxJ2<#(hw5cE;D&zvx zDIXdjJ>-M&@4p39iF}Ajd;1K`2qTk83nO7l=9YFPjgGu~nCqw|X*o3qI&w5JSehIP z%OF(<l7Qn}`t?`mmU&q9yq#D_#~HjJ6;E z+;c;N8RFnO4SYu=)rS{nw%L|kh{UiAZo$}+>4^f3*tX>2dsg0-yu&AR-<#R?qQ5yg znFiOe!Qr;$M8{%#-_Jg|1j4}Euth6@gbYv#X*od(Ioz)w>h?!wu6J2v_5ejHM^TGo zi%9yw+lj$XVzAoA&qI}|vP!dUJPpVu+(l^~*v13Tq}ky%PAuHEV-?-p*DV-p3A`lf z5U4KK%pODXyR)?=C1)j*w06*J^DlF-vkk+RF z8p^AZCc(fAi*0DmJ`$e6{zfqO7ZF;rVv+{>nUf=s;cmzs@{W;T4D&ttv`l=a{$JiP zD?0suxX0q%yklmZYBLWg{tvxl)~3Qew#dyrW?$8Tvq@@L!6#-;n&xNU47DM@Sbuag zEGtO2oJ)-jD1$UU63L~8FJEeuuQXhYcdPIS{9i36DjM&6l8C`nR&Kmg5+Fk72&1*E zXau4EKUz-w&(#EV7JDAe9b$PyuToN)L`0G-$_2u*Nq!N~(&UJ=uzt~D{lfa`HgZO} z6E>`$eRz;C@G2O{ypd{67e?|hkb{w&=3*oZ<0W}V{sXJiO1@EUB}XI(6M1tyfWW^z z4_#u4h+=dcxWr*r?slg7LG$Io?&ov z7^d*^J4x*)!H6k_Ih;asgxf<8ZVq1}ucIxI8(3@)*}*tUiJpV}DU4u#WBNBlDUp*P z7cy?+VM(d|5GFoxg{g@?+hf;|0=N~d-(Oo+X8mR&74{q{n2SBP107kne#xNw#nYQi zW}1uJi`UEzxkNq^C+`>yC}!W@`NE-G?)~Buv71MEG1U&sMULd5xU!-NV@YAew1k^6 zxUw&&F6(O7!LLk(pyCM+2j{2+WyO}OvtTe_L<*vOP2<$a>;N}Trx#wpf zIMbCx!Oh$$$m=GR!PU4(dd8C=gaOOl>z#Eg*xyYMgQr+*?~VrR4l5`j^e3joBO{1_ zW*7T18YC)+fG|P?G=%-%h+w)k)joSYDjLZ@0TpQjhmNk$vdFve)SraHaB(Lu4kVmS za-{t_-UOS8+pnZP7TfstxDJIG3-h&#(|ql;6pB2OD-1VZEw;ZQrRkCIP>^y**)Bxd zth*!e^#xH4W>MI!oVnzQRqwr+JV3c;&xhd|S+*NHX<)ZroPGpW6%`KSLzt)4T7Usj ze9mf?!)wx;=to2kLupt)ZUn*_OM*SOm}t;|XiZM0@hYqzm@w&M%lP(|b3cS&@?|jjECPJ;;u;tvla!3(Sq|f*37GgqeSd}Zch;w%z5>)2p41=X zBd-rthixYt75)#ZnM8;>$Zo<)Pl z(1d@P&^)}IR_=1QG`U=f%RMsps?$#wmU|u!sM}5l6ba2$Dnvs3nBd)7Jf zSlIECc?CcEfj3cCaO{ZBGmf%ZFMNTbUK4%r;nvI5_C?rHa~bciFgJ?Ht2uNRf9!kS zeI$;gZ++Z=ve_Hw)Ef>B&A~*J0=)TIM8Re6O);vabDkpd^?gdoQFcsz1+Y&G?fn`) zY7i%M+=;Nm7&4>qJ|7cd0{=xFaOvBaefe#pI#z5ju+RhO+tkO=#*wyrm?R8{(F6J= zSU4bD!q2jGn=~THhe8k6Ew)P*9I6tVO>;(p**0`7Iz(+eYQ)Z|)Qaq3bJnyJ>H8|B zgGH==9H@uWS`LE{nG$fj!JdfOg`NG*2fDB&Ry{3dNc0(w%(feT58Fjs!uK(~oF(N8%7n=l|JA`Dmp6ZK#p1gj%d za@JO%Von{8BO=n$gaT#+vd0%ZQp@TlJNvoqv@Zl||8`#FtUZBT%{)VaOTxiqPB zH}NFdKJ+K-3;7GZtbc!;Hq^g@y7jlWhWRACyM<5z*9Af!?9<8O$2KP~Cli4ljT`~O zOr9pXjlB;?RR|tn#|J}cuy3(F?@#qWq;?(hN%cH3foWKYolZSZw z(&PIIeGuq&P!+Cc^^D&S0GU9wDbKn0dZqAzWeyK{(N>YlVulXBuD90a!nzy65UsEl6?#Rb2CRLGVXgn;<1 z@h|*R6|VeF&Z~^yse<2FWDd(bAo+a@DrSC5@N2dWM;pc2?d{&-43ikq+(kn$9ZH62 zuBxPg2W@p>I0wbRa2}P$@k$6}1Jh(%X#-b5alvpQ6|yDT5&TyJQx&cZzqhY4hGz?g zqj>`tNQTFL2!?~)8@N-vTLZ_!|HXB6HNO58ShZpwi_R2iu`iUP?HQki8Y-KL5{0om ze2O`lkEe2CGTUCcWq-f!qb^EyhmW%uNgLoL!F@hYc9Qc_HC*~yu@A1IzsJt~Jx3#L zzha`o3>CHyTU6lk*!cr3jwV%H#Pid@&@-Zecxxd&My9pRYT6ZSpOI0|Ktr&@y({UD z1TI-d<53x$Hp>rC;`79(7K$Q>(&!L8m$F@!CE{)A=F1|wL27F%a* zqMF*&WZoCv)Q?^;r-(o8Jc8^=0qAa^-Q+KZN;JZwMQ=geu+QyxTY4FaXlWl(mKDpV za(jF|M_ExXB=MeQNq#LA8Mih)iup$$J9+E;v4tcKD`GhxF=y@S%nb?toE+UN6cpM5 zETU#aI}@&d8xf&0kUBrTEQB}Fa_Smr%VKo!q=sFSFk_!ITb%=CW(o-)^Bj5(#!1Q> zk|R}^?_a+@hIbp;$S5i(m5;QUOE`gIL4Y~~7G?BMT>}#AwKkCSXv_6Pa9~dbIVgqI z9Y41YT=e1R&G;fmD(LF9kwwTK{h4h>v+ZS*y+abwDWr+Y$%@RJxfTUsA|`}o-jm}& zFKDD2AUdx;V%}^*Ndubt znUkO^cYI!-4fUTG1RoKcB=~#N6xNr*|A)GFfs3l@{)cDgfHH@{K?Nj5K_#;^!&};e z8j~P1I-{7Eth7k2e8`Htl$Clgq@2bv?9sMeH0;SId%8#$8ze=%BzQ-&GV_AnJftNW zDW=K$U3;IIIfGRG-uL(ae?D)0WS=>Et+l^O(Cfizf17D9ClD_uP~DG@N=0u2?IbFKdU6e^o&VD?|Q}v z%%$dWmf(U{#eeP~ET0 z<&_tLX{g|KwGf}Zlm7_e8p-cB8aeU`#$f%0!ofRQp>L+X0&CYMjm3BuA?%Mej!rZu zDOhf02iE9w;qe^iKOj2`^BgXBC9Tsy@^<={6M?^3^oIVY)?<{0b`#cZ{CE*i2O|A>QgqlKdXi91WzPcquQG0A8S zU2cpTopZPw)GCaX^6oJ@$><>;r?09vJvl-h{}akKe`~zIXwh&P=-gA9-1-Z7c}>Vu zxWI&`OjihO+z#3?HHO9&ld>?PD!cnEyeOw5b`5u2Qo%3YHNxl-$`FN}n@gtyj3n7#zj;Qn?`YkPiun6&`QlSRx?ddR;J zW>prp2ere!&w=%_GvXcRH%W-H7Br`~=f8I3Z;HlPsLA2Ag<(;vb>V4ZbXTJA9emZS zgjKUx5eg+d9(`Ly*fWU6h+erXbF7|n4TYcV>PX@2`zr=QNw%S<5QbyeVIF>Qr&^R4b74MZuel@T*9MZ zqC0beiEM4spqegdejW%Ja?>oIPKZ^ph5)-=sBV_#AwkTKQWwcT_Q^X+_=Mv%^+hl` z3;W}XW*qK1JVld#M;|l3g8%^y5F_X+f)o+-7XdkVh#MyY^49Q+MhFq)@&MmCPx!Ro zh5<$fTFdZ9@rdc1Sx6ca!1WXi4Xlhw<1EW*pbg|z{=Ew4!Z*#OKEV7Mo*lH{tLR`9 z_^;HdizbJvg74di6}C3KZy)){3fCZ5ry`1?H>3TV>)2eZ!q+j}w; zn!XmZ&Y_z!)S9;F=*-(nv(DrbltVkZ%@`N6LnfWc7#dGHlf7u~uIR4@M#L5WGW7pb zlg?C~)D^E_Y&@`pm0lrNFl{mA^M7~Jnd+w6!VgG+jw*P4)ew;;`J}V9GIOZ~Xz`uK zXB}%ZxAG3joJ!qT@hJ5Tvw!sNbXjF+G2L;mm`fc`Wig4%!dDp{BtCrmZ0o~l$t!9_ zJfgMn!sEJ`=LO^^VyK6PWl_fqG18uguo%`m27h_Ta zfyI~^3sl3RSiTr@yCN2Y+D4wsSOAY=PNi)m>Ns_Ed0wf7!ZU(23cP%%%r?@+XQJVY zVJ3P^5!E=)y{m~+TVC$%&zV+b^I+*X9xU&QKz$-2sH|Ny8mu$w?)M07^+dl;3=r|A zt5JU&z5&{MbeyQsQsdv^UH~7^_@y*g^8$<>`VJIuc6zjtqw0B zd%|ZS)Mw^H*B-t+Cb%N9=>?G+px-}V5E+4NqJ&YbG=oixAbHX9Nz`ip9H`3YKr3wu z@8w`gfoRTGrSPI&Dq3~EmIN(7eIzhhBEB4}vhhnD{3>cxqX|*o2zdE~^3_dw2&p^!TmFY&~UmQ%ygfS%-d!=pE>l@-3tONpPB3 zuO7fxequHNOGB{^6e_6aX0l46(k82P=gOEizgM_Ms>K63P=RzgsFwO zIu$6;!C$L@@}*w)0@9jPKt-!f3&VaeEzHdd6T{S~z>tbT8=M%P*l1#SV*e{AhH-n# z;iqAZLbm3D;jDe!)pe`GeV7mPaq0Ap^Kj<`>lmYG9b@<<^{Iyf?wB+6*SQD$V$iTa zCMJEY^H0EO!V^{qX2V4-%c2PHhG=wxN|R7o6zZ3M^KVgy#Cy76pevd&URq-0Q8gE1 zG)Cj4;akqj$2hmB%LVs3B!pUpxsMH;qQw3P{Nze?58U*EZ)W0Zf*B8?N>b6lTh(Tu zG3C6LswAI=&V#!^t)tgV4H(TrPYldLPsEJyswD8b&@~(9zGnuef|Ek0p*!(u=$_>zufo7m5M&KW%XVB7{wR@57_YeVPOV)y;I%OB@6sA7*hF{n88e3kjRQBud2bE3B zL-oq;E!cI+<`jNqPX?=|>?i(G0d(jUDL~P*-LwLtH3dv@519-FO!+GXe6j}$_yH<} zdnXkCvu%u62P+hB^O&Id{z%y7xr^rhN%2aC=Pp_tXdA;zn|DDp?bC8qnEWhYa1W_- z--8___guo-02DzEieMTq0_uG^-6(=-@oHZnIElSfjcrV4Vp)(GVq!{T8_U(Q9AV?T zdYd+~UAw8Aw_@0F!h(P+73xV{vA956TW~RSZNc5zBDvGL#RVs@xZwP}ZDPCU2GWw6 zyBO_Hqs0Xjf!w3cWh|(%VDpE+lcNo2XnXqWQEkyrM6W1X^l?Pz#^v6NPf9fo*+>5e zYfV)=p~sE|H$~Od#;#p0f?^&lE#blPa`CcK1XUt9D1vGcs3NEpLA}DmrH11qba@01 z)<%mUUIa-Z=!$@PD+Hv`Cm&z%Lo~WceNwbnZC~egh>rvOSeko~hU+$|>Bqo`Z$8fm zx_=qbBu$~86}*F0M1*3l{07q7Unla(3Q7bM11RGBEjRF4fhz~YXgZV%Li67E;D7gb zG0ZvEHg=S4Z14RFFx$q8sS$0zxNWTZdzA2kf_O_h0Fu}dmqg&YRnv|*Y=|@P>>Vqm zc=fhf30!ne2a=6%(3PTJ*FYpuWMUw8p^~FoWKzz*b4$;r=fKlAA;A|$tKkg5S!t--(buC9xE)IU2&^+XQaTdp(#(H zv;qoB(iBATYUd|31$EXGq+F??Jd582RWVMmu?U|*ahp#yB=Ku?;L)o8U5-|mR<9uc z)t{mjCOWddm9P1&uWUXTN>AaBtt67?-%FGP+cZL{FTwVb`E-*=oKOZ!wRIS+dONdY>c7gm#w|GBb}^W;{7;0XKQk%sMjM&h1U!kwBZU|$2D5f{1RcuG9Q|uqER2p zEsgq+4XS5X>r}s9r~2z(4OPA6YrX10Nvi*4xX}c>0C6gZC-CRNJ;cRAo^VR z%m3u_x6-vVnS0=Fu`TYs&?BJSe38khSHqY%=P6HEm{@KZ)v%0qkegPhSqz%D52dpd{#d zE+YVv%LU8w5kT$Qt2yAt@u20w(tra%6lktVWy7JEK(gh!WHTBiJC!FZ)`WPgK}pHV zNH(M3duu@vN+2NSD5Z~^5rl$fk3a`IprI;6l7`B8xFo!ohp&YfQF!$V`b3BHwPm3S zn$3~Y0VHs6szIp`)cbH+iyvVwj&vxc%iaaT!^3p|vk}LOkcTKj9-;&(yn29}bO4o0 zEEM4~j*z}4gb<_zaMLgy!0!kkwnzzp13~~IjsxT&0P+w3DQps;(xi=T)*&3<2w({Z z*ii!rN&?tX4-m(VmgYU;2l$#xuR+9dfII|1g+Blxg-s%C65tjc!1XVMYVa@zNG%F! z5R?RP9=4wciueZtIF$p0{i&BQp&Bs4Y(#Q|JOn}>0w9G~4{)mvU_v8+^*RkI-fEB% z!sFN}A3%tW)TMd2SxJ=f_z-}I;{bUGfII|13a=jEX96GwSn$o9y);yX35TfRrY|%vSRS7b#st}N60U71b8)rmv%sd2U9s)CkjWPc@NSKAcdrP9IYaeIMH~mnLjdF<08)7M04sF>pZ^zhs!S>; zFOPdlvpGWAe@vwgQbIUF4-hBAmgeD#6#;OELk|#f93T$?kcR+B;hzJ9{e^zsw(Ai7 z^kQhKFW~^`P&fhzN&>iMh)#ni2_P;~5dd!p0f;ybkcR-sL;C*G!=EE;3~+}I;Lt_@ zi#b5PItlSfHCaHkI7e;0>pu!;lp zS8Px!gz(V}a&CG|=KjnJXgLFQ=4XP7>pBG7BboXFM;u4XL!jj$&{BBSXqD<+I=Fun zhQh7maQ&_rC<*Q6bX|e}LI80qhX6P*1R&x#Kpp}h4*`%uKS1U09j@IvfD;-4jQEBc z%4p3ZK}i5R=>cNvYAM~bEC4PaqSqke6poPgw?+dY4}p+EKf=EUxJL(Y!waDrOb7u8 zN&@)I;D82|4Y{?15O-_{gnwk{5h9KQdVqU%0NaNGR7z7gLVheJ>I_H; z;kUO15N^mlLjZA=h5$Gr1R&x#Kpp}h4*`(Es{x4mM{aSI4&j_dp(;%00R7(@P!hn~ z^Z;?5aA_Vc%n$%Kr0X?^I1Z490LViCq!0iV?&tq~8Sm2pJmL)nn9TwD+ig%1z&C6< z4gN|1aW94d*j@)v3C~6(N614U^;XfQr^} z!pXm-dAR;UAe=K;uR_FefII|19s(eRR}b)W9l+%a{Tfunr>`(Xg&-w_6Vr4m#K|M2 zdFg(DM{d&tL>vdmLjdF<08;oj02N)&?tl*AA09tK0dO@3C{}EEt3gQsH{YrQh!Mup zJltg=G&nE>AdNm!*OP|;$U^`;*P#3@LLI;_bO0wb0$9QU`ul*OB!Hdt0I|QSG!Iu+ z2!P9NT!Vi9i#A^oLLLGk4}p-vzfqwM;Fmgp8=eom8_0H09?=~P%x2*>#m z{*k6HW5jWQJOn@<0w9G~5AZ7;!1e@C?|&WU2>mS~ND1M$1C56Kf!EC7{_F&N3IpHf z3xpO|ItYDcg`h>)?o|*)oDu>MaSBI> z2kw9I5C|#sBmDbs^AR1utVRIGbAbL@0!jiH3xF6u90z|}u@;RGIr5G=*i}Ipg~iqrkdvN{(|6Eu(n>h^-VJd}Euo;oW?-A+)S3ZOoOnV0eW>udpm3{tTv#=gPqd(pJ{F>qB>dD$)1rP9q*ksG2QGQ z*&tJ5km*uWOqOatzLA1SA%L-*i#IdfL7*!Vk*fg#u7qGxaY3fhO)*UlFr5%}tx-y| zIg^5#Alea;)WQJQhe0k~Qg1eu)W-p)Iew<_oP<%MxV`TRu~A~-@BUJEeH4={A|gDP)|V^@IVc5oOBd3|h#EpnTYpR1;*Fq1 z&ByqPXm)sx5w)%l{^&mg^pV2{V;#l@K^dK6BuYC`jt)?!86SpBnz}_BqP*ZI<=>WU zP>J*>s!zxPQa3eOe$l)4|O?>B6qO1#0)+ziu8%d;A zwIGBv>^qP~kQ1rign>|QSjL=gf_zyh`D*;Mt)tX)EUHnX=IAWsiETVU@mH)OsXr-v zv2)>{4dVs&AtqsUT;GGMiS-YgH8z0nENVp^p$U2hhVM1-2Dn}`Fv?8Wb#jv_{t7e? z1;mm*`hbQC0^4oViClBIXn+BRkcSx+GBush(M<|%qY2d!PHvL$m!JH8X@eSX*VNG3 zHdcZ5W;DsMLC5jiX^o>5SNDP@85U{`SXf8PnHsORrzKKXuD4gjdD4HfO6>ppnbEdJ zM@G}?Ep_@sSS}VkQ;pt1@0f{OP9XoUuD4e<(1I}ayPN3F>!4sk4LBG3thj21O$$o7_sIRrsTCaCkFvz4|NW zamgY@D|U$}qkjmcq@kUhj_P)evgT!UgavsYP_7%$h@5{a1}N$)A(CekXBq+T4PV2{_(<Elm~AB z%FCEB3!q#_DDUy393Fyloua`65sd&8^AIp8)WQ54lppC(KJs{|F1vD+{?U0*63X6$ zau?P-C;^zo1oHtu%(uJim5Dg6OdbLy4}p@xt4I014(0Zl0;NLVM)+H$X(2E{N-!5) z517BBH3%*dDjf$xzV@7!2u(+313CCmCqGA%?-!rV#q;H47^ndyiNEQ3qhhF$F|PDy z@?-S!KhVjKY$QLI%O{tI27*9I@~d!|P|b=%w6wLMjQso3LS&WJF^Uz9YU<#wVwK}; zu$L|gL{i(JCSnqz<_QeL(nVa_YTZgyTWmPQ!r~-{dpFLB{dB`HEY!4P=Z{#uTR|S6 zL9F3L^v8(C##)Ex9_$YP24t)G*|bq_;ysSvJBY0l#TabD(%TXq=r2A(Tv`K>5~N*4WQqv-iy%t`<3x}xf+;+hvjBUfuuqDP<(yE2ES2CY zG7Jaegp@^@P_5nLigtMB((N5ikJ;{V^tb0XL|6+VX_g2V<6yLm4pMPW`o@ue5trj^ zgtnbnDV=}9it`#;p0A+M3v0n@yxs^pgU$WB!#foB<9uyh_%FOncOP}1>9#ljc=K*& z?34ENK3CB2cq=+4WdIH!7;pyHaX9FDkD=ZHRkYjJe!hYnq8Yc`hHFBq@JC6nibjxL zmBjz1495F?_>;abn*UAWe^VU!n~~cs7R@^vHoM$?B&T$2gu4&qZgQr6IqfHn72ZNQcCuihc@mbl zqKbZ5nnGvK&?;}IJ0{t-u68qRJ|9gNgN>$(!A8@?U^w`|?oOwR!A2*isJ)MJw>6D6 zEti#?KyTUUaaERPt7rrHWSnOX$Z4art3=JbPVA360h_^TkGUYCjfghBc3l1XONjE! z>?#gjrObt{aOVdOVSzer^o>WX8lQ`Ui8dn}I7?Q`24?H29!&}yg-017q)leQPFX0; zLZ*qNKm9>Q)^g#e2u=RhEW1Y>9)qj9NV2DZ19Q_!F0N%5K`vVlhb@p_cnip|n%zb0 zZoN!~=vhv!RKVN5OT4S6*290J%O_9>=%}Uhd*E@64zuXJy`}}J*R{q~#-qP3+ zr`Azb@724#^a@A~@WTme&0UnQ5I{;jz4_m{O{Os*YJJslA%N(W28i@oQ%WbWh9deu z2#6YYwelXlh7@|IA)->Ri6cP4jox&wigpKR#wW?a%jn({}LOkYmPa zfA#_(YJAK%9Y0>AygUsfATqc#wyUP8qiyL4{GohVQa+eWeg};`Yv> z@}EVoBc$oskP990rUys!7yi$hpABF8o1X%bQl@N0!r0F^i$peVgo@AztyXt-5;z_L z4m3iAfkuc9Y)~icKTmIq18+Oh+f2MgDN>12OXH$K%%hUU(fL#<`H4~GXf3fF4M%vQ z%|TYM&6(OAZ$T2LL<_3jXG7l>Jqd@{CJ=iOe zHG0T0RN@Wd$5A_+O;1zkPcHr_$+PUZbuka1DWrm@uuuz^XsbgY}b`GaT~OYqvs30{hgP^fq>SNz@Q$$Ww5w-`nLfi4YqR` zbSA{VvE9RVt~s6t!5Olh--@=>FvAwy7Xoy4$XP~ap6+U~xD8N|uPa8&um=PD{x|KZPkBowavm#FEuYNiB6ATCIxORx%fn;p1w zPSG~0W3MJPmg(+t+MatHhyMUuk?up;q+RTSi?sMfdDwA`dtLZdiPZ9m zn-gugLUA*{8t?5#2u3#xD2gj(Oi1fQjFdqG*@joQ&WHcz<^*zfVQm z>wU7Hjc?__x!1V=W=jE-;GFax9X{TBzpLP9sIHvy?dJD_IIJVS!1>|0{N`)W$7}n; zaIU;7@{llG_~ev%+HuE&RV8!+H+DB4#7{^e7aEaO2-M{hVzIB&T5vn&R^ck(Y@#c! zZ^e0lGhz0}=mYQJr@gD0Q_u&?-&#v=CzY4cATD|>82l*20b{6x{GfPyMOZR*Yt-u( zh|zMGYc+kC4_;|+Utx7I+1nHND%5<1PD~Rf|FH;y-T$qjwp(%qGQ6B-T^n!CVn zKif6?!NonoerjMp*bYy3ZPFz`ego330#Y9y84K-gbVn3>dajD}E*6 z7YrzxzvLHysM&YNip?_1{>*~-ojJ-(G*G8?CS-m|yE$HP0VL`WGg&4jQ=_r1k3)@ZEb)L={$2}r*ir@&tM)4WI?P#!7N=QA4 zWXjYl#SYfQe)k&}J2@bhf0Vx1dA_0S)RkOO8rOT^%HKf!M8#lT^Z^=0)G=)CorRO2 zBJ6ZH9(BtF1$smuXtX+Qtb*<4l z<~O2BA%Z^5iQpC@7;sCvwQI!#>DJBV#&qkLinB_FwWajH5Zou3Xiu%OKGPj0OJx?k!Nncb9Q+DRi;3c_KzI(5=`^iulTrUvAPs zMw>ZCQp7D#0#^VsPrzF9JSW}6leFf5Kr_ceQO7SP|Yt#F&gRO?xmaX`&S;bd{T7t6d~TQaMMK9=e7xV+2_}ZcipzX|6 zaOrNXXgIljl?R*5D!#_2BJ<#UYBKFp;^;6@!SCk=b3K^RgrX7ULlqcg0%1)jq}cl# zel;WRu$AMoOEs1@Q%!6~rJ8S9o;AuEUxY7l?9WQJ^{{Av>zKl2=mP z9B@S?T?SdI3yoaar7Nr3s(4ZNGtP3UTLV%PNoqexEyHmby5690d>_@=tY9lECb8dx za~&Uw^UR4?*J$yyjn&@?4Cz!M^P*4n_coyDuiCvD8{ir4aJ$|HMB!5evPFeYU-@(4 zdA%`3H)E=&eIXf0{Z+p`ZeEbJfptL0mwDl+S{fk}2S>FW_$M6Yj=OI(PM3 zzqg@8?$`WPt0U-cypJ?+i5_*IT<#-|c|UM}HE=f?uBL#y3ODnITRB?IUH!Qq-<0pb zUD1wtpOLrf_tM4PgW}2>>+rAmp&O1(-@#W^egb(sw&!A$*G|brp2X!~{qY2gEkt(k zehPkxP2KK-Y&_Fw*L#EwF2^_oYB*eNzWOdcjA~>CywX)<)S<&s@TJIO6-PSwJyzwv z6a4CgB&S!;T)1m=WuAlN?Xg4t~AS=u`z(W)-SPf2&S1AFim{^ z4Ql0<^U!LoXv~xlmxIz$-5Ay_OTJR-aV!cYsq=)?qJUJ|KBi8GR17rp^Cqb)RPVlA zaL&4Dvk~r}rx{%!jfR1gf@6NI^S>eYf(Bca9eA?2&tOn5|2TOT3k`_|Ix5q%l!$TU zqtp8sjiDZ-0ng#yn6~sSmvMJ_Yuo}IXThhodoO%j;c?(nb~qT?_cbP&E{TpoKl#2e z;+S9ne>Jh-@(MU5o#0l$35ij-Zvnr8KFXbl2jiCBk=zmKMmM#Ct%}&XOYl@$!M(sI zy_Md@m}wxcK3yr5K}0#AStB2VyBL{pG2-cj%xA8Ll5Jj_F?E~uxm8sED7%yP+PhU^ zKpr=1e*~4eci?;VEgX#fP|4E`9Z(y%MLEdN*hc!Of^nIKc?ZP6O|XtYhTu@dS(;zr zW{?(;?%8QL9kd*t1>ICXy%$a&h76otp@>0Yj58yl&Pd2EZR>pw-iCp^jTGGJPFLPz zB8p zXm-;*H+H!x@YzYnp`O8`K)Q;?GX?h58#mwt+Rf@VC=9fp>UwH7)qCSGyYb7F9!Cn; zLq0rZpsewohP3@Pub>^rc{??UBFw)Ge`712QNW0u9c<;dqt?_MyckF1`)giO(dLS) za`FJeKu6!US7zbN8gzotZn(p6^6hRKzM->lZFkTa-}n#b;KFyo0a6%;1|&LGNXw1; zqPlW}80w;u5%c)A;53d7vpjSkOLW5h5w{_vw;;l6%r_fBnPbb4J4uGAgYe7Z6PccR+8 z&g&Z-=MOoheM3EAmBZX&RW;Or_l5<1iMbW6TZhp{+<`d*gHXG1GHVTuL{4$x@_=qf zT$1v&Lptf8A2?5YYVtUzdvbCX9g1&vdZs4lq9S5B;P~WhI>dO2(=$0ad$?!76njI( z2={<-BRm79I;Ee6yJw^7OJCblFHbv8Y~z6TRwGg4C_fVAodDd2rgzj~ws+f%n(~DL z?5HLC?4B?a@JHM3pqBr*0L`69&*eUdb9D2o>+S9uw2i0BX{y#v#rdSk-t7x}w?9x!`|uB!otH-p zMU!|Ib6P{aF>TPjY7^Ge?tLr_Z$SGSf6>y8#*`S*l!EIFabq$t4m8b)n-kqaG6cUP zwR~Ek6LVD7HRXycb<6aYfZI?$)NP4&;1ppXK7;QchHH-TLlJ+X$)GeE8eNyfhdslR z!)UM*qn`A=gmPymN2@n(;zg50lhy}Nw@VM=&pK=pFsLT{rH>kR;u{*5FUAJ-1w5`) z6fhmgmO@2}0xq{M`W<5Iup|_4Lb8hr*)xMGR71qfi8P@&bG*~Nx%c)@kpRtW@B3*+ z=b@g2cof}GcS7_~&(!#cq3)^C5zuF}J#`0Fr}1W-OgRiYiSfC}f0bvW61SIJgSj4@ zrM$)AiP_?C$Ly%dBaxU6*o>)4exF$HpGm$A`g7sLZ0ni|XSZKm?!(S*)lTVzL)z-{ zPM&FSdAdJ@)LriGcR4+Mrr4#^nDQHMmyYt(o!-f2qXUOtH#jDwmQU{pSvW(vBPH$Z z_9e=I#G-WSfI=GTj){YVp$1%mjzFZ|_bFG@tO%I}WB*y6;F-!gTo&0QGo*)JfIlB<0lTrvNXf(WH)K|34xTb;zY3P~?gK`RA zn!6yWY#AsuDCzF^Xk3d?5p+CH`EL1 z2$TkO&Yz1f_KUA-QhXYTUjgyKbH+7Ymhj~GiIyn0O1G@GK`Q8CWG}VC{?P2A{VKrZ zs4~iq60N7PK#Y8*r~Yo8kCS5prCG?+ZB&|B5biI{JP@c;yYted=RYaTaeqMh(&P#LX=zsa^}&-0_zhX4Z}<)4vPmH?KvG#1R{*~^3U@|Vb7cIG zKs9=%zBI}Hf{w{SzkHEzUYwAdt;wH~NAgoR(qYgb9qg_tyqc%ClrJ<93V(YBSNPd~ zLE!~ITNj;y1vxx%F3&x1#BsNTXRzJw8Kq>|J=4*0^>(1~a-dDia^cI^pMRYSdZQ!Y z$iIXy*7bPeiz5mW=?RMAbVsw;=k0 zi0}!wdk4Je?Do6UYq{MaU2^1qR}cR!3B!+k$iOA-a!EMoZUeb-c!a0xXx&Y*-iFhYuPC?a9orkE$(t(B%6MBu%D7p|uatkn^Gj!*- zMA3yPl8NGak|BmkiJ}=Oeo}~}2a$9q5keIbToW+)_UhYr}Q;`w~R44rTt*VH@l(2o;qi>^_e_; z$u= zc(+L=ia|ti15tD*84;lPi7L(wynYeIEkx1F$^xDd7{&Ewa-`Nx+Z~G8;r<-0G&%TnE~~QUFz)r8?sR${ zt|WY@chnG6qAethumx%h9TIwiM@D$N$2p}Mm|!JLH>Lyb1*W=a$Jhnc#coct6R9Vr zeTVLXQ*zfqH32y==5V3axaF^2bHE1m|k*M}Ss`Zxlf9{Vja3spF#^ zEDQH!Ml+<@>SP4|#(K|mFd%G>e=RUlQu%lrYuB&OTE`y*@~`pY^T(T&0CfYrUU6fV zpI_$uQ7*yX2K)+I*PE&y#~{x5Dk>@b+7ZG%pFW`InT#4sHzm`}8!+!Z>P|afY>aVB zoSPkeTi)zj8g80_xgngizg?-N9wXKpUO)(68gt>+5tV#RF^-T&i>bCB3U2qoJMXrQ zyH_BD^s}DkXhvwD0k_tn5w?5bb@x8UZ?1E?Em#!i)ZbNyUznrCvIHmYsN3-N`G)f} z6x;y&*xG+fA@}ZEE4Xl^7VxQg@?_#7oN^bC!1bH7Pu$|d2P8~rJDi^8FvkAS2=v@C z1E0=0wWzx)T$O4#0#s{V?p@mV7wd%4Eb-5;dxNO(!dl#0ARq%vHgA%w&pu(q07ePz zw0F3FM3*25PohhJ2Dz*Vt`u}xO7Uv1P6+`II~qypT(XZr#~t`t^giJ7O(8zq<&vlV z$3>UJsf~wvam&arPAmn-)qxmnsaA_Kv8;PNgu!FuNlYroH17gjX9OvQs_`Lsg_7PT_d!kE<%P@MD& z1iS_+t|7mO!$Jg1ucb+yOESI>k-;~$149W!ly@f)cM{R5AW^#e{(~SmsHP!;UtzG7 z+df^|E!{Ms)|q<0YF+eC)F*rZs2K585KXZtK#wRuQQg^1Cp*RZjmF`=Kxgf{&%$0j zHqCerirX6;lP=OM^`i4==3JgTvAVfuh6lSgCvd|dqro>q4HyoFK6#?J*|JH)Nq6tG zrB1+1_;koqO6c%|rfkOWv#=S8SAR|XQ=5qaT~jtgeB5Rp97dfD4D~cRkhua4qpI*K zjwLOynnyEWH3<;cwAGYjssK0WvzHgcuCbRZ&UkSJg;;fM&e7pL@aJpy=jdIm3jf93Kqn@`kf8Nk!BkzHRW^?;LHJTZq<3^+WSxa-Xk*!Vzm9C{($mvB(Gm-=>2@$YboKYl9 zrVq6e-9Z%6(7Yxjh=!&GiFh+agwAj#X)R3+<}J(K4N?UxrwS3FmSdOxf7Z}=|GJ?m zN3O|cctexl?oVyz0Op!oCK;%K`MVk^Etf_gI)Ps!KNCT_ld|7Bnp_zQbdHBi`LNe z{GT>7+K}Zz-au|JggOd^NZPipT3qH;OiM_eZtNWj4EgmZE&wm4`f>faSVPG`dgJ~s zWVDi8lPpkB=~KM==rtJI!mu^{z#2&P^+5_QyujE-e|)OA2!6&*M&2pPdPT+p8Z>Go zavSHy%mv)PbzJK2gT#e&;xamHsYlmz<`s7j(yi`!+B(j&SdXVpcY;lE&s>dypuSkT zr|&-(48tthIi1I}j4L8(5x>=}C@|dSa`#vJ{1%JMz^U6xEJB8kvxsx13C{8Wr=!Ba zcO+J1RMvq)QGcn6h1sj;^Q^SqWB%cXb>p^tItGzLPsAW8xB-|uJ4k;+Z~6rC;^&4L zYGxuA7>wpuIr7^f>5jZSu4{C(FJqsLnlex*yb}~oS4>;+wSh;b>3enaMt4k~O^2ci z!Q-3+4|ZmWBYzw8ixsK3yEWur3dQ`B9*`nAi~Ns)vz#QpD*8S?xOWcvCMs8(wNol*T=Gk>!?}+xlW&F)uVpkIv@;+Ongcn1?Wr&pe8= z9QT-SDJ@OITPzyE`dL^+}v9Bv~pLtzf=qG5;?MS7^!cVJGc3%7fR5RQR2a0 zTpUq>JyPm|d+XWEH_XFKza1i3ZG2z9VU99M({AF~Zp}9Ck(0QD-1X-1MlYMa%6y}g za_}OH{#I`5+qTMF*Ide8w1gc$6w!_ye9wHz_$K?}ee)9Iy)0*q`8w%d&qd#oHRch< zh*dGMu%C=-R`!9pGi&jId9`sr^L=3cL#l!%Lv+7XdiU8YUiH_gd;>o=M;WEzpI&B* zx0~Ct2iKanw}{5P8gjh{E6db*d)S~)%%df|^DX_v>@Wrj!j#^g&0TIzke;8%OX7Op z@DlSsjnc}tjSAVgp1DfRNz(Xv7kwz>3Zv99zA1%B1FmhuYebe4lSH&oxTTW81KKAIYuRlZBcld#;qn8#}QR8_ffxHJ*#i_E1=B-!0|l4Fc$e zO|Y2mto>$lU&-_QMK)%$xl&3)UXr$$Ek-G;atXuJINx(y&0dp~jh}5Q%!+X{V-?^a zGvx^!Vcjc{1BxF}Y3^!zaXovo()^KRS*hu*XqP#|w`jY$xlzgk(Xt)p{w?qjP-D+x zc65jNDQV~4%j~iFatG$xj!JRUPIC)Zv=cfseHj!K#*XYXr%TI@1xalze;0tqeb1>{ zv-@_#P}9ap zcP#K`ci`z$4@;%E_wh!6crEbsyoXKQYmQIP3s652h#RlHJK0@_uG#Dk72&rBsM7*Z zJv^*(uX%`c>emNZ%PR9VQc~T6?8Yi{N9B+?&QOt2<)dt3Lr!VeI&v{w7+a=#i%D;F z+;#AuDl!fx0ba?aUlEPk#c5LnEj}%N+U}tB6wH8b+%$;~dHn?qzIT3_2$JWSP``Z( z+D5j!%Di5BHc!H&?-OG0cmxjElLZ2w`#`odp=DtSbVx}H2zisTt zUi`v*%J@4|zBK>G_;1$bD|3zUpDg+yezo%X4w_FJrJd6*u(uDH*BWnN_kLsk#hA*5 zA4cG01CO9Z8NvQ>)cn0Mhb10EP~Z!zHYb|el=G={Ufv~D!Dlx2-N?ag&bQ{sFrr{* z-i>U_{`0NbCV|NJ)3@eFOxEfkc}XqaKKO(AvN4R_vX)ywo__-56j5=)ye2BFo+51D znY(tW$4m{zkdjK$puN&`u0k&#F$riffAD!<DRw$WK5hIjI~FUyH0Yb# zf^t6Bo-L5sTFK(_qwyT6J;&hr;#~1Q9?!qdWgo@K*GePXU0~nDA>DemxQ*OEK|E9! z&7QnQ{@&QlcTZc{5iV_S7|Q;eD3_ZqKgXsf$)lw2(k?LL{P5Q7izK6IBQqN9A> zP1A8os=Hu3ssu_j+QXm363UW1Ua(8aNm=(Uo*T><(yRS0__Djnxy_6vY+q0LlJQgDo?f!sBt7}lPvkGfy*ebHb3$QWVpz@Kqv9Avhm=ALZk5%bmv z>3RODTD&Stm6uDyx?N!R43JYy9~HAg3a6iDn+M39usZ(&J260>FQpY~A8GeMxvgn! zJC-+CPGFk`$`g%CS@IzHqVZ0abSog3SjDY!q3QTVc4wOGFm*|1Z>GrurKkUUp51o@ zN<5z?uQ2}Vd&wrZFh+d;j0R=7P43B#+$R51D)J{Zc`y?CDV7o%Wm*->z8EYg8n?3F z2FvwE5Bnt@Y4u@CGmuv6bL_eyNNe06Hf@NUobYWcc$O9JnQ%<0rNc+vlTmBKMfQtV zo@XBpkv}kA>zkZO>Br6C>8tFaOr-ygUG8WaRm}F-iiBl!Go zrz~(|GNUVgqY77HqhM+J1!~y6L=tR^_pFXJc)}z04>h<8=m=Uru~QK9SAiyHC5Vv- z-Q`Ei@Jq&vL~w*{Vt{e9U?iGgD*t5JBjjGg$BVe^khqRQXdYhT6J#ivB7`m=A`SUu z!AB%PnKi6>gxq%cR1vo{)VR+gC6XZ0-mAz$9^OM1Qm7+dFNpc8K(?BJ7#30lI&LAeMIx*9 z7P3_^5=}6bJ?!G`u#jCM?qEpVvu|>tba^SakOe|$JY`<9kOP8`NP;qlv!_SNZI#0! zj?OO*#&r-fbMcZ}$U;pUI+@=KJ|YS7{rK-#!^s@f=2@sxRMPc2jyl1?Ujr>;;)|?smbrs6aX#0k3KerZC=@xbC6#O1Ob}v;BnWlKO0t8non!||x=bev zV*VE$4%mI8F#4qg+9q+M$05=f=HU?iGgD)$qkC!;GXyhn;>`D5kQN*_VDAcU^H zNT3ogxlODV2~-i0mWu&`k4S>@e<&jP1yi)rGmz#q`gB3hUj;II3PwJ;8ep8moOj5*T%$!?VMqz}6(Ia3RHc(OUeNPb0a@XkKBGT-tZlP+_T3$F z>$u5+Ekgg8!%3@ibdn_<(TpNgRFQQ+J({ccm|h2P23)e zMFxv>nw%{J5=l^#>sOFHoU0&vIH)6@FNpc8Kn`92G3+4%Ipy}SUL+Fzht3`r3Pz#{ zrg8@{l0CSdf;}w06ZWt~&}E0vSw#Xxc**UdQY5gNh_v#3P4E#(Q2tlAN?m6U;#dN$ z-PSS^LjTrsVGmuQTy77$L_#T~Y%QU81tXCJ6MB^0brv$wGj-9?sj*Z(Y==jpN0Nona_HM1rr{0Y+--R+?bT`WU@wvP> za*;J&=2apSvvk@zAOsRgFcU{{{kSJQ{xd4`Vjb~e4P^-N2Ovh7SK}ow^TQ$$^$(r5 z@V#IpnqVqVvaIp=7Mv1sX(4LtDTEf{B`;@H2wkRAS)Je`lAz2BtZKa6cFZLaR}vDp zoo*Db;F~phk)9GVsmJFp(y)uX@y1$Foy^6=hkZ_LUpExPm0UWj86fCF`>U@KT}43_vd>E{g1&3oQYC*2tmPs^LzB4tK#R@i1vPr7py#gw z8R@;O2PKrTfS09(r;<_VSJY_E;=)Xze>5VDeRi+hrS*6bQ5=le$u8fEN<+SOQns8J zIhj+eH6Zsd&5MX*+1YY4W%H9fSJ`;U%O+anY6_`HLpfETB$A-;8yJ<%#T)jHxC zf|$PwK>Xt+o=6qwc-bU~L=Ni9X0~7?nqVrQ5hJypn~tJvI^Kt}nJ?&Qxm}QMj!1y| zp}cImYPldHEf)*5T!iptaQXhS$;k5)FX6tMD5|)-HC&=D{{!nwBOZ~D8t-O39+k_ChuP1M%1;}M*gtdSBgWfU=3}zYxPvu3CVy^xmVG`=V`)Df zEM9hLI#^n;PiKH-KkGLWEHhZ_H7(x2 zmd%p)M09fU9%~gF`54Aj7d|O(Gz}ca_V$u*@jd&Le4o+y7*n6t((E-`eyY=W+9K=W z>)$ZGLQToKk{wH+`{h)T%ZicbJ+mS+Gm}Ep`iAh#mOE_F#o%F=XSV2Jo$-8 zlnUC7XuCI~knLNF@$Q!MWSj95Hfo;yoN3BN-{E<3oYD9a`}G+N)qKDX=F5+n5|h~n z^X1Oc^7a>LhE}*@;UV!N-uG#N{7Ja!gq>|%B=?cj zKZIq3na0A(9$SOif#ikqO;XQp7uhARyvbzCY(zMIw4ZQ?7lb1;LgTBfY!OT?An=ph z{dBo6fbNK2;BSK)35*`;CyZMR!fn^{ly77+7t7P6q{Z48O!$j(XJeu7`WI!Z(U`_= z`4@(ce)N6!FAR{FZhnh}EtMAC(Ls zm%OD``x(w-kb&I4+1bnwlUwWEDg&d`m<u zYpHzu>} zSaUcVd_o>0En%0~t0&~KQBRap1D8=^cZYYM&Mu#j?=-b6XFX5KNv1W^*v3$rs1Hv}Y1&gBw}x3H9x7*0I#s1WcCK1Kw=^C%Z^>TONH>=G`Z_xgYU!=nPi z?oS1T{6~a@M}0!Vb&qffd8;)E(LPA%$mU#@oBO8zEO#+ReYuVcgVPiK&Q$jLFLJH% zYgTv~=H+>aZ9I+H=!ago#6CDD4~~s~Xs7`r6ZWIW!rY6NrD%3Y+N7F}Y6 zzssXFp|d^-2p#iJF4Xk&TDJH!47=|XAvJ2DCbjfIE>(IXAobEpP3l5Vh}5hW_#Ti>9rk&Z@8{ge`9@!d z8zXa@N#($`xOZf%B&A6j{j^)H?A}eFKXx+`+`BxMCC=6o{A3QL*U&%G+gz#!=L>0( z3na-9rg0j3Sy|N{aAu_=rF#l}H$5NuoY6OZNaXtwl3~{pR@=dHzt24)@+CqyLtpp%F5De?2R<(0n$jxSV-q4jl&*aumK9zT z+18hKPvoQFQW~ha?%GTy-K90t0QHO3>u$*-jdYjaEG&DMrZonw4fTEVaO6OfWN5DO z8=C1=fI(2YjS8V>@4u=OcT_QaOmZy0$JMb)}j8#79_EXG9=Pg)tJW6H#8z|4SJ!9DiZ;0}Y^5y+IGACRz z>|Wx7`ffsAG$zxf9c<7$kslcE^wqu-xvg1P((VvFb@+(%lozRi+EC8+{Ei$9_(Xte z!5+zt?9Xb}MrIh>`fmCp^0($v+HOs23(H7rX%@i?_jkf3RD)Z5(VHV%nWb!yaV0&! zlayqL(#RfSd-i~=(l>8!x?QCXw z9@AT6n_D8yQW7}0HnvAw$Yfe-Sh`OXCbKgJ9I%2Gtk?~OKN(|5H+pIh?7_WG@s$)@|?^lf~_;tOZ%Gb|mA z->{<@c-duz?{bmlKr{C84HgSac3EPL3j2r4@}Q~WCEw|%EH&Z2g`+GfCex)9RyM}+ zfGK^EFE`)vzR`E!4$EMR$=1oY@n*|pqi@drmdBdINjW_gQe&T>q=tq0iXO9gj3#eu zb}Ylkm( zIUglGQ{hjzW}~H|xiNx$P=VZyO3-pQaTkhG+Et<@oVo`|w232y#)tbJ`rLBJC{6!B zOP_rK!Jqox|H9HHLi%;JmRy^oU`cJppi&=`4;Ukv^$oL`wI3iiXU1ce)={Ik!*Qm? z^6qe(!a5$abiO7*v19Vmj@e7T90{?t4oqE+{+UfUX331&S{dM2H&<{hncF1C)>DF` zPmrUh#$joiqmRb%Wbe>+jT(rrc47rFo`wB2?^?LBkI`0r!Ax8 zg`aSS<)5@;J5Hk&*f_k7)q+zhz{3r-mYXFf9wyaVdPO(4)#22s69m$t-jG$tR@GWM z$pve;-`l`;;Q|2d`zM>2C^u))RzTAuS^wx)& zzO+B+>8oNCQ3E|SUz54EItmZ{-plkAo9OAmcQSo>Vf4h_&h%w9i`r_Gs@}?EZ6cyh zO5gq`(-&@zDltmet;%HOa+F)@+^vo|Bcl?fo?YtLBauJ<&31T#NHdI6)84shftfhS;cf&D@FV2i@z~<(9}#&*VBbs13ryQD);5P)z$decz1;N_z;g&l2&o5c>c> zCdoG1hUMDqf!0wUn|8d)5@MnjN?SYDv3FvkI!k*J>e#-Rs9w_XS2UFtTrX5g?N}Kd z;0aLgE#{y$FK)*&Vo^XhyuxP3qJZLHw=c({fX)|k0t*N(#zO3(u63+qT+|>bDyfc5 zjElO?bn*q}iHo|%RQ&?`Ph3=Dd}qPYAA!0v!>`G=UtmW-)#sHL@cQ^*p5Ly4YJlt- zIa}Xf5MTP5$nF86UE2<=Uz?~Eri5j_9c`knHOh0^i+pr8vBMpr;#+v)>u|K)&(`@g zd+wU3o23&=GnsL0Y-_Wq)1Sje z4qp>B&Kx1gY+g37ZB()}4DTnmjk-B{BwvXy+lwN65$G+$gl^D6Yl~$dv zH?bG2Q8$=AEfjjY7e+>3!%xUo_+eSz*z?cv%)~5UIf>9)SYe3XYCF`ijfv2kO_1I5 z97{@q-lpJvW)ckML~I>fkQ9~Je0KqGr~Kokj!`kUY^LYfe+cu(Q8}Vj#BSX(x}^jL zI`dhc=!*!{_fkoN=h5=Pm>7#MlnR?nBsFjBNnD$-cbd7R20*-3kLGK@#(9 zyUw5iL2D44JnGGFiG&8yAM0}|;T-+jZ?W5m8j^6+0^SF7|?o*trOH zAA9eL*jL5gd+#WAT`N-Th40MFhI@bad+%R9XU}=g+3e2DZep@{If}xLqL`y#ubBIk ziE>os9YqyK;pZr7IEp|=QQJ`jIf`IMQQuKCbrdZeMQcaV)=_kr7NzV+m}65{N73C; z^l}t^9Yutr80;v9I*K8VVz{Fi zwWC<)D7HF^U5?^_qd4X$PCAM+D5Cg|oOf)x<|ytuiU*G3siSz|C|)~?w~ivsQG9b0 zS&kwXCLhnzI|>skqS(-LcWkmd3U5bI#8DJ?6y+R+ucN5pDC#(h+K!^GqX=;njT}Ww zUPK{2)Um0Pqv+x&x;cuTj-rpF=oHjZ(?Q#?c z9K|t5an?~>a1_@a#XU#y*ipQ46mJ~GCr80nN`4mpC`FW$(+p*k$x#$=6vZ4xSx4dH zD5^S&>W(77Q3N}RR*s^ZqZr{RW;lu{a#UL!#bHNr%~3pe6zPsa6{GBQUPn>fQB-#n zO&mp6M={J%Omh^Aqa4*XM{&|oJWz^&%~koz`wW<`st0gw!myc(%^gqTMknSs*4|S> zbQz-Hn73Ga=Rs9>>W2v)!7-`wG*7;e5RcAg2GM)#Z5I^uqaRd7Gj*foL>vv zDy~-6<+U(^208b$tE}v*=wA-jKf7w5U5(1FVzR4^+12svs{0y;%jN8C&qc-Ng&vo2 zu?vN>tM=K|utF_tH z_3TQ6TO!d>A-n35T}{odlCrD&*_9^V(VH*3suLy3py<=naYYV_{>}a|PJfCw7dVNo zt2}emHcEN>VHa^d#Zy^NWIaLci>^1PxJK0bMIFSpZxeM3R<9CuUslf-^%z#q5OqvE zu1jym39y+F5u(1#>K>wg!|HaT*5iisO=D3PWpyo4`?9*Ss2i}lgs8``+Dp_6SZxyZ zPFCkc&CdU62EMUd*Epx!tbQ-*A$av~o{0Jb+kQ*bTHGkVVSkwb`h2WDB!tP}J;w#+$sN-pgtiUPn3IX5bf}l};~N{YlhLb5Xw#bx~H|6LkYtUlMgF ztB;9#1grOmI*!%sd5Abdi&-t+PdFv8dbZepfYno?1US#YXi;Bh^#D;nVs%$he_(ZM zQU7Ljh^RgAp6pExQTwslN7OA?T}0FaS#1+_46E~qdT$g1IRtpQ0(B-E<`@TTyDaLm zD^Wib^=G#Iny5YSe)G*KQ5R)3`$7zQ%d&c#sKZ#jO4NN>JzvyASUrP1+!hUU7#JrA zZ-l)YhK+}?5nptUb4q4KIEuHdz=LC*Jn;7VT{9G|nYbQ`!fZ?$R@%7ae}1Y0q?YL{J2 z%dWf-Ds)4$t3}!Dk?d{9qOv#YRy$grWN&Mey)7p>*izY5^XzJDcC{|MdXQb^z-KFB zXG&#P?L^g!?v>Tosxd{AnZ-VG+*2e3vqD~whh6vrK4LfJzOMX=Hr#n)HJ>2k0{j>~ z;4RzzLl`qTzN%3xON^Umk z@SY|s%Wc&}s##vYxO35o_3@MX(|9`Ka9z-uy7+y4*6DZ7jpNEzMrV_$UxvHjBMkW} zcByg9(=4|;QA~aYHP+__INMon^RS7#Kfo?A@fwGCa}L6HE%kLXI&1jEIKz} ztOuQOMz=hH8M42xGu(zJHO0Bbg35Bcj?LT@4=TqP4H$#1cw06B|1@R~!;wGfGAYYP z@0)v3ZnkTw^6cE16j(v;r3u$$Qs)Z#NxFKxM}K&^C%vtpFQ03zIx}nkNeZu^ck>L6 zb#rTmK^Ofa2i`6lr?6)`vWH0I%PK?7D&k#!k~Wj(SJV&DNUBV7siZIL;$0>rN0#2R zDan=f1wCR6JodSc5I(3(PdGT4~>jB$(8ux~Kl zRtNK4)IY!`cI5C8u{*}xn}Xj&^PVDNU7KGdCo}LD2783TRA%5ORz&?`#bFBXkZ;B)gSjr}xm=?dZnbO*-dV@;y({$_q0mWyt8^j%wK@L}lG zDPKsABMsTjSnM|bI5+Ff!SX~b{g z+*HE1e;oPO)=#yY(18>22)D`y{kcNlADiTypXfnteY?DNuYVsmmzw;zxsAfaJ(3}g z+X=KIzRXM-TSs4^-fB;rnyeFzW0&!L42r3XH$85#`1lEb{PM(`2+TCB*4Xu#xcSF3 z*0S8L_GiQ9G@t6DurbT+aDPgxqc70H3&Rgno!##7ss2{(fT{4t_Vu4ry%tzGJ&jM1 z{%FT5D$@@@0 z`_Y8Ddb?rWcTDcnlYeK8=qT^cq78NRB?~_Kh2+?L`}$(E#QAFQ775R4;h({U#QMv| zuasI>?^$UVo5FaW?Qm;MDlPTSKLU>e#&iE--3r9e>w0?cVyE6`;D6b$ z<~YP_{}vD54+c4=FI29+eoUS9?rf~!zsj=oOZ-rt&B?BYIbz$|CjU?kcb)u0J=_p7 z`K(RO!#tSqNMA9K`ryqr&iSF~^tQe}KwC(_k<-a1L|?hsOMHL;)(`*4W%9a+j3a|Z z>p4MsO{c#?^aa(ctI@U)eg0CDtZZNM;K&);jh%uY`*=lu`-U<@ z^o!I_-cx)7e1Lzs6K!swPgh@mN6Q=P1J&0uD5aski8|;Vm2IT=Ru}6?%^T@$YOjt` zzef7AYW41Ls?<~;r1lAyMmE)-(iF0k55ekqY#))d@zftS7Ja|x!7jx){m3JA zYN=0FYxd&5d8>!&^Jx~K=n#sJi3g#G4%OGIGgZs>o*&7vrBVLpk$nHoaU?6?5{_9A zK9(P=Wn&0m_6yK@3fKleCuxHtnKFj69{5MjlgmXpl2t|PaY6nXOPmtsdpYHTtID27qJ#PkKw^LIqdon^CjQdGk`a_WC5_ z&XK&k2JS~>316}-yHdZOc687O7!yWtrrL5aYw^8;3aj*a$<$HrteY$t18!ctJL)ra zi-vQh2{#x8I_ZB@ovBE?*#9er#H1dXCHAkMP(EAYDK!bx z+f=$vLwW15#hx^{GpyPT;rI|P!*cQ8|I_NIuqr2%a~F9^%eyeEf)Ttm0{_2vv@5K< za9zjn8h~49`R<+6Z1331=5d^*>aZju#etDr7hQ+clyNBpT00E)r-S2 z>>5F7|I;W@808R3b(~bDKQl_}!8@PCQquu2`p})jhgdA-`l$9qQnDw5Bz*We_Ok*1K;K!O&KHg{j?PXJU5YgjnX&K z95|9eeUtQs)XU0A4@T)Lsnm(b$v8$|M%%L;?|VCeg2(9ZnQY9SIvD+v#2^+}d65ecD!+ls|awmwu6_Bs-ZvV{9eLNrU*PsT||*w#!W zjG*92NVw2cBw#V)N9jJzIl~erBVnN6wqjwEt@o9LU5{o+V5}!c@U+#i}J+?oh9rd;|wG`Y9JB@ zQ}7HV{0tEZSlW2PO&W5ECBz_Mh2XYgF_Wz~m4t1M1TU6wO-cBRB_xtD76}>kM8W_H zjzxl5Ko_iIJmDIJUu6k1k+7#Omu|(9CR?v537Z`W9xUOqk`TudwvjO&3A$jB(3gVa zkx-(Jcnw(1c*13Baf2nyLc+z`BB2jUxU3{>a3ok+!UZK^HcQw{#yLpv4iX8yD0mJM z0&9r`tX4eX0tMY>33HL~EKnr$WC<6Pgtd+YSC(*ANtnkHHjr^X68vh4gzgkP9|>&( zL;{vEo^X~b++zs~knp31NWhXNThA&9s~ia?mT*c*SjZCAl97rrM0JsX z^^7N+BJX6Dum}mRg4>EEOSYa;5|%p>^eo}HlCYR1tRmwQBn+%362d5W2@+zfiUh1z zJmEN*Q&_@MB$N}})=n(pxRS8Mk)UG-2}0pfC0@Y zZ4<*@(zeUd2_h2 z9!=i~@fiWf*Q1>~A--3TvypXa_b!NUVM#*os9=(IL%c=6Cc*S{H^hhYbGA_(dcFtZ z1Nk_tUz=X!)&l( zR_3u?YIK&Fb%KBQb1>VSn|D)rqH{1ii&+n|z2#`kd6@MRupOq9d~z;byaclWidl_^ zcFF$&GaCT^Ru^G*!-aQmEJM>T!t9eXho?(Z-%Bu?Ctx4UG5O{!O1cWOzTC`PecvvX zzRbMF!M@HFcztu?%~DAkbp>8l0dJR}_E+I`ASY)>W0J|wXVTUi@amO8A;)np@7N{J zYs_mV+$&v&R{;%IpDjkcufr=q&EdHkfx@MPt z-ez9g;O=@CUW0z~=GO(O{#|&@{KcVDK`MCh6`KamxcC(KLuVLGRWmJye`hBw)t(|DKBO)BtQ-$td~@`>Xet~B9=K1My_9YqHjYEa#m z&@NBq+**qi`%+(Br5*f{C}$E5GL$zw^oe2HM-N zg!bhdXp6t&oW>xPe#^Aq-*9{^4-I+;?bH`S>-!$s_cG^p=awShGwspW97pKr$OmYB zp9$^MkI?RV#kuZU>EcJGo%E99f-YqE1ntYmLVNoYv?E?{&ed7+Ok>)5&pE#4M4i*2 zUGPX~i)KLU_l$EVb4vX)m{#|cy)`zd@^8@Q~vtf9%xkyMBgxJ?@R!$#DCj575m>=H$)acB#`3 zy`M@K_JD7g{R=-6`3ZICEurrD3+m?gIXU^KUE20bKT4&O@A3`mA9gDHN54$7`#Op$ z=7RM8kG_;(ijS8nys}=c(1mhCPI%VxgZvaN0~{;)a(ozv}f-O12Y z)5Ir(sy8weaIUnu{C}{>XN!V1(I+ zVv5<#g)pnqNSIwRGP6aexwg=2JL%0ZyLUvGT`iG8pUg08eToZGUfQXJ1!k8ED`var z!OR*W%-&m=*{l;>tA2rTkr!tBlZ07f(F`)V!K~47E;#bcPD9*amQYYJn>QO~UxI~M z9xF4Oew1sUJ+V_0cbF~OFU)2Y${-&b%<3HBf)$VLcv2(G;_@kG!{T6eCrFr;@nB|A zhqxBAg$CMTHhQlx8(biRntQ^`KZy$_JhanJPnZp~D`u_!g4w>B!mP0uGaG$?Yu7x$ zILimKcDsaGGcSy@{4lG$p9?zQ$2iLmvnK9}S*7VPTj(#$1{7dsL-%p*q`Mer1z}b# zQJ9tYz&P`US-HJjQ1cGPnK#VJ=2gsGr@(AvHDNZh5HlOJn`^t>!Z<4oGut*{X0&3Q z6@gi)U0jg=CdOG&nCZ=mS;j<|wejUfbh%S$E=&G@q zlga1NRj-`rnpF;6s(2}_kHCX76-sOV}|6&=6}D+)87b$P4YfK?QWCAXIc!OIO_2k6ja~P&Ttp&6AWfzPRL*L(ualy8y&507@!XN zNM%C|1=YnnOU*(Ija9l2@m%@Wb~~+a0H<2hgj3Z|%&9CbbHZgUs=mS1ta9TY(Qd|S z1?zeVc6!s$&{XaFj=Xch(X*q}v5}#)858#^qI^YLsTDx;UO2r&@E6H z?!t-%!z!3I@@fOy*G4K?c;;>=^>4~Nvu1EjzfE>J-3*=uCsNZU@O&#gALe#=ju)Ou zSh(O>4D&{wlbe1wf#*x%`LneY*@AhxOyimk>+N*AB|J^zsdIC9z80Rp3=YpE;du({ z7d)-&;2G^g`WEoSV=35cf7e2aZOuF_lewnh8aurVg=dbjG^iCkp9@bfi^KD~@VpYu z^|>&$4BvVxz$(N>2o`Hei}&=+Q1W!yk#e-hMU8)s+FIh z+Y`9{3%jg`tEp^TcqR+ai;bkM9hj&0c&;h6%uY_7;Q3@2#kYs&BjMS}rg&QMH&7Ao z_9&9;Uttc(EwXY^%?^f!s(ZpTDMU&NW2Pm?a*=(po!q*>^jZY1=mgUT!gQRcV@L6r z1ZMhjG}qt3Op=3sQIjz2=xyP-wXSrrEAy;4ifeS3N=3WD^VmSz-UXg_h3B&T4$m~< z`Edl-pP3KO3g0QLD?D!q&!x4cj{dA06oi&s)OtkhjCLJpRl) z_Ve3NuHQEYp59+*V0U=pSs?7h#|BF8dcjj0GK6d1&Z6KxhDGXCz3EC%SY8*F4~sY~ z2MWua5nR3jlTXGaZG10SUJ{m(HKdNvwZweA4*7;h+~{#ZhqG2YNxrGApc*okU`L|voM zpI!|8p~+<4WGEr+j53sl3NguDMKYO7_EO3e zCfTV-3Np!UMKYC3c2mkUCP`Ez`I+RVBAL!5J1J!blO!k-FDALJNMg7oky8F*lC6rw z&LmeANi3HnP|8du*{n!xOmbO~#Bs@1N{MHZjf%v|Bo`IQEH2qhDYKbmy&}oWB^*K>kN5S>In;|)_TK1 z_0ZY$Ydua}n;cTX4TfNqy4^fR6rsO18ak<`#dCj6zds(5ev_fTO5JCUpvP_oy>OiAeJAKUQv`i5(?dGElhOO93%b;9(61&5`a-&gl(3u8=cWqU zz8CbDiGqIc$wOMcm(lko3tA_E&J`u-w;w&EIEm46w4i_N2W=fM=pXMrr11wB{Vht+ zZx4bl7Aa`mI}d4KlEK4OQ)PfMr&eAu4Ape(olfI^8oV`ucRi$PR}H09nhyQaNtK03 z7kSOFOB2{LoqVoCQ24fo)cU%ihf0&P&) z8XY#d>DMi&G~tTs^)(M^_HCv*g~q>CUU#8--dRzdz2YJ5xXV=Q(D=8i#(k(xc2ZOu zFL_AU?laYtF8@?@N``7}2Sqjgf`{}enW=h&{ZlpW5mb}gDXQM*JS0;JQw4YYr)t?_ zsJgdNRQ1nzNIp-Ps!02Pst!Gcs!nS~Rs58P)chG!h1hoKN6*yAkzf zLt6FIfX}O(YjOu~y8p|tMf0XwI!*hH6L)!&hqUE4mP^eMe=dmEJgTA?AK&01?aMN> zQ)#yQrIT4@jMrSQtZ+Nmc}QneMsO>trjxe@+~JA}w|b3-bVtLuc;9rY-~=wgN8#qI z@{nFRF>XSobP93?x4fLfMX&IXzBn^(P=$1Ap#>LLM&X7m^N{dY5x{jWpHAVq!HqAa zaN$clBx@eVH7%P?L-gPVmQc7Bi#()a2FBGaolen4aACz1E@+{LRK>)&awXGgju~8& zA_`YwzK2xL!npj!(`mIUxPU?m=RMa$YLnMk*;P}~HJ##$8@FhD4e3<9gwb2=F+mC| zVXUjt*v;uwql~dAT_|b1qPdkjotBmYzduqsQpy;q(o9AN_@kO3+I0F;22|)6$-As^ zv`SMrPdY6t2g>ZMP@hLi(d8L+65?Mzpmyd|s0G8Nrxh609pX-vK($aSlW*LYN&mPNnI7z?Ry50+L}Va!@+y{dtk^II?@21+VF#?;AyAygeqg`a|P>o0}- zgHb>KP02Nk$JE!q31V*_>39GmCjTV=KoCQ|2qLtX9%AQ0wEL458mMb~D; z$uIP?4v3v;f>;nPJq%j>gi+4#xf}b#h9!WTX20ePN%_Ksw*a*hi&~eJI$*osApS zW9|wztiI&Yg|Yq*1iP#&*pjyetFJ5d4QK4TyMle+4eb3Jf<0VYI?$c5OK%IdMo+LY z*91GTmZa^)*hV)6JF_=fzbk^xS5s==hp|7e3HD)Mux~C3_OidUxgTTku^WHUWd?v< zd|t5Q{iN>$7~AoZV8;yt+u*EV%T|>d3}$TZ3xd5A0rvYT!9J=iEgr(yq_cwc8U}Xr z3Bkryl->+8`Z}vu9F+=28VxFS&4c7K&R9xqFC}#vXY8s`=SY%{L>Zr`)K~V$MAa~DfxRx?rY`HD!B6QW-Gg=p0pCMq;vTDF0S zqew)#Tr)tC~s>0u)nwB6`6BC%Kc1)TyekW7iovf&K zXFz4$BvhYvG1ZO9Y0`&%Ox1gWqN?)|sts#|s_TBH>NX)w3OmG9Uq>sdn=({YmJ8Lj z!^S%rwRH^Pbb8S7al}}o!^aNmy9Znv2PmfxPjAu&nC^hY|NEYU8=936Rv|k+C6RI zJ+L=z(!(2!eb8O7zwdw@+&PV!KLUNlCY8Cz=)XD(y2(S(1=^?4s%N0j*`#rg7+t-+ zpqD=deYI5@eR>W0q)oc?jL~mf3Hrk;&{0j(sMZJ2M{JUp%;+Ue1s(7nbomBpG&>#i z0UI8U$LNL)1Ra+K`f;5!dh!+YZku!{ozXw)2>Q_%(6ef$k=uB8*NjYzUzM8wy`(66Ekg;s4=zI zEfP3irfs7or%9!Yzr}gi3>$elndTTXZgM<29jESj8z-tcz!YGPZ_MAftrA?(bep8h zWeQg5!f$Z#-A^`Z=WME@%Pa6-!0Vk&e{^}SbAD2)jS^f;F}g9=I8Oa&qgq;1E1j3X zb3fXo8+FSA!+V!Ft`7V;kExX* zQs75#vG*a(XtmZoxvF%&7rAoM8|;b!&hiD0eSv=%;QZt~$7N+3KDdB$6M>h! zw$TC;oIjo8e86isZ)zl*eay^x%URAmdugL47C46qya0HK1 zDg@{G631h2+h}hgI9C-oA0~i2!%sLjFU*`j?d8f7H*GYq2%OgnJOcP&5jZd1!})Y1oLvNdaNS0s#o)YkH|NJ=w9B%uaQ;+`IrrSfnL^hvo=d>lCh+a67|$i(Y}(2B z%U3X-OTu~l4vwn>e=Z5;vci0{=LJ@mvAU27#Aj*vl@Zh4ZxvrV=Whv{CHSY3x%aQ&(LRflr>oLRrbA zQt4`M;DY@pZ8WMf7Nd>pInIZ1FV86MMD3QE8e2CsxA_OCjV4V1w=BW$(qGr`i#npfM zOQWlsN~?5LS8|6*hj5bo5&2>T$K?;%_SImCcb0SPon#|JfN7epp1^Ys+Gs_9sjcqi zGS2$|X9bx4Qa}Gnu{9BJqPMiCrm4J2XIjbywfAF%2t>f)B^;+pHmO!EmXNrZZ+N=T zMooi|P(a`oz$rmUII@WIm;n@68wqPOM8c%*Qf6(I@Ma+wsP|w#2P0vjz=^neO$=rU zGZt{c>RmR9uZx6l^EoyH=dXtZ5_rc>8%5PaLibdWP`is%xjsucF_$--NW|<5LBe2x z2PfL3V<9Xdd=3|cZ@1Bv21vL*o8#*VHtO6E2@wKE03U6Lgu?Gcg1VzLyb()S7S9_d zZN+J5jD!XPm)~mJ*MtT5$8p|!3r<5*1Z8);87 z7BK8D-cWlZPD6796cjjh15QH=mSBnDf~V_o8d@S@(hQDU0H?G>g15k**5Nd?VyEGm zavEAnnXOntqiMWBjmvu3P$Ybt%5mZvoQ6=A@OBE{uzEF4LmMP?5ZDZyzbz8JPv-oN zRX7c8*=a~oPD4|vayyn#coG+!Sb@{f9tqc?IUc+Mr=dMdI5ClL2w#rV&;bb*1-`xv zr=cSfu19e`0{Cc0b{ZZir=g)Vyc0|KHJ%G5Ex~CBL&9c(%P+C*>&ya{j^n)dVw{F9 z2*@q)oJBYdT@bJ(lJh>mSzXv^xUHOqy3(GmEa1)8C5#x& z1yASWG;~M8%TXM+08Z(Sged}lnupWSgPn%!%4rCaGJCLuT_bpddM-{wFC=skIB^b6 zLoXy~TMXxd)w3zCw`sce_%II5vngL6Q#)-}0e8%z34Khl>h717a}Yq4`EsBjD0FXUQ=~rS9IW8if;oWtGYDRL~lA_QzRUb+XU(w6AT>F<%`I}TpS zT{zqpNt4FG>sDtD*N>%`@$jlGpeud^J^@}Y!#KNdj5HchrCrg9S?_!)t#B4u_4Tq-c0`6wo?SvQ1)M=JuREFq}qAhS#Zf91a*xCnm$| za9a+04x{r^;8j|{n?tGNRCrx!!`YETrTu^^?bJ|?J%*6mba+)0@KOYIn+~rEtvP#o zF!h}Qua&JhtTdQ@&VW~K0q+cw+Ql%h?=3hzW+3hT3trm7_N6uP@Ul1I?9@KAc^158H0BV0 z)7F1Byh;nWu(z}bP^Ep*kkfv>=<^(Sk$~@eQti3$n%#i2FMCjfdGPuZ!eOf(lspe! zs|EbhU8**pd3CDK>BZe>!2)<01#H}no-KfvOFhok4W~B?;We@@hr7E{B*Du=z&2f_ zdt?e%Y0uT+^!v_Kd$B28+gZR#ouzGyO=^|4Rc%g>3L|L=Cingz4j*=+mP<|TwQU3( z+llrpHBDCgE+M~VrZQ@yPU^kPma|oNlRCmyj0o|{#-t&4INtz^Fji8 zwvk-dm^3P_wK}Jbp;TZk%%}Nr7}c5**TTH0fcaaKX&sil>vL%NI+*WJNoUrX%sBN` zxx8shda@qoo&x@CAywMI%#Bqzo!XoNH^My1m%}d2>FP$9=NIr#GxFI4^PO?rTr>N( zyYzaK$)wWuuEh1_nl9V|^SlBjH<4OxVdgFsIeWD+b=eB@(G@rhY)q+JVeT$qN+W8% z4d!!Vgn7hwcgZ<{nRhME^@fI2a68=f0wy((hHYo=s&br8456q*xDP4IVSx}b?tr^V zz$18c?GCsPnJV0ye|DFO?_};BN^||kx>Rcy+?@qnT34F4i@E~|av~oAx`wN&= zhsy7PyH3Crb!he;xVMNF?mlVmQvJQmy+v`}eg$8W+6VVP#W;)%l6LQ7?&(E29$br# zN^tKc;Nw7Qwjb^)0Vf2~j{R`2FkZNuKDbN04>0!zg?an-0GfCZ?q3RV*fBu5d62ok z_2#%)4SJje_YMLc^{2sy;QqZJXFL1TwL@?>j}h*lWOr%$VdfrGfD7XNXw?z8f6ULJ zzn_$Ggt9 zI(7o?uk9Rq`bw@RnR~Ja$HvN3;1t{&2^dw05>LVXt&Ow!E0O6m+^oH(nz~$qd60mCr786i%%7Mzn^KCJ zUxxXdKEgcW9)|lBQ(cwzn}G}Nm!QzACU12v6^*`Xs-RseHjgVoE&R-`bo#0(UR^Q= zy{l*rr7hP?9kqda-dC_V8LpecjQ8_!cn~8_E*hJY;#98g(wyt;mSsh5P7N+fM{k(C zG^>BRQ_2lfF>Q0P-Mc8I-7&dR!JDR7&GldIwEd=OnL(%HP01K?a=jT;-Yko+28*9zRgcFb;M){GDgwaUFL| zxwX-vCBT~nuh4w>#xr}6|4COZW!*KE*ZSw;re6zC)q7ae@2yV2`s$czy1ZC)w(Im?v4bGi}6ynJTVe`Jn-r)1`PiOeOU<+p_@yhLWgTO~8{ z3NiyBORBK znGYn!Z4YX69hq0(AoE@(H!W@;=eNj=6!3yx>hYFkrloVbH0F)GA>uzW!(J$v0q>Ey zR3Iv8T|OW)ERCCzj_3n2a|l>nCuM$MnIls)Ot|4rsz0X6 zy3&I9g!M1*4_?#C>+baAk7>K{#$(<=m>9A;EGMn*YWAW7S*Gf`fr6=sRq=P0DMFLw z`)NUhxtJzpz5Cw9W_OkD)Fa+H0_)pBmDy9X@rpYY%w_hy2?cWIW3xv$EQcw2;j zWZITW_!)%j%*Ax!f_(e|;W`$68sR$g5<~u5BK$oIZy~}~V2*>D_og0Yo z(;__Mq6lZyrjUPz7jlHpL3myk{^z_1f5x=+l<DH57~BPpF7RT$5^$R z+gbKrWZRKF^_0lQ_?Df6M0OXET})5`jM`M|pV@Xtc8nD7#j?wv5ZMoyw5F213)%UR z{q(rV#_H8PKg-^U?EJ`HaZF@m$jiGokFk<9FU7LgBfAu`-|rFG81J%k1(7{Z zWXB0AfKi)#{+X?FWRH>J%dqSvyF~T{CM~CAuR(S>WH%P%V=QUS%dza$$S#L$?M{)6 zF)cfn71>Wj_Ld!-3SiVG{5{UU*S1`a>=9DDkGY*ncVRo124Xe)RKc8IGiZf7nJb#h z>V^v9HCD5bissdtdCT4DeMR$5oofQ`m~qOTHdZn>*B#i#ak*3OlB%+~vPu`bm2dcj zH7d~8?5QralvK6MUT&Sj@yx33b=l$@AS7!biSsotSGQb3*K3)3QU2k1^|Z2zxuoIS zW^NLO(Jr4WN=vJo8(aIp0L>(*Ul`PK@1i;B$YYD2G^DCIMpZm{BkwAG6x4>oe_w*} zs5fK$M&%7b81em~06%kXU7YB6gf*?DANC|}q1cngBd{kus+&vdLN;*EMOfUZy1A|K z^?Hu0VlK#Qyp{MW{&?lZqt|gNDG5}Sg8vc!VV;OjsDb!OqGMo^JDsS3_VKt#56cmiS>dUxE$ZmIf9gMvDOF4dxVK29ISMsLSWqHGwaH>BBzWmDV zKk}Bx(9?RzD<;JGusmAoBk%GI+F2iYPZx2Mdx`GUHUxPS1s;_M(`T+q-j@)TXCp5C zi2*N4>c)y zy&AK;!}GW_b_=Ln#{bAWJc*7sLEc~?4#4`D-UN9cqG?W3f16cYY4X zvrOXXBTpYmLqd@^ zB9?ErVSRLOgS@-~OBnldpl z@ypz4S4ZTP9ZoGeA@B4QZc=TjJALhhydDDI#c-BuXW{RuvDI#2m>Ivl`#4GL%3^nt zJDa`KqlZwgF6K(Qd1CwfMebCmi+P1+X#~IVpGN(PPT=JjwzA7N4ZgZ$EQ51q`1>m;0E9s>@!cpuWh<6Cm~Li))~v#V9WCj^Qb%;HzA{@ZMrU zPm!5-*x#9Iq01Xb_WtG->Qg;LWPt&QJTiiNT#Kd70}$Coz#*}8cmN^;&WlJdKdHk& z78yB=%ZFjm$sa$6$o1h$LNj5yiwN<^M+uS9nEJ2G16f}`o} zNJM6~6OpN-5E;;qd*ql%!pNX#YR&PW6)w?mqx=tseqgD1n)O2j1w;Wj)5wg$W4E+d>3hjY432H_jCtO@@gGEHB{k zQ8aKO0^{~lg@FhxD(RwGV8gCleG(%~uK9qD4MJcOB`~OW_G$dth0BJIpo5bTSfq&v zJUSVHQfJQj45vSn5!g<^>%%B)3Idn!B<~>z^p<{1VS&RtarI4%FS+R*+A$P?4VA$7 zzXOX3*_0u)Wf}r2HxPk|(-HWz1GlIZK_90haFT#e2UC+72uw&I^9Tgylito?fh*f_ z^>d6ax$_NLH4=gKl)&V_1Dgxk{DHLOF9ZhH6@e>b5tyefw`e|qQeqL9(1ydb{uD41 zfrmGfY77EBqz5xu;HB1_&cN7`2jN@AV-Z+e2`tek`;d+ovUPpwuXqHu4ibU0W+Bk8 z6}RZxhpx;*;DeSNs`^mb*$BM6p3=r4&`r89+dM>NeA=ATZ+jxJ=LHP~#aZ%F=eg!b z#;45$gHeUwQGtoKG?3=aL$6^-Q%?26NRnTkr5|J-PUT*>=Ay^RmfRGz$lTg`2s?|# zadH!`9EX7o7kiN)r1 zDs5~Cr`m_n?Ilnyug_tBoND>bF-7UJj46-T<HaycnuEU;V{c>_A1I58<~=-bLx9j^4$#OW)CTFi}y4Brv7gms5TX=<{|c^H%1t5ssa_Z=0elv4bi7DsrlQJ-WRU z%0?A9?2lt7-`T7vU3N3&(DIxbQ-}8MfpSVY4r6h!LuZC|)vu z*X}IM;fg?-z27`YGiZD&sScP+Y8rm9N@WjVxNFar6b%6sf6)9&d#?nCJ8RJRB=b2< z@v*5CatIBYw^nKRA@fR=wq-G{uv90nBj#6z?nOB)j6)~KFJE}x+)q6+l`fqymr}p7 zN}GI7yom!P*IYu)FQI2xDtVnj&vUEv?F8$2Re+0zR-!|v z(DOAvhm�R7pG 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

      gvTTYikLAdFVJP9FjcO{kXC5!!rO`fpuu*vx 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�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
      +@AmML7+v~lLk)( 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ℜ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 0) then - ! rcode = pio_inq_varid(pioid, 'cft', pio_varid)) - ! rcode = pio_put_var_int(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/))) - ! end if - - varname = 'PFTDATA_MASK' - call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - call pio_write_darray(pioid, pio_varid, pio_iodesc, pftdata_mask, rcode) - !call pio_write_darray(io_file(lfile_ind), varid, iodesc, fldptr2(:,n), rcode, fillval=lfillvalue) - call pio_freedecomp(pioid, pio_iodesc) - - varname = 'LANDFRAC_PFT' - call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - call pio_write_darray(pioid, pio_varid, pio_iodesc, landfrac_pft, rcode) - call pio_freedecomp(pioid, pio_iodesc) - - varname = 'mxsoil_color' - ! TODO: output this as an integer - not calling darray - !call pio_write_darray(pioid, pio_varid, pio_iodesc, nsoicol, rcode) - - varname = 'SOIL_COLOR' - call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - call pio_write_darray(pioid, pio_varid, pio_iodesc, soicol, rcode) - call pio_freedecomp(pioid, pio_iodesc) - - varname = 'PCT_SAND' - call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - call pio_write_darray(pioid, pio_varid, pio_iodesc, pctsand, rcode) - call pio_freedecomp(pioid, pio_iodesc) - - varname = 'PCT_CLAY' - call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - call pio_write_darray(pioid, pio_varid, pio_iodesc, pctclay, rcode) - call pio_freedecomp(pioid, pio_iodesc) -#endif - - varname = 'PCT_WETLAND' - call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - call pio_write_darray(pioid, pio_varid, pio_iodesc, pctwet, rcode) - call pio_freedecomp(pioid, pio_iodesc) - - varname = 'PCT_LAKE' - call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - call pio_write_darray(pioid, pio_varid, pio_iodesc, pctlak, rcode) - call pio_freedecomp(pioid, pio_iodesc) - -#ifdef TODO - varname = 'PCT_GLACIER' - call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - call pio_write_darray(pioid, pio_varid, pio_iodesc, pctgla, rcode) - call pio_freedecomp(pioid, pio_iodesc) - - varname = 'GLACIER_REGION' - call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - call pio_write_darray(pioid, pio_varid, pio_iodesc, glacier_region, rcode) - call pio_freedecomp(pioid, pio_iodesc) - - varname = 'PCT_GLC_MEC' - call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - call pio_write_darray(pioid, pio_varid, pio_iodesc, pctglcmec, rcode) - call pio_freedecomp(pioid, pio_iodesc) - - varname = 'GLC_MEC' - call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - call pio_write_darray(pioid, pio_varid, pio_iodesc, elevclass, rcode) - call pio_freedecomp(pioid, pio_iodesc) - - if ( outnc_3dglc )then - !'TOPO_GLC_MEC', topoglcmec - ! 'PCT_GLC_MEC_ICESHEET', pctglcmec_icesheet - ! 'PCT_GLC_GIC', pctglc_gic - ! 'PCT_GLC_ICESHEET', pctglc_icesheet - end if - - !'PCT_URBAN', ut_urbn_classes_g - !'PCT_NATVEG', get_pct_l2g_array(pctnatpft) - - ! rcode = pio_inq_varid(pioid, 'PCT_CROP', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_l2g_array(pctcft))) - - ! rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_p2l_array(pctnatpft))) - - ! if (num_cft > 0) then - ! rcode = pio_inq_varid(pioid, 'PCT_CFT', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_p2l_array(pctcft))) - ! end if - - ! call harvdata%getFieldsIdx( harvind1D, harvind2D ) - ! do k = 1, harvdata%num1Dfields() - ! rcode = pio_inq_varid(pioid, trim(mkharvest_fieldname(harvind1D(k),constant=.true.)), pio_varid)) - ! harvest1D => harvdata%get1DFieldPtr( harvind1D(k), output=.true. ) - ! rcode = pio_put_var_double(pioid, pio_varid, harvest1D)) - ! end do - ! do k = 1, harvdata%num2Dfields() - ! rcode = pio_inq_varid(pioid, trim(mkharvest_fieldname(harvind2D(k),constant=.true.)), pio_varid)) - ! harvest2D => harvdata%get2DFieldPtr( harvind2D(k), output=.true. ) - ! rcode = pio_put_var_double(pioid, pio_varid, harvest2D)) - ! end do - ! deallocate( harvind1D, harvind2D ) - - ! rcode = pio_inq_varid(pioid, 'FMAX', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, fmax)) - - ! rcode = pio_inq_varid(pioid, 'gdp', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, gdp)) - - ! rcode = pio_inq_varid(pioid, 'peatf', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, fpeat)) - - - ! ! rcode = pio_inq_varid(pioid, 'Avg_Depth_Median', pio_varid)) - ! rcode = pio_inq_pio_varid(pioid, 'zbedrock', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, soildepth)) - - ! rcode = pio_inq_varid(pioid, 'abm', pio_varid)) - ! rcode = pio_put_var_int(pioid, pio_varid, agfirepkmon)) - - ! rcode = pio_inq_pio_varid(pioid, 'SLOPE', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, slope)) - - ! rcode = pio_inq_varid(pioid, 'STD_ELEV', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, topo_stddev)) - - ! if ( outnc_vic )then - ! rcode = pio_inq_varid(pioid, 'binfl', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, vic_binfl)) - - ! rcode = pio_inq_varid(pioid, 'Ws', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, vic_ws)) - - ! rcode = pio_inq_varid(pioid, 'Dsmax', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, vic_dsmax)) - - ! rcode = pio_inq_varid(pioid, 'Ds', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, vic_ds)) - ! end if - - ! rcode = pio_inq_varid(pioid, 'LAKEDEPTH', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, lakedepth)) - - ! rcode = pio_inq_varid(pioid, 'EF1_BTR', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, ef1_btr)) - - ! rcode = pio_inq_varid(pioid, 'EF1_FET', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, ef1_fet)) - - ! rcode = pio_inq_varid(pioid, 'EF1_FDT', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, ef1_fdt)) - - ! rcode = pio_inq_varid(pioid, 'EF1_SHR', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, ef1_shr)) - - ! rcode = pio_inq_varid(pioid, 'EF1_GRS', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, ef1_grs)) - - ! rcode = pio_inq_varid(pioid, 'EF1_CRP', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, ef1_crp)) - - ! rcode = pio_inq_varid(pioid, 'ORGANIC', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, organic)) - - ! rcode = pio_inq_varid(pioid, 'URBAN_REGION_ID', pio_varid)) - ! rcode = pio_put_var_int(pioid, pio_varid, urban_region)) - - ! ! Synchronize the disk copy of a netCDF dataset with in-memory buffers - - ! rcode = pio_sync(pioid)) - - ! ---------------------------------------------------------------------- - ! Make Urban Parameters from raw input data and write to surface dataset - ! Write to netcdf file is done inside mkurbanpar routine - ! ---------------------------------------------------------------------- - - ! write(6,*)'calling mkurbanpar' - ! call mkurbanpar(datfname=mksrf_furban, pioido=pioid, region_o=urban_region, & - ! urbn_classes_gcell_o=urbn_classes_g, & - ! urban_skip_abort_on_invalid_data_check=urban_skip_abort_on_invalid_data_check) - - ! ---------------------------------------------------------------------- - ! Make LAI and SAI from 1/2 degree data and write to surface dataset - ! Write to netcdf file is done inside mklai routine - ! ---------------------------------------------------------------------- - - ! write(6,*)'calling mklai' - ! call mklai( mapfname=map_flai, datfname=mksrf_flai, ndiag=ndiag, pioido=pioid ) -#endif - - ! Close surface dataset - call pio_closefile(pioid) - - write (6,'(72a1)') ("-",n=1,60) - write (6,*)' land model surface data set successfully created for ', & - 'grid of size ',lsize_o - - else ! fsurdat == ' ' - + if (fsurdat == ' ') then write (6,*) 'fsurdat is blank: skipping writing surface dataset' - + else + !call mkfile_fsurdat( mksrf_fgrid_mesh_nx, mksrf_fgrid_mesh_ny, mesh_model, dynlanduse=.false., harvdata) + call mkfile_fsurdat( mksrf_fgrid_mesh_nx, mksrf_fgrid_mesh_ny, mesh_model, dynlanduse=.false., & + pctlak=pctlak, pctwet=pctwet, lakedepth=lakedepth) + call ESMF_LogWrite(subname//'successfully created file '//trim(fsurdat), ESMF_LOGMSG_INFO) end if ! if (fsurdat /= ' ') ! Deallocate arrays NOT needed for dynamic-pft section of code + deallocate ( lakedepth ) + +#ifdef TODO deallocate ( organic ) deallocate ( ef1_btr, ef1_fet, ef1_fdt, ef1_shr, ef1_grs, ef1_crp ) deallocate ( pctglcmec, topoglcmec) @@ -878,10 +642,8 @@ program mksurfdata deallocate ( soildepth ) deallocate ( topo_stddev, slope ) deallocate ( vic_binfl, vic_ws, vic_dsmax, vic_ds ) - deallocate ( lakedepth ) deallocate ( glacier_region ) -#ifdef TODO call harvdata%clean() #endif @@ -898,7 +660,7 @@ program mksurfdata ! if (fdyndat == ' ') then ! write(6,*)' must specify fdyndat in namelist if mksrf_fdynuse is not blank' - ! call abort() + ! call shr_sys_abort() ! end if ! ! Define dimensions and global attributes @@ -962,7 +724,7 @@ program mksurfdata ! read(nfdyn, '(A195,1x,I4)', iostat=ier) fhrvname, year2 ! if ( year2 /= year ) then ! write(6,*) subname, ' error: year for harvest not equal to year for PFT files' - ! call abort() + ! call shr_sys_abort() ! end if ! end if ! ntim = ntim + 1 @@ -989,7 +751,7 @@ program mksurfdata ! else ! write(6,*) ' PFT file = ', fname ! end if - ! call abort() + ! call shr_sys_abort() ! end if ! end do @@ -1160,22 +922,22 @@ subroutine normalizencheck_landuse(ldomain) if ( pctlak(n) < 0.0_r8 )then write(6,*) subname, ' ERROR: pctlak is negative!' write(6,*) 'n, pctlak = ', n, pctlak(n) - call abort() + call shr_sys_abort() end if if ( pctwet(n) < 0.0_r8 )then write(6,*) subname, ' ERROR: pctwet is negative!' write(6,*) 'n, pctwet = ', n, pctwet(n) - call abort() + call shr_sys_abort() end if if ( pcturb(n) < 0.0_r8 )then write(6,*) subname, ' ERROR: pcturb is negative!' write(6,*) 'n, pcturb = ', n, pcturb(n) - call abort() + call shr_sys_abort() end if if ( pctgla(n) < 0.0_r8 )then write(6,*) subname, ' ERROR: pctgla is negative!' write(6,*) 'n, pctgla = ', n, pctgla(n) - call abort() + call shr_sys_abort() end if suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) @@ -1184,7 +946,7 @@ subroutine normalizencheck_landuse(ldomain) write(6,*) '<= 100% before calling this subroutine' write(6,*) 'n, pctlak, pctwet, pcturb, pctgla = ', & n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) - call abort() + call shr_sys_abort() end if ! First normalize vegetated (natural veg + crop) cover so that the total of @@ -1208,7 +970,7 @@ subroutine normalizencheck_landuse(ldomain) if (abs(suma - 100._r8) > tol_loose) then write(6,*) subname, ' ERROR in rescaling veg based on (special excluding urban' write(6,*) 'suma = ', suma - call abort() + call shr_sys_abort() end if ! Now decrease the vegetated area to account for urban area. Urban needs to be @@ -1237,7 +999,7 @@ subroutine normalizencheck_landuse(ldomain) else write(6,*) subname, ' ERROR: trying to replace veg with urban,' write(6,*) 'but pcturb_excess exceeds current vegetation percent' - call abort() + call shr_sys_abort() end if end if @@ -1255,7 +1017,7 @@ subroutine normalizencheck_landuse(ldomain) write(6,*) 'n, suma, pctlak, pctwet, pctgla, pcturb, pctnatveg, pctcrop = ' write(6,*) n, suma, pctlak(n), pctwet(n), pctgla(n), pcturb(n), & pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() - call abort() + call shr_sys_abort() end if end do @@ -1306,7 +1068,7 @@ subroutine normalizencheck_landuse(ldomain) 'n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),pctnatveg(n),pctcrop(n),suma = ', & n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(),suma - call abort() + call shr_sys_abort() end if call pctnatpft(n)%set_pct_l2g(0._r8) call pctcft(n)%set_pct_l2g(0._r8) @@ -1318,7 +1080,7 @@ subroutine normalizencheck_landuse(ldomain) write (6,*) 'pctcft%pct_p2l = ', pctcft(n)%get_pct_p2l() write (6,*) 'pctnatpft%pct_l2g = ', pctnatpft(n)%get_pct_l2g() write (6,*) 'pctcft%pct_l2g = ', pctcft(n)%get_pct_l2g() - call abort() + call shr_sys_abort() end if suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) @@ -1326,7 +1088,7 @@ subroutine normalizencheck_landuse(ldomain) write (6,*) subname, 'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() - call abort() + call shr_sys_abort() end if suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() if ( abs(suma-100._r8) > 1.e-10_r8) then @@ -1335,7 +1097,7 @@ subroutine normalizencheck_landuse(ldomain) write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,sum= ', & n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), suma - call abort() + call shr_sys_abort() end if end do @@ -1356,7 +1118,7 @@ subroutine normalizencheck_landuse(ldomain) write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & n,pctlak(n),pctwet(n),pcturb(n),pctgla(n), & pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g() - call abort() + call shr_sys_abort() end if end do else @@ -1374,7 +1136,7 @@ subroutine normalizencheck_landuse(ldomain) write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,epsilon= ', & n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), epsilon(sum8) - call abort() + call shr_sys_abort() end if end do end if @@ -1384,7 +1146,7 @@ subroutine normalizencheck_landuse(ldomain) if (pftdata_mask(n) == 0 .and. (pctnatpft(n)%get_pct_l2g() > 0 .or. pctcft(n)%get_pct_l2g() > 0)) then write (6,*)'vegetation found outside the pft mask at n=',n write (6,*)'pctnatveg,pctcrop=', pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() - call abort() + call shr_sys_abort() end if end do @@ -1397,7 +1159,7 @@ subroutine normalizencheck_landuse(ldomain) do n = 1,ns_o if (abs(sum(urbn_classes(n,:)) - 100._r8) > 1.e-12_r8) then write(6,*) 'sum(urbn_classes(n,:)) != 100: ', n, sum(urbn_classes(n,:)) - call abort() + call shr_sys_abort() end if end do diff --git a/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 index 859ff9fe1a..0ca622d051 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 @@ -92,13 +92,13 @@ subroutine mkurban_pct(ldomain, tdomain, tgridmap, urbn_i, urbn_o, frac_dst) write(6,*) 'tdomain%ns = ', tdomain%ns write(6,*) 'size(urbn_o) = ', size(urbn_o) write(6,*) 'ldomain%ns = ', ldomain%ns - call abort() + call shr_sys_abort() end if if (size(frac_dst) /= ldomain%ns) then write(6,*) subname//' ERROR: array size inconsistencies' write(6,*) 'size(frac_dst) = ', size(frac_dst) write(6,*) 'ldomain%ns = ', ldomain%ns - call abort() + call shr_sys_abort() end if ! Error checks for domain and map consistencies @@ -118,7 +118,7 @@ subroutine mkurban_pct(ldomain, tdomain, tgridmap, urbn_i, urbn_o, frac_dst) if ((urbn_o(no)) > 100.000001_r8) then write (6,*) 'MKURBAN error: urban = ',urbn_o(no), & ' greater than 100.000001 for column, row = ',no - call abort() + call shr_sys_abort() end if enddo @@ -126,7 +126,7 @@ subroutine mkurban_pct(ldomain, tdomain, tgridmap, urbn_i, urbn_o, frac_dst) ! output grid that is land as determined by input grid allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() mask_r8 = tdomain%mask call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) @@ -190,7 +190,7 @@ subroutine mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, urbn_i, urbn_o, n write(6,*) subname//' ERROR: array size inconsistencies' write(6,*) 'size(frac_dst) = ', size(frac_dst) write(6,*) 'ldomain%ns = ', ldomain%ns - call abort() + call shr_sys_abort() end if ! ----------------------------------------------------------------- @@ -315,7 +315,7 @@ subroutine mkelev(ldomain, mapfname, datfname, varname, ndiag, elev_o) allocate(elev_i(ns_i), stat=ier) allocate(frac_dst(ns_o), stat=ier) if (ier /= 0) then - write(6,*)'mkelev allocation error'; call abort() + write(6,*)'mkelev allocation error'; call shr_sys_abort() end if write (6,*) 'Open elevation file: ', trim(datfname) diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 09f609d041..0b8e0c95b1 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -182,7 +182,7 @@ subroutine mkurban(ldomain, mapfname, datfname, ndiag, zero_out, & urbn_classes_gcell_o(ldomain%ns, numurbl), & frac_dst(ldomain%ns), & stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() ! Obtain frac_dst call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) @@ -244,7 +244,7 @@ subroutine mkurban(ldomain, mapfname, datfname, ndiag, zero_out, & ! they're needed to try to avoid unnecessary memory paging allocate(region_i(ns), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() call check_ret(nf_inq_varid (ncid, 'REGION_ID', varid), subname) call check_ret(nf_get_var_int (ncid, varid, region_i), subname) @@ -264,7 +264,7 @@ subroutine mkurban(ldomain, mapfname, datfname, ndiag, zero_out, & ' ERROR: max region value exceeds length of region dimension' write(6,*) 'max region value : ', max_region write(6,*) 'length of region dimension: ', dimlen - call abort() + call shr_sys_abort() end if ! Determine dominant region for each output cell @@ -351,14 +351,14 @@ subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) write(6,*) 'size(sums) = ', n_max write(6,*) 'size(classes_pct_tot, 1) = ', size(classes_pct_tot, 1) write(6,*) 'size(classes_pct_gcell, 1) = ', size(classes_pct_gcell, 1) - call abort() + call shr_sys_abort() end if if (size(classes_pct_tot, 2) /= size(classes_pct_gcell, 2)) then write(6,*) subname//' ERROR: array size mismatch' write(6,*) 'size(classes_pct_tot, 2) = ', size(classes_pct_tot, 2) write(6,*) 'size(classes_pct_gcell, 2) = ', size(classes_pct_gcell, 2) - call abort() + call shr_sys_abort() end if nclasses = size(classes_pct_gcell, 2) @@ -366,7 +366,7 @@ subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) write(6,*) subname//' ERROR: MD exceeds nclasses' write(6,*) 'MD = ', MD write(6,*) 'nclasses = ', nclasses - call abort() + call shr_sys_abort() end if ! Do the work @@ -389,7 +389,7 @@ subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) if (abs(suma/100._r8 - 1._r8) > relerr) then write(6,*) subname//' ERROR: sum does not equal 100 at point ', n write(6,*) 'suma = ', suma - call abort() + call shr_sys_abort() end if end do @@ -523,7 +523,7 @@ subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_ski write(6,*) modname//':'//subname//' ERROR: array size mismatch' write(6,*) 'size(region_o) = ', size(region_o) write(6,*) 'size(urbn_classes_gcell_o, 1) = ', size(urbn_classes_gcell_o, 1) - call abort() + call shr_sys_abort() end if if (size(urbn_classes_gcell_o, 2) /= numurbl) then write(6,*) modname//':'//subname//' ERROR: array size mismatch' @@ -546,17 +546,17 @@ subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_ski if (nlevurb_i /= nlevurb) then write(6,*)'MKURBANPAR: parameter nlevurb= ',nlevurb, & 'does not equal input dataset nlevurb= ',nlevurb_i - call abort() + call shr_sys_abort() endif if (numsolar_i /= numsolar) then write(6,*)'MKURBANPAR: parameter numsolar= ',numsolar, & 'does not equal input dataset numsolar= ',numsolar_i - call abort() + call shr_sys_abort() endif if (numrad_i /= numrad) then write(6,*)'MKURBANPAR: parameter numrad= ',numrad, & 'does not equal input dataset numrad= ',numrad_i - call abort() + call shr_sys_abort() endif ! Create an array that will hold the density indices @@ -574,7 +574,7 @@ subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_ski allocate(data_scalar_o(ns_o, numurbl), stat=ier) if (ier /= 0) then - write(6,*)'mkurbanpar allocation error'; call abort() + write(6,*)'mkurbanpar allocation error'; call shr_sys_abort() end if do p = 1, size(params_scalar) @@ -594,7 +594,7 @@ subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_ski allocate(data_rad_o(ns_o, numurbl, numrad, numsolar), stat=ier) if (ier /= 0) then - write(6,*)'mkurbanpar allocation error'; call abort() + write(6,*)'mkurbanpar allocation error'; call shr_sys_abort() end if allocate(extra_dims(2)) @@ -620,7 +620,7 @@ subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_ski if (len_trim(params_rad(p)%name) + len_trim(solar_suffix(m)) > len(varname)) then write(6,*) 'variable name exceeds length of varname' write(6,*) trim(params_rad(p)%name)//trim(solar_suffix(m)) - call abort() + call shr_sys_abort() end if varname = trim(params_rad(p)%name)//trim(solar_suffix(m)) call check_ret(nf_inq_varid(ncido, varname, varid), subname) @@ -637,7 +637,7 @@ subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_ski allocate(data_levurb_o(ns_o, numurbl, nlevurb), stat=ier) if (ier /= 0) then - write(6,*)'mkurbanpar allocation error'; call abort() + write(6,*)'mkurbanpar allocation error'; call shr_sys_abort() end if allocate(extra_dims(1)) @@ -722,7 +722,7 @@ subroutine lookup_and_check_err(varname, fill_val, check_invalid, & if (ierr /= 0) then write(6,*) modname//':'//subname//' ERROR in lookup_2d_netcdf for ', & trim(varname), ' class', k, ': err=', ierr - call abort() + call shr_sys_abort() end if if (check_invalid) then @@ -740,7 +740,7 @@ subroutine lookup_and_check_err(varname, fill_val, check_invalid, & if (.not. urban_skip_abort_on_invalid_data_check) then ! NOTE(bja, 2015-01) added to work around a ?bug? noted in ! /glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 - call abort() + call shr_sys_abort() end if end if end do diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index 569550f1e4..25dd8fc10d 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -313,16 +313,14 @@ subroutine check_namelist_input() end if #endif - outnc_1d = .true. if (mksrf_fgrid_mesh_ny == 1) then outnc_1d = .true. outnc_dims = 1 else - outnc_1d = .true. + outnc_1d = .false. outnc_dims = 2 end if - end subroutine check_namelist_input !=============================================================== @@ -374,47 +372,47 @@ subroutine write_namelist_input() write(ndiag,'(a)')' mesh for topography stats '//trim(mksrf_ftopostats_mesh) write(ndiag,'(a)')' mesh for VIC parameters '//trim(mksrf_fvic_mesh) - write(ndiag,'(a)')'mksrf_gridtype = '//trim(mksrf_gridtype) + write(ndiag,'(a)')' mksrf_gridtype = '//trim(mksrf_gridtype) if (mksrf_fdynuse /= ' ') then - write(ndiag,'(a)')'mksrf_fdynuse = '//trim(mksrf_fdynuse) + write(ndiag,'(a)')' mksrf_fdynuse = '//trim(mksrf_fdynuse) end if - write(ndiag,'(a)')'mksrf_fgrid_mesh = '//trim(mksrf_fgrid_mesh) + write(ndiag,'(a)')' mksrf_fgrid_mesh = '//trim(mksrf_fgrid_mesh) if (outnc_1d) then - write(ndiag,'(a)')'output file will be 1d format' + write(ndiag,'(a)')' output file will be 1d format' else - write(ndiag,'(a)')'fsurdat is 2d lat/lon grid' - write(ndiag,'(a,i8)')'nlon= ',mksrf_fgrid_mesh_nx - write(ndiag,'(a,i8)')'nlat= ',mksrf_fgrid_mesh_ny + write(ndiag,'(a)')' fsurdat is 2d lat/lon grid' end if - if ( outnc_large_files )then - write(ndiag,'(a)')'Output file in NetCDF 64-bit large_files format' + write(ndiag,'(a,i8)')' nlon= ',mksrf_fgrid_mesh_nx + write(ndiag,'(a,i8)')' nlat= ',mksrf_fgrid_mesh_ny + if ( outnc_large_files ) then + write(ndiag,'(a)')' Output file in NetCDF 64-bit large_files format' end if if ( outnc_double )then - write(ndiag,'(a)')'Output ALL data in file as 64-bit' + write(ndiag,'(a)')' Output ALL data in file as 64-bit' end if if ( outnc_vic )then - write(ndiag,'(a)')'Output VIC fields' + write(ndiag,'(a)')' Output VIC fields' end if if ( outnc_3dglc )then - write(ndiag,'(a)')'Output optional 3D glacier fields (mostly used for verification of the glacier model)' + write(ndiag,'(a)')' Output optional 3D glacier fields (mostly used for verification of the glacier model)' end if if ( outnc_3dglc )then - write(ndiag,'(a)')'Output optional 3D glacier fields (mostly used for verification of the glacier model)' + write(ndiag,'(a)')' Output optional 3D glacier fields (mostly used for verification of the glacier model)' end if if ( all_urban )then - write(ndiag,'(a)') 'Output ALL data in file as 100% urban' + write(ndiag,'(a)') ' Output ALL data in file as 100% urban' end if if ( no_inlandwet )then - write(ndiag,'(a)') 'Set wetland to 0% over land' + write(ndiag,'(a)') ' Set wetland to 0% over land' end if if (all_veg) then - write(ndiag,'(a)') 'Output ALL data in file as 100% vegetated' + write(ndiag,'(a)') ' Output ALL data in file as 100% vegetated' end if if (urban_skip_abort_on_invalid_data_check) then - write(ndiag, '(a)') "WARNING: aborting on invalid data check in urban has been disabled!" - write(ndiag, '(a)') "WARNING: urban data may be invalid!" + write(ndiag, '(a)') " WARNING: aborting on invalid data check in urban has been disabled!" + write(ndiag, '(a)') " WARNING: urban data may be invalid!" end if end if diff --git a/tools/mksurfdata_esmf/src/mkvocefMod.F90 b/tools/mksurfdata_esmf/src/mkvocefMod.F90 index 0d00dfca15..d40e435b93 100644 --- a/tools/mksurfdata_esmf/src/mkvocefMod.F90 +++ b/tools/mksurfdata_esmf/src/mkvocefMod.F90 @@ -101,7 +101,7 @@ subroutine mkvocef(ldomain, mapfname, datfname, ndiag, & allocate(ef_btr_i(ns_i), ef_fet_i(ns_i), ef_fdt_i(ns_i), & ef_shr_i(ns_i), ef_grs_i(ns_i), ef_crp_i(ns_i), & frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() write (6,*) 'Open VOC file: ', trim(datfname) call check_ret(nf_open(datfname, 0, ncid), subname) @@ -147,32 +147,32 @@ subroutine mkvocef(ldomain, mapfname, datfname, ndiag, & if ( ef_btr_o(no) < 0._r8 ) then write (6,*) 'MKVOCEF error: EF btr = ',ef_btr_o(no), & ' is negative for no = ',no - call abort() + call shr_sys_abort() end if if ( ef_fet_o(no) < 0._r8 ) then write (6,*) 'MKVOCEF error: EF fet = ',ef_fet_o(no), & ' is negative for no = ',no - call abort() + call shr_sys_abort() end if if ( ef_fdt_o(no) < 0._r8 ) then write (6,*) 'MKVOCEF error: EF fdt = ',ef_fdt_o(no), & ' is negative for no = ',no - call abort() + call shr_sys_abort() end if if ( ef_shr_o(no) < 0._r8 ) then write (6,*) 'MKVOCEF error: EF shr = ',ef_shr_o(no), & ' is negative for no = ',no - call abort() + call shr_sys_abort() end if if ( ef_grs_o(no) < 0._r8 ) then write (6,*) 'MKVOCEF error: EF grs = ',ef_grs_o(no), & ' is negative for no = ',no - call abort() + call shr_sys_abort() end if if ( ef_crp_o(no) < 0._r8 ) then write (6,*) 'MKVOCEF error: EF crp = ',ef_crp_o(no), & ' is negative for no = ',no - call abort() + call shr_sys_abort() end if enddo @@ -185,7 +185,7 @@ subroutine mkvocef(ldomain, mapfname, datfname, ndiag, & ! output grid that is land as determined by input grid allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() mask_r8 = tdomain%mask call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) diff --git a/tools/mksurfdata_esmf/src/run_mksurfdata b/tools/mksurfdata_esmf/src/run_mksurfdata index aa5e110aba..299519218b 100644 --- a/tools/mksurfdata_esmf/src/run_mksurfdata +++ b/tools/mksurfdata_esmf/src/run_mksurfdata @@ -20,5 +20,4 @@ mkdir -p $TMPDIR #make # -np {total_tasks} -cd /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata/run -mpiexec_mpt -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata +mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata diff --git a/tools/mksurfdata_esmf/src/shr_sys_mod.F90 b/tools/mksurfdata_esmf/src/shr_sys_mod.F90 index 76a898a058..9ce6b48d4d 100644 --- a/tools/mksurfdata_esmf/src/shr_sys_mod.F90 +++ b/tools/mksurfdata_esmf/src/shr_sys_mod.F90 @@ -43,9 +43,9 @@ subroutine shr_sys_getenv(name, val, rcode) !------------------------------------------------------------------------------- ! input/output variables - character(len=*) ,intent(in) :: name ! env var name - character(len=*) ,intent(out) :: val ! env var value - integer ,intent(out) :: rcode ! return code + character(len=*) ,intent(in) :: name ! env var name + character(len=*) ,intent(inout) :: val ! env var value + integer ,intent(out) :: rcode ! return code !----- local ----- integer :: lenname ! length of env var name From b2f605bc0eade1f2eb8e21f240559732eb54e934 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 23 Jan 2022 13:59:27 -0700 Subject: [PATCH 025/614] git organic to almost work - still need to adjust the mask in the input mesh to have the values from the land mask in the input data --- tools/mksurfdata_esmf/src/CMakeLists.txt | 1 + tools/mksurfdata_esmf/src/mkesmfMod.F90 | 43 +- tools/mksurfdata_esmf/src/mkfileMod.F90 | 39 +- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 1 - tools/mksurfdata_esmf/src/mkorganicMod.F90 | 203 ++++++ tools/mksurfdata_esmf/src/mkpioMod.F90 | 342 ++++++--- tools/mksurfdata_esmf/src/mksoilMod.F90 | 440 ++---------- tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 | 147 +--- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 286 ++++++++ tools/mksurfdata_esmf/src/mksurfdata | Bin 4141144 -> 4175456 bytes tools/mksurfdata_esmf/src/mksurfdata.F90 | 719 ++++++++++--------- tools/mksurfdata_esmf/src/mkutilsMod.F90 | 4 +- tools/mksurfdata_esmf/src/mkvarctl.F90 | 95 ++- tools/mksurfdata_esmf/src/run_mksurfdata | 2 +- tools/mksurfdata_map/src/mkncdio.F90 | 558 -------------- 15 files changed, 1259 insertions(+), 1621 deletions(-) create mode 100644 tools/mksurfdata_esmf/src/mkorganicMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mksoilcolMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkncdio.F90 diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 2699c3f2df..e4b94dde89 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -21,6 +21,7 @@ set(SRCFILES mkvarctl.F90 mkpioMod.F90 mkfileMod.F90 mklanwatMod.F90 + mkorganicMod.F90 mkesmfMod.F90 mkutilsMod.F90 mkchecksMod.F90 diff --git a/tools/mksurfdata_esmf/src/mkesmfMod.F90 b/tools/mksurfdata_esmf/src/mkesmfMod.F90 index 665cbf81c1..5515be33c5 100644 --- a/tools/mksurfdata_esmf/src/mkesmfMod.F90 +++ b/tools/mksurfdata_esmf/src/mkesmfMod.F90 @@ -10,6 +10,11 @@ module mkesmfMod public :: regrid_rawdata + interface regrid_rawdata + module procedure regrid_rawdata1d + module procedure regrid_rawdata2d + end interface regrid_rawdata + character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -17,7 +22,7 @@ module mkesmfMod contains !=============================================================== - subroutine regrid_rawdata(field_i, field_o, routehandle, data_i, data_o, rc) + subroutine regrid_rawdata1d(field_i, field_o, routehandle, data_i, data_o, rc) ! input/output variables type(ESMF_Field) , intent(in) :: field_i @@ -46,6 +51,40 @@ subroutine regrid_rawdata(field_i, field_o, routehandle, data_i, data_o, rc) data_o(:) = dataptr(:) call ESMF_VMLogMemInfo("After field regrid in regrid_data") - end subroutine regrid_rawdata + end subroutine regrid_rawdata1d + + !=============================================================== + subroutine regrid_rawdata2d(field_i, field_o, routehandle, data_i, data_o, rc) + + ! input/output variables + type(ESMF_Field) , intent(in) :: field_i + type(ESMF_Field) , intent(inout) :: field_o + type(ESMF_RouteHandle) , intent(inout) :: routehandle + real(r8) , intent(in) :: data_i(:,:) + real(r8) , intent(inout) :: data_o(:,:) + integer , intent(out) :: rc + + ! local variables + logical :: checkflag = .false. + integer :: n,l + real(r8), pointer :: dataptr(:,:) + ! -------------------------------------------- + + rc = ESMF_SUCCESS + + ! Interpolate data_i to data_o + call ESMF_VMLogMemInfo("Before field regrid in regrid_rawdata2d") + call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) + dataptr(:,:) = data_i(:,:) + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + dataptr(:,:) = 0._r8 + call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, & + termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + data_o(:,:) = dataptr(:,:) + call ESMF_VMLogMemInfo("After field regrid in regrid_rawdata2d") + + end subroutine regrid_rawdata2d end module mkesmfMod diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index e76a512ad0..8f4fd5d87b 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -15,7 +15,7 @@ module mkfileMod use mkharvestMod , only : mkharvest_units, harvestDataType #endif use mkpioMod ! TODO: add only - use mkvarctl + use mkvarctl implicit none private @@ -30,7 +30,7 @@ module mkfileMod !================================================================================= subroutine mkfile_fsurdat(nx, ny, mesh_model, dynlanduse, & - pctlak, pctwet, lakedepth) + pctlak, pctwet, lakedepth, organic) ! input/output variables integer , intent(in) :: nx @@ -40,7 +40,8 @@ subroutine mkfile_fsurdat(nx, ny, mesh_model, dynlanduse, & real(r8), pointer, intent(in) :: pctlak(:) ! percent of grid cell that is lake real(r8), pointer, intent(in) :: pctwet(:) ! percent of grid cell that is wetland real(r8), pointer, intent(in) :: lakedepth(:) ! lake depth (m) -#ifdef TODO + real(r8), pointer, intent(in) :: organic(:,:) ! organic +#ifdef TODO type(harvestDataType) , intent(in) :: harvdata #endif @@ -49,17 +50,19 @@ subroutine mkfile_fsurdat(nx, ny, mesh_model, dynlanduse, & type(file_desc_t) :: pioid character(len=256) :: varname character(len=256) :: longname - character(len=256) :: units + character(len=256) :: units integer :: xtype ! external type integer, allocatable :: ind1D(:) ! Indices of 1D harvest variables integer, allocatable :: ind2D(:) ! Indices of 2D harvest variables integer :: rcode - integer :: rc + integer :: rc integer :: n, i logical :: define_mode - type(io_desc_t) :: pio_iodesc + type(io_desc_t) :: pio_iodesc type(var_desc_t) :: pio_varid + character(len=256) :: lev1name real(r8), pointer :: rpointer1d(:) + real(r8), pointer :: rpointer2d(:,:) character(len=*), parameter :: subname=' (mkfile_fsurdat) ' !----------------------------------------------------------------------- @@ -127,7 +130,7 @@ subroutine mkfile_fsurdat(nx, ny, mesh_model, dynlanduse, & end if varname = 'LAKEDEPTH' - longname = 'lake depth' + longname = 'lake depth' units = 'm' rpointer1d => lakedepth if (define_mode) then @@ -141,12 +144,28 @@ subroutine mkfile_fsurdat(nx, ny, mesh_model, dynlanduse, & call pio_freedecomp(pioid, pio_iodesc) end if + varname = 'ORGANIC' + longname = 'organic matter density at soil levels' + units = 'kg/m3 (assumed carbon content 0.58 gC per gOM)' + lev1name = 'nlevsoi' + rpointer2d => organic + if (define_mode) then + call mkpio_def_spatial_var(pioid, trim(varname), xtype, trim(lev1name), trim(longname), trim(units)) + else + ! inquire about varid here + call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + call pio_write_darray(pioid, pio_varid, pio_iodesc, rpointer2d, rcode) + call pio_freedecomp(pioid, pio_iodesc) + end if + end if end do ! Close surface dataset call pio_closefile(pioid) - + if (root_task) then write (ndiag,'(72a1)') ("-",i=1,60) write (ndiag,'(a)')' land model surface data set successfully created for ' @@ -178,6 +197,8 @@ subroutine mkfile_define_dims(pioid, nx, ny, dynlanduse) rcode = pio_def_dim(pioid, 'lsmlon', nx, dimid) rcode = pio_def_dim(pioid, 'lsmlat', ny, dimid) end if + rcode = pio_def_dim(pioid, 'nlevsoi', nlevsoi, dimid) + rcode = pio_def_dim(pioid, 'time', PIO_UNLIMITED, dimid) if (.not. dynlanduse) then #ifdef TODO @@ -201,7 +222,7 @@ subroutine mkfile_define_atts(pioid, dynlanduse) ! input/output variables type(file_desc_t) , intent(in) :: pioid logical , intent(in) :: dynlanduse - + ! local variables integer :: values(8) ! temporary character(len=256) :: str ! global attribute string diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index ded81b86b9..b455a1ee00 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -126,7 +126,6 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regrid_data in lanwat") do no = 1,size(lake_o) - write(6,*)'DEBUG: n,lake_o = ',no,lake_o(no) if (lake_o(no) < 1.) lake_o(no) = 0. enddo diff --git a/tools/mksurfdata_esmf/src/mkorganicMod.F90 b/tools/mksurfdata_esmf/src/mkorganicMod.F90 new file mode 100644 index 0000000000..7a03a31690 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkorganicMod.F90 @@ -0,0 +1,203 @@ +module mkorganicMod + + ! make organic matter dataset + + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths + use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_ioformat, pio_iosystem + use mkesmfMod , only : regrid_rawdata + use mkutilsMod , only : chkerr + use mkvarctl , only : root_task, ndiag + use mkvarpar , only : nlevsoi + + implicit none + private + + public mkorganic ! Set organic soil + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + +!================================================================================= +contains +!================================================================================= + + subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) + + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o + real(r8) , intent(out) :: organic_o(:,:) ! output grid: %lake + integer , intent(out) :: rc + + ! local variables + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + type(file_desc_t) :: pioid + type(var_desc_t) :: pio_varid + type(io_desc_t) :: pio_iodesc + integer :: pio_vartype + integer :: ni,no + integer :: ns_i, ns_o + integer :: nlay + integer :: n, l ! indices + integer :: rcode, ier ! error status + integer :: srcMaskValue = -987987 ! spval for RH mask values + integer :: dstMaskValue = -987987 ! spval for RH mask values + integer :: srcTermProcessing_Value = 0 + integer :: ndims + integer , allocatable :: dimlengths(:) + real(r4), allocatable :: data_real(:,:) + real(r8), allocatable :: data_double(:,:) + real(r8), allocatable :: data_i(:,:) + real(r8), allocatable :: data_o(:,:) + character(len=256) :: varname + character(len=*), parameter :: subname = 'mkorganic' + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (root_task) then + write (ndiag,'(a)') ' Attempting to make organic mater dataset .....' + end if + + ! Set variable name in raw data file + varname = 'ORGANIC' + + ! Open raw data file - need to do this first to obtain ungridded dimension size + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) + + ! Get dimensions of raw data. + ! NOTE: + ! - raw data is dimensions (lon,lat,lev) + ! - input read from pio has dimensions(n,lev) + ! - esmf field dataptr has dimensions (lev,n) + allocate(dimlengths(3)) + call mkpio_get_dimlengths(pioid, trim(varname), ndims, dimlengths) + nlay = dimlengths(3) + if (nlay /= nlevsoi) then + write(6,*)'nlay, nlevsoi= ',nlay,nlevsoi,' do not match' + call shr_sys_abort() + end if + deallocate(dimlengths) + + ! Read in input mesh + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Create io descriptor for input raw data + ! This will query the raw data file for the dimensions of the variable varname and + ! create iodesc for either single or multi level input data + call ESMF_VMLogMemInfo("Before mkpio_iodesc in "//trim(subname)) + call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_iodesc in "//trim(subname)) + + ! Determine ns_i and allocate data_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + allocate(data_i(nlay,ns_i),stat=ier) + if (ier/=0) call shr_sys_abort() + + ! Determine ns_o and allocate data_o + ns_o = size(organic_o, dim=1) + allocate(data_o(nlay,ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() + + ! Read the input raw data (all levels read at once) + ! - levels are the innermost dimension for esmf fields + ! - levels are the outermost dimension in pio reads + ! Input data is read into (ns_i,nlay) array and then transferred to data_i(nlay,ns_i) + if (pio_vartype == PIO_REAL) then + write(6,*)'DEBUG: ns_i, nlay = ',ns_i, nlay + allocate(data_real(ns_i,nlay)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real, rcode) + do l = 1,nlay + do n = 1,ns_i + data_i(l,n) = real(data_real(n,l), kind=r8) + end do + end do + deallocate(data_real) + else if (pio_vartype == PIO_DOUBLE) then + allocate(data_double(ns_i,nlay)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double, rcode) + do l = 1,nlay + do n = 1,ns_i + data_i(l,n) = data_double(n,l) + end do + end do + deallocate(data_double) + else + call shr_sys_abort(subName//"ERROR: only real and double types are supported") + end if + call ESMF_VMLogMemInfo("After read_darray in "//trim(subname)) + + ! Create field on input mesh - using dimension information from raw data file + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/1/), ungriddedUbound=(/nlay/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After field_i creation in "//trim(subname)) + + ! Create field on model model + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/1/), ungriddedUbound=(/nlay/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After field_o creation in "//trim(subname)) + + ! Create route handle to map field_model to field_data + call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + !srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_FRACAREA, & + srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) + + ! Regrid raw data to model resolution + call regrid_rawdata(field_i, field_o, routehandle, data_i, data_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regrid_data in "//trim(subname)) + + ! Close the file and free the iodesc and deallocate memory + call pio_closefile(pioid) + call pio_freedecomp(pio_iosystem, pio_iodesc) + call ESMF_VMLogMemInfo("After pio_freedecomp in "//trim(subname)) + + ! Now compute organic_o - need to remember that nlay is innermost dimension in data_o + ! but outermost dimension in organic_o + do l = 1,nlevsoi + do n = 1,size(organic_o, dim=1) + organic_o(n,l) = data_o(l,n) + if ((organic_o(n,l)) > 130.000001_r8) then + write (6,*) trim(subname)//' error: organic = ',organic_o(n,l), & + ' greater than 130.000001 for n,lev ',n,l + call shr_sys_abort() + end if + enddo + end do + + ! Release memory + ! TODO: something is hanging here + ! call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + ! call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + ! call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) + + if (root_task) then + write (ndiag,'(a,i8)') 'Successfully made organic matter ' + end if + + end subroutine mkorganic + +end module mkorganicMod diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 7978bf1a97..10c44f086f 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -5,7 +5,7 @@ module mkpioMod use shr_kind_mod , only : r8 => shr_kind_r8, cl => shr_kind_cl, cs => shr_kind_cs, r4 => shr_kind_r4 use shr_sys_mod , only : shr_sys_abort use mkutilsMod , only : chkerr - use mkvarctl , only : root_task, ndiag, mpicom + use mkvarctl , only : root_task, ndiag, mpicom, outnc_1d implicit none private @@ -17,11 +17,12 @@ module mkpioMod public :: mkpio_iodesc_output public :: mkpio_wopen public :: mkpio_close - public :: mkpio_defvar public :: mkpio_def_spatial_var - public :: mkpio_get_dim_lengths + public :: mkpio_get_dimlengths public :: mkpio_put_time_slice + private :: mkpio_defvar + interface mkpio_def_spatial_var module procedure mkpio_def_spatial_var_0lev module procedure mkpio_def_spatial_var_1lev @@ -74,9 +75,9 @@ subroutine mkpio_get_rawdata(filename, varname, mesh_i, data_i, rc) rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(filename), pio_nowrite) call ESMF_VMLogMemInfo("After pio_openfile in regrid_data") - ! TODO: put this in the calling file call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_iodesc in regrid_data") if (pio_vartype == PIO_REAL) then allocate(data_real(lsize)) @@ -115,20 +116,20 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, type(ESMF_DistGrid) :: distGrid integer :: n, ndims integer, pointer :: compdof(:) + integer, allocatable :: compdof3d(:) integer, allocatable :: dimids(:) integer, allocatable :: dimlens(:) + character(len=cs) :: dimname integer :: lsize + integer :: nlev + integer :: cnt, m + integer :: offset integer :: rCode ! pio return code (only used when pio error handling is PIO_BCAST_ERROR) - character(*), parameter :: subname = '(shr_strdata_set_stream_iodesc) ' + character(*), parameter :: subname = '(mkpio_iodesc_rawdata) ' !------------------------------------------------------------------------------- rc = ESMF_SUCCESS - !if (root_task) then - !write(ndiag,'(a,i8, i8)') 'setting iodesc for : '//trim(varname)// & - !' with dimlens(1), dimlens2 = ',dimlens(1),dimlens(2) - !end if - call ESMF_VMLogMemInfo("Beginning setting compdof") call ESMF_MeshGet(mesh, elementdistGrid=distGrid, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -154,22 +155,212 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, do n = 1, ndims rcode = pio_inq_dimlen(pioid, dimids(n), dimlens(n)) end do + rcode = pio_inq_dimname(pioid, dimids(ndims), dimname) call ESMF_VMLogMemInfo("End getting dims") + ! Create compdof3d if needed + ! Assume that input data is always lon,lat as first two dimensions + nlev = 0 + offset = dimlens(1)*dimlens(2) + if (ndims == 3 .and. trim(dimname) /= 'time') then + nlev = dimlens(3) + else if (ndims == 3 .and. trim(dimname) == 'time') then + ! do nothing - keep nlev at 0 + else if (ndims == 4 .and. trim(dimname) /= 'time') then + nlev = dimlens(3)*dimlens(4) + else if (ndims == 4 .and. trim(dimname) == 'time') then + nlev = dimlens(3) + end if + + if (nlev > 0) then + allocate(compdof3d(nlev*lsize)) + cnt = 0 + do n = 1,nlev + do m = 1,size(compdof) + cnt = cnt + 1 + compdof3d(cnt) = (n-1)*offset + compdof(m) + enddo + enddo + end if + ! determine io descriptor for this variable - if (ndims == 1) then - call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) - else if (ndims == 2) then + if (ndims == 2) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + if (root_task) then + write(ndiag,'(a,i8,i8)') ' set iodesc for rawdata: '//trim(varname)//' with dim(1),dim(2) = ',& + dimlens(1),dimlens(2) + end if + else if (ndims == 3) then + if (trim(dimname) == 'time') then + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + if (root_task) then + write(ndiag,'(a,i8,i8)') ' set iodesc for rawdata: '//trim(varname)//' with dim(1),dim(2) = ',& + dimlens(1),dimlens(2) + end if + else + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) + if (root_task) then + write(ndiag,'(a,i8,i8,i8)') ' set iodesc for rawdata: '//trim(varname)//' with dim(1),dim(2),dim(3) = ',& + dimlens(1),dimlens(2),dimlens(3) + end if + end if + else if (ndims == 4) then + if (trim(dimname) == 'time') then + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) + if (root_task) then + write(ndiag,'(a,i8,i8,i8)') ' set iodesc for rawdata: '//trim(varname)//' with dim(1),dim(2),dim(3) = ',& + dimlens(1),dimlens(2),dimlens(3) + end if + else + call shr_sys_abort('for lon/lat support up to 3 spatial dims plus a time dim') + end if else - call shr_sys_abort('rawdata input must have ndims either 1 or 2') + call shr_sys_abort('rawdata input for variable '//trim(varname)//' must have ndims either 2, 3 or 4') end if ! deallocate memory deallocate(compdof) + if (allocated(compdof3d)) deallocate(compdof3d) end subroutine mkpio_iodesc_rawdata + !=============================================================== + subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) + + ! Create pio_iodesc for varname + + ! input/output variables + type(file_desc_t) , intent(inout) :: pioid + character(len=*) , intent(in) :: varname + type(ESMF_Mesh) , intent(in) :: mesh + type(io_desc_t) , intent(inout) :: pio_iodesc + integer , intent(out) :: rc + + ! local variables + type(ESMF_DistGrid) :: distGrid + integer :: n, ndims + integer, allocatable :: compdof(:) + integer, allocatable :: compdof3d(:) + integer, allocatable :: dimids(:) + integer, allocatable :: dimlens(:) + character(len=cs) :: dimname + integer :: lsize + integer :: nlev + integer :: cnt, m + integer :: offset + type(var_desc_t) :: pio_varid + integer :: pio_vartype + integer :: rCode ! pio return code (only used when pio error handling is PIO_BCAST_ERROR) + character(*), parameter :: subname = '(shr_strdata_set_stream_iodesc) ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (root_task) then + write(ndiag,'(a)') 'setting iodesc for : '//trim(varname) + end if + + ! get pio variable id, type and dimension information + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + rcode = pio_inq_vartype(pioid, pio_varid, pio_vartype) + rcode = pio_inq_varndims(pioid, pio_varid, ndims) + allocate(dimids(ndims)) + allocate(dimlens(ndims)) + rcode = pio_inq_vardimid(pioid, pio_varid, dimids(1:ndims)) + do n = 1, ndims + rcode = pio_inq_dimlen(pioid, dimids(n), dimlens(n)) + end do + rcode = pio_inq_dimname(pioid, dimids(ndims), dimname) + + ! Get compdof from mesh + call ESMF_MeshGet(mesh, elementdistGrid=distGrid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_DistGridGet(distGrid, localDe=0, elementCount=lsize, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(compdof(lsize)) + call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=compdof, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Create compdof3d if needed + nlev = 0 + if (outnc_1d) then + offset = dimlens(1) + if (ndims == 2 .and. trim(dimname) /= 'time') then + nlev = dimlens(2) + else if (ndims == 3 .and. trim(dimname) == 'time') then + nlev = dimlens(2) + else if (ndims == 3 .and. trim(dimname) /= 'time') then + nlev = dimlens(2)*dimlens(3) + end if + else + offset = dimlens(1)*dimlens(2) + if (ndims == 3 .and. trim(dimname) /= 'time') then + nlev = dimlens(3) + else if (ndims == 3 .and. trim(dimname) == 'time') then + ! do nothing - keep nlev at 0 + else if (ndims == 4 .and. trim(dimname) /= 'time') then + nlev = dimlens(3)*dimlens(4) + else if (ndims == 4 .and. trim(dimname) == 'time') then + nlev = dimlens(3) + end if + end if + + if (nlev > 0) then + allocate(compdof3d(nlev*lsize)) + cnt = 0 + do n = 1,nlev + do m = 1,size(compdof) + cnt = cnt + 1 + compdof3d(cnt) = (n-1)*offset + compdof(m) + enddo + enddo + end if + + ! determine io descriptor for this variable + if (outnc_1d) then + ! Assume that can have (gridcell), (gridcell,lev), (gridcell,lev,time) + ! Where lev would correspond to an undistributed dimension in esmf + if (ndims == 1) then + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) + else if (ndims == 2) then + if (trim(dimname) == 'time') then + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) + else + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + end if + else if (ndims == 3) then + if (trim(dimname) == 'time') then + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + else + call shr_sys_abort('support on 2 dimensions in addition to a time dimension when outnc_1d is true') + end if + end if + else + ! Assume that can have (lon,lat), (lon,lat,lev), (lon,lat,time), (lon,lat,lev,time) + ! Where lev would correspond to an undistributed dimension in esmf + if (ndims == 2) then + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + else if (ndims == 3) then + if (trim(dimname) == 'time') then + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + else + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) + end if + else if (ndims == 4) then + if (trim(dimname) == 'time') then + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) + else + call shr_sys_abort('for lon/lat support up to 3 spatial dims plus a time dim') + end if + end if + end if + + ! deallocate memory + deallocate(compdof) + if (allocated(compdof3d)) deallocate(compdof3d) + + end subroutine mkpio_iodesc_output + !=============================================================================== logical function mkpio_file_exists(filename) @@ -387,8 +578,6 @@ subroutine mkpio_def_spatial_var_0lev(pioid, varname, xtype, long_name, units) ! Define a spatial netCDF variable (convenience wrapper to mkpio_defvar) ! The variable in question has ONLY spatial dimensions (no level or time dimensions) - use mkvarctl, only : outnc_1d - ! !ARGUMENTS: type(file_desc_t) , intent(in) :: pioid character(len=*) , intent(in) :: varname ! variable name @@ -419,8 +608,6 @@ subroutine mkpio_def_spatial_var_1lev(pioid, varname, xtype, lev1name, long_name ! The variable in question has one level (or time) dimension in addition to its ! spatial dimensions - use mkvarctl, only : outnc_1d - ! !ARGUMENTS: type(file_desc_t) , intent(in) :: pioid character(len=*) , intent(in) :: varname ! variable name @@ -448,25 +635,21 @@ end subroutine mkpio_def_spatial_var_1lev !----------------------------------------------------------------------- subroutine mkpio_def_spatial_var_2lev(pioid, varname, xtype, lev1name, lev2name, long_name, units) ! - ! !DESCRIPTION: ! Define a spatial netCDF variable (convenience wrapper to mkpio_defvar) ! ! The variable in question has two level (or time) dimensions in addition to its ! spatial dimensions ! - ! !USES: - use mkvarctl, only : outnc_1d - ! - ! !ARGUMENTS: - type(file_desc_t) , intent(in) :: pioid - character(len=*) , intent(in) :: varname ! variable name - integer , intent(in) :: xtype ! external type - character(len=*) , intent(in) :: lev1name ! name of first level (or time) dimension - character(len=*) , intent(in) :: lev2name ! name of second level (or time) dimension - character(len=*) , intent(in) :: long_name ! attribute - character(len=*) , intent(in) :: units ! attribute + ! input/output variables + type(file_desc_t) , intent(in) :: pioid + character(len=*) , intent(in) :: varname ! variable name + integer , intent(in) :: xtype ! external type + character(len=*) , intent(in) :: lev1name ! name of first level (or time) dimension + character(len=*) , intent(in) :: lev2name ! name of second level (or time) dimension + character(len=*) , intent(in) :: long_name ! attribute + character(len=*) , intent(in) :: units ! attribute - ! !LOCAL VARIABLES: + ! local variables: character(len=*), parameter :: subname = 'mkpio_def_spatial_var_2lev' !----------------------------------------------------------------------- @@ -527,7 +710,7 @@ subroutine mkpio_put_time_slice_2d(pioid, pio_varid, pio_iodesc, time_index, dat end subroutine mkpio_put_time_slice_2d !=============================================================== - subroutine mkpio_get_dim_lengths(pioid, varname, ndims, dim_lengths) + subroutine mkpio_get_dimlengths(pioid, varname, ndims, dimlengths) ! Returns the number of dimensions and an array containing the dimension lengths of a ! variable in an open netcdf file. @@ -540,106 +723,29 @@ subroutine mkpio_get_dim_lengths(pioid, varname, ndims, dim_lengths) type(file_desc_t) , intent(in) :: pioid character(len=*) , intent(in) :: varname ! name of variable of interest integer , intent(out) :: ndims ! number of dimensions of variable - integer , intent(out) :: dim_lengths(:) ! lengths of dimensions of variable + integer , intent(out) :: dimlengths(:) ! lengths of dimensions of variable ! ! local variables type(var_desc_t) :: pio_varid - integer :: dimids(size(dim_lengths)) + integer :: dimids(size(dimlengths)) integer :: i integer :: rcode - character(len=*), parameter :: subname = 'get_dim_lengths' + character(len=*), parameter :: subname = 'mkpio_get_dimlengths' !------------------------------------------------------------------------------ rcode = pio_inq_varid(pioid, trim(varname), pio_varid) rcode = pio_inq_varndims(pioid, pio_varid, ndims) - if (ndims > size(dim_lengths)) then - call shr_sys_abort(trim(subname)//' ERROR: dim_lengths too small') - end if - - dim_lengths(:) = 0 ! pre-fill with 0 so we won't have garbage in elements past ndims - do i = 1, ndims - rcode = pio_inq_dimlen(pioid, dimids(i), dim_lengths(i)) - end do - - end subroutine mkpio_get_dim_lengths - - !=============================================================== - subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) - - ! Write variable varname to output file - - ! input/output variables - type(file_desc_t) , intent(inout) :: pioid - character(len=*) , intent(in) :: varname - type(ESMF_Mesh) , intent(in) :: mesh - type(io_desc_t) , intent(inout) :: pio_iodesc - - integer , intent(out) :: rc - - ! local variables - type(ESMF_DistGrid) :: distGrid - integer :: n, ndims - integer, pointer :: compdof(:) - integer, allocatable :: dimids(:) - integer, allocatable :: dimlens(:) - integer :: lsize - type(var_desc_t) :: pio_varid - integer :: pio_vartype - character(len=cs) :: dimname - integer :: rCode ! pio return code (only used when pio error handling is PIO_BCAST_ERROR) - character(*), parameter :: subname = '(shr_strdata_set_stream_iodesc) ' - !------------------------------------------------------------------------------- - - rc = ESMF_SUCCESS - - if (root_task) then - !write(ndiag,'(a,i8, i8)') 'setting iodesc for : '//trim(varname)//' with dimlens(1), dimlens2 = ',dimlens(1),dimlens(2) - write(ndiag,'(a)') 'setting iodesc for : '//trim(varname) + if (ndims > size(dimlengths)) then + call shr_sys_abort(trim(subname)//' ERROR: dimlengths too small') end if - call ESMF_MeshGet(mesh, elementdistGrid=distGrid, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_DistGridGet(distGrid, localDe=0, elementCount=lsize, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(compdof(lsize)) - call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=compdof, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! get pio variable id, type and number of dimensions - rcode = pio_inq_varid(pioid, trim(varname), pio_varid) - rcode = pio_inq_vartype(pioid, pio_varid, pio_vartype) - rcode = pio_inq_varndims(pioid, pio_varid, ndims) - - ! get variable dimension sizes - allocate(dimids(ndims)) - allocate(dimlens(ndims)) rcode = pio_inq_vardimid(pioid, pio_varid, dimids(1:ndims)) - do n = 1, ndims - rcode = pio_inq_dimlen(pioid, dimids(n), dimlens(n)) + dimlengths(:) = 0 ! pre-fill with 0 so we won't have garbage in elements past ndims + do i = 1, ndims + rcode = pio_inq_dimlen(pioid, dimids(i), dimlengths(i)) end do - ! determine io descriptor for this variable - if (ndims == 1) then - call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) - else if (ndims == 2) then - if (trim(dimname) == 'time' .or. trim(dimname) == 'nt') then - call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) - else - call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) - end if - else if (ndims == 3) then - if (trim(dimname) == 'time' .or. trim(dimname) == 'nt') then - call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) - else - call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof, pio_iodesc) - end if - else if (ndims == 4) then - end if - - ! deallocate memory - deallocate(compdof) - - end subroutine mkpio_iodesc_output + end subroutine mkpio_get_dimlengths end module mkpioMod diff --git a/tools/mksurfdata_esmf/src/mksoilMod.F90 b/tools/mksurfdata_esmf/src/mksoilMod.F90 index bd68e779c8..cdcfb6c71f 100644 --- a/tools/mksurfdata_esmf/src/mksoilMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilMod.F90 @@ -1,12 +1,14 @@ module mksoilMod + implicit none + private ! By default make data private + !----------------------------------------------------------------------- - ! Make soil data (texture, color and organic) + ! Make soil data (texture) !----------------------------------------------------------------------- use shr_kind_mod, only : r8 => shr_kind_r8, r4=>shr_kind_r4 - use mkdomainMod , only : domain_checksame - use mksoilUtilsMod, only : mkrank, dominant_soil_color + use mksoilUtilsMod, only : mkrank implicit none private ! By default make data private @@ -14,8 +16,6 @@ module mksoilMod public mksoilInit ! Soil Initialization public mksoilAtt ! Add attributes to output file public mksoiltex ! Set soil texture - public mkorganic ! Set organic soil - public mksoilcol ! Set soil color public mkfmax ! Make percent fmax private :: mksoiltexInit ! Soil texture Initialization @@ -29,9 +29,9 @@ module mksoilMod integer , parameter :: unsetcol = -999 ! flag to indicate soil color NOT set integer , public :: soil_color= unsetcol ! soil color to override with -!=============================================================== +!================================================================================= contains -!=============================================================== +!================================================================================= subroutine mksoilInit( ) @@ -43,12 +43,12 @@ subroutine mksoilInit( ) end subroutine mksoilInit - !----------------------------------------------------------------------- + !========================================================================== subroutine mksoiltexInit( ) - + ! ! Initialize of make soil texture - - ! !LOCAL VARIABLES: + ! + ! local variables: real(r8) :: sumtex character(len=32) :: subname = 'mksoiltexInit' !----------------------------------------------------------------------- @@ -75,7 +75,7 @@ subroutine mksoiltexInit( ) end subroutine mksoiltexInit - !----------------------------------------------------------------------- + !========================================================================== subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) ! make %sand and %clay from IGBP soil data, which includes @@ -179,81 +179,29 @@ subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) call check_ret(nf_close(ncid), subname) - ! Compute local fields _o - if (soil_sand==unset .and. soil_clay==unset) then - - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call shr_sys_abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! kmap_max are the maximum number of mapunits that will consider on - ! any output gridcell - this is set currently above and can be changed - ! kmap(:) are the mapunit values on the input grid - ! kwgt(:) are the weights on the input grid - - allocate(novr(ns_o)) - novr(:) = 0 - do n = 1,tgridmap%ns - ni = tgridmap%src_indx(n) - if (tdomain%mask(ni) > 0) then - no = tgridmap%dst_indx(n) - novr(no) = novr(no) + 1 + ! TODO: create an array that is size of (ns_i,mapunits) + ! read in mapunits + allocate(mask_mapuntis(ns_i, mapunits)) + mask_mapunits_i(:,:) = 0._r8 + do ni = 1,ns_i + do nmap = 1,mapunits + if (mapunits(ni,nmap) == nmap) then + mask_mapunits_i(ni,nmap) = 1._r8 end if end do - maxovr = maxval(novr(:)) - kmap_max = min(maxovr,max(kmap_max_min,km_mx_ns_prod/ns_o)) - deallocate(novr) + end do - write(6,*)'kmap_max= ',kmap_max,' maxovr= ',maxovr,' ns_o= ',ns_o,' size= ',(kmap_max+1)*ns_o - allocate(kmap(0:kmap_max,ns_o), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(kwgt(0:kmap_max,ns_o), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(kmax(ns_o), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(wst(0:kmap_max), stat=ier) - if (ier/=0) call shr_sys_abort() - - kwgt(:,:) = 0. - kmap(:,:) = 0 - kmax(:) = 0 - - do n = 1,tgridmap%ns - ni = tgridmap%src_indx(n) - no = tgridmap%dst_indx(n) - wt = tgridmap%wovr(n) * tdomain%mask(ni) - if (wt > 0._r8) then - k = mapunit_i(ni) - found = .false. - do l = 0,kmax(no) - if (k == kmap(l,no)) then - kwgt(l,no) = kwgt(l,no) + wt - found = .true. - exit - end if - end do - if (.not. found) then - kmax(no) = kmax(no) + 1 - if (kmax(no) > kmap_max) then - write(6,*)'kmax is > kmap_max= ',kmax(no), 'kmap_max = ', & - kmap_max,' for no = ',no - write(6,*)'reset kmap_max in mksoilMod to a greater value' - call shr_sys_abort() - end if - kmap(kmax(no),no) = k - kwgt(kmax(no),no) = wt - end if - end if - enddo + ! Compute local fields _o + if (soil_sand==unset .and. soil_clay==unset) then + ! Now map mask_mapunits_i to mask_mapunits_o + ! result is mask_mapunits_o(no_nmap) + do no = 1,ns_o + do nmap = 1,mapunits + kmap(no) = maxval(mask_mapunits_o(no,:)) + end do + end do end if do no = 1,ns_o @@ -288,30 +236,24 @@ subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) ! c. If this has no data or if there isn't a second most dominant ! mapunit, use loam for soil texture - if (soil_sand/=unset .and. soil_clay/=unset) then !---soil texture is input + if (soil_sand/=unset .and. soil_clay/=unset) then + ! force soil texture to be input do l = 1, nlay sand_o(no,l) = soil_sand clay_o(no,l) = soil_clay end do - else if (k1 /= 0) then !---not 'no data' + else if (kmap(no) /= 0) then do l = 1, nlay sand_o(no,l) = sand_i(k1,l) clay_o(no,l) = clay_i(k1,l) end do - else !---if (k1 == 0) then - if (k2 == 0 .or. k2 == miss) then !---no data - do l = 1, nlay - sand_o(no,l) = 43. !---use loam - clay_o(no,l) = 18. - end do - else !---if (k2 /= 0 and /= miss) - do l = 1, nlay - sand_o(no,l) = sand_i(k2,l) - clay_o(no,l) = clay_i(k2,l) - end do - end if !---end of k2 if-block + else + ! kmap(no) = 0 + do l = 1, nlay + sand_o(no,l) = 43. !---use loam + clay_o(no,l) = 18. + end do end if !---end of k1 if-block - enddo if (soil_sand==unset .and. soil_clay==unset) then @@ -433,7 +375,7 @@ subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) end subroutine mksoiltex - !----------------------------------------------------------------------- + !========================================================================== subroutine mksoilcolInit( ) ! ! Initialize of make soil color @@ -454,298 +396,12 @@ subroutine mksoilcolInit( ) end subroutine mksoilcolInit - !----------------------------------------------------------------------- - subroutine mksoilcol(ldomain, mapfname, datfname, ndiag, & - soil_color_o, nsoicol) - ! - ! make %sand and %clay from IGBP soil data, which includes - ! igbp soil 'mapunits' and their corresponding textures - ! - use mkvarpar - use mkvarctl - use mkncdio - - ! !ARGUMENTS: - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - integer , intent(out):: soil_color_o(:) ! soil color classes - integer , intent(out):: nsoicol ! number of soil colors - - ! !LOCAL VARIABLES: - real(r8), allocatable :: gast_i(:) ! global area, by surface type - real(r8), allocatable :: gast_o(:) ! global area, by surface type - integer , allocatable :: soil_color_i(:) ! input grid: BATS soil color - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - character(len=35), allocatable :: col(:) ! name of each color - integer :: k,l,m,ni,no,ns_i,ns_o ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mksoilcol' - !----------------------------------------------------------------------- - - write (6,*) 'Attempting to make soil color classes .....' - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ns_o = ldomain%ns - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - allocate(soil_color_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call shr_sys_abort() - - write (6,*) 'Open soil color file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'SOIL_COLOR', varid), subname) - call check_ret(nf_get_var_int (ncid, varid, soil_color_i), subname) - call check_ret(nf_close(ncid), subname) - - nsoicol = maxval(soil_color_i) - write(6,*)'nsoicol = ',nsoicol - - allocate(gast_i(0:nsoicol),gast_o(0:nsoicol),col(0:nsoicol)) - - ! ----------------------------------------------------------------- - ! Define the model color classes: 0 to nsoicol - ! ----------------------------------------------------------------- - - if (nsoicol == 20) then - col(0) = 'no soil ' - col(1) = 'class 1: light ' - col(2) = 'class 2: ' - col(3) = 'class 3: ' - col(4) = 'class 4: ' - col(5) = 'class 5: ' - col(6) = 'class 6: ' - col(7) = 'class 7: ' - col(8) = 'class 8: ' - col(9) = 'class 9: ' - col(10) = 'class 10: ' - col(11) = 'class 11: ' - col(12) = 'class 12: ' - col(13) = 'class 13: ' - col(14) = 'class 14: ' - col(15) = 'class 15: ' - col(16) = 'class 16: ' - col(17) = 'class 17: ' - col(18) = 'class 18: ' - col(19) = 'class 19: ' - col(20) = 'class 20: dark ' - else if (nsoicol == 8) then - col(0) = 'no soil ' - col(1) = 'class 1: light ' - col(2) = 'class 2: ' - col(3) = 'class 3: ' - col(4) = 'class 4: ' - col(5) = 'class 5: ' - col(6) = 'class 6: ' - col(7) = 'class 7: ' - col(8) = 'class 8: dark ' - else - write(6,*)'nsoicol value of ',nsoicol,' is not currently supported' - call shr_sys_abort() - end if - - ! Error check soil_color if it is set - if ( soil_color /= unsetcol )then - - if ( soil_color > nsoicol )then - write(6,*)'soil_color is out of range = ', soil_color - call shr_sys_abort() - end if - - do no = 1,ns_o - soil_color_o(no) = soil_color - end do - - else - - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine dominant soil color for each output cell - - call dominant_soil_color( & - tgridmap = tgridmap, & - mask_i = tdomain%mask, & - soil_color_i = soil_color_i, & - nsoicol = nsoicol, & - soil_color_o = soil_color_o) - - ! Global sum of output field - - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - end if - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - if ( soil_color == unsetcol )then - call gridmap_clean(tgridmap) - end if - deallocate (soil_color_i,gast_i,gast_o,col, frac_dst, mask_r8) - - write (6,*) 'Successfully made soil color classes' - write (6,*) - - end subroutine mksoilcol - - !----------------------------------------------------------------------- - subroutine mkorganic(ldomain, mapfname, datfname, ndiag, organic_o) - ! - ! make organic matter dataset - ! - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio - - ! !ARGUMENTS: - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: organic_o(:,:) ! output grid: - - ! !LOCAL VARIABLES: - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: organic_i(:,:) ! input grid: total column organic matter - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: gomlev_i ! input grid: global organic on lev - real(r8) :: garea_i ! input grid: global area - real(r8) :: gomlev_o ! output grid: global organic on lev - real(r8) :: garea_o ! output grid: global area - integer :: k,n,m,ni,no,ns_i ! indices - integer :: lev ! level index - integer :: nlay ! number of soil layers - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mkorganic' - !----------------------------------------------------------------------- - - write (6,*) 'Attempting to make organic matter dataset .....' - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - - write (6,*) 'Open soil organic file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - call check_ret(nf_inq_dimid (ncid, 'number_of_layers', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, nlay), subname) - - allocate(organic_i(ns_i,nlay),stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(frac_dst(ldomain%ns),stat=ier) - if (ier/=0) call shr_sys_abort() - - if (nlay /= nlevsoi) then - write(6,*)'nlay, nlevsoi= ',nlay,nlevsoi,' do not match' - call shr_sys_abort() - end if - - call check_ret(nf_inq_varid (ncid, 'ORGANIC', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, organic_i), subname) - - call check_ret(nf_close(ncid), subname) - - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. - - call gridmap_mapread(tgridmap, mapfname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - do lev = 1,nlay - call gridmap_areaave_srcmask(tgridmap, organic_i(:,lev), organic_o(:,lev), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - end do - - do lev = 1,nlevsoi - - ! Check for conservation - - do no = 1,ldomain%ns - if ((organic_o(no,lev)) > 130.000001_r8) then - write (6,*) 'MKORGANIC error: organic = ',organic_o(no,lev), & - ' greater than 130.000001 for column, row = ',no - call shr_sys_abort() - end if - enddo - - write (6,*) 'Successfully made organic matter, level = ', lev - - end do ! lev - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (organic_i) - deallocate (frac_dst) - - write (6,*) 'Successfully made organic matter' - write(6,*) - - end subroutine mkorganic - - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mksoilfmaxInit - ! - ! !INTERFACE: + !========================================================================== subroutine mksoilfmaxInit( ) ! - ! !DESCRIPTION: ! Initialize of make soil fmax - ! !USES: - ! - ! !ARGUMENTS: - implicit none - ! - ! !REVISION HISTORY: - ! Author: Erik Kluzek ! - ! - ! !LOCAL VARIABLES: - !EOP + ! local variables: real(r8) :: sumtex character(len=32) :: subname = 'mksoilfmaxInit' !----------------------------------------------------------------------- @@ -761,12 +417,7 @@ subroutine mksoilfmaxInit( ) end subroutine mksoilfmaxInit - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkfmax - ! - ! !INTERFACE: + !========================================================================== subroutine mkfmax(ldomain, mapfname, datfname, ndiag, fmax_o) ! ! !DESCRIPTION: @@ -1012,11 +663,6 @@ subroutine mksoilAtt( ncid, dynlanduse, xtype ) lev1name='nlevsoi', & long_name='percent clay', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='ORGANIC', xtype=xtype, & - lev1name='nlevsoi', & - long_name='organic matter density at soil levels', & - units='kg/m3 (assumed carbon content 0.58 gC per gOM)') - call ncd_def_spatial_var(ncid=ncid, varname='FMAX', xtype=xtype, & long_name='maximum fractional saturated area', units='unitless') diff --git a/tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 b/tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 index d355a29d84..d4a274189f 100644 --- a/tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 @@ -1,168 +1,33 @@ module mksoilUtilsMod !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mksoilUtils - ! - ! !DESCRIPTION: ! Lower-level utilities used in making soil data. - ! ! These are separated out from mksoilMod mainly as an aid to testing. - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! !----------------------------------------------------------------------- - !!USES: + use shr_kind_mod, only : r8 => shr_kind_r8 - use mkgridmapMod, only : gridmap_type implicit none private - ! - ! !PUBLIC MEMBER FUNCTIONS: - ! - public :: dominant_soil_color public :: mkrank - ! - ! !PRIVATE MEMBER FUNCTIONS: - ! - - !EOP - !=============================================================== +!=============================================================== contains - !=============================================================== - - !----------------------------------------------------------------------- - subroutine dominant_soil_color(tgridmap, mask_i, soil_color_i, nsoicol, soil_color_o) - ! - ! !DESCRIPTION: - ! Determine the dominant soil color in each output cell - ! - ! !ARGUMENTS: - type(gridmap_type) , intent(in) :: tgridmap - integer , intent(in) :: mask_i(:) ! input grid: land mask (1 = land, 0 = ocean) - integer , intent(in) :: soil_color_i(:) ! input grid: BATS soil color - integer , intent(in) :: nsoicol ! number of soil colors - integer , intent(out) :: soil_color_o(:) ! output grid: soil color classes - ! - ! !LOCAL VARIABLES: - integer, parameter :: num = 2 ! set soil mapunit number - integer :: wsti(num) ! index to 1st and 2nd largest wst - integer :: k, n, ni, no, ns_i, ns_o - real(r8) :: wt ! map overlap weight - real(r8), allocatable :: wst(:,:) ! overlap weights, by surface type - logical :: has_color ! whether this grid cell has non-zero color - integer, parameter :: miss = 99999 ! missing data indicator - - character(len=*), parameter :: subname = 'dominant_soil_color' - !----------------------------------------------------------------------- - - ns_i = size(mask_i) - if (size(soil_color_i) /= ns_i) then - write(6,*) subname, ' ERROR: size of soil_color_i should match size of mask_i' - write(6,*) 'size(mask_i), size(soil_color_i) = ', & - size(mask_i), size(soil_color_i) - call shr_sys_abort() - end if - - ! find area of overlap for each soil color for each no - - ns_o = size(soil_color_o) - allocate(wst(0:nsoicol,ns_o)) - wst(0:nsoicol,:) = 0 - - ! TODO: need to do a loop to determine - ! the maximum number of over lap cells throughout the grid - ! first get an array that is novr(ns_o) and fill this in - then set - ! maxovr - to max(novr) - then allocate the array wst to be size of - ! maxovr,ns_o or 0:nsoilcol,ns_o - - do n = 1,tgridmap%ns - ni = tgridmap%src_indx(n) - no = tgridmap%dst_indx(n) - wt = tgridmap%wovr(n) * mask_i(ni) - k = soil_color_i(ni) * mask_i(ni) - wst(k,no) = wst(k,no) + wt - enddo - - soil_color_o(:) = 0 - do no = 1,ns_o - - ! If the output cell has any non-zero-colored inputs, then set the weight of - ! zero-colored inputs to 0, to ensure that the zero-color is NOT dominant. - if (any(wst(1:nsoicol,no) > 0.)) then - has_color = .true. - wst(0,no) = 0.0 - else - has_color = .false. - end if - - ! Rank non-zero weights by color type. wsti(1) is the most extensive - ! color type. - - if (has_color) then - call mkrank (nsoicol, wst(0:nsoicol,no), miss, wsti, num) - soil_color_o(no) = wsti(1) - end if - - ! If land but no color, set color to 15 (in older dataset generic - ! soil color 4) +!=============================================================== - if (nsoicol == 8) then - if (soil_color_o(no)==0) then - soil_color_o(no) = 4 - end if - else if (nsoicol == 20) then - if (soil_color_o(no)==0) then - soil_color_o(no) = 15 - end if - else - write(6,*) 'MKSOILCOL error: unhandled nsoicol: ', nsoicol - call shr_sys_abort() - end if - - ! Error checks - - if (soil_color_o(no) < 0 .or. soil_color_o(no) > nsoicol) then - write (6,*) 'MKSOILCOL error: land model soil color = ', & - soil_color_o(no),' is not valid for lon,lat = ',no - call shr_sys_abort() - end if - - end do - - deallocate (wst) - - end subroutine dominant_soil_color - - - !----------------------------------------------------------------------- - !BOP - ! - ! !ROUTINE: mkrank - ! - ! !INTERFACE: subroutine mkrank (n, a, miss, iv, num) ! - ! !DESCRIPTION: ! Return indices of largest [num] values in array [a]. ! - ! !ARGUMENTS: + ! input/output variables integer , intent(in) :: n !array length real(r8), intent(in) :: a(0:n) !array to be ranked integer , intent(in) :: miss !missing data value integer , intent(in) :: num !number of largest values requested integer , intent(out):: iv(num) !index to [num] largest values in array [a] - ! - ! !REVISION HISTORY: - ! Author: Gordon Bonan - ! - ! !LOCAL VARIABLES: - !EOP + + ! local variables: real(r8) a_max !maximum value in array integer i !array index real(r8) delmax !tolerance for finding if larger value diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 new file mode 100644 index 0000000000..6937d6b8f0 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -0,0 +1,286 @@ +module mksoilcolMod + + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dim_lengths + use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_ioformat, pio_iosystem + use mkesmfMod , only : regrid_rawdata + use mkutilsMod , only : chkerr + use mkvarctl , only : root_task, ndiag + use mkvarpar , only : nlevsoi + + implicit none + private + + public mksoilcol ! Set soil colors + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + +!================================================================================= +contains +!================================================================================= + + subroutine mkorganic(file_mesh_i, file_data_i, field_o, mesh_o, soil_color_o, nsoilcol) + + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Field) , intent(inout) :: field_o + type(ESMF_Mesh) , intent(in) :: mesh_o + integer , intent(out) :: soil_color_o(:) ! soil color classes + integer , intent(out) :: nsoicol ! number of soil colors + integer , intent(out) :: rc + + ! local variables: + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(ESMF_Field) :: field_i + type(file_desc_t) :: pioid + type(var_desc_t) :: pio_varid + type(io_desc_t) :: pio_iodesc + integer :: pio_vartype + real(r8), allocatable :: organic_i(:,:) + integer :: ni,no + integer :: ns_i, ns_o + integer :: k,l,m, ! indices + integer :: rcode, ier ! error status + integer :: srcMaskValue = 0 + integer :: dstMaskValue = -987987 ! spval for RH mask values + integer :: srcTermProcessing_Value = 0 + integer :: ndims + integer, allocatable :: dim_lengths(:) + real(r4), allocatable :: data_real(:,:) + real(r8), allocatable :: data_double(:,:) + integer , allocatable :: soil_color_i(:) ! input grid: BATS soil color + character(len=35), allocatable :: col(:) ! name of each color + integer :: ier ! error status + character(len=*), parameter :: subname = 'mksoilcol' + !----------------------------------------------------------------------- + + write (6,*) 'Attempting to make soil color classes .....' + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ns_o = ldomain%ns + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + ns_i = tdomain%ns + allocate(soil_color_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(frac_dst(ns_o), stat=ier) + if (ier/=0) call shr_sys_abort() + + write (6,*) 'Open soil color file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + call check_ret(nf_inq_varid (ncid, 'SOIL_COLOR', varid), subname) + call check_ret(nf_get_var_int (ncid, varid, soil_color_i), subname) + call check_ret(nf_close(ncid), subname) + + nsoicol = maxval(soil_color_i) + write(6,*)'nsoicol = ',nsoicol + + ! ----------------------------------------------------------------- + ! Define the model color classes: 0 to nsoicol + ! ----------------------------------------------------------------- + + if (nsoicol == 20) then + col(0) = 'no soil ' + col(1) = 'class 1: light ' + col(2) = 'class 2: ' + col(3) = 'class 3: ' + col(4) = 'class 4: ' + col(5) = 'class 5: ' + col(6) = 'class 6: ' + col(7) = 'class 7: ' + col(8) = 'class 8: ' + col(9) = 'class 9: ' + col(10) = 'class 10: ' + col(11) = 'class 11: ' + col(12) = 'class 12: ' + col(13) = 'class 13: ' + col(14) = 'class 14: ' + col(15) = 'class 15: ' + col(16) = 'class 16: ' + col(17) = 'class 17: ' + col(18) = 'class 18: ' + col(19) = 'class 19: ' + col(20) = 'class 20: dark ' + else if (nsoicol == 8) then + col(0) = 'no soil ' + col(1) = 'class 1: light ' + col(2) = 'class 2: ' + col(3) = 'class 3: ' + col(4) = 'class 4: ' + col(5) = 'class 5: ' + col(6) = 'class 6: ' + col(7) = 'class 7: ' + col(8) = 'class 8: dark ' + else + write(6,*)'nsoicol value of ',nsoicol,' is not currently supported' + call shr_sys_abort() + end if + + ! Error check soil_color if it is set + if ( soil_color /= unsetcol )then + + if ( soil_color > nsoicol )then + write(6,*)'soil_color is out of range = ', soil_color + call shr_sys_abort() + end if + + do no = 1,ns_o + soil_color_o(no) = soil_color + end do + + else + + call gridmap_mapread(tgridmap, mapfname) + + ! Error checks for domain and map consistencies + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Determine dominant soil color for each output cell + + call dominant_soil_color( & + tgridmap = tgridmap, & + mask_i = tdomain%mask, & + soil_color_i = soil_color_i, & + nsoicol = nsoicol, & + soil_color_o = soil_color_o) + + ! Global sum of output field + + allocate(mask_r8(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + end if + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + if ( soil_color == unsetcol )then + call gridmap_clean(tgridmap) + end if + deallocate (soil_color_i,gast_i,gast_o,col, frac_dst, mask_r8) + + write (6,*) 'Successfully made soil color classes' + write (6,*) + + end subroutine mksoilcol + + !----------------------------------------------------------------------- + subroutine dominant_soil_color(tgridmap, mask_i, soil_color_i, nsoicol, soil_color_o) + ! + ! Determine the dominant soil color in each output cell + ! + ! input/output variables + type(gridmap_type) , intent(in) :: tgridmap + integer , intent(in) :: mask_i(:) ! input grid: land mask (1 = land, 0 = ocean) + integer , intent(in) :: soil_color_i(:) ! input grid: BATS soil color + integer , intent(in) :: nsoicol ! number of soil colors + integer , intent(out) :: soil_color_o(:) ! output grid: soil color classes + ! + ! local variables: + integer, parameter :: num = 2 ! set soil mapunit number + integer :: wsti(num) ! index to 1st and 2nd largest wst + integer :: k, n, ni, no, ns_i, ns_o + real(r8) :: wt ! map overlap weight + real(r8), allocatable :: wst(:,:) ! overlap weights, by surface type + logical :: has_color ! whether this grid cell has non-zero color + integer, parameter :: miss = 99999 ! missing data indicator + + character(len=*), parameter :: subname = 'dominant_soil_color' + !----------------------------------------------------------------------- + + ns_i = size(mask_i) + if (size(soil_color_i) /= ns_i) then + write(6,*) subname, ' ERROR: size of soil_color_i should match size of mask_i' + write(6,*) 'size(mask_i), size(soil_color_i) = ', & + size(mask_i), size(soil_color_i) + call shr_sys_abort() + end if + + ! find area of overlap for each soil color for each no + + ns_o = size(soil_color_o) + allocate(wst(0:nsoicol,ns_o)) + wst(0:nsoicol,:) = 0 + + ! TODO: need to do a loop to determine + ! the maximum number of over lap cells throughout the grid + ! first get an array that is novr(ns_o) and fill this in - then set + ! maxovr - to max(novr) - then allocate the array wst to be size of + ! maxovr,ns_o or 0:nsoilcol,ns_o + + do n = 1,tgridmap%ns + ni = tgridmap%src_indx(n) + no = tgridmap%dst_indx(n) + wt = tgridmap%wovr(n) * mask_i(ni) + k = soil_color_i(ni) * mask_i(ni) + wst(k,no) = wst(k,no) + wt + enddo + + soil_color_o(:) = 0 + do no = 1,ns_o + + ! If the output cell has any non-zero-colored inputs, then set the weight of + ! zero-colored inputs to 0, to ensure that the zero-color is NOT dominant. + if (any(wst(1:nsoicol,no) > 0.)) then + has_color = .true. + wst(0,no) = 0.0 + else + has_color = .false. + end if + + ! Rank non-zero weights by color type. wsti(1) is the most extensive + ! color type. + + if (has_color) then + call mkrank (nsoicol, wst(0:nsoicol,no), miss, wsti, num) + soil_color_o(no) = wsti(1) + end if + + ! If land but no color, set color to 15 (in older dataset generic + ! soil color 4) + + if (nsoicol == 8) then + if (soil_color_o(no)==0) then + soil_color_o(no) = 4 + end if + else if (nsoicol == 20) then + if (soil_color_o(no)==0) then + soil_color_o(no) = 15 + end if + else + write(6,*) 'MKSOILCOL error: unhandled nsoicol: ', nsoicol + call shr_sys_abort() + end if + + ! Error checks + + if (soil_color_o(no) < 0 .or. soil_color_o(no) > nsoicol) then + write (6,*) 'MKSOILCOL error: land model soil color = ', & + soil_color_o(no),' is not valid for lon,lat = ',no + call shr_sys_abort() + end if + + end do + + deallocate (wst) + + end subroutine dominant_soil_color + +end module mksoilcolMod diff --git a/tools/mksurfdata_esmf/src/mksurfdata b/tools/mksurfdata_esmf/src/mksurfdata index 6f0f01104ea61685041f09aee9202a17eaf2e538..d789397af5e49e864b0424f0135c52d069aefdb7 100755 GIT binary patch delta 782979 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
      z z$GKd3{aE&c=yEc*l_7v!7@+S(e&_X580U^8#-Ja-{2E188T6-_;Zb6epl_&V7PJ?M zQJ*3=uC|$eAddR`OPtU`pN#^f#=|$~e~~7^dfX{6lXMN%N6|K05Ud|rkG4p>c_(cV zG#Mu~i7a};wAQzzZQ8oE{!7ny=;W3o=UVFp1}*fgwZ5L3nH?zB3DuXVncU}MMVOwq zV}uu?UAVp{ZgqVj_K(yTxhet)r(c;$vM_hkJ28^vvJ>=|)Xc*d;)gx-2OQX0uWyhx z1N5IbagLG(``Sovs4yuRpg+s}U{AgusGq?E*%N+{{tfesM%2HjALC3jBJ)P;AHQw? z)G_)Mc8uz!SZ|`fv$K1k>oQg42e9y_Jpjq%k0Brmu*v!m2dW%Y7b27OozzUuEAg`w zJx)$=d@U}Vp>M}hLh;Zi`qP@X%CII)A7Dq%tQLQpr*A8F#WxxHBS>B?7BA3$X3rVs z%9{<-;=LSk8wWyWO*6@DGM9{9q{oSFPD#XXvA#P~S}l%StoO2G+S$a}U+X_%y+2Bk z6DOEkd<+m?GCZ=#qW2N&6TQKS>GlC>wH7M&agKfuGkmg$z*Bo>!WaoF_TQv`p=P2+ ziM=-K(TO^5B$I#C_hsF;-w^lzs1H`NgMYa}o^H|aV%KiFL4N*8KbOtfc0+9SGn9?l zR!!Dy)1RV#(l7c8%<*b5{#X5ENy&(~SO0|B-;?~bPk)t}W)r{2(|@gDro@ZJ-}I68 zv`*s4Bl;(5sdj^o>Az^Q^DezOZs5e&O@D~A|0>k{lvRh^>tZhN;6Si zrr*S{aq1*-OF6oeRD}I4eP1S|A$fFPA1mhE(*Gc3DkfO>=w@9S4FtMww1&epJLD0kWu{ZzHj&)&4z z?}wa8G<(N4S>S_c@D3AX7!ZE?Xh5?8Ct_l4oJvlY*TN*)HL${CAi@K0gE#-`Z^$maH|Yb3d7)6X|L zAxMAN|LaLXZN?eAi;{MdU{3RwOJsH$-&L3Af<#A=p>8`Mn&C#5NRnEY_xAV(2;6T# zj|aB7nSo{0e7}g6G=aoHppw8BKII_ZVvqMxZ0z5_)0SdIi$YToFS283BZ9YGz#hc^hLloA8Y z6iNepSp-HJ=jH>_WQM=t)Y2&u2h#;PMUvqxZ}4|U&}1vbDwYaRj5dEyDIPM+nrDuY zWChDNa5?O#$P|bpEH5~(2Lj~F5q`|_AG17wiFSOW&?gSa+3gwJj3e4b?pVi*8-2!h z1ntMpV-AtzpdCMDSYKeVkc9bF$mIm{Bin(`UY0<3+N{?u_!dSN zifD_b4O~p?7Y)S<6wSEUrZE78K@2V!|CMHH%IZ>@{=A-cK@(^fz1n-ZT@qQW;U8%2 z?Ln)vlU&9=l4RNQnH`2{BqeBsm#eZ86ltOI0}Kmcxb8BZ8N%}hS^|kH@nl-MH>kMRuBmc3}7cAK0fnTbmjTfNPr;W9JWb== ziWrF3iSHaTM#2U`+E;WEd5#Mme+FK*+$m5 z@WG6ujhuGjeT2u=9b}$sc$=MA)gLYE8*eMbwbj*xH}Kx%m>XZ$u=$^)+N=_M<1JSs ztD3xV<9*tH03!MWuOA|^R@7KR#I{mRe?*%#ec>jWv#F)6d>@}?n|1B0NuoR7jd}Wp ztZ?T8nNx2_fjg@3>l>vC7t7=-)WL0xZ^%P;zBM!IjZ_6=B4}bVCHtVrcXmQmzgTU4 z`*_>_B2DWzWQdk;)>Qo;WOM4syx)F}Q?~J7{u5TwEt;#Z$uC-d0F&{WIC+4T;jc+6 z58j{Y^qM4i@EsVt*JPmwiZ6aei}wn!gzb1m8IbzH+EqrRV|w*Z)h+M zVcN9@!>3&<-qOXRhjoCxvj?0wx-e#8;&F@q z%?sq2N%K^F_KI>n$Bp*vTR>Z4i>p{Tl&7xPg<{d2dqMWp;R9Q5K&+L%)vx#d) zuv-XN`}^R*mwx$t7-F$#P67v=j4h_>6)7=1&8*1<)}q@3mu^Ik8(nBSYSU~)5NmF5 zWfMgn)#bU7Go*0r@yyR@oh`b_2-g_&Ewm-D9c>_RmETG&5Cf3@LJF%gEt+tIWX6L4 zQN{z|%Vw=1jdSCki&MS$ZffS-GqOj=w_-LvBUL&m&irS@(VI_X+CC!#y@9uXMl!v5 zKJEhgdcM@*18Y0{y09Czfzc zlczx;SKI`sYFd#d>&eMTJjAQWX#rk+>u!7xyLrBd5MhY3OL6 z(AYGmX`EZpWAd9X|7Fdi0eRn#-xc%mpNOh8@RS#`Za8oj%}BVkCMB>Pl99K#b)&@l z&2F9G*Nows_J5N8_4vNVE05%2OW;ebb;PEju-WY}-1wqcGGd9|TfAP6*QmLihcfX} z_%*~7HoGl+xQv5&>hzE#aD1aEKOkk@h&S&Dq_((n9aWWQSStxRQ>1zEK#q?wCl*_| zb9U%1iN(searFWDh2y(;WPzrtl{TM#sD*2p9}ovU-_&;?u+kWUle{GzccfJ_Js|OV zs1o;pjMMWeO@6pvBi3&LQL%mvU)IKKK)Kj)1li8NPwaU9J*L%tGMtAgbGk1L47$7b z6subIOs!SDKpwdB!R;`ISc%wpTL#^yfzt%KK=`i|^J>whBTnu!ij8Y0jT6)E(Q%?_ z-)Ka~W>Rgc?O6#p+m`mM28cq#&Fg?LRvs@%_W_uOnug#C)PK|KBhBg1cl$0`X#nSk z?vnim-p6svT_}Ou&v!|wf!ArjM#${;CESHes0P~!{7|OZT{2qWL+FWP%LU%ZoUbB# z1wO%hP8B58GUSZO>=hWZ&>m7Z>r$$S-pB_wlnjE#1PaNpXtRE$b7G8FErF{19)TiF zqbf4q$Tx}om)>bA!nKR|S+_O)_g-2{uowhInxF2F-;MkiO#M4#bO7IA=<7;q#H!(D zoY5|tB2DEaLv|Y|v+gEbOe7^!ZOZChn*I_KNk33wBKiA6bXc4epW=iA-L)C%;KG!i z%c0R!DfBq!j7srl04`^BFT0JbG}k5f>TU8%Aisu*#0h5&_&|dXu=E#i&X;r<$7D#l z{1?^bm$%5$20ZR(xJ8aOz_^!ri&Qt@y@ljkbkvi_kJ?cWY-;0dMHrcGk~<9NweGM2${oX!i~4I ziElRDG2YxJEvjXTcD;8MgB5fM;W7yJmQ_1Sae1`v|z#BMIV$Kpw zbY0B4e&tY-W0I1@;w4uTzAuBdm9Lucf$jgeA=e<$yg-uduZmZaii25Enz)@kI9s3smwU~RSkw6Z!Go3up8vPrhL;D zntxJhvsz&OXx3TFWNB5v$EzZIDt--Lnl$AD{kH-0uiY`pNFFrhTQC#K2;Yo11a$?W zB`lt1@JzdCAjT;NPsd4A1O# zx|Hm0##fjn=VN`Gn4F1QQ1Ms-3jDYnOIsX4LGd^W_EKBrJMHwd4sUngHS=Q;Q5*Qp-- zPF?-6>tt_pKHe=2p~@>rU8MQ&I`M45w|5JtD6Fjm)$BSM*n%J8eEJ&nDyT?v=o-mu z!E@Y?Gz>la7QUosCv6gJ4$HnqTqF60#J?qGvE1m|tY=DB(jls{5`lkhyJH;f zOqEy2idOu<2CJ@gP(hdw$Med=@Z&8RgJ4UrJ}I57!9Fa~%(_B!LA>BS5Tx{Hom(iY zCN{ftzCyYOfyuuvQzp^ZqNMTb;bpQWh;Pv?59k^um6=EuzVD|Ru?|s{Y0}63iviLf zo)Szz(93vC{Y?W*1Myn4al9E5&JQmWT`(UQ+#Qq_w?w$~;oXM$3)QnDcVigS?S-drH&5Z=^n&jrfXKDd;vEXiV@!P3bQvt~VzX1BF) zYuGZ`4&&&ORw>`dn4e`lOLeM>k$|~vEs>vGAYP$-efRz}k)}I!b*2j>Hk40eiq4aw zP>g+R&y#zhP?LG*iE|j#X2^NcI*bo#YdHU}#zEr(ykZ=r(QI~nRZl2WGfA2L{DZ6t z<6G#cfmFu2QmRB4>$dzsu7&XiX7L}y20v=tAK)f(0(CXR;7VKBF?7GZy8PcPx1%>z zwuXO@A#LzTdi{5@wGAH_w)=Ov!4u7kB|G>NZG6m@@PLSSxk{we46(qo_gck*FdzS+AKO;9R&@f`W3E$_`7 zIww`M!K!n#qHCzDSqk?*Dq5sTIY->u@fpm^vt(&Ibk&lxB)=W+@4Nl1(nBtZ@36l5 zEM?u~*$1&zK~MuMt6`4U{VeI+o^Se|KhW>;J;#xXUjrb9MG39gCF<%+ z$e!kW19B;XZ|0T?Oyxr;PLT#1!|HV4qup9l)Orb3zl03$z>ju5a0)WV#TL6xk>efs z0Dc(_!zM3;Pi?aKA$|JEM98d}dx~1+8I02@k`al8lZumMb0nsW`%jV+k!WRdlKd6P z$N9vbq>}6mx2g?VGYE^M_#)sW84$$>htr-^V~^=RJUTMnI|06a{J-q+dN~(5WLOtI zkO*C17K5ZfCNuvKv3B9lGd~>^_jl#@sF}~SWKKM9@a;9p1KR{29Qji_sN}IpJJ>bw zvDQQ1XA;>F4|$$;$2M)=;G8qjL-nWD!!2hb8PJVSVS?SsiEcc;hIdXP4&C`~tOtO8 z-T4JxMu)=dz6tZC3%S>uuNR);asy{h zB)b>5qubDruB{=SujPADtnbytX=~zqXdJ%tQ&}Tjh^Y_XK^Kh|ZP<;qCz>MHy(qIC z*4zQ#efZ|}(%y|4iKsm?rhl%ydyyO_wm$q|>1E!KzWhpd1SE32AMZ=tJp>OipdXb| zFXtq&OMkwfn%x9w^#C4Q?kR5HKpxkeO;w3OgZUR~*Q9NVx=yMtBVj}Mc9A{aQ>4@o zQL>bL0lh1w4xOo#oTYee#yLnyyDJe>ohMt#<{^A|_;QsZ8@HPJ53oo5X%^PmHF33a z3#V~d?oe4rs0crlugAowNcd2`L%qMr=!g3d1jQWI+#N)g4CR|M7xt3;p?s9?Zvv}N z>43rKn|xE|y}cxI7(Y;w6&c3ouvW+*d^q1hmd30Rd=E7nBGoGJib3F?vy=EF#^w?;s-SM3+H;-WAd8wh)o7n-s6j=pl(H ztFNR@O%O)`!}If-k^#T zoJhJ){HNkjR9Ni?I*iCc6Yd!TW95m5o3hz$dpUk_6S0-UC zMN*ZD$$WRUUGBRyPo;>cspw^__ti2oG8u=Tel?A6&z`O<6HiX#Z>e1?Rw(kiejAne zh>wiS@1&^IGDOKLl?muwd2MMld`;Ht-Ry3$V3ZKnB zcS#~?(|Iq_eJ1ZNUQgk*vbY{i=R2#}XxF!~e@fDdp2d%2*k{+u#2-H8PpDl37Ax}6 zLx7*p;iEddYOBcS?4la^90K&Nd@7ApKB5$_%?PK4iT1d4i^%Iad<(Yk^)k|YF7Fr7 z_PQdc+V1tV0&e%uB&^YxsBpY;6_q&_Qf6b;rJdZ!;14zryple&xct#f9j?ZY9EOt#25o<5w zUZ+#Rg`X=E$IjSF+|W&i^LG&b{*!r$by=Rlcl zuZ+2LSo5+uL?!pQJB!H{GoL8c|Fs#)e^j&S8_IB7n4lv$ZT0qIqmBGjh7sM!i0wR2cK*PZGf&ou-)!cus2P5W zICBeshGDu*5)-!a*t@lJ74aBk@Fvq58#UsSZTut@z|y1zOv+ed+`<3K#1rxN9sDh9 zwdhCkM81vt&VI5^;T2fqFa3x*m-o|s1sq;)q`1@fVrB%)n$&)zRW9GNyZiTLIOfzY zaEz%amR1z&-u^OmvIb|?R5iz0neIRU#z7@^fZ)C8OQ+%YaBS|W4P`dE9&+Cr_8mEr z%fFYn@GF|3bUaaCWQu7p%`+J(Cq9Q> z=GzZkf{-euPkhlKI%SqBN;{oZjlABe_D4!SO;F=WN=Bokj0VA#tJ@ONlB>IP9htO; z@7}!VRU7G1DvwsvZMPDVb_lzb_eR~0qzo_cfX-N3GJO~)yi-AmR+VSWf^T+v)(dPrORj_4IITw^Tyv2HP|#X(axcFyz-u*aFZ!ac*z|0_ zfIE5J5@~`X$)0pKX6(Hj^2t6v$g|E{WP?UMuk1->gJ;R_z`aR2miZGv z7PloY$e;W8HbL`1fRpZ0Al3%60prw0T{3*LZjzL=0$LQkP8RDe>xOU1pgev#d%P-# zY{}>Sm>oTcdp_Tx`A1bbHq&mp)|^o&?Nf-+#uQ_jWmpe9rfdaAn8_C=m~U9)k#c%I zAHvoJ;QAY1Pn}4L^7+ZlyZ!ZUOLb5}a!ZX%e7B{xt(05JVes3Qy8f)DrQAR(x74X; za!XYv$e4d`sZ&ZU7RaBGrv-eI;6=bFEwun3ZK+iFX15f$H7ynYZB0vUT}65p@@WC9 zm;Xmg{n7nxOP#dlkVl1lbI)(zB56wr3rWlUXsPKyOD*+fZA*=pT1x+vjNQ+-4$^_3 zrls5f)0Wb}H|t(?qe*E?orbp14sgrbb|op=&zso~ZYwR-uN#?q04-JL_P@7Ob^JeC zs`6G2`QrduYC8a_u~){EM!)eP%>y2zsqg|v>QovpB_uVKCJNbL^i(=kCXt$I!u9@d zn@aq%rm1emDNUu>2ppb(y3kFj(zUi;wGcYfeuXYq?rMd}Ub%8t!@Z5z`J}`aX@>qu z^apuki>bg+Yu3=B9}ke4oZ;}X=KwCOnY*?5N-8Hsb#S6`@B<&EN-F*DR zcP0Ox5|SmK-i2~nBl#0cCCR4-_I)e)*AHqW-xRb`C(+ym?*Ep&y+ZfzlD``(=YqMT zlJmk?d`NfD^z0no$q1Y5k_V9ohk54~+d-(vVGBSihwtEi#MEQ)~guL{1Iw7EG^CZn61uhN{A96Q|P zi|f!$&3}(4-nX#GhF#6=Z}GF#o-;8JcgwPK-$S16j3rb!F&`(VQ&7iNV~42v`rxZ4R{c#6(X zFw`gh35E)(7$(tRbYMq#C5a9D8LTWj_i3rbV75C7TldnuVU&(NN&cd3-@oM*Vo z);m#3vNH^m{f=J%^9X_cX2Us2woMlrX3Kl%fB3@ilbUVpog}`u$dIgIujiMFC0`rx*xt@NiL5O*c!^E3 z4Gm?IzRL_f)$GwdrQ-L*@S$4Sn%`2B+@qjocm5|U41p}$@<6G$c9lV=W|tM>W$0={ zD(eLxVvS)Y>sMGR?pk9=lD6K9jejtlcBJ1My!yq^nN35Pre6(GuOIuXLF)Ajel z!={P7ZWyql7hNw&M018?wHT4tDhyw#nb(uWk8T<8MasjJQiAphC&CkhGnrn6V^Wu_ z(Yuh+Rt68!yV8)t%ugo8m4=Coe=-TVW4PzGtBWs)Xa!f^2u|9KZDOB$aBLLmdykU(_b6*XxPRawwAL(02yj8v=J?g&{%B`wp6>f zlKl>Xzj%%n#xU$Og-Qg~Fq!Xs2jL*BCL%s{5&Xn8&cZ-B;<=0Pie*)LdD&OQvTq+b zVzj3)n`Pq=ffWAY8!w^1+C?f$kCl&*LQ6TF?yzbDS_$q5+`>RUfD|$pV&jdDnJnO^XVlVuw&1@xh`JmC$zDzJ87D` z%B-%^##zjCd#Xhx{nkpSpDnkr1dCa2%G;3I|xPzm)Q}ou8T>d zg=~8^+JHA3lZ2fXWI3iE^* zcP4HD8TXZNof$u0?E1Cvxxd{Kq>;uH@!`+HWVy1#wh5!ub{A@52x6Lu9={5mS#;UQ+C7J`dBR|K$9Hh$-;&9BLbQhmaPj+JbPOp>Y_{Lpc^%oC zhmtmYO{_QvhV>0dBB%0&#*AjI_#$7}q-LtVAnOZ-?aT%u4%#o=b?Cf_amV+(vD@%p zm>xOtZm9fTW@2aQ-urs^JQff{uBvh`a2$>IG6Vm3Wz%}Z7UuRZGS`i<=xuk%f+MKa z;XCBu5n%!|=niRlRA|af=tKq|6#~N|tCTEFoun*rP*w;aDNE-9SDIzB-(T6J?C9y} z*lTdMl59UJv}0CRl6yymk%pgD?y9)`rNWI0s zheD@x?IaH${zsfnsiYqOzd!W15Sw*Y)^*GgezTS>AX82VEwz=mKy7x2v*1s6+A_@0 zi6po}5ctb8uD`qTS2NwFbMMN686>Gf2;eWL{1=)Ovb93snbgVT6!nKsCJ&G%;?;-$ zng%a3eefT-<+htj+wUbB_&kDcYiY3Y0s5-*o7*JeCiDfDgwDJvgfQxlPX96att>x5)FGLKtJ1L|WYfJBz2vev;z%oJtno z0(({eUTwTn^}&DS-J7-S(buduX|VADfchIZaaj!5%ezT@Z-c#Q5~ai*qIDA`N{PKc z74~SV!8b|rZLo(+vzFf$`t%B_pM(i{hu~1`w(F=$c8a$ZQ6S|nlWn>%VF+SlEdzY< z1Z?Uf9d?29MbPtc-*^MezjG%b9v$4$!(+lUfYyUENVru9PMwWFg1KLyV_Z>8php@) z@s=KO3FaYzz7!*5N|@=raH3maV~Pn{0!*T%%b+-OLSVbyX~>lOs z3Aju!llD~LmcTz)KZzJC1z+|!fDQoKpQG8Dmj=?gRJ>)`a)r1M{uL#vSdOCUX+9kCcmrDSY?_`3e7|KPn4+Va?~~@irR$NNPdkbw+oa@_XQHA7b-LYg04yw-OYt4 z$^W~J`()MxI03_P!8#0YMUjH=3@ECF{ZXzngf$y z>Er?7$*lrDN#PyAD>am+v<&8`z~fB09cWTWw^t0sBga9K_!Fei5JmEX6r!0!BtVw@ z1i)Ic8?v7#Nk3VMTY@^IDKHiEOa;yXtWt@6s{{{wozMuMJ1z}ePWQRUdT5NG&(MQ_9*DldApRQuQTR|xJvO?gfinXg%v1nT3Sj(D&i1{BX9S<4G`u6`? zYcZ}$VC~7m=YkijYK{kv=YlWOc|6(sTxjm|1(-7B7Q>~z&V9l;KvvawQvF=mz%;K* zHoOpm3@_`1t8z;bgR`HkPWdlw=GZh#Y#K%$pIlXgB=Yoykn32~FkH1Kcl1iK^QG{W zqrN88^Oc}uKJX;tUJ2nruRJlvXy;u<0~GjTn6l{(GzeGi#>15@xRR zDI|Qjj4ub?B<(7QGfRgyV8iq=;OH;TvapbPUY1#LHk~sP>`D7;B+y~I+{4MNYN4y! zcLCw50-3!P0pvurP*17ff&lWM8ZCpWIN5{}1)E{S;*#(&<7>iDd$`=`ICkR~TcMuXm7Xc1B;)No{P) zbPgn+s*Q8GPYvO!`1FGU-VfMx!w}drLSok~z$F|XV;TdP76#IuG2)tZ0~yU2zh`y? z5NFmH70mJBcpAKy+_b8FoFp9=AWV6UQG1*dNXw5a%AiMD00AcM>2W87agZzJzw!#+ z-dKN$Cs$cxMBVyM5M8p?rdw%*ydyMTPT{1PoiU)kMEVe_q147fk9aJ&1;wSmvL!c7 zk4*f9)~Jzlq0I6I$8fUN&e)(vn9R?{#98d51B>E94&i8%3yGs|+H|8h zTKm^8Oj)t^G1{J1Q~FKlUGsZrf#w=xXGX)34>iV+E|inFh|fw;laz*d;qxMEfW5Zo zpOW0|Aa}%CG9{B~c9nuvUH(Bu(d3TC7^Spo8-EgHZ|q-Z+q01{w_bs9=3ay1ESg;V za6;^jqqLvaLx+mVV)? z%5ktRioke3T1b6yvZK*Ktz~>`v(){}hLg{ni~{qU4_WVI4A#@4C?D~b*@5^vwAUb; zF3X3iza|Q#k3gE*7h&xBErbvfEF%Wty4Xq4q=}?<)1f`GATtqmzfx_$)Z?Gq~q^=kdIEp*P4{w6DS^r!{Yvdqx z=u_T=I2(J{bDT|W$9$wIpkSO$GZ<-Xx-s5_aWM{McLXJgqg;%?sN0S7dRuKbm7K3D zt){QleJOO+L4s}gIubRv=>kArNykuPa5vT?W8I8X>a44aWR}Oc&4#{&j z8ko#FRvcwB{q=R zbRA*3B<5(KH4V@ho30hWIE$MHZZ?)Makl+&=B#b#x^ZT=moI27Ub}^3hokp;GOez$ zQESr#1)*$MO*~9djvEVMXY{KR(KiPq-FzG<*N{6B4DkG zzizWQnzM3{ucBkqfKSh(2$;|h-gcBhz$?7TQtJwY(sl^|A%+IeAqGj+eLuU*ST%*tuvTD9?QF2JIv^en>71nuJ)FnD&TXr>oqdH?hsY#69#vj>YCX}4= zHrDroH+SFSH`pZgY5lc!P#f98grz(rr#WMz+M&Y684oo- z{{X4A^JaO}TF^DHXz}UQ|29B8)Ehgyn-H($-jEF!O}ufXS|^!yvd@a8ic@t&SsT-Ja5vVG8l#*$`vi6X* z?L}5+jI9^a%Q2_1y9$ffHrl9fMOz;8DUe7z2CxPp-!!MBeN;-%ajLQw)XWXjqm3h( zC8gw6w6Qny|B?6IVNoQ{-#b05EC?(jND^UYc6Px?G$9HK3W_-^<{UAA;S8vlR^;?N zwajNcy*uyDa5`o{R7__&10rHR7cpZx6L0nOf_it~-~0RXeZH^HBVApe>h9{Q>h77@ znQk|4s23$1A#epsqJ%|+zXIPj7Sc)5We}SPgGt_XnBPQbhC_)yzi@QHBx>4xLo{Av zO)GJmbRCMC2t)1k*U^S2EP-~=GaCDI_9Em&3&ExRUK%6#Rj}a5%F&L&!{u;p(O5oc zAt*+unDPeMxIB(VB`x_{Tp8&P;xDN0b8>KHEIFhLQU%`Rpuql8fj>SI@L&QNRA5D^ z0R1Ygv<81BaEJ;_EEV{M38biP)MXOMRH6%$NJ=U#9?!sO*ANW1f}Kmj-V7W@!75g; zeknMCfek6hSwWvtaJ~wrXrCQJ^sbHC^W;f*x!fP4X%wB`@ytI|h%OgM7NFQRMiwKf zE&w^&OeED<%h6uXtEX8@2T6`L4@o~pW*`~K$eAeHn~|fDoTid>v`bOqDOOyB_lV5m zYnj?@QOFX{6vMM{(NO58;V50A-Ej=wG!>eJwFO7KezesqZY_`+7-jBk!|v$tC6#@+ zp@(KKoig#>DSc2m%VH1gV|vF-^)0;CCFesl=4`yQR(G4l7j@iP!zl>F$;&8W_U?S7Cies#x=g240z2{I*j+vjlg8DXN*F?l#-_GyeOE$gh;4ZZKQb8SXa6 zb>OQrP`QP$qUzGYI0pJTrd(2&Y<>DI>>++0h$~WE8;DbF$vR`QcvvWd849 zA1`D%^bW&kBIZn-@=O(>O-rFBS#TO`TMA*W=UR_sNb~dqj)7=m%P%fWqS9$)T1&xB z%Wn(9*`l3*KhO>iOH}MS2pNQrep8^F>Lm2$$oAP#ql=K>b}BOjKSO^SZ@w9Ce$W!X z$Z*5+K;})lKl!ZT?VDg6AQo z!n$69YuL3^8WZs~_R*Lqp)ui@TgECs&#?@TPaml`XcPp8mW4!ozTyqck^B0in* z4^f*0lQgv0DexuMQ0a*s|jeV zMblL+7hv)?V`ct}u`Uv*+C!)*H8}7$rKvDex)6Pn<|s{PO8a2Ff3u%g84H#6nGV}~ z2(AHr(W|MiK932lrYt6Oc*FKDi>l}}O;xeG4lDVairO+3s#u1rE_S3dR9Zx8A5?hc%g+^l`mvyN+|RoI z5tUt_fs&pW2*XoUWrw6dKrg}D;Zq>|qJcKOP_Ih+U|KKKEBg)A>%&x4uiCGt{zI=9 zWh~UI3|IAfj~6MHjgJbHqF%V(22Vrhwu!NslQ~=-f6B@RrpNtObr)?aAM z*Lqn1qxuUyNX~C?w!aX}pTbsb1_<@4FGj8Dxhz!AY^)Mbv76y~ewDlEY+vFGJgwYQF&YYq8XMT>xDMqxP;?Gy1H;IG8^83++3-R<*xr)&9`7ziEH7 zO#5L^sP>zZnfBi$|3mv#Wh~VGyJV;}L&>1&o`2`LS6-E=` z7bR?%kcaQh2PcBd2w@994T*yzggg90jGGN3g&O*8!SofP+4Sk0jeh1fI5$RcQ(lY| zE^)jiI8ix0N?2q=2A+W4$$~p+djcjV3)y^NNFp>ECyY@Szu(3QYsyt=f|h!9xu7H} zZ4F(b!gG_HaoE3ajO-hiF=(dVRwbC7_63M`E)ep#Lg;78V%=lp8n+F z3ixrVFp@uxa^5MzEb?MGtWObE@~v+aK;$&RlfQGRKuMS;)aCfxa|Hm?g=+kdNF1Fm ztlA)n(9{9XXXGllN_DC|PpSweNb z7ILP|5&H`hs$`Xu>~Uv0Wx zTJ9ey0FSSQE5xx4Jo{Q`Wsf1s$ zzX0BTBmCmte-DO^IVZ-fnxfE$E?&;33zUpSLL66R;~~}Tu{pvV8UW_X?SUF`(nYhTeICbqO;96us(dS!s@eJz~0gF zNp%oN-<5z}--kc3Xe{-PQPqx^Z(wIvqp3n(?L+6`+0D#rE3jN4Pn+C^zEPWOutc!u zXP4#%E)lA_RJPWxpSAo2iqFp*5S7 zipNp$W>nm>RN#+gf=7j{y=Y5%L)(aY?T@2YyLc|gK{O9@G0TNOzH=#i$#S6udAJd7 zFUR}y^oPR|Zt(eV(&Gi0UE(6>7s75&tg z_>%U=nU~U6^wbylihi~<$}WI~D}_Y<_rnE1Rtf$1K}ZZ;WQOht1@n4x=Kjr z`0T9(5Why~$Pe3EplnWR~Kig2637oDR+9eF(Y&+0g zo9R$f5o$DxrHoPfTJd!0$0xraJ)A3F2?K|!()#Ed!S#h%dVit8a^B=hG!^rtyP2(+bE+!s3? zGBbqAw$yd|dQXR^4x)!G_0&G}6v-6AR8M``Aa%ltvX(k!T0MmotDa(76;*19-`SM5 zVVfnS@_u#keS$1ugUK=t>%WPAFp|#2rrF0~CwkDI!e8g8oyev5xoHr0K``1LrjXrCo9u#+;4&yEg;eP+3 zL6JM{RcX`bFA6XGtc`uHCzUGMQ`+#oOF|a>b_`eWE&rW;b3Khyb6~whXntClXKS?@ zTstjz+Ll`C-D&*ov(!nZ--Rikob=NfA*hAbR-YTO@CQ0?lqC6;M(w}(j(&DoikJG% zbXKVUfA`(=v%=GV_Zgd&-mlmt$O*w z{IWnio&Q-NKFt3t5IwF7lRpLG%7Xt8i0f$}zWSd7aq7PWqWg{iO(2fGfv;ix>m>4d zAbxdIc+9s6PlRE&g!i`A`5i{y7Tj%1XY={DtxNMhT$*>@76x;!bZz`{#w|>S(Y#ox z?S*8Kt+=JL?`N}e;g>7+9_zIKxx}Xxdr#>)u=MUfR&38GvnO2#u9dCWMR)%fEB2~; z!el=8|Bt@LKMkowdGQa*>BzTnh^-NLODt(u(((j6B)LLB&Qy&R|an=>| zlZWgJ>A7_HNXR$tb(XqZ{=qq~#n%jT5nzwi?ELN|(zKAUpYKe1zJ*G2Xmd8sO9OCqg;yU*=Bx!hX1%m(Jd$E5+WYpDpKqJ{87)8le53f3}>je*Uk^ zxqacBe;J9lpa1J}ZvW+S9#Jej`LQ&b| z`SIOnlV_FpLV!J8#myaa>D5--_rm;7?z#KnGxzv>{15J#`&rPHuGoD){%_oK@T2hj zKe^{b>58qKEfI7ao}`<&Bu~s%Z)(20E-f5ac2iS!b$XZ+CH1C;&YTZ9arCF*)t?vH zO$}ZIe;QtPh0W;jdR2N;^KVn6j1txGnju6a-GMZrE4J!9_pf;!K;yqNUKd3XmS!+r;` zeA#Wx?+)UBxQ)>}ilP6T+ZYLEIf|qHIs4gtc`xJYBrf4SBJm^;C((f`8%`N|@zX`| z4ZZlqaB^`LXM7q?D=Ub>@&CLowlBPgfrVe#|4-K=_J#Bn-_ohoI?NPL7x5{_ul;{Z zsfq656OQ+fN>qkKx6h<=QB3Zh%Un~wvP!&P!68vBvaQ?r z?`l>p_l24j%P}=8Gxis1YOK8fq~;#2TGgI^sCn7ulbVNZn40UYJgVl`HdZy`ZJ?$J z)y%Z2S)qw|2nzhgOD>lLxt*$WSV?9jrV$h$5eXeSNVGaet;XsW0Lu&^J-b;W(zbN);Z_UUMwElUW#kc&J20h<2Ql z_)rClXe5<;2t{$Czx#nAR)7xWA_;;0Dg*X+6uruq#p!ViwIHslsn_|JxF zD3KAOJ?GTU@~NHL7S_(g`+sYvNM-!3ox}HGeq(IsDYoO#L|nm`mN7& zp1_PV;+Aqg7FR;21vfv{JN711I)L%mf#lRU{wm{dN|)S#*3HGQculj?hPGe-XG5#6 zTN}#A|J2ZieAZA`#{1Mz7nSk1hHB-5Z!2tQE;h8P6}3*eJZ7D{SCwu!uX0XLb3avn zF_&3qUM{oFtXyWDwz%NOtX*FgHD7x$-?CyvYc;ZF4(NWyZFDtA0;rV~5`O0}#Gsi(f zN70+?I>##h@!a1lo_mf}-0K`X>53Km#U(0Rx{32RVt)p>o?=C4mLNJ3%kOGN8ImC4 zafWYBGkv$7hDANZ0QYsLKdV;VLj+Zxd>StF5NnW@r)kkFehbz-t1k}um{W9klER%V zKGs^Z>i$lzadU2b`!Xo%HNA|{B)MWpY-R#%4f>50N;?Ht`iXwrDdkN+(U#**E*&6x zaVNnW6UUQk{pxC{ISGvih{4tEq1m#DF zJ`OgFqf67iItZa7#CjzAAS8|ubNJ(B4d(6tticoeS%ZfdlQsDBe%4^hertnu_Nfh) z_t{t4pdRc;h*cc!?o}Ds-sQcly$yR|!D#Ua-zGj$=`;r8RewrR+q#`jhOcaOly<1wFah>?N9mDyX-0LeGaQ(i=y zWA2uAie7W2X@_oAE>6MNbe#TES!)A-Qv2lU!&qu_OxpV=2uTtB$+I7!M~c{sAJqzX z$Vd^JYCW9W(vMj)GI0*rJ57D}B{ux9J{`|rZ{qC+&a*`w)So2^Wb!%aF-wdkxQX^= znoc+e&uH5F9E8snV;u&6Dmxm4j#&0aUvC|3oh=$2+I+%9h852i14#5as4_=v!B6Xy z2*c;#tUU7^a1Fh^VZ$73&?Xz6MSItRmvh7bKDI4>Njq1JQe_9s6&v&0kn`hQv8Kwo zHdk!Jd$dc0nr5-S${A)BTl3S9bI>dXshnqKv8}_hZ2ESO+Qa%#Aq^+pKJ&zAvML)k z&l7u+%E@4xCN`vPH%k*Y(Y-+)r-@DIv8W;Q#YU8$G++GMaakw&wuV{_z7$yDYtah= z(#2Y&!8z!bE_NWH=U^L6tDl2%UyIF%-#KXgH7mdHYjGuSp{gz@Rdsr<|iPl{Eg`z*dy)?HJb7UlbNV^bCQmvF*`5Unoe`}<*#K3P* zX3a=g_zlW*FXcW&F7HvAtF;JaE{%Y7%S2BYvq+2}Q%1n{MPf@*)5`SxR%}YU-RE1e zm!r)m>)n0}Df2}Sxc4nOvdVC9UMx1}FATG`oxE7AM&=J=_3o#crq&F%1Tz|IrWt1V zeM7B<(rGTKH1`J;tT~ib;kgtumLV+Di)PkaGn*j4ptkh1UEpe%e%3h2Lvw@h0lAp?gV@{yMRK&CU4n%}0EBrN~)Z zg7cY7GiL1)&1K&g6P2w~%tq0uQ zg!$8(pxyTv+nUaa;I~6`Q&OQ(RFR_T%;_cN5G>3yhK|z5GvmgWBJU1IK|%(TPQnj;EF-k1;W9b z;sAcjphU>JgAYna&_kMXhbpaai5+pnl;O(vx5XwL@ffKT-4O@kQO>xf*gesP5Wi7M z*Zblmytf@iYc{}Ji|91R0k!EQtRUd=9>iXfIeH-!ngS{1yvN%R7ZFSNfLUuYU z<;zP8I1=2B){;*`W0bEPB|IyrxbH3Hmmkv5s%9e&o_b4e%ALy6UK9R(Iv5 zm!SBT##FdbRccIyrD|Ad<`|`WHLB;jaZo8x8cJLXVMd@7Mb2B4qk$+$CGA3_V46mR zNU=1XgA)U$%C8|(OO9w>!@0WXmx^IhYx3hOs9jGAgvDXfD$;uf1lN{o(6mo&X$dL! z67uRx0U*?oe97q-O5-}xe2&yCrseyS+~>6D1uAV{A63J&aeefp;TbIzM+%=Ra<~+Z zJ7CR#z73>5i0u>5HN@(AM@V(ZuE(%ELK;D8Kc>u9RH#csX(SohL6c%zT!tcbS5!_O+ZHUTanKw~b=5iqnZjAX&g|N4=B$G9T%FV_!hCkeg(a~s> zz4u{PwA6$o-G@do*mZr3RFl+FGhN8NKb7S%(pKD^>>f00CPkB5cOku*6hl_rg^M(8 ze^>F2l`e23>|y@{rTQovr1Q~0?+sV%bG1nkOFzW$}2V7fzNr#_%Nxr zw2&7{b5Ev7wV+KO=@I{=*jliCUn!8|e|Vm+%=EJS;q#CexhGYYm2S}^= zy-%!_nFmUdd_T;c9w-f~^73&$zKkDp96!GA9~;g-#MjR}P2WeX|7SjQ93)lee|nq` znd>B1W!WI92FDM2WUcAiVCg6R`-j%tsv%M$FJR7TsI-coQKS;S%ITp}FOKIPrSRhdC6q$qx7Y3|Sp48($c z`AXZBIKcU}d##1muaatUeD^*1%Ei@^J>gsJR_%6%pR&tZ&nJ^TT8j;skY8#tdw8){ zs!(O`Z~tbu{nTzBe^TvMolpENU%^Q1&G8O9trgeaAZ_KF@37|HY``Eqx;-C;Zp0uo zGQwB!-$bpo>DPRi_dNz-c_dK4S81|Y%HoJ_rc&+)>4pudlLC{ENtJ>BMOr};Q{cN_ zq?P2Y4jTL_^>;onqr3+9e2R1}a)?dW{xU<^_NxSh?3$#+?U1hW8Ri|3DjRnvvl;^ntK*vA5}(UDVa;o; zT-MH_WH^05>Ka|g%JnFuM{UJM;0LgpWPIb`LQ(}R<7q`J7cM}wv?kulwJ9o(GB1;q zAqS;4gp`bc8&9Mva5Y1^Mz)NG-I-DlNgfS_nbHk%BuzP)CGF-&*OpH}Yn>tLnUap_JuQne3mB1R*xb}vPDUizV& z-KoCi@gQLNNH5rT1sCvN`h#<>RJHco{#d-cFQ8o0^7KHW8Pl-Wg{|E3avS8+68+k7pHXQ*Zjl^5?Oa=bOQZVyPLiG*osM zOQANE#5!oIbT<=C@NLi{Tg=qX-2Fz9Ilq#y@*1-PG1S-HR>Dl@#${ID&q;S zhBe_${mN^a>6H%2q-FX*E-LGRHa`4HOMR;s7)JAaRcvxHeg*a>D(eX~TU<4K<@`!) zdc+ey7%doDl0zPlDHy7dHEzmH!SIzpE)+pR6GLtC)(#pjGgKloij=KQ44XN-A+PMQ z{}BgXLqd!plx%$oi((9&or>SuGp*26L*B#d7(;!}Q-9f0tz4(JOixsmY8ieJ6>|Lx znm096Ci(ARa8tt_yP#rwv_(YKr%H!rhU>ihwL3KLc9SNh&U-T49=?k=90kXC!!W#t;$K6tv#T$B*^K6DSMC1OhV`9@=Vf##MQ+aU3A7m(e}%3+!>QbX|Og{wPsIW9C7D@>_eucw4)+ z`P2+P&2K0w)f3xIGb#!MG8(X9cO4oY94_$F-@47NYtU$!!Hrm!DxH=Yrf_zJ>u3cL4K_gja&&I>b>OnX(8lSj@5|cq zdAb=!tuWND+isKU+{#wx7NK$T(IC?|+iP0t<3Ff=k2YUPz3E(X%pLN!@OUuq6qz;qV^AWpZdPtk`R4OFzhdwAZlA?))6ubJ=;e^7TGLfvv}~ z6no8H)x7$Q=+3ocvu@jmIg#cGMlZ>bVMXqub8C4Bx zy2(E{q*SNUcX2w}kGq1n$xC!j^Cf%De(F>7M{X6ET}56}zmI57SCsfz5|=)a!$l=7 z{3L4lqkt;uTb;!)t{xj>E{e)}q>W0w@rMP~1IHt=>(9u_JDdu@$o!(d{TjrYU zGbYFNjKu}P4?n`fcJ{d|M||aHG8z8>lo&aTthI&5F>)p1|3E3%RNlck+q|%&z3=>z zCSl`>mE+B1Bj@z^wOy&Qj{X0F_px%A$EjC#>hjmMWqK2;Yi#&g)Ya`3#Kp-_QuKENX7dwthpRP?h^R1xm>gEus}`8O}#H(nN@j<*13fFY+ z&3EeD$#NH;&e5+g`)T(b4pR@M2*Jqy+_kZY51hat9w?DzLtX8q?{s(x0>)RVB5 z*79c-k^@#LHF4 z>eDbiUN(`W)9_=w96;hu!=-pxAjZ@1hNk>!@NS9e%~Q~jrUy?!ADXT>1v6;HU| z>;r3B$p-o-+?`j24i{pHHb?RM#=L?0#2Sx_;b|*b^!l-w)wEtsySTA@7svI*P`$Oh z#Azk+kAD2~_1CmTs^&#CidkyScl`rP*SMkby52%t`7k^|dy4TK z@2F`PH&(uj%<{Bc*ITnP@$X^$e-CTXUR5O%zhbD?PF_TM6+=cl+1tJ^_TlIU=df!x(3mJo@6`~DqvhmVGyBBvx?kP+5tE}*U*!)y&W&V9-MQ<5@mxn)<&3)vS zoUTJ4Ua>ni?*Q-n%D}aU#r@={^6dlh>9=XtL-&|r{!LD!ne zw1!H9vCUTS%V0UOe5*jbRy~Wl^k@Zt4VL%dSxGyFpoT4%4wV!5z~VgUHB@fHPbtcS z9Yf`8Q%OF~c(}y@ow@MV?z)Ckxdq!6si` zMPa9OM=u0JGNU?J3a{mX|7f{7h>3EQ?v;^k$tl2A(xzaSv*(AJvkc`$kuu3Iy5Vaq7F8Xxc^4=#_ABVAl_X}9JZ;{4R-vC36d z&x9_^@NKvd+zmXYvSq|$R5bm7!C%1dkw;-0ak#EvJ^+hYdaL;(vFVcyI!k*sgQsO3 zFzE2*MoSYlk9)abo(hNL=Ry8xxu>!3724`dLo8NFeZtze{Pc(!KAs!kToO|mg2u|O zkTeD-fk&5N`xv=C|LjU0JRT#DbOAPy+n1^_OL;Jo3qqNx=L9XNtT(cpflbUVgWzw`#z1c2EI;`ZTUJ6 z@?cq#Eb=>Y^Wb2T>{-RAwyc_kidrg_X<}J_@#dryvh><77WE^iH0-F+e0M+QVA((IslY8x}Y07gkXTdXJMU zhdjN`xN|Sl^w=~sd5V6f`tU|=_{{>=@LX%@ZRk-f?Jw=Z0#Ru(c+^s*q~O#yBnh`q zp_*>876`j!ZN_=LT)BeZy}XjbZ}H3Y*t7-)3w9AA#>@Tu6KG${oI3R)3O&Q$CRt5a zzGh7ix@hh5_3^Tw?#9wEjiu_1JkU;%C-P3{faw!tuNIrmt2VBpDYJ2n^~j1fS2tK< z?qe&dNAOlMtad|Yu?cO^Vh69$){n;0t**YqfW&4k<_mf7=L9*lfy=GD5;_(ipi=4% zTm_AfMf;U#EOBUwIP)?5iB&&yv-(^H33_OQrO}@#n(p@g9CVr}`=*>aM^$o+F45tj zv2;COro_+)s}jAj&@+rC9HA{|mFQ>EeJAL_UI$SYFKKWq^6EJ4Z8b~?R7cAp4f;9W z{MORrCe`VQB}~-~#{|{QA9Y)d4A!G$hZI^XUJ_iuNpa}?vYfg)IDxF)R(@nCsj6jojF!2bVQ{}g?1lfLhdtV zZ?CV)ghqWK)YmFBj0zdcgerd_BA%0F7#+y#{?ZSKfX)|}le*`YBYWO;s^ zjw>1}b1@rhK5Xgjk2n23G#1bbff#3rWt9#1qO#7`%EryY7UeP_?=OTLRiSELH;


      7(k>Mo(qs>3T^21g>*gi8u4ui!hR`&* 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�FyJ;?U%XHSK4b`-174R?om6Lzow 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�kWsi1Ua?6WfWy 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 z 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 diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 09c9a0fd2b..a04f9a7984 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -98,8 +98,8 @@ program mksurfdata use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride use mksoilMod , only : soil_sand, soil_clay, mksoiltex, mksoilInit - use mksoilMod , only : soil_color, mksoilcol, mkorganic - use mksoilMod , only : soil_fmax, mkfmax + use mksoilMod , only : soil_color, mksoilcol, soil_fmax, mkfmax + use mksoildepthMod , only : mksoildepth use mkvocefMod , only : mkvocef use mkglacierregionMod , only : mkglacierregion use mkglcmecMod , only : nglcec, mkglcmec, mkglcmecInit, mkglacier @@ -110,12 +110,12 @@ program mksurfdata use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, numurbl use mkgdpMod , only : mkgdp use mkpeatMod , only : mkpeat - use mksoildepthMod , only : mksoildepth use mkagfirepkmonthMod , only : mkagfirepkmon use mktopostatsMod , only : mktopostats use mkVICparamsMod , only : mkVICparams #endif use mklanwatMod , only : mklakwat + use mkOrganicMod , only : mkorganic use mkutilsMod , only : normalize_classes_by_gcell, chkerr use mkfileMod , only : mkfile_fsurdat use mkvarpar , only : nlevsoi, elev_thresh, numstdpft @@ -128,6 +128,7 @@ program mksurfdata ! local variables type(ESMF_Mesh) :: mesh_model + type(ESMF_Field) :: field_model integer :: nsoicol ! number of model color classes integer :: k,m,n ! indices integer :: ni,nj,ns_o ! indices @@ -295,7 +296,7 @@ program mksurfdata if (ier /= 0) then call shr_sys_abort(' failed to open ndiag file '//trim(fsurlog)) end if - write (ndiag,*) 'Attempting to create surface boundary data .....' + write (ndiag,'(a)') 'Attempting to create surface boundary data .....' write (ndiag,'(72a1)') ("-",n=1,60) else ndiag = 6 @@ -343,8 +344,8 @@ program mksurfdata allocate ( pctwet(lsize_o)) ; pctwet(:) = spval allocate ( pcturb(lsize_o)) ; pcturb(:) = spval allocate ( urban_region(lsize_o)) ; urban_region(:) = -999 - !allocate ( urbn_classes(lsize_o,numurbl)) ; urbn_classes(:,:) = spval - !allocate ( urbn_classes_g(lsize_o,numurbl)) ; urbn_classes_g(:,:) = spval + !allocate ( urbn_classes(lsize_o,numurbl)) ; urbn_classes(:,:) = spval + !allocate ( urbn_classes_g(lsize_o,numurbl)) ; urbn_classes_g(:,:) = spval allocate ( pctsand(lsize_o,nlevsoi)) ; pctsand(:,:) = spval allocate ( pctclay(lsize_o,nlevsoi)) ; pctclay(:,:) = spval allocate ( soicol(lsize_o)) ; soicol(:) = -999 @@ -360,6 +361,7 @@ program mksurfdata allocate ( vic_ds(lsize_o)) ; vic_ds(:) = spval allocate ( lakedepth(lsize_o)) ; lakedepth(:) = spval allocate ( glacier_region(lsize_o)) ; glacier_region(:) = -999 + allocate ( organic(lsize_o,nlevsoi)) ; organic(:,:) = spval ! ---------------------------------------------------------------------- ! Read in and interpolate surface data set fields @@ -384,9 +386,15 @@ program mksurfdata ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] zero_out_lake = all_urban .or. all_veg zero_out_wetland = all_urban .or. all_veg .or. no_inlandwet - call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & - zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') + ! call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & + ! zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') + call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) + + ! Make organic matter density [organic] [forganic] + call mkorganic ( mksrf_forganic_mesh, mksrf_forganic, mesh_model, organic, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') + call ESMF_LogWrite("After mkorganic", ESMF_LOGMSG_INFO) ! ! Make glacier fraction [pctgla] from [fglacier] dataset ! call mkglacier ( mapfname=map_fglacier, datfname=mksrf_fglacier, ndiag=ndiag, zero_out=all_urban.or.all_veg, glac_o=pctgla) @@ -447,10 +455,6 @@ program mksurfdata ! binfl_o=vic_binfl, ws_o=vic_ws, dsmax_o=vic_dsmax, ds_o=vic_ds) ! end if - ! ! Make organic matter density [organic] [forganic] - ! allocate (organic(lsize_o,nlevsoi)) - ! organic(:,:) = spval - ! call mkorganic ( mapfname=map_forganic, datfname=mksrf_forganic, ndiag=ndiag, organic_o=organic) ! ! Make VOC emission factors for isoprene & ! ! [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] @@ -481,8 +485,8 @@ program mksurfdata do n = 1,lsize_o pctlak(n) = float(nint(pctlak(n))) pctwet(n) = float(nint(pctwet(n))) - write(6,*)'DEBUG: n,pctlak = ',n,pctlak(n) end do + call ESMF_LogWrite("After fixes", ESMF_LOGMSG_INFO) #ifdef TODO do n = 1,lsize_o @@ -617,11 +621,14 @@ program mksurfdata ! landuse file. if (fsurdat == ' ') then - write (6,*) 'fsurdat is blank: skipping writing surface dataset' + if (root_task) then + write (ndiag,'(a)') ' fsurdat is blank: skipping writing surface dataset' + end if else !call mkfile_fsurdat( mksrf_fgrid_mesh_nx, mksrf_fgrid_mesh_ny, mesh_model, dynlanduse=.false., harvdata) + call ESMF_LogWrite("Calling mkfile_fsurdat", ESMF_LOGMSG_INFO) call mkfile_fsurdat( mksrf_fgrid_mesh_nx, mksrf_fgrid_mesh_ny, mesh_model, dynlanduse=.false., & - pctlak=pctlak, pctwet=pctwet, lakedepth=lakedepth) + pctlak=pctlak, pctwet=pctwet, lakedepth=lakedepth, organic=organic) call ESMF_LogWrite(subname//'successfully created file '//trim(fsurdat), ESMF_LOGMSG_INFO) end if ! if (fsurdat /= ' ') @@ -822,352 +829,354 @@ program mksurfdata ! Close diagnostic dataset ! ---------------------------------------------------------------------- + if (root_task) then + write (ndiag,'(a)') + write (ndiag,'(a)') 'Surface data output file = '//trim(fsurdat) + write (ndiag,'(a)') ' This file contains the land model surface data' + write (ndiag,'(a)') 'Diagnostic log file = '//trim(fsurlog) + write (ndiag,'(a)') ' See this file for a summary of the dataset' + write (ndiag,'(a)') + write (ndiag,'(a)') 'Successfully created surface dataset' + end if + close (ndiag) - write (6,*) - write (6,*) 'Surface data output file = ',trim(fsurdat) - write (6,*) ' This file contains the land model surface data' - write (6,*) 'Diagnostic log file = ',trim(fsurlog) - write (6,*) ' See this file for a summary of the dataset' - write (6,*) - write (6,*) 'Successfully created surface dataset' + call ESMF_Finalize() -!----------------------------------------------------------------------- -contains -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + contains + !----------------------------------------------------------------------- #ifdef TODO - subroutine change_landuse( dynpft, lsize_o, mesh_o) + subroutine change_landuse( dynpft, lsize_o, mesh_o) + + ! Do landuse changes such as for the poles, etc. + ! If have pole points on grid - set south pole to glacier + ! north pole is assumed as non-land + + ! input/output variables + logical, intent(in) :: dynpft ! if part of the dynpft section of code + + ! !LOCAL VARIABLES: + integer :: n,lsize_o ! indices + character(len=32) :: subname = 'change_landuse' ! subroutine name + !----------------------------------------------------------------------- + + ! + + do n = 1,lsize_o + ! TODO: define latc + if (abs(latc(n) - 90._r8) < 1.e-6_r8) then + pctlak(n) = 0._r8 + pctwet(n) = 0._r8 + pcturb(n) = 0._r8 + pctgla(n) = 100._r8 + call pctnatpft(n)%set_pct_l2g(0._r8) + call pctcft(n)%set_pct_l2g(0._r8) + if ( .not. dynpft )then + organic(n,:) = 0._r8 + ef1_btr(n) = 0._r8 + ef1_fet(n) = 0._r8 + ef1_fdt(n) = 0._r8 + ef1_shr(n) = 0._r8 + ef1_grs(n) = 0._r8 + ef1_crp(n) = 0._r8 + end if + end if + + end do + end subroutine change_landuse - ! Do landuse changes such as for the poles, etc. - ! If have pole points on grid - set south pole to glacier - ! north pole is assumed as non-land - - ! input/output variables - logical, intent(in) :: dynpft ! if part of the dynpft section of code - - ! !LOCAL VARIABLES: - integer :: n,lsize_o ! indices - character(len=32) :: subname = 'change_landuse' ! subroutine name !----------------------------------------------------------------------- - - ! - - do n = 1,lsize_o - ! TODO: define latc - if (abs(latc(n) - 90._r8) < 1.e-6_r8) then - pctlak(n) = 0._r8 - pctwet(n) = 0._r8 - pcturb(n) = 0._r8 - pctgla(n) = 100._r8 - call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) - if ( .not. dynpft )then - organic(n,:) = 0._r8 - ef1_btr(n) = 0._r8 - ef1_fet(n) = 0._r8 - ef1_fdt(n) = 0._r8 - ef1_shr(n) = 0._r8 - ef1_grs(n) = 0._r8 - ef1_crp(n) = 0._r8 - end if - end if - - end do - end subroutine change_landuse -#endif - -#ifdef TODO - !----------------------------------------------------------------------- - subroutine normalizencheck_landuse(ldomain) - ! - ! Normalize land use and make sure things add up to 100% as well as - ! checking that things are as they should be. - ! - ! Precondition: pctlak + pctwet + pcturb + pctgla <= 100 (within roundoff) - ! - ! !USES: - use mkpftConstantsMod , only : baregroundindex - use mkpftUtilsMod , only : adjust_total_veg_area - implicit none - - ! !ARGUMENTS: - type(domain_type) :: ldomain - ! - ! !LOCAL VARIABLES: - integer :: m,k,n,ns_o ! indices - integer :: nsmall ! number of small PFT values for a single check - integer :: nsmall_tot ! total number of small PFT values in all grid cells - real(r8) :: suma ! sum for error check - real(r8) :: suma2 ! another sum for error check - real(r8) :: new_total_veg_pct ! new % veg (% of grid cell, total of natural veg & crop) - real(r8) :: bare_pct_p2g ! % of bare soil, as % of grid cell - real(r8) :: bare_urb_diff ! difference between bare soil and urban % - real(r8) :: pcturb_excess ! excess urban % not accounted for by bare soil - real(r8) :: sum8, sum8a ! sum for error check - real(r4) :: sum4a ! sum for error check - real(r8), parameter :: tol_loose = 1.e-4_r8 ! tolerance for some 'loose' error checks - real(r8), parameter :: toosmallPFT = 1.e-10_r8 ! tolerance for PFT's to ignore - character(len=32) :: subname = 'normalizencheck_landuse' ! subroutine name - !----------------------------------------------------------------------- - - ! ------------------------------------------------------------------------ - ! Normalize vegetated area so that vegetated + special area is 100% - ! ------------------------------------------------------------------------ - - ns_o = ldomain%ns - do n = 1,ns_o - - ! Check preconditions - if ( pctlak(n) < 0.0_r8 )then - write(6,*) subname, ' ERROR: pctlak is negative!' - write(6,*) 'n, pctlak = ', n, pctlak(n) - call shr_sys_abort() - end if - if ( pctwet(n) < 0.0_r8 )then - write(6,*) subname, ' ERROR: pctwet is negative!' - write(6,*) 'n, pctwet = ', n, pctwet(n) - call shr_sys_abort() - end if - if ( pcturb(n) < 0.0_r8 )then - write(6,*) subname, ' ERROR: pcturb is negative!' - write(6,*) 'n, pcturb = ', n, pcturb(n) - call shr_sys_abort() - end if - if ( pctgla(n) < 0.0_r8 )then - write(6,*) subname, ' ERROR: pctgla is negative!' - write(6,*) 'n, pctgla = ', n, pctgla(n) - call shr_sys_abort() - end if - - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - if (suma > (100._r8 + tol_loose)) then - write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla must be' - write(6,*) '<= 100% before calling this subroutine' - write(6,*) 'n, pctlak, pctwet, pcturb, pctgla = ', & - n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) - call shr_sys_abort() - end if - - ! First normalize vegetated (natural veg + crop) cover so that the total of - ! (vegetated + (special excluding urban)) is 100%. We'll deal with urban later. - ! - ! Note that, in practice, the total area of natural veg + crop is typically 100% - ! going into this routine. However, the following code does NOT rely on this, and - ! will work properly regardless of the initial area of natural veg + crop (even if - ! that initial area is 0%). - - suma = pctlak(n)+pctwet(n)+pctgla(n) - new_total_veg_pct = 100._r8 - suma - ! correct for rounding error: - new_total_veg_pct = max(new_total_veg_pct, 0._r8) - - call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) - - ! Make sure we did the above rescaling correctly - - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - if (abs(suma - 100._r8) > tol_loose) then - write(6,*) subname, ' ERROR in rescaling veg based on (special excluding urban' - write(6,*) 'suma = ', suma - call shr_sys_abort() - end if - - ! Now decrease the vegetated area to account for urban area. Urban needs to be - ! handled specially because we replace bare soil preferentially with urban, rather - ! than rescaling all PFTs equally. - - if (pcturb(n) > 0._r8) then - - ! Replace bare soil preferentially with urban - bare_pct_p2g = pctnatpft(n)%get_one_pct_p2g(baregroundindex) - bare_urb_diff = bare_pct_p2g - pcturb(n) - bare_pct_p2g = max(0._r8, bare_urb_diff) - call pctnatpft(n)%set_one_pct_p2g(baregroundindex, bare_pct_p2g) - pcturb_excess = abs(min(0._r8,bare_urb_diff)) - - ! For any urban not accounted for by bare soil, replace other PFTs - ! proportionally - if (pcturb_excess > 0._r8) then - ! Note that, in this case, we will have already reduced bare ground to 0% - - new_total_veg_pct = pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - pcturb_excess - if (new_total_veg_pct < 0._r8) then - if (abs(new_total_veg_pct) < tol_loose) then - ! only slightly less than 0; correct it - new_total_veg_pct = 0._r8 - else - write(6,*) subname, ' ERROR: trying to replace veg with urban,' - write(6,*) 'but pcturb_excess exceeds current vegetation percent' - call shr_sys_abort() - end if - end if - - call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) - end if - - end if ! pcturb(n) > 0 - - ! Confirm that we have done the rescaling correctly: now the sum of all landunits - ! should be 100% - suma = pctlak(n)+pctwet(n)+pctgla(n)+pcturb(n) - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - if (abs(suma - 100._r8) > tol_loose) then - write(6,*) subname, ' ERROR: landunits do not sum to 100%' - write(6,*) 'n, suma, pctlak, pctwet, pctgla, pcturb, pctnatveg, pctcrop = ' - write(6,*) n, suma, pctlak(n), pctwet(n), pctgla(n), pcturb(n), & - pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() - call shr_sys_abort() - end if - - end do - - ! ------------------------------------------------------------------------ - ! Do other corrections and error checks - ! ------------------------------------------------------------------------ - - nsmall_tot = 0 - - do n = 1,ns_o - - ! If the coverage of any PFT or CFT is too small at the gridcell level, set its - ! % cover to 0, then renormalize everything else as needed - call pctnatpft(n)%remove_small_cover(toosmallPFT, nsmall) - nsmall_tot = nsmall_tot + nsmall - call pctcft(n)%remove_small_cover(toosmallPFT, nsmall) - nsmall_tot = nsmall_tot + nsmall - - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - if ( abs(suma - 100.0_r8) > 2.0*epsilon(suma) )then - pctlak(n) = pctlak(n) * 100._r8/suma - pctwet(n) = pctwet(n) * 100._r8/suma - pcturb(n) = pcturb(n) * 100._r8/suma - pctgla(n) = pctgla(n) * 100._r8/suma - call pctnatpft(n)%set_pct_l2g(pctnatpft(n)%get_pct_l2g() * 100._r8/suma) - call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8/suma) - end if - - ! Roundoff error fix - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - suma2 = pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - if ( (suma < 100._r8 .and. suma > (100._r8 - 1.e-6_r8)) .or. & - (suma2 > 0.0_r8 .and. suma2 < 1.e-6_r8) ) then - write (6,*) 'Special land units near 100%, but not quite for n,suma =',n,suma - write (6,*) 'Adjusting special land units to 100%' - if (pctlak(n) >= 25._r8) then - pctlak(n) = 100._r8 - (pctwet(n) + pcturb(n) + pctgla(n)) - else if (pctwet(n) >= 25._r8) then - pctwet(n) = 100._r8 - (pctlak(n) + pcturb(n) + pctgla(n)) - else if (pcturb(n) >= 25._r8) then - pcturb(n) = 100._r8 - (pctlak(n) + pctwet(n) + pctgla(n)) - else if (pctgla(n) >= 25._r8) then - pctgla(n) = 100._r8 - (pctlak(n) + pctwet(n) + pcturb(n)) - else - write (6,*) subname, 'Error: sum of special land units nearly 100% but none is >= 25% at ', & - 'n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),pctnatveg(n),pctcrop(n),suma = ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& - pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(),suma - call shr_sys_abort() - end if - call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) - end if - if ( any(pctnatpft(n)%get_pct_p2g() > 0.0_r8 .and. pctnatpft(n)%get_pct_p2g() < toosmallPFT ) .or. & - any(pctcft(n)%get_pct_p2g() > 0.0_r8 .and. pctcft(n)%get_pct_p2g() < toosmallPFT )) then - write (6,*) 'pctnatpft or pctcft is small at n=', n - write (6,*) 'pctnatpft%pct_p2l = ', pctnatpft(n)%get_pct_p2l() - write (6,*) 'pctcft%pct_p2l = ', pctcft(n)%get_pct_p2l() - write (6,*) 'pctnatpft%pct_l2g = ', pctnatpft(n)%get_pct_l2g() - write (6,*) 'pctcft%pct_l2g = ', pctcft(n)%get_pct_l2g() - call shr_sys_abort() - end if - - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - if (suma < 100._r8-epsilon(suma) .and. suma > (100._r8 - 4._r8*epsilon(suma))) then - write (6,*) subname, 'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& - pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() - call shr_sys_abort() - end if - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - if ( abs(suma-100._r8) > 1.e-10_r8) then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb, pctgla, pctnatveg and pctcrop is NOT equal to 100' - write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,sum= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& - pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), suma - call shr_sys_abort() - end if - - end do - - ! Check that when pctnatveg+pctcrop identically zero, sum of special landunits is identically 100% - - if ( .not. outnc_double )then - do n = 1,ns_o - sum8 = real(pctlak(n),r4) - sum8 = sum8 + real(pctwet(n),r4) - sum8 = sum8 + real(pcturb(n),r4) - sum8 = sum8 + real(pctgla(n),r4) - sum4a = real(pctnatpft(n)%get_pct_l2g(),r4) - sum4a = sum4a + real(pctcft(n)%get_pct_l2g(),r4) - if ( sum4a==0.0_r4 .and. sum8 < 100._r4-2._r4*epsilon(sum4a) )then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 - write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n), & - pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g() - call shr_sys_abort() - end if - end do - else - do n = 1,ns_o - sum8 = pctlak(n) - sum8 = sum8 + pctwet(n) - sum8 = sum8 + pcturb(n) - sum8 = sum8 + pctgla(n) - sum8a = pctnatpft(n)%get_pct_l2g() - sum8a = sum8a + pctcft(n)%get_pct_l2g() - if ( sum8a==0._r8 .and. sum8 < (100._r8-4._r8*epsilon(sum8)) )then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 - write (6,*) 'Total error, error/epsilon = ',100._r8-sum8, ((100._r8-sum8)/epsilon(sum8)) - write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,epsilon= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& - pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), epsilon(sum8) - call shr_sys_abort() - end if - end do - end if - - ! Make sure that there is no vegetation outside the pft mask - do n = 1,ns_o - if (pftdata_mask(n) == 0 .and. (pctnatpft(n)%get_pct_l2g() > 0 .or. pctcft(n)%get_pct_l2g() > 0)) then - write (6,*)'vegetation found outside the pft mask at n=',n - write (6,*)'pctnatveg,pctcrop=', pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() - call shr_sys_abort() - end if - end do - - ! Make sure that sums at the landunit level all add to 100% - ! (Note that we don't check pctglcmec here, because it isn't computed at the point - ! that this subroutine is called -- but the check of sum(pctglcmec) is done in - ! mkglcmecMod) - ! (Also note that we don't need to check pctnatpft or pctcft, because a similar check - ! is done internally by the pct_pft_type routines.) - do n = 1,ns_o - if (abs(sum(urbn_classes(n,:)) - 100._r8) > 1.e-12_r8) then - write(6,*) 'sum(urbn_classes(n,:)) != 100: ', n, sum(urbn_classes(n,:)) - call shr_sys_abort() - end if - end do - - if ( nsmall_tot > 0 )then - write (6,*)'number of small pft = ', nsmall_tot - end if - - end subroutine normalizencheck_landuse + subroutine normalizencheck_landuse(ldomain) + ! + ! Normalize land use and make sure things add up to 100% as well as + ! checking that things are as they should be. + ! + ! Precondition: pctlak + pctwet + pcturb + pctgla <= 100 (within roundoff) + ! + ! !USES: + use mkpftConstantsMod , only : baregroundindex + use mkpftUtilsMod , only : adjust_total_veg_area + implicit none + + ! !ARGUMENTS: + type(domain_type) :: ldomain + ! + ! !LOCAL VARIABLES: + integer :: m,k,n,ns_o ! indices + integer :: nsmall ! number of small PFT values for a single check + integer :: nsmall_tot ! total number of small PFT values in all grid cells + real(r8) :: suma ! sum for error check + real(r8) :: suma2 ! another sum for error check + real(r8) :: new_total_veg_pct ! new % veg (% of grid cell, total of natural veg & crop) + real(r8) :: bare_pct_p2g ! % of bare soil, as % of grid cell + real(r8) :: bare_urb_diff ! difference between bare soil and urban % + real(r8) :: pcturb_excess ! excess urban % not accounted for by bare soil + real(r8) :: sum8, sum8a ! sum for error check + real(r4) :: sum4a ! sum for error check + real(r8), parameter :: tol_loose = 1.e-4_r8 ! tolerance for some 'loose' error checks + real(r8), parameter :: toosmallPFT = 1.e-10_r8 ! tolerance for PFT's to ignore + character(len=32) :: subname = 'normalizencheck_landuse' ! subroutine name + !----------------------------------------------------------------------- + + ! ------------------------------------------------------------------------ + ! Normalize vegetated area so that vegetated + special area is 100% + ! ------------------------------------------------------------------------ + + ns_o = ldomain%ns + do n = 1,ns_o + + ! Check preconditions + if ( pctlak(n) < 0.0_r8 )then + write(6,*) subname, ' ERROR: pctlak is negative!' + write(6,*) 'n, pctlak = ', n, pctlak(n) + call shr_sys_abort() + end if + if ( pctwet(n) < 0.0_r8 )then + write(6,*) subname, ' ERROR: pctwet is negative!' + write(6,*) 'n, pctwet = ', n, pctwet(n) + call shr_sys_abort() + end if + if ( pcturb(n) < 0.0_r8 )then + write(6,*) subname, ' ERROR: pcturb is negative!' + write(6,*) 'n, pcturb = ', n, pcturb(n) + call shr_sys_abort() + end if + if ( pctgla(n) < 0.0_r8 )then + write(6,*) subname, ' ERROR: pctgla is negative!' + write(6,*) 'n, pctgla = ', n, pctgla(n) + call shr_sys_abort() + end if + + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + if (suma > (100._r8 + tol_loose)) then + write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla must be' + write(6,*) '<= 100% before calling this subroutine' + write(6,*) 'n, pctlak, pctwet, pcturb, pctgla = ', & + n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) + call shr_sys_abort() + end if + + ! First normalize vegetated (natural veg + crop) cover so that the total of + ! (vegetated + (special excluding urban)) is 100%. We'll deal with urban later. + ! + ! Note that, in practice, the total area of natural veg + crop is typically 100% + ! going into this routine. However, the following code does NOT rely on this, and + ! will work properly regardless of the initial area of natural veg + crop (even if + ! that initial area is 0%). + + suma = pctlak(n)+pctwet(n)+pctgla(n) + new_total_veg_pct = 100._r8 - suma + ! correct for rounding error: + new_total_veg_pct = max(new_total_veg_pct, 0._r8) + + call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) + + ! Make sure we did the above rescaling correctly + + suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + if (abs(suma - 100._r8) > tol_loose) then + write(6,*) subname, ' ERROR in rescaling veg based on (special excluding urban' + write(6,*) 'suma = ', suma + call shr_sys_abort() + end if + + ! Now decrease the vegetated area to account for urban area. Urban needs to be + ! handled specially because we replace bare soil preferentially with urban, rather + ! than rescaling all PFTs equally. + + if (pcturb(n) > 0._r8) then + + ! Replace bare soil preferentially with urban + bare_pct_p2g = pctnatpft(n)%get_one_pct_p2g(baregroundindex) + bare_urb_diff = bare_pct_p2g - pcturb(n) + bare_pct_p2g = max(0._r8, bare_urb_diff) + call pctnatpft(n)%set_one_pct_p2g(baregroundindex, bare_pct_p2g) + pcturb_excess = abs(min(0._r8,bare_urb_diff)) + + ! For any urban not accounted for by bare soil, replace other PFTs + ! proportionally + if (pcturb_excess > 0._r8) then + ! Note that, in this case, we will have already reduced bare ground to 0% + + new_total_veg_pct = pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - pcturb_excess + if (new_total_veg_pct < 0._r8) then + if (abs(new_total_veg_pct) < tol_loose) then + ! only slightly less than 0; correct it + new_total_veg_pct = 0._r8 + else + write(6,*) subname, ' ERROR: trying to replace veg with urban,' + write(6,*) 'but pcturb_excess exceeds current vegetation percent' + call shr_sys_abort() + end if + end if + + call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) + end if + + end if ! pcturb(n) > 0 + + ! Confirm that we have done the rescaling correctly: now the sum of all landunits + ! should be 100% + suma = pctlak(n)+pctwet(n)+pctgla(n)+pcturb(n) + suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + if (abs(suma - 100._r8) > tol_loose) then + write(6,*) subname, ' ERROR: landunits do not sum to 100%' + write(6,*) 'n, suma, pctlak, pctwet, pctgla, pcturb, pctnatveg, pctcrop = ' + write(6,*) n, suma, pctlak(n), pctwet(n), pctgla(n), pcturb(n), & + pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() + call shr_sys_abort() + end if + + end do + + ! ------------------------------------------------------------------------ + ! Do other corrections and error checks + ! ------------------------------------------------------------------------ + + nsmall_tot = 0 + + do n = 1,ns_o + + ! If the coverage of any PFT or CFT is too small at the gridcell level, set its + ! % cover to 0, then renormalize everything else as needed + call pctnatpft(n)%remove_small_cover(toosmallPFT, nsmall) + nsmall_tot = nsmall_tot + nsmall + call pctcft(n)%remove_small_cover(toosmallPFT, nsmall) + nsmall_tot = nsmall_tot + nsmall + + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + if ( abs(suma - 100.0_r8) > 2.0*epsilon(suma) )then + pctlak(n) = pctlak(n) * 100._r8/suma + pctwet(n) = pctwet(n) * 100._r8/suma + pcturb(n) = pcturb(n) * 100._r8/suma + pctgla(n) = pctgla(n) * 100._r8/suma + call pctnatpft(n)%set_pct_l2g(pctnatpft(n)%get_pct_l2g() * 100._r8/suma) + call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8/suma) + end if + + ! Roundoff error fix + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + suma2 = pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + if ( (suma < 100._r8 .and. suma > (100._r8 - 1.e-6_r8)) .or. & + (suma2 > 0.0_r8 .and. suma2 < 1.e-6_r8) ) then + write (6,*) 'Special land units near 100%, but not quite for n,suma =',n,suma + write (6,*) 'Adjusting special land units to 100%' + if (pctlak(n) >= 25._r8) then + pctlak(n) = 100._r8 - (pctwet(n) + pcturb(n) + pctgla(n)) + else if (pctwet(n) >= 25._r8) then + pctwet(n) = 100._r8 - (pctlak(n) + pcturb(n) + pctgla(n)) + else if (pcturb(n) >= 25._r8) then + pcturb(n) = 100._r8 - (pctlak(n) + pctwet(n) + pctgla(n)) + else if (pctgla(n) >= 25._r8) then + pctgla(n) = 100._r8 - (pctlak(n) + pctwet(n) + pcturb(n)) + else + write (6,*) subname, 'Error: sum of special land units nearly 100% but none is >= 25% at ', & + 'n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),pctnatveg(n),pctcrop(n),suma = ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& + pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(),suma + call shr_sys_abort() + end if + call pctnatpft(n)%set_pct_l2g(0._r8) + call pctcft(n)%set_pct_l2g(0._r8) + end if + if ( any(pctnatpft(n)%get_pct_p2g() > 0.0_r8 .and. pctnatpft(n)%get_pct_p2g() < toosmallPFT ) .or. & + any(pctcft(n)%get_pct_p2g() > 0.0_r8 .and. pctcft(n)%get_pct_p2g() < toosmallPFT )) then + write (6,*) 'pctnatpft or pctcft is small at n=', n + write (6,*) 'pctnatpft%pct_p2l = ', pctnatpft(n)%get_pct_p2l() + write (6,*) 'pctcft%pct_p2l = ', pctcft(n)%get_pct_p2l() + write (6,*) 'pctnatpft%pct_l2g = ', pctnatpft(n)%get_pct_l2g() + write (6,*) 'pctcft%pct_l2g = ', pctcft(n)%get_pct_l2g() + call shr_sys_abort() + end if + + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + if (suma < 100._r8-epsilon(suma) .and. suma > (100._r8 - 4._r8*epsilon(suma))) then + write (6,*) subname, 'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& + pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() + call shr_sys_abort() + end if + suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + if ( abs(suma-100._r8) > 1.e-10_r8) then + write (6,*) subname, ' error: sum of pctlak, pctwet,', & + 'pcturb, pctgla, pctnatveg and pctcrop is NOT equal to 100' + write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,sum= ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& + pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), suma + call shr_sys_abort() + end if + + end do + + ! Check that when pctnatveg+pctcrop identically zero, sum of special landunits is identically 100% + + if ( .not. outnc_double )then + do n = 1,ns_o + sum8 = real(pctlak(n),r4) + sum8 = sum8 + real(pctwet(n),r4) + sum8 = sum8 + real(pcturb(n),r4) + sum8 = sum8 + real(pctgla(n),r4) + sum4a = real(pctnatpft(n)%get_pct_l2g(),r4) + sum4a = sum4a + real(pctcft(n)%get_pct_l2g(),r4) + if ( sum4a==0.0_r4 .and. sum8 < 100._r4-2._r4*epsilon(sum4a) )then + write (6,*) subname, ' error: sum of pctlak, pctwet,', & + 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 + write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n), & + pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g() + call shr_sys_abort() + end if + end do + else + do n = 1,ns_o + sum8 = pctlak(n) + sum8 = sum8 + pctwet(n) + sum8 = sum8 + pcturb(n) + sum8 = sum8 + pctgla(n) + sum8a = pctnatpft(n)%get_pct_l2g() + sum8a = sum8a + pctcft(n)%get_pct_l2g() + if ( sum8a==0._r8 .and. sum8 < (100._r8-4._r8*epsilon(sum8)) )then + write (6,*) subname, ' error: sum of pctlak, pctwet,', & + 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 + write (6,*) 'Total error, error/epsilon = ',100._r8-sum8, ((100._r8-sum8)/epsilon(sum8)) + write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,epsilon= ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& + pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), epsilon(sum8) + call shr_sys_abort() + end if + end do + end if + + ! Make sure that there is no vegetation outside the pft mask + do n = 1,ns_o + if (pftdata_mask(n) == 0 .and. (pctnatpft(n)%get_pct_l2g() > 0 .or. pctcft(n)%get_pct_l2g() > 0)) then + write (6,*)'vegetation found outside the pft mask at n=',n + write (6,*)'pctnatveg,pctcrop=', pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() + call shr_sys_abort() + end if + end do + + ! Make sure that sums at the landunit level all add to 100% + ! (Note that we don't check pctglcmec here, because it isn't computed at the point + ! that this subroutine is called -- but the check of sum(pctglcmec) is done in + ! mkglcmecMod) + ! (Also note that we don't need to check pctnatpft or pctcft, because a similar check + ! is done internally by the pct_pft_type routines.) + do n = 1,ns_o + if (abs(sum(urbn_classes(n,:)) - 100._r8) > 1.e-12_r8) then + write(6,*) 'sum(urbn_classes(n,:)) != 100: ', n, sum(urbn_classes(n,:)) + call shr_sys_abort() + end if + end do + + if ( nsmall_tot > 0 )then + write (6,*)'number of small pft = ', nsmall_tot + end if + + end subroutine normalizencheck_landuse #endif end program mksurfdata diff --git a/tools/mksurfdata_esmf/src/mkutilsMod.F90 b/tools/mksurfdata_esmf/src/mkutilsMod.F90 index 77ea3dd75b..7a2439972c 100644 --- a/tools/mksurfdata_esmf/src/mkutilsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkutilsMod.F90 @@ -64,14 +64,14 @@ subroutine normalize_classes_by_gcell(classes_pct_tot, sums, classes_pct_gcell) write(6,*) 'size(sums) = ', n_max write(6,*) 'size(classes_pct_tot, 1) = ', size(classes_pct_tot, 1) write(6,*) 'size(classes_pct_gcell, 1) = ', size(classes_pct_gcell, 1) - call abort() + call shr_sys_abort() end if if (size(classes_pct_tot, 2) /= size(classes_pct_gcell, 2)) then write(6,*) subname//' ERROR: array size mismatch' write(6,*) 'size(classes_pct_tot, 2) = ', size(classes_pct_tot, 2) write(6,*) 'size(classes_pct_gcell, 2) = ', size(classes_pct_gcell, 2) - call abort() + call shr_sys_abort() end if ! Do the work diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index 25dd8fc10d..ace024f4c6 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -329,63 +329,84 @@ subroutine write_namelist_input() ! Note - need to call this after ndiag has been set if (root_task) then - write(ndiag,'(a)') 'PFTs from: '//trim(mksrf_fvegtyp) - write(ndiag,'(a)') 'harvest from: '//trim(mksrf_fhrvtyp) - write(ndiag,'(a)') 'fmax from: '//trim(mksrf_fmax) - write(ndiag,'(a)') 'glaciers from: '//trim(mksrf_fglacier) -#ifdef TODO - write(ndiag,'(a)') ' with: '// nglcec, ' glacier elevation classes' -#endif - write(ndiag,'(a)') 'glacier region ID from: '//trim(mksrf_fglacierregion) - write(ndiag,'(a)') 'urban topography from: '//trim(mksrf_furbtopo) - write(ndiag,'(a)') 'urban from: '//trim(mksrf_furban) - write(ndiag,'(a)') 'inland lake from: '//trim(mksrf_flakwat) - write(ndiag,'(a)') 'inland wetland from: '//trim(mksrf_fwetlnd) - write(ndiag,'(a)') 'soil texture from: '//trim(mksrf_fsoitex) - write(ndiag,'(a)') 'soil organic from: '//trim(mksrf_forganic) - write(ndiag,'(a)') 'soil color from: '//trim(mksrf_fsoicol) - write(ndiag,'(a)') 'VOC emission factors from: '//trim(mksrf_fvocef) - write(ndiag,'(a)') 'gdp from: '//trim(mksrf_fgdp) - write(ndiag,'(a)') 'peat from: '//trim(mksrf_fpeat) - write(ndiag,'(a)') 'soil depth from: '//trim(mksrf_fsoildepth) - write(ndiag,'(a)') 'abm from: '//trim(mksrf_fabm) - write(ndiag,'(a)') 'topography statistics from: '//trim(mksrf_ftopostats) - write(ndiag,'(a)') 'VIC parameters from: '//trim(mksrf_fvic) + write(ndiag,'(a)')'Input rawdata files and corresponding meshes' + write(ndiag,'(a)')' PFTs from: '//trim(mksrf_fvegtyp) write(ndiag,'(a)')' mesh for pft '//trim(mksrf_fvegtyp_mesh) + write(ndiag,*) + write(ndiag,'(a)')' inland lake from: '//trim(mksrf_flakwat) write(ndiag,'(a)')' mesh for lake water '//trim(mksrf_flakwat_mesh) + write(ndiag,*) + write(ndiag,'(a)')' inland wetland from: '//trim(mksrf_fwetlnd) write(ndiag,'(a)')' mesh for wetland '//trim(mksrf_fwetlnd_mesh) - write(ndiag,'(a)')' mesh for glacier '//trim(mksrf_fglacier_mesh) - write(ndiag,'(a)')' mesh for glacier region '//trim(mksrf_fglacierregion_mesh) + write(ndiag,*) + write(ndiag,'(a)')' soil texture from: '//trim(mksrf_fsoitex) write(ndiag,'(a)')' mesh for soil texture '//trim(mksrf_fsoitex_mesh) - write(ndiag,'(a)')' mesh for soil color '//trim(mksrf_fsoicol_mesh) + write(ndiag,*) + write(ndiag,'(a)')' soil organic from: '//trim(mksrf_forganic) write(ndiag,'(a)')' mesh for soil organic '//trim(mksrf_forganic_mesh) - write(ndiag,'(a)')' mesh for urban '//trim(mksrf_furban_mesh) + write(ndiag,*) + write(ndiag,'(a)')' soil color from: '//trim(mksrf_fsoicol) + write(ndiag,'(a)')' mesh for soil color '//trim(mksrf_fsoicol_mesh) + write(ndiag,*) + write(ndiag,'(a)')' fmax from: '//trim(mksrf_fmax) write(ndiag,'(a)')' mesh for fmax '//trim(mksrf_fmax_mesh) + write(ndiag,*) + write(ndiag,'(a)')' soil depth from: '//trim(mksrf_fsoildepth) + write(ndiag,'(a)')' mesh for soil depth '//trim(mksrf_fsoildepth_mesh) + write(ndiag,*) + write(ndiag,'(a)')' VOC emission factors from: '//trim(mksrf_fvocef) write(ndiag,'(a)')' mesh for VOC pct emis '//trim(mksrf_fvocef_mesh) + write(ndiag,*) + write(ndiag,'(a)')' gdp from: '//trim(mksrf_fgdp) + write(ndiag,'(a)')' mesh for gdp '//trim(mksrf_fgdp_mesh) + write(ndiag,*) + write(ndiag,'(a)')' peat from: '//trim(mksrf_fpeat) + write(ndiag,'(a)')' mesh for peatlands '//trim(mksrf_fpeat_mesh) + write(ndiag,*) + write(ndiag,'(a)')' harvest from: '//trim(mksrf_fhrvtyp) write(ndiag,'(a)')' mesh for harvest '//trim(mksrf_fhrv_mesh) + write(ndiag,*) + write(ndiag,'(a)')' topography statistics from: '//trim(mksrf_ftopostats) + write(ndiag,'(a)')' mesh for topography stats '//trim(mksrf_ftopostats_mesh) + write(ndiag,*) + write(ndiag,'(a)')' glaciers from: '//trim(mksrf_fglacier) +#ifdef TODO + write(ndiag,'(a)')' with: '// nglcec, ' glacier elevation classes' +#endif + write(ndiag,'(a)')' mesh for glacier '//trim(mksrf_fglacier_mesh) + write(ndiag,'(a)')' glacier region ID from: '//trim(mksrf_fglacierregion) + write(ndiag,'(a)')' mesh for glacier region '//trim(mksrf_fglacierregion_mesh) + write(ndiag,*) + write(ndiag,'(a)')' urban from: '//trim(mksrf_furban) + write(ndiag,'(a)')' mesh for urban '//trim(mksrf_furban_mesh) + write(ndiag,*) + write(ndiag,'(a)')' urban topography from: '//trim(mksrf_furbtopo) + write(ndiag,'(a)')' mesh for urban topography '//trim(mksrf_furbtopo_mesh) + write(ndiag,*) write(ndiag,'(a)')' mesh for lai/sai '//trim(mksrf_flai_mesh) - write(ndiag,'(a)')' mesh for urb topography '//trim(mksrf_furbtopo_mesh) - write(ndiag,'(a)')' mesh for GDP '//trim(mksrf_fgdp_mesh) - write(ndiag,'(a)')' mesh for peatlands '//trim(mksrf_fpeat_mesh) - write(ndiag,'(a)')' mesh for soil depth '//trim(mksrf_fsoildepth_mesh) write(ndiag,'(a)')' mesh for ag fire pk month '//trim(mksrf_fabm_mesh) - write(ndiag,'(a)')' mesh for topography stats '//trim(mksrf_ftopostats_mesh) + write(ndiag,*) + write(ndiag,'(a)')' abm from: '//trim(mksrf_fabm) + write(ndiag,*) + write(ndiag,'(a)')' VIC parameters from: '//trim(mksrf_fvic) write(ndiag,'(a)')' mesh for VIC parameters '//trim(mksrf_fvic_mesh) - - write(ndiag,'(a)')' mksrf_gridtype = '//trim(mksrf_gridtype) - + write(ndiag,*) if (mksrf_fdynuse /= ' ') then write(ndiag,'(a)')' mksrf_fdynuse = '//trim(mksrf_fdynuse) end if - + write(ndiag,*) + write(ndiag,'(a)')'Model grid configuration variables' write(ndiag,'(a)')' mksrf_fgrid_mesh = '//trim(mksrf_fgrid_mesh) + write(ndiag,'(a,i8)')' nlon= ',mksrf_fgrid_mesh_nx + write(ndiag,'(a,i8)')' nlat= ',mksrf_fgrid_mesh_ny + write(ndiag,'(a)')' mksrf_gridtype = '//trim(mksrf_gridtype) + write(ndiag,*) + write(ndiag,'(a)')'Output configuration variables' if (outnc_1d) then write(ndiag,'(a)')' output file will be 1d format' else write(ndiag,'(a)')' fsurdat is 2d lat/lon grid' end if - write(ndiag,'(a,i8)')' nlon= ',mksrf_fgrid_mesh_nx - write(ndiag,'(a,i8)')' nlat= ',mksrf_fgrid_mesh_ny if ( outnc_large_files ) then write(ndiag,'(a)')' Output file in NetCDF 64-bit large_files format' end if diff --git a/tools/mksurfdata_esmf/src/run_mksurfdata b/tools/mksurfdata_esmf/src/run_mksurfdata index 299519218b..a4d4dd973b 100644 --- a/tools/mksurfdata_esmf/src/run_mksurfdata +++ b/tools/mksurfdata_esmf/src/run_mksurfdata @@ -20,4 +20,4 @@ mkdir -p $TMPDIR #make # -np {total_tasks} -mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata +mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/run/mksurfdata diff --git a/tools/mksurfdata_map/src/mkncdio.F90 b/tools/mksurfdata_map/src/mkncdio.F90 deleted file mode 100644 index 555eb6ae80..0000000000 --- a/tools/mksurfdata_map/src/mkncdio.F90 +++ /dev/null @@ -1,558 +0,0 @@ -module mkncdio - -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkncdio -! -! !DESCRIPTION: -! Generic interfaces to write fields to netcdf files, and other useful netcdf operations -! -! !USES: - use shr_kind_mod , only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush -! -! !PUBLIC TYPES: - implicit none - include 'netcdf.inc' - save - - private - - public :: check_ret ! checks return status of netcdf calls - public :: ncd_defvar ! define netCDF input variable - public :: ncd_def_spatial_var ! define spatial netCDF variable (convenience wrapper to ncd_defvar) - public :: ncd_put_time_slice ! write a single time slice of a variable - public :: get_dim_lengths ! get dimension lengths of a netcdf variable - - interface ncd_def_spatial_var - module procedure ncd_def_spatial_var_0lev - module procedure ncd_def_spatial_var_1lev - module procedure ncd_def_spatial_var_2lev - end interface ncd_def_spatial_var - - interface ncd_put_time_slice - module procedure ncd_put_time_slice_1d - module procedure ncd_put_time_slice_2d - end interface ncd_put_time_slice - - public :: convert_latlon ! convert a latitude or longitude variable to degrees E / N -! -! !REVISION HISTORY: -! -! -! !PRIVATE MEMBER FUNCTIONS: -! - private :: get_time_slice_beg_and_len ! determine beg and len vectors for writing a time slice - - logical :: masterproc = .true. ! always use 1 proc - real(r8) :: spval = 1.e36 ! special value - - public :: nf_open - public :: nf_close - public :: nf_write - public :: nf_sync - public :: nf_inq_attlen - public :: nf_inq_dimlen - public :: nf_inq_dimname - public :: nf_inq_varid - public :: nf_inq_varndims - public :: nf_inq_vardimid - public :: nf_get_att_double - public :: nf_get_att_text - public :: nf_get_var_double - public :: nf_get_vara_double - public :: nf_get_var_int - public :: nf_get_vara_int - public :: nf_put_var_double - public :: nf_put_vara_double - public :: nf_put_var_int - public :: nf_put_vara_int - public :: nf_inq_dimid - public :: nf_max_name - public :: nf_max_var_dims - public :: nf_noerr - public :: nf_nowrite - public :: nf_enotatt - public :: nf_strerror -!EOP -!----------------------------------------------------------------------- - -contains - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: check_ret -! -! !INTERFACE: - subroutine check_ret(ret, calling, varexists) -! -! !DESCRIPTION: -! Check return status from netcdf call -! -! !ARGUMENTS: - implicit none - integer, intent(in) :: ret - character(len=*) :: calling - logical, intent(out), optional :: varexists -! -! !REVISION HISTORY: -! -!EOP -!----------------------------------------------------------------------- - - if ( present(varexists) ) varexists = .true. - if ( present(varexists) .and. ret == NF_ENOTVAR )then - varexists = .false. - else if (ret /= NF_NOERR) then - write(6,*)'netcdf error from ',trim(calling), ' rcode = ', ret, & - ' error = ', NF_STRERROR(ret) - call abort() - end if - - end subroutine check_ret - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: ncd_defvar -! -! !INTERFACE: - subroutine ncd_defvar(ncid, varname, xtype, & - dim1name, dim2name, dim3name, dim4name, dim5name, & - long_name, units, cell_method, missing_value, fill_value, & - imissing_value, ifill_value) -! -! !DESCRIPTION: -! Define a netcdf variable -! -! !ARGUMENTS: - implicit none - integer , intent(in) :: ncid ! input unit - character(len=*), intent(in) :: varname ! variable name - integer , intent(in) :: xtype ! external type - character(len=*), intent(in), optional :: dim1name ! dimension name - character(len=*), intent(in), optional :: dim2name ! dimension name - character(len=*), intent(in), optional :: dim3name ! dimension name - character(len=*), intent(in), optional :: dim4name ! dimension name - character(len=*), intent(in), optional :: dim5name ! dimension name - character(len=*), intent(in), optional :: long_name ! attribute - character(len=*), intent(in), optional :: units ! attribute - character(len=*), intent(in), optional :: cell_method ! attribute - real(r8) , intent(in), optional :: missing_value ! attribute for real - real(r8) , intent(in), optional :: fill_value ! attribute for real - integer , intent(in), optional :: imissing_value ! attribute for int - integer , intent(in), optional :: ifill_value ! attribute for int -! -! !REVISION HISTORY: -! -! -! !LOCAL VARIABLES: -!EOP - integer :: n ! indices - integer :: ndims ! dimension counter - integer :: dimid(5) ! dimension ids - integer :: varid ! variable id - integer :: itmp ! temporary - character(len=256) :: str ! temporary - character(len=32) :: subname='NCD_DEFVAR_REAL' ! subroutine name -!----------------------------------------------------------------------- - - if (.not. masterproc) return - - ! Determine dimension ids for variable - - dimid(:) = 0 - - if (present(dim1name)) then - call check_ret(nf_inq_dimid(ncid, dim1name, dimid(1)), subname) - end if - if (present(dim2name)) then - call check_ret(nf_inq_dimid(ncid, dim2name, dimid(2)), subname) - end if - if (present(dim3name)) then - call check_ret(nf_inq_dimid(ncid, dim3name, dimid(3)), subname) - end if - if (present(dim4name)) then - call check_ret(nf_inq_dimid(ncid, dim4name, dimid(4)), subname) - end if - if (present(dim5name)) then - call check_ret(nf_inq_dimid(ncid, dim5name, dimid(5)), subname) - end if - - ! Define variable - - if (present(dim1name)) then - ndims = 0 - do n = 1, size(dimid) - if (dimid(n) /= 0) ndims = ndims + 1 - end do - call check_ret(nf_def_var(ncid, trim(varname), xtype, ndims, dimid(1:ndims), varid), subname) - else - call check_ret(nf_def_var(ncid, varname, xtype, 0, 0, varid), subname) - end if - if (present(long_name)) then - call check_ret(nf_put_att_text(ncid, varid, 'long_name', len_trim(long_name), trim(long_name)), subname) - end if - if (present(units)) then - call check_ret(nf_put_att_text(ncid, varid, 'units', len_trim(units), trim(units)), subname) - end if - if (present(cell_method)) then - str = 'time: ' // trim(cell_method) - call check_ret(nf_put_att_text(ncid, varid, 'cell_method', len_trim(str), trim(str)), subname) - end if - if (present(fill_value)) then - call check_ret(nf_put_att_double(ncid, varid, '_FillValue', xtype, 1, fill_value), subname) - end if - if (present(missing_value)) then - call check_ret(nf_put_att_double(ncid, varid, 'missing_value', xtype, 1, missing_value), subname) - end if - if (present(ifill_value)) then - call check_ret(nf_put_att_int(ncid, varid, '_FillValue', xtype, 1, ifill_value), subname) - end if - if (present(imissing_value)) then - call check_ret(nf_put_att_int(ncid, varid, 'missing_value', xtype, 1, imissing_value), subname) - end if - - end subroutine ncd_defvar - - ! ======================================================================== - ! ncd_def_spatial_var routines: define a spatial netCDF variable (convenience wrapper to - ! ncd_defvar) - ! ======================================================================== - - !----------------------------------------------------------------------- - subroutine ncd_def_spatial_var_0lev(ncid, varname, xtype, long_name, units) - ! - ! !DESCRIPTION: - ! Define a spatial netCDF variable (convenience wrapper to ncd_defvar) - ! - ! The variable in question has ONLY spatial dimensions (no level or time dimensions) - ! - ! !USES: - use mkvarctl, only : outnc_1d - ! - ! !ARGUMENTS: - integer , intent(in) :: ncid ! input unit - character(len=*) , intent(in) :: varname ! variable name - integer , intent(in) :: xtype ! external type - character(len=*) , intent(in) :: long_name ! attribute - character(len=*) , intent(in) :: units ! attribute - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'ncd_def_spatial_var_0lev' - !----------------------------------------------------------------------- - - if (outnc_1d) then - call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & - dim1name='gridcell', & - long_name=long_name, units=units) - else - call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & - dim1name='lsmlon', dim2name='lsmlat', & - long_name=long_name, units=units) - end if - - end subroutine ncd_def_spatial_var_0lev - - !----------------------------------------------------------------------- - subroutine ncd_def_spatial_var_1lev(ncid, varname, xtype, lev1name, long_name, units) - ! - ! !DESCRIPTION: - ! Define a spatial netCDF variable (convenience wrapper to ncd_defvar) - ! - ! The variable in question has one level (or time) dimension in addition to its - ! spatial dimensions - ! - ! !USES: - use mkvarctl, only : outnc_1d - ! - ! !ARGUMENTS: - integer , intent(in) :: ncid ! input unit - character(len=*) , intent(in) :: varname ! variable name - integer , intent(in) :: xtype ! external type - character(len=*) , intent(in) :: lev1name ! name of level (or time) dimension - character(len=*) , intent(in) :: long_name ! attribute - character(len=*) , intent(in) :: units ! attribute - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'ncd_def_spatial_var_1lev' - !----------------------------------------------------------------------- - - if (outnc_1d) then - call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & - dim1name='gridcell', dim2name=lev1name, & - long_name=long_name, units=units) - else - call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & - dim1name='lsmlon', dim2name='lsmlat',dim3name=lev1name, & - long_name=long_name, units=units) - end if - - end subroutine ncd_def_spatial_var_1lev - - !----------------------------------------------------------------------- - subroutine ncd_def_spatial_var_2lev(ncid, varname, xtype, lev1name, lev2name, long_name, units) - ! - ! !DESCRIPTION: - ! Define a spatial netCDF variable (convenience wrapper to ncd_defvar) - ! - ! The variable in question has two level (or time) dimensions in addition to its - ! spatial dimensions - ! - ! !USES: - use mkvarctl, only : outnc_1d - ! - ! !ARGUMENTS: - integer , intent(in) :: ncid ! input unit - character(len=*) , intent(in) :: varname ! variable name - integer , intent(in) :: xtype ! external type - character(len=*) , intent(in) :: lev1name ! name of first level (or time) dimension - character(len=*) , intent(in) :: lev2name ! name of second level (or time) dimension - character(len=*) , intent(in) :: long_name ! attribute - character(len=*) , intent(in) :: units ! attribute - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'ncd_def_spatial_var_2lev' - !----------------------------------------------------------------------- - - if (outnc_1d) then - call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & - dim1name='gridcell', dim2name=lev1name, dim3name=lev2name, & - long_name=long_name, units=units) - else - call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & - dim1name='lsmlon', dim2name='lsmlat', dim3name=lev1name, dim4name=lev2name, & - long_name=long_name, units=units) - end if - - end subroutine ncd_def_spatial_var_2lev - - ! ======================================================================== - ! ncd_put_time_slice routines: write a single time slice of a variable - ! ======================================================================== - - !----------------------------------------------------------------------- - subroutine ncd_put_time_slice_1d(ncid, varid, time_index, data) - ! - ! !DESCRIPTION: - ! Write a single time slice of a 1-d variable - ! - ! !USES: - ! - ! !ARGUMENTS: - integer , intent(in) :: ncid ! netCDF id - integer , intent(in) :: varid ! variable id - integer , intent(in) :: time_index ! time index in file - real(r8), intent(in) :: data(:) ! data to write (a single time slice) - ! - ! !LOCAL VARIABLES: - integer, allocatable :: beg(:) ! begin indices for each dimension - integer, allocatable :: len(:) ! length along each dimension - - character(len=*), parameter :: subname = 'ncd_put_time_slice_1d' - !----------------------------------------------------------------------- - - call get_time_slice_beg_and_len(ncid, varid, time_index, beg, len) - call check_ret(nf_put_vara_double(ncid, varid, beg, len, data), subname) - - deallocate(beg, len) - - end subroutine ncd_put_time_slice_1d - - !----------------------------------------------------------------------- - subroutine ncd_put_time_slice_2d(ncid, varid, time_index, data) - ! - ! !DESCRIPTION: - ! Write a single time slice of a 2-d variable - ! - ! !USES: - ! - ! !ARGUMENTS: - integer , intent(in) :: ncid ! netCDF id - integer , intent(in) :: varid ! variable id - integer , intent(in) :: time_index ! time index in file - real(r8), intent(in) :: data(:,:) ! data to write (a single time slice) - ! - ! !LOCAL VARIABLES: - integer, allocatable :: beg(:) ! begin indices for each dimension - integer, allocatable :: len(:) ! length along each dimension - - character(len=*), parameter :: subname = 'ncd_put_time_slice_2d' - !----------------------------------------------------------------------- - - call get_time_slice_beg_and_len(ncid, varid, time_index, beg, len) - call check_ret(nf_put_vara_double(ncid, varid, beg, len, data), subname) - - deallocate(beg, len) - - end subroutine ncd_put_time_slice_2d - - - !----------------------------------------------------------------------- - subroutine get_time_slice_beg_and_len(ncid, varid, time_index, beg, len) - ! - ! !DESCRIPTION: - ! Determine beg and len vectors for writing a time slice. - ! - ! Assumes time is the last dimension of the given variable. - ! - ! Allocates memory for beg & len. - ! - ! !USES: - ! - ! !ARGUMENTS: - integer , intent(in) :: ncid ! netcdf ID - integer , intent(in) :: varid ! variable ID - integer , intent(in) :: time_index ! time index in file - integer, allocatable, intent(out) :: beg(:) ! begin indices for each dimension - integer, allocatable, intent(out) :: len(:) ! length along each dimension - ! - ! !LOCAL VARIABLES: - integer :: n ! index - integer :: ndims ! number of dimensions - integer, allocatable :: dimids(:) ! dimension IDs - - character(len=*), parameter :: subname = 'get_time_slice_beg_and_len' - !----------------------------------------------------------------------- - - call check_ret(nf_inq_varndims(ncid, varid, ndims), subname) - allocate(beg(ndims)) - allocate(len(ndims)) - allocate(dimids(ndims)) - - call check_ret(nf_inq_vardimid(ncid, varid, dimids), subname) - beg(1:ndims-1) = 1 - do n = 1,ndims-1 - call check_ret(nf_inq_dimlen(ncid, dimids(n), len(n)), subname) - end do - len(ndims) = 1 - beg(ndims) = time_index - - deallocate(dimids) - - end subroutine get_time_slice_beg_and_len - - - - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: get_dim_lengths -! -! !INTERFACE: -subroutine get_dim_lengths(ncid, varname, ndims, dim_lengths) -! -! !DESCRIPTION: -! Returns the number of dimensions and an array containing the dimension lengths of a -! variable in an open netcdf file. -! -! Entries 1:ndims in the returned dim_lengths array contain the dimension lengths; the -! remaining entries in that vector are meaningless. The dim_lengths array must be large -! enough to hold all ndims values; if not, the code aborts (this can be ensured by passing -! in an array of length nf_max_var_dims). -! -! !USES: -! -! !ARGUMENTS: - implicit none - integer , intent(in) :: ncid ! netcdf id of an open netcdf file - character(len=*), intent(in) :: varname ! name of variable of interest - integer , intent(out):: ndims ! number of dimensions of variable - integer , intent(out):: dim_lengths(:) ! lengths of dimensions of variable -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: - integer :: varid - integer :: dimids(size(dim_lengths)) - integer :: i - character(len=*), parameter :: subname = 'get_dim_lengths' -!EOP -!------------------------------------------------------------------------------ - call check_ret(nf_inq_varid(ncid, varname, varid), subname) - call check_ret(nf_inq_varndims(ncid, varid, ndims), subname) - - if (ndims > size(dim_lengths)) then - write(6,*) trim(subname), ' ERROR: dim_lengths too small' - call abort() - end if - - call check_ret(nf_inq_vardimid(ncid, varid, dimids), subname) - - dim_lengths(:) = 0 ! pre-fill with 0 so we won't have garbage in elements past ndims - do i = 1, ndims - call check_ret(nf_inq_dimlen(ncid, dimids(i), dim_lengths(i)), subname) - end do - end subroutine get_dim_lengths - -!---------------------------------------------------------------------------- -!BOP -! -! !IROUTINE: convert_latlon -! -! !INTERFACE: - subroutine convert_latlon(ncid, varname, data) -! -! !DESCRIPTION: -! Convert a latitude or longitude variable from its units in the input file to degrees E / -! degrees N. Currently, this just handles conversions from radians to degrees. -! -! Assumes that the longitude / latitude variable has already been read from file, into -! the variable given by 'data'. ncid & varname give the file ID and variable name from -! which this variable was read (needed to obtain the variable's units). -! -! !USES: - use shr_const_mod, only : SHR_CONST_PI -! -! !ARGUMENTS: - implicit none - integer , intent(in) :: ncid ! ID of open netcdf file - character(len=*), intent(in) :: varname ! name of lat or lon variable that was read into 'data' - real(r8) , intent(inout):: data(:) ! latitude or longitude data -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - integer :: ier ! error return code - integer :: varid ! netCDF variable id - integer :: units_len ! length of units attribute on file - character(len=256) :: units ! units attribute - character(len= 32) :: subname = 'convert_latlon' -!----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, varname, varid), subname) - ier = nf_inq_attlen(ncid, varid, 'units', units_len) - - ! Only do the following processing if there is no error; if ier /= NF_NOERR, that - ! probably means there isn't a units attribute -- in that case, assume units are - ! degrees and need no conversion - if (ier == NF_NOERR) then - if (units_len > len(units)) then - write(6,*) trim(subname), ' ERROR: units variable not long enough to hold attributue' - call abort() - end if - - call check_ret(nf_get_att_text(ncid, varid, 'units', units), subname) - - if (units(1:7) == 'radians') then - ! convert from radians to degrees - data(:) = data(:) * 180._r8 / SHR_CONST_PI - end if - end if - - end subroutine convert_latlon -!------------------------------------------------------------------------------ - - -end module mkncdio From b7fd811dad877d692a716cb6598dd5dc178810fe Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 23 Jan 2022 21:08:41 -0700 Subject: [PATCH 026/614] updates for bug fixes --- .../mksurfdata_esmf/src/mkdiagnosticsMod.F90 | 63 +++-- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 61 +++-- tools/mksurfdata_esmf/src/mkorganicMod.F90 | 46 +--- tools/mksurfdata_esmf/src/mkpioMod.F90 | 216 ++++++++++++++---- tools/mksurfdata_esmf/src/mksurfdata | Bin 4175456 -> 4224448 bytes tools/mksurfdata_esmf/src/mksurfdata.F90 | 4 +- 6 files changed, 245 insertions(+), 145 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 index 4aab56e792..c4f9fa4b80 100644 --- a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 @@ -9,7 +9,6 @@ module mkdiagnosticsMod implicit none private - ! !PUBLIC MEMBER FUNCTIONS: public :: output_diagnostics_area ! output diagnostics for field that is % of grid area public :: output_diagnostics_continuous ! output diagnostics for a continuous (real-valued) field public :: output_diagnostics_continuous_outonly ! output diagnostics for a continuous (real-valued) field @@ -20,23 +19,19 @@ module mkdiagnosticsMod contains !------------------------------------------------------------------------------ - subroutine output_diagnostics_area(data_i, data_o, gridmap, name, percent, ndiag, mask_src, frac_dst) + subroutine output_diagnostics_area(data_i, data_o, name, percent, ndiag, mask_src) ! Output diagnostics for a field that gives either fraction or percent of grid cell area - use mkgridmapMod, only : gridmap_type use mkvarpar, only : re - ! !ARGUMENTS: - implicit none - real(r8) , intent(in) :: data_i(:) ! data on input grid - real(r8) , intent(in) :: data_o(:) ! data on output grid - type(gridmap_type), intent(in) :: gridmap ! mapping info - character(len=*) , intent(in) :: name ! name of field - logical , intent(in) :: percent ! is field specified as percent? (alternative is fraction) - integer , intent(in) :: ndiag ! unit number for diagnostic output - integer, intent(in) :: mask_src(:) - real(r8), intent(in) :: frac_dst(:) + ! input/output variables + real(r8) , intent(in) :: data_i(:) ! data on input grid + real(r8) , intent(in) :: data_o(:) ! data on output grid + character(len=*) , intent(in) :: name ! name of field + logical , intent(in) :: percent ! is field specified as percent? (alternative is fraction) + integer , intent(in) :: ndiag ! unit number for diagnostic output + integer , intent(in) :: mask_src(:) ! !LOCAL VARIABLES: real(r8) :: gdata_i ! global sum of input data @@ -45,22 +40,17 @@ subroutine output_diagnostics_area(data_i, data_o, gridmap, name, percent, ndiag real(r8) :: garea_o ! global sum of output area integer :: ns_i, ns_o ! sizes of input & output grids integer :: ni,no,k ! indices + real(r8), allocatable :: area_src(:) + real(r8), allocatable :: area_dst(:) + integer , allocatable :: mask_src(:) + integer , allocatable :: mask_dst(:) character(len=*), parameter :: subname = "output_diagnostics_area" !------------------------------------------------------------------------------ ! Error check for array size consistencies - ns_i = gridmap%na - ns_o = gridmap%nb - if (size(data_i) /= ns_i .or. & - size(data_o) /= ns_o) then - write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) - write(6,*) 'size(data_i) = ', size(data_i) - write(6,*) 'ns_i = ', ns_i - write(6,*) 'size(data_o) = ', size(data_o) - write(6,*) 'ns_o = ', ns_o - call abort() - end if + ns_i = size(data_i) + ns_o = size(data_o) if (size(frac_dst) /= ns_o) then write(6,*) subname//' ERROR: incorrect size of frac_dst' write(6,*) 'size(frac_dst) = ', size(frac_dst) @@ -75,32 +65,34 @@ subroutine output_diagnostics_area(data_i, data_o, gridmap, name, percent, ndiag end if ! Sums on input grid - + ! TODO: get area_src and mask_src from input mesh + allocate(area_src(ns_i)) + allocate(mask_src(ns_i)) gdata_i = 0. garea_i = 0. do ni = 1,ns_i - garea_i = garea_i + gridmap%area_src(ni)*re**2 - gdata_i = gdata_i + data_i(ni) * gridmap%area_src(ni) * mask_src(ni) * re**2 + garea_i = garea_i + area_src(ni)*re**2 + gdata_i = gdata_i + data_i(ni) * area_src(ni) * mask_src(ni) * re**2 end do ! Sums on output grid - + ! TODO: get area_src and mask_src from output mesh + allocate(area_dst(ns_i)) + allocate(mask_dst(ns_i)) gdata_o = 0. garea_o = 0. do no = 1,ns_o - garea_o = garea_o + gridmap%area_dst(no)*re**2 - gdata_o = gdata_o + data_o(no) * gridmap%area_dst(no) * frac_dst(no) * re**2 + garea_o = garea_o + area_dst(no)*re**2 + gdata_o = gdata_o + data_o(no) * area_dst(no) * re**2 end do ! Correct units - if (percent) then gdata_i = gdata_i / 100._r8 gdata_o = gdata_o / 100._r8 end if ! Diagnostic output - write (ndiag,*) write (ndiag,'(1x,70a1)') ('=',k=1,70) write (ndiag,*) trim(name), ' Output' @@ -219,11 +211,10 @@ end subroutine output_diagnostics_continuous !------------------------------------------------------------------------------ subroutine output_diagnostics_continuous_outonly(data_o, gridmap, name, units, ndiag) ! - ! !DESCRIPTION: ! Output diagnostics for a continuous field, just on the output grid ! This is used when the average of the field on the input grid is not of interest (e.g., ! when the output quantity is the standard deviation of the input field) - + ! use mkgridmapMod, only : gridmap_type use mkvarpar, only : re @@ -289,14 +280,12 @@ end subroutine output_diagnostics_continuous_outonly subroutine output_diagnostics_index(data_i, data_o, gridmap, name, & minval, maxval, ndiag, mask_src, frac_dst) ! - ! !DESCRIPTION: ! Output diagnostics for an index field: area of each index in input and output ! - ! !USES: use mkvarpar, only : re use mkgridmapMod, only : gridmap_type ! - ! !ARGUMENTS: + ! input/output variables integer , intent(in) :: data_i(:) ! data on input grid integer , intent(in) :: data_o(:) ! data on output grid type(gridmap_type) , intent(in) :: gridmap ! mapping info diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index b455a1ee00..633d049f7e 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -10,7 +10,7 @@ module mklanwatMod use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 use shr_sys_mod , only : shr_sys_abort use mkvarpar , only : re - use mkpioMod , only : mkpio_get_rawdata + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem use mkesmfMod , only : regrid_rawdata use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag @@ -55,16 +55,18 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & type(ESMF_Mesh) :: mesh_i type(ESMF_Field) :: field_i type(ESMF_Field) :: field_o + type(file_desc_t) :: pioid real(r8), allocatable :: lake_i(:) ! input grid: percent lake - real(r8), allocatable :: swmp_i(:) ! input grid: percent lake - real(r8), allocatable :: lakedepth_i(:) - integer :: ni,no,ns_i,ns_o,k ! indices + real(r8), allocatable :: swmp_i(:) ! input grid: percent wetland + real(r8), allocatable :: lakedepth_i(:) ! iput grid: lake depth + integer :: ni,no,k ! indices + integer :: ns_i,ns_o ! local sizes integer :: rcode ! error status - integer :: srcMaskValue = 0 + integer :: srcMaskValue = -987987 ! spval for RH mask values integer :: dstMaskValue = -987987 ! spval for RH mask values integer :: srcTermProcessing_Value = 0 real(r8), parameter :: min_valid_lakedepth = 0._r8 - character(len=32) :: subname = 'mklakwat' + character(len=*), parameter :: subname = ' mklakwat ' !----------------------------------------------------------------------- rc = ESMF_SUCCESS @@ -85,24 +87,32 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & ! ---------------------------------------- ! create field on input mesh (first read in input mesh) - call ESMF_VMLogMemInfo("Before create mesh_i in lanwat") + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create mesh_i in lanwat") + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) ! create route handle to map field_model to field_data - call ESMF_VMLogMemInfo("Before regridstore in regrid_data") + call ESMF_VMLogMemInfo("Before regridstore in "//trim(subname)) call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_DSTAREA, & srcTermProcessing=srcTermProcessing_Value, & ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regridstore in regrid_data") + call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) + + ! ---------------------------------------- + ! Open input data file + ! ---------------------------------------- + ! ASSUME for now that have only 1 input data file + call ESMF_VMLogMemInfo("Before pio_openfile in "//trim(subname)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile in "//trim(subname)) ! ---------------------------------------- ! Create %lake @@ -114,17 +124,17 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & write (ndiag,*) 'Attempting to make %lake .....' end if - ! read in rawdata + ! Read in the input data allocate(lake_i(ns_i), stat=rcode) if (rcode/=0) call shr_sys_abort() - call mkpio_get_rawdata(trim(file_data_i), 'PCT_LAKE', mesh_i, lake_i, rc) + call mkpio_get_rawdata(pioid, 'PCT_LAKE', mesh_i, lake_i, scale_by_landmask=.true., rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! regrid lake_i to lake_o - this also returns lake_i to be used in the global sums below - call ESMF_VMLogMemInfo("Before regrid_data in lanwat") + ! Regrid lake_i to lake_o - this also returns lake_i to be used in the global sums below + call ESMF_VMLogMemInfo("Before regrid_rawdata for PCT_LAKE") call regrid_rawdata(field_i, field_o, routehandle, lake_i, lake_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regrid_data in lanwat") + call ESMF_VMLogMemInfo("Before regrid_rawdata for PCT_LAKE") do no = 1,size(lake_o) if (lake_o(no) < 1.) lake_o(no) = 0. enddo @@ -149,7 +159,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & ! read in rawdata allocate(swmp_i(ns_i), stat=rcode) if (rcode/=0) call shr_sys_abort() - call mkpio_get_rawdata(trim(file_data_i), 'PCT_WETLAND', mesh_i, swmp_i, rc) + call mkpio_get_rawdata(pioid, 'PCT_WETLAND', mesh_i, lake_i, scale_by_landmask=.true., rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! regrid swmp_i to swmp_o - this also returns swmp_i to be used in the global sums below @@ -180,8 +190,8 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & ! read in rawdata allocate(lakedepth_i(ns_i), stat=rcode) if (rcode/=0) call shr_sys_abort() - call mkpio_get_rawdata(trim(file_data_i), 'LAKEDEPTH', mesh_i, lakedepth_i, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call mkpio_get_rawdata(pioid, 'LAKEDEPTH', mesh_i, lakedepth_i, scale_by_landmask=.true., rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! regrid lakedepth_i to lakedepth_o - this also returns lakedepth_i to be used in the global sums below call ESMF_VMLogMemInfo("Before regrid_data for lakedepth") @@ -198,15 +208,13 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & #ifdef TODO call output_diagnostics_continuous(data_i, lakedepth_o, tgridmap, "Lake Depth", "m", ndiag, tdomain%mask, frac_dst) #endif - deallocate (lakedepth_i) - if (root_task) then - write (ndiag,*) 'Successfully made lake parameters' - write (ndiag,*) - end if + ! ---------------------------------------- + ! Close the single input data file and release memory + ! ---------------------------------------- - ! Release memory for route handle + call pio_closefile(pioid) call ESMF_VMLogMemInfo("Before destroy operation for lanwat ") call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) @@ -215,6 +223,11 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_VMLogMemInfo("After destroy operation for lanwat ") + if (root_task) then + write (ndiag,*) 'Successfully made lake parameters' + write (ndiag,*) + end if + end subroutine mklakwat end module mklanwatMod diff --git a/tools/mksurfdata_esmf/src/mkorganicMod.F90 b/tools/mksurfdata_esmf/src/mkorganicMod.F90 index 7a03a31690..cf7d3df7ab 100644 --- a/tools/mksurfdata_esmf/src/mkorganicMod.F90 +++ b/tools/mksurfdata_esmf/src/mkorganicMod.F90 @@ -40,9 +40,6 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) type(ESMF_Field) :: field_i type(ESMF_Field) :: field_o type(file_desc_t) :: pioid - type(var_desc_t) :: pio_varid - type(io_desc_t) :: pio_iodesc - integer :: pio_vartype integer :: ni,no integer :: ns_i, ns_o integer :: nlay @@ -94,53 +91,25 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Create io descriptor for input raw data - ! This will query the raw data file for the dimensions of the variable varname and - ! create iodesc for either single or multi level input data - call ESMF_VMLogMemInfo("Before mkpio_iodesc in "//trim(subname)) - call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After mkpio_iodesc in "//trim(subname)) - ! Determine ns_i and allocate data_i call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - allocate(data_i(nlay,ns_i),stat=ier) - if (ier/=0) call shr_sys_abort() ! Determine ns_o and allocate data_o ns_o = size(organic_o, dim=1) allocate(data_o(nlay,ns_o),stat=ier) if (ier/=0) call shr_sys_abort() - ! Read the input raw data (all levels read at once) + ! Read in input data ! - levels are the innermost dimension for esmf fields ! - levels are the outermost dimension in pio reads ! Input data is read into (ns_i,nlay) array and then transferred to data_i(nlay,ns_i) - if (pio_vartype == PIO_REAL) then - write(6,*)'DEBUG: ns_i, nlay = ',ns_i, nlay - allocate(data_real(ns_i,nlay)) - call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real, rcode) - do l = 1,nlay - do n = 1,ns_i - data_i(l,n) = real(data_real(n,l), kind=r8) - end do - end do - deallocate(data_real) - else if (pio_vartype == PIO_DOUBLE) then - allocate(data_double(ns_i,nlay)) - call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double, rcode) - do l = 1,nlay - do n = 1,ns_i - data_i(l,n) = data_double(n,l) - end do - end do - deallocate(data_double) - else - call shr_sys_abort(subName//"ERROR: only real and double types are supported") - end if - call ESMF_VMLogMemInfo("After read_darray in "//trim(subname)) + allocate(data_i(nlay,ns_i),stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, varname, mesh_i, data_i, scale_by_landmask=.true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) ! Create field on input mesh - using dimension information from raw data file field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & @@ -168,9 +137,8 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regrid_data in "//trim(subname)) - ! Close the file and free the iodesc and deallocate memory + ! Close the file call pio_closefile(pioid) - call pio_freedecomp(pio_iosystem, pio_iodesc) call ESMF_VMLogMemInfo("After pio_freedecomp in "//trim(subname)) ! Now compute organic_o - need to remember that nlay is innermost dimension in data_o diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 10c44f086f..29b60668ee 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -23,6 +23,11 @@ module mkpioMod private :: mkpio_defvar + interface mkpio_get_rawdata + module procedure mkpio_get_rawdata1d + module procedure mkpio_get_rawdata2d + end interface mkpio_get_rawdata + interface mkpio_def_spatial_var module procedure mkpio_def_spatial_var_0lev module procedure mkpio_def_spatial_var_1lev @@ -45,58 +50,183 @@ module mkpioMod contains !=============================================================== - subroutine mkpio_get_rawdata(filename, varname, mesh_i, data_i, rc) + subroutine mkpio_get_rawdata1d(pioid, varname, mesh_i, data_i, scale_by_landmask, rc) ! input/output variables - character(len=*) , intent(in) :: filename ! file name of rawdata file - character(len=*) , intent(in) :: varname ! field name in rawdata file - type(ESMF_Mesh) , intent(in) :: mesh_i - real(r8) , intent(inout) :: data_i(:) ! input raw data - integer , intent(out) :: rc + type(file_desc_t), intent(inout) :: pioid + character(len=*) , intent(in) :: varname ! field name in rawdata file + type(ESMF_Mesh) , intent(in) :: mesh_i + real(r8) , intent(inout) :: data_i(:) ! input raw data + logical , intent(in) :: scale_by_landmask + integer , intent(out) :: rc ! local variables - type(file_desc_t) :: pioid type(var_desc_t) :: pio_varid - type(io_desc_t) :: pio_iodesc integer :: pio_vartype + type(io_desc_t) :: pio_iodesc_data + type(io_desc_t) :: pio_iodesc_mask real(r4), allocatable :: data_real(:) real(r8), allocatable :: data_double(:) - real(r8), pointer :: dataptr(:) - integer :: lsize + real(r4), allocatable :: landmask(:) + integer :: lsize integer :: rcode - character(len=*), parameter :: subname = 'mklakwat' + integer :: n + character(len=*), parameter :: subname = 'mkpio_get_rawdata1d' !------------------------------------------------- rc = ESMF_SUCCESS - ! Get data_i - Read in varname from filename + ! Get data_i - Read in varname from filename lsize = size(data_i) - call ESMF_VMLogMemInfo("Before pio_openfile in regrid_data for "//trim(filename)) - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(filename), pio_nowrite) - call ESMF_VMLogMemInfo("After pio_openfile in regrid_data") - call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) + ! Create io descriptor for input raw data + ! This will query the raw data file for the dimensions of the variable varname and + ! create iodesc for either single or multi level input data + call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc_data, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After mkpio_iodesc in regrid_data") + ! Read the input raw data + call ESMF_VMLogMemInfo("After mkpio_iodesc_data for varname "//trim(varname)) if (pio_vartype == PIO_REAL) then allocate(data_real(lsize)) - call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real, rcode) + call ESMF_VMLogMemInfo("Calling pio_read_darray for varname "//trim(varname)) + call pio_read_darray(pioid, pio_varid, pio_iodesc_data, data_real, rcode) + call ESMF_VMLogMemInfo("Finished pio_read_darray for varname "//trim(varname)) data_i(:) = real(data_real(:), kind=r8) + call ESMF_LogWrite("Finished transfer to data_i for varname "//trim(varname)) deallocate(data_real) + call ESMF_LogWrite("Finished deallocate of data_real for varname "//trim(varname)) else if (pio_vartype == PIO_DOUBLE) then allocate(data_double(lsize)) - call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double, rcode) + call pio_read_darray(pioid, pio_varid, pio_iodesc_data, data_double, rcode) data_i(:) = data_double(:) deallocate(data_double) else call shr_sys_abort(subName//"ERROR: only real and double types are supported") end if - call pio_closefile(pioid) - call pio_freedecomp(pio_iosystem, pio_iodesc) - call ESMF_VMLogMemInfo("After pio_read_darry in regrid_data") + call ESMF_VMLogMemInfo("After call to pio_read_darrayy for varname "//trim(varname)) + call pio_freedecomp(pioid, pio_iodesc_data) + call ESMF_VMLogMemInfo("After call to pio_freedecomp for "//trim(varname)) + + ! Read in the variable LANDMASK and scale the input data by landmask if appropriate + ! if (scale_by_landmask) then + ! call mkpio_iodesc_rawdata(mesh_i, 'LANDMASK', pioid, pio_varid, pio_vartype, pio_iodesc_mask, rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return + ! allocate(landmask(lsize)) + ! call pio_read_darray(pioid, pio_varid, pio_iodesc_mask, landmask, rcode) + ! do n = 1,lsize + ! data_i(n) = data_i(n)*landmask(n) + ! end do + ! deallocate(landmask) + ! call pio_freedecomp(pioid, pio_iodesc_mask) + ! end if + + call ESMF_VMLogMemInfo("At end of "//trim(subname)) + + end subroutine mkpio_get_rawdata1d + + !=============================================================== + subroutine mkpio_get_rawdata2d(pioid, varname, mesh_i, data_i, scale_by_landmask, rc) + + ! input/output variables + type(file_desc_t) , intent(inout) :: pioid + character(len=*) , intent(in) :: varname ! field name in rawdata file + type(ESMF_Mesh) , intent(in) :: mesh_i + real(r8) , intent(inout) :: data_i(:,:) ! input raw data + logical, optional , intent(in) :: scale_by_landmask + integer , intent(out) :: rc + + ! local variables + type(var_desc_t) :: pio_varid + integer :: pio_vartype + type(io_desc_t) :: pio_iodesc_data + type(io_desc_t) :: pio_iodesc_mask + real(r4), allocatable :: data_real1d(:) + real(r4), allocatable :: data_real2d(:,:) + real(r8), allocatable :: data_double1d(:) + real(r8), allocatable :: data_double2d(:,:) + real(r4), allocatable :: landmask(:) + integer :: lsize, nlev + integer :: n,l + integer :: rcode + character(len=*), parameter :: subname = ' mkpio_get_rawdata_2d' + !------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Get data_i - Read in varname from filename + ! Note that data_i is coming in as (nlev,lsize) in terms of dimensions + nlev = size(data_i, dim=1) + lsize = size(data_i, dim=2) + + ! Create io descriptor for input raw data + ! This will query the raw data file for the dimensions of the variable varname and + ! create iodesc for either single or multi level input data + call ESMF_VMLogMemInfo("Before mkpio_iodesc in "//trim(subname)) + call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc_data, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_iodesc in "//trim(subname)) + + ! Read the input raw data (all levels read at once) + ! - levels are the innermost dimension for esmf fields + ! - levels are the outermost dimension in pio reads + ! Input data is read into (lsize,nlev) array and then transferred to data_i(nlev,lsize) + if (pio_vartype == PIO_REAL) then + allocate(data_real2d(lsize,nlev)) + call pio_read_darray(pioid, pio_varid, pio_iodesc_data, data_real2d, rcode) + do l = 1,nlev + do n = 1,lsize + data_i(l,n) = real(data_real2d(n,l), kind=r8) + end do + end do + deallocate(data_real2d) + else if (pio_vartype == PIO_DOUBLE) then + allocate(data_double2d(lsize,nlev)) + call pio_read_darray(pioid, pio_varid, pio_iodesc_data, data_double2d, rcode) + do l = 1,nlev + do n = 1,lsize + data_i(l,n) = data_double2d(n,l) + end do + end do + deallocate(data_double2d) + else + call shr_sys_abort(subName//"ERROR: only real and double types are supported") + end if + call pio_freedecomp(pioid, pio_iodesc_data) + + ! Read in the variable LANDMASK and scale the input data by landmask if appropriate + if (scale_by_landmask) then + call mkpio_iodesc_rawdata(mesh_i, 'LANDMASK', pioid, pio_varid, pio_vartype, pio_iodesc_mask, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_LogWrite("Reading ing LANDMASK", ESMF_LOGMSG_INFO) + allocate(landmask(lsize)) + if (pio_vartype == PIO_REAL) then + allocate(data_real1d(lsize)) + call pio_read_darray(pioid, pio_varid, pio_iodesc_mask, data_real1d, rcode) + do n = 1,lsize + landmask(n) = data_real1d(n) + end do + deallocate(data_real1d) + else if (pio_vartype == PIO_DOUBLE) then + allocate(data_double1d(lsize)) + call pio_read_darray(pioid, pio_varid, pio_iodesc_mask, data_double1d, rcode) + do n = 1,lsize + landmask(n) = real(data_double1d(n), kind=r4) + end do + deallocate(data_double1d) + end if + do l = 1,nlev + do n = 1,lsize + data_i(l,n) = data_i(l,n) * landmask(n) + end do + end do + call ESMF_LogWrite("Finished read in LANDMASK", ESMF_LOGMSG_INFO) + deallocate(landmask) + call pio_freedecomp(pioid, pio_iodesc_mask) + end if - end subroutine mkpio_get_rawdata + end subroutine mkpio_get_rawdata2d !=============================================================== subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, pio_iodesc, rc) @@ -109,7 +239,7 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, type(file_desc_t) , intent(inout) :: pioid type(var_desc_t) , intent(out) :: pio_varid integer , intent(out) :: pio_vartype - type(io_desc_t) , intent(inout) :: pio_iodesc + type(io_desc_t) , intent(inout) :: pio_iodesc integer , intent(out) :: rc ! local variables @@ -130,7 +260,7 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, rc = ESMF_SUCCESS - call ESMF_VMLogMemInfo("Beginning setting compdof") + call ESMF_VMLogMemInfo("Beginning setting compdof for "//trim(varname)) call ESMF_MeshGet(mesh, elementdistGrid=distGrid, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_DistGridGet(distGrid, localDe=0, elementCount=lsize, rc=rc) @@ -138,17 +268,17 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, allocate(compdof(lsize)) call ESMF_DistGridGet(distGrid, localDe=0, seqIndexList=compdof, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("Ending setting compdof") + call ESMF_VMLogMemInfo("Ending setting compdof for "//trim(varname)) ! get pio variable id, type and number of dimensions - call ESMF_VMLogMemInfo("Beginning getting variable id") + call ESMF_VMLogMemInfo("Beginning getting variable id for "//trim(varname)) rcode = pio_inq_varid(pioid, trim(varname), pio_varid) rcode = pio_inq_vartype(pioid, pio_varid, pio_vartype) rcode = pio_inq_varndims(pioid, pio_varid, ndims) - call ESMF_VMLogMemInfo("Ending getting variable id") + call ESMF_VMLogMemInfo("Ending getting variable id" //trim(varname)) ! get variable dimension sizes - call ESMF_VMLogMemInfo("Beginning getting dims") + call ESMF_VMLogMemInfo("Beginning getting dims for" //trim(varname)) allocate(dimids(ndims)) allocate(dimlens(ndims)) rcode = pio_inq_vardimid(pioid, pio_varid, dimids(1:ndims)) @@ -156,12 +286,11 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, rcode = pio_inq_dimlen(pioid, dimids(n), dimlens(n)) end do rcode = pio_inq_dimname(pioid, dimids(ndims), dimname) - call ESMF_VMLogMemInfo("End getting dims") + call ESMF_VMLogMemInfo("End getting dims for "//trim(varname)) ! Create compdof3d if needed ! Assume that input data is always lon,lat as first two dimensions nlev = 0 - offset = dimlens(1)*dimlens(2) if (ndims == 3 .and. trim(dimname) /= 'time') then nlev = dimlens(3) else if (ndims == 3 .and. trim(dimname) == 'time') then @@ -173,6 +302,7 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, end if if (nlev > 0) then + offset = dimlens(1)*dimlens(2) allocate(compdof3d(nlev*lsize)) cnt = 0 do n = 1,nlev @@ -219,8 +349,10 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, end if ! deallocate memory - deallocate(compdof) - if (allocated(compdof3d)) deallocate(compdof3d) + ! deallocate(compdof) + ! if (allocated(compdof3d)) deallocate(compdof3d) + + call ESMF_VMLogMemInfo("Finished setting iodesc for "//trim(varname)) end subroutine mkpio_iodesc_rawdata @@ -233,7 +365,7 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) type(file_desc_t) , intent(inout) :: pioid character(len=*) , intent(in) :: varname type(ESMF_Mesh) , intent(in) :: mesh - type(io_desc_t) , intent(inout) :: pio_iodesc + type(io_desc_t) , intent(inout) :: pio_iodesc integer , intent(out) :: rc ! local variables @@ -357,7 +489,7 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) ! deallocate memory deallocate(compdof) - if (allocated(compdof3d)) deallocate(compdof3d) + if (allocated(compdof3d)) deallocate(compdof3d) end subroutine mkpio_iodesc_output @@ -569,7 +701,7 @@ subroutine mkpio_defvar(pioid, varname, xtype, & end subroutine mkpio_defvar ! ======================================================================== - ! mkpio_def_spatial_var routines: define a spatial pio variable + ! mkpio_def_spatial_var routines: define a spatial pio variable ! (convenience wrapper to mkpio_defvar) ! ======================================================================== @@ -602,13 +734,11 @@ end subroutine mkpio_def_spatial_var_0lev !----------------------------------------------------------------------- subroutine mkpio_def_spatial_var_1lev(pioid, varname, xtype, lev1name, long_name, units) ! - ! !DESCRIPTION: ! Define a spatial netCDF variable (convenience wrapper to mkpio_defvar) - ! ! The variable in question has one level (or time) dimension in addition to its ! spatial dimensions - ! !ARGUMENTS: + ! input/output variables type(file_desc_t) , intent(in) :: pioid character(len=*) , intent(in) :: varname ! variable name integer , intent(in) :: xtype ! external type @@ -616,7 +746,7 @@ subroutine mkpio_def_spatial_var_1lev(pioid, varname, xtype, lev1name, long_name character(len=*) , intent(in) :: long_name ! attribute character(len=*) , intent(in) :: units ! attribute - ! !LOCAL VARIABLES: + ! local variables character(len=*), parameter :: subname = 'mkpio_def_spatial_var_1lev' !----------------------------------------------------------------------- @@ -673,7 +803,7 @@ subroutine mkpio_put_time_slice_1d(pioid, pio_varid, pio_iodesc, time_index, dat ! input/output variables type(file_desc_t) , intent(inout) :: pioid type(var_desc_t) , intent(inout) :: pio_varid - type(io_desc_t) , intent(inout) :: pio_iodesc + type(io_desc_t) , intent(inout) :: pio_iodesc integer , intent(in) :: time_index ! time index in file real(r8) , intent(in) :: data(:) ! data to write (a single time slice) ! @@ -684,7 +814,7 @@ subroutine mkpio_put_time_slice_1d(pioid, pio_varid, pio_iodesc, time_index, dat call pio_setframe(pioid, pio_varid, int(time_index, kind=Pio_Offset_Kind)) call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) - + end subroutine mkpio_put_time_slice_1d !----------------------------------------------------------------------- @@ -695,7 +825,7 @@ subroutine mkpio_put_time_slice_2d(pioid, pio_varid, pio_iodesc, time_index, dat ! input/output variables type(file_desc_t) , intent(inout) :: pioid type(var_desc_t) , intent(inout) :: pio_varid - type(io_desc_t) , intent(inout) :: pio_iodesc + type(io_desc_t) , intent(inout) :: pio_iodesc integer , intent(in) :: time_index ! time index in file real(r8) , intent(in) :: data(:,:) ! data to write (a single time slice) ! diff --git a/tools/mksurfdata_esmf/src/mksurfdata b/tools/mksurfdata_esmf/src/mksurfdata index d789397af5e49e864b0424f0135c52d069aefdb7..5a8e95c7a7594bfa05cc997267e1ecd06e78d45c 100755 GIT binary patch delta 767606 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


      1&&=q^_RXZ>FecQ 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 z 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

      3Mm2+}F&!hgG_7 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

      fVKHeS5xVMCi%|N1AL;lca!6S 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 n?HF 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

      55H9iGdJOn$ef1mm@hsT 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
      N6RBIZ(d`NyUL0#&*=6mg3B8 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

      FUP!@pGODq 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

      C5nC*UR29P#GAvlP|l+9LC}1 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·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%0AjUW12JLBl%TMc zMCuW%4dwwEtIgG|-W+JTc(*wCLo!y|!*Kt}r1UR11DBNk5-#G0 zIvNqH?Oe0cPRD9%fv0`@x}by>VvUyT_g#4EFjiZ;O2{~28Dj8<#A<7=_}8NU(l$6) zIi>i<+WQ<46$vG9T1;EfEr36Ot%x8QxVF=Nz*ueVsNI@fPs&QoUsKn_b8s@8(P|xG ztTpjJS7j|EDYcQmskME6QFd*Fv1)s6zqOI6skJ?7QyXEd+9vF;Hmjo4SZ$-SD-?C5 z#A++Zu9LDAvD&WFsVK_;o`}^33kbKQR;)IU7Fhs7p~QMI!CH;80PU0cW1Z0|UV<&f zC0ID^Rncirp4bGoz-doB8e`$7!r$PuCtf7BrbK!(&(iK*-hP($7F;(D^(^fbur7I) zR*NsO`8+`he0pN@%4qRtChZcy@l>ct&0nRKuSoP%%U7##C&-^& z#$BQ_@Mf7f##G^4f_pj$`M@!PzqEQaDWi6vt$65E=sx;E-1pA0mns zV&e?NH&^7E0QSaJc!W0+IR^t2`K89i*)^75Ugp%7jY39L4f(%Yl<-&Qi#bpNC|G!* zhrNmybic>>9G+seED;~Ro9+_#w~_0yMSWRixJ5*ID&q5FYAf9Hn-a%ZtU*2HpbDW} z_&b7#!wr#C#xE6Nii**|Idm8KGI4|z+bQ9#j(>u-U~pqxC!jLhe>zRws}N-aW7r$- zeFyq$dgy~4fD&c4wg#B~y;1tcn83|Ys2%y2I5kr>b5TX5N4+`+r^m+t6n zF$ge9@=TT>rjto9nRBEUr{X4K7}lvr;wD7w3a#`iu08&17*`!pon$NE4A?3hzZ%_v z+?FbIc4!y|ka0J5zRtMwv*0cf+X+l7k{1UP2+B_UtSa!>j;Kp}k$VngMTUJtjF#Ao zDqi4VH~Bs*XB99y)z;@wKiW>>M*`*SD*yQjy_(-jUQf6sN#cCv{B4d z)VpW{zEwq*(lw$nEM`z7P6&5squ=91_7wl=_?uVL7cH^^XW$)7&uw40BI0Xe0DjG{ z>E9@fw?zqf&6r@@z6EHB2}UfqNyAqLcyPzBM6jQ|70UhpI7uFAd|LDy1dWP`vthVP zh+(dUcR~HdtXq!{XH?F7mo|R~zWS;+A~?)yJdyoPVcmSf9Bjs;SDT-MakU`N-^X3C zku&@(v<{0`?Q&E=U^H?U`o-BYVr+^3a<5|%;ivjM!F{>YFYv`47gEF7m=AZGA_4n_CJZH)2f<$?8dmF`*ehi;;v1#-L!JS1CPy;E%GHu9a6TCd z^3?d$oP7P)ukT|BF}}bS5)0`NJmF|u315Yvo3N^}1o(u(K~{T$Zwl;k{3VTfrOr3x z91%e51#;3EDLBg6wmi6$eUYQg`5er}`iw7&30<*r&32hc5|%>_e_+YJbVUcN?qM&8 zDr$~)Ya20rMca|V6{wCsr@o0#f$P%EYHqT~FJ_-=^QdCdjtw;)KL7VPZF>O09JoF@c^#XSS@&_kVZCDBBg8fQ0~SfHO7(axQdRvNFXaA$L0K066z?_j z%HzB;X&_w7%*?7b92tZ|@>P~Y>Sw2#Wi#|@3nMkSFHZ>uQMozBr`?l+)YL&4NLAv6 zM5={I4NpPJ!~iEcJ*~9HCZ1VHT|%T-HUla25(lf-F`ttZQ5ta$=Ybj_#<}B7u^cO* zJNOpgxV|F`GrplSSis{5iA5a;vX&m;{}q1YL~g0VJU#)F1zv_$m1AL&UWIE>8QR^U8S87YQ%G8WyR2 z3V(?ace@4t-p)n|md^*m6(&wFv8-6@(dLQejh_?&0d;JNIMfo8(!wY<^}FmD3(?B< z+>yrx7Wm4B`IU`eKKoBG1ri+jd=L_3pby^TmN+vupg}a26c%Q4E-gF>wCe*NWUJyi zogEYveK8*3!7C{b?!lEy+}(!*CG#6EcnAUCtOl_F7x}brz1ogMF&ncs83QsE=`N7! z1&Qt!%AVlz0&0)M)sno-ud$eqN^p17+R>Yn-anoO6gzZS`J?bNYkb?#l)?XmA%i>M?C=He&N z8qkgwj@{)DFY+r~5jp6fs(v{DslRo@dI*=FM4j$S<$df^TuA9BW=KCq-xOkwMMHEe*} zQ6=uNBAj$HpR#1YB#;uRy$OFU2HDGilS~;vwWwVVxFQqATCyNp4g~MAmji4wMGmm> z!zc$%i0?-Z90dioBRR0+e@+fOiWw~Bz*uW8cR~)lTKfNl9C&ps{0fB=h2TUzViC;{4peJ&S;b|`gn4G8XnPH{5?IyH)+^BBcJ>VPm&!8xF& zh~KG9SgW$dD>u|J@)_wzyF!zATxt^40y0J4ejjsRN{~606zGHm@%K9j3F3)QhbCd+ z%TNyc!x@@{iSu8%taU)O&(t6+YAxzV$NM26D?HUY(jayT4MMh%7&AKVQra~LXQl?R zRY(r2yIfZ!WrfwOr6mwes&k_018WJh`cpc{fk|^hs)BGKR(=Oo{&TIBKVfBU?N~XG zksZvP19bdDQx3f4twK3a%dtU7DhDuja8^|3(FvrL;X_Z~8uD9e4eUF<*0VM;23JT5M|NWlY(Mgm_(C~j^6*h(5kSlw$nNM1Lc&rZ zC+qmhJ)QoKTOcx%@=^lP6H=|NM{@6h#wq}beVG1oPvf#O)XablX)E!i-!U=aZp#kmc4_;t7<9>sQb~SX6t_sVs)2R8FMRep z7PWG-_KMu)3{&Id`a;yoU1FjURb9V9yoUQ{;#1vAO9Q5HlJ3Dtv8$vqdC zhk!ZeMjf9AAy!B6qPqWQ9-1`4P!aX>54f8r&#)%(mfi??yX$e&s(&K2Z=V?dY%yT*!oyz?lrPB;Pn9**ZDWiW(tG=$Dr1s;NbO|&{eenhx(cj+@(cTID%(rh zrn2D!Y*Q_M(QIX`x5Q+6bCz~;$MmE!nNBEG%e7!W?oUYD7|t4?Tk@_SFHn5CVn50y z%|B9fnEH)*=5ld-Vt-tuFcq~Knd0sWtglkJ?1iV!nyLEWx}BZ4vy?7cHo9ahm;1vR zH!Vz@-@$|+d&M%HrBX|QX`L`x%B31F=+n|rfKWV1S=7rKI^xm=&WBRWQ{MQ*KDc#Z z>Y7>RsS||6v+vB0y-8Iwy)!M8EFM@RglHXD@B9i22oIkqCUN-00V$5N;QC+=jlkZn zejna-@sGmaBEK^!G0zPwCACMCl^-mp8K`GUS!Vlpxcq#76Th2rKjaiwwv`9)jgGinqOk=1fi2 z!dgfz>^AQw$Fg>trr{i?AHsky&zdsK$CuagPKmJa!}?|()cA5A7ixp8U75F6PEQ{X zdf@4f4y%50OwvL}MVFcukv2Z+A+#x+CG-5)t6e?>hwgL&aA_A0RpY*h?u8<1j;i(p zFq3{!#XMBO%b#MiOwY*x4pHlY^FY+-LRyfFAZZ{qBQ8P4B751Y zpLBP!HFH-(Y5HsE%IO<*W}e|jy`(n7^beziF#WS7?$&X+AgNJ6MWbxx+>QMTUj6H68>a2NtIjFa@n4UlrJwzK^fMKE4wB_@PM&dIn$)VBJHk3ufo|jLZVo0o0AUCI}{==?Gi|i zMHC`>+pBrm!h=(6h!ZJeYRWk2Wxkl+rea5Lsivxd7h-TEiW!&%x4w6s@4w5ES{5d% zg<8eRz_3y!w2n$|EW84(s*V*({B?fE*>=1i!eu&2YqoP~<Vb?nc77R^%2{ugy~3BDhB z-4_h|;qsc-qB7+5Kd((n(Dua!@|vL0uxR!$%In);olT$Ol-HZF&9Rr)6aMGq^%-bX zjw~IaBs!}D9|b{n5IXSxc6nW3C$Hak9%gyHit#(5QakwHCa)Jm&|%ICd3>Wb3dTzz zkGl7Q2pmGbs(3KvJR=dLT`Zf42i3R*1~Pkva(Rg6`APi&Jr)eiLX<8Cor_s zUr@0&akOKn62A>qFl<(1pfV4!wBSEdz0a|ep|qO#t}8$tJE!hM6spjVp?A@u`5KUR z>~zJiMEnx>$8b?V*`*w_9xULzD3SPcS ztdF?X+Z28j_25+whT6}()f=i_Ej1a!%9CS_P@|%Qt4Bs|o|HQ(dUJK|h{!qOTi%F> zzZ!AS-o~Ze+dn~Bg8H;==_74aeB$xBE^SkMdYfbSl;b%_Fyiu8Bl_4e@Yn0tg^qcR zu4CGgqYh4-iLT!2`5Z8w{N<+FV(k`^8(k&CUdD5j@G{5vawxJk{1zmiCk{I%M@z)Az&b=Mf3jaNv)5t=k^wrO4Wz+1*I4h*@Vms%Hih-lE?! zz>Yol68skcw>+SvvzPJH4eaQY4Mq@SjcTCZ+1ZmTUI{Rq81&}#cYCV7INFY?_i;vR zEJL8-^tvY?uh7o)qz}p!(2~x!v z_~`*!-`CrY&;%|_8XrRnX14y8b(Ay|z?8cw{a^pl>EQ{GPBP3^Xe-7_;U905%t( z!T7l#K zFvr?kn2DKW)t+ES*6#^EH+|ynU4?hU-Z{X;y}`Emv8=C(&1Z262n?^sr2QyG)tI@_jhCiqos zYJUse2-~KHu+Pz;AFu#K9du_ z!ICbt?=g#qaCJ9tlpVrdncpxW9Lr|d+n4ZNM;gsl-Ru}M3RM|D#IE&w+P7I(VjN%oH|OO+>n2YfK)h20z+;M6CDv1K>FW$+d!?|UT*{Z%;0=5|&d z4V(5i{l#DGqn8lv2%#nsH7GMF;~aF0@&3j%QGZVxcKLrbJvLKz=OaHP!kLL87-tE` zKWJ#hkv8)p$k%NUTcCvJkKmd)c=SnT&0=NYQV-F@tOWEP?QfHo7C znjhm;?O&;}-XBHpdT^s&``)AdL)B^`$$$cgCV*H0h%2nE08EuL@bpT2&hX(TJCsjf zZ0Q7icw+PAUHvd^k@6fB{t4wf5QP3GkDn_Gjb5m?{x%OrIZ;|$j*GkDop2g(M@L;MA_#{T^IJtdJaL_Y%Cb^_4`d^7 zw$+aaRGwT~^KFwDu^>H1ZE^?r8JIQ~M}B({#nKxaA8?r$lUQc?@W9lg=a$yM_JSWY zaYw)%dvE~?nP8(})y*Fj_x3H2rdoG7qK=1oq+W$^^Yq47+#47(Lz{mSh($oa$@sVg z{)l<7=S<=&wCRhF&BfOV`09(*3TG7BeBJata|o!ZN8o|KPlJPMxE=_=*G~!E4N_&m znQ}ZK;0#v`1e_U;55P&gPD*y`TJZ)cIWQXFlU!i>BpcoB5BA{0LKKzwY@CreqhaCN z5S>rYhDcb&FOm7|LQpJyEsk_H3K-nC3=^m@aWs5%1DA{~@o3@2uwdhZ&LUpzYZ&y# zpr~Fxf~RKUS;MvCIBRu9Ygw&35@&<%NG(QFCkgXY#7#rE8SlUtma!War4x9c%YM3CU8 z#5tdwWxNlEBxpWuXQCU>=T!1&yM0<*Ot)B^eh%O>#}DEKD_D?f#bwO#1WY00;v^YI zkc`3T?n5TyKixVy-b>;tJ>1|gE->Zo37^E#qY2ihpbGCciRzz$izQT&jDbu@W08j?-IrPyo|K4nYUl{khu620w?ijnAwh~bF{!Fe?ZF)TZqA%+p20U?G* zh|t03d)g#s=LD8=FpDU|?VuS^h6Sj+LLoQ`#tvj(H-(4bga15j;q`cQ2A&mHE71Yz z&T2aoJ-p@r^l9&zqSymVRHT* zwmE&&xMZD~bGi<0335)~Z8<0$@?`jeXWbN@8G1qob6Wo&nA1N^lF^T3bZSnQc6em} zzj{u8o;Ih4!ru48=JWu#;`}e3(}}L;(pOi?5gV(eYGFydZoj7QXPmEm`Ep&6%Zte} zBrd`NDkQKceorn`@97gPaUR??NtvU8IX-QRr}bkT1De`OuUy;{@Hy5wl_wiKtsD6C zI+})O%ahC8#jBLiI27_~pL?|p`p3US`bD`k0}oapHkZ!D2(LrMks%fl8q?i4I^J9H z$hE*7DLBttE|d+kC{BihKekNL3xS0ADFB zA1CIW5;IG{8#~XSb_97BXqiYsAkgF&Pe-Uib&#mWFhJU?NYdzwg-N4HoH=5Ue+)jG zxNLcBa{0#POLO@yMC>5{5tfQ@?&!Fm4x5XF!Z0XPVd#Mc9=CtC!X}2s+4p8kqIzT< zFtr1u%r>is51`Zz{F9u~MI4X9qX)P3M8Dw+vJT)cvJT*{xcVbig0t{dT>WW>J4(Ry z5OBykVCn<(#FSGMLCx5K9qI${IcT3TL2-vMXZn@qY?0qFr$=%p5pxIBc+Fg#%wTJT z`K-o!pR4A#dK{}cjq%#!*ue>o#5PK(x48F$X#O>G^{zip&S*7%T0o7}M9c;nyAE7qCpcpue1IMUm#_!M#^VEQJbH_bM~y%0BBV30 zqQo5;bt%&ZrtVQ{JXu@#;9gXFDbRGrmhv`|K4~^Wmt{85E2{}zeRMOo>b1PFgq?_W zdM%EmoZ=3ne)Mh|Y#TFl1F>%xhNjntW8``@Ltole?A_C;oRerYkGsCMnyrIev%CfV zg#2uoXe;5%0g#xJZpJe7Yi#OQ!lwb&xDJ0z3!rT?!)=@SdLN3Gp=i1R(9pl_l1+&c zt|$0^@h5%tG~6&9?~lg6x7yKoJ8SzR{$!GQhi&5{2!0p-?2pW=ZCm1%0ONeNM0uAq ze;Imr+m=559^gFzoyY^4!rWQLgW2~(ne=^B@pwN!T6AAtx{_KxTzimq=vFPP& zDTB-bwk>_bbMR9EZq1+*wd4$P#zqZHPE;k_M9}Z>CnoMPI2U7*=Tx*H%i)i)BjJ>H zMO`&>v5w#7i_Mqc$JIROj*OcE&!|R*B>c#fQ!+JW+X|OMSYnjm0vs{JQZhU`u5j+~ zNN-EIG3MgE8%eZ8*fYp0=2XN5Kp|j8Mf-V2M*6{TTZqX~(TQGWz#I+Vs0JTGj;%Kv zgDcb#xz4tC+>Z51@Ygu`f~V7{XxS+vBW3+f5aV*ZwroMh35d@PK`-6N6-Lyg^Elj* z9*2DwAGP>kqD9mGX2tVFqSj`>!M;Pwg&CLOD^B5 zns2dJL$<8ocYBmj7#lm6usyHGoJOvUC1^26FTI&pR7C{PP$5QeQ+Odr8z?w?4YCiu zf^Wjo9v4w%k&a_A-k@)BwH0PNA2OD{)3O{Uf|pRF#l0?|glh5RX)sEWZ4h_q@5eVd zWwBP+ghYbMIIA#2>+;bGtxFggT9=jk^3Bk?ohoXD*2M+odzqb*_Y7RHbEjLtU0SQi zPU%9<&bywwg(}eI-jqioz-2`}Vmbm7P=Lkhv0Y#fGPf;|9}Iw;Oz`Mlr)rPwzz=^4 z02U_63{EnSqs2+YUTsDXz)_F1)B6@5G57nLXv=ImJ)z@FFIH(p+P@Hf`)dG=SXiab z_=GBKAeQ4<FUy=v;uDj;*EQ3GaF(pCZ4*K!Q~WuDUtpUiQxgWi5Q!g=F){dg zK;$Vb2K+i#aU*6JQoz23Yhe*l3WcjsxGEyrYFSpQgc~p-$M=C~IZ(l?tw`&*4QU-Wpo#_^Uyz2eVLS3V zRxSl^a$Lp#6!>gwHFF}yEB|i34>s=rwBjmWfh?`e)fn8;Uwm2J(A)(N+IrNEhPTYX zW)@i`kxh~ND5v&uLn5zub#PmLaO>{;jnObiAQDt9uZlFTPE^%@)rDCax8+yWf8N#E z@CC9$8t&rFs3#YgA}i#ULS%nL%EpUWSzrsYH;U2e>h=zz^doy?Ba%RpzKGzNId&;K zYWmiLz`&NT%W~_R3q+bnQ3(gQcn~hd$X)e1C7HHUf94pmM;&9%q4u022n)wE0+C%} z5q3J-2!;UYI7wE9lrZZP6N|So&Ag5NvF$PHmC%Q5L1fr_0#A$2Bue76GbO7`4;iUa z)gHVFgFwJ!G$qpo6#2)eM%4cYs}>RUAH)+5IG9o@JEDF@?F7oIUD$YQ(rRCpto?pj zJ5xg*uy&jLk>1#nF(j)Vq>B`fIQqI@d~qrt-oF}e#qn3y9rB}Deyo-s^=eSBs@Wt* zSG`^UNyK%k46)|>o6q&lU7|4#Ndz2rMqguv2sm67`24M^ZaeU?&lz~&9lR{6>b5f) zWRziNqi8?Z84=K-djH7ET>lV60_*LJ-oFB{-3!XTa7M&q;Anje|(%M#4RDBmAx zz5A9CSH!z$P-K3I+|S9?BJxTg8Rg6PqQ-(;2UJIp%Z2}zmY|u7axj=%u~sIiQe%H3 zkiPAK%?L-$RFsptv#1~$ds4FwEtmrVr)r|AsHmt6t9qDyP2v?$%aK(iy2#J&MY6E+T2O}0nQ^VEZLVn1eG?c+$8R@{{r~|ir_n8V zI@D3VUDi2&pfBf2xO8`*Vi+d4PdR$eFCk}Ejlte=}qAU%CBC9wZ^%&iiz zt1+h=4(zd_^NS@jnr05cH~y1}Q1kro_cy_R1aO=ITVKoYHCD3#7h*V4&3g2&uOs(r zuCyvlCY(}2SCAqhBKqSgB~TEmq(D%?iHu1+9EfC2Vko{fS0SqYT&S4AX$x|u4|6GX z*kIJdR4Fh)V)poiCw;MpNLX<1vCjD9W|uOu(H+UdDX>oy?^TC;!BnnX&<$@9qfd~L zI33;&qLvt}B(d=zZ!xRUyIx)hCP`9b?geV@{d_G~zNxs}AcV2r>+%lA&d+Hr6e9R+ zJRR!Tk^O1*i4vwDgn49fU?^0BDjD~=86pAZ-^G$KF}nH8k@sz zP_;P=@quwSNcKp8(vO4v*fczDA1Ck#Q->n^qB)g_x3!G5rZLz*g)^r(Idf)IW0}?8 zpV(pNMzI9T&K-}ZAJ(}cUKqmSEC`E_K=kaHG+N#{s4@S{^w}zDEk}z$R|(@@L5|T6 ze_CdmQLYPN-A!GjKOmZ72F}M*XJ??uh(|$mcEtvGo zvY?SEvBK?l^~}+76A(@23q!oHWKK{BEGUyyOS@wzw0Go5?8rAxrlM4XVAW!uqqfal zk7@%?i^EkgHrymYfDlos=LbCOZ{}R_4_$mbz8^@LB}@hb z+8Mcozgpa6lEfujv!Lq;V_GHkyLV=>v%NN}B6+Lemh7rzEldr2R(3t9Js@&`99j>2 zeTmfr|Gk(!AeY?O8?qOFXLSU6zeu4P(D>@;1m;v%h)G-I4YCU)_54->oE1%G{OIp1|GT{OPp~${=}Au1Bb7t z>}~TjxuMWxBZYwl4vC4XxBBD~_&v(d@kV`hx9hSlaPItm|Jl*-L#SD(vRhzP) zQ_lhP=$BbsRbw$7=+&7ChrQU@fH)*XdQXi#)EAE)q)l?Hx$`Wq)@bgkG@-KT=g%RT z;&}-av1Ec_<`-T@w6)c^D^67n0hMV3^T8COEu!H|Bocmcg?M_`r9DfNkcSC}Q<4jB zif_g{kzDvRvzf(g2ClfQ%oP(g;W9F-am7R(37=PzgY^dvN$)KN{y9i1>~n0%Oe_45 zS?B($!~Ri{f(Sa^LGaR;DYejix)!3HwAUJh<~c~kla*0v4Nc~JKJ@%%?RnFuOmb;c_G1#twjE=9LqgWE z>s{JT_)zPgZ3Ox03Ig+{x40lh7vO$e#&1%CH%8%7MY}+pd@1V4)Mk{>LpYu>1>!Y) zJamEB-b4@kCWf>(u?N?EI@3hc%!L?;5rkV&XEw~mV0fzvx;z3~Xsh%)$L`}+EHo0= z4U)azu3UPsEJ)?DH=Yhrxs-d)nlVY%sY#vdKOFNvOy~N3l(pjL<7t07*JYP=a>Z{K z!b<2rV7{DSZ{n%5x|g{}5u8C}4Y7Tcn|EpN&_`Wj!>z}6uycNphWgKu7Pmfd@1I)( zFd~v8;m|bH_HomQLw7lD=HN+kYs4gB-Axfk$R#xa2YQcDKna+PsfYsrnDuG=hdp0; zb^Kb|`qylC7Ppx;e3$kS-Y;=Os0P1ihAF;3&JtY3ZCX>q7c|!I!!vF8u84qvao^dH zD4;1GMtq(q$b$je@FA>(Ilp0BUU2JPG>DpD$!Gg8{KNJ>GTvL*@*&w^|6k>b_ZB96 zVU-sqd{kX1&G-Q64^zHd+W^}=jrag^Hf%Gk`0uov@P%PsNXnT!nQ#_=6l~t-)HcJk z?<{VhZNC||{ovNk#mgfCLK=2U!=Sys0GcoKFZ{WdlPvuS89(h18oReBR-vExFOe4&wluL-^8_0UVsS#rGXj~KyfhMI zTKY)Lfxku+^(7@!yR3N@3X&X2lks$j%qOasD&YY{6$>zUD3C})b;@S~)e6(n*N&=+ zpgz%AJaY)l;Y=%u%wn$j$Q+Ssehuz1+o0P5VJ^{az*8sCMZ)=;QFV)ZZ9z@Xx4r}8 zD_U^ey7a%h+pLW8S=?T@O^|T8XIF4OQ0%Yp=0A;AwxJD0to|-tmct`N_?~C6< zt|L~N2d8~!AVN}c46~3$j4in8Y(r&9lFE&^9o7jdkve`Vs3pya%yewy_;PdVJwT%oc-2D#-`R5u&IqO zR&7=LtIet?H81>`*%eCr6uB>LN&nuMMK4z~6M-q9V>J z984_$t%2vfm~*X0Vk2()!oCRhi9$&?w8z}-ZfMhS!MD?HXfFb5>4x?op4#2eg824- z&<(9?GQ)dEE@-clEtV77Rj}R}cYNH=EMWq9|9T+>-++`lJmwE2G%>l*oQ@}$Kn~dq zVv0=TKJ;1#_pukiIPB9Jp$cL=?8RN*fgbH$xDd{z*XAn>qzy!fZn@I zuns4=r|?`+kBh;N68iPQfWF=v>nD8Yy%nE&wQE+ml~NI)xYjg=SKtRUvZx-PNSz))k-$(ms{Q#C?2(#qj|?BJ z%Q2pFl#qtMaF9^rwU3JG1eVa^0_eCVCk^H~`t7UadGm88W7aNR064hkFE|MWgG--c zTmEi%TF9rG%HUE)bIPeH^o2k3pMmBuQ7~~bukL@3ljSVGe^?>NFkGXJP43&)sNa2| zw652bvI_B=8XMCWH7g;W)_G#CvLa9HRVwkm*u&J^!50;XcyWisoBtk|P{nVEuZItK z4=c0QiE;&Hujf3%{Yp{W(a$53v|0`S*IL4&$WT#%_v~D+BhGSnOn0`-GS6OL0N%h) zf8qi*|8PBtLrBsP?;Oj8YapId&R_v_6Y;{qQxEPHm}hvFc$38wqu4B&A%?+R(u5Sy zOmq!rRU(D(hIer+#O9CTx7d7vb?ikB5KpWwg(aSNfddz72jXt%D&>9^$XpV?`Gj0w ztg;Lj8w4Lb`3k%v+m3$frE_w;)$4t6?+Lh`9%rjlUq(w})M=t6G$@*n$>!1TXb`A< zjC##>(N&^Ay!TL#L-a~22fqcCeG8-b)Vt+~R{=01ttKf8@pI;p~%igC(Rn zx#Y<|mv(3%toJ;J8$&TaO>{l^v&3dFHnuN%NIc?lQLe}FD#w*_|4)GxKsj?=(IVqq zyc``bIMd@;rp#)?Z|!5`eS9N@_f)1+7{_}_p^B%@jgi0e0;w&97G`iVEUmf06NBf6 zId0V0kj3B$I_WSPC zhD}}9&MA_wf<<6K;#|>)){0*_QqYY4+S$T7##s!W6W9|QhdG-2u;lF+6znNyBk_a> zDLX5+NEY}BX40IG_@>&t8=z{-cs(&Di{qBS^*1X0Lx9N18L8A&UVKr!`)GIkx+jr* z1_b=P*^8LKAmTeU*pN3WQaRcr1F%ys&P@d*(5T2%ajU?i33n4OE*Jb6m#B|GT>Hy# zzOs4>qMjCn7__nHSXX>Pvr`$lJd!8E+6%N215MeK9R5S}zn+!ChcSIk z`Y}W((UD}1wl8#qBs(lcZ!KkMZ2kiNUGxI};*RA)@lm@NA091#@oLO}k9Jv+Q@gsv zsZHta(=O`k(=IDjO2T8nYp2pHOc13cK1qI!H{&Z}?@q>7pZ4qy@nfiPGDI|hU4=W8 zlG%lmsmVPw?5JiOQXE=kD0mCGbAH^Juf*ykbpRTXVAE0(t=0%U^$z{;Lu?mAG@k z$1RG-Jgs{`gEHqx@iH7?KPh$F5`*~{j`#85p9Oc7+;L=Z&pG}c2oFpE%qQe3Fu#C6 zxbAN=#W>EzI2LfeHWwf9DSNd=0hEYe_Jvk^7avBfLwpfDBzj?mV`adO^4}FJGUM&$ z-C1RgFaHt2y;$#^kQH8yTB#@yubqo>dgwgqE%h;EP;e<<0nlCG`Lkk$pxeb*|s%f*`=T%~NWd7UuV7`t!AzB5DGj;`TtB^&?tk;hLB74rkWeYw4@$l#1ltoL;5sl%S z(E6!~9?s~jvoL)k;=6@<=!_Cl*(y&dAgZB4ES94eRLUNsAP+E$t42%#?c!WUjU;|;U-jO$US zPx`JoBfWTENlKRXRw>*N+j#;JgEc+!zBAg#IqdzKUnTJf|AZ7U(WsOa{!0GD(W3uS z{8Uq(guVN8*_Ds>Xy=z7N&2L;Y+J?KQh43Lu0Yfj`jh`X~^Re zn529qZrw_fS1J#mA477Azj}?&uL*%E{41x&K)XoxsW} zjC%x`VKL9*GcZa`nxPHc|#?MfnT8-6U zml98a&FEBS60Yo3>eu0NDSnyO$6LKpzU$G}00s>Xtwo zDCJy&*N`SlCjo5)(pj@zs^Sm_6adbbO1;$(tmZ)Z-W4xHsd``aXBWpSj~f-OtaL{z zdz-j>@;`7zx(_$M`QnvFjfzgK%ymbm_RdWO@ea>LBrnIZDMy%Z6AR29bj7_nxmGty z5ri8{q@p}d1U+#lIM6U<7%=z6gkmt7F>Kt?-bcA3z4IZ92!`xAMfhDTrq0HK+|tAm ztOGnM|EEWe9ZRktvWW&2_A9;1rR)VnlPL@CyHE)~fT4)ar^{YZO)q%h48az_8WqXm z?1uD!y7C#WUO|5RsVB+^0rDiCOt~=qQi?9GIe6h4hhD8Y1C9#Q2RVfx3*3_n_2YB2 z=Lzo4oerI68M^RDyj#iX;8-*DOE2zfm9H}AFtXg|OA#Q)4_61!4D%?&=MEI1eG4nX z0~4`EX6|=tdS&f(^vAE>Y(?#D#pU6L=@(UpS!G=wzWGhmnHfKPrSUlufTRcP-Kn4S z4on%DpidZY08~YUb7*KHlfXCn;#0WS#!e6iF2;}X#|#^6i$LOyYy^}rC%*Ah8zdgb zE-@1cC44l&&lZR@5)n8JR7fPkt!O{FQ>iR7u7JxxQZ_v?kkjUEH@13VTJ9`eK`P*; z25P*_%gMtrLQu|*hXZX%m(`aPIY+%LMcdtt`7_j)>e_NYL#tShmTd_wLdGehe=NzDKbm+8A8 zi$iG6vYENG-EM7{o`ZEdyYH?sY>I*RfV!iSCRGXYlBNjr7%2Dc^10WQj2Rh538I8ss;%RKQJU?

      Y;*1Zj{y^!%+zIglUItHL?l1 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%0Dq&^91b@}>-;k2Y(fB`!_8R9{)vwF1?T-Q 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

      bAzo;%>8peqjBB@~+_N@%~*F*#KE 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

      kEyWNVU-uY`-5vfyCFHXH^wKsgd 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

      ubR zChNt+@>t6Id>2#b_&q0|aZiqbH;Q*V6+Khkx#vC#M66wGM%Jm{SFN9$wsXZ5lAIDLHTqa|LK%jr3On;_T+x6l4{kjcpZ{SmlZ``w8< zf!O=l%8B|UeX>5qx97dNelsbzy*QWtey_cfZoIp-PXDOK$1XhbonA-Je5Z~6dGDsZ z)`vpwbv>ikek%R+-RU>>&3SBgj(O)Ep8*A1;`YhE4l;K$|9ATDwCC#C%y)M4&U4#yhw^jGzT`XYU?zC>TDzoswKU)PuGEA*B68~Q4JwZ2AwQ(vpUrLWW1>l^g9 z^^N*F`X+s|{;vL>zD3`vZ`0q`KhU@9AL<|JAM2m!pX#6KpX)pHFZ3_Gc}Fv7d4KH%EYc7vrDEk-d#R{|8^cMH4sge0A;pAm`D-`IOmxOdK8iHM~#eJ?kM` z=H%SR4FCH2?{m0Yo$~m;&+UvVMseGFGwV>udlYndC-2-lZTe5Tzn!tkD4Q_?{~t%- zKk4|r-L{bb7V^KA3&C&O+$HUi`u{k8{}cP1_TI^G@Ae4X-MMhLTb~jCc1Pgu?*Chj ze!IQND1WOXaI1Uh_Ia{}w-@jFzrVvrezLazzTEAM5B9bseBatx(jJT3iGMR?$m!if^B(V)+-VUwYtZ+vgK5k=OIi_vo?ANFcO0)i?_0e=*2{Z)&259*60fww zcxBv_R~A#Q>tCb42)^G@GV_es`fv?BT>e{c)vjHO%Sqvtrh=Yx%`VsX)((q#M`>N9 z3b&C=@ zJ9Uijv}l+9t-f2|qwm$f)A#B7^#i)|O4q69pnga{tRK;j>fh_`QR=SA>y+lnj1j$8 zs<_qPB8=zM=|pzZ9^()$=SFg9w~U)RrXSaT&`;5IPM6X(Vqx6 z44>7zhkJy7(wm1{h0p0f>#f7R!fnIn^+&_)!yUpG^o#l>{TKaL{Wtxx-Z}ic{)hgj z{+He@d_`{-ZV~Pm9vY75ZNecVlhHez*@!V>jW{EVk<|zrltCMe!5W;w8-npnSTrO< zHWWiOG($HG!!#_zHnJJ_7}iH+; z^*?p|{8RPZ{&7mq>wo_^z1{Q9&Go0eQ6cr{uV_><28JseRg9`eHKV#w!+6lBY1A@m z8+DAjMm^&pqrTC=c-UxYG%^|+O^l|-BStf$xzWOCX|yt08*PlXMmytCqrK6==xB5@ z9y2-{j~iW#uErBaH>11J!{}-BGI|?*j3F{*pdE*7+MPr6B)0kz< zHeNF37%v-hjRE0##(d)yV}bFivCvp#EH;)HOO4l{&Sl2y#&ToDKUn9=Yjyr_kFD3w zH;h%Ob7{4)#(2|MYrJKwGu9g$jJJ)A#_f3T7@LgE#=FLQ#uj6%vCVkj_`q;K;rM6P z)!=m&F8@SrZe8wr=+)QYZk}8_TfNUG@ewfno7esueLFb)82=et+}Enk+W&i5a*LP4 zc6&KYIeEYPpV7CBR@`_5+-q}Pf9+ix%DrBfchxQTnp?Q`Z}oh4i&qDh_UByI_1*eB z#z_Th@Vl6Hw>v2}M@B=}Rj|Al!`b4r%cY!n9+P(7b=|cW!*kq-ZY{XReHFYK9<7t_ zRNZ)g-YT)(_|W*s_}KWw_|*8!_}tiGd|`ZPd}VxXd}Hi1b{XFqyNx}@UgJAspRwOK zU>r0K8HbG{#!=&Y{yqYydQ!-^!F;!DDb<;3S(=u%{n|Y6!-MrU~HxtZ6Gs#RgQ_LJ@PBWL8 z+sp&yuspn?1%*Nq+^1C@UJG9>9||P{lOvUO+lS?yn^PWMOM~Oo9|~dpSRRQ)xOdCv zg0xqEzSQk*`$HkJ{bc=4`$M7JP{!?lKGW+z)=!p??*G*W!z#a7z$^%n3Ymq?B4$yu z7^I7vCCrlMeP$`Mw0XZ-#(cmmYnC(1n-$E8W+k(-StYf#UW~h!Y82b(x}Wdf>N{{Z z%ey_gS^jpo^#9G}&TVn~6I@@v-ALbvxV`PyFHLR@wjJ|T&1z_U+FP7>reh$Ex_n$jrQI3 zrkJZ!GtF7%Z1W{^j`^}V*PLh0H(xOqn6H`(%|+&7 zbBVdse9c^DzHTlzSC}i!H_TP$YIBYGrn%O9%Uox!H#eAXn;Xq{%uVKI^WAGTzGrSR zx0>6`_stK??dFH(N7uGEZTZ;zB;Z81F~j-$BS4-Z{y*pDQvY7>=TiRK$=uy&)u*Pr z+>PkB8q@7BuA`TmkM^1AEN%%L)AZtb6D#!TXVsS?Y1Oi{qK)}w^zK>ja%ih zI8ScO|GPw;(Cy9Kf3x-Oafog3j@mofBInh>os8(ly7A2L_s%Va>l>FuD*eZIe=IWX zlu66;M>x`|of+H+Ps{m|vP- znJdJv&2P+|<}P!k_^r9y++)5W?lr$N_nG_61Li^Vka^fVVjeZWH;VPPxCMH ziWxCORwgU66=TI(aaI;9D=Zhputiz4#aL@a*5WMQ8Yc>tXi1iADVAz!mTnoAX<3$S zWwY+FvRn6B@m7MBXeC+6R*IFw%4y}Ya>J6x%4_Ab&IprWLRoc4WDq}rhm9@%Q<*f=tU;*)yQgWHL;pnk66vDjbd}Fh1Jq(WktkRR%>gM*v4vWwX+_zHj6I_ z?X3=0N2`O-0EU=wVtrLS>3H3R!^&!)!XW0J!w5<^|kt0{jGP!0oK#jKx>dS z*m}m=A`Y>JTEnd2)(C5)HOd-otrxONW2|SbvDP?iyfwj^Xic)Vij%D=)>P{`tEe>1 znr=OBy(+8>g|*Up!&+snwis!R^`^Dfddpg8t+zH}RKD0ivKDIuwKD9oxKDTyQUszvSU%~RV^^GM;JFQ*Tx7KcJkG0qO&iYx{XYIER zSO={`)?w?2rAtSx@2z9jaq9=`1T2PBTsmp}Xq~c7TW73K1WP(={bcPB&sjfP^ThMk z1?y|^qIJpo#rhSN->l2l@75pIpVnX26)R$e>`ZoMJI0Q+W; zSGB9z)$JPg2f~APO}my|+pc5RwG*Uz_Ct1kyMg_%-Oz4iH@2JDP3=eQW_EMCh27F_ zWw*B5*lq20b`B}0^r+q5?qGMcJK2xfo$bf%E_PS@3A>x!-OeTTuzT9Q?A~@C`$_vL zyRY5P?r#sUpSB0ugY3cfGxiXBs6EUcZjZ1>+N12z_89wFd#pXq9&b;u3rGc|iS{IW zvOUF~YCmUBv!~n7+b`G!r5EiP_Dp-0J==cCo@2jk&$Z{-^X*sc1@^1=$L4>3Yq`uB%m4BS+-L?*7BZIquOo1yxskE`|IY|S ze76w%D+E5d6F@#YLc_cAY5C!+z7*hHUkv(iod}F02mPyYqImd)3Gz`s@c2WiU>p(J zkDd~U@A^y{z6xGiKA%P$3F70}1mmNR9u4x3n_DlJhL2uaJbr9~3dX_sWWC1}w_eiU zr(nI&{E1W^HsNlD_@0pW{7kS7b%-YY%;2Glgh)RIJk-0HNk0}mRJi~j2Og>vL-JX` zL-8@BpA|e*?tmW#57j*op8^jxEWp#?p{4|U20YXc0iOjARWr~|4m{M{K)pP8sLukv z03K>#AdUzg3hs&Vm%u}nk0pH>Jk<1nuYiX-8Squ`P*(!&(ZE9;3A9HC4^=vjtk(b! zRg@)t6FgL*Or&pthnkcc2QJbXn72-U*>rsT`$lJe!idG8+N8$!`-{O}9G5w@{eJ%x z9f_Qxr$q5ffL{{#L+bqW^Gm^B8aF43k7Z!yGG(ITF9UvAT(;DC;*aw>_^-z`it?9( zzdUY7RQwg-uZSBN#jgZ^W!%On{|)fph*MJcufN_^;IE476V=Yu;IEDgMfGrQ3X9GX@_{+lMof|*< zwfIgPY)@K`Ul=o+>P_MIJ#85IUd$UC%DD1Dxrv!L6e$GIA zcYN^7>E197KBq`)d@zmzBb2LxOFQ+te%^Ha0s$YYNIlOKPACdBqntRdUo4>ncqq~@ znNSKmRCVHfSURB$cqo#8AfX(1s7$Hz!Hr)&p(1#we1so~R00ph5q{-_s^FngQjb$N zPPK#@;GxKRA55qP9*Xp9C)5QGm7T+JcH`7bs1F{BOR7cM0$dUDnj_Z68eCLBI|uJp)YtS((jir06Y}wKbzW9E`d37xK z`N2o|`SIWv0IxuNZ0h*9^-cso2F|xJOhLkrz-V9|I^CI{~!AJS|ncx=#59Rk~gI^pxl;58NehKhU zet$0bCBZ8hUy*2k1a9|%kMi^LfiDFf%I_}#zchF#zrPUt`@uu`{l(yy0k2H_TB5&8 z!G8e!2jZ&{YztB>xWZ)qq9$`OOLM z0gHN@nCDx7uMTYW_|wFBep|u^z@o_b+kvkEJjx&cql8a@MUnicz&{8q%FlnE@CC3a zlK&F;n!uv`{MQLPfkl!0F5qhci}Lfk6ZQg&BKhxtuMI59&+kt-2rP=^4*_2XSd^cK z*A>8`NFMWb;~n|=qY1}=Mdc-qm*WYMNIl@|#TO(VFHR)<2rP<>e+u}AfJgb`pGo)$ zSQN>h1HL}6C_jHb;UcgolD`Ce17J~p{?~-dz@kY0cije73~wz@kY0Uf`PnkMi>giAlhs zNIn_(=D?!-e2&Ciz@kV#H}EZhMfv%>iTPm*zAr)Yn0H)OYzQoht@?*%N%&reO91}y4hqCL}r?+tA4_|J&; zypT8pSQHt5Ch&cLNBQH=PMiZQisWAg{z+g_em)YJ2P}%@G5=J&BR@YsaRIQXT}1m| zO@vod!1s;cL$rTU;u2s{`v`t1@cn@A7k`l8mnAL-7Dcva1@QfWNBP_HM&fE$WZzsM3EQ;he0Y4B}l%Ib$aSO00lHUsaAYf5`{{6)5 zz@kY0L*NGki}LdyCw>Yniu6BA+yNenjPpfeB=StWBY&K)62Ac!Me;j=9|Ane&wrb^ z2Urxz?*)D+uqfo+^Pvo%^f>P~Rw16ZWBFmgqWtk;en4zg(BBUp${*i3e-4k2L{Ma$ z1Hhu9`4PaPNd6$OsGxrcJXCa?k@0Xw0g-VI1B(j!N5De`{iEQaqT`Q>k3>*p{O^H9 z1^r{-p@RN#@K8bj2k=mi?|)t~IzAFXk@cPc78UeQf`^KZGbTO~L6LEO1Qr$aPl1OD z`lrD|MaO?OJ`zD;e1H4Lf`=mOJp(aNLH{gxsOUK3;v*3h8RsWpQKWw^@jQ5_GsNrq z3yG1)c!)7R{$8Gpa|u{fbiEURN0Iz5z@no0iNK;r{#Rg8LH{@KP|UX? zSX9ve9XwQYoXPQ#2#SpJ2e2s8|1G zc+Yp@h#@X15_u6=mv{OlhJ+*u;z*fi1meix&y4qcH;xK%W&-Q-ZX7+ygg9pAS%Ekf z__O0Z-;I+E;>-rt<()X8Q1+yFh=U@>Ap!W8fJb@b5DFzFr2vZ}`5eH{0T$)wb0y^g z7De)TfqxlTl%LO^R1jDc$rl2CF0d#+UnHp*uqcu*4*Wb|QGUK;QYm0jBwrf%`M{$5 ze3_)Oz@kXL9PqCIi}Ldok}3g-wF6- zz@z-}J12Dk7De)1fqxxX6!PwV?3UCGwm3I0ju`5Z)C*$t%Dnt4@18e$gTEr)^WEe0 zNry~ZdL394$u9?f1F$GRzcOhRuqcvW4gA}{qWt`uNpAs*BKdW|Zv+$WA0>SPEQ;hm z1^!)NQGWjOq%VL)k^GmyzXvSJ&wrh?6Ic|;68t=%@?@9U& zSQN?cOM-V`fJgaxc&!F3D(D{s4@Jho{G0HYgCgS`0u~j`zaJlop#1#dq@%#1vJ&Uv z?~`C}0sBEbO`M01C!GKmRg`!i<0SCgf!`iqf_NX}RMHt>QDl400{Vj3SX3}hR`5{KaXycaL{J#VeOyCs2Y4tl zei&k)qWLd?MUgxOEGp>J;Gu#(10E{qv*4i|-`~zJ<0BCiSuY1HDw_WaSQN?gz@no0 zuYpC8yZ|gJn*Rn^6v>OgqN4eoz@m`%_iGn;sG$EXc&MPi8$49d-vb^h=XboVO!z`xSgtkpB%l z6#DR0LwNlj4rPUB%I?kYOQ}bwv&HY@H?G~A-G*0oK7M1_z4`0KZzj7p z*AIT5(Dm`Pgv;U@efN8eTC%sr?;Gj(RyuyRbo}h;`0)YX-7n5NqE4H<_J`rSo@6^+ z9=|c}-u%3gj-MFg(#|+!2^|mNZy`K4Gz8yViuN<5<7ZCCk4eYRnvM^@SV*(pa5_Al zjvt$jUoag%E*+mu$7j;<`E-0C9luaIe&MVBiNJnw$7f$U{_cR!U5)c`z)vqu?yGz- zet~rST#4?bo@M5{Y>eML(ngFm3NMdB;WDkpP$L;_}+0; zgou-p4xc00E8)aHceS0lV!q7=&vUXBy&5MJ)&AJj#|e+L%jo`3K>oHvz3Iv6J(Y(YiG`6C|Q=?A%S@O|d|$w)dk z^!?8d|BQ!MB%q-G7kH?ke+4`g`tI+@3Z~o6La+tp@Xq5!C{#Gm9(R0-CKm@5MaD0Y z>Y(fRE?+Xa6l_6}e(B^g;GszWf#h=Fp-8`caz*e^q+cny3V0~eubNyPJe1?R<5?rQ zW@Ys7hU4S56TSfmEb3X}^&osV2Ru}euLm9~=syG=D(Ke-549-}zX5otApbCUsGkFT zL-0^RJ{NeXoLR|!H3AP6Nq{O@KuO{ifidg8n1mr7F;#X5gcOd~@(n zucZF&&)Y98z(WQ3mf)d+ek<@$;{)}!1`ieF+kl4(`fb5O1^ss5p*9ooA5HE69*X2U zCO-xq%JJQK*f|+~jRvoo3_5pee_g)|_@%%{`H$--z%L74S-J?pcL%>6_$WW$Gr4zV ztP^j3AM;^7#zfC&G1M@oVT^xXIp-NMgk$F1K1%JEd;S>)^}07~kL!;J_)dSt zQ0ti1G122JhML7Ri%D-jWPCjpC!=4oJ2BtIEgR5Z^3iz4|cz@nmg7FZPW?mTQ1(kbe}4cNFP2q1rHVU*Mo<;FK|7F4d9`I{M+E6g8oME zPyaB$E zP&mpr!8a4?M)?-_R>I}f{qDB^yW~j31|JoyHye1_611o|_kfQI^4Y;d1^s)$Lk0bK z@Zu91M#WD69~I;i!9xZ8B=Ar{KN&n!&`$v`CBclUHwXBrAfFRFRM5`_9xCYP1}}F) z$Ef&uz()o7yx^gNem?L}K|eou`4hTE#V-IpD##ZEuV6x(D83N*s32b$Je1$x5A&o5 zcqqSr5d5Oxq5M7`FU7z^`TfJd7Y7gJ_mM9F9xCXU1P>MT?*s3?1exg9QHWm(d{mGx z4IV1!-wz%t=$8Qx74#nf59RldLA_|k9u>`30v1K`XMjaT^Ob=`k^EU;QPF%AU{NIh6R@agzACUNl0OG5 zDw?kbEQ;iR1{M{~R|ghF^5=m?Me{X)MUngkU{TThgTSIl{vxobXuc+}D3ZSfEGn6p z&se?|u(c9$ruy!D_$B!_U{PfJ%gOL9Rp3!%{6Bz2kv!(>0E;5|KY>L>^L2qmk^Eo4 zqN4eFz@kY03b3eX{vlvdBp*RGO};*`DCF@vHaJEY*S(>SSI!|ne{?>da>o;Lv5unK z(*R_$3@nP|GXsl?<{JWwBKa6#QPF%OU{NF=3oI&{ZwxGo6(z7?=2lIMU$Mf0tJMUgxYEGn9B11yT<1z=Ipd|O~qBrgJsisst^ ziz0amSX4CsD6lA!mw`n^^X-8}k-P#dDw^*AEQ;h+U{TS0M_^GTuK|mS<~sq4B6%HH zR5bq>uqcu@fJH^~oqya_BSntvQv6vAvzij0#8EQ;hY-wjw4$tMAeisrimiz4}CU{TS04`5Lwp8_l@n(qlL zisW+ui;CuZ0gEE}oWP=@`QE^ykau5yA=d{yls`_clspgvMe=!5;J4AhqWpaRl!Cyb zNWKv8PXUYa^YBa_SQN=)zAvySKVLMZIIt*^FOdSjjRqFw=i!+-u&An0&u97r+drWO z@qDIK%KgBi$oOSa;J4Ahqx|v9rj!R3Me-GZe;QbnpRbfs1y~fxR|S3`uqZzd&lrJ4 zkv!%H0gLkUHBxEgWKN47!pYNK|4OkS(cL#nHuqZ#@Go?4MD3b33{AgfNejbh> zU{NHG`7ywv{CwY({=lM0en1L*iUTal&%+D^7De)y9}6sslVN_rohZl1_(&8FqE0epePpXy@N`#_ujB!uh(9%WAD8pT|^N? zv4J20f`C}CH|)Lh)|zch#Bqx)Tr2E&S%Y^+)&}Gv78_;FK z{-x+L>HdxAGGYHRbeVMjCUlvwe>u8Lx_>jeOxPcWE|c!xf-V#GuRxbc_isg)3Hw)~ z%cT3aq05B*tI%cA{oB!H!v59hGU@&u=rUpd8g!X-|4ww7uzxMOOuBy;x=h%=4qYbQ zzZ+d9><>qmN%!wTmkImVqsyfG_oB;${Tt9_(*66;Wy1cA=rVZk)x18rA6|tz>HdT0GGYG~bQ$Zn!Wiqf!5Hhe!x-y#z!>Xy!Wip!!5Hgz!x-!L zz!>ZI!WirK!5HiJ!x-xiz!>Wf!Wioh!5Hfg!x-z2z!>X~!Wiq1!5Hf!V2t(0VT|>W zFvj{Q7-M}jjIllj##kQox63C37|2F6&Q3}dWMfic#fg)!Er!Wiq%!5Hh$!x-z+V2t$_V2t$_VT|>cV2t&b zVT|=xV2t(YFvj`}7-Ria7-M}Vj46Ayd$#+t-TlWYe;*`vzEbS_=lT4ecke~tC(pZ& zg;xr%65d>R3*jw=w-R10ytVK)!rKZj2yZ96ebjls@Z758zT!W5Kj!g^G_k)^a6cUH zcZl}$u4B}3Do1n*3s{>~_WNhsNvh=g|54I5Fq#vR+ybt3{VT zk6#>!t)IN>5_K-WozLGvh+Qw2lU>{A@+AJ;e~+%x{gwDM;V%k*S@?9}<@I?&WVdJDkG$Vwp2zP`#BOhC{ZzYGqxVa-nn)ENvGvLOCAJ@<#hlAxosZL4pB~#!(wkxq z{t?_RZU~%jo&B_5RO$O7Z+-e+UT>EM{kK-w9~SiAHvK$qLAX8(joW!1zrqrF>F?Uf z^1tiN>FV9CrNTcD{*mxcgnuUd3*pO*^L~uoFWi1&&g~)Q>Gf7xKk4nEUE}&p`&E_P zP7?pxTTb7<6<*#R+BeQm?w9YqzJI^`DEw#RvEQ5HcF5naiLHm&=OWlomgiS9Kk?s% z|0(=$;md_L=}}%oTo1{5E^7yIzg!pGFBxx+f4}5}H#MH#U#%>zw_|WWR(Ny#`>{%R z`F7nDJldey7IeNw2qiD!EZ5-p-%X z=(|PtS9!Ou@l_hmr%U`|Id zr?c=?|ML;S`d|G&$Nnd}JgbWPcQxT%gpUfYw|slY1zsbTrxtT?|Qb+Q(eXKcN0D#SpGV*JjwMI|MN*fzvq7*uKzWKmzTeLsRA` z%)2Aac3XOW$-5y@k3D}S#}_;gy?1KMa8M4PibG1rFJ(U% z##lcD##lcT##lcL##lcb##lcB##lcR##lcJ##lcZ##lcF##kQ$W2_$wW2_$sW2_$! zW2~P5W2~PDW2_H_G1gClG1gCpG1gCkG1gCoG1gCmG1gCqG1kw3G1kw7G1kw5G1kw9 zG1kw4G1kw8G1mVFW2~PCW2~PKW2|2QW2|2YW2|2UW2|2cW2|2SW2|2aW2|2WV@h5+ zj%(&FZxm|D)B6p)-oQ>E=G~R!MMA9KML9k+UfyqTNoI9PmM8SrgwGcKy6`!|=L(-E z{0-srg)b2PrtpQr7YSc1{4L>2gugBP9pUc^e^2;Q;qMFoK=_BkKN9}2@K1z)D*Q9y zp9}v&_?N<$3I9s?*TTOM{;lxugnuvm2jM>o|4I1I!haF|tMK21|1SIw;eQJMOZeZy z{}H}ixT}fp_nHV_Nq9zhR(MW$UU*aC&4lyU4DIs~rBZm6@aDo>2yZF8mGElet%bJ{ z&RBJ3dOZ zG$-~x8|QO|J>KV>^y{eSg5$Vrdz9zL`!59j;VbOF9Q1EkVSh%@ziEa2Swa7n74}~b z`nQ>W@_tl#E!3XR_x;kxt@DES8}IPu#QO_^{#~Y@zTQQ_`(WkeSrYg?V$OZW)64&E zusjc#epCE?3Y$x?9rAXSA1{+LZSkzbgxmSEnRYNH^j9;h!^ig-;UxjBtO8_Lpa}=uZ*;tnel-xwYZ;mJyy6Ui!to z(ky>DOTW06_Niid@?w6a@aDoxzc8D=-j7I5I#-JFa2^~ zdO6#PIWLGgyEdNTo}SZR_yFMt3O^|76*xb>be;U~@^(_;S__Y_p9*~6d3;X%c2&6e z?W(}{q{ZjNZ&!tj->zn^^vz49S-f54=N&v(U|-HyPp+A-Tl{`EbeZz{Y35!O_v1>@ z_0Y_{B>D%4eopwyV$LhVrwcFrqGfsgB+qN5U%*WJ3^C_b;WLHL68@U-*}`8JK1X=z zmo(G2Yp&?e6JGj-&Gei%M1Q{U(l1x0=PVHY%IM>wnQPMci#h2zZ;CmkU!qL+tHk_{ zVmn+Y<}VVS6U(`qx!$~682$SiUrREJdn~~VK(&IODnXvym`VHtZe*e!Nf1}HU{eRH!i7w;!UF}MFe4hyt_A|Bk zZYp#czn`mZiY^oOo1woZx{TkitZj}i6ZTu6-wR#F@3*RLjV=@R+n~P|x{Tj1)V4>L z3HvLfzc#vz-|tx48C@pquY!JWbQ!=zrSYfTIe!ie{J;FN0;&Y>(s7?E)(|GN52ocjNjj&b|Z9|u)i_- z8=%Yh{Y`5(N0$lvTcE!ox{Tl7s&*T6nXtbt`WvCk`2Fo`cSM&7`#Yh(F}jT3?^nAE zx=h&L75z=nW&Hkt+Ck_tVSh0Co1)A3{oQN#M3)Ksd!fG>x{Tl7r*=PdnXtb<`kSN6 z`27QG4@Q^SHu&AQL(ty>-7RW%2!8kNu-YTgWy1MKqQ52jj6eVA+9BvNVgFe4w?dck z`^VRwh%OWMhoZkVx{TjHx%O0anXrEv`rDw(`290#&q9|8`)8xSExL@~KezTgbeXV! zKKk3C%lQ2ZYcEEZ3Hz6zzdgE)-@mMO7`jZ@zXJUo&}IDoRkhck%Y^-F(cckW#_tcW zy#ZY&?B9s~PUtdz|K{3T(PhH^ZRqz!m+|{|)ZT?I6ZY>$zaP4c-@mu^esr0z{{Z?s zqs#dHhiV@|mkIliqQ48ejNczoI}%+c?2kf!S9BS_Kc;pZx=h#~kA8o28NWZFb|Sh= z*nbNB0q8P*e^TvabeXBa<7*1~1JNB=Gc9<0O|5+%T_&7A4gEprGyeP+YhOl}3Hz_0 zKNwxc@6V{6i7pfNXQ96vx{TkST{{O|W^SE2h0CP?E-X}aQ>UUxNOg=rVr)o!a-%Wy1ba^!GxS@%tateuOR)_CH2{Z*&>I|7q>#=rUpd z3-tFvm+||{YQIL83H#rmzc0Fs-~X=m2XvXR|0DYQq09LFpKE_bmkIm7p}#-6jNkvG z_Ahjqu>Uvu2cXON{pGbyn&SKDkg&f}9loUnUB>Tc>+WQi zjxH1SyP$tKx{TlNTGt(2ChYe>{|Iy$zh75ZM3)Ks4d@?e;4$RN0(tgd4HyVU4Q(W(#7|IbpxY5 zxNdONcdy$$;?-`?x;-QA+}?FF^RfLc_83h|32)babqBzi$C~@gc_5~rfZKFJ&G<%7 zj$03|I}}|eyuF8^e>rK(P;?o;KcwzBbeXV!Jo+c0%lQ2h>rO(K z3Hv9be=@p^-#@kPbaa`pe+K%epv(CEv+B-4mkImlqJJv7jNd=6?gDg~uzw-?r=iRE z{fp}^MVATtm!W?;x{Ti+R(B=3OxV8){WH*I{Qfm{*P+XV{o&}Ji7w;!Z>YNoT_)_` zjQ&~ZGJgNoy4%rZ&TBzWw*NcOKO5b%Yc6c`Wc#_R?jCfRaQ?mMpMyT*&%eL!L3Ek0 z{}B4;qRaUGN9rC!mkIkL(ElI0jNczwHyT|g?2keJJaieqKd$ZxbeXU}0sZsQW&Hlc zx~I`)!u}-mFF=>^`;+UQMVATtQ_;T=UB>S}U-tsKOxS-B{fp3L{Qk>z)6r$Z{tWal zMwjvXGwWVMm-#HXe`lkA3A&fmd>P!obL!@y%Y^gaK>t$o8GrtQx`pU6VSf?&m!Zq} z{kQ7gMwbcu@1TD`oqv={QgIEpP@P?ET67t|-=sd%4BrEcg#Bzi_A=-)em`H|3|%JdSD-%}UB>TM)we*G3HvS4 zzaCx2?^oBiL6-^pZPC90UB>UXt6v#iChT`W|3-8fzu&2T6?B=fzbg7Sq09LF)$41} zWx{?}^lwI&@%!EDYtd!GejWO^pv(CEVtr3^nXtbG`nRIX`2Ak>Yop7A{od%`hA!jx z*R5Y4T_)`JLH~Ai8Na__{l@4rVSf|!??9LF`*=-+gm!-v)E; zslN}#{1Ev4^$)_Bp96oW{t+1STi}n@kAN|M2L5>cC>ZlkqbKWsbUnVy3b*UYnxh++ zGx4$TiSUUvcLhEk{uG??x3>xKr(ulm6XBC!jPFmwpMf#HKLei(V|_| ze-p-(JXy~R>+xzBx9QoMjT)CT@x}0|@ToPM1-=CS9Gvmj&pYtvVT|wZ!Kc9(-`|J7 z0Au|1^I`qR&G2_vWUFAkeNz7!jM*;m&+EU0G2xtL^tJ_;2-p>{#lDbN)vECG;78JuI(pvQw;|E#lo_bQ!;& zFE)$ztI&T1UB+LZEsCuwuxmiZ1?#Q4*apUg{kFw+Fedc&#SSngT%L|a9PQvbr`LQE ztcT9<8Soi3or1^vs_<9guhujPevfr^_)PfBnrz@T@LBL#HBAHW27e9yT1{o(J>aw9 zvuj!eUI%|2{(4PyqbHBwVzFlhUhg6OgZzGrdo z;!+sn`@Y5fi|@l2-w!MvT>JpW_xYDXQt=cR6Z)ye(_u{LXB5wZF`=JbJQv1<{=ee+Feda1iWk9{&@V1t3S&y1 zY|ob!hZR4;ZDRb}du8$J;-@gi_iKy8i=V+5-)|`1RQw#q_c zF}~kZysx+n#`yj~@uA{ZFovG2|3`|C;Wja$k0_3WF`Tj0t^GaWaeveM)gEj464t{+}yOD}IgJ#Q3-O#p27wZ(xk?(~GYbzlAZr&nnI? zeg|WGpHrMy{2s>mKEL>8@dp^=`=a7o#UEje?{631E&c>!=*jwDTKoXFi3$C~;>R#1 z^iPVP!I;oLFMbJQLSI(=8peeFP4PPz6Z-eXA7M=BKNWw0F(psd|F1>7(#CCK{M-9G z{1+JG`=7#c35Z}<)CnDM=#VU1|NS3|FVeZ62kuidat zU;lO`>vR2v4Jz^a0V&N-e8b9(U`*&6H*5-HLf@=%a~Mjf_+Sk9{WX{0KzT3onP{W}AuGycnTf-i~ zoMgT2-LP*Z-iJX-*PHl$4F|xO&<|`l7{-KtNadk0rsT=`Ijn(Fy7=qu2;oN=Pj2rq z@ISF`82@%13;zqo_)eV%=h0CA# zwT;cRUuQg7Z^IjI_-~TG9&T#5rQsi}8^-tB8t#bp?`pW~UmqDf-tTF+udlzH$@+P) z;o(ZW3yFlc_mRp+VNB?cH9QVuLLXT<3dWQ?dAyHq7z<-co~)m7jY9Rk+Kq2089ouv zxctd^rV~s*@h3g+f*V!xYS+npo;>E|{z|DnzmJsPIh8C8|JfWTrA8fJT1DqN4f;6Q zfzERtte4KKUCB)}%U?Plw%R@Q-+CympK8po=gD$=Xe~VUJzDH1^Cx-N>-#h2dXxT? zzU5oMeg|AH|6N)6>xvHF3hnT$nRc!RZtH%Z-;+$|IiE4-Z)(Pz+g8kZZmM-IV-=R@ zxybFJPcyeGxxFt%`g}d`is-*8`m>DlKIDDxFQ>o$XPbVqJadH46F&c#@-=Wf=X&OM zdX|;HCRuVmCS%U;^o%(lOV)XQH_!4~R9XHvyj|S(o51b)UrB$l=_me{@Fl|E7XFU# zca8IYsl-ygCwytd+oJ!z@zUe2nft)=)>sdv@2_j-J~W=JpBCO4<$5cvhlTyBN&4R#FU_xZKZ*H2oB5^JV@>d! z6fS?Voc28Tq;K!X#M_zsJ()AQ@l2@Fb@28kZqIX1=Ggl^>D%+%llAbcxm`)$p3k26 z?`HiZZqIWs&2Q%ZF!Ph^{i|=d-je=u(@*9%sS5ig$7_YEL-39%Q+oZA_}CmD8Kp-@ zdA;HNn5wPdjNfnK?Drug>(f52ljX7Bhmd$yEGPcnhJV9^*K5C*Ah}+<-za_0Nwv$H z`H43b-b{Ff@#K2#^KWv0RrceOmo8m!W0U?qjcY#b{`u7GC+nw$x!%NEdd@zdXWQa` z)yi{zk89HRzo&xzWO@AWCGfq%JWfmffA{7%W?KI5aTA|6+u~Wc+Pl5U^DMos@b*Lg zT{-xN-|r;)s|xQTyqoY^;YHzV2wzM1I>Of%zM=3# zJtyn`=$<&c1J3w9q#w@0g)zP#kA4Qm_|ETV$if)kPeeZlV|+ge^Ybvq_fv=9Y+e}S z`@txnd&;rKz&iztL7~?x%kF|m^ zW%plYmVP&43ggN0TqXP(n&INtN} z{pH*Q;S+^FExf!u-v`T6_MZZOM$DNaygcXEU{2Zp2z;uT^Sto#oWFxPWp@RCy_LPQ z@YMo;L0s=k!prkB!JM+^1Aj%#nIXJ9ry`hB_U3`l6mwn^UY=7E%qe?!;jM(X5#COC zhrnMK%Q;v08^RX|FW;`Z;Cjp6Abd^XYX`niT<>DxON758{5|3C3;$5~$HL3&0f$<6 zK284a@M%@~-}t}Z@tN_`>zSs`e?ODQcZvJ&XZqd+ub7gH@BaIlzWeWI`tHA<>AU}a zrtkjynZEn)XZrrRx88jJQutTGzY+eO@E?T#B>WfQzX|_C_+L@4cK`HC?yb`6-qQVB z?V9Wy_pI=y!YhTh5MC|3t?>53J02Tf{#Aw72=5`hD11%fy@jtYd?VqT3EwK>6?ngQ zyEW45fxd(AorL!jzKihw!UqZ;EPQw2d+r>+UHb^%U-&`74;6ld@S}wvEBplECka2* zIFG;hyHRHdKU?_!gkK>1V&Rtwze4!c!mks4gYcV$-zNM{;r9r?U-(199~J(%@X^A@ z37;VRDdEoue^&VO!e5MfQ}=N0mF76R04Y6Rl(xgBct3wSj0t^NF zax-B}=-H}SFedboxz}J!=%aG8VNB?wbFagg(8uKFz?jg-=H|kf(8uNG!I;p;=iY!Z zp+AwE4`V`~kXry_LZ6s>6UK!8d*wnH6Z%uRMKC7x#m(P>F`+-5TLNQ3pOkwW#)RIl z>Kzyp`ZKwAVNB@zRlNseLSNeaeHasZld2D3Oz3@BBXD9x%ptzF%DnV|;H9uY)nZ^L^%e7~^{fcoD|<&hIsCfHCys zxW@mSOw#9jquef&OEo?;l79aabCl!5V5Rq0tKEmkCR0ksWr=^fbKJjJqwHLsq`%DT zm)*HjfBNy&a6P-X6wSUm3>O`dTo?`r0tYdT$tGeH|EMeO(x1 zeLWaseSH{Xy$_7Bz5$G}z9EdUz7dSEzA=p9e#T$Vo4^>`-xS7J-weiB-yFtR-vY*1 z-x9`H-wMW9-x|hP-v-85-xkJL-wwuD-yX(T-vP#0-x0=G-wDQ8?+at>`tJv0Y=37M zV|^DGV|`Z`W4%9&u|5FCSRV*utPg@QcKHXx80)*i80)*k7(0It7-M};7-M}e7-M~J z7(*}b&sWF3he`MML6-^pUC?E$*T5L-U13am{=S&a*yY?0#)Q|~4KtW@e}8nDu-_eB zCfz>(T_)`JK$l7P4@8#<`~0Pv(y!Ho{yLnoeg5K2=~r*UK7Sdb^y?U**J4?i^zs~p zWnsd89lA`qe=xcX`=!rmSKu@5Y?dx%Z|3?{C2Hr_V>V;G2xF`_z?hQz`_)6REKIok zJ<(;-{X@}Z!u}fQGU@(d=rUn{O>~)b|8R7fu-^+^Cfz>*T_)_Wg)WosABip#_SZ(2 zN%xOJmkIm5(Ph&8qtRu;{yOL~>Hab3GGTvRbeVL22)azzUk_a--9HvxChV_|E|cyb zhb|NL`=HCD`^Tfpg#8WBWzzi<&}G8@hUhZs{)y-^VSgiZnRI_Bx=h&L7+ogaKM7qX z>~DfDlkT64E)(`QMVCqUPeGRn`Hg{HGGTv9 zbeVMj40M^WzZJSnx_>6ROxWKVT_)W>3tcAcZ-XwA?w^e=6ZW@7mr3`}L6-^p+o8*( z`{$y|g#GQ&Wzzlsq05B*9nfXc{qxXe!v2ovGU@*L=rUn{Cv=%~{{nQGu-_M5Cf&af zT_)`JLzhYSFG80I`#Yn{r27}6%Y^-1&}Gv7OVDM){;udU>HekYGGV_zx=gx%8M;i^ zAAl~C?q7~B6ZQw9%cNg74nvpW>&f!#xG@Zn%Y^d>qsyfGSE9>={oT-I(*3K@ zWy1dM=rZa4)#x%|e-Ct-bpIN3nXtbnx=gx%ExJtD-wRzP-M>q$GlU|;i(Pg+i z{_DD1V2t%!VT|?LV2t(KVT|=VV2t%UVGNhwU!J>QjP2hIV{HE(7-ReQ!WirK!5BN| zei&o>55O4f55gEb=OGwl`wzny>yN+~JLgdtWBZT680#ZojGgm1jIllv#@IQdV2t(A zFvj{A7-M}bjIllr##kQ@W9)K10b{IBfH8K?lQ72mL>OcJDHvntKMiASe-ezb{tS$< zJ{iVXp8{j-^*#$@Y=0_@p(p3<9@zLu=cB#krN7ryyMsLE{KO9yeu(fxg&!vTaN$P? zKT`Nn!jBeyjPN1Cj}?BL@Z*J_ApAt(LxrCt{AA&$2tQT$X~ItzeunTfg`Xw-Y~kk! zKUetwgr6t;eBl=ezfkx^!Y>wniSSE>Uncx=;lqSqA^b|=R|&sb_%*_>6@H!Y;li&M zeuMBEh2JFnX5qI8zg75c!fzLThwwXv-zEHR;r9r?SNMIx?-%}n@CSuIB>Z9Fj|hKM z_+!FH2!CAoNa3S|j}|^g_*miNgpU{ggzyQ%pApCSBJ;WLHL68@U-*}`8JK1cXm;q!#QA$-2@1;XDH zzEJog;fsa8C47nSw}rnW{9WPi312Gwec>Mn|4{fx!ao-NiSSQ_e>#3-2PlMtE1@-Gp}+-a~k;@H*l3!i&Nig!dG_hVV6o z_Y%IA@U?~a7QT+~b%n1de0|}4gl}NH^gX3j!S|7J|CyXuTi&ad_N%4u74$!MUGltJ z()hpe`wm|!)zrQ3FwXlF3;OWn{mBi@@+996bEetPC%%#BZ*08ueOCVUp5FNR@U-^{ ze3M?~Tfp^@?r#+IH(OzU)1be_3j13G{jFBm-#X}Tv%>y%L4Ugy_IC{WJFKwZFX->I z!v3y7zuyY`1B3o9E9~zU^!u-{zh}@NxWfKEL4WWH`}+s|-B;K@DCqCG!v3K_e{a#> zS9p2rKQfrJzvv$*ygX+}Fy~;=KU8>m&I!Ss!$to{;pI6e2Xl@V{UO4SGoHtHvT|Qp zp1}6%`9c5874|O*`e(1Oe`(M^cZL07LI1oJ_OA;17p$; zCa(8!;iH6)5kAg%vR^GP|Ln%)N&E@ZPxiM@MjhX)-?BWZ{Ccw5JuQ5a@MnZi7CuGz zv%;qee@^)G!lwy;LHLWpUlRVZ@K=OS7d}JytHNgrpC$Y?;j@LmE_{ygxx(iOe?$0u z;R}SnDSV;uMZy;ge@plh;cp9nNBFzK-xI!6`1`^?5dNX?kA#0L{1f4y3ja*_=fb}b z{-x*L|2rsz3wN#J&udMDuOvJpJS#jWJTJVd@Mgj*gjWi$65d>R3*jw=w-R10ytVK) z!rKZj80Ys$@OM=XG4IPIew6TbVorPGd_R!$R~Ftuct_!#gdbs+Gr8W*qQ8ppRfVr6 z{FvzVR=d^vhmWJu@>IL7!g~m>7v58NFX6p~uP1y1;TsFzO!$_JH)ql36FiAvkCrM z=c?0l+TtDVCIdoGzE>){cHHyAn+dNJ-duP~;nl+12rme4FT8{BPQq6azMAkZ#*_Qe zzK@i+eP1YX`#w+N_Whj1?fWE&+xJNlx9@u-Zr|TX+`hk&xP2cZar-_-;`V)v#O?bS ziQD%v67MS3b9dpj!s~@M2wy{ZFX3woUq|?Q!utr{Q255eH;s5(>^C;QF5C}rJ=3>2 zG44Bm8#^zC{n+R2>ARTQmCV^ycz@vogbx%xNcdpk zy9wW2_#VPz=jm`g>?!(t3Ex}zKEn4EzMt^@g&!b1etg~3#gDI>y7=*RQ+J@4e~|El zg&!jPP~nFOKV0|`!jBYwlyN?;xgR@v?euJ z=Lx?+_(j4mF<#oARJ+TB4-b@X9<5z_-x^?3!fu=uJC!n z-w-}u_yXZ?3STIEk?_UB-x9tg>Mh;dC&u*Di& z7xVuXbKJoAoQ&}N(0IR6cuO&-weUjk`26;w-*ITXzpC&WF~8gJ_?-H2aqlJi>kf?f z`-uJ~!nYh6pR=u)zk~3;!gmq#2M&*4?;fJRkC?x|@PmXO+B<%|hYLSa_|d|L42;h| zUii@A@&0L|f9BA5|6DQWLNVu(-tjq?2_GirUo$j5=X%k`rA0>S3(D?F95dEim$NQ5+e~R$ugugH}KK~Wbe^vNv!siT+&tEV!?u&cJeTkT} zRP;X(^FI;(#lZOWekJ@{;XjD^zx0mJ|4q#KQ_NW|<}|rJK0iMw=GCrZow!#CZy~&u z@YcfH3U4QTW#Ju#cNV_tp!n_WBD|aMTH!_EYY1OU_&UPZ7rvqJO@wbQd@JGG3g02> zEnQ#XyQ~vi|1DjA;RD5--9&$ni1WC9FX8({=Ci-Q@Pi_AnxKD(@WX^3A^a%e$D9;j zZ^w)NiNa43ev0tZgr6b&EaB$}|KFha?YiKkxL+dXTqb;&@GFI1E&N*H!-d~4D8BqR z3%^bHox<-~CqDl^;SUIZNcbbd9~1t#@KM6Y2p=c>i9zw(J5l%~F=w*qPZd5*_)B8` zE296Z@Yha?->$i0{u^S>o5B|he_Qx_*Tx=#d!Z#9gHWj{wn6uT%@#Wc0%-K=Q=_`C^;k!nh zue$~ePA?CAaK!ohwtGb8(DxF)kMRA3A0Yf7;fDx6O!yJPj~bj_54>GNgdZ<_sPI#S zpDz3?;pYlJU-(7BFBLva_*KHM6@I<&n}pvg{0`xF3%^hJgTfz)IJf^1#`#?!rSAh7 z)fV46jikT#_&I#%F~jdYF84>H%cT3yqsxT-G3YYs{xo!%us;@ECf$DlT_)_0LzhYS zUqqJ)`w!vwgP3%`rUt*rgoOR^n9Y>FU&a5v^p`N3=@P7;C(vcm^It}n3Fl8hmr2im z1zjeb|0KFhdj52DnQ;C@beVL22D(hxe+peD-G3EbChR|rE|c!hM3)Kslh9?-{aNTT zVgDI)nRNd(beXU}8C@p5K4+uLg#9V#GU@*7=rZB@e->RP-JgRl6ZWT~%cT2r(PhH^ zbLcYZ{ycPU-|OnUvifi4r?-f8GE>Hd6lnXvx?x=ea`7NE<7%kv_-OnUyC=rZB_ zm(XR>{e|cGU5E`=rZa4Tj(-je+Ifty1xWnChWh8 zE|c!RjV=@RXQIob`|qI3g#B6QGU@)i=rUpdHFTNu`g{*vCS0Gh(Ph%}m!ivr^Iu1o zN%!AJmkIlG&}Gug^8va{xIA;wWzzFMM3>?G()R{5b8lwYEM0tGWW4-*HxIL!^!$%7 zn+ccy4Ro1w|6_ESusHg>F zGGTuax=gzN1-eYwUyLr3Uj8r9Wy0lu3tcANUxqFd_Lrc`r2Ai?%Y^;6(Ph&8uhC_~ z{yXS0>Hat9GGYH+beVMjTXdPQ{~o$bdVPL}E)%ZLrRXy0{`crIVgG$}nRNdLbeXXK z0lG}O|0B9g*#8h+Cf)xDT_)^*gf5fr|BNmZ_CH3KN%wz2mkIlypv$EDzoN^8{ZG+l z()ZVI=rZB`^%=TMdj9X|GU5Es(Ph&8KhR~u{uk&n>HeSSGGYHqbeVMjFLar(zYJX_ zeS7~#mkDq0SLib7`TwBHg!8{fmr3`RqsxT-Z_s7Zeb)`YWR8UWZ_#Da{U+!#VgEaH znRI_8beXXKJ-SS~pFx)i`#+$|r2AQPnXvyOx=gyCLzfBrKcUN{`+0Pku>Uiz$5cV#Y3yE8tOwq?e~PW-#IPHbIw3_uHV$g#DG!Wzzk&=rUnHgD#Wq z7tm$GeimIO-EW636ZUiHGU8b!hR*XOuFA0T_)^Tq06NEtDwt-{ni<5C5ZK@*wz^9ufQ1V&2gQK^%>|g z)?1*k4%+CiMD3 zJ&XyxSSZ4n&>IR3Fedb#g`O}b^fd}=z?jh2EUXD*Lhn`R1!F>AtFRV~34QIt+At>c z-i6*UCiHa*>%f@M*Db6IV?tlAupW#Fef`4vFedaqg+4GQ^bHCdz?jfCENlp4Lf@#c z5sV3a$G7j0t`F!uBvG^c@O2z?jf?EbItlLf@&d6O0MH zZ=o-Y3B6yTAB+io=fch~CiGnjyTF*xcP;D+V?ys==nrE;A5a(oV?rNT7zkrRA5<6w zV?rNX7z|@V->tA4j0t`B!tO98^gRlDz?jhYEbIwmLf@;f7mNvg@50_NCiHy@`@opc z_bu!TV?y7rupf*GegDG#FedZ^3J1WL&<`ve2xCG&sBjRB3H{*0!7wKDLkfq$n9vU` z913GXKdf*VjG?E$Cm+u}6~ggl{;NceBlsd@)tGzp56AT-7rsA`T<;OWojLzK=^rWj zM+rY#_%Xu!i0d69`u05iWI2x&{o{lmFZ=}ICkh`b{3PKg3qM8pslrbae!B28gr6z= zEa7JhKS%hv!v81yJmKdHzd-nf!Y>kjvG7ZTUn=}E;g<^^Cj1KFR|>yM_|?L%5q_=k z>x2&%e!cJ;gx@IK{=QrCc)v;XZx()w@LPr7Cj55ccL={z_+7&97JiR#`#V9&`ngy1 z?-PE%@CSrHDEuMe4-0=p_@lxf6Fx%tRW@G-*23LhtYyznQ4PZ0j3@QK2o z68^OCNy48IK3Vt_;m-=6D*QR&&kLU>`~~4J3V%uX%fep~K3(_>;japxDSVdj*M!d& z{<`p$#Ot>?qCZ#oJmGH$pD%oY@Hd4o6uwCKV&QKIUn2Z%;qM54SGfKDrDXsAp6D+X z{=V=JgnuafBjFzl|3vsH-us#U@yn;8|C#X5g?}OZOX16eeZRLzX<M};a!Dy6W(2T58<`K>xA3yu}s!mz33N(Hwf=3d=24i3hyO+ zE#Yem?=5^C;p+-tPx$)6`v~7a_=dta627tUO@wbMd^6!q#p~P6MSlz7TMFMw_}0R= z5x%YP?SyYHd3g1b1U*QYI>$-lTzq9aNgzqZ6zwiOV2MQk~e6aA{gzqkV58-QOqlLdK z*7GrnD7z8M+zS$e6;W}!p909Cw#o{CxlNB{-p4U!k-fUwD3v7pAkM; z_!QyK3ZE+cIpNO>pCpDp}#;d6w~ z6+Tb+8^Y%cUm*NV;R}T?624gYTf&zJe_QxF!rvACp75o@-xvOY@DGK5B>ZFHp9ud{ z_-DdD7ygCtFNH4?{*~~rg?}UbTjAdc|6cfy!haV2tMK21|1SIw;eQGLN4RS*{=Q(m z^!fa1w^E;#`Xv90^5+bzUA9j)>iItTs5jfA*&eYuReMxLy=9;3=$vZdZThr{_VMBB zsJHLaKI$F%bclMVKAi&R>t3FlvC4mnbD8kD$Gq!=Z&wM=zu<=feHHEJwytnXmg|9Ds1K}G9-$eLk!nY8W^W&Zo{jBi3J66n(dq(uL!t?GpF+c7Z(a#FcyW_?DxMxH^D?IN`5cA`n5&f+2 zygO0Mk9$V+v%>RksF)x3jOb^D=iNzSe%v#npB0{WCyV)U&xn3jc;1~N=EprF`dQ(5 zcdD2l_l)Rgh3DOAVt(B7?sUcmEUfdM)b47^X_~xKkj*Vf#}CQBl=n4d3T|h zANRbwNc7{L5&f+2yt`P;k9$V+v%>T45-~sSd3UMkTj%#(@R*_eYN>qO#Me=mi8*o4 zh<;Xh-d!%{$35?ciGJMk?h4V5d){3c?dRQ9QO^m_yQ@V%?s<2O=*KHJMMXRgXqUS?`{(PxaZw1q96CXyG``to_BYMe%$l!F42#B zM)dRU9x*5G8PU(X``X9vuefJKKPx=%?vE~K-aRP%Vd0MoA0d3C@X^A@3Lh_gg7AsL zpBDa%@F~Kl3V&Ys3&LL#{)+G!!eQ9)N}6m4Pwiab0-RqzmCeelSDuM`YPv65&hGI z$6rU~+!>-De|?p6@z+;5cb1rQj_~;FsGR$s=*M4Q#>}RzaGnp=ewMXKi}nC{P`>A;?G|>7k~cBx%l%=&c&a1a?XF=DL;?ood3Mzd;Iw# z=i<*7ITwGv$hk|!dXDe^bMA7{ze0F?zm4|?L_fYi&$;;iJm=#3tDL(=%)d@}e1DsB z*Nc99Kb&*%{cuJc_hrO!U&h@Sz21zA@5eIkX3>uy4`y8acrfGQ$AcLc-;ZV7t>Sv) z$9)+WKkm!8_;Fvx#rIbkce}XW`2Hm0;>Tqf7e6k`xcG5d#>J1zGA@2xmT~dpuZ;7L zzsj#OGtNK$^4&lF^4&lFD(@dM!SR>hztdZ9zQ>QtGR{9P^ZWjBneYB_neXxAvW$x# zmt|c1_$%Y$$6py2KmN+N`0-c9#gD%-E`I!#aq;7?jEf(CWt{WYvwy$jg*OvkExe8J zg7EnBQARu;WnBEYCgZw@`SIhLjEg@{W!&9jPW<>KMSx)70)|a@w}52&lg$oe32FV z`K;K_XI*?hkL480@9!te`=zXV)a&~`LikAG@yAzIJifBxaglZL?J6s_tE`LPk6C#? zj@~nN+>~|WginZi-aX~5hw}a{?c3x8MmQsEy6|46w1IP%xqC!+tE@Gpcfi+WCMpErc_L+0>?K9`%+h@+jx6ho5Z=X3A-#&9LzJ2CgeEZC~`1YA|@$EAc zEPr`_l?j&LcYpbP_m|)I`12Z$`@F}C-;e(tBrA?nvf?-;>*B{LS#f)_;`U~P`>VX1 zS*MmWe!P%#UwgOL-~YrtNp+|{KPaJ zoNF5G<9)EGXIu;6)ltv6w!+&-J>!&jjP~*VSkyDZb8dCfk9*E_jrMb{N7OUI@%~%1 zpL0EGA7wvYC6ZYSY8 z3-2#{P}DOn?m4%6w4ZZ(3Ex-v0m2WCdd3|V^_=u0qy3DFd(Isr`pS;n)7Cu?{RN>Qvza)IR@R`DA3!f`|zVL;@-xB_g@TF1Di2Yl} zsr}f8(K&d%9rcX+JnDE|9rcX+Ch9r&y>Qi6*ZY&0^Q-Vbg#Rtv?Hzkvml4aKaq;KP zjC|daiO$C-wxXVQ6~dbfZ*^vD`SY%=@Rfyk7QVXhZo=z?_uM(0I~6$avB} z*m%-E#CX#G)SQ2v^glD6^ba+2lKx@Flm6kxll~FLlm3y$lm1c0OWR4cJKA{Z{;hWQ z{$;-f{u6(^v~aP<3;UDI{a(7>7B2RHFKK-}kpqzwd9Ke&63d>0JIQ+}>l%`cH1x5aGufFP&fCA~?UEk2|i1 zO8ob6k$zkF@t$*eIEQ|M@b|_2c%s+m^>Tm9+cng9a(hpTIIs6)<2<=aEG{>n@Bs&Z~-g)?FHPoKF<>th*xWIIkz_S$9p; z^X|HivGs}bU!tB9o_E)ae%x`sjOfQb?`{cO%98 zxa04e(SBBV-i?a(bHX#iv%>Rkw3r`veEv4t&kE1GG0}cbct&_uc;1Z_^W%=s2}k?* zJXqB8Zd}xJ!tpw@ee88+PI%sp7xUwu5&f+2ynAA!`0~U(@17L>xZ`tHq91pB{z~+% zmyQRk+@Ox-<>zr$;*%p@g(EO~Tv<9Us}jd$Rqmw7oVJ(~KMt*OQ%t{fyj&%Yud7nW z*U9q7k7uh=$FuCW!1C;BuD5iYTa`M_P5QC-A2{b(GY3C~>?+`k%yDkwwca;OaQ!E~ zy6`T-7mN9C311@oZQ<_-f7f`je&X-9RHfdZDZM{XCEhova`yd!q;KC(NbdLe`#Dvq z_W`h~T@&0d59g-h9%D+shn4uFx#wU^=*udfhcTf)mYW7+LLZTP0mg)$t$Gp0gg!F& z5{wCbRPJRM6Z+`fD=;SXF}dk5CiJnn889aFak*DvOz7itGhs~VPvmC7n9wKWUV|~A zPt47RF`@rn`8tdV{i)m>7!&&9=5t|8=uhY7!I;n|<=%iXq4%qr4`V`qCbs~_guY+Z zn=mHyrOg+@n9!S4ErKy6PxfO+HVSq5^5p$G?hjA&ocn>&`>R#%D9_pF_tLPx*mL$v z@2^&+-d|1n*O|v@>HAl!Fb&Js?cZQd;!WT+aE9{}UkTn7#`vCrcY`s$XW`vpjPE&k z4;bTn9$pJ$d~XV`gE780gV)0t-z(rn7~^{-yaC4eUIp(7V|;H8UjxSY-U7ZRjPboC zycdk|y%l^d7~^|2d~F!xduw=a7~^{z_&PAg_qOnLVT|tu_PMfHA&zfNuz6eD4U~2*%Kp?ccudo$SxwGTU>q{oD7$ll~IZPv*bvIUg^{oOg_u zo-dla0iN@H;L@Dt?oiKL|2L<(JIr`8r@!Z%llZ&F`TlbgJX)7jm-Yet@8tbw`g@|k zRQUVCKM?+*@Q;LlEc_GUpBm?P@$z%5dNg_ ziNc=}{r9We@Xbu!e0?SUHA;)uL_?je3tOn zgwGcKy6`!|=L(-E{0-srg)b2PrtpQr7YYB|>^GAA$rrw3XOj4r#*_WbGS3UxKPUc` z=l*{9YvJDr|5o^S!oL^(gYX}P|0Mip;lBv~Rrqhhe;59T@IQtBCH!yU{|H|$+;xgS z&o&XhlJJc1tni%hyzr*Nn+dNFUMajvcyr+`gtrvlN_e&K*23EeZ!5eYyq)m&!dDjF zL3l^uorHH5zKZZwg|B8jdH-#7&-r>g@h--b*UvS^ljFp$#@qjUyxGloGQYd<9>z;^ zn!8%hxxXzfPjgo%yk2-wc!TledV30A!+7V$+Z%rGYco8#@JJbpi=&$Ih09+V=_}{` z!a018uRNvn`k%8)^Vh@@G1k|DG1hy-80+i880+i980#Cr80#Cs80(wB80(wC80%ZW z80%ZX80*`>80*`?80$O080$O180-CDjP+e$jP?F7#`-`QV|_4;vA#QuvA!pavA#Eq zvA!>ivA#cyv3?+ov3@X&v3@9wv3@v=v3?|sv3@j+u|5RGSU(QNSU&;ASRV>wte*^H zte*;Fte*~Jte**Ete*{IN?v+@tn|3v81H#7+z2V<;X0As9Q1Y@jU z0%NRS24k!bgE7{xgfZ5yhB4N!g)!EL!x-x~z!>W{!5Hhez!>Yd!5Hgzz!>Xy!5HiJ zz!>ZI!5Hfgz!>Wf!5Hh0z!>X~!5Hh0!x-zMV2t%KFvj{g7-Rhj7-RiO7-Rh@7-M}B zjIll$##nzA##nz2##o;QW30ajV@mEn4_<-C9Ah7kSHT$T*T5L-*TER;*TWd=H^La} zH^Ug~x560fx5F6gcfuI!cf%O#_re(K_rn!Ro0As9AgfZ5ihB4Nkfic#nz!>XOVT|?XVT|<`V2t&bV2t%wV2t${Fvj{! z7-Ri47-Ri)7-M}djG^tfjP)O3jP;*kjP+k(jP>7PjP*ZZjP<`^ zjP>QTh&SoHd^uzL85mx-#`@|o#(E8mvEB{FSnmO2tk=O9>qQt-a=s2p_Iqz&-^nEV)x;OT z80!mRjP=DZ#`+Q%WBnZ%WBolCWBq*?WBo%IWBp?oWBpSYWBqd&WBp4QWBn@_WBnT# zWBofAWBmshWBn%>WBnHxWBoT6WBm^pWBo4}WBnf(W8HOMzMQeX5{$8)g)!FiFvfZ_ z7-PK>##nC-W30D?G1jYT5pM%yY`*|wtha|T);qu$>z!bX^;KYu_0?dE^)4{RdRG`@ zy*rGtUJGNa*TWd=4KT*~8ZgFsFBoHeZ5U&H9T;PMJs4xX4~(Jn^&UU-$NgGzQO?(U zrN4Lk{ka9-dv20UDScim-Cq#&*IHqJanN7a^z*K%`5p5<&vPO9_ZPmVEH4cn8~8AG z9>&jRm3_m;e&QQ=^EoH+O@x={yi@S|Wq-fXo2Hg$|A&GC{U$5ue2rpmn zregk1b zWZ%yCI|x#GT$Fu(7-RiF7-Ril7-RiV7-Ri#7-RiN7-Rit7-M}1jIn+kjIn+KjIllx z##lcY##lcU##lcc##lcS##lca##lcW##lcO##p}q##p}y##p}u##p}$##kQ)W2|2Z zW2|2dW2|2bW2_H{G1hN@G1hN_G1hN^G1hN`F(vokPumdB2~6^Qk?cP=hB4MRg)!DQ zhcVW-gfZ5)hB4N+g)!E*hcVW7gfZ6p!Wip2!x-zk!WioVV2t%aFvj|BFvj{GFvj{` zFvj{mFvj|RFvj`;Fvj{pFvj{JFvj{}Fvj{3Fvj{(Fvj{ZFvj|^Fvj}vFvj|cFvj{x zFvj{RFvj|6FovEy&+_q*T)Nmzw1%J%4d6h0B>Z&p%2oyxzol z{!w!Ao#!7V7vFiFQF8H}=K&=b-+8`Ia`Bz#`y?0Nd0tO)@tx=OBp2U#UQcrIo#*u= z7vFhaPjc~{=k+8P-+5k7a`Bz#^&}VHd0tO)@tx=OBp2U#UQcqNC)>Hd{de*FQExl( zeVI8QEtxYy^t0Y}<3je|+cphRMZuf4}6rzhCm* z-!J*@@0Wb{_e;L}`z7D~{gUtge#v)#zvR2WU-I4GFZs^%Mw5&0b2=yLpSRe=%{89v zm*#oy@AuviK416(;cp6GDEx*@dHMb2StR=Z$KHF#MRD!_|7Z5hE+D9^t1*c>1A>Y= z;I3k?pr}|-iYRta1Vt=}1$*ztlGqbV)LqTmJI2IBWA80lBgGmMjY*8@G2#0<2Z(d` zdLEDDbK_sXpXBvA?|IIdbIzPOdvj82=d<+ zPjcghzo(GMecgCtzh5ry&o6Xb-_H*O{7V7*rfN*Uz_luAgu9TtDCHxqiOYbNzg)=lc0p&-L@Ip6lmZJ=f2-daj>u^;|!% z>bZVi)pPy4s^|K7RnPVFs-ElTRXx|wt9q`VSM^*!uQL9kd6n_vaju_N^;|!%>bZXY z)N}p(sptCnQ_uDDr=IKQPd(SqpL(vJKlNNcf9kn@{?v2*{Hf>q`BTsJ^QWHc=Se-+ z&y#wtpC|QPKTqnpexB5G{XD7X`gu~%_4A~j>*qbZVC z)N}oOsOS3mP|x-AFyr_SlE~L?^Jj58XS>b+h0l+Y{^NO5Y@RRX`sYpQx&C=mdhX}; zzFb_6{&`dS{QBoj>AC)SQ+lp{-jtr}pEsrF`sYpQ`HP>gB@zApvi>Y?zkYx9T))41 zuHRoh*YB^M>-SgB_4}*m`u){&{r)n}#zWzKN{=xjm!ZD;8I20rw6&`r(jI(+z7_x&ON}G+_@JR zlRNhYV{+#u!I<26X)q>tZU$p==N2#~cU}&R$(@%6V{+%Ofib!B3Sdm`yb>6bJ6FM& z+_^s(lRFOpV{+$Jz?j^5H83W3ULB0do!10oa_7NdOzylE7*io<^JMXTePi(55fhs? z^n5HBlRF;|#^lZ?f-$-C$zV+Gd@2}|JD(256V{+%a!I<3nUN9ziz8{RqogV~aa_5J@ zm>6gGeHrmCv+M=W(_s9?&zYA5&p($0&k2_V&v%ss&-a!D&p*faZi0617VxbC{^I8V zOM>U_N`mL*N`mKvOM>S=OM>SrOM>ThOM>SlOM>U9OM>T$OM>U^OM>U*OM>UaOM>UU zOM>TtOM>TYOM>TDOT@-!ayFa)=lGob!sh@>q_!Y`9Rc4d7!P{R&bx|V7y9w9=c{$) z==mA}-zDJs=h*AZd0UWQKmPUk_2Xa9_2XR6w+qVOA>jJwKABZn$*YiL7p_q3R@Xi7rE8y`0o*>{o z1-y@dCkc46fTs$0nt%@x@ZkcUDd3|8e5`;^5b((YK25-93iuoWpD*AG1$>EsFBR|= zFXSG?{r-f)ap*zZzh^JztDC%N+Q519c`zVUJ`+XF}-2Fa^V(xw) zMKO23kD{2n-$zl*UwnK^5%>Ejiu1eQM^Vh(@1rQ@?)Om?bNBlwin;rJ6vf>AK8j-Q zeji0KUn>}g>jiv+fN$#gqH&IK`-1!y;z`~U@U1W45`N*a{e@hA7YN=T@upe4Uprrz zzZBUm;QHsU>R&JGOTKu&_Evl`-zVVv1w2(y{sBS$g92Wu^o!e*Ey#aJz~2|}^5tG! z{$WA>4+Q)}0Y4((9|`!!0)AZ3pGO7xj|uoE0)AY;PYC!)0Z$UNvz*{Ko)VPPNB4YG z{kVNqP)=V#{?mf;{}8nEj3ED60Y4|;=LP(NfJX`1?-aE2qM)2h0)AP*ue^}^lB+#m z^t$jRp9=U50nZWed;z~B;P(amO96lMLheDnsraJ(@*v;3@xtdry3NDBh4V1`F70_K zn4j_RbM|=|r#0j|w{nX469NBTz@G~Ej{^Rafd4GuzX3L7Hd7!vIB>|@bE(^H(yj@(rQIOw5z&!=rOTbGAxVM03xXlB_?JOzCUrNAB3%IX< zyU!=Z^_m6w%Luqdz{?7FIRSq~z{?Bxs{;O-fWI!_6$QMKfGYy73b?<3R~GO90S^@L zDgs_rz^e&(kbqYg@EQVMQ@}L=4;Jtc0k0+CRspvOcx?f%BjBL|URS{D33z=0Zy?|e z1-y}fHx}?F0^U@>n+tdg0S^;!_s<2z^GvuPe@g*xCE%?Eysdyo3V1sKZ!h2-1iYhw zM+tZ*0q-o}(E=VT;Bf-pMZn_)yqkb02zYk^pD%d7>mkVBQ^0!(cy9skBjAYwo+RM? z1w2{62MBnIfTs%hKmi{l;AsLrSisW-e29P#74YE#o+02P1Uyr~M+*1~!MGYN$e$(P zV+DMifR7jOi2^=Zz^4fKQ~{qR;L`FW?IV{0#wLDBz0( ze6fHp5%4z!{4D`rD&Wfme7S(H5b%`(zDmH~7Vvije2svw74UTezFxpL2>3<;-z4C6 z0e1-aW&z(K;O_~zQ^2ca&e3yXl7Vtd+zE{Ba3HW{iKOo=-1w3284+;4D z0)AM)KM?Q_1^goc|5(6}3ivSr|3tt~2>3|>KPBL&1^kSFpB3RaFc+02)LJkmk@Ao0WT@wr3AdRfSU!}BH(2Oyqti)BH-l({8a&eO~79l@CpK6 zQNSw+xFX@fX@@~ z`2xN`z~2z?g#x}vz!wYn5&?fpz?Ta6G67#M;41`trGT#z@YMqTwt&AQ;A;eYoq)e9 z;2Q;elYrX=+#%qb1^hh$cMAA60pBj*I|O`}fbS9Ty#l^Z!1oLI0RcZK;MoFxNWkA0 z@WTTBfq;J~;70`fBLV+dz>f;}_k!( z*Qo^DAmCKMjRI~Ga8CjE5^!$;_Yv@t0$xhMOAENKfSU!pjDVLF@NxqFih!3F@K*)= zH36?6;1va25pX{NuU@L)uYdacQ7a4b2Mh8C2=WICcohM!D&VyR^;UDsk6V`i|9}4< z?14m*MEa5bB$*5#DI}E)B!fsA8BEg25HgeuBg07s89_41NHU6yCSynz8B6@|=SlsD zOly-mh$VU$OVy~2*hnkCQ0{CEi^B+^x8M@J4L8s`a7ypOJ?TAo33{J=L0V$#2P6V{ zzl2NlE4YC^gnQCQBoh2`!9 zej#13{#Up}e}fz7?{H80j3j{kLH@-4jUb80lZfR+tWU(&iO7+N*7ZZnlCdrs>yoi9 z8GIm?2V!|3mIq>a2=WgF8wxfQY$#v$q$9ybf{g?liF{dzvyg_N=Oif+9!5-*A~GQg zqDDkPv?X$RNd4d~v7Hwp10oOVjmQI$4=stvhqi)BOa0+yDFS6#q-1ym$|{G*gvf)I zN92Jhh`xp>2$2u1fXIioL8+Cb6nGotRS}sGc~E~u9*C;Z07TVjTjZ!BrNXO8k=U>5 z(m;45YO0AyMr5MFh)jrrXe~rRh&<3Q9!T4fIv|6P8faZ<5WGFgtS_a(J75nRNrT}X zu+#(*V?MMQA|FHtNDD*M&v_Nq%P=@fzn8L7u27INJeC$>4;2-O3YmG(mi@j0}sqi&YfT4;Z z4CA62+QeSx)o69Jq#FGcJyz536Z|?9Z1@r02{~$^eh(Ugp0ycj!4tsi7_#8WS`))6 zX@C}Pm@LgP%r~?#L>k%~IvP3|1{kso;|x;_ei+Ms*xC;x*$+MLhw<)*vAonks6;K) z6P`_n(-Ab=FdAzjXk+q}Zbttt#+t4409lH38(j|HPFKQr(6#V$bQAnM-2%Tr&%m>J zS-a?Nx`*zi`{;gpfF7iW==<~o`XN0+KcXMgWAqbxoSvX3=_z^|rFmk@P4KgH7fRR% z9pEKNAQEyGw$77BM>vtNokTywR#%W-L5>^rCe5Y!^ftXq@6!kLEBc5&rr*+|bOrr| zZlK@O-|09yo=%|UWI{X3a(%f0)|+TUxslvhZX!38o5{`P7IK&zF1M6h$q{mE zxsBXbj+EQU?d1+~M>$IFgl$Z;E=sM7+UlT=c%+SxHUMjhb%}C6IayAT2g+%3x;#`K zE{~8$%9(O$IvQzdnkA2uC&-iJDe^pdfxJ*&EWar)m6yva<<;^#@>+Slyg}Y1JLE00 zQ{E=;kax*@vM-h|V-HQ#7cIJq z$dg`2Kbh!f*jp35A-h0s$~WMzK)EQvla`0_(G#BZHu?gucx!kB3sX&hx7Z5(6FGLAKlGmbY- zFitd1GEO#5F-|p3Gfp?oFwR67Q;pS3v8HOKI8$4wnyHJa9Zxf{oM}1mIp`IrJX8_#hblugp<2*MuMeTmyw-ai_IelE0o5+iq(lSg6{tK^5vmEb z@s9Uyh15{#Je)I#QQVv6W$+spM*{zZtWBAbHwMm&k3$ikskFqgSd6cW+mG| ztxI+-d86bR=witnp5~YASgLlZ^QCr|a+X>NtuN(WI=u9O(jA~^C?4towJ5!>^zhOd zP-f}fr6)sEO7B6s2kCI6OOWSnXgy?yoX{d{Q^hyLmjp|}hF}baU}LZ;*dy38*eke1 zuy?ReaLM3O!KH(JgU!KZf-S*igUbcK5?ns`)!^5HUk|PjTrs#(uoA2W`vv<4R}Kyc z4h*gmTrD^_ILG%p%M;7@mZz29k|9BOY5BPU2W zX+}Bg>)sI4bcWerJjaYDwVHPsZy0nF@`RN zK88d?vSE;6T%~sm>4q7V)*6Nzh8ac}G7V!4Qw>h3Vx>if#hC4@P)SLIhhr|LN)kMr z1W+TQ07N$GfyhQrV&3&q9>7~6hquxn-U>NNA__ocqoonq5LKgQMAZ-lQwySCivO<@ zEvH!EWh9A~MEsv zE+QMw5(8*`WiY&+BGZOSeRv1(#$ar1Fl~w`n0CbW&6RX`N3n~aXm_->m(l|sgL?Xa+3=q4K@*h`@L1&NhY0y351Op> zfcJ$`ltg%vf^%%8A3P3u)09kj9P*|k3P5C|LlM~!1=Hb(f^l9ENJl6m;a$+fBN15< z1=G=pf@vz+ouv$f50X6TI3*1pk9YV9$|!g|%AABK0OzZOPEkg~yJG*QA(9Yz(iw>G z&WBdaLWI3W-Z_W@Xg4g)Q^vr%A;$tlo;dIDpbM2Ocz2xdE>_0EyCd(Lh_JtC_fkYQ znhIqi|7e_ZWI>7KL&GHOeLl`U1L%6Z4gzpa=0!Ik@}fu4mQ4!&KVOIlbs!>$yyzB0 zY%QfuM3k;m40M~a9&W(??ojYy3=yHb5D`RPbPpmgM3nAB#I`We1K5InstTal82tf= zyy*Lgybw|P0U}Dzpzb5eL--lg{V^hf$cr9BQ0x%i^=zWX^7J1PJh`i_yZ2y(A6TSo6KSD$h zdC|v+*jh@zMMMz=&?krjaBK;EiepO<1<)T6G3G^oM&yNv(q9o#`n&RnQlRX@nd2^6 zmJ$_bkq}WOq!Q9_q~SPsv>;xL9FppZ^#;`oP7zB~Ml4Yy;&5t098NvdeaOELxqXq# z4EZ958CnYNt1iVFv-&D{8TB=|1+hfSB9>@5^#Jl5Kn_2w@rV3C{UJY;><=x+dOvkJ za`>x3SYKJK4i7*q(Llr!t%5k5Rz)06tEt(@pN-sBRPM`Q`>@vtC8@Q zh%x&k#_X*gN1o%z(HU!4j9Cj&XRKpO5|%Jqp%%6jj-_y%7nenvfLyU~%xLg%+EqP` z9H+6aFV-YNeX%YP>Wj6B&=#!kt8PJ#L^T!blhlFmeuyR7A2F_@AP%Pk5Qozgbr;&Q z4>|y4Lr0+F&}oRM5l}XceFT(^qaOifBF*%$#4P&URu1eA?Y5CLUl97I6)9D#H) zMn(jkqLzS9RlVWUR3G?swIqCoS_(c>Ee)Tg`oaCMoj+24q?M6YMjC)L0BIo7K%`ZW zRzX@7X;q}vkh0?)gme*(egs{t)_^ZjYr@}DHTYXNN9#Sn~uOMh#>zQIucO? zJ*FPP_&9=baRlQ5#}Jb7X^xEsPxvCF;aFztJmD*m;}TvqGQA8Zbd)-mj#mFf8GoXT zKT*bUyhuix*0Rr z4BD5B#~zHw-knBUPooVNkX}G~8r%Pbbu7)sYmm?}>U^4okx!6+A)SCIf<9IE;tFY5 zYVf0ezJ7kB4h#ORuW3;l6s^*X+Rp1nxstS zrX+||$9W~Yf>{e!a+!}HEy+%(AL60hN0LR-PSP6Zp+iYDiNzUd9L`cZz&qml$QE4x zz&ig+#>>Vl#;eBGcz5ka-lXfOxiY(=Tc2OiZOGk5tURqlYGX|u9@ph@UBa&T)5ypr4N8&trIQK}Bfi#|s@Q){%P$U`2J(7$nN+Zc={+|AFNB-zYK)OH9SiqA~bm&f@9*R)eH zESK@0!?D(+j z@$7i8-UCOYsJX1VeAAUW?qMTDEGSD>v6Boy#e=z+*uuL3sy^ET37exOztDOkK#U>`xx$7+{eN%1zrxk5_mQ6THy7-PXj*-bOqiB{5R5; zG;M}9OPiz3(-vq8wZ+<-+EQ(~wo+TIy`!zw)@vKIO`1d7qB*r~+74}(wny8i9niA1 z_q7kSBihH>G3~f^Qai1k)y``dwaeO7?Yj1vc0;?VC?GSVxJLxj`i_Os+ZJ0saA4m@~q_L$s3cilW!&8PyTLz zXG&0tUs_UHR@$DlvuW4TZl;wUTy}8i;Iv^iGU{bC&S;*|CL-$&u2uP~s;sWH zy7uZOtGlnh|Mti=lh$ln^ZuG+YtFB^yyn+6f2=9B*0R=bZR54=*2b(|u=ee>>(-XB zwu+62ZEsy^?Fe;(qM=x*3)B@#fO{BQMNN*y&iPVntTj)FJ3G_Ym2eb#J5VK@{&ulPnHE%Ohvurk+cba#Z zcboT^_nP;aUpJe~9%fIozuC)N!t8DKF_$!#GM6^{n$6}i=0tOnxu3beIoUkGoMKKj z4>S)lr2r;u6+`yf3H*z;|_u%fu-J81)_fp(T zbNA(L=3a(7!M+xjTA0$JWn)olDoQ-ayD0T3N=p@`rHfMEqSRcJvOZWx12LH|1cS}IethD5RT^SOI*zZuWSTRcvWW-;Y)8jpMNI4qWN&lKiq!_OU~Rlh*5-fg%q|pSXLa?U`cMO?A>L`N5PQdE z-|n-&P^d1(KqAI;B1Uu~Msy-ZaU#ZXB1Ul{MsXtgG!f%C5hFPfV>uC{IgyWN#txVX z@AVvCDf5=y7+H)am5>xY&vbbO&2nhS(2wX6u$0^LUo~fP<^NY)DU9lAk0}_)@Pn6ZE@#BGVYUL9?#FJTakCI z8!;1Xw!VisXB+05U3mTP!#tCXIpzb*FCSxWIe{7BjP9U z`7D-qB7KT_?A9$vH>2hqSbG}LGqmX$TJ{v|Jw&&#yb*OcQPVM$>O@Ts!M7rP3V(_g zZAZEt1vr?8gA-|`X**A@CHl(z$G52MbgpH~IF=S?{tv zeazEG@M9PYdC0#5{uDJofamiZEPcqu_TmwGdMg*(@8Vv+hc%}$a@hJW_{ez3d*czd z{0i(EU-Jxm#m3Yvh_!Dwyzp3AN%k-sR2!-Tg+g_qdQg3+0n`v;uLI^RFMAy@XZhJH zjXB$for^PP+p%+T=4@MbF3!BL9=0u;QJAxBQ%Pr>rT2%z@NG#F(hPiVjmO`tY0 zuHD@C;1ggMGNQL{Qt*KJan%y~rIi}+{@@y^rTe_zsae)AY(E4#OvA8M818Ed!}l@a z_{{Ih#l-?S-TO&793bshWx)gkmGZrcHj@;QdJ7Y0tGCxc${^`Wx z-yceY2Jri)(!tXarK99@Y+D%b=1aS=w3{;)rIS6J?%@&3$)a+VM-=&P-Vsu|)JnXMCE*ojCljBTC6cpQb}Y zprP1iFg|go<7lQMA6qjN-Wl5sE2^h6me@YBYZ)21MllL)NkTizRc6PIxef1=wV^st zC{!1!2i1ofKn)=_Dw(sqY*aF5`Prys&bDErk~!OsjY{ThTQ(}07uLhJWuuZg+m^i} zGH2VecSYuGTlUV#+QhbH?~eDAQ}}oav$wQI*xT46?H%o%?9ujEdl!3GdxE`(y_da@ zJ<;CJo@`IC545M*)9q92)9f?sv+Q&1^Xv=k3+;>TZ`zmIm)lp`SK9*|RUFkE)g3h* z!H!yvI*z)I`i_Q<#*U_r=8iB&OGkvGjU&?0-qF#~$r0^{b#!rbbtE`?IC?qyI1(NG z9LbIp$3RD#Bi%97G1f8OkyUAuV~S&%V}@gvW4>dt<4wnM$4bX)$2*R-j`fZWj!h1S zV~b<3VU1yyA=bIiallbks_%?(uCuJSyldHD*=X5hv0EIL&6X{e_bg7!R?9ZacFPXS zPRlOKZp$9aUdukqe#-&NK})vfkmY^LVao@W4=qP5A6Y)O9JL&?d}29nIbk_zIb}I* zIb%6%IcGU@{Q$NOWXNB3^+Ca@{rn5_hX|IW_4+s@KfTzQ8Okr zpLuB3FS8deG7PGaeq&hPh^EsAEq=0cYShSBIjurQ@JwY*=U$J7o}bZw&gmrA6m|BQ z-sMvUr9aEKuxMtd1JQXgpY*>v$T#D`DAUZIGrwI>d->4Szr8bm%%rS!6HZT)-~4oL zemA*K-|-VCCuN)&b9DaC%Us=(dRhj3o?d!rtqJufwqJH7X5QqS=yTB($9_2B$+VHn zCeOQ=^yl1$Q4e~Q={sx0u#x3se;;$C)0RFZqs|Q;lU#YivDn_-q|uSn-Xo?{7ylR&9`|+c&xt&z2D>7Z51*IZb0V!-IM zq=lKi7vZMPRs92oMh>5oc_!~`OoQJ;7IrbqLh zE0Zq_4m$*6U$%=G4|e9lRh0kqlc2dcR=HX9hY70-6Hy< zF5SCj4#42heW!~lJ~h5Yx6R%9_k62wYT_G--zRoTzLUIoz>L(<>8}r|JaowLni-Wd z7mta|YMa$LD?V#M)*D$Z#!eag(KxS(VG}cOE63w0SyQ`C_notBjx?{~ysPs)7wlhn zcUi&m#w$kl?d=0#`V|3k&9T~$jO(PqRtTaj; zb#v4YquPybG5Xw?U1P_M?=hj-q?l>nPRp7VHfQFXBXiHreLQ#Wyao$17Oh-7YRULz zH_D6_hqt6fezSF4;3uIu^lG=8;3!xnL_$h@wuOF4a9SMyq~ePita-1|EKv+@AU z$i)$hCrO!@i!(_k?q{}?)Iyo4N=j0d5^xVC&4SCAq2nI@Vho5q?ZnX*h9O?K0C(=^je(=5{h z(|pq#rrD+yrp2Z$rX8j|rd_5(ruR)B;r^NraevKK(>C07bHa4WG}?65blh~>bjcKH zs){>vs^Tu3s<F1w#=~J5vyrgRmTA3V|Y^NT{8u26zqd z8sIg+Yk=1PuL)ig%QdlF6U!R%Xjo<*j5Gvk2%-?gbr9DmjZO zUJuLl5!XlB0BVSJ4UslN+6ZYF(lD$KL*6jH9Er4@DI6>u%i(B8IF?&t&s!pIOYoM+ z+tSnuihv@ac39G&U?>ENfFhxGhzeWJS{}jwBH`^!t-)I(e{1m8Agz(VHFz8FHdt`1UNS2*%m%#H~geT=X% z#+;2X7PHaDYL7tqY?QIF#>OCXMpz!^jI$%lMqlChV|&cDV=ZFsVr4RCBa`h78<%WU zvJ#jV#;hk;&1`fQI_nP>GiUw7TEfOD8c3fCL7dm@I7ZP^N zSl=?v^0QLd5oKkvnDr;i!}^f*7<1NFg|92-EPvtafNjTOMp&)vwaT2eko6&p*(=UxrYMmd`Y*ej^8Uu*F^ ztX4MS+9F3oh`j>ZVwts@l@Vz&lfo3g4Z$)i$Bz`}^drT2JqSB)e%x8UHYoKRYDDXa zWHneD@ozw1v6i=1^{e7n*3aVChm0c=NLgz+tFP5;En)Sx`dCX^OIb@>dyrnFnO^|@ z@7Fa*Flj=Xk)9-wR3Rs3)1+5F(6tpdfENEBIzMw-v$AYMWP6eF{q6=aQ zVhiF5x)j70bS>yskWkRQpf?#$CXyM|XIB3m*C{qwH{rU(7VBMHlX-wo`Rr=KN?e2P zZ?oBI+v?atZFOz+Z1rsoYz=LVY>jPAY)x&=Y|U*gY+<%=TT5FjTZFB(t&Od%Ez;J` z*51~^*3lMa>tyR}i?+qsVr_A@F1C1ES6eq*f~~u)hpnfrm#w$0kFBpQ(UxTEXM2}y zAX~`}Vkeu(7C%FkMgEKZm-xTwzpl#JDv~QGM{-q%YCtt14GM-rpjwa>vO%?>I#4K7 z7pe!a^c4C5 z`VsmG`WgBK`W5;O`aOrbK7u}mjzY(vPoU$_3Fstr3OWs)fzCqbp!3iL=pu9px(r=` zu0q$K>(HmrXOIiJ0eueLgmR!5qlx`|YZMm|m8dSR|ZIds%nn5h>ns0Pv=NPeFVY;&@{Q&8~ zT%&6Tl+9BU`pSg9GNG?b=qnTY%7nf$p|4EnD--(4guXJNuT1DG6Z*=8zA~Y&Oz0~U z`pSg9GNG?b=qnTY%7nf$p|4EnD--(4guXJNuT1DG6Z*=8zA~Y&Oz5jnSJ&K7S2EPC zDD8uE2*lE%Md`4jba+vkfixRp+Z`%O-$%-}J6x2qWwt$A9-3>D>Khi*CG;)aJ+ln= zpRJ^;=xX{leTS~W9VhGQ4|F57QwQBlJt`Y2|41*>@91^N$pkOEjss&jg8&n&r1BF6$p?Xk#r~%XvY6LZgnm|pVW>9me1r!E_ zLoIWMnAV$yn%H;mR-)nhh=!{&8m_BoxT>Pznu>-iDjKe*XtJ7w+-gyK?WwJ%M|7 zcv)*KDQ9hoyS%&N&Y8BjJ{5~N7JuyeRXk`*T*YE)g}-)WoV7i!EAO#(?Qt&lr1kZL zyK^>1`3>+N-Z5r=p9Rr7lPkr9PuMd5yKW8R$_`zc)TLj$MIQZPlcr>i9qSo4c}Sg+ z88Q32bX;84s-={(mbH3CF`v(UP7fAm4`Uvi#Qd{S%yVOycTFy5UEb&0*rrhpqQatD zU@Y|Q^nNEp=dqnvcD~qoO=y^_QC?hh|LD=tVXlg~*`X;&+vhHi-WYu@YHM_VSAH&y z$q#KD(>i8!Ou4$oSW|3dZ1>m^u@hn^#fH1IykW!6#O5RFm;WgCNvtVuO2kEoD_zTXjgHTZ|EAl8u0M1w*==6e+TCp3wswoa{PKOb zpSzh7Dkmf*M7TERMYta3eVtIDd$sPagaO^ZsrRg&XOCt*TDwl=9_!)i@f6Xk`2{^p zJ!AV!so%HfM?DwxY~#9@+ps+WaHmbW~9WVc66oZypgJ=mK_*AaKpfd12+%q=-QBXbI_|z{L`Xb zj-0r(s3sX{Yt!Dx(t^A;F7MnZ*Kc`IgFCqn=NuV)esId*SJIoM4@@7EJ|n%8OUVsQ zuQg=IkUC9I4(a5&ocC+`kfEJiz4JS{-pD^OwBfJ{!3 zGx(C6wyw3gzN2DY>+@q>2lM0bPW-I7C$2L*&56UiL7eNg+&Ii6%4l`;ywR;&ENjul zRVgQG%w42a^SZcJLC5nRWz`C6H@4H*c-Q#cc$XvZo3V!Qc(mulxYOgRg?DvL&bcyv zUHF&d?~W%Ey1HiO_nRQKJUPKIF=Aq9%Wke99L+X)35agwjh)mD?-u-h|%Hm#3~-nAU3X)Ol0i znYt%t*VH{zKbZQ()b6e(`IV;io3?FQz_bshJ(w0d?aZ`u({iTu!2b7erRDa(J4elk zC)1x!e`Q8b*O~nOGkUnR{9X}>5j|YH@_XVvCM}}#%#@h}XKtA}duFLwcV-67N}Dxv z)@Kp7XGybvjp#eOmn$Xjv)OsG>$d)F_WPl|UE6bdy9VTb*!pDab#wc;Hs?6!e>}g! zg3$~5xN7BxyX2g+3l1;%Zb3NSjjp|s=(>`d=z5&{)}kki%!?CUA^8;+H(2u764#RP zOMZQ`+*?Vm-}2`zT^e~{X+PKK+%F=JE!*8IV0nL6L~eiA>v==kjcRvmc{0Z8?smzp zWjWPXB)j(K-dRznef5=&l}A_px$;8$0WNEPi?{!H`$C7u9a7#&#e3*49a3G!+*DVo zyj0iXy!eiPt}(7Hz4n#016?HVBl0mhN{*3F$VqaFoF-?;S#pk?Cl|;?a*13fSIAXz zja(<65*N8aJ|{Ox4#_2XWQ;^4gCt8P$x|vJ`ADTCU#W~#R(eHxReD{jC@GSkR9Om? zf}|RfCWT0~rBJD!)KF?HHI$hNav-C(q-wYbY1#Px*^?^@}yhR9qFF*h4iKLQ2JW> zM*3cQBK;u!BK;;klm3*5!C;ULCWEJ;gu%y9%HV4#V<>BQ#qg@(bwfpiVhA);H3S)I z7&JqO!D^^&Xl$6MP13>)tqpAr?F=0ZQHG&fx;9LkBF&WMNOPrylGE{~wAJyJw7~J6 zW4W|U+U`iwwmIIGhG_3dYo-30UD_h;a%`7c8Fop#r3k|TX}4piV;Ie#qv#*>Pg+3V zqfUB}y6ERLkKUqp=so%c{gOVUU(;{suXGaqnf``f@|oo__>E&({EqJxxjcTM_ZoiJ zSV68RSCSQ3mHlLYxiWs;7${eftIE~nAi26+1HZJ>G0kCDg9C+WO=SUUw%Vg zBrlQQl9$OV&&walm*gw*HThHg0`YS>N6wRP$#>*?@)!6;;Y0ar`5XB=`Fr^X`6u}o`8WBQ z{HIKe2BT~=89j|9j6TLvMqgtYV_D-X##fE68!H+Wqo1*|G0<4m7-Xzr)QllUo3XaB zjxp3&*I3V3-`K#|(Adb>*x1C_)Y#0}+}OexW(+sBG`2EE7+V|L7~2{njqQx>jU9{~ zjZwx<#?HoQV~jD@7-#Haj5iK*4tHiaM>sQ`Bb}q1qn%@%S|Ek})A^QjsdJfgxpRecrE`^Y zwexM~JI*!Ewa#_U_0D&l8=M=Ro1Av1!@1eH#rdAo>D=nv=G^Yw;oRxm<=pMuy}M!1D6cB7D-{(*@lz@*fl5^+NU5P{N{C`rYAc~iJ*9!tNNJ)pQ(7qDN-L$c z(pG7wbWoy{&Pt3Dr^GAWloNmBYN1C&%{kTO`orEw)g$y7!uW0bMVcx9q8 zS(&O#S7s`+mAT4%j@}csP za#Z<5IiZ|V&M4=U3(6(sigHc)RB+J@a!a|R+*7_#zEmD6Un}1z-zncKKPW#b zzbL;c&y+tEPyDu^1b$QCgWnRA!fyy(#V<)-S1YI$)k^p!NOk-MpeFA955_(JweU-h zhH4|VvD!p!sy0)bf0rZ>qnjzp4+_N9u3t@9J!IjyhMJr_NUwsBfqX)fMVWb(OkWeOrA;U8Am5 zH>+FJ_f)64Ro$j;S9hof)ok^!dQNqzH`FiHuhg&AXKHQ#zW#~+N&fx(`}-&R5AaX% zPxT+@Kgd7Lf3SbL{}BJ7{?q*T2ObDK7?>S+DDeHj!+{?Jei(Qp@T0(w1CItC3;ZPT zc;Jb^lYyrKPY0d}JR5i}@O9%IlQe@yHCZ#_vYdzJsd;H7G;hsEE2)*zN^8EF zSu3Miw6a<`?G>%O_Nw-p_PSO8)85rK zYIbe2_MWy?+pg`@c58dJ{n|n8kak%6Q2R(bs(qrJ&`xP*v~$`8?UHsyyQY1rxwOx< z94$|~rQOjUX^*w2BPT#G*+kChC?(p5|yUTaC z?;hX1zWaRl`yTK;=$q|($oGBU!@eK*e&~C|_aonreUJJc^Zms4xbI2d^S&+Y;r3Sc z*7mmc4)!Q}XM2o2&K_^?X76tAY42_CYfrNGw-2zV+6UPO+b7$n+NaxR+GpG6+UMKf zurIPNvA<M(=pGn z$g#w+%(23;%JH^ijbokTUB^a;-LcuR*RkKR$KhX4xgek*u%Jpo)q-jTK?T(dY82Eg z&+Gpg}>yf<^_Bi{Off1Q{Sa{sCt+lFJC0AP>kB z@`6f0-jEMe5-J6ihI}D2R0gs@WubD=D^PjpRp>S7b*KVV5vl|!kP7)h{!nEo01AYv zKvkh?&`xLVz3?S=M1`=JBSK`0wK1icR(hCYBkgpNQTK_5d$p<~b|&~fMlbP_rR zorcapXQ6Y@dFTRk5xN9jhOR*DO3q|x3N#g(22F=%Kr^9P&}?W9G#8o&&4(61Z$Jy7 zMbKhs3G^oP7PJ&v1}%qHKr5kD&}!&y=pAScv=&+it%u%)Hb5JpO^_XOK%1d0(0h;* z+6rxhwnIChozO05H?E$ngVsauLK~os&?d+ZIiStZ7U(_532lY8LEE7n&`xL<#LC(O z?S=M1`=JBSK`0wK1icR(hCYBkgpTAiauHmWkRSs@AsI44CddQwguI{K5m4r$` zr6FI)43&W_P+6!P^a@lSdKG#NdL60&RfH-*3Zz1Qkbmy;M@@y0=V#2v8RlofRSoAQ zo(E@*&-4DR2=98&^S!G`#G9~l>Oyw1XcardCb%Y3c!qvhISU?SVCUPf;*9%so|~Pm zJ}>F-MF&wgd(UUN55Yr<&i#X=i@bosb9XDwo!KHg7v}gM*co27#{Cq$2Kfc&{sf;a z*uMx~E+MUyHbv1tD7q+X;aLc4`}5B#Y!&-t@lXmeT*l{%brL&=|EFc2H^}B zqEA4nQVtn{_OeeW8Az|<6Uq*WeLDE3HQYm~qi|+KNCwVZSPkDRxnz{|i-ONr_*a{k z_y*SeU;q7}+x913!!2@~+#z?#J#rs~;-|ur5l`>A!0VInBkO-wlZ4+{Ki^^lAHN=w z7cY&F2SuyArIH{aKe<3CTv?uPGIH3*P5@ z_ceJ;z9H46Z+Xo%rC_NRO25Qw@G^M+;~LKLvV*ywhSwm!O07`Z6JCC6UM|M5(zYln z+TnkYv{53J_Pp)ilc(ed@+0|)Z{1PqgeN4`GF*|OrS(!tL+O9q_Vc{eg-yB0YxtG? zMt&y)@dT%#Xm6U7E{#BXO&Tukl*$>(|Kl3&qf|VR06s!_z-xG_{6R)bc&;c}iRC)H z#D$3dum673ZTqugLjU^~krGO&|8t+S&pc&#Y38ERyp_`b=h8|lr4MFdY-F}QWvGxAPxU2q48f))4!tU`Tt&2kAFU9}O zj3$3Y&Hjr1UTM#B)mIuTO?fZG{Z&SMQPfT8#v^ux>iHIbFY1oZ>a1_O{8eh#q9{R0 z;E~y2`NyU9Q2LyQQBAOTNL5E;~$or#LMg<^(rc%Pf?nPC#)3j?Q8$A z%zk_hNGjTXkkbFJl3xFZB^6%fka6UfW1RLYDkn`z{;R|a|FFb#WvDV7Wd#v-wImbe zO#kZ@K*&s8T)g*xH=WH(ouW)rMxxXi%8I|rn)O%ocguR7Zw?{jY{Y2yF6)Hju-D9xMP#I@k(?YUkQ-$3fkKk`0b_i53(&m|AyLGrlg zbHBy?Hs(DK@=RCS9Zvqxk-I$S*W4dV-l*dn?%yJ(M1JG`JNG}i7x0`l46MeQ23CFt z-Um_KHBLJ6xD)qap3}*cDwuoZ-tE_Em9zxYp;)cxunlxZay>NZ_X|6(1yC|?y%aKaJFRJXsx zTKrUh^@Ms1HQC50bqB8rPoKfR%j%_nwdbs=P5qSDb4T6z68DI;{Q<9Mta_f;gD2tO z-);5Qzq&u2)oAq#lxQVm)N?O!e_E(vsHHZZ#B<>#*3wr^RDV*R;)9e-uJU@W!958U z`9G;B{ZwY}uJ}F^D?E7YgEgL{WYPM2JiUW&NoC?gzT->Z;G53EQocv(NqQA6-RJ3D zxgn>Wi)eIF`WY`hme=_ zl_6zFAor@=KjMCr`&Cm}QkGQrVs7Ie>Q#=sLe6@f^D0kXBW=Cgdw1}DoxD!of>$8t zyw7-7Kzi1@BB@B)`cxv7$VYIMob)+`XOgnzvp#;rpR_C4p`;(dy}u?#bK-a8Kc$%6%Zpk;oYCSqgi#jO9K~q3Eyi|5g6q-;@8$Igyt);a@9n z5?Wb;%-5ASmy-oLGLP@!YLF0O$2aCUf7Gr0&-VQfsjvLN)1PO4Ie8< zkRE?2H5}tt{!VZ|$!oiUJ1_|O^rh5xjn{Bhxs3F)mr}!Zz9%m3H+XG1xQ~R8TmM>Z zcXTD?@fvcKn@Df#_*fp-$m7mB3v`|J{y%la#_eMy&U| zad*?dS?+(ART}p)v3Kz@YFVCI)N(w19d}YOUIF)0v6fU;1ChSWe^u2*yruxP%1f@P zn!1?RR0DU2z05trdmZi#W4%`sccQ)Anrh)5H1;{Vwi^19YpTcVsiW3?$@SFd^)$j= zdoQ==n(=xX@rzO8kiN`+@w}c`waZJc zrz@|A-Cg-I_lA%@D8DvIQv1K;dIqTLcuoD(92UpZRL;+qs|T zeu4W%?s8?8$BVlU_dxDdxrcFY#k~#pNbY^PCvi{bK7{*F?!&kb=bp)ZB=<4gv$#+G zf9$;nU|Z$YK7Q?N6G|9m7X(SjXzauZB*7s8$ChmoFFcYk71@#<5nD2noH(omN-1qA zr4&lbD$ufLffgu~Rd#_wTUN_Rfv=3h$0$%bNdC`x&pB7RuO&-%X}|CL{ZV2)I_Ev- zyyL!mUGsgC`98&bf7N`SX1>2}zOOak*O~9@&G!xFdz1P8qxpWte7|bG-!k8SHs5cX z?|01i3p45F!}>Y&-Dtj>&3B9WZZqG@&G$<4eVF+^!h9cPzE_#=4)Yx`-`(aritqiL zzB$JjOwLIeTsvo-!S!>FHF*4-6M*|VXPfVf%=fkC`+Diy~rusmT~sBbn`OWPrNjze)}aj|5@bR zu|tt_C;sl*f!+vIzUnl;;;(mwV zosh%ZaGYPj?QZ#f7k=OKRDY^#VP7KN8SD-91v~qbsd%qjjjCH&r{f$jf6mM)d+fa3 z#Ieq9yKOgNf`cy-Or{dizG$pF*dL3gKu_)I2@^lo8C)F+g(Hbzs3+PT3nrt-MufjM zWHBL|h;+siVN13z7D;u6yMoF7j;?4AJb{65G#TpXiIDwRf3G-2aBE#>Z(lSXjKsp> zNEZSe3#FoK;bTK{AXpRai3HarqNzwQl!6~Uu;cO*2xXcLJAD)w3a)R-Vqd%`tYn6c z+Jc?Erca*^of)M|x_Uz0$r-+VeA982Fh1q@n=ymq+*i5;u}+r75V&Y85+>8oDqRBm zmJ<|=OGl(T8Vf?pE9h4ZNx#vC03r=9dx7Fc9 zkmMSxg0WC<#L!)+ZdYfzz(^(;N~IEbJR#iLnbszzO|y_hFD;uX7LN7~G6i0y2z(zT zl8xt@%I;xLBu24x!zr}JO-S-PL!Y_nXC!SIQVeP5<}GPEAm(&;pf>LaB_r0uh;@cc z<&THzTkL&I@Gms@*>zYf-#+{JjPbsB(z5MOB;tt*)P|@#rzWY2tgEis&({@C^oCL> zc?fMse^(hP9^exKr5*lSejxmmJT@0;VzV@jxccW*ajL3o#^A3Qe?^*x-1c)`qx7MV zZa-5L*(ieM=2YQ@5O8!!deGLWmxdLNFwfXieagt{laVsTgOb~{q{J#+k_tt8e5Jl} zqsd|l8#+s&JV|#tQ8`l0* zl1ZmI7NT2bER`S?$T|; zEh@Vke@$PCY98%^p~gwMovfZvG8N?JS<@s7t1r~KCOClbt4x0^%~BpW4V1uK)YEh> z2}$^_L?lARnu@WoVv%(gCqu|nCFSBvt*r(vQtIz$*nz+3#)UKdPT<+~MlwS)m;-T> zRbZa#1h+4Ue42NzcmmBT8nk0@pECH`*r9jk^hOfh5pwE}B#|fJV={=oZwjrxlcLtC z6S*B-ZDf!js?ovv9BijE9>d_FAKp*}Mw&?z%Ji4SX|* z{|NUl9f0rY_#4^39q^p5{=sSMy4vrko_ELIcMS2__H)4@Qs<6gB+orJT!aLFs(Rj2 zdp|YAXIrivqrq4t5=I?oN~7}7aWMVE_N9lm`E6!vT~kY&&1}!g4KxlG%)+awZ>k(5 zSl!gVw0@B1(4N2VAkVXMGsBMRb#R1~=?S_ry%ADwM&Omzo`vU$kP3Puq+CzXl}R?! z(NwO9kXxryd!4P0UyBI?8T*;KUucM$PfcKDgTKO8v;Q3Ql-m5Y{+3yWXz^Fp`{D`n zyQ-<7x!%9h7fM8Yv3Sat?CgO&tOMU1L30aCH=*rqp&JZ!_2q^mNNetse6J4vGl5Y3~q`W z`kpN>8^n$l!{4;!UC{Ty(94yM`E0ruZlK>)`j^75VtkJf0`FoRZtx-IUsTJXd3S># zLc4h>+@Qaq%Gtc72EQM2wrn6hI!GSG-^-4(5%}KmCd~(eH2$CtONt-DfEgPz1Jd%D zK7HcYu@1gKFPjh?pBxvNkQ#g1m(?CFR5@?& zZT}NL51;sH$$KSdP1tw*Gh^Q?85pzc==VzQEPfBXk^DOfdHqA2rhd}-nR9`2GT!Ua zh#B%-5v%_kws-YC#U!tSFC$F|cZ8eZ(_iVPxZFC@EtZXyxX}n8-v)taQfv){|FGG}f8W7;-uc z=GZzyWBSgR$WEfUFs_2Z{+@WOoBqrk7`zT9J6B_bsP2QD!|{GvO;Go)o_HwbQvDe8 zritWgnzvNRevjQuL6(#7QoTYcV0szp&>510W`4TiGL!_${N@mupC&l`i~Zo=CLrb~ zg~I&E8U#1v(jzkMfy^Iugu*^*a;8tEdG;8ll1wH~&s$m3iw@;pGGYx!kvFi06z@;j z{0x6c4P)PdLH=dP404pT#8g5TttX{YAxu+xnc;|Gx^e74I+!?0)twcZvA%>kE8jXy z?_hPQ!Z$UHK0wSYaDevVS^IRH>q}y0rN@WK=P)^8m4a5yXhmXbxXf2&hS0P`?4dLw(pKdJA2|ubQ2^w3`G&oq|E@^oxPC?1VL08GhVl87!h}=#N27tG@VOA z6t${yHS_Rkz9nNGmTD!C=~_vup$w4>PCEQ>=SOeylrNN`$x-?aSD4-rmWO<1#IA|2 zYfMXg=q3gmDp#f}d77FCM&o(y(X7Bw<}{_u?1Ax|vxxcTehYsSgMJZea>?|FPOQ+3 zi&_5&V?{2@#0!>7O(lz7wfAG$Gm%1e?$tR$x4$iOC~AnT*lvjkbu`UVuh)|d>K`|( zd-jkoG~L}@{?l*&{6goAJ$(xf_(qEd1|N7r0IwMVR5+RH@$z~u;Vwr)bnB0uP5B}*ufnq{_Tp? z-VOIYynf6M$J9>Vxb@GD+U1p3A6mBCjF0}b>C1oo$*$*r?{{bXKKXuNWpr9%$(DN_ z`OY&}Ui9MG=N&t-t>s6vzWLhQkALv|R(G8B!-JN;`^%X}Ke)Eu?FwKXV z3BsOud<_?ri5xcd`)Eik!6^b z%TO~bhZR1TBXkYguaocj$l&o z5W(4kC4&F;D$DQl2IJ<}8J`inUhq`G!v*IEzWWx-KP31=!F7U7f>Q+l_9n~UKk+aV zzZ(TF5IjvVC3vJ@jo`Vvvfft&V_h#pyVoNXF7yki9aQP1@Ig0BfaEBL73iIgEe$8sq8f79GD(wsY&rj9Z_?IOPN{t$fAXj~m)u<#OQ_@;pBHF57waOvX#U&A9e-FRgsV zRo@)iUFC9N(P^wdL-Na$=QI6Z=P@4heJ`zi#hcC@+Fj*xp-=K>x8&QO|A_5vxszN8if$;7`1?@)d8rVQ6=i%Y_Gt|9k$1?OgRZ z;}ySREPBXGD_?Q>14Fy3TrT{Eq{AJru$}*YiLv=b#_;oATKS59e|BhhmCJ>1%JZmu zkL}EPhw=44Gyd!iFRgsVi(enwUFC9NrR0li|IT)5K4CoguZ&N9=%tmfxP2aXmCJ>F zl0W}Z#QAoq!+7=<@&8jsrENSckGm~z(x=YyZ0EzJ4Q1;I?78cU-67Q?kblH zza`~Wx&_Yd|e zPSMu;wz#hntoZ`V&k*zp?r7mep})N~%PZP?r;2+@@TzTD{&c~0g3W?+1phjT<(61z z>+L4)Z*Rl$pPC2psq-oBH7&yKn_|47Vl-~k9glCK={LEi|B?Hr4oT2=n$N!`6@ThX z!n+?P6{jVL=NrxLTg1{oaieB>U1qaphe1ev({Ln-T}G)0O_>-vie1bYZKfi;k0{!O zjoFc4Z?e0r6H}uOHa{h>wHotZ*elXUTPwp@GwY<8u&(}|p7rDjt)qo}HCQ@rsciHm z`y!puu4tz(Lfh5U9b3zKBE8rsim@8@hrzr@(^~_(f1C;DA?Fpo#6SX$N+q#Nkp1<%BJBs#tLa6d@(G4(onax zslBDjkNwfH?$l~{;S0wjNwb=XO*)7Q#^=1j+LgfC;rduAG{DbYAYJ@q7uYKwnGps||$%Hr%`La`@`+!f&j(+p#>8B%#r z!kHjqwvCPqAhqK@nm*4Wx3scqS!;78lE!4cEE0}``P|ZYSE<=U8SYO|;?o>mR$1{8 zlM)?~gbx$l$!Iv@!_-4}_J`Hf>~ExX=4yXUpwaKE3Do<|9AOlhoyvimo@^L9IAgxR z>?TY#BQ23>ql~FJ;%U@~=8|_r*)X(A%7OAunP$?;7S%mRCO`Lp^i%f|wKrTmaL!kN- zNgQD@Il`@Vvl_(QAeKg=ol%O-+Grw0g}yh^8&6=$FHY6-YSfKuqn+8asl$1O_7{4J zUe5H)mM*lQlPz$V##=|l)KnR4k+Qid8bjrCj~^sGn{$32c8d0*)k$Q}j(qxro-{Uj zR5vx&A38)`s(Ck*=D0l=8O^Ej)BOS7%Z11QZ#Z z^|J^f3}`uM=?@PXEx+k9F4JV@KRC%BTXe>*|WC>4V{n4L#NAt$|vs%9(R?Zv3dn zL~%g;TwXZ3mRjSE^}b^xiFlfiR#1gq*}gcuz(J+XNS|~u9bP=ZIzk`T2)oe%gl(*U zB|CAv5!nvufmK7()H{xba}8F6C5UbQmIf0>bwi5b3={%?NPB=nzb=73ich-^UD$8N zbq?)$)_O&GR1YDatw#USt$QdMd~^^g8jqpuMon!1bq8%PdU&bTy%a`@Jr@%kPNMe1 zB)gMDPY_$&5^?HqcA*e?T-|(9 z9y4{nn{n5L&=KPiNd=Y5ScJ~}arvg_NR`WM!QoY|AI1Eikw$#lUIfRjQ+iPn4EmckJjcvoxmT?qSSh<4c5_%~B7J%~4HCj}TG|uagE1^=`&as_ z+S~j=?3-<GacTZ(0X5_m)5aqRGt=faD*y>S{^&a(BnFBZ;+mAZA#B1A+L2lC-~o63RR!Cx*!!pGjn-6|>Bq6J$WC>6l4vB(4Ae zn`zTT%I`s0i;gJj*v`#?G^c?O#d|13sI%$xFolECWAH2vcK3B4+N98*=!`gn{eYT= z8{V0MMC-4VizuFSepS-h^NfaaGhxwZ<2becMtU{~EIJ%?5NT@90PP_Pqn+2R>(|Z& zva=Lq93JPqNa>wT4%8L1mBQbYoN>i?QQ-7};+04$j+3c#UmeX7|`w}RuJun-_!{!5D$W+%#nsiFdT1Ix4wznFy zPJLY~T9~k}1&F>78XMFsXo5^1%WY+St3&9SQeUID57jeW{y-TYonb2VS~X1PGQN1m zEFb?ux7GBz;<&8Al?qdT+%y+vKago6ao8Gd74|wr)^ZU-n@01&%~ZGa_xie!)sUM* z>o6~pGQ-DNKFmkc@onCXWjb-NOY_=h(wdqyn52m#>Z;JhHZ{GDKARNIOj7j*KariJ zPbl5}si=4c%W8~8&rb4OqdPf|kRT;HqPPtu=3BQK zC4qv~i60m!H=)pQx5u4VqM#3{ke*8|Tu0~n3fFKPnJX?>CD2PH7cHhfNMsev+QiWb zM{`P!Nn|$kVbHValYWG&Lk=OCDdW;_`Wdc!H}%4#Mf7zg;=OdLv&?bbT|XhD57-TP z4mmCA@X56kN@A*pvR7ETXBn#_Xg#Poq=32duD{vi%A=hO|8W=`&z+h=+R}``A{wY8 zdV7(D(J-RO!Ef}6GQ;Hhkr6j+{6?P)9kW2SCpc&_Tg*}}RBpfwQhos%GXUJyE zgn5Ot#x+v}-3U3ah5Vf(++O)G=BOzFPz7O=AO;HM8DYWzVjAXSc!my1flFpE8Hk9c zWu_(3MwlrxlK?0#+(oA$wkIvzbTdY@^PW`+xz=qarEBM-83>va@VfCFdp0-CPO6xx z$L(op$NEw;DWK{e+vy=UJG;-x8xKm%tZ^7DZ;lgCCW+yEIBMf`8e*e;Mm{0AJo&>l zW#uv+;wBY@ZKDWb6y@o6bne_;@+&oJbNg<;7R9(NOW4JSmrp;!!&ozmj zYM5#aGZ`$IxO|$qzF@H4EJR?Ky8f1yrWRjoTT?UDSG*QTEwtycXS4^^<`fh1KUT~! zaNuV9>`rO(EB1?l0>HYqc0YI2$nhlZ$?K+j5N8c`EYJJjDgjiwW)H8xEfl&7rc zOg#)tkC}Bq+>JzoI5|$64(lTHZz$=|(wRK#HkYP@NoAVaJ9G}I5NABUMLsNNVYuGk zQA#dy5m?kT@DOwJ2IQgx6m>)*)ZddrErezWLvS;Z;VzO0H(mZJ@G#e#1m;}?6ldBT zZ<=2T4rbAKAw9#t3R8#ZL>U@!s`=9E@3f%rhOGjf4Q`ty&-6w@F@(%FZFRgSG7WJz z#@vRh6yeT{oAC>Yz-=D_8!OE;#|!e_RHgoOBGpsjBRl$=?vcTGH97-q<;fW+WxIS+ zwYuE2jU;;32#Q!yKF*2AE(^-4W(gYp1~S(txrU(*hj#NlyEJ5G$f+^QGiptuiNIna z7E?C8I)kJ$>QkdsXHg%2dSZrec{E8&ps;~P4ZU%!<)vsXk0ayw+Au?_EwdTUP=1l> zjJie0xYUoQ-aMt7k;jA!CeYALGYWWAW^`aCxKtL44=EbM$o6bUH;7=VQg^eUr;4^c zS*gRUYVoy-ef67Juu}0?q^KO#@M=B95!E(tOu<gYz+pNGUURb44rj%6&h=Yfi@)6fn*@y_xpp@ zf#rc}e{kuc!NdG5P4r-RjRxk(4Jx8RWmO1}UVW;a~Dyy)3l%beQ zyeHIwF|1p%sJ`IAH6CqkQ(F@rvpIqwmmQ#<8y=2LBI))3{#K22L*1b~Dlq^~RQyZj9@iR8eVwU>oIE`j`i+d4Om92iRDDaI5 zU@R+FwfTsP=gOBhWX>SCMj#BUG=WVcb4rtpa({MNS0HY5cv z@Mg$2G*$bRt2QdDs{E~4WS7=gHZBukmBj>CgRS3+dPc0%xqx~@ z+iKKV@lLE>BMr>cn+Xv&PFNOgYN<{KRQ<{@kSSZQ;pF;PGn{rU!cNAVrM)taaK%dN z+H3u&C~2~jXTg)c`TH)@bpom*(zeobU>Yh^o^B<5bh$fC(=b5jkF8IjW*?-Kx3^NB&1}L zu9TyF4OnO}fj0rrN6Pz|s6OkD@o&et<3`A^(40rJCvX%}I9Y2ceuLam6C`Vo-`BMI}qR;Z3b3OQuh&?X=ES&~qG| zzbTxp{zKZa;1xh$z-$RiXD>2j!bd5_X#siiLi%~eQ63ItGx8hqp1GkC$&dMav(?)y z2=GFX+pM97gN%bo51-kC0vqZ2(#zNQ$do%2xmTlnS)_FNoM*L93btMZC7q!*%4s#} z1{M<1wwVZ~^ML8|8y?RPXFgW02%S2z6+$diiFhA|9(D_=#WJHS=GJj^y9Y+ZC`Jgu zYApZi!mor=hos!crU${JE{(T$UpHkubeoWlgZCp*73glNF?mGlPIniSR*-IuNF&iu zy3dCWFE9Ths9t}0FBPv7vxqiy=tjoSeT$X4y%!(qkY4m75og+mZ}O1a?bAM%G%;yD zo_i#Lc^#8ad>zqlT2M5Xg^MT++YoPDS&JQBTuP|Al3JgNx|7*-b9$N@EmOp)79TV% zRtSwK`&;cN3!6j9V*`@6F9mtO?Czo|j5(%XOR0^jh@QVZJxUvjUS=`T2P++Pt^#<* zdNr4l7s^d9(uu1MG@wRF@5MH|$UKQTo%fL9 zq9U@>?hZ%kPGsHm!4t_e8=kg=bZ)8&RJQq19MR9AZVvQYBBuGLnGVxKm9Z@uYi^#9?P4N{XBP&WZpzq!ife4rlMJ+;MUOzc zSD2%qr;vVGLb=oG*5GhMy#jC22}#1(v)DMe98VjEi5LUZs4etp(gURHe=+E2?DdN zc?|_cwp2NoR>X*OfVUDSLQyIZC?S1lh7!EH8uM1!Wi+i>7|%114l~cbBA|BPz%KVy zt#yH#Hq0&adp|PM&+*6_34}}(2Ib^(&d4+`Z2A&9y_&g5NBPRvnOq(1N(DPZNIQ|` z(3W}@^t`g@`JnDZrQ&(;#0b*P$hJTOCKn{z(%o^s>Gl4`#Zq?}SNEA92nFgL)`XK} zBhbU-XgfM6`8BD4QPTVH-VEBblboS>-*nt6e4ZyjiEp;+QrXu0M(HBuC5KLPOH*|_ z=J~u@Ex6p@&U7?r$7G(#dt^78jGgI*_Pe#c!SdG=Bh6F(CeDR9GL=UMsgP4#p7&Cu zQgvm^p`It8N|X%TAx91|iBCg2jH66#Z5lgQpJYi2Psk%g*;wpRI_1yDY2jLbTV+da zg>Sj3lTaZn%UTy$WhFHCssLxtV9g#&7O^05o98g=C9u{jICF3&LQ>uv{Ft?)T zk*PF75?AVXnhBnCeHC(Re#t(RCRyY>SJu>v$NAPlWJStv_r^Y9+YBe2Qq9|n(0K3 zX^(rAJErF+;gxjvVrpOqr&$*N2R&oFLj(gRWL0;DV2Je4)4&y3{F0)pp}|0T=zQB? zR^seD*zBqJFl$Uz0$+4Wt4N(ubCidQBJxuSmbNh0$=$bcbo1 z##E%CjuD%iS_5r?rbeCTS3cHEGq_a#>fvj8{lvtYN-s^FPbjima;f1?C zXFNfsqr=6>x7?McS$(=JpXM^A`7sCAYIbMTLr@*$a)@ZYO+jh(QX?W z$eOl`anQ>sqh?8)7JEPPN&f$crA* z4{^(;$ul@*g5^2cSAj+kULgfgw6OVw&Z?N>QAmqyd#a@1$zCeQ+{@|1J|E1dkl$vX zSSck77aYt|!8cP0ns`y6MQ;gjtglCdMz6i08Hd$c{6V^Q0`rIq7T^_uy?u0ZE^QvcbUJE>l!wRuRn|5(wYCMS zf|&Pb<;-y4{HVGkXwCJNxRP^vd7W=olm(e}Z<>;-bqmb9nO@zP!&%*~jq zVjNr>-A0>kI?QPqK0!jI0kh+)>0~WkHBuoLOVj%YHp?BsbXV{b2k?DE4+-8Qc)Q?D zg4YQCSnxu@?+L=J=OcGtBQs^3Ji$IZtecq|ZQQjVxp*hr*-4K~>d> z@x2oT!!?inBRG7GRcn+Lw^E@DU8;*jXmxtlh1LUflmGO_rZ&7X#AJJ0Q#<{m5LDE!@9KDq-gK8rtor zWe;vY|kk zOOuf0WzWxa;~$p<*!KLQhKemGe+v;c*yQ#i9 zdvB5YGc+;lxf;Q>XaCUpllBSf{ZHs(;XFK=1MEM>w2)~RybsjforL{%=&WHcI-WS) z{*u`;nUa*wb?({zkgvLp5{%X=HN#-PYorrnLsT^>Gb|2K*O4#raJ`n{HT7|3>0|>h zn6?C#WBMgqnW#j?g+mQ^4`r;A`U++~KiZ2S8SSp3JwSM2VjLUex)E2eC|~Y_&IMIv zN$f}CteP(9IwyhQlk2tT;UTfxbDsIfLk~1HwAPw!va+>^k}-~o8e9F0lP0HaHT@Kk zWJo*Iq4sHin*Zo9U1M`7!0cx?aY3Qvox!*U3w18y7LIiE(_VnI)%34QHv{xxD9hnX z&*QM8nes=Okf|s>)Wz+pIVnL|UeA`NE%UFDtPRXUX)(9$glU#{G2Y&l`!kX?1j~N8 zc{ywjFGjM~VAgsoZ4G{`S#utsefr3N z>0WaOW>qN<;u;@xy>NL4uF2yYeYEw^efj9UCFukv6;;l)e0W7H#}io#$!F-l>6Rf4 z2QbBCZrLFZ3$b6fbcG(E)fRCr&MMIEkP*eneR%)6|1@?o^>hq}5wayxS~!}zb=#|qt5#i` znLn)V8Z}R*pW|+2?P{rssl5 zYqa~GL#_Ofa|9l2bJWyVneP2c4~7=(vFp>kMUHy3v`~WDcCZh*O&b^QI&*r@BR2Aq zS$BF0B?R?XH#+gO3&E6W*-tV=;=>2IH=U|&TDH>-9A?NTo9R#|qq<`{& z^4Zzf^pVXDpLzNeWn|egezAEcoD8nZ91|dx9qlb_&)BmI_Y1 zfb~8+pYa93`vtEOJVP)ks5!L=KQjL)9lJ2XTg|VDbbQul%f0N+Zv+p#kLmB;!`Laf zMDYH*nXht+f3ftp6Fcgzw4(AAm2acED{l2T`(GsZ*T%&?udfNnk6=;_aJ?Ulz| zhVDgo^6(aaZLnqGk!i0y!OSMS|8RuM=L}1_d|1+Rhb294Skn6rOM1WINLL4jBi%YI z>7~uXvAuNVaHOk;C0#iz>8fE#w+<_of#FE|YwCxQCRMGqtu?K~P{1X7!;q#6zcCqF zc;Unz1{x_3L!+uCe<|w1F468}>5|TMVG7E=W&37UH*OuFV#&h9x>D;3vDSsl`3vwA zcN67HCJkRAT(D^GKxfia@KzN&D9#W}1bcC%E(Ic=a4?xVe9n<*KlDu|VUUGHGK(VD znE4(_7DaySBT(dev_M7dFvdD2E;}jU5mF$_N17~_V&TbRDHfhAmSW+_0>$Ab%iNJB zi=|k2vRI0RCyS+6c(OooxXChaq{(6_7M?7YV&TbRDHfhAP#kWu>^stAu@nnW7E7`4 zWU&+rPZlT+H(B-@X|h;~g(r)pSa`BniiIZ&6o;EE^GBL2mSW+_Vks7$ES6&7$pXdU zCd-16CX1z5c(PcEg(r)pSa`BPaahSR(Az6L73$)cevbRKGTRtayIeuiWghn|12V7s;E|ZeJ;xBtE0cZf<&nuc=&~iUkG4Eg zSq43WhgtbF23OztGzQn(`7{Ps*x594)zpJzt$|4aakexHh_j_pK%6a&0^$sfg5zwB zItqxhrBOhfEsX-=Y-tn_XJ`~0XKP4NK%6a&0^)3G6cA@iqkuR=qu@AOi_)XYpqQIUs*$ zKZ`%P^8l8U2Yu)w+!Wq-gdL(oEQ8agCOLVp=V55SIbC-Gi|vie8k<%$0;~Nsc$acD zc=dr++|+~pGk8%W-oGUK56r1RvojF!|BfkEZNuBq<^RR z;HnJJU)zAofQ(xQoYG8fe6Z2D1-=Z|8v= zc8Agn3+Uz#H(lt8ZbaCGwwe+RpY~?h%Bk#6RB(pin^Ty7 zvtUYap@qsWTHN6xy{)+SWVgD7CZ|f^x)PYbQ6d|O}nDyQLB)c7lEd=xc5C@SC9SH8-ryQ11xRC&c08##W8 z%D45EuX5J*Kc8Ds$&a=a+g&8Mm*6l;BN*nRZ5lpgV*J^*6Z_Z>Y~0k)i#I z#rPvye~%KH^y#i5q6zKKla<&|H-e9E{K)if+wQ^1R9WOO*7skYW&)ZneM%7ck(z&og>?qoL zN{ItaQML1DWd#t|#@eQg-y;7&i> zG1ywk<12d48|m^pw`gp!v>|{nHn(7`FwG(YImf;19<53MPLw*{!5wMRhGrjZN*XMAKLacPKXEEt+j~o`?39 zn|QNZkbJ{W!>9N*BV9;_!bkjEpJSfq`ld~AiQtz7_q5!%x9AI>^Xi`=w9VgO$*F&R z7C$8PVvAp9(R&I#$>OWs|1{e1&F6oSg!_YMIsIN0yjxK9Zxs3x!LtNU6cYhA|J9F@F$-%enUYkSi$2s`6{{I#Ff?>wzY>_`*@Fc;t!?d$TFAM%|n06i!`MYxH-JFB3>3L-yca>ATP~^`N{F>nLf*2CY z(5|Scy_MdUNT0uBOsxFPG?p)C{y*vWT>fqN^D=(#tH0};+eCh|gWs+^e!KGc?aE_4 zkyV{foyzu=^823-PWQ?0Vyvg~9D?Kg)9~8naDM##Y{nx6-za1HMZsU>!Nc^f|K@FSWsEocZSYa{Bq`5@pHx3=4<>f zcspvG)E^Ds&hlI*h@ysXcj2r5wq2#w{y`#d$G=Ya>aW^gXvwQR8`b{5`}xh1@M!+l z^!c%*yB+>1B423w{JYctehH@?{wIaMwIr;j|0XM58oxIzzCO?QEWXD36XB~}tvCK@ z@iqTDbzII>Uh~~(;j4dkKFCFD{+MXl)#o?K;;X+q2w%gi@jpfC8|7;}cemtog~#S= z_$FETMZ-5*_?kW%zE30^nm!ti_k^$Mq~Uzdl2`ZFEWY~lnDDo<18mV6{#7~3$30?4 z?P~aM6TXJeGV79R|4gy3@zwM>UicbLeNLwdU*qW-w0@}lDf0YOU-`2vzWTeb@YTM? z>wti_zoGUHu;lf5RSSQjgiGzU317>l6>OK(aQ;)`tLdrX{Jx~KhC{xbI6 z`vYn}CH|^?OFb{C_H*T*mDY3A@Z0T)`rj<_n!bv5xyTi;A7WuI^ABd? z@|k~F5%m1aT-R|I<6uKSzpwcQgP532(FYm|lAJ#I~DAq8& zk6?|U%H8f~_jY%ANif z_9yl}7XvKYmR#d*NuY8s3*~0!P28C8^6Ip%u>+T2cA7zVcPhE$7moKC_(t9VzyTem;CuLQ@l?xBxzI0sh3%{RlR`fvsQ%qy(ciJ?RTiy!icg%({`h~) zxP#!UKVteO!3}}|!R-a#yo%-S75stVF@m*%y9&N@CCh*1=ZqbKm4ZIOPj6@UX9a&E zc;?;AUoCi$;Ld{oeHXjmD|oixubyE3HIFm?_A$mM1ivYGkVUK9f``5Gs(0K&%s=q~ zMx~DxdYQ#n_kR`D|CwT6>AUauhVu%GR=Iqb$f1{uZ`&(WPW6T>uX_J3%oUzod^;S4 z%Bh~p|Nd9}{B9Q9Uh?B`@fb`0NQ-d>xBPV;drt4@&_D`wSqsf(B|8;EpOAu zSoXe@$3I(tr1W&l-@D)Ec&a^(#~VdKGkzQpyxl^ZZ_~ECO(!gSJLmDw)*mUox8?6u z4#!jNX*}*2&-{x7PZA6Z`UNKo773a}^L%YJx~QnQNI$xs>=Chvt%}B|JfY)kwbfXs zSeKUR>^-(0OprZq>@ZSUb!2se5C)gEC}hZn*CC12br6<00D^_l>8NRo2~b=XoDId+ZY9zVk;1 zopbjyW^X8YN$*1C)mF#ZdRKlfiudor^s$0UtNSA1+j!gVthZKh7mHT+mv&=08v|3B zuQ*odTc$8yX>~tN_%=Q}jpff1th8u#-%9v4-aLo(75jvqA*i&vzc-uZZ9H%u^NR(q zn(L+2Jt=$}?_I?5iYE%aKu~FQ-(11+HdZcS{%FDL7kg=S9}vEcr`E8%VwKSU^fO;+ zb^oRCZTz&3 zIN`3hU$z!tczafwcgYp`1EX z_v@}?J8=uu&VItrh1-k!b62n(MU9W`e=ffI_c?Mpex45AbkKZ6?W`$}L+^`m%i9WE zk$~6Mwfag+eQTqMR6n*n(R~H8e4U}#v=rX4Os|c^J3X<@M)v?y*-XC7{*M%UL_Z&H zd5QfQE*>U&imHFk^K4Ji<|{o?%w<>kiW)9O^)DZ-`YLbZx1Zzq+3khN7g)#D{#V8O zELS9W?R#EY-H#Q%jhnY!McKf4Krm_1>b_9;HkR(j`r8SCO`HojlS`r%r} zJ8Hc2=>et(gkK}5^hpiuUMKjsdM~Z+cM0Fd`AsZ8TJY{hFRkup3*Sb~SGqr7^5Lwn zxalya&lFTz-B$?T#`5D>FL-Qr{CGX{pAx)T@GJ`t6g!H`#XT3kGr)FN2<~E`+Ie{$ z%jLpfi2KPFYJ6<}bMe)`&ymyn^K|g0gXW`m&S1Xc)j}^7R9f8~;oG?29JZtQ;n_@| zE~vD+A1r(uufK}*6xRs7o1oI_{>qgsZ{vTx%KVYynAcc8A08|I3>Wu%iR~+@{s%8I zU(x0(JyOhNSNVz>E=Bb(AFcW-Z{w}^a{LkxdvS))cRj>>rByB^d>fB_jO7)}g?{i? z%vW07j~Bj;cRtDTibwPZqw7y_;B1af;Blzs!84)jckJ8^81?mRJ1Ue=!{uR9fBl6uylg7lj=9DBdje zGC`%)eVp)Zd~^)kQT&?FdkQM8?td7~@-~*2FkkV%Cop}gpwjBzAbcB5r0`|;pKaRh z_sBTQrS1I)wE1Ar3`oX#1=k&S%RyAU234Qxlz5n6H6iR`ZUGoclgZ|f^x<*pRH;iB46RDHFpX!DgGDIR8p zS7{s7e?|4rrd3bf|8xSUtI~r|+^0lhI31S$Ofk2?r)fJs+w{~!r}onMvZ-}b8>Y6F zIaBAA&Fdk$bL!l(xnc8_wx+*c>vNo|L2Np3^Ohf$;0LV(%u&}Z_(7Lp;^3EIeU|jV z<(w`@30^07u%PWuHzF4mX~=jUvupo3$y7o|$i{6WOU%JcCw(>@D0nw;BmS1*k9c>N z)I|n-)&0GFzId0fJsC;(s^U08Hjwg#Qa=AcXQVF`jmIiz&BkeM4Ymdj^H<=f`Q40P z;MLSu*0vI}W&aANrF@QYZz(SqoGUm_a9_rSB)cE~t`0D^3N9tfu(x!jxC>SZRtmO? zT!0ZT_crqU+U^Rvufx#%p6v>!bw#zIYuZ*YHi>>UW0kl!tgLD!O@lsq<2H2L9LK-1 z88?TT*8n)Jf!fAEO`xh0FDoc5b@1o?Q20wK!(mKw$LTm;X3|!aOf4-hFDoxkPA#8b zRzAO{XC*lMm+i0g$`Yr&DxI$Qjq64b2z=U>F2iM{W;z>JXD-FHpFv!~S+y*PNaAWy zGv7Uwdu5L~ABc(VR=l4Y0c%ZRMxGyfEJY#942RF>h7>R4SV?4NASpoBr=&I#izH|= zF4Bz?ZIMLMSCfeM`Wix=tD~`q<}S;l9yXm$0Xs!L7towyp21KFWs0ixRMKQkPdt>0 z#=3pYajbrr$B~E^{IuLmKmiz<@aCi;o}Zd2pIcTwm#vnRSi#iHB)N6S990T~Nu-iV zu%rgV;vyq23{%@due+zrM__%Gd@eNTL9A?O$Xl|#6=5E##0Qg8OXu>#FnNJ9R>t?| zGM}f9FC#x>{-%CO=BK125G!qn^u`nGeO4tx9UD(w=QcuG1(~LAXhQ3gyw$Oq@l5_w#D1u$nq|&hXS~6(xD9EU)wDmDA^yQ)Y#f`MaRJ!DF}(Z)Y+6 zcifRur1Up;9ielGSbsU^`Fw6;HDxO zbSTyt=}FV!2>Sc0(=^^Ik;>HX?Z@CRNLyLbGR*6VcdoH{{W0dI`JM4tIJhokjJjbW zUeXLV+;B#Y!HPXReqiSg^4`Vch2Bw6X_b3?CziKyuRWQs__sZnR(x9MgGDYE+WNnl z%XSp+7J5K1BG@YUt$8dzQ&8yzLhmTJS>%t{kL9Ne{$^jMzb#lVxPyh~&1bnT!4-mA zTc~omu;>7`^V}lFM+KF>O6apK+$i)x4XpR{GREr<_R?nwoeN*+VEG+8v*S&9+;iy- zr#0{PwtG&Q-k>2lG$F}-IcNbj1#)Dzh$!^E4p|EaB^8SiU!1f0622Fy&D zxrw%*z7)hu2O4Wlh1Xg~FHP~fVS=N&sU7n##x~wA6Kre>u4t*G&3rAjfksnj;@()i zO0qtSadAslO-0;J<-co+D6s0`GwM|zefCv zS=ezhheP>F+nCSYmbYouKVSU2$inZP%HdGH(l+LEx8-eG^`8*`p0e=GZ*n-4ue6Q% z+--TAR{gTm*}rlN1M*%r)+qCL$eIxrf z$-?j4;^ixCqw3lGLTS~1T>N{|!b5(};ZVNPHs*7;iY2mi=K1t;(ZDT%n zTi&Kszd`(Kw(!{pI6aiFw2k@PZF!qk{oNj9|Msvj_NbSyw2i7~^9!X_{|@o*E(^aP z?+I1D(l+LEx8-eG^$!>Sj& zp?sxn%;#>)+qCMxBmTW-;jwQ^{t&*>HmaV@FO*jOBjvrYt1KM#K8Hj3O52#v-Ilj$ z)qg?!d)dO{Kjv^KUuhfjx!dwKt@?M0e|KAW#6LJ3%2(RPeD1cqO{@M7#J>wHJlg3r zLrmo>ZDT%nTi&Ks|2pySClCNrESdTZp+)W>Yp&0{X5CRJI8tXO53P z^&8~9-G^9s?p7QQF+nCSYmbYou|6U#Ycbwot!9Ue9KNqe1+eGe?&j{7-aB-FRe}IJ(gjRg0 zhU0a+h3yt?yDR;=->d&Cp)a)fDt}xKzPc|EcgK>;7k|}Px&PPVuj^i8>N&mdSjKpa z;55M(4`%*%1p|T`8kn!RR%peT(25;GD=OdCSH8-PX=HyC|0#A9KNMQ=&q6CI-_}>Y z%AFppDZPU*FC>9B=_<`6}d_`zQ<=gtoSGh4=?9cwIvg4}}FaKVPUT@KA zXQss;W6>(NDeSec{M#-5*%qyGiYHp`t1Nn{MNhHlu@?QuPH(vGwCHm!I$_Zb7Cqgf zHQb{u{>vR+e^o9Q{#@kG5$qFOCb*Aak>CpS?@Fc+_1Q!TyC-}}$toMkZ#`{vCwSKkFAJM*u&UkNcJcdnF$MoZUK4r#G zBVN7Kc&P4yz!gNx=qQcS?KL(2ma3+9K3n4MbC698hHj^g54ms zdySU+18cnUxt^cuEB?P0|CFTXYQb$kBOGJd`I|haeD>ceQ0@-}%H{L#|9bq>HEZUt zj02cp7voH3vH7PmMPDk~qiD~fy^8iOnp(6^(e$F3S! zi0|2>=8SfV=8l?2?*BVJc1S4ZnSXXDsr{pi_|OKrcV?2z`#<9Pp!mnx@kDX26dWgb z*QG2!`iG3k3mA_UeCR@^zb3TWQMBzHFLJhB+kP&8Z2#2XndfsjY<&AX<}3b5=qoL} zROnpk^Esc>@&E7X5RrURE%{h+FQFCxA^B19X`vNw5Zczan^wN!5|O_|>LtbFgjQ@9T5-0}iW73^+wv+mQdE2SaHRHay;mil zD&}&x`AVyv;yq$d-ECU=isy^`OBZo{qIjFoif0L}7#CVGkVD^=SGkd*+RKL{wQuX~ zBk@wqW?5Vp=D_`*slJ8Hvn4ixI!D)hy;8W5cxJK|e!8Sp4S39b&e3kFJ zg#A%$7Fw}fXvHrIt*CrkU->GxUiv+Kg581}1&ITH zx+`8O_S9WzyPtUO4IIyw>#}3*)y%);3dU;$i?3q(7ecEY#a#B3uXYvHzM}1q?VtMF zbvcK_M)jvqTy!Jb`5Zq_2Pz|WKG1yBC;44*q0ovu3a$7%$)AcJ3vKJ$@+vn{RD1bw zr1ot+jh|vJcbl)Y>M7nN>7?#9t$fAri2OrWa{g63U1-Ilg;ty{wBo@z^lf>S8!4*2 zd^l43ww}gMF_*i|S6cNHCrCP}yG<)!@eL^#6Qw;-d`j98#T$fH>=Rn?+d|v=w!F%X z6xCin9I1UjxAm2;a`Ud|c+3>sORz$4XTf>W56Xv!N;v*i zd_eqFwC&~MtDL$kHi|uUSDNMlgZSzVrGjfiJ^i?nzYyyJ!1qG9?|DcTDxSgyw8VljYBSBz)G8m6(FxA{348P6( z=fedeH%9R3KeOItf_;J|f@|Jl_onw5=YGWa;fIXZ3U&(~ELbWyN$@X!VfkkS9~2xb z*!=;!j}zP?{=Jh2e<$ww@CK2~g(nqg$M&bwvTM7mf6C8A+kBNT6q_U*pCjj^|7+>6 zM4n%%;O>H33I6>(j@O%lj|tu&c%fjfcxyfyRB;G{ZtpBAE*@1h8t+&eTQsg{e9?qa zCB<8fnmB6fQC}$9rf5>pw#C~OZ(qDa@fVACEZ(Vj=i*(8cP-v+{O+T^G*eR155<8~Ui^SE8c z?K*C^312GNqh!yLy-N0;Fr{SbgncGVE15oFM#;=^U!E|lq;y3?1~2ht}QZL+|>PXdSj z@rUkxuyux_w{d1TC|pdc5EypEdP@- zn?8&i?`_mD9rO{qD=I%1+IDQ()>FGS+H!@`wtxBPLhb%f%jJrPhO5x@8?GI-tNsiZ zbNQ$I;oAF8%NHEZU3Z;BcMI)mUoiCV3h;ypgDr2h6}@J3@F!dQB2qLQz{R(TK7H}e zVC_MiF^)5Z{_q-8^EVMle>=(__HpcE{|z#d!PsV8@nrq`0)A)yWr$_{xzjeICePe! z^yHl;6;Gz$J53rjd1w6I8Na^_z9RjmKa$NfgvRPi!)mZHm2>>o^sw3SS#Xu`HwoGRF%xv~B`#jtmd~VTS|6YFnNvP@ z-oE?IU$Aih%B5A+{+di(`faJtwA6jJd_H$u{(qW2p*U82Lh-8NJBwc}etXcrJHb!? zt1YH~bBg!IH*qHwsoPrT&f>6Bjqmio?L3qNYPkAs4b_V$obq-3Oeo}&B|SH0@)|>p znWWQM+*aIKTvL2$@gv1g4ElE|`00P8#q@8-;_>(i#~(+Q+zjSqyvpLfyO`^cCI^4G~*q&jg^f~EEIF*m8(LPb< zjkR@Vs66Si-@QTf#fiq9sY`Uwv6KFC7;xi*KR)qWb9-9)$fK&>MjpO}JnU`WxUUwY2z;=8K!M4XWonamV((uU3@K z54F#l@sfAg{Vp=GU2<@M1Tz%m`7H+lh+u!`g(hEmbE=-h_e)p8>{)O8d z`^l}BopbfVK>a_?`r3t?79O$Z&)2TcP;_U6ksA9dK9`|q-<`L2&|+_PfR0Uyji?}^rm9e#EF{RiE5TE+7x{QjdSKe(&n ziZibK!F?GVZ^I%=m$zWt9{)O7wAN^W`etVNTTo;C533m#f@?Qee8 z^vG8}U36{LZ=O0bG53ITe^*oU(HFW8xby4JoqN-7E;wMv<*#3K!>HdJaQ>GsIraQg z#x6d2ZD93%Qx90Y?OUZM{oveV7M~Md|HloVUbgs-Up)K#%g6s=@j1`z^Tt+X+b*d% zeaMD|MM&JcRlc*SH1t6 zhK}X~kK5t;+CLt9%7N$ofIhb$h=+mCdxBFAGNf}T<3ZnMJnff^M}J~)<0)m84n9wA z*J<#SXU{bldHiugU-07Mr9hPI1%#KLy=yP_ZMWy_*Qed%-|N{w{e4sUhyJ%tzj*&cm&~Y{a^v{Z-u+gvW~bPgpZ@f=@77%K zNX_1_UjA^+sN-;A-*PPt&P$IN+UhS*C^}qhxcB^Z5i>|1;ZKsQBe{#u=Gk^QU zZ)(4E@C6@!?c{NFmmTrT_h)o2u6uo#T^IcQ$V6S};!XDtd~|u;`iFP^_?eqtsH;EW z*M~m%?zVx8j;MO?)-^SO2j{iDec9OK14mqZ%gxhH`AGojV?LU1G~a*Fe9ol1KdP8} z`Boo3bmxn8Wjj9b@r%{R-#X*Imu@}D-}arU{bwI|^y{-9^*wz3$rrXhGV1?h@6F?) zEZhI@OF+e)ToTtN*GUOcQE^8_9Tjy_QZiFOz(Em+MJKZ&vzm;G%!N#iOpVHnN|Vft zObwS55p`r8m;na2$V?|ikKg-ZN$bAvzRUA_{&-%mhj|^mnd>}1$9A4`%`h`CokLSb zjm|cA>hNgOme2M5{E>ETnp8|JY(2L1&#k|F{?hbkTg*LuS$^HR+x1Od$K`YT{oQ0Nhsu%x<)ytzj)Qe{?&tB7e#q_%8Tm7kiUF-W6 z>v+q0C?sm?@^(ky_Sr5$vn>0=pIHBS zXxq4eX=lvS!kW*@8oMi^?V@t)nr|Nr*tEoYetD7ifFGakH!bUG*}~VB=5H7_=+Y_u zvjgLIj(F(Vot&d;ziR8N{T|#xT!=K5n(^|GyndU@GRy@a<>FTEc$af#>>s~>^t0SOlSA@0jJUiir0`bucT;-r*td4*_|Lk2 zaq9Q#aZ^0LI{D&&>bCQ4&L6vV)bNdie!rP>tmQG~rE7a$y`y{H^7h`-@mumY2QKZ| zsP&P@4qrX9>(%u)XAV#B`?>9bjlEZ|S*L7V^1~M%H}@qfM}Ph0*}QmtYL^X{IzF%_ z)U|B?_TY72KR3DS<;G8SS@Y)AHSbK?y>0M-PnKmoSu*v|fwk+(FYHVoc5_9S7$#R*q7vN(0;PJw3d5`WqXfTEEov z{D(0k`S$aP+ON9hO{`;T9kc3qtCqf-YN`LRmOZZ5u>Qe|X8(bj>)ORvYxsxLI+ebA z$L&*D|InpR#j3Ztns{APz6YlE|9HL?x_p1M)0^G! zOi5hces8byW+i!N)BxivuPVD|Hy!<;;bY~4D<@8NI(Q~^Ra@WS$DUY~wY@{~H`}AP z4{N2l-utcNCs#FD>o5)-{bE_OZw8-l{MHA>(-yk?eDvDU_1#_^@4F(pddr@ezG{B#vMuDyS^-D?!{+M z4tV~pq~B~ESAPH0SJ7TuJ_zYI$TGgjY5V4p4<}J~%~z-xWU)j^tR#q0R`5IWN_jkR8LEs>e3fy^1ZA=^RnaQ} z%4}thGEWIsLY0NeVkJs>T1ilh%CpJ~%1Y&BC;Q^GP<{9BK3|&DsKeE~H!fWMZt9*_ zTxX^^H*3RWDKfYcKV&{vGT0TX^HrQ~D{VvRhxc_4zAz+ZC3~ypj3d zyphH0<^`CKc3D)iZgcVcrIR*UPadcYnE8Fd-sWvWV>(~mdgZOPtEFJ=Z@xYSbNcRRWBbuTzl!$vro@v+S-dp-_JxZzuo=l?&P~S?`*y^@y@O4 z&DFluS8gZY9(mhxYmTy)KMZ@S!M+CVot}33$*G6)^UnFsT9;>C)U57(J@5VasnD(S zmerp}H^11&`R?Sw>+Vu7V1pg6ewR5rZ~Mv}TTkR%yq4R#=Oo*sgT1HE z+;y`0)Q=x@f6@AA(fcQJvRn#xq=kD;dH=%5v&D7ihZu+3Sx4hV!yfOo@9m_Qr>!4! z`G9hv#TUoc9qsw;$@dq(^U2J`3CkN_X|>?MoJP&I@87-Z>;vb=&GPl_a_gu5FZ5qm z_*+qU&raX9cGB(3yz@)d@Z8VL2fufI$ouV$#Up=N`A&zslPtN~pJz5$eLy=@1|M*H zJEQgLj_>sjzvaBncf$v^=|v&Ozy0-<`OXKb>}%rJSSOfL8{L0-vBmwDm2L08Ea-Iq z#jo4_mon|WOL)KgFTDrdyV!@{yBr;R|K;ypzjytQK>hxJxnU=cyxnrguG9|Jlls?x z)sAct*1mbdi?1XsJv!s$#sMd_Q$MmjHS+LN!(ZRBX7c33(e3TC-_|Ya^sN?t&^WQ`0>`!L)OK9 zV-9(+dgrYL*IzF@xi+u&Lv1!M`n=<{VYZOc5>G=;?suEU8f`oLP9!9sz105au`V&Q zyth@_ZeM)ky|^k%qyK#Qp~d}|t!?kW+`kqJI)!$tzl8O^|H4D+`!4rZqW7Sz;rCyT zj{V==zs~(*@3kdmdB^m!@vi00BX?q}58iHf`?*_3|7i2a_C}LitnJu)&|W2~K~E>M z(;DaYF2`I}HS}(Dwb8xx<)_5I*b^{>jwx z{>d12`!6h!@qaRg|MS=1`~EL|u95z|um9A)zxV2|z4?1D{$4xb{$6h)$L=?--uoi| z7w)%vBeg%N@&5Xi$g`LC>|g4ynf#Y}eK~ZWsUH7fzw->5NbzX(nKhN_cLe|c{-y_i zUu*R`Uw>ckzh6&e&OaH$|M~0h{r~^k{{Hus)juz&wyNeUQPeXSUw_^2RW$RV~TX$W3 z?PAiB;DupO&zXEibOIk49H#iI-}sstoe;Z#pU@BS>_6ns58JK%kl%a9ygd7Rse^I# zFNUCP+B85dF+}~)>9}W>ghWS1EYL*9Y7Be~d0fp$QHQD@Mjjp=NkMV7pF6I`tpED+ z!x#BjX=>DT$Gzsyga7;kpAD*3HSEvVT**v7?%q|7dl~CKlH1s{u4+vbVVJ|*+PXF2 z5s@`MIHGo>?n9zfHylw*?HSiIv?p&j?-ypQ=~urc!7=K)&wEBj*1Q{1C7(xMbIr46 z#nrI{rC)G@acO;_b)4hW!0AMThz2tn4Ch~oJf{RH)074rbFUkJJZfMKxIPU%rUdZD@t5k7@yxhUS-W(ey$qSQ5Q7L@k`KV+o_gM8_H2Z%f4GWS5V<5FQr%nrQy=$#%wIq6l3-=R)GFKW)tI%%YSQBK3YW!3@PUf@fY~!91&mjwOdB^% zeKI;Ylsx?cmDtd@urLyv;Wu;qcoM7i6QQP8=VuaW4!SR9SnRzR<7cQp*J@(I?;Y1q zxOaSkT6UeUacb#GoFQ15sT-p#iD5nUfpz+jW%uTdovr>{>vt)guGi1#K>e7STuuKLhDVXHqD-7nvjoagb<^-QOWinp zEv?;HPphjq>%PrZ=aaPmjHjloEQnkdqUy%^&mOBXHZ&$eZT1X5{Uo)~5h3x)q_F|? zJ1(A&zNF_f1E#>Zg+^uO#6V>k=jMp0r8Vm_d+fC7lcvq8S)Uj_1T#EhA^Uqeubxk= zuPJ5#Z#)Z&jSE}AZQ;+}445=6VEl}ku7sngkTd~tgUjfjm< zZ%=%z-lV$ggKIt!vi8_uZ?ypRV>e?KFH~lanG~R(QXe;jo6?{0#&Ua7!lIsDu!O9~ zPkU_KR5DgG@Si_v=9u|@d>hNHMo~O8eEa(skD+Q0-Mhb2@6YeupVbTg^>x?UdG+7_ z^>xv|-cQ#1`HxKe>&XB8d}{q$M*lbS`hT2HeZ2Y()$(8aRA2XhH?N%^ro6FoS!D36 zDZYdHbZ)6+?oQj3yvi6E6rdaNXxCQ%a(!XQlL1pFjP~i@r+epiEgS#K_3E9 z#=RKNWIU1aAjW+e*D$Uyt}w1Jp3JzOaWBT*7_a)Ae7?ZG!uFtJT*J7+xaBkaF`mqL zGULgNYZ$kvIetnWj3+X#XI#&?o^i`Z9A`X{@gT;18Fypcjd3@|QyC9p+>3EH#uYU_ zIcAe%HaP|{?#8%<95Trvog5PxPh>oiam}0bX$@oVFmE06*E44We%>YiM*P1=O`C|j zg?!(~Pb#stqWuv6+t4I)487M{j-k&+uSvlt`b_k0XoEK66TN~~{{cSHSE2Xaep627 zajXO%7BrZGB^ToZOD|#$mR*Pstg3(*m>ZUwPfY9x`oZXrpqqu2qg#qK!q%hhg?){7 z0(K5vICcZwE7*hBe)Jyb_oMa43eZJj)##G2&e%@0Bd`-_=VF)9t-zXNU!w1Z{!6rD zu^hA^*fn%3vDVmDv;(k%XlG!h=wdM^EDgOo`ZTmYSQgqq%#O~8xne13wO9sP9cD&n zz#M3|U@g&aLF*!WtZLw`=y|F`R127xf)z~d`tFeyQCuoOZ$I#BfE}~nGHN`ff?St(@I~mJEn}}7R zOT^r;RJ2}LCR#maK^KE5STb4-mX6jJ%SIcM&3rS*&NGIko`YEGS%{_PLM-(R#8PvJ zgC(9OF4}OcIr=2D)#z4W)#z4W)#z4W)#z4W)#z4Wm(k9}PN1EOIiX*P{u>Aow z>>Aow>>Aow>>AowtQ74G>>%11m;aeS5 zqp%{h^RObc^RObc^RObc^RObc^RSa>M`63rj>2qcL$O@60az~D04x`60G5k30Lw)i zfE_~Xjcr5gjpd=8gB?RV89Rn{GIk8@Wb7E)$=ETpld*kh`(PW<_QA5z>ak3;zE~z& zUn~=?FP4ec7t2KJi>0I0V997TSSDIuEFG;EmX6j7OGoR4rK9!2($RWhsc7A>M6~L8 zR6W3EH#;XKtfNy7qBr@*HxQ20samyX@VLX%ZOvd$$ zyD?t%2kUg3To_MeJdyE4#@!gtzR7XMlNpa;+?R1*#(f#j{+;8D$1tvE+>3FAafNY( z@npvJjB6NI7_TCSOmfVmhD>VEGp;b6O%Cbgn96tz<1viKFs|Mg1aaO-=NzV3@nvI9 z8Gg#i!A|T-YPv|=%jA3oKUaxWh5lD!TtidDG4z^Jj-k&)?}j$00-xv=wE9cjq`3F`rMyBdr>cz-H&y{syyir=7yy{>JTq1(}Q|2OJ8!w6l^{EM(Ee0 z?S*}fb^>+|T{w0F-7DCG*bcOVu_NeaVdZF(uxfNkSZ8b}+7Z|Zv~#h`=vH9Ou}x?_ zu>ENLu>!O!v1{m7Vy&^QXa`^i(ayk1(Zym;*c!CmurJY$#d6RZF*`aV=8C1D)nXZF zb(k5Q0dt@;VeVKOS|2P6Z4_37E(*Jg?oF&KwhQej>?GQG*j04TV=b{QXg#q5XhX4F zw4vB_bgQto*fzA@*deq5mV;!+i(CV>Fw0g{fE(TMuWV9MA9jz~xjW!6YLYIiSVX0_+HO$v?tT$u5&|_6S zAy(A`VpZKCR@Dt+mWPRlWuhI76`-Aqoj~i4oj~i4oj~i4oj~i4oj~i4?MLf@Z9?mT z<)EE`9Yi}8JBW5Hb`b4Y>>%2)*g>>ou`khf!`7hfhGn7EVHs$Bune?5SO!`jECa0% zmVwp>OGE39nb5jp2hfhfcA@pecA@pecA@pecA@pecA@pewxDf^J&(2}wi~TCwhe6$ zY#Z7h*fz91ux)62VB664z}BL5!Q#=nV4tAvgKb3H5!;BiBeoH3M{Fb7j@U-D9kJDD zZ=qX+-Fk?1M61D)(Yj&DXx*@6v~E~3S~n~its9nzz6xy+R)szpts9nzR>2a{Dp(>~ z1xrM$V2NlIEC#&=tsYBvVsAO~b3@n&y22)~8Eg()!dCDB*c!Hl?O=Q8PFz*%!q4dS zjUjq{Q;1&Q0;1QuLG=1I5WW6Eh+f~pArY|)<}Zm`=(!*`UKtl1#Z#(L@tT;}=$PPz zH6K>535$*8=~gYzn#LuB#KlL%^W1K9)FZ?A#ghLsKXnYx5X~4L@c0b=?4ik|fde!> zBaNDeN2*Yo%&a{ST6>`8d51k=SR{E9!qdjtqQ+cI_TEbqu?bO{=miTBVq?QX zJ$PoH*A7B8Va5oa1yk!%moPG7dF}3u4zGJvKw}7w3XN1>$_OT{P|w<>r^%sVHJzLm z;OFnJSrQ$ZK+`r}j$ zy{_56EJ6tVteJG*^46?Vo$kIxuZcX9s0%gI!j_?mi;qpH>9u-tiHV7h<@wY4cz@T` zyg0y0{2R?*ZtDRCnud5GFZXDc1=qf)6_OAU8LyVA?k!gH8D5cME%8*8vFcV( zZ(Bi%E;=?$8!+_|jbB3az4|%R{PR|=y*a46FEUI$wR5|h8P7S5fAF+WGjq~ZKh1b! zd{~rvLXXo7)M#s7(|Y9oefa0r{kMt!ncsc4AMgKOQh!SSF`;|2c=hdnkXT)|f6D(S z`EhoQQg000xVRlhb6#6gcS2V0Mm52qbt}vbuEzhp^>{QcCTu}OxcVCI{i=W4x|)N3 z=J)58j;mcV^~FTb0X3bheZA=ZHMw^_(MN^_b9&=GIU=09O#|o5kZ4YT>a8R?CM=dS zn0gAXITh46`|Hi8?zB`}hI;Pfb(p{G$^RGpduY@bF>8|H)ypx{{QgqeU!wDx=>Prt z26$+A1@4FB9TQ~k&@oP^0!Q9{@ zctoY1h}3(D+IxtadnomR+5LBH>aufx$s=VIvD{JI7v^y`7Y{-rqV7|1E{jlKx#Lbe z@|l_;&L7;@@W}el?ff4d-sfBW@qc@M=4ME%)O!B;EIlrG0k?$O$Fpi{7ew>0Ye77D z$A+nQ$m+wIIE|O5rfwm_q89Rix%Lj!5F8u2j7M_n&ge(c(`VM73)QK(ujFA-KdVA1BgsHQaLNPt`*WUr`#*Oy;LGE-uV&(D+#wC)Xnl$h%Pk7x%{F8-A)ZcH?j? zlJ`_cY8&c*P>*uJx$&$5r-m~cG#=fclk@PMJf@B34Kw!eY;o|jZbi0ecz;L=%;I{| zbJ^m*qU>_I=1Nxp86Wj{ZVVLJ>se(WEV_u-5jPhb0eBB%W@cBWfB@+%A z%sdze-T4dog+s^#eglorK8(0$!E@vA10VBa9Dd=?@h26f zXfE;QD$4Aq$P30APK%b`MZZ~cT9RR##M6>EPf_}&knem&`Se}#fG=+&ZjhqfhH3EE zuTF~(??cJ>8b5HrPvjq>C`Vxy49Yq!4j5K}e|~rR9R|XLEBJ*!Lo=NI3-$4?1l={p z;Ubs_O*hFO?rfMNRj^x&9P!~vfSnKK2!AT6B(=|xG&s*aN6at_y7C**_zpSZ1&{a6 zkwEyFXO1Mo(fxBI9iH;d5j)JDm?K&P`A^Of1MEB{N0Ol)Wc z9nVNAJlyMyIN(x`GonvWly~)K!~!3RIwPi~>?`9LF~c>>@w1HE&$cs?2D|>ue50Z) zhDP{Z_8G~551u(ARd80jTrn(H6a!2n51012Vulu&%<*PDa>e~wZrjio9)bqgwkP9o zCCq?Vy>i88g`&(K%60h7s9e!Jrziyzb0rmy*5yhTd;wO$?CJP~es5Ugm$gA0;pN;d#bi z;XHDId|)9o!G3x8hc7}iJOhn;PL?`-xDzHqjg`FN zT4;f;Hv03rqO5?vunNY&&@$pfGt7qm<-||oZ>6CZ^sXR2OoPd=vz_=b8CF4;O5(r4 zzJofL24mnYm;(JTG9PY%c31`7-sE@sOROtg3xi-eG(n%s;TD(*3t<-Q{5yHUC!za0in0m%Lbn_A z3$B8x&;heysU=~bRu@!=kr3VYopKHLD64eT2sK70lS!HX~%KB=6QOn3rT!I2Hl@?IA9 z7u3OTVGO(lQ{Yf1=0hX2!@bb$UHT4v;2`I-5(ML+34R6B;WcQ6{awzAvXRFbPzw)2 zJ#5?XtQcW9OobUR3wky>D-M_lHSckIgF4uwF?qqIFa>78OxV$tykI1B+r<8dKG3r( zj7sa8D4slyxwQOJ&zt*63H)>`}ML8dbe>iK|Io^AwCqG z_}fjNUq2_laPAK3f^WboSbdQ3uelxmL>_SE@pF<6i+{uaUT!CMiJ!sk0BT{Oa$W-A zwRYzv8xHPpUX*Y6jp?EDVt`lsotG-u#OJ)|_9@C!Q_f2&TpV{^g1+Vb*DKCTCj9hy zbo)6^zI9%Fq2cZGVuV>6&Wi<(+={>NcwF-7c`?Jc_Hz9I>$0D?aOOdD-xDtj|FAOW zyl68O=HBT(?I&}Ss^KO$o@q*D!^CSpXH_MY`=+rzY@;6q_n;A;hpF(%9?XY- zK;@XCTrei0=)gQNL1i#~gxjG7P98$vPjOxuktaSd3I@SXpb1`t>9E(xJTb!%sAO}V zf?8Mv^|0e8>Vm=E*)m=7NxkAHXyI^e{KuPIzYqeL2hh)=c&R%z}Zi-{bg&YhXIO0nPBqS@h)`kN2S#J~W%YKoc~= zH(@Hg1hZi4K>7kFLih8W51=o+I){A#M?OiN&;&DK8MMO_i3MO)163I@VOt@FhMTer!V444G%uu4oL#D_Zu6CXwoB|aQH zocQq02;y7m|0v?a*L{f(qs9;)J~o#4(0d&5Z9FgIM|{|BJn^9eroj9O#D@na5+8n` zBYqkAOd>w~5t`u0$;5|yp&j<0Li}?2GL87~wx0OVHk0`9=q%#HF@eOd;PJo{#E1Q# zBtHCjF7e@GPZ1v;hYmP?9`Wt`-US2U(D}rN-9m^Dox_L^?F)%tsVJux5g*QpBtEn* zAwG%PIMyTp`YT#E0Qq zh!3xBCq8ulocPfG4e_Dw2=TA-`*|+$;ZZB`;iOB%hl{Th9}X1a|H8UAE8u;4+^=>h zkQi94Es#{W%Bw)K;jWe3P$BO>Rg{Jig`&Ah9Z(N@E+RhM1Jj{yG4Y{$WTDJ;u)m-gnwJzxz#lwbiy|&e zi7piXTf~bglq?wdbfNg&roLF>LHD>q8BvWMW<{l*`cc0{QVwf8dLSvKwk&Dirqy4HUS*bk4pn31Ny_1HHBh>Y0v>p?-WXWL;S-ml^dwDQ3J)e zxljrkH&ApR5YM%N;=Y6YnxKOtn&J=Yq5DVF0ktq48a|~D%{cxA>+k^n_Od>0@$&=z z+mYWX{I@6W=|b7&j-Q-Du|xMWh2q+QyrBn7JIg%ifY+h>IqK_3ov;VYf~%nGdE!C? zv_K=gu8u>mPWXd<&<+Ek14hC$GksH!!(6Dnz<%nC9{NKw+ys5{s2irh5na&3Bp8@a zf1m+Y!7S+8m2nsdwFRsL)Ik%>f}7Oih4_OeIN~AV!z8FJDwLft5FUbQ&;cFLLxZ1U z_BS-Zc$fxF&}^Yk>bRAC+6}*D)YYBi6@^mW1HTtpr(V=`nSS>skE{6A($8P1vk(4$ z<95}Tb@-jWdC*TsA@6x5k6Yy1k2uxT=S3cO>Ei(U;Z!8e2f~I$lC9FUNY;A8W z2(~Pe&isc{p9hM>qOxs~Y#RdG7m2|Kb}SN)p|DGlRH@Vy$?jpWdyyE2!(K%)Vgz+) zizH)+p-nC=$nL^6OV5+A+-QPrR|@Kd?wl<5-_TMUvr1eM5@GKAwDs7K!^r z>K{=gIvw?l!v7@v`W8vrWa=GTB<3mj9bY7={^)c?5;~RRQ}92HxYLT{GE8}_NYbaH z3n-F!J$;;ABtDN3cTSO1!@#GCBy$G+4=R#XGs$ZK@dAh&PM;p9&k^(q8WvN}Ec`Ah zk{+|kFB-p47fZc?#EGX)XkS_+0Z-uP8TtoJ&lXAK9P)gQ`k^+FI8Tzt$|7-_OWv!B zWD|6MmAs!KpVdWj9U9*tuX*@QE|R4A)b$Si3c}BN;s+D|UHT8*Hy6qN5aOlM#|7v= zBz`FR9YvxEL;o>-fEhdKZ#eqTiN6rtmqp@lAphO;5gNaye-YG|fnR9eS0pPIv0mR5 ziR)tgf6qRFh9B@7iQgZKWGBozOh1>9&rd~i2x^ZNi9U)vP83N2G@W9-qM4sV|6}lf zwn%)RCLc5XjYXeNd}uCWpT*I?k|K$T$DfV9CJ^6F{H5f3sYr66_A2YWjC_8juSW8} zPW)%^`#aZ{hvs@$ju!0Di*IT^l3n`T!%Vu>VKa;4=$D!srd0J7T*uZYgnBon}9ZeqF$bSs|*iJsS% zJ|!Q2=IzAKROWp~{OQE`oci?Cl}@}FTe z|Gns*ES5ts>#1TfW#D&yvG{+3pO9j4+lMX`J=BHM*KhG_D3-bV(J!KZ-=U8z78}fp zqE83V#}NN}^l|hllRm}Mj~|$yfZv1Ey%hbA_%$-`5Pf}yz8yxtocm=7-EtXZMn7_K1zqi6) zQn55YO}sbh7xYOkmbE$5v!?pfRObww)#4jr98*x5rJz;&GmM zTi74a@jiK)(S1-X+6&~jm3*Q5Hu{x^emn7@c?bIx`lL~3zIuMaKXiOjECB`Rcd{>F z#%HWYA^OkRztEV@?VyO`Us4}*-^1}@j_)nz_cQ!{LqALKyPx$e#qR;?f{skq$BN${ zxjos?A11#t^jYK$jmOxh<>*gvyQn~aivHNCGn@5;=F=Rnq)%tq*U*?t{TEr6v-BIf zpJ(4*qEBY_3(UB{e!EPc^I0btSipX`LZ1rhFLV@<-&Oi-VSS;ov{?Lp!Jm!eRrsqQ zZ)m6_?_cqEiM+4j?<#r!hQBKEhH2Nx`#S!vli%<7yGhh#kGe;+PXL?fxRtahsH-Nva_L+lI3BM z#74~Xw1{70C&g!gMciGP=WUS!m^Q>B=}nk7)FSb`@x^_lMRd)WH`*f2n>#6{u@x-IrKoQwMa>776O;q!?l? z;@t^dyhR)^W0^%xbVm1#MUuOa*K_o{E4mjfqJ4-uS6ZYR8dg~(Q$roETKF3dbgx+? zup9LxS;V6|`6gTBGSscLNLml_-GHB-s2ByW2mOC)(Zb;OrQfS$O<5^;ZwdRLT40Zenh(Yk&MUTni5$t3$CZ$*>EHE2Er}Wt8y##J^^=7?;Q9E^*#xAQLoA`sdp~? zntGpt`>1ywbsV5x=z5TP=hM%_)EmTj7WD?R4kxG=W}Twm5b``jy$i_u9QB4$M;`Tt zQCA`LLWhNV!>QXwy$k6>1@#)>r4q5htY1oap9%f?twbUh;pb+Fcr7N6+tdq9LcNjX z;an;!mf)vxsrW{bN3&9KiKf4;N+k>Wv?-OO82aD7RP;}iN2gM08%y3@N_jkpe@&@u ziok$|5^O2rO+JW6HfQgr=FC1x3U_b(N1BYAq4iUVd0DV6=tpdVH$ ziObQCEET_J(fgK)>k5vKE0q(_JfT#QpCgaSr4sNw^QM-H`wP^mFO>r59#AT&iPSN> zR6<|G@0?Q6uB6}dO64*P3@+vIB7F!gmH1WUv9MHpUZ&2)rBV$YOG+j46~<#qW!002KT|5%(EeXsdP@l|Ef~4K<%rgvh5B0y;drQ zH_0!lR6O3Ij<-sAT^`+I}gi$0@NY*6=YsibYB9|uY$@;&rF zl#16T@;Ov0*P-L5Qpwm%zQkrKhtg`%8!NAuvYroGCE#=Xxm(3Oo%o%sQUJ|et&;i$ z^*wBr&@a*Vu!{C8*0Z-&F2j^QR{r*y`X04P{2tRDd4*L{vdHHJtIR!0zALSwIYxh8v5F14zh;%ROmO5_Q~-?EC= z&%}GjD%YWTy_MIgsBfcHR-D5BW~=ySlm7=+aXC%=ZC1&Gu4z_D$|1i`t)f3eyj@ml zn@hjGwDLL*`RuXErn4N+uu9N5;(TkB9_R7%y_MHfn0L@BJI&;A*eWp>h?8X%?>y!o zxAORuJWsLy`Q(wq`WF!AEbCuL-DcLmh&=OIf9P7w`WKUbDeG^+PZ{f9g1(aVhsMjS ze<|~SVg0SF&u^^1jXG|y{?PFU>t9AbcUb>&^oot=)6u)wq#7C<+a%MDzNt-CRgzB& zo1|YP?^ZS`xWw@XY~p%_y4u>r`zrGvv`Nq})bDPSq$>P$vPs6TG%I4c<=U;}5xJ_tFz*mYLop< zoH>7zXESFdWu{F+n=@|~b+m9+e4emL^H$E>4^yX`vtpiSlid$ED`~;>p$&dRZ8Enl zaTe02cEnv|6PNbRiYbzDck+rt-vRy8`0wbf1jZ4+6Z!<3xOXQ0GMjYnf_}M8G+l|m z!X`Z)qK@ZnqSX-pMH_#2jK7y`;?<4#FVpw#Q8@m+QdG9x;`hqH}k%*iSHoh?Y2qeVEle-XxG3bul#D6S#{!Aan zp+8AnKk7JT69;rX&HfxuojI)Y1pJ-B&qVr=OC37$I!9iU=+k+d=qIBy)88rd^8))6 zy5=+ApMDom?^OI3vJTUjU&J`fDrS5-{w$2^$*+|0$B1WT9GYy5&%kdP<1?wFobdpT z+llu$d0(`NaTep3m^T~U75W{BzpLEto*+&Y`8-MdYc>g(OJ2X(B=ITg|DE-ihyJEb z%=6JZ*k8fuZ_$Sk^tai63#ji7>l;eEyD$vBkViOqHYgLrLi{+DNu+@~oXdFsE&dvo zN&F(}Y*Z%3#rSPpCMzQ8Lz6N|T!R0mWwI)YJ~k^8Q#5g!m+|-qe=W--^l9R?Dw7eh z_;o82_c-P~P$t)*xpkRj$K$7Mne0rUo_6S$66Zm5%c!$`nfMyX!@W#8KZD;6W#WL^ zPGyq2oVcCKB>h?RUCX3k1%4kY6PM>X{&1Oiy}YnKXZyy!w`j&nx(Sl(?^wmuHzIo9K^Mne2a!yatqseKr0EmdWMU@jD16p&MK# zRd29!9}qX7OoFx&=W*8KL*~t9y|>}-3F_TW+$X7b2ma<#??==z55FHX zFNk&cgnUBS7oXxUv`kWVl23S<9Qq7@3yHgnd?HwY@fWG{d&Xa)51EX=Oy3SN zZekz)$oOjVJw(1qWuiYqUT>B0z8va$yG(ic`_`_qp8Abu{QKg_TWu5+Do(b%Z+K>H2W_b&B0@CVaiD0Dz0bp3<%gYIw}%y2K~9i_zWSS~?| z3+ID!iHG*i<)Uc-yOhgZn9;Rd_CxJM<-9KGq8Q+H=+l#NCl@6Uu7C!Z3{AbtB@3p( z0;nBOE^D2cH>6xfxNvnaYM>FEBD;GPoZzvbv=FEGyTwGe9|FB$?mRyHzVak`~vI*+GDi<@%fY+gU zH-1_%5BfrL7RO;mLAj*4p{t@V51{+4TuiO02OfeBcp0YrUM{QJaQ#NP1h!@TcDZbW zK6j`aI+O|-(GI^2E5!9d<~OO3OsH#KA>Qp>6xS9NG8ekHtdI<7hE>q?0Q20L*QP== z9bA;GwiS{D)7n+=dMWj`uaLBk%-2*%d?&^qsSw}J^rcS)uV*q29WZS$e!GwdJOSMw zuMlHb#^+Ut83w*mA(n?YzPdspH5`YT(Dn5S$%R^Ihk;2I{2vtJy+Iu4{#J#g!ocJT z{?7+>y8aGymOHan%tKj)B`o5_` z4ngzg3jRL|d2gwZRnR@PLTu3Ig9`EMjo+;myv~XKL-bno+t5Sv_6o^@hBWGbgn6G- z$j(00v4`t@nGc(LFb`^=&)4JwO)wCqz)0x2m%O1Cu7$=7`VCERKXkxs==u$L!N7g^ zSI1$GN6~#-AwDo|e}(wNtON81ru@iyLBo*>NrAefn|1jzbV!gURKAe zDn#3#dVgiTpc$sZlxr1I0Cm5S=K$tiXFZ_tclrcVZm?gW?k0ZJ|%%7zILgGcIY;kaSyxnfEkaH57c?uB@G(-F&~<|?4ljQ zy#97EK*In#ugl|Spj|9b=S_V+93NztAZQv)Utro0#-Y~7F4xuL&~+$%8fKTyFl&@u ze4uHJUHoCnc=`(slkBoqr;_(D`U!hL$27Z)fJVJt^w4#tT|%LK zmR%BI))V-Hj;H7cbf3@qsMka2uX;TcKf}2lgxSRxX21Yw3a1~?0TZENA%374rolji zUG~E)m<_dy$PelkvtA>}Cz8Bi$`bN{rYO6tfbKDNNrsN6>7zOxiy!C{$2vhfysRFN zw~Nb2;w9L{0~(jI?l5bao!_(Y^9=h2roeP{d^vqm`7C+Btmmjt9Z#fRqsZ?i>V&SZ z(kEzsjrD|CtEmsVzd?P_{uX^#nQWIs&~**#2n}mlM;N$)`bKknBkK+wn^`}VTc{Hn zQ&~r7-pcI+W^JcVn2|=E(C1_NrCx_NX#T`5ZGGw6PU?eMpOFvr*+o7u4W>bDI`g6F z3+hsje@Xl?=)a;KXxvSF==wGBp>8iabv(l^W_5fYamG^TxAYTcKtJf%&pN}D1I&l^ z@0ky?eqbG-&q2E=iLYN*R$ z-N!S2hJ2wJj(}OY;shr?57E^ zko=&zi1QEB6|;X}2F!%o66%}Cb?6RLN~ur1ZsmLdwKn#%dK{XdYZ?0*8euwgz(eYI zIqL#-6|4))fQpX%?W_wlK`qo(QYXxSdiDB6>V#%!goaDh2^}yM8ZUGHhOSq*{lFAh z0JT?HAD97MCc$4gZ$Z~zIS)f4^n-R72m`ONkDwVQLig*eJIsI?>h<60BQ!w^binKC z_zljBlkw}oKTLyOQ1=J^p&bT7(=Gf%_uKe~8E`EOtY+Ur2iy-+?r{5pX?NKV>TzK| zK%G)4Zc{i8dq4;Df%XQK;t#dXl@bI4T`DCW`ZTPRWR;C7Ww*-4mAvnX_^y>w4Gm53 z=g<76_*2;oe=3{f59(Ur4`#r4sBKv(Cg|R(QZ}h{tCVz=4^+w_sB2v*4w%xWQkqZ2 zf7?pY!oYU;gFX*diUDfdS4xt4y+fs>sqBOv>N;1-W$50elGoAbXV*&cfDWjKI!&d7 zLc_zAk_t`TDy0CXb*~in>FoO+l@b7rJu4*=YI{}6DyZvSDVfkmTPe9JAE^|(%0Bb~ z8lYBBoiGsE;VNkCiw>s2%g_NkKZakAO3}d#Xo9Z&Dy8iV>h_}F(9|CtbU+)-7{K^U z{0*d!D!s`!fVe{{Me{iGeJUjeW{gBP3;(|4GaJ8CDrM~x)HM&kbJ&+K4Q9-z&(IXa zyeEkRW1uOdQno?e0_sv3%J^K48|dFt=oeMW320wTf9K(6Nu}(E?$NCOeDZ=LV9L|v z7es#&hzB!F?285Dk&ORP=C2{|F#JFtXnu#jL*rWdu5ulHff*Yr`8#*~q%c36Jl`cx zmG7|+p>Y#=EW|JLhH0BwUufDw-O!NA`ohj1P%j(-+ZtRHkFCUoJE1|n{$Zu0z_~C} zJr3>AxSjeVU>0@2jGxH|M&`24i(HiEXDcNU?mt&47I^u5C9g-~CyzW~K>_<41{RX9 z%2MJ+GQWa&(A`cv74>ijfZ*_^kXNUiXz3YLmYW)A_o^w~jT*EL7lVKPpLl{;~ty)?&S+(kx zRV%9&lU3`FHVLbSVHm;?hQ178eCKNj`!bAQST(*wv})B#80Yu?oX@$>x%ceuc1HhB zc3!XT^W5jWpU?C8e4an&IiKgxITH6lqmSF5M$d*^(Hqn%&{oi9(Bv~VsNs2#51Ig4 z3YrNTam@yG1!&d?$O&4Xxj{{t2YItLsJWo&Q#Po}K;vg`P^AU<4H^xa2buy}ng<+c z%^cuBn?P5AhRlT?pfRA~`H%xN0W@MB@&!%58To>i=ObUxRiM!Y_+1FQfM%6I{#&3Q z=xWgV2atXt(mjH7pdn?j=dHkjrht}%7J*j22s~)h8z_fG$hUiwy8I5vaZ!^RUI=~{ zH(~!bdN-*nKy%Z9TME9Tny?=m_P(}BZ2(Ol-=xMC zfq!^eS^SXW`zE#MA;|dy_=1)2hBTq zqq-V2qT5C_^fBBA?EzW|nhjb5x(KuhbOpsnZB%!H)`Lbq4*5WnK;uu}s1|{ip8UmY%s$O#=;y0UywavvL0kqyvoxtvqL=nh9DTi~FFZ=Rtn@4I2I=(skdc zCVZB*U=f<0#=-w`o78O3l0KVob~)-v-%U8f9sP8Fr28CljN7E{`~v(kHeufz z_%GU|uKGXpUyp237p;c8kK#Azs;4(${~3OlZ&Fu-rh!Ud<2kSb{6WKC-lR4YeFMM0 zLHs-5R}VfPB45zx&mr#`$OF0(G@@>k8oCzt10zM!$7A-y-N zxu6k=o7Gy-Qc!6F@JXAoKM8UVL^{y&L7TCz5ONPezM!Q;H>;~bW3C3jjlhA%g64sy zf!2V|2Mw9HS z>T=MSqng#=KY)vCR(r@nQi!`5^SD7$<=AF5)EOitXEfss_aLe1=4N&EK|y%WYKGqx z_rC!CP{e=PtY(6)!inu^VL{UBi?*n-M+ae^W{bKLG&f<3+T)lYX(gx|G`!aq_&bB7 zti&y9WH|U-iFnZTK3mihq64<54WP-%Th!2FgQP;x1kf7LOwiUrThwOI|gQR-U6wu`1Thv9MAtSb^D?n>NSA#Z< z+@c0YAbu3&1 zGr^DOYB4;l|z0$K@L zMZdGRz)uT)prI#&A7~HIQcyQ&CFmm1de9Z1>C>Sv=xR`@8`9^)zM!{&W`dU9vPE46 zTDcH>K?`q%9H&5zCAbe-Qw(`Q>p`nP)9;78pz%*3zbNFt66Jp?JVqc4Tr*FkR3kZi~eTA2g6LGxz9F7Ze|Z>yRM+FAg)Kx=LX z|I5H{Dfoki6oWr#X$km)wm!5~l`aS0$G56IKx3XpI?&SRz!x;+McCmA=<~`}bs1>Z z8z>jhZvlVMn4KtR(BxLg4O%E|Q)3g6UfHI)LCd>rgI@-G z4%((RgT}b<`%3%o(!i zH0!JF>T1v$&}Pv1ueW2r6z+esU5y4!uSa^&8qhS*!Zq9RUJCivLJrXQb=%c)&{ohY z(5!~-Y8_}L=z6;U?RK>lv<5UZ3+cYwu10|t{tx$kr<9~php!GjO zPSBe5+tp>DAwO?dE9f`qD$vpm+tqrCZ`!W5&~MP-Dd4*qd_l{%Y*#Zt(_0`XXeH<> z(0b4Y&_3I@tInxNzjM2q2%7iDc2&wodeAV?QqXA7a?p6t5P63hHXY>+8V#BZngAMd z#17ScJ?sja0~&wi4z(6EBy5M;3Yq~Lc?0+!w?oYaZ9RU6+6bB+u|t(|AQxx^Xv7IS za2_1&0h$V01DZ|oC+<)SDIT;Ov=Vd`XcOp8&>ko4P?K+jUXeT06`)BcgFk2{=uXhp zpvf~J_gOpCEYNt+`JhRl#h{fJ?oijyMEpgNXBPAV4FgRFjRwsEjR(yGO#v+g%>XS0 z%>_;Gu>phs51Is;ehKsj z-Fev#H8c;_)=uXgb(4;Yt^A?oT6wq72H+P3xzX*0-0J(05 zenmUfw8fwgqa2FB=kXota?prp!1qq%|LhLDcS3H^m7q1CwV>tC19unrfL4JPu7Esu zBmWn7sF|Sg6)3M_=na|*S_+y88c~aUiT;H2piL6KjYISze5VMsG6~}HM7r4{${Rq%fd?zLP zKJ+j6c8VJ`7~jEJ4oX*;_8(_<%o-v&azh=*hja}ta&!%)_z3*1imp}9)GHPi8IOg5^OT^o$_PMgYFQX)Fz4+oDtMx<&Kp{qQh{u(2a z!-=%{gP6~aWM*%S22??xj(Aq1O4t7~C0&R`tL{9g<< z>qGn(c$g};1&QD}2G0!Q@@OWUO( zI_^w_=@Rv5M!r+oM3Qkl<&P!QQr-m4|0<3)@Nz#5N%bN^!5J4i4$JAaOYj|^ujutl zStu(Cn;Ai>sX$WtbfjNAiSx;Hn9`4f8I4-~fX7VPx}+p$DbjDB%;~3daxXcvgq&E~ zCr!AHaRZ&EeB{#nWBY2{k6kE_^aPY!6wZk9aU#u2(>Ohj`_L|-r@TqahwK~!+>_ai zd(Dg+4SU?93y*umHy!vf(-}|ppiA(*NnPdB1oPAZode1bM%Vel+G#jZD z_gjFUr{j-5#AK&=D4(0OOsIT@iO_66p>>`(_?ZVhZA6~LJtc$Q-t&mvjEt1r2o8*(|>)imfT1$ zr+7cu^!|vN+&da83VkC&#(3^CqnrH9b6c5cM1JCl9ESk1)SiEk7U$N`#)3rU#k6IqW$kh|EFjwhB(mw zfnUQG<~OU&bAsBv*MsslO+>1B;;AnW6>%vRL!xoWMq4(zky62h`$=jM2OE|0b8-7e z5i;V8XSH}f#ByJpq}z7Jd$uflvP= z=5srq;XZuuo}(lj36$XX7yu z%=Lv@)0KMBQ$0&Xx?g5N}GH{`{GQYXz_iVg>8vT&WeJvR-gc}-y+Q^Cc6ob!_+nEoxziF3{>n7;` zlt*oS1Wm1UvS_e0bk+O{_26^I66SM1voZ7=4ta)ae2_Ic3K>B9hQUu8wUpCcV@@Xz z5%!A*ZnlnlpbhRGVV4Zxjw)h)*lwv^LLc-yUVcuNi1fKw=%WohsQ#9N&)U10&*N?K z%clYx>Z!wxxL*(a&BctLeJm#s`O3*K!22Ep$k&Mwk2R@iHgoMnQ09JxLK6kh7jC8F?_rVLC?n|?uLZ%0Tm!tGkEpIBBT-JetcR6)2q;l{}J_cuC zuVj8B&F|IlL+Y=sNa!`(|G>jnUg!xap&|z_AioV!;ztCqy8tS0i=h0l=e}GlLJcBR zh7k8Nt&sP(cUazGX1h&+yj<3l<-a`1`)aA#?(uksOnH~nFP32dT%vx>MgMr2DB}Kl zGOfIFkZ#TUobF_EIvEX9S;Weq9+1a|_)>Y5Bi)}La5^0Crd=XGw|9G%2Ws+CJ)(II z9&pU^gy`9rj?}H-_rpibuf;qbmpE+XmekG z%KY2(4?g`5J@qwpv~_wNb&-L6hXwPD=2XZ>>=sXVJ zeA3eu6C>|*ayAShUb>COsFWBwzbEW;mSLwB5qX9{Dp5x8A|t4^O0AHT?$n|kLX8bTze;$-mlmA$=3_{m?0y)fznoTnJNXIgt3UmKY?MV59 z?M_wiii5O-WQPKztBB%sBtKoE-A-gd30DqWgN{qmP+mAVKPV~;^49?ueJb;tu1``6 ze)3S%H&IiJ*JR~0Zh2JxZ)?gSq+HHTfr5Jdr{EBy`urrIzZ=j#+*}E2xTd^)#HwJR zbT^W%Gh)3md)|oE+dlCy3--;TT=-NPVEwM zWP!gnO5%9JmjPcfnB~rvO?aBu=|#ric&dkWz(=Jr9><<)m*7v;&~Q;}Rhs~*_zQ`| z^J5sNYiLt{(=i^>`&P2Av#Y1%^+zlsdtxW0~*2%+FcOqk28=l>#m{ zYHN)eGiobYB66J07Hj@6{|CMgPh`HQPyyo-ddf*)JcjEu@wi*?P#!m87aI?j>$pY{ z_B8{0q8H#`A<#+#t9hP>u@nXmI9}j~E zUSfWc=K47u{C*;STJdP}PdUK9{xah~ID_MbooKy;avZ;TP(9P1%cfuot4XnU1Zg5t zu&a@*H+8T4lHJq5rWwIQjo?&6JgpqVPLZVibu8aI(QV~Zl<$nvdr{a*@d|ns zD3sc(onV}+7uN+cNs|3obA1676dsH^c(OwgMMCl*{L=5ED*@L(_QsR8A2JdClY$3)Qp< zT=v!*V~c`+B_HgV}K}D6DZ$uu~7pWgyj6{uvxTw z-A;6yMkU&9eKbaKuY2M|JEHu{kpIzHEa!BypMvJ=AJvjk4f{jX8n0r~Uyg9!tC)WF zq>rtqqK->2<3{B>M*)|E_;lc&(s6^$eqegec{zm2J+diB`BQC{p+$lR zX=q^-m-hUsL%ut2XFWpT`=?8^fB71p3L}fBr|#n;L#{F!yOCS7$k&e@9l(d2g>O1N z)Q&uU_{RfZq2s5RNP$irj4+RaE zkkRQX^E73^lkC+BzQwOF-$%@RHNT8Md#w`fQ@P!+m(fm)@<=}$&$YLh|5N7jo(H*^ zJ$3xX17w+@fo6GrL@;|GJq?KDuLS?EtM?rLh;uN1@DcN0?8iRd3b2og>>e*3cFH8S z4=E@V(0g2xKM(v}pEG}2TS%8^4`d%>Qo^uLvSFXA{jm4ghw4o|_+RoB^MAq2KNrp6 zK~c$1F$z_;IyDlbP`6VXpeqW0ap&Tj!0VVV{iaLE&C_cdE*-c-8v^6V4h6uSr{iMV z*tu^z?KagA*%I2@YELgWRO?LdH6P>^GYq>OqWKC{N;WS;89N&@+Tr>Wa}2$DjSU8 zDZ)HPzDg!VQVyhT0rLIm2+p_7yauh`G}^%pTDH`n7KjinBhczw4fwni#(ajb_=f!G zce4PDLVOEwK}YQx7tvjkuCahi1ny}IxGdm)w}2}KZs5_omah`HM=anPf!ksM7jnKN z^*(0T`Njcvj|E&ha6ekW6##c}c;I~TsFKQoyFQ*kFd@^ z9ry(uz!w6)O~+@O%M0TxxsPvoRRVwQ3D)Il0=}*T_=pQJ9zK!z=a}W8^&BR7l7X-6 z06q`+*psaDF9*J?1NeI2!y~Qp54i}>pbp^UftOCU&OZzIoDSeifnVPNd=2pF-K@*g z3Vdw`@G(8`ygJ1?|8(G2TEx?HsSx;>DCR%JT;IH&UlqX3wScP!uGRw1c`?3aed@0B zjR7vl0xlJ}_blM@fD1ou*ZGzKH`xNN2DnNKxEA1Cr|&x7h)b}4)B-LMxEC$pvVe0& z?>gUN;D+hA3Fdl$elSlT$5aAWX#v*=T(>hg-$49AF2y=!3%EGoHd(->1DAT{uJbJb z?sW^ea^ND*+BLsA;1*iIwF1{<0T&gI{gpAh&NmsjmAk;vxFiR-6VGOTZN?e&oa<{m z=cr#O1AeKFzrtJ};MSmpgM_OA?qdtM7T^v&hw~4_FXA%H=~=)f0(XZ6To!O2TEG

      ++-n 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

      Mr( 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 P-_!d)y?9~q=jQ(c&s~%I diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index f52dfb1eb2..f9c90a3c21 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -106,14 +106,16 @@ program mksurfdata use mkharvestMod , only : mkharvest, mkharvest_init, mkharvest_fieldname use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride use mkharvestMod , only : harvestDataType - use mkurbanparCommonMod, only : mkelev - use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, numurbl use mkgdpMod , only : mkgdp use mkpeatMod , only : mkpeat use mkagfirepkmonthMod , only : mkagfirepkmon use mktopostatsMod , only : mktopostats use mkVICparamsMod , only : mkVICparams + use mkurbanparCommonMod, only : mkelev +#else + use mkurbanparCommonMod #endif + use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, numurbl use mklanwatMod , only : mklakwat use mkOrganicMod , only : mkorganic use mkutilsMod , only : normalize_classes_by_gcell, chkerr @@ -175,8 +177,9 @@ program mksurfdata real(r8), pointer :: pctlak(:) ! percent of grid cell that is lake real(r8), pointer :: pctwet(:) ! percent of grid cell that is wetland real(r8), pointer :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) - real(r8), pointer :: urbn_classes(:,:) ! percent cover of each urban class, as % of total urban area - real(r8), pointer :: urbn_classes_g(:,:) ! percent cover of each urban class, as % of grid cell + real(r8), pointer :: urban_classes(:,:) ! percent cover of each urban class, as % of total urban area + real(r8), pointer :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell + integer , pointer :: urban_region(:) ! urban region ID real(r8), pointer :: elev(:) ! glc elevation (m) real(r8), pointer :: fmax(:) ! fractional saturated area integer , pointer :: soicol(:) ! soil color @@ -193,7 +196,6 @@ program mksurfdata real(r8), pointer :: fpeat(:) ! peatland fraction of gridcell real(r8), pointer :: soildepth(:) ! soil depth (m) integer , pointer :: agfirepkmon(:) ! agricultural fire peak month - integer , pointer :: urban_region(:) ! urban region ID real(r8), pointer :: topo_stddev(:) ! standard deviation of elevation (m) real(r8), pointer :: slope(:) ! topographic slope (degrees) real(r8), pointer :: vic_binfl(:) ! VIC b @@ -318,8 +320,9 @@ program mksurfdata call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) allocate ( elevclass(nglcec+1) ) call mkglcmecInit (elevclass) - call mkurbanInit (mksrf_furban) #endif + call mkurbanInit (mksrf_furban) + ! ---------------------------------------------------------------------- ! Allocate and initialize dynamic memory for local variables ! ---------------------------------------------------------------------- @@ -335,40 +338,63 @@ program mksurfdata allocate ( landfrac_pft(lsize_o)) ; landfrac_pft(:) = spval allocate ( pctlnd_pft(lsize_o)) ; pctlnd_pft(:) = spval allocate ( pftdata_mask(lsize_o)) ; pftdata_mask(:) = -999 - !allocate ( pctnatpft(lsize_o)) ; - !allocate ( pctnatpft_max(lsize_o)) ; - !allocate ( pctcft(lsize_o)) ; - !allocate ( pctcft_max(lsize_o)) ; + !allocate ( pctnatpft(lsize_o)) ; + !allocate ( pctnatpft_max(lsize_o)) ; + !allocate ( pctcft(lsize_o)) ; + !allocate ( pctcft_max(lsize_o)) ; + allocate ( gdp(lsize_o)) ; gdp(:) = spval + allocate ( fpeat(lsize_o)) ; fpeat(:) = spval + allocate ( agfirepkmon(lsize_o)) ; agfirepkmon(:) = -999 + allocate ( topo_stddev(lsize_o)) ; topo_stddev(:) = spval + allocate ( slope(lsize_o)) ; slope(:) = spval + + ! glacier properties allocate ( pctgla(lsize_o)) ; pctgla(:) = spval + allocate ( glacier_region(lsize_o)) ; glacier_region(:) = -999 +#ifdef TODO + allocate ( pctglcmec(lsize_o,nglcec)) ; pctglcmec(:,:) = spval + allocate ( topoglcmec(lsize_o,nglcec)) ; topoglcmec(:,:) = spval +#endif + + ! lake/wetland properties allocate ( pctlak(lsize_o)) ; pctlak(:) = spval allocate ( pctwet(lsize_o)) ; pctwet(:) = spval + allocate ( lakedepth(lsize_o)) ; lakedepth(:) = spval + + ! urban properties allocate ( pcturb(lsize_o)) ; pcturb(:) = spval + allocate ( urban_classes(lsize_o,numurbl)) ; urban_classes(:,:) = spval + allocate ( urban_classes_g(lsize_o,numurbl)); urban_classes_g(:,:) = spval allocate ( urban_region(lsize_o)) ; urban_region(:) = -999 - !allocate ( urbn_classes(lsize_o,numurbl)) ; urbn_classes(:,:) = spval - !allocate ( urbn_classes_g(lsize_o,numurbl)) ; urbn_classes_g(:,:) = spval + + ! soil properties allocate ( pctsand(lsize_o,nlevsoi)) ; pctsand(:,:) = spval allocate ( pctclay(lsize_o,nlevsoi)) ; pctclay(:,:) = spval allocate ( soicol(lsize_o)) ; soicol(:) = -999 - allocate ( gdp(lsize_o)) ; gdp(:) = spval - allocate ( fpeat(lsize_o)) ; fpeat(:) = spval allocate ( soildepth(lsize_o)) ; soildepth(:) = spval - allocate ( agfirepkmon(lsize_o)) ; agfirepkmon(:) = -999 - allocate ( topo_stddev(lsize_o)) ; topo_stddev(:) = spval - allocate ( slope(lsize_o)) ; slope(:) = spval + allocate ( organic(lsize_o,nlevsoi)) ; organic(:,:) = spval + + ! vic properties allocate ( vic_binfl(lsize_o)) ; vic_binfl(:) = spval allocate ( vic_ws(lsize_o)) ; vic_ws(:) = spval allocate ( vic_dsmax(lsize_o)) ; vic_dsmax(:) = spval allocate ( vic_ds(lsize_o)) ; vic_ds(:) = spval - allocate ( lakedepth(lsize_o)) ; lakedepth(:) = spval - allocate ( glacier_region(lsize_o)) ; glacier_region(:) = -999 - allocate ( organic(lsize_o,nlevsoi)) ; organic(:,:) = spval + + ! voc emission factors + allocate (ef1_btr(lsize_o)) ; ef1_btr(:) = 0._r8 + allocate (ef1_fet(lsize_o)) ; ef1_fet(:) = 0._r8 + allocate (ef1_fdt(lsize_o)) ; ef1_fdt(:) = 0._r8 + allocate (ef1_shr(lsize_o)) ; ef1_shr(:) = 0._r8 + allocate (ef1_grs(lsize_o)) ; ef1_grs(:) = 0._r8 + allocate (ef1_crp(lsize_o)) ; ef1_crp(:) = 0._r8 ! ---------------------------------------------------------------------- ! Read in and interpolate surface data set fields ! ---------------------------------------------------------------------- ! ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] - ! call mkpft( mapfname=map_fpft, fpft=mksrf_fvegtyp, ndiag=ndiag, pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft) + ! call mkpft( mapfname=map_fpft, fpft=mksrf_fvegtyp, ndiag=ndiag, & + ! pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft) ! ! Create harvesting data at model resolution ! if (all_veg) then @@ -383,100 +409,89 @@ program mksurfdata ! call mkharvest( mapfname=map_fharvest, datfname=mksrf_fhrvtyp, ndiag=ndiag, harvdata=harvdata ) ! end if + ! Make organic matter density [organic] [forganic] + call mkorganic( mksrf_forganic_mesh, mksrf_forganic, mesh_model, organic, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') + + ! Make urban fraction [pcturb] from [furban] dataset + ! call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, & + ! zero_out=all_veg, urbn_o=pcturb, urban_classes_o=urban_classes, region_o=urban_region, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') + ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] - zero_out_lake = all_urban .or. all_veg - zero_out_wetland = all_urban .or. all_veg .or. no_inlandwet - call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & - zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc) + ! zero_out_lake = all_urban .or. all_veg + ! zero_out_wetland = all_urban .or. all_veg .or. no_inlandwet + ! call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & + ! zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc=rc) ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') - call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) + ! call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) - ! Make organic matter density [organic] [forganic] - call mkorganic ( mksrf_forganic_mesh, mksrf_forganic, mesh_model, organic, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') - call ESMF_LogWrite("After mkorganic", ESMF_LOGMSG_INFO) - - ! ! Make glacier fraction [pctgla] from [fglacier] dataset - ! call mkglacier ( mapfname=map_fglacier, datfname=mksrf_fglacier, ndiag=ndiag, zero_out=all_urban.or.all_veg, glac_o=pctgla) - - ! ! Make glacier region ID [glacier_region] from [fglacierregion] dataset - ! call mkglacierregion ( mapfname=map_fglacierregion, & - ! datfname=mksrf_fglacierregion, ndiag=ndiag, glacier_region_o = glacier_region) - - ! ! Make soil texture [pctsand, pctclay] [fsoitex] - ! call mksoiltex ( mapfname=map_fsoitex, datfname=mksrf_fsoitex, ndiag=ndiag, sand_o=pctsand, clay_o=pctclay) - - ! ! Make soil color classes [soicol] [fsoicol] - ! call mksoicol ( mapfname=map_fsoicol, datfname=mksrf_fsoicol, ndiag=ndiag, soil_color_o=soicol, nsoicol=nsoicol) - - ! ! Make fmax [fmax] from [fmax] dataset - ! allocate(fmax(lsize_o)); fmax(:) = spval - ! call mkfmax ( mapfname=map_fmax, datfname=mksrf_fmax, ndiag=ndiag, fmax_o=fmax) - - ! ! Make GDP data [gdp] from [gdp] - ! call mkgdp ( mapfname=map_fgdp, datfname=mksrf_fgdp, ndiag=ndiag, gdp_o=gdp) - - ! ! Make peat data [fpeat] from [peatf] - ! call mkpeat ( mapfname=map_fpeat, datfname=mksrf_fpeat, ndiag=ndiag, peat_o=fpeat) - - ! ! Make soil depth data [soildepth] from [soildepthf] - ! call mksoildepth ( mapfname=map_fsoildepth, datfname=mksrf_fsoildepth, ndiag=ndiag, soildepth_o=soildepth) - - ! ! Make agricultural fire peak month data [abm] from [abm] - ! call mkagfirepkmon ( mapfname=map_fabm, datfname=mksrf_fabm, ndiag=ndiag, agfirepkmon_o=agfirepkmon) - - ! ! Make urban fraction [pcturb] from [furban] dataset - ! call mkurban ( mapfname=map_furban, datfname=mksrf_furban, & - ! ndiag=ndiag, zero_out=all_veg, urbn_o=pcturb, urbn_classes_o=urbn_classes, region_o=urban_region) - - ! ! Make elevation [elev] from [ftopo, ffrac] dataset - ! ! Used only to screen pcturb, screen pcturb by elevation threshold from elev dataset - ! if ( .not. all_urban .and. .not. all_veg )then - ! allocate(elev(lsize_o)) - ! elev(:) = spval - ! ! NOTE(wjs, 2016-01-15) This uses the 'TOPO_ICE' variable for historical reasons - ! ! (this same dataset used to be used for glacier-related purposes as well). - ! ! TODO(wjs, 2016-01-15) A better solution for this urban screening would probably - ! ! be to modify the raw urban data; in that case, I believe we could remove furbtopo. - ! call mkelev ( mapfname=map_furbtopo, datfname=mksrf_furbtopo, varname='TOPO_ICE', ndiag=ndiag, elev_o=elev) - ! where (elev .gt. elev_thresh) - ! pcturb = 0._r8 - ! end where - ! deallocate(elev) - ! end if +#ifdef TODO + ! Make glacier fraction [pctgla] from [fglacier] dataset + call mkglacier ( mapfname=map_fglacier, datfname=mksrf_fglacier, ndiag=ndiag, zero_out=all_urban.or.all_veg, glac_o=pctgla) - ! ! Compute topography statistics [topo_stddev, slope] from [ftopostats] - ! call mktopostats ( mapfname=map_ftopostats, datfname=mksrf_ftopostats, & - ! ndiag=ndiag, topo_stddev_o=topo_stddev, slope_o=slope, std_elev=std_elev) + ! Make glacier region ID [glacier_region] from [fglacierregion] dataset + call mkglacierregion ( mapfname=map_fglacierregion, & + datfname=mksrf_fglacierregion, ndiag=ndiag, glacier_region_o = glacier_region) - ! ! Make VIC parameters [binfl, ws, dsmax, ds] from [fvic] - ! if ( outnc_vic )then - ! call mkVICparams ( mapfname=map_fvic, datfname=mksrf_fvic, ndiag=ndiag, & - ! binfl_o=vic_binfl, ws_o=vic_ws, dsmax_o=vic_dsmax, ds_o=vic_ds) - ! end if + ! Make soil texture [pctsand, pctclay] [fsoitex] + call mksoiltex ( mapfname=map_fsoitex, datfname=mksrf_fsoitex, ndiag=ndiag, sand_o=pctsand, clay_o=pctclay) + + ! Make soil color classes [soicol] [fsoicol] + call mksoicol ( mapfname=map_fsoicol, datfname=mksrf_fsoicol, ndiag=ndiag, soil_color_o=soicol, nsoicol=nsoicol) + ! Make fmax [fmax] from [fmax] dataset + allocate(fmax(lsize_o)); fmax(:) = spval + call mkfmax ( mapfname=map_fmax, datfname=mksrf_fmax, ndiag=ndiag, fmax_o=fmax) - ! ! Make VOC emission factors for isoprene & - ! ! [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] - ! allocate ( ef1_btr(lsize_o) , & - ! ef1_fet(lsize_o) , & - ! ef1_fdt(lsize_o) , & - ! ef1_shr(lsize_o) , & - ! ef1_grs(lsize_o) , & - ! ef1_crp(lsize_o) ) - ! ef1_btr(:) = 0._r8 - ! ef1_fet(:) = 0._r8 - ! ef1_fdt(:) = 0._r8 - ! ef1_shr(:) = 0._r8 - ! ef1_grs(:) = 0._r8 - ! ef1_crp(:) = 0._r8 - - ! call mkvocef ( mapfname=map_fvocef, datfname=mksrf_fvocef, ndiag=ndiag, & - ! ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & - ! ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp) - - ! ! Do landuse changes such as for the poles, etc. - ! call change_landuse( dynpft=.false. ) + ! Make GDP data [gdp] from [gdp] + call mkgdp ( mapfname=map_fgdp, datfname=mksrf_fgdp, ndiag=ndiag, gdp_o=gdp) + + ! Make peat data [fpeat] from [peatf] + call mkpeat ( mapfname=map_fpeat, datfname=mksrf_fpeat, ndiag=ndiag, peat_o=fpeat) + + ! Make soil depth data [soildepth] from [soildepthf] + call mksoildepth ( mapfname=map_fsoildepth, datfname=mksrf_fsoildepth, ndiag=ndiag, soildepth_o=soildepth) + + ! Make agricultural fire peak month data [abm] from [abm] + call mkagfirepkmon ( mapfname=map_fabm, datfname=mksrf_fabm, ndiag=ndiag, agfirepkmon_o=agfirepkmon) +#endif + +#ifdef TODO + ! Make elevation [elev] from [ftopo, ffrac] dataset + ! Used only to screen pcturb, screen pcturb by elevation threshold from elev dataset + if ( .not. all_urban .and. .not. all_veg )then + allocate(elev(lsize_o)) + elev(:) = spval + ! NOTE(wjs, 2016-01-15) This uses the 'TOPO_ICE' variable for historical reasons + ! (this same dataset used to be used for glacier-related purposes as well). + ! TODO(wjs, 2016-01-15) A better solution for this urban screening would probably + ! be to modify the raw urban data; in that case, I believe we could remove furbtopo. + call mkelev ( mapfname=map_furbtopo, datfname=mksrf_furbtopo, varname='TOPO_ICE', ndiag=ndiag, elev_o=elev) + where (elev .gt. elev_thresh) + pcturb = 0._r8 + end where + deallocate(elev) + end if + + ! Compute topography statistics [topo_stddev, slope] from [ftopostats] + call mktopostats ( mapfname=map_ftopostats, datfname=mksrf_ftopostats, & + ndiag=ndiag, topo_stddev_o=topo_stddev, slope_o=slope, std_elev=std_elev) + + ! Make VIC parameters [binfl, ws, dsmax, ds] from [fvic] + if ( outnc_vic )then + call mkVICparams ( mapfname=map_fvic, datfname=mksrf_fvic, ndiag=ndiag, & + binfl_o=vic_binfl, ws_o=vic_ws, dsmax_o=vic_dsmax, ds_o=vic_ds) + end if + + ! Make VOC emission factors for isoprene [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] + call mkvocef ( mapfname=map_fvocef, datfname=mksrf_fvocef, ndiag=ndiag, & + ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & + ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp) + + ! Do landuse changes such as for the poles, etc. + call change_landuse( dynpft=.false. ) +#endif ! ---------------------------------------------------------------------- ! Modify interpolated fields based on additional constrants @@ -568,24 +583,20 @@ program mksurfdata ! Make final values of percent urban by class ! This call needs to occur after all corrections are made to pcturb - call normalize_classes_by_gcell(urbn_classes, pcturb, urbn_classes_g) + call normalize_classes_by_gcell(urban_classes, pcturb, urban_classes_g) + ! ---------------------------------------------------------------------- ! Make glacier multiple elevation classes [pctglcmec,topoglcmec] from [fglacier] dataset + ! ---------------------------------------------------------------------- + ! This call needs to occur after pctgla has been adjusted for the final time - allocate (pctglcmec(lsize_o,nglcec), & - topoglcmec(lsize_o,nglcec) ) if ( outnc_3dglc )then - allocate( pctglcmec_gic(lsize_o,nglcec), & - pctglcmec_icesheet(lsize_o,nglcec)) - allocate (pctglc_gic(lsize_o)) - allocate (pctglc_icesheet(lsize_o)) - end if - - pctglcmec(:,:) = spval - topoglcmec(:,:) = spval + allocate(pctglcmec_gic(lsize_o,nglcec)) + allocate(pctglcmec_icesheet(lsize_o,nglcec)) + allocate(pctglc_gic(lsize_o)) + allocate(pctglc_icesheet(lsize_o)) - if ( outnc_3dglc )then call mkglcmec ( mapfname=map_fglacier, & datfname_fglacier=mksrf_fglacier, ndiag=ndiag, & pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, & @@ -628,7 +639,8 @@ program mksurfdata !call mkfile_fsurdat( mksrf_fgrid_mesh_nx, mksrf_fgrid_mesh_ny, mesh_model, dynlanduse=.false., harvdata) call ESMF_LogWrite("Calling mkfile_fsurdat", ESMF_LOGMSG_INFO) call mkfile_fsurdat( mksrf_fgrid_mesh_nx, mksrf_fgrid_mesh_ny, mesh_model, dynlanduse=.false., & - pctlak=pctlak, pctwet=pctwet, lakedepth=lakedepth, organic=organic) + pctlak=pctlak, pctwet=pctwet, lakedepth=lakedepth, organic=organic, & + urban_classes=urban_classes, urban_region=urban_region) call ESMF_LogWrite(subname//'successfully created file '//trim(fsurdat), ESMF_LOGMSG_INFO) end if ! if (fsurdat /= ' ') @@ -1166,8 +1178,8 @@ subroutine normalizencheck_landuse(ldomain) ! (Also note that we don't need to check pctnatpft or pctcft, because a similar check ! is done internally by the pct_pft_type routines.) do n = 1,ns_o - if (abs(sum(urbn_classes(n,:)) - 100._r8) > 1.e-12_r8) then - write(6,*) 'sum(urbn_classes(n,:)) != 100: ', n, sum(urbn_classes(n,:)) + if (abs(sum(urban_classes(n,:)) - 100._r8) > 1.e-12_r8) then + write(6,*) 'sum(urban_classes(n,:)) != 100: ', n, sum(urban_classes(n,:)) call shr_sys_abort() end if end do diff --git a/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 index 0ca622d051..70d61cb02a 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 @@ -1,10 +1,6 @@ module mkurbanparCommonMod + !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mkurbanparCommon - ! - ! !DESCRIPTION: ! Common routines for making urban parameter data, independent of the method used for ! making the urban parameters (e.g., averages, dominant type, etc.) ! @@ -13,136 +9,27 @@ module mkurbanparCommonMod ! separate mkurbanparCommonMod in case a similar split comes back in the future. However, ! if such a split seems unlikely in the future, these routines could be moved back into ! mkurbanparMod.) - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! !----------------------------------------------------------------------- - ! !USES: + use shr_kind_mod, only : r8 => shr_kind_r8 - implicit none + implicit none private - ! !PUBLIC MEMBER FUNCTIONS: - public :: mkurban_pct ! Make output urban %, given input urban % - public :: mkurban_pct_diagnostics ! print diagnostics related to pct urban - public :: mkelev ! Get elevation to reduce urban for high elevation areas - ! - ! !PUBLIC DATA MEMBERS: - ! - real(r8), parameter :: MIN_DENS = 0.1_r8 ! minimum urban density (% of grid cell) - below this value, urban % is set to 0 + ! !public member functions: +#ifdef TODO + public :: mkurban_pct_diagnostics ! print diagnostics related to pct urban + public :: mkelev ! Get elevation to reduce urban for high elevation areas +#endif + + ! !public data members: + real(r8), parameter :: MIN_DENS = 0.1_r8 ! minimum urban density (% of grid cell) - below this value, urban % is set to 0 public :: MIN_DENS - ! - !EOP +#ifdef TODO contains - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkurban_pct - ! - ! !INTERFACE: - subroutine mkurban_pct(ldomain, tdomain, tgridmap, urbn_i, urbn_o, frac_dst) - ! - ! !DESCRIPTION: - ! make percent urban on output grid, given percent urban on input grid - ! - ! This assumes that we're neither using all_urban or zero_out - ! - ! - ! !USES: - use mkdomainMod , only : domain_type, domain_checksame - use mkgridmapMod - use mkvarctl , only : mksrf_gridtype - ! - ! !ARGUMENTS: - implicit none - type(domain_type) , intent(in) :: ldomain - type(domain_type) , intent(in) :: tdomain ! local domain - type(gridmap_type), intent(in) :: tgridmap ! local gridmap - real(r8) , intent(in) :: urbn_i(:) ! input grid: percent urban - real(r8) , intent(in) :: frac_dst(:) ! output fractions - real(r8) , intent(out):: urbn_o(:) ! output grid: percent urban - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! (Moved from mkurbanparMod Feb, 2012) - ! - ! - ! !LOCAL VARIABLES: - !EOP - integer :: ier ! error status - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - integer :: ni,no ! indices - real(r8) :: relerr = 0.00001_r8 ! max error: sum overlap wts ne 1 - character(len=*), parameter :: subname = 'mkurban_pct' - !----------------------------------------------------------------------- - - ! Error checks for array size consistencies - - if (size(urbn_i) /= tdomain%ns .or. & - size(urbn_o) /= ldomain%ns) then - write(6,*) subname//' ERROR: array size inconsistencies' - write(6,*) 'size(urbn_i) = ', size(urbn_i) - write(6,*) 'tdomain%ns = ', tdomain%ns - write(6,*) 'size(urbn_o) = ', size(urbn_o) - write(6,*) 'ldomain%ns = ', ldomain%ns - call shr_sys_abort() - end if - if (size(frac_dst) /= ldomain%ns) then - write(6,*) subname//' ERROR: array size inconsistencies' - write(6,*) 'size(frac_dst) = ', size(frac_dst) - write(6,*) 'ldomain%ns = ', ldomain%ns - call shr_sys_abort() - end if - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Determine urbn_o on ouput grid: - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. - - call gridmap_areaave_srcmask(tgridmap, urbn_i, urbn_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check for conservation - - do no = 1, ldomain%ns - if ((urbn_o(no)) > 100.000001_r8) then - write (6,*) 'MKURBAN error: urban = ',urbn_o(no), & - ' greater than 100.000001 for column, row = ',no - call shr_sys_abort() - end if - enddo - - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - - allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call shr_sys_abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! (Error check2 in mkurban_pct_diagnostics, which should be called separately) - - deallocate (mask_r8) - - end subroutine mkurban_pct - !----------------------------------------------------------------------- - - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkurban_pct_diagnostics - ! - ! !INTERFACE: subroutine mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, urbn_i, urbn_o, ndiag, dens_class, frac_dst) ! ! !DESCRIPTION: @@ -245,17 +132,10 @@ subroutine mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, urbn_i, urbn_o, n 2004 format (1x,'all surface ',f14.3,f17.3) end subroutine mkurban_pct_diagnostics - !----------------------------------------------------------------------- !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkelev - ! - ! !INTERFACE: subroutine mkelev(ldomain, mapfname, datfname, varname, ndiag, elev_o) ! - ! !DESCRIPTION: ! Make elevation data ! ! !USES: @@ -267,27 +147,16 @@ subroutine mkelev(ldomain, mapfname, datfname, varname, ndiag, elev_o) use mkdiagnosticsMod, only : output_diagnostics_continuous ! ! !ARGUMENTS: - implicit none type(domain_type), intent(in) :: ldomain character(len=*) , intent(in) :: mapfname ! input mapping file name character(len=*) , intent(in) :: datfname ! input data file name integer , intent(in) :: ndiag ! unit number for diag out character(len=*) , intent(in) :: varname ! topo variable name real(r8) , intent(out):: elev_o(:) ! output elevation data - ! - ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: Keith Oleson - ! - ! + ! !LOCAL VARIABLES: - !EOP type(domain_type) :: tdomain ! local domain type(gridmap_type) :: tgridmap ! local gridmap - real(r8), allocatable :: elev_i(:) ! canyon_height to width ratio in real(r8), allocatable :: frac_dst(:) ! output fractions integer :: ns_i,ns_o ! indices @@ -356,5 +225,7 @@ subroutine mkelev(ldomain, mapfname, datfname, varname, ndiag, elev_o) write (6,*) end subroutine mkelev +#endif + +end module mkurbanparCommonMod - module mkurbanparCommonMod diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 0b8e0c95b1..965c1dc133 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -1,112 +1,87 @@ module mkurbanparMod + !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mkurbanpar - ! - ! !DESCRIPTION: ! Make Urban Parameter data - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! !----------------------------------------------------------------------- - ! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkvarctl, only : ispval - implicit none + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, cs => shr_kind_cs + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem + use mkpioMod , only : mkpio_iodesc_output, mkpio_def_spatial_var, mkpio_wopen + use mkpioMod , only : mkpio_get_dimlengths, mkpio_get_rawdata + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkesmfMod , only : regrid_rawdata + use mkutilsMod , only : chkerr + use mkvarctl , only : root_task, ndiag, ispval, fsurdat, outnc_double + + implicit none private - ! !PUBLIC MEMBER FUNCTIONS: public :: mkurbanInit public :: mkurban public :: mkurbanpar - - ! The following could be private, but because there are associated test routines in a - ! separate module, it needs to be public public :: normalize_urbn_by_tot - ! !PUBLIC DATA MEMBERS: - integer :: numurbl ! number of urban classes - integer :: nlevurb = ispval ! number of urban layers + ! Note: normalize_urbn_by_tot could be private, but because there + ! are associated test routines in a separate module, it needs to be public - public :: numurbl - public :: nlevurb + ! public data members + integer, public :: numurbl ! number of urban classes + integer, public :: nlevurb = ispval ! number of urban layers - ! !PRIVATE DATA MEMBERS: + ! private data members: ! flag to indicate nodata for index variables in output file: - integer, parameter :: index_nodata = 0 + integer , parameter :: index_nodata = 0 character(len=*), parameter :: modname = 'mkurbanparMod' private :: index_nodata private :: modname - !EOP + character(len=*) , parameter :: u_FILE_u = & + __FILE__ +!=============================================================== contains +!=============================================================== - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkurbanInit - ! - ! !INTERFACE: subroutine mkurbanInit(datfname) ! - ! !DESCRIPTION: ! Initialize variables needed for urban ! - ! !USES: - use mkncdio - ! - ! !ARGUMENTS: - implicit none + ! input variables character(len=*), intent(in) :: datfname ! input data file name (same as file used in mkurban) ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! - ! - ! !LOCAL VARIABLES: - integer :: ncid,dimid ! input netCDF id's - + ! local variables: + type(file_desc_t) :: pioid + integer :: dimid + integer :: rcode character(len=*), parameter :: subname = 'mkurbanInit' - !EOP !----------------------------------------------------------------------- - ! Set numurbl - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_dimid (ncid, 'density_class', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, numurbl), subname) - call check_ret(nf_inq_dimid (ncid, 'nlevurb', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, nlevurb), subname) - call check_ret(nf_close(ncid), subname) + ! Set numurbl and nlevurb + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(datfname), pio_nowrite) + rcode = pio_inq_dimid(pioid, 'density_class', dimid) + rcode = pio_inq_dimlen(pioid, dimid, numurbl) + rcode = pio_inq_dimid(pioid, 'nlevurb', dimid) + rcode = pio_inq_dimlen(pioid, dimid, dimid) + call pio_closefile(pioid) end subroutine mkurbanInit - !----------------------------------------------------------------------- - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkurban - ! - ! !INTERFACE: - subroutine mkurban(ldomain, mapfname, datfname, ndiag, zero_out, & - urbn_o, urbn_classes_o, region_o) + !=============================================================== + subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & + zero_out, urbn_o, urban_classes_o, region_o, rc) ! - ! !DESCRIPTION: ! make total percent urban, breakdown into urban classes, and region ID on the output grid ! - ! urbn_classes_o(n, i) gives the percent of the urban area in grid cell n that is in class #i. - ! This is normalized so that sum(urbn_classes_o(n,:)) = 100 for all n, even for grid + ! urban_classes_o(n, i) gives the percent of the urban area in grid cell n that is in class #i. + ! This is normalized so that sum(urban_classes_o(n,:)) = 100 for all n, even for grid ! cells where urbn_o(n) = 0 (in the case where urbn_o(n) = 0, we come up with an ! arbitrary assignment of urban into the different classes). ! - ! See comments under the normalize_urbn_by_tot subroutine for how urbn_classes_o is + ! See comments under the normalize_urbn_by_tot subroutine for how urban_classes_o is ! determined when the total % urban is 0, according to the input data. Note that this ! also applies when all_urban=.true., for points that have 0 urban according to the input ! data. @@ -116,96 +91,164 @@ subroutine mkurban(ldomain, mapfname, datfname, ndiag, zero_out, & ! better, in terms of maintaining helpful abstractions, there could be a new type to ! handle urban, and both that and pct_pft_type could be build on a single set of shared ! code - either as a single base class or through a "has-a" mechanism). This would allow - ! us to combine urbn_o and urbn_classes_o into a single derived type variable. I think + ! us to combine urbn_o and urban_classes_o into a single derived type variable. I think ! this would also replace the use of normalize_classes_by_gcell, and maybe some other ! urban-specific code. ! - ! !USES: - use mkdomainMod , only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkindexmapMod, only : get_dominant_indices - use mkurbanparCommonMod, only : mkurban_pct, mkurban_pct_diagnostics, MIN_DENS - use mkutilsMod , only : normalize_classes_by_gcell - use mkvarctl , only : all_urban + use mkindexmapMod , only : get_dominant_indices +#ifdef TODO + use mkurbanparCommonMod , only : mkurban_pct_diagnostics +#endif + use mkurbanparCommonMod , only : MIN_DENS + use mkutilsMod , only : normalize_classes_by_gcell + use mkvarctl , only : all_urban use mkvarpar - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_index - ! - ! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - logical , intent(in) :: zero_out ! if should zero urban out - real(r8) , intent(out):: urbn_o(:) ! output grid: total % urban - real(r8) , intent(out):: urbn_classes_o(:,:) ! output grid: breakdown of total urban into each class - ! (dimensions: (ldomain%ns, numurbl)) - integer , intent(out):: region_o(:) ! output grid: region ID - ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! - ! - ! !LOCAL VARIABLES: - !EOP - type(domain_type) :: tdomain ! local domain - type(gridmap_type) :: tgridmap ! local gridmap - real(r8), allocatable :: urbn_classes_gcell_i(:,:) ! input grid: percent urban in each density class - ! (% of total grid cell area) - real(r8), allocatable :: urbn_classes_gcell_o(:,:) ! output grid: percent urban in each density class - real(r8), allocatable :: frac_dst(:) ! output fractions - ! (% of total grid cell area) - integer , allocatable :: region_i(:) ! input grid: region ID - integer :: ni,no,ns,k ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: dimlen ! netCDF dimension length - integer :: max_region ! maximum region index - integer :: ier ! error status - +#ifdef TODO + use mkdiagnosticsMod , only : output_diagnostics_index +#endif + + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh + logical , intent(in) :: zero_out ! if should zero urban out + real(r8) , intent(out) :: urbn_o(:) ! output grid: total % urban + real(r8) , intent(out) :: urban_classes_o(:,:) ! output grid: breakdown of total urban into each class + integer , intent(out) :: region_o(:) ! output grid: region ID + integer , intent(out) :: rc + + ! local variables: + integer , pointer :: factorindexlist(:,:) + real(r8), pointer :: factorlist(:) + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + type(file_desc_t) :: pioid + real(r8), allocatable :: urban_classes_gcell_i(:,:) ! input grid: percent urban in each density class (% of total grid cell area) + real(r8), allocatable :: urban_classes_gcell_o(:,:) ! output grid: percent urban in each density class (% of total grid cell area) + real(r8), allocatable :: data_i(:,:) + real(r8), allocatable :: data_o(:,:) + integer , allocatable :: region_i(:) ! input grid: region ID + integer :: ni,no ! indices + integer :: n,k,l ! indices + integer :: ns_i, ns_o ! array sizes + integer :: dimlen ! netCDF dimension length + integer, allocatable :: dimlengths(:) + integer :: ndims + integer :: max_region ! maximum region index + integer :: rcode, ier ! error status + integer :: srcMaskValue = -987987 ! spval for RH mask values + integer :: dstMaskValue = -987987 ! spval for RH mask values + integer :: srcTermProcessing_Value = 0 character(len=*), parameter :: subname = 'mkurban' !----------------------------------------------------------------------- - write (6,*) 'Attempting to make %urban .....' - - ! Obtain input grid info, read local fields + rc = ESMF_SUCCESS - call gridmap_mapread(tgridmap, mapfname) - call domain_read(tdomain, datfname) - - ns = tdomain%ns + if (root_task) then + write (ndiag,'(a)') 'Attempting to make %urban .....' + end if - allocate(urbn_classes_gcell_i(ns, numurbl), & - urbn_classes_gcell_o(ldomain%ns, numurbl), & - frac_dst(ldomain%ns), & - stat=ier) + ! Open raw data file - need to do this first to obtain ungridded dimension size + if (root_task) then + write (ndiag,'(a)') 'Opening urban file: '//trim(file_data_i) + end if + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) + + ! Read in input mesh + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_i and allocate urban_classes_gcell_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + allocate(data_i(numurbl,ns_i),stat=ier) if (ier/=0) call shr_sys_abort() - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - write (6,*) 'Open urban file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_URBAN', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, urbn_classes_gcell_i), subname) + ! Determine ns_o and allocate data_o + ns_o = size(urbn_o, dim=1) + if (ier/=0) call shr_sys_abort() + allocate(data_o(numurbl,ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() - ! Determine % urban by density class on the output grid - do k = 1, numurbl - call mkurban_pct(ldomain, tdomain, tgridmap, urbn_classes_gcell_i(:,k), urbn_classes_gcell_o(:,k), frac_dst) + ! Read in input data + ! - levels are the innermost dimension for esmf fields + ! - levels are the outermost dimension in pio reads + ! Input data is read into (ns_i,numurbl) array and then transferred to urban_classes_gcell_i(numurbl,ns_i) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'PCT_URBAN', mesh_i, urban_classes_gcell_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + + ! Create field on input mesh - using dimension information from raw data file + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/1/), ungriddedUbound=(/numurbl/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After field_i creation in "//trim(subname)) + + ! Create field on model model + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/1/), ungriddedUbound=(/numurbl/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After field_o creation in "//trim(subname)) + + ! Create route handle to map field_model to field_data + call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + !srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_DSTAREA, & + srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & + factorlist=factorlist, factorindexlist=factorindexlist, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) + + ! Regrid raw data to model resolution + ! make percent urban on output grid, given percent urban on input grid + ! This assumes that we're neither using all_urban or zero_out + ! Determine urbn_o on ouput grid: + ! Area-average percent cover on input grid to output grid + ! and correct according to land landmask + ! Note that percent cover is in terms of total grid area. + call regrid_rawdata(field_i, field_o, routehandle, data_i, data_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regrid_data in "//trim(subname)) + + ! Now Determine total % urban + call ESMF_LogWrite("Before allocate of urban_classes_gcell_o", ESMF_LOGMSG_INFO) + allocate(urban_classes_gcell_o(ns_o, numurbl), stat=ier) + if (ier/=0) call shr_sys_abort() + call ESMF_LogWrite("Before loop", ESMF_LOGMSG_INFO) + do l = 1,numurbl + do n = 1,ns_o + urban_classes_gcell_o(n,l) = data_o(l,n) + end do end do - - ! Determine total % urban - do no = 1, ldomain%ns - urbn_o(no) = sum(urbn_classes_gcell_o(no,:)) + do n = 1, ns_o + urbn_o(n) = sum(urban_classes_gcell_o(n,:)) end do + call ESMF_LogWrite("After loop", ESMF_LOGMSG_INFO) + + ! Check for conservation + do no = 1, ns_o + if ((urbn_o(no)) > 100.000001_r8) then + write (6,'(a,i8,a,i8)') 'MKURBAN error: percent urban = ',urbn_o(no), & + ' greater than 100.000001 for no = ',no + !call shr_sys_abort() + end if + enddo + !call shr_sys_abort() - call normalize_urbn_by_tot(urbn_classes_gcell_o, urbn_o, urbn_classes_o) + ! determine urban_classes_o + call ESMF_LogWrite("Before normalize_urbn", ESMF_LOGMSG_INFO) + call normalize_urbn_by_tot(urban_classes_gcell_o, urbn_o, urban_classes_o) + call ESMF_LogWrite("After normalize_urbn", ESMF_LOGMSG_INFO) ! Handle special cases - ! Note that, for all these adjustments of total urban %, we do not change anything ! about the breakdown into the different urban classes. In particular: when urbn_o is ! set to 0 for a point, the breakdown into the different urban classes is maintained @@ -216,7 +259,7 @@ subroutine mkurban(ldomain, mapfname, datfname, ndiag, zero_out, & urbn_o(:) = 0._r8 else ! Set points to 0% if they fall below a given threshold - do no = 1, ldomain%ns + do no = 1, ns_o if (urbn_o(no) < MIN_DENS) then urbn_o(no) = 0._r8 end if @@ -224,29 +267,37 @@ subroutine mkurban(ldomain, mapfname, datfname, ndiag, zero_out, & end if ! Print diagnostics - ! First, recompute urbn_classes_gcell_o, based on any changes we have made to urbn_o + ! First, recompute urban_classes_gcell_o, based on any changes we have made to urbn_o ! while handling special cases - call normalize_classes_by_gcell(urbn_classes_o, urbn_o, urbn_classes_gcell_o) + call ESMF_LogWrite("Before normalize_classes_by_gcell", ESMF_LOGMSG_INFO) + call normalize_classes_by_gcell(urban_classes_o, urbn_o, urban_classes_gcell_o) + call ESMF_LogWrite("After normalize_classes_by_gcell", ESMF_LOGMSG_INFO) + +#ifdef TODO do k = 1, numurbl call mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, & - urbn_classes_gcell_i(:,k), urbn_classes_gcell_o(:,k), & + urban_classes_gcell_i(:,k), urban_classes_gcell_o(:,k), & ndiag, dens_class=k, frac_dst=frac_dst) end do - - write (6,*) 'Successfully made %urban' - - - write(6,*) 'Attempting to make urban region .....' +#endif + if (root_task) then + write (ndiag,'(a)') 'Successfully made %urban' + write (ndiag,'(a)') 'Attempting to make urban region .....' + end if ! Read in region field ! Note: we do this here, rather than with the rest of the reads above, because we ! expect the input urban fields to be large, so we're just reading the fields as ! they're needed to try to avoid unnecessary memory paging + ! REGION_ID is (lsmlon,lsmlat) but integer - so use pio and create and iodesc to read this in + ! for the local grid points - allocate(region_i(ns), stat=ier) + allocate(region_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call check_ret(nf_inq_varid (ncid, 'REGION_ID', varid), subname) - call check_ret(nf_get_var_int (ncid, varid, region_i), subname) + call ESMF_LogWrite("Before mkpio_get_rawdata", ESMF_LOGMSG_INFO) + call mkpio_get_rawdata(pioid, 'REGION_ID', mesh_i, region_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite("After mkpio_get_rawdata", ESMF_LOGMSG_INFO) ! Determine max region value, and make sure it doesn't exceed bounds of the lookup tables. ! @@ -256,48 +307,59 @@ subroutine mkurban(ldomain, mapfname, datfname, ndiag, zero_out, & ! between region values and the indices of the lookup table; however, this use of ! coordinate variables currently isn't supported by lookup_2d_netcdf [as of 2-8-12].) + call ESMF_LogWrite("Before allocate dimlengths", ESMF_LOGMSG_INFO) + allocate(dimlengths(2)) + call mkpio_get_dimlengths(pioid, trim('REGION_ID'), ndims, dimlengths) max_region = maxval(region_i) - call check_ret(nf_inq_dimid (ncid, 'region', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, dimlen), subname) - if (max_region > dimlen) then + if (max_region > dimlengths(2)) then write(6,*) modname//':'//subname// & ' ERROR: max region value exceeds length of region dimension' write(6,*) 'max region value : ', max_region - write(6,*) 'length of region dimension: ', dimlen + write(6,*) 'length of region dimension: ', dimlengths(2) call shr_sys_abort() end if + deallocate(dimlengths) + call ESMF_LogWrite("After allocate dimlengths", ESMF_LOGMSG_INFO) ! Determine dominant region for each output cell + call ESMF_LogWrite("Before get_dominant_indices", ESMF_LOGMSG_INFO) + call get_dominant_indices(factorindexlist, factorlist, & + src_array=region_i, dst_array=region_o, & + minval=1, maxval=max_region, nodata=index_nodata) + call ESMF_LogWrite("After get_dominant_indices", ESMF_LOGMSG_INFO) + + if (root_task) then + write (ndiag,'(a)') 'Successfully made urban region' + write (ndiag,*) + end if - call get_dominant_indices(tgridmap, region_i, region_o, 1, max_region, index_nodata, mask_src=tdomain%mask) - - write (6,*) 'Successfully made urban region' - write (6,*) - +#ifdef TODO ! Output diagnostics + ! call output_diagnostics_index(factorlist, factorindex, region_i, region_o, 'Urban Region ID', & + ! 1, max_region, ndiag) +#endif - call output_diagnostics_index(region_i, region_o, tgridmap, 'Urban Region ID', & - 1, max_region, ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) + ! Close the file + call pio_closefile(pioid) ! Deallocate dynamic memory & other clean up - - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (urbn_classes_gcell_i, urbn_classes_gcell_o, region_i, frac_dst) + deallocate (urban_classes_gcell_i, urban_classes_gcell_o, region_i) + + call ESMF_VMLogMemInfo("Before destroy operation in "//trim(subname)) + deallocate(factorlist, factorindexlist) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("after destroy operation in "//trim(subname)) end subroutine mkurban - !----------------------------------------------------------------------- - !------------------------------------------------------------------------------ - !BOP - ! - ! !IROUTINE: normalize_urbn_by_tot - ! - ! !INTERFACE: + !=============================================================== subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) ! - ! !DESCRIPTION: ! Normalizes urban class areas to produce % cover of each class, as % of total urban area ! ! Specifically: Given (1) an array specifying the % cover of each urban class, as a % of @@ -312,23 +374,15 @@ subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) ! rule that all area is assigned to the medium-density class, defined by parameter MD. ! ! The returned array satisfies sum(classes_pct_tot(n,:))==100 for all n (within rounding error) - ! - ! !USES: - ! - ! !ARGUMENTS: - implicit none + + ! input/output variables real(r8), intent(in) :: classes_pct_gcell(:,:) ! % cover of classes as % of grid cell real(r8), intent(in) :: sums(:) ! totals, as % of grid cell real(r8), intent(out):: classes_pct_tot(:,:) ! % cover of classes as % of total - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! - ! - ! !LOCAL VARIABLES: - !EOP + + ! local variables: integer :: n ! index - integer :: n_max ! number of points + integer :: n_max ! number of points integer :: nclasses ! number of classes real(r8) :: suma ! sum for error check @@ -346,7 +400,7 @@ subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) n_max = size(sums) if (size(classes_pct_tot, 1) /= n_max .or. & - size(classes_pct_gcell, 1) /= n_max) then + size(classes_pct_gcell, 1) /= n_max) then write(6,*) subname//' ERROR: array size mismatch' write(6,*) 'size(sums) = ', n_max write(6,*) 'size(classes_pct_tot, 1) = ', size(classes_pct_tot, 1) @@ -394,17 +448,11 @@ subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) end do end subroutine normalize_urbn_by_tot - !----------------------------------------------------------------------- - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkurbanpar - ! - ! !INTERFACE: - subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_skip_abort_on_invalid_data_check) + !=============================================================== + subroutine mkurbanpar(datfname_i, mesh_o, & + region_o, urban_classes_gcell_o, urban_skip_abort_on_invalid_data_check) ! - ! !DESCRIPTION: ! Make Urban Parameter data ! ! Note that, in a grid cell with region_o==r, parameter values are filled from region r @@ -415,54 +463,43 @@ subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_ski ! each parameter) wherever (1) we have a nodata value for region_o, or (2) the parameter ! has nodata for the given region/density combination in the input lookup table. ! - ! !USES: - use mkdomainMod , only : domain_type, domain_clean, domain_read use mkindexmapMod, only : dim_slice_type, lookup_2d_netcdf use mkvarpar - use mkncdio ! - ! !ARGUMENTS: - implicit none - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ncido ! output netcdf file id + ! input/output variables + character(len=*) , intent(in) :: datfname_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh integer , intent(in) :: region_o(:) ! output grid: region ID (length: ns_o) - real(r8) , intent(in) :: urbn_classes_gcell_o(:,:) ! output grid: percent urban in each density class - ! (% of total grid cell area) (dimensions: ns_o, numurbl) + real(r8) , intent(in) :: urban_classes_gcell_o(:,:) ! output grid: percent urban in each density class + ! (% of total grid cell area) (dimensions: ns_o, numurbl) logical , intent(in) :: urban_skip_abort_on_invalid_data_check - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! - ! - ! !LOCAL VARIABLES: - !EOP + ! local variables ! Type to store information about each urban parameter type param character(len=32) :: name ! name in input & output files real(r8) :: fill_val ! value to put where we have no data in output logical :: check_invalid ! should we check whether there are any invalid data in the output? end type param - - real(r8), allocatable :: data_scalar_o(:,:) ! output array for parameters with no extra dimensions - real(r8), allocatable :: data_rad_o(:,:,:,:) ! output array for parameters dimensioned by numrad & numsolar - real(r8), allocatable :: data_levurb_o(:,:,:) ! output array for parameters dimensioned by nlevurb - integer , allocatable :: unity_dens_o(:,:) ! artificial density indices - integer :: nlevurb_i ! input grid: number of urban vertical levels - integer :: numsolar_i ! input grid: number of solar type (DIR/DIF) - integer :: numrad_i ! input grid: number of solar bands (VIS/NIR) - integer :: m,n,no,ns_o,p,k ! indices - integer :: ncidi,dimid,varid ! netCDF id's - integer :: ier ! error status - character(len=nf_max_name) :: varname ! variable name - + real(r8), allocatable :: data_scalar_o(:,:) ! output array for parameters with no extra dimensions + real(r8), allocatable :: data_rad_o(:,:,:,:) ! output array for parameters dimensioned by numrad & numsolar + real(r8), allocatable :: data_levurb_o(:,:,:) ! output array for parameters dimensioned by nlevurb + integer , allocatable :: unity_dens_o(:,:) ! artificial density indices + integer :: nlevurb_i ! input grid: number of urban vertical levels + integer :: numsolar_i ! input grid: number of solar type (DIR/DIF) + integer :: numrad_i ! input grid: number of solar bands (VIS/NIR) + integer :: m,n,no,ns_o,p,k ! indices + type(file_desc_t) :: pioid_i + type(file_desc_t) :: pioid_o + type(var_desc_t) :: pio_varid + integer :: pio_vartype + type(io_desc_t) :: pio_iodesc + integer :: dimid + integer :: ier, rcode, rc ! error status + character(len=cs) :: varname ! variable name + integer :: xtype ! external type ! information on extra dimensions for lookup tables greater than 2-d: - type(dim_slice_type), allocatable :: extra_dims(:) - - ! suffix for variables dimensioned by numsolar, for each value of numsolar: - character(len=8), parameter :: solar_suffix(numsolar) = (/'_DIR', '_DIF'/) + type(dim_slice_type), allocatable :: extra_dims(:) ! value to put where we have no data in output variables, for real-valued parameters real(r8), parameter :: fill_val_real = 0._r8 @@ -472,44 +509,47 @@ subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_ski ! Urban parameters with no extra dimensions type(param), parameter :: params_scalar(13) = & - (/ param('CANYON_HWR', fill_val_real, .true.), & - param('EM_IMPROAD', fill_val_real, .true.), & - param('EM_PERROAD', fill_val_real, .true.), & - param('EM_ROOF', fill_val_real, .true.), & - param('EM_WALL', fill_val_real, .true.), & - param('HT_ROOF', fill_val_real, .true.), & - param('THICK_ROOF', fill_val_real, .true.), & - param('THICK_WALL', fill_val_real, .true.), & - param('T_BUILDING_MIN', fill_val_real, .true.), & - param('WIND_HGT_CANYON', fill_val_real, .true.), & - param('WTLUNIT_ROOF', fill_val_real, .true.), & - param('WTROAD_PERV', fill_val_real, .true.), & - - ! Note that NLEV_IMPROAD is written as an integer, meaning that type conversion occurs - ! by truncation. Thus we expect the values in the NLEV_IMPROAD lookup table to be exact; - ! e.g., if a value were 1.99999 rather than 2.0000, it would be written as 1 instead of 2 - ! Also note: we use fill_val=-1 rather than 0, because 0 appears in the lookup table - param('NLEV_IMPROAD', -1, .true.) /) + (/ param('CANYON_HWR' , fill_val_real, .true.), & ! 1 + param('EM_IMPROAD' , fill_val_real, .true.), & ! 2 + param('EM_PERROAD' , fill_val_real, .true.), & ! 3 + param('EM_ROOF' , fill_val_real, .true.), & ! 4 + param('EM_WALL' , fill_val_real, .true.), & ! 5 + param('HT_ROOF' , fill_val_real, .true.), & ! 6 + param('THICK_ROOF' , fill_val_real, .true.), & ! 7 + param('THICK_WALL' , fill_val_real, .true.), & ! 8 + param('T_BUILDING_MIN' , fill_val_real, .true.), & ! 9 + param('WIND_HGT_CANYON' , fill_val_real, .true.), & ! 10 + param('WTLUNIT_ROOF' , fill_val_real, .true.), & ! 11 + param('WTROAD_PERV' , fill_val_real, .true.), & ! 12 + + ! Note that NLEV_IMPROAD is written as an integer, meaning that type conversion occurs + ! by truncation. Thus we expect the values in the NLEV_IMPROAD lookup table to be exact; + ! e.g., if a value were 1.99999 rather than 2.0000, it would be written as 1 instead of 2 + ! Also note: we use fill_val=-1 rather than 0, because 0 appears in the lookup table + param('NLEV_IMPROAD' , -1 , .true.) /) ! 13 ! Urban parameters dimensioned by numrad & numsolar type(param), parameter :: params_rad(4) = & - (/ param('ALB_IMPROAD', fill_val_real, .true.), & - param('ALB_PERROAD', fill_val_real, .true.), & - param('ALB_ROOF', fill_val_real, .true.), & - param('ALB_WALL', fill_val_real, .true.) /) + (/ param('ALB_IMPROAD' , fill_val_real, .true.), & ! 1 + param('ALB_PERROAD' , fill_val_real, .true.), & ! 2 + param('ALB_ROOF' , fill_val_real, .true.), & ! 3 + param('ALB_WALL' , fill_val_real, .true.) /) ! 4 + + ! suffix for variables dimensioned by numsolar, for each value of numsolar: + character(len=8), parameter :: solar_suffix(numsolar) = (/'_DIR', '_DIF'/) ! Urban parameters dimensioned by nlevurb type(param), parameter :: params_levurb(6) = & - (/ param('TK_ROOF', fill_val_real, .true.), & - param('TK_WALL', fill_val_real, .true.), & - param('CV_ROOF', fill_val_real, .true.), & - param('CV_WALL', fill_val_real, .true.), & - - ! Impervious road thermal conductivity and heat capacity have varying levels of - ! data. Thus, we expect to find some missing values in the lookup table -- we - ! do not want to treat that as an error -- thus, we set check_invalid=.false. - param('CV_IMPROAD', fill_val_real, .false.), & - param('TK_IMPROAD', fill_val_real, .false.) /) + (/ param('TK_ROOF', fill_val_real, .true.), & ! 1 + param('TK_WALL', fill_val_real, .true.), & ! 2 + param('CV_ROOF', fill_val_real, .true.), & ! 3 + param('CV_WALL', fill_val_real, .true.), & ! 4 + + ! Impervious road thermal conductivity and heat capacity have varying levels of + ! data. Thus, we expect to find some missing values in the lookup table -- we + ! do not want to treat that as an error -- thus, we set check_invalid=.false. + param('CV_IMPROAD', fill_val_real, .false.), & ! 5 + param('TK_IMPROAD', fill_val_real, .false.) /) ! 6 character(len=*), parameter :: subname = 'mkurbanpar' @@ -519,29 +559,30 @@ subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_ski ! Determine & error-check array sizes ns_o = size(region_o) - if (size(urbn_classes_gcell_o, 1) /= ns_o) then + if (size(urban_classes_gcell_o, 1) /= ns_o) then write(6,*) modname//':'//subname//' ERROR: array size mismatch' write(6,*) 'size(region_o) = ', size(region_o) - write(6,*) 'size(urbn_classes_gcell_o, 1) = ', size(urbn_classes_gcell_o, 1) + write(6,*) 'size(urban_classes_gcell_o, 1) = ', size(urban_classes_gcell_o, 1) call shr_sys_abort() end if - if (size(urbn_classes_gcell_o, 2) /= numurbl) then + if (size(urban_classes_gcell_o, 2) /= numurbl) then write(6,*) modname//':'//subname//' ERROR: array size mismatch' - write(6,*) 'size(urbn_classes_gcell_o, 2) = ', size(urbn_classes_gcell_o, 2) + write(6,*) 'size(urban_classes_gcell_o, 2) = ', size(urban_classes_gcell_o, 2) write(6,*) 'numurbl = ', numurbl end if ! Read dimensions from input file - - write (6,*) 'Open urban parameter file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncidi), subname) - call check_ret(nf_inq_dimid(ncidi, 'nlevurb', dimid), subname) - call check_ret(nf_inq_dimlen(ncidi, dimid, nlevurb_i), subname) - call check_ret(nf_inq_dimid(ncidi, 'numsolar', dimid), subname) - call check_ret(nf_inq_dimlen(ncidi, dimid, numsolar_i), subname) - call check_ret(nf_inq_dimid(ncidi, 'numrad', dimid), subname) - call check_ret(nf_inq_dimlen(ncidi, dimid, numrad_i), subname) + if (root_task) then + write (ndiag,'(a)') 'Opening input urban parameter file: '//trim(datfname_i) + end if + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(datfname_i), pio_nowrite) + rcode = pio_inq_dimid(pioid_i, 'nlevurb', dimid) + rcode = pio_inq_dimlen(pioid_i, dimid, nlevurb_i) + rcode = pio_inq_dimid(pioid_i, 'numsolar', dimid) + rcode = pio_inq_dimlen(pioid_i, dimid, numsolar_i) + rcode = pio_inq_dimid(pioid_i, 'numrad', dimid) + rcode = pio_inq_dimlen(pioid_i, dimid, numrad_i) if (nlevurb_i /= nlevurb) then write(6,*)'MKURBANPAR: parameter nlevurb= ',nlevurb, & @@ -570,70 +611,218 @@ subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_ski unity_dens_o(:,k) = k end do - ! Handle urban parameters with no extra dimensions + ! Open output file (this will go into define mode) + call mkpio_wopen(trim(fsurdat), clobber=.false., pioid=pioid_o) - allocate(data_scalar_o(ns_o, numurbl), stat=ier) - if (ier /= 0) then - write(6,*)'mkurbanpar allocation error'; call shr_sys_abort() + if ( outnc_double ) then + xtype = PIO_DOUBLE + else + xtype = PIO_REAL end if - do p = 1, size(params_scalar) - call lookup_and_check_err(params_scalar(p)%name, params_scalar(p)%fill_val, & - params_scalar(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & - data_scalar_o, 0) + ! Define urbanoutput variables + call mkpio_def_spatial_var(pioid_o, varname='CANYON_HWR', xtype=xtype, & + lev1name='numurbl', & + long_name='canyon height to width ratio', units='unitless') - call check_ret(nf_inq_varid(ncido, params_scalar(p)%name, varid), subname) - ! In the following, note that type conversion occurs if we're writing to a variable of type - ! other than double; e.g., for an integer, conversion occurs by truncation! - call check_ret(nf_put_var_double(ncido, varid, data_scalar_o), subname) - end do + call mkpio_def_spatial_var(pioid_o, varname='EM_IMPROAD', xtype=xtype, & + lev1name='numurbl', & + long_name='emissivity of impervious road', units='unitless') - deallocate(data_scalar_o) + call mkpio_def_spatial_var(pioid_o, varname='EM_PERROAD', xtype=xtype, & + lev1name='numurbl', & + long_name='emissivity of pervious road', units='unitless') - ! Handle urban parameters dimensioned by numrad & numsolar + call mkpio_def_spatial_var(pioid_o, varname='EM_ROOF', xtype=xtype, & + lev1name='numurbl', & + long_name='emissivity of roof', units='unitless') - allocate(data_rad_o(ns_o, numurbl, numrad, numsolar), stat=ier) - if (ier /= 0) then - write(6,*)'mkurbanpar allocation error'; call shr_sys_abort() - end if + call mkpio_def_spatial_var(pioid_o, varname='EM_WALL', xtype=xtype, & + lev1name='numurbl', & + long_name='emissivity of wall', units='unitless') - allocate(extra_dims(2)) - extra_dims(1)%name = 'numrad' - extra_dims(2)%name = 'numsolar' - - do p = 1, size(params_rad) - do m = 1,numsolar - extra_dims(2)%val = m - do n = 1,numrad - extra_dims(1)%val = n - - call lookup_and_check_err(params_rad(p)%name, params_rad(p)%fill_val, & - params_rad(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & - data_rad_o(:,:,n,m), & - 2, extra_dims) - end do - end do + call mkpio_def_spatial_var(pioid_o, varname='HT_ROOF', xtype=xtype, & + lev1name='numurbl', & + long_name='height of roof', units='meters') - ! Special handling of numsolar: rather than outputting variables with a numsolar - ! dimension, we output separate variables for each value of numsolar - do m = 1,numsolar - if (len_trim(params_rad(p)%name) + len_trim(solar_suffix(m)) > len(varname)) then - write(6,*) 'variable name exceeds length of varname' - write(6,*) trim(params_rad(p)%name)//trim(solar_suffix(m)) - call shr_sys_abort() - end if - varname = trim(params_rad(p)%name)//trim(solar_suffix(m)) - call check_ret(nf_inq_varid(ncido, varname, varid), subname) - ! In the following, note that type conversion occurs if we're writing to a variable of type - ! other than double; e.g., for an integer, conversion occurs by truncation! - call check_ret(nf_put_var_double(ncido, varid, data_rad_o(:,:,:,m)), subname) - end do - end do + call mkpio_def_spatial_var(pioid_o, varname='THICK_ROOF', xtype=xtype, & + lev1name='numurbl', & + long_name='thickness of roof', units='meters') - deallocate(data_rad_o) - deallocate(extra_dims) + call mkpio_def_spatial_var(pioid_o, varname='THICK_WALL', xtype=xtype, & + lev1name='numurbl', & + long_name='thickness of wall', units='meters') + + call mkpio_def_spatial_var(pioid_o, varname='T_BUILDING_MIN', xtype=xtype, & + lev1name='numurbl', & + long_name='minimum interior building temperature', units='K') + + call mkpio_def_spatial_var(pioid_o, varname='WIND_HGT_CANYON', xtype=xtype, & + lev1name='numurbl', & + long_name='height of wind in canyon', units='meters') + + call mkpio_def_spatial_var(pioid_o, varname='WTLUNIT_ROOF', xtype=xtype, & + lev1name='numurbl', & + long_name='fraction of roof', units='unitless') + + call mkpio_def_spatial_var(pioid_o, varname='WTROAD_PERV', xtype=xtype, & + lev1name='numurbl', & + long_name='fraction of pervious road', units='unitless') + + call mkpio_def_spatial_var(pioid_o, varname='ALB_IMPROAD_DIR', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='direct albedo of impervious road', units='unitless') + + call mkpio_def_spatial_var(pioid_o, varname='ALB_IMPROAD_DIF', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='diffuse albedo of impervious road', units='unitless') + + call mkpio_def_spatial_var(pioid_o, varname='ALB_PERROAD_DIR', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='direct albedo of pervious road', units='unitless') + + call mkpio_def_spatial_var(pioid_o, varname='ALB_PERROAD_DIF', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='diffuse albedo of pervious road', units='unitless') + + call mkpio_def_spatial_var(pioid_o, varname='ALB_ROOF_DIR', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='direct albedo of roof', units='unitless') + + call mkpio_def_spatial_var(pioid_o, varname='ALB_ROOF_DIF', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='diffuse albedo of roof', units='unitless') + + call mkpio_def_spatial_var(pioid_o, varname='ALB_WALL_DIR', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='direct albedo of wall', units='unitless') + + call mkpio_def_spatial_var(pioid_o, varname='ALB_WALL_DIF', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='diffuse albedo of wall', units='unitless') + call mkpio_def_spatial_var(pioid_o, varname='TK_ROOF', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='thermal conductivity of roof', units='W/m*K') + + call mkpio_def_spatial_var(pioid_o, varname='TK_WALL', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='thermal conductivity of wall', units='W/m*K') + + call mkpio_def_spatial_var(pioid_o, varname='TK_IMPROAD', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='thermal conductivity of impervious road', units='W/m*K') + + call mkpio_def_spatial_var(pioid_o, varname='CV_ROOF', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='volumetric heat capacity of roof', units='J/m^3*K') + + call mkpio_def_spatial_var(pioid_o, varname='CV_WALL', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='volumetric heat capacity of wall', units='J/m^3*K') + + call mkpio_def_spatial_var(pioid_o, varname='CV_IMPROAD', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='volumetric heat capacity of impervious road', units='J/m^3*K') + + call mkpio_def_spatial_var(pioid_o, varname='NLEV_IMPROAD', xtype=PIO_INT, & + lev1name='numurbl', & + long_name='number of impervious road layers', units='unitless') + + ! End define model + rcode = pio_enddef(pioid_o) + + ! ------------------------------------------------ + ! Handle urban parameters with no extra dimensions + ! ------------------------------------------------ + + allocate(data_scalar_o(ns_o, numurbl), stat=ier) + if (ier /= 0) then + write(6,*)'mkurbanpar allocation error'; call shr_sys_abort() + end if + + do p = 1, size(params_scalar) + ! get variable output (data_scalar_o) + call lookup_and_check_err(pioid_i, params_scalar(p)%name, params_scalar(p)%fill_val, & + params_scalar(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & + data_scalar_o, 0) + + ! get io descriptor for variable output + call mkpio_iodesc_output(pioid_o, mesh_o, params_scalar(p)%name, pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//& + trim(params_scalar(p)%name)) + + ! write out variable + rcode = pio_inq_varid(pioid_o, params_scalar(p)%name, pio_varid) + call pio_write_darray(pioid_o, pio_varid, pio_iodesc, data_scalar_o(:,:), rcode) + + ! Free memory for io descriptor + call pio_freedecomp(pioid_o, pio_iodesc) + end do + + deallocate(data_scalar_o) + + ! ------------------------------------------------ + ! Handle urban parameters with no extra dimensions + ! ------------------------------------------------ + + ! Handle urban parameters dimensioned by numrad & numsolar + + allocate(data_rad_o(ns_o, numurbl, numrad, numsolar), stat=ier) + if (ier /= 0) then + write(6,*)'mkurbanpar allocation error'; call shr_sys_abort() + end if + + allocate(extra_dims(2)) + extra_dims(1)%name = 'numrad' + extra_dims(2)%name = 'numsolar' + + do p = 1, size(params_rad) + + ! Get variable output (data_rad_o) + do m = 1,numsolar + extra_dims(2)%val = m + do n = 1,numrad + extra_dims(1)%val = n + call lookup_and_check_err(pioid_i, params_rad(p)%name, params_rad(p)%fill_val, & + params_rad(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & + data_rad_o(:,:,n,m), 2, extra_dims) + end do + end do + + ! Special handling of numsolar: rather than outputting variables with a numsolar + ! dimension, we output separate variables for each value of numsolar + do m = 1,numsolar + if (len_trim(params_rad(p)%name) + len_trim(solar_suffix(m)) > len(varname)) then + write(6,*) 'variable name exceeds length of varname' + write(6,*) trim(params_rad(p)%name)//trim(solar_suffix(m)) + call shr_sys_abort() + end if + + ! Determine variable name + varname = trim(params_rad(p)%name)//trim(solar_suffix(m)) + + ! get io descriptor for variable output + call mkpio_iodesc_output(pioid_o, mesh_o, varname, pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//& + trim(params_scalar(p)%name)) + + ! write out variable + rcode = pio_inq_varid(pioid_o, varname, pio_varid) + call pio_write_darray(pioid_o, pio_varid, pio_iodesc, data_rad_o(:,:,:,m), rcode) + + ! Free memory for io descriptor + call pio_freedecomp(pioid_o, pio_iodesc) + end do + + end do + + deallocate(data_rad_o) + deallocate(extra_dims) + + ! ------------------------------------------------ ! Handle urban parameters dimensioned by nlevurb + ! ------------------------------------------------ allocate(data_levurb_o(ns_o, numurbl, nlevurb), stat=ier) if (ier /= 0) then @@ -646,34 +835,41 @@ subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_ski do p = 1, size(params_levurb) do n = 1,nlevurb extra_dims(1)%val = n - - call lookup_and_check_err(params_levurb(p)%name, params_levurb(p)%fill_val, & + call lookup_and_check_err(pioid_i, params_levurb(p)%name, params_levurb(p)%fill_val, & params_levurb(p)%check_invalid, & - urban_skip_abort_on_invalid_data_check, data_levurb_o(:,:,n), & - 1, extra_dims) + urban_skip_abort_on_invalid_data_check, data_levurb_o(:,:,n), 1, extra_dims) end do - call check_ret(nf_inq_varid(ncido, params_levurb(p)%name, varid), subname) - ! In the following, note that type conversion occurs if we're writing to a variable of type - ! other than double; e.g., for an integer, conversion occurs by truncation! - call check_ret(nf_put_var_double(ncido, varid, data_levurb_o), subname) + ! get io descriptor for variable output + call mkpio_iodesc_output(pioid_o, mesh_o, params_levurb(p)%name, pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//& + trim(params_levurb(p)%name)) + + ! write out variable + rcode = pio_inq_varid(pioid_o, params_levurb(p)%name, pio_varid) + call pio_write_darray(pioid_o, pio_varid, pio_iodesc, data_levurb_o(:,:,:), rcode) + + ! Free memory for io descriptor + call pio_freedecomp(pioid_o, pio_iodesc) end do deallocate(data_levurb_o) deallocate(extra_dims) + ! Close input data file and output surface dataset + call pio_closefile(pioid_i) + call pio_closefile(pioid_o) - call check_ret(nf_close(ncidi), subname) - call check_ret(nf_sync(ncido), subname) - - write (6,*) 'Successfully made Urban Parameters' - write (6,*) + if (root_task) then + write (ndiag,'(a)') 'Successfully made Urban Parameters' + write (ndiag,'(a)') + end if deallocate(unity_dens_o) contains !------------------------------------------------------------------------------ - subroutine lookup_and_check_err(varname, fill_val, check_invalid, & + subroutine lookup_and_check_err(pioid, varname, fill_val, check_invalid, & urban_skip_abort_on_invalid_data_check, data, n_extra_dims, extra_dims) ! Wrapper to lookup_2d_netcdf: Loops over each density class, calling lookup_2d_netcdf @@ -688,23 +884,22 @@ subroutine lookup_and_check_err(varname, fill_val, check_invalid, & use mkindexmapMod, only : lookup_2d_netcdf - implicit none - character(len=*), intent(in) :: varname ! name of lookup table - real(r8) , intent(in) :: fill_val ! value to put where we have no data in output variables - logical , intent(in) :: check_invalid ! should we check whether there are any invalid data in the output? - logical , intent(in) :: urban_skip_abort_on_invalid_data_check - - real(r8) , intent(out):: data(:,:) ! output from lookup_2d_netcdf - integer , intent(in) :: n_extra_dims ! number of extra dimensions in the lookup table + ! input/output variables + type(file_desc_t) , intent(inout) :: pioid + character(len=*) , intent(in) :: varname ! name of lookup table + real(r8) , intent(in) :: fill_val ! value to put where we have no data in output variables + logical , intent(in) :: check_invalid ! should we check whether there are any invalid data in the output? + logical , intent(in) :: urban_skip_abort_on_invalid_data_check + real(r8) , intent(out) :: data(:,:) ! output from lookup_2d_netcdf + integer , intent(in) :: n_extra_dims ! number of extra dimensions in the lookup table ! slice to use if lookup table variable has more than 2 dimensions: type(dim_slice_type), intent(in), optional :: extra_dims(:) ! Local variables: - integer :: k,n ! indices integer :: ierr ! error return code - + !----------------------------------------------------------------------- do k = 1, numurbl ! In the following, note that unity_dens_o(:,k) has been constructed so that @@ -713,7 +908,8 @@ subroutine lookup_and_check_err(varname, fill_val, check_invalid, & ! Also note: We use invalid_okay=.true. because we fill all density classes, ! some of which may have invalid entries. Because doing so disables some error ! checking, we do our own error checking after the call. - call lookup_2d_netcdf(ncidi, varname, .true., & + + call lookup_2d_netcdf(pioid, varname, .true., & 'density_class', 'region', n_extra_dims, & unity_dens_o(:,k), region_o, fill_val, data(:,k), ierr, & extra_dims=extra_dims, nodata=index_nodata, & @@ -730,13 +926,13 @@ subroutine lookup_and_check_err(varname, fill_val, check_invalid, & do n = 1, ns_o ! This check assumes that fill_val doesn't appear in any of the valid entries ! of the lookup table - if (urbn_classes_gcell_o(n,k) > 0. .and. data(n,k) == fill_val) then + if (urban_classes_gcell_o(n,k) > 0. .and. data(n,k) == fill_val) then write(6,*) modname//':'//subname//' ERROR: fill value found in output where urban cover > 0' write(6,*) 'var: ', trim(varname) write(6,*) 'class: ', k write(6,*) 'n: ', n write(6,*) 'region: ', region_o(n) - write(6,*) 'urbn_classes_gcell_o(n,k): ', urbn_classes_gcell_o(n,k) + write(6,*) 'urban_classes_gcell_o(n,k): ', urban_classes_gcell_o(n,k) if (.not. urban_skip_abort_on_invalid_data_check) then ! NOTE(bja, 2015-01) added to work around a ?bug? noted in ! /glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 @@ -745,12 +941,9 @@ subroutine lookup_and_check_err(varname, fill_val, check_invalid, & end if end do end if - end do - end subroutine lookup_and_check_err end subroutine mkurbanpar - !------------------------------------------------------------------------------ end module mkurbanparMod From faa0280a4c447a6903b90f1cc04deb069373a02c Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 26 Jan 2022 19:40:01 -0700 Subject: [PATCH 028/614] updates to get soil color dataset working --- .../gen_mksurfdata_namelist.xml | 2 +- tools/mksurfdata_esmf/src/CMakeLists.txt | 5 +- tools/mksurfdata_esmf/src/mkfileMod.F90 | 18 +- tools/mksurfdata_esmf/src/mkindexmapMod.F90 | 12 +- tools/mksurfdata_esmf/src/mkorganicMod.F90 | 16 +- tools/mksurfdata_esmf/src/mkpioMod.F90 | 3 + tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 | 89 ----- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 318 ++++++++-------- tools/mksurfdata_esmf/src/mksurfdata.F90 | 349 +++++++++--------- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 37 +- tools/mksurfdata_esmf/src/mkutilsMod.F90 | 82 +++- 11 files changed, 456 insertions(+), 475 deletions(-) delete mode 100644 tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index ecc76c5be2..2690ec8759 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -39,7 +39,7 @@ - lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_soilcolor_CMIP6_simyr2005.c170623.nc + lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_soilcolor_CMIP6_simyr2005_cd5.c220126.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 00224aa6e0..1e0438c3e6 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -22,12 +22,13 @@ set(SRCFILES mkvarctl.F90 mkfileMod.F90 mklanwatMod.F90 mkorganicMod.F90 + mksoilcolMod.F90 + mkurbanparMod.F90 + mkurbanparCommonMod.F90 mkesmfMod.F90 mkutilsMod.F90 mkchecksMod.F90 mkindexmapMod.F90 - mkurbanparMod.F90 - mkurbanparCommonMod.F90 nanMod.F90 shr_const_mod.F90 shr_kind_mod.F90 diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 7e6a3de131..ef9d45f097 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -36,7 +36,7 @@ module mkfileMod !================================================================================= subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & - pctlak, pctwet, lakedepth, organic, urban_classes, urban_region) + pctlak, pctwet, lakedepth, organic, urban_classes, urban_region, soil_color, nsoilcol) ! input/output variables integer , intent(in) :: nx @@ -49,6 +49,8 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & real(r8), pointer, intent(in) :: organic(:,:) ! organic real(r8), pointer, intent(in) :: urban_classes(:,:) ! percent cover of each urban class, as % of total urban area integer , pointer, intent(in) :: urban_region(:) ! urban region ID + integer , pointer, intent(in) :: soil_color(:) + integer , intent(in) :: nsoilcol #ifdef TODO type(harvestDataType) , intent(in) :: harvdata #endif @@ -120,11 +122,16 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & 'kg/m3 (assumed carbon content 0.58 gC per gOM)', organic, lev1name='nlevsoi', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call mkfile_output(pioid, define_mode, mesh_o, 'SOIL_COLOR', 'soil color', & + 'unitless', soil_color, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + write(6,*)'wrote out soil_color' + ! call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_URBAN', 'percent urban for each density type', & ! 'unitless', urban_classes, lev1name='numurbl', rc=rc) ! if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! call mkfile_output(pioid, define_mode, mesh_o, 'URBAN_REGION_ID', 'urban region ID', & + ! call mkfile_output(pioid, define_mode, mesh_o, PIO_INT, 'URBAN_REGION_ID', 'urban region ID', & ! 'unitless', urban_region, rc=rc) ! if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -356,13 +363,20 @@ subroutine mkfile_output_int1d(pioid, define_mode, mesh, varname, longname, unit rc = ESMF_SUCCESS if (define_mode) then + write(6,*)'DEBUG: here1' call mkpio_def_spatial_var(pioid, trim(varname), PIO_INT, trim(longname), trim(units)) + write(6,*)'DEBUG: here2' else + write(6,*)'DEBUG: here3' call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + write(6,*)'DEBUG: here4' rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + write(6,*)'DEBUG: here5' call pio_write_darray(pioid, pio_varid, pio_iodesc, ipointer, rcode) + write(6,*)'DEBUG: here6' call pio_freedecomp(pioid, pio_iodesc) + write(6,*)'DEBUG: here7' end if end subroutine mkfile_output_int1d diff --git a/tools/mksurfdata_esmf/src/mkindexmapMod.F90 b/tools/mksurfdata_esmf/src/mkindexmapMod.F90 index cfc2adbc09..fdb1ee9ef4 100644 --- a/tools/mksurfdata_esmf/src/mkindexmapMod.F90 +++ b/tools/mksurfdata_esmf/src/mkindexmapMod.F90 @@ -478,18 +478,8 @@ subroutine lookup_2d_netcdf(pioid, tablename, lookup_has_invalid, & call check_dimsize(dimlens(2+i), extra_dims(i)%val, 2+i) end do - ! Read the lookup table; if the given variable has more than 2 dimensions, we read - ! a single 2-d slice - - allocate(starts(ndims), counts(ndims)) allocate(lookup_table(dimlens(1), dimlens(2))) - starts(1:2) = 1 - counts(1:2) = dimlens(1:2) - do i = 1, n_extra_dims - starts(2+i) = extra_dims(i)%val - counts(2+i) = 1 - end do - rcode = pio_get_var(pioid, pio_varid, starts, counts, lookup_table) + rcode = pio_get_var(pioid, pio_varid, lookup_table) ! Determine which entries are valid diff --git a/tools/mksurfdata_esmf/src/mkorganicMod.F90 b/tools/mksurfdata_esmf/src/mkorganicMod.F90 index e6f2668494..cb52f1708a 100644 --- a/tools/mksurfdata_esmf/src/mkorganicMod.F90 +++ b/tools/mksurfdata_esmf/src/mkorganicMod.F90 @@ -7,7 +7,7 @@ module mkorganicMod use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths - use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_ioformat, pio_iosystem + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem use mkesmfMod , only : regrid_rawdata use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag @@ -54,7 +54,6 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) real(r8), allocatable :: data_double(:,:) real(r8), allocatable :: data_i(:,:) real(r8), allocatable :: data_o(:,:) - character(len=256) :: varname real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) character(len=*), parameter :: subname = 'mkorganic' @@ -66,9 +65,6 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) write (ndiag,'(a)') ' Attempting to make organic mater dataset .....' end if - ! Set variable name in raw data file - varname = 'ORGANIC' - ! Open raw data file - need to do this first to obtain ungridded dimension size call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) @@ -79,7 +75,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) ! - input read from pio has dimensions(n,lev) ! - esmf field dataptr has dimensions (lev,n) allocate(dimlengths(3)) - call mkpio_get_dimlengths(pioid, trim(varname), ndims, dimlengths) + call mkpio_get_dimlengths(pioid, 'ORGANIC', ndims, dimlengths) nlay = dimlengths(3) if (nlay /= nlevsoi) then write(6,*)'nlay, nlevsoi= ',nlay,nlevsoi,' do not match' @@ -96,6 +92,8 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + allocate(data_i(nlay,ns_i),stat=ier) + if (ier/=0) call shr_sys_abort() ! Determine ns_o and allocate data_o ns_o = size(organic_o, dim=1) @@ -106,9 +104,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) ! - levels are the innermost dimension for esmf fields ! - levels are the outermost dimension in pio reads ! Input data is read into (ns_i,nlay) array and then transferred to data_i(nlay,ns_i) - allocate(data_i(nlay,ns_i),stat=ier) - if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, varname, mesh_i, data_i, rc=rc) + call mkpio_get_rawdata(pioid, 'ORGANIC', mesh_i, data_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -164,6 +160,8 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) do n = 1,ns_o if (frac_o(n) > 0._r8) then organic_o(n,:) = organic_o(n,:) / frac_o(n) + else + organic_o(n,:) = 0._r8 end if end do do l = 1,nlevsoi diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 2f774c14e5..316ca1d33b 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -554,11 +554,14 @@ subroutine mkpio_wopen(filename, clobber, pioid) endif else ! only applies to classic NETCDF files. + write(6,*)'DEBUG: here1' nmode = pio_noclobber if (pio_iotype == PIO_IOTYPE_NETCDF .or. pio_iotype == PIO_IOTYPE_PNETCDF) then nmode = ior(nmode,pio_ioformat) endif + write(6,*)'DEBUG: here2' rcode = pio_createfile(pio_iosystem, pioid, pio_iotype, trim(filename), nmode) + write(6,*)'DEBUG: here3' if (root_task) write(ndiag,'(a)') trim(subname) //' creating file '// trim(filename) endif call ESMF_LogWrite("successfully opened output file "//trim(filename), ESMF_LOGMSG_INFO) diff --git a/tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 b/tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 deleted file mode 100644 index d4a274189f..0000000000 --- a/tools/mksurfdata_esmf/src/mksoilUtilsMod.F90 +++ /dev/null @@ -1,89 +0,0 @@ -module mksoilUtilsMod - - !----------------------------------------------------------------------- - ! Lower-level utilities used in making soil data. - ! These are separated out from mksoilMod mainly as an aid to testing. - !----------------------------------------------------------------------- - - use shr_kind_mod, only : r8 => shr_kind_r8 - - implicit none - private - - public :: mkrank - -!=============================================================== -contains -!=============================================================== - - subroutine mkrank (n, a, miss, iv, num) - ! - ! Return indices of largest [num] values in array [a]. - ! - ! input/output variables - integer , intent(in) :: n !array length - real(r8), intent(in) :: a(0:n) !array to be ranked - integer , intent(in) :: miss !missing data value - integer , intent(in) :: num !number of largest values requested - integer , intent(out):: iv(num) !index to [num] largest values in array [a] - - ! local variables: - real(r8) a_max !maximum value in array - integer i !array index - real(r8) delmax !tolerance for finding if larger value - integer m !do loop index - integer k !do loop index - logical exclude !true if data value has already been chosen - !----------------------------------------------------------------------- - - delmax = 1.e-06 - - ! Find index of largest non-zero number - - iv(1) = miss - a_max = -9999. - - do i = 0, n - if (a(i)>0. .and. (a(i)-a_max)>delmax) then - a_max = a(i) - iv(1) = i - end if - end do - - ! iv(1) = miss indicates no values > 0. this is an error - - if (iv(1) == miss) then - write (6,*) 'MKRANK error: iv(1) = missing' - call shr_sys_abort() - end if - - ! Find indices of the next [num]-1 largest non-zero number. - ! iv(m) = miss if there are no more values > 0 - - do m = 2, num - iv(m) = miss - a_max = -9999. - do i = 0, n - - ! exclude if data value has already been chosen - - exclude = .false. - do k = 1, m-1 - if (i == iv(k)) exclude = .true. - end do - - ! if not already chosen, see if it is the largest of - ! the remaining values - - if (.not. exclude) then - if (a(i)>0. .and. (a(i)-a_max)>delmax) then - a_max = a(i) - iv(m) = i - end if - end if - end do - end do - - end subroutine mkrank - -end module mksoilUtilsMod diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index 6937d6b8f0..853e3ddab5 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -4,17 +4,19 @@ module mksoilcolMod use pio use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 use shr_sys_mod , only : shr_sys_abort - use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dim_lengths + use mkpioMod , only : mkpio_get_rawdata use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_ioformat, pio_iosystem use mkesmfMod , only : regrid_rawdata - use mkutilsMod , only : chkerr + use mkutilsMod , only : chkerr, mkrank use mkvarctl , only : root_task, ndiag - use mkvarpar , only : nlevsoi implicit none private - public mksoilcol ! Set soil colors + public :: mksoilcol ! Set soil colors + + integer , parameter :: unsetcol = -999 ! flag to indicate soil color NOT set + integer , private :: soil_color= unsetcol ! soil color to override with character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -23,74 +25,93 @@ module mksoilcolMod contains !================================================================================= - subroutine mkorganic(file_mesh_i, file_data_i, field_o, mesh_o, soil_color_o, nsoilcol) + subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, rc) ! input/output variables character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Field) , intent(inout) :: field_o type(ESMF_Mesh) , intent(in) :: mesh_o - integer , intent(out) :: soil_color_o(:) ! soil color classes - integer , intent(out) :: nsoicol ! number of soil colors + integer , pointer :: soil_color_o(:) ! soil color classes + integer , intent(out) :: nsoilcol ! number of soil colors integer , intent(out) :: rc ! local variables: - type(ESMF_RouteHandle) :: routehandle - type(ESMF_Mesh) :: mesh_i - type(ESMF_Field) :: field_i - type(file_desc_t) :: pioid - type(var_desc_t) :: pio_varid - type(io_desc_t) :: pio_iodesc - integer :: pio_vartype - real(r8), allocatable :: organic_i(:,:) - integer :: ni,no - integer :: ns_i, ns_o - integer :: k,l,m, ! indices - integer :: rcode, ier ! error status - integer :: srcMaskValue = 0 - integer :: dstMaskValue = -987987 ! spval for RH mask values - integer :: srcTermProcessing_Value = 0 - integer :: ndims - integer, allocatable :: dim_lengths(:) - real(r4), allocatable :: data_real(:,:) - real(r8), allocatable :: data_double(:,:) - integer , allocatable :: soil_color_i(:) ! input grid: BATS soil color - character(len=35), allocatable :: col(:) ! name of each color - integer :: ier ! error status + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + type(file_desc_t) :: pioid + integer :: ni,no + integer :: ns_i, ns_o + integer :: n,l + integer :: rcode, ier ! error status + integer :: srcMaskValue = -987987 ! spval for RH mask values + integer :: dstMaskValue = -987987 ! spval for RH mask values + integer :: srcTermProcessing_Value = 0 + integer :: ndims + real(r8), allocatable :: soilcol_i(:) + real(r8), allocatable :: data_i(:,:) + real(r8), allocatable :: data_o(:,:) + real(r8), allocatable :: mask_i(:) + integer, parameter :: num = 2 ! set soil mapunit number + integer :: wsti(num) ! index to 1st and 2nd largest wst + real(r8) :: wt ! map overlap weight + logical :: has_color ! whether this grid cell has non-zero color + integer, parameter :: miss = 99999 ! missing data indicator + character(len=35), allocatable :: col(:) ! name of each color character(len=*), parameter :: subname = 'mksoilcol' !----------------------------------------------------------------------- - write (6,*) 'Attempting to make soil color classes .....' - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- + rc = ESMF_SUCCESS - ns_o = ldomain%ns + ! Error check soil_color if it is set + if ( soil_color /= unsetcol )then + if ( soil_color < 0 .or. soil_color > 20 )then + write(6,*)'soil_color is out of range = ', soil_color + call shr_sys_abort() + end if + write(6,*) 'Replace soil color for all points with: ', soil_color + do no = 1,size(soil_color_o) + soil_color_o(no) = soil_color + end do + RETURN + end if - ! Obtain input grid info, read local fields + if (root_task) then + write (ndiag,'(a)') 'Attempting to make soil color classes .....' + end if - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - allocate(soil_color_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(frac_dst(ns_o), stat=ier) + ! Open raw data file - need to do this first to obtain ungridded dimension size + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + + ! Determine ns_i and allocate data_i + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(soilcol_i(ns_i),stat=ier) if (ier/=0) call shr_sys_abort() - write (6,*) 'Open soil color file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'SOIL_COLOR', varid), subname) - call check_ret(nf_get_var_int (ncid, varid, soil_color_i), subname) - call check_ret(nf_close(ncid), subname) + ! Read in input data + call mkpio_get_rawdata(pioid, 'SOIL_COLOR', mesh_i, soilcol_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + + ! ** TODO: determine the maximum value of soilcol_i - across all processors - doing an all reduce + ! For now hardwire nsoilcol to 20 + nsoilcol = 20 - nsoicol = maxval(soil_color_i) - write(6,*)'nsoicol = ',nsoicol - - ! ----------------------------------------------------------------- - ! Define the model color classes: 0 to nsoicol - ! ----------------------------------------------------------------- + ! Determine ns_o and allocate data_o + ns_o = size(soil_color_o) + allocate(data_o(0:nsoilcol, ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() - if (nsoicol == 20) then + ! Define the model color classes: 0 to nsoilcol + allocate(col(0:nsoilcol)) + if (nsoilcol == 20) then col(0) = 'no soil ' col(1) = 'class 1: light ' col(2) = 'class 2: ' @@ -112,7 +133,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, field_o, mesh_o, soil_color_o, ns col(18) = 'class 18: ' col(19) = 'class 19: ' col(20) = 'class 20: dark ' - else if (nsoicol == 8) then + else if (nsoilcol == 8) then col(0) = 'no soil ' col(1) = 'class 1: light ' col(2) = 'class 2: ' @@ -123,155 +144,89 @@ subroutine mkorganic(file_mesh_i, file_data_i, field_o, mesh_o, soil_color_o, ns col(7) = 'class 7: ' col(8) = 'class 8: dark ' else - write(6,*)'nsoicol value of ',nsoicol,' is not currently supported' + write(6,*)'nsoilcol value of ',nsoilcol,' is not currently supported' call shr_sys_abort() end if - ! Error check soil_color if it is set - if ( soil_color /= unsetcol )then - - if ( soil_color > nsoicol )then - write(6,*)'soil_color is out of range = ', soil_color - call shr_sys_abort() - end if - - do no = 1,ns_o - soil_color_o(no) = soil_color + ! Create field on input mesh + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/0/), ungriddedUbound=(/nsoilcol/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After field_i creation in "//trim(subname)) + + ! Create field on model model + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/0/), ungriddedUbound=(/nsoilcol/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After field_o creation in "//trim(subname)) + + ! Determine input landmask (frac_i) + allocate(mask_i(ns_i)) + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Now determine data_i as a real 2d array + allocate(data_i(0:nsoilcol,ns_i)) + data_i(:,:) = 0._r8 + do l = 1,nsoilcol + do n = 1,ns_i + if (int(soilcol_i(n)) == l) then + data_i(l,n) = 1._r8 * mask_i(n) + end if end do + end do - else - - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine dominant soil color for each output cell - - call dominant_soil_color( & - tgridmap = tgridmap, & - mask_i = tdomain%mask, & - soil_color_i = soil_color_i, & - nsoicol = nsoicol, & - soil_color_o = soil_color_o) - - ! Global sum of output field - - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - end if - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - if ( soil_color == unsetcol )then - call gridmap_clean(tgridmap) - end if - deallocate (soil_color_i,gast_i,gast_o,col, frac_dst, mask_r8) - - write (6,*) 'Successfully made soil color classes' - write (6,*) - - end subroutine mksoilcol - - !----------------------------------------------------------------------- - subroutine dominant_soil_color(tgridmap, mask_i, soil_color_i, nsoicol, soil_color_o) - ! - ! Determine the dominant soil color in each output cell - ! - ! input/output variables - type(gridmap_type) , intent(in) :: tgridmap - integer , intent(in) :: mask_i(:) ! input grid: land mask (1 = land, 0 = ocean) - integer , intent(in) :: soil_color_i(:) ! input grid: BATS soil color - integer , intent(in) :: nsoicol ! number of soil colors - integer , intent(out) :: soil_color_o(:) ! output grid: soil color classes - ! - ! local variables: - integer, parameter :: num = 2 ! set soil mapunit number - integer :: wsti(num) ! index to 1st and 2nd largest wst - integer :: k, n, ni, no, ns_i, ns_o - real(r8) :: wt ! map overlap weight - real(r8), allocatable :: wst(:,:) ! overlap weights, by surface type - logical :: has_color ! whether this grid cell has non-zero color - integer, parameter :: miss = 99999 ! missing data indicator - - character(len=*), parameter :: subname = 'dominant_soil_color' - !----------------------------------------------------------------------- + ! Create route handle to map field_model to field_data + call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_FRACAREA, & + srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - ns_i = size(mask_i) - if (size(soil_color_i) /= ns_i) then - write(6,*) subname, ' ERROR: size of soil_color_i should match size of mask_i' - write(6,*) 'size(mask_i), size(soil_color_i) = ', & - size(mask_i), size(soil_color_i) - call shr_sys_abort() - end if + ! Regrid data_i to data_o + call regrid_rawdata(field_i, field_o, routehandle, data_i, data_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! find area of overlap for each soil color for each no + call ESMF_LogWrite(subname//'after regrid rawdata') - ns_o = size(soil_color_o) - allocate(wst(0:nsoicol,ns_o)) - wst(0:nsoicol,:) = 0 - - ! TODO: need to do a loop to determine - ! the maximum number of over lap cells throughout the grid - ! first get an array that is novr(ns_o) and fill this in - then set - ! maxovr - to max(novr) - then allocate the array wst to be size of - ! maxovr,ns_o or 0:nsoilcol,ns_o - - do n = 1,tgridmap%ns - ni = tgridmap%src_indx(n) - no = tgridmap%dst_indx(n) - wt = tgridmap%wovr(n) * mask_i(ni) - k = soil_color_i(ni) * mask_i(ni) - wst(k,no) = wst(k,no) + wt - enddo + ! Determine dominant soil color in each output grid cell + !call dominant_soil_color(data_o, nsoilcol, soil_color_o) soil_color_o(:) = 0 do no = 1,ns_o - ! If the output cell has any non-zero-colored inputs, then set the weight of ! zero-colored inputs to 0, to ensure that the zero-color is NOT dominant. - if (any(wst(1:nsoicol,no) > 0.)) then + if (any(data_o(1:nsoilcol,no) > 0.)) then has_color = .true. - wst(0,no) = 0.0 + data_o(0,no) = 0.0 else has_color = .false. end if - ! Rank non-zero weights by color type. wsti(1) is the most extensive - ! color type. - + ! Rank non-zero weights by color type. wsti(1) is the most extensive color type. if (has_color) then - call mkrank (nsoicol, wst(0:nsoicol,no), miss, wsti, num) + call mkrank (nsoilcol, data_o(0:nsoilcol,no), miss, num, wsti) soil_color_o(no) = wsti(1) end if - ! If land but no color, set color to 15 (in older dataset generic - ! soil color 4) - - if (nsoicol == 8) then + ! If land but no color, set color to 15 (in older dataset generic soil color 4) + if (nsoilcol == 8) then if (soil_color_o(no)==0) then soil_color_o(no) = 4 end if - else if (nsoicol == 20) then + else if (nsoilcol == 20) then if (soil_color_o(no)==0) then soil_color_o(no) = 15 end if else - write(6,*) 'MKSOILCOL error: unhandled nsoicol: ', nsoicol + write(6,*) 'MKSOILCOL error: unhandled nsoilcol: ', nsoilcol call shr_sys_abort() end if ! Error checks - - if (soil_color_o(no) < 0 .or. soil_color_o(no) > nsoicol) then + if (soil_color_o(no) < 0 .or. soil_color_o(no) > nsoilcol) then write (6,*) 'MKSOILCOL error: land model soil color = ', & soil_color_o(no),' is not valid for lon,lat = ',no call shr_sys_abort() @@ -279,8 +234,25 @@ subroutine dominant_soil_color(tgridmap, mask_i, soil_color_i, nsoicol, soil_col end do - deallocate (wst) + if (root_task) then + write (ndiag,'(a)') 'Successfully made soil color classes' + write (ndiag,'(a)') + end if - end subroutine dominant_soil_color + deallocate(col) + deallocate(data_i) + deallocate(data_o) + deallocate(soilcol_i) + deallocate(mask_i) + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + call ESMF_LogWrite(subname//' finished routine mksoilcol') + + end subroutine mksoilcol end module mksoilcolMod diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index f9c90a3c21..2451957378 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -98,7 +98,7 @@ program mksurfdata use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride use mksoilMod , only : soil_sand, soil_clay, mksoiltex, mksoilInit - use mksoilMod , only : soil_color, mksoilcol, soil_fmax, mkfmax + use mksoilMod , only : soil_fmax, mkfmax use mksoildepthMod , only : mksoildepth use mkvocefMod , only : mkvocef use mkglacierregionMod , only : mkglacierregion @@ -115,6 +115,7 @@ program mksurfdata #else use mkurbanparCommonMod #endif + use mksoilcolMod , only : mksoilcol use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, numurbl use mklanwatMod , only : mklakwat use mkOrganicMod , only : mkorganic @@ -131,7 +132,7 @@ program mksurfdata ! local variables type(ESMF_Mesh) :: mesh_model type(ESMF_Field) :: field_model - integer :: nsoicol ! number of model color classes + integer :: nsoilcol ! number of model color classes integer :: k,m,n ! indices integer :: ni,nj,ns_o ! indices integer :: lsize_o @@ -182,7 +183,7 @@ program mksurfdata integer , pointer :: urban_region(:) ! urban region ID real(r8), pointer :: elev(:) ! glc elevation (m) real(r8), pointer :: fmax(:) ! fractional saturated area - integer , pointer :: soicol(:) ! soil color + integer , pointer :: soil_color(:) ! soil color real(r8), pointer :: pctsand(:,:) ! soil texture: percent sand real(r8), pointer :: pctclay(:,:) ! soil texture: percent clay real(r8), pointer :: ef1_btr(:) ! Isoprene emission factor for broadleaf @@ -370,7 +371,7 @@ program mksurfdata ! soil properties allocate ( pctsand(lsize_o,nlevsoi)) ; pctsand(:,:) = spval allocate ( pctclay(lsize_o,nlevsoi)) ; pctclay(:,:) = spval - allocate ( soicol(lsize_o)) ; soicol(:) = -999 + allocate ( soil_color(lsize_o)) ; soil_color(:) = -999 allocate ( soildepth(lsize_o)) ; soildepth(:) = spval allocate ( organic(lsize_o,nlevsoi)) ; organic(:,:) = spval @@ -409,88 +410,89 @@ program mksurfdata ! call mkharvest( mapfname=map_fharvest, datfname=mksrf_fhrvtyp, ndiag=ndiag, harvdata=harvdata ) ! end if + ! Make soil color classes [soicol] [fsoicol] + call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, soil_color, nsoilcol, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilcol') + ! Make organic matter density [organic] [forganic] call mkorganic( mksrf_forganic_mesh, mksrf_forganic, mesh_model, organic, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') + ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] + zero_out_lake = all_urban .or. all_veg + zero_out_wetland = all_urban .or. all_veg .or. no_inlandwet + call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & + zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') + call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) + ! Make urban fraction [pcturb] from [furban] dataset ! call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, & ! zero_out=all_veg, urbn_o=pcturb, urban_classes_o=urban_classes, region_o=urban_region, rc=rc) ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') - ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] - ! zero_out_lake = all_urban .or. all_veg - ! zero_out_wetland = all_urban .or. all_veg .or. no_inlandwet - ! call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & - ! zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') - ! call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) - #ifdef TODO - ! Make glacier fraction [pctgla] from [fglacier] dataset - call mkglacier ( mapfname=map_fglacier, datfname=mksrf_fglacier, ndiag=ndiag, zero_out=all_urban.or.all_veg, glac_o=pctgla) - - ! Make glacier region ID [glacier_region] from [fglacierregion] dataset - call mkglacierregion ( mapfname=map_fglacierregion, & - datfname=mksrf_fglacierregion, ndiag=ndiag, glacier_region_o = glacier_region) + ! ! Make glacier fraction [pctgla] from [fglacier] dataset + ! call mkglacier ( mapfname=map_fglacier, datfname=mksrf_fglacier, ndiag=ndiag, zero_out=all_urban.or.all_veg, glac_o=pctgla) - ! Make soil texture [pctsand, pctclay] [fsoitex] - call mksoiltex ( mapfname=map_fsoitex, datfname=mksrf_fsoitex, ndiag=ndiag, sand_o=pctsand, clay_o=pctclay) + ! ! Make glacier region ID [glacier_region] from [fglacierregion] dataset + ! call mkglacierregion ( mapfname=map_fglacierregion, & + ! datfname=mksrf_fglacierregion, ndiag=ndiag, glacier_region_o = glacier_region) - ! Make soil color classes [soicol] [fsoicol] - call mksoicol ( mapfname=map_fsoicol, datfname=mksrf_fsoicol, ndiag=ndiag, soil_color_o=soicol, nsoicol=nsoicol) + ! ! Make soil texture [pctsand, pctclay] [fsoitex] + ! call mksoiltex ( mapfname=map_fsoitex, datfname=mksrf_fsoitex, ndiag=ndiag, sand_o=pctsand, clay_o=pctclay) - ! Make fmax [fmax] from [fmax] dataset - allocate(fmax(lsize_o)); fmax(:) = spval - call mkfmax ( mapfname=map_fmax, datfname=mksrf_fmax, ndiag=ndiag, fmax_o=fmax) + ! ! Make fmax [fmax] from [fmax] dataset + ! allocate(fmax(lsize_o)); fmax(:) = spval + ! call mkfmax ( mapfname=map_fmax, datfname=mksrf_fmax, ndiag=ndiag, fmax_o=fmax) - ! Make GDP data [gdp] from [gdp] - call mkgdp ( mapfname=map_fgdp, datfname=mksrf_fgdp, ndiag=ndiag, gdp_o=gdp) + ! ! Make GDP data [gdp] from [gdp] + ! call mkgdp ( mapfname=map_fgdp, datfname=mksrf_fgdp, ndiag=ndiag, gdp_o=gdp) - ! Make peat data [fpeat] from [peatf] - call mkpeat ( mapfname=map_fpeat, datfname=mksrf_fpeat, ndiag=ndiag, peat_o=fpeat) + ! ! Make peat data [fpeat] from [peatf] + ! call mkpeat ( mapfname=map_fpeat, datfname=mksrf_fpeat, ndiag=ndiag, peat_o=fpeat) - ! Make soil depth data [soildepth] from [soildepthf] - call mksoildepth ( mapfname=map_fsoildepth, datfname=mksrf_fsoildepth, ndiag=ndiag, soildepth_o=soildepth) + ! ! Make soil depth data [soildepth] from [soildepthf] + ! call mksoildepth ( mapfname=map_fsoildepth, datfname=mksrf_fsoildepth, ndiag=ndiag, soildepth_o=soildepth) - ! Make agricultural fire peak month data [abm] from [abm] - call mkagfirepkmon ( mapfname=map_fabm, datfname=mksrf_fabm, ndiag=ndiag, agfirepkmon_o=agfirepkmon) + ! ! Make agricultural fire peak month data [abm] from [abm] + ! call mkagfirepkmon ( mapfname=map_fabm, datfname=mksrf_fabm, ndiag=ndiag, agfirepkmon_o=agfirepkmon) #endif #ifdef TODO - ! Make elevation [elev] from [ftopo, ffrac] dataset - ! Used only to screen pcturb, screen pcturb by elevation threshold from elev dataset - if ( .not. all_urban .and. .not. all_veg )then - allocate(elev(lsize_o)) - elev(:) = spval - ! NOTE(wjs, 2016-01-15) This uses the 'TOPO_ICE' variable for historical reasons - ! (this same dataset used to be used for glacier-related purposes as well). - ! TODO(wjs, 2016-01-15) A better solution for this urban screening would probably - ! be to modify the raw urban data; in that case, I believe we could remove furbtopo. - call mkelev ( mapfname=map_furbtopo, datfname=mksrf_furbtopo, varname='TOPO_ICE', ndiag=ndiag, elev_o=elev) - where (elev .gt. elev_thresh) - pcturb = 0._r8 - end where - deallocate(elev) - end if + ! ! Make elevation [elev] from [ftopo, ffrac] dataset + ! ! Used only to screen pcturb, screen pcturb by elevation threshold from elev dataset + ! if ( .not. all_urban .and. .not. all_veg )then + ! allocate(elev(lsize_o)) + ! elev(:) = spval + ! ! NOTE(wjs, 2016-01-15) This uses the 'TOPO_ICE' variable for historical reasons + ! ! (this same dataset used to be used for glacier-related purposes as well). + ! ! TODO(wjs, 2016-01-15) A better solution for this urban screening would probably + ! ! be to modify the raw urban data; in that case, I believe we could remove furbtopo. + ! call mkelev ( mapfname=map_furbtopo, datfname=mksrf_furbtopo, varname='TOPO_ICE', ndiag=ndiag, elev_o=elev) + ! where (elev .gt. elev_thresh) + ! pcturb = 0._r8 + ! end where + ! deallocate(elev) + ! end if - ! Compute topography statistics [topo_stddev, slope] from [ftopostats] - call mktopostats ( mapfname=map_ftopostats, datfname=mksrf_ftopostats, & - ndiag=ndiag, topo_stddev_o=topo_stddev, slope_o=slope, std_elev=std_elev) + ! ! Compute topography statistics [topo_stddev, slope] from [ftopostats] + ! call mktopostats ( mapfname=map_ftopostats, datfname=mksrf_ftopostats, & + ! ndiag=ndiag, topo_stddev_o=topo_stddev, slope_o=slope, std_elev=std_elev) - ! Make VIC parameters [binfl, ws, dsmax, ds] from [fvic] - if ( outnc_vic )then - call mkVICparams ( mapfname=map_fvic, datfname=mksrf_fvic, ndiag=ndiag, & - binfl_o=vic_binfl, ws_o=vic_ws, dsmax_o=vic_dsmax, ds_o=vic_ds) - end if + ! ! Make VIC parameters [binfl, ws, dsmax, ds] from [fvic] + ! if ( outnc_vic )then + ! call mkVICparams ( mapfname=map_fvic, datfname=mksrf_fvic, ndiag=ndiag, & + ! binfl_o=vic_binfl, ws_o=vic_ws, dsmax_o=vic_dsmax, ds_o=vic_ds) + ! end if - ! Make VOC emission factors for isoprene [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] - call mkvocef ( mapfname=map_fvocef, datfname=mksrf_fvocef, ndiag=ndiag, & - ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & - ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp) + ! ! Make VOC emission factors for isoprene [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] + ! call mkvocef ( mapfname=map_fvocef, datfname=mksrf_fvocef, ndiag=ndiag, & + ! ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & + ! ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp) - ! Do landuse changes such as for the poles, etc. - call change_landuse( dynpft=.false. ) + ! ! Do landuse changes such as for the poles, etc. + ! call change_landuse( dynpft=.false. ) #endif ! ---------------------------------------------------------------------- @@ -498,121 +500,121 @@ program mksurfdata ! ---------------------------------------------------------------------- do n = 1,lsize_o - pctlak(n) = float(nint(pctlak(n))) - pctwet(n) = float(nint(pctwet(n))) + !pctlak(n) = float(nint(pctlak(n))) + !pctwet(n) = float(nint(pctwet(n))) end do call ESMF_LogWrite("After fixes", ESMF_LOGMSG_INFO) #ifdef TODO - do n = 1,lsize_o - ! Truncate all percentage fields on output grid. This is needed to - ! insure that wt is zero (not a very small number such as - ! 1e-16) where it really should be zero - - do k = 1,nlevsoi - pctsand(n,k) = float(nint(pctsand(n,k))) - pctclay(n,k) = float(nint(pctclay(n,k))) - end do - pctlak(n) = float(nint(pctlak(n))) - pctwet(n) = float(nint(pctwet(n))) - pctgla(n) = float(nint(pctgla(n))) - - ! Assume wetland, glacier and/or lake when dataset landmask implies ocean - ! (assume medium soil color (15) and loamy texture). - ! Also set pftdata_mask here - - if (pctlnd_pft(n) < 1.e-6_r8) then - pftdata_mask(n) = 0 - soicol(n) = 15 - if (pctgla(n) < 1.e-6_r8) then - pctwet(n) = 100._r8 - pctlak(n) - pctgla(n) = 0._r8 - else - pctwet(n) = max(100._r8 - pctgla(n) - pctlak(n), 0.0_r8) - end if - pcturb(n) = 0._r8 - !call pctnatpft(n)%set_pct_l2g(0._r8) - !call pctcft(n)%set_pct_l2g(0._r8) - pctsand(n,:) = 43._r8 - pctclay(n,:) = 18._r8 - organic(n,:) = 0._r8 - else - pftdata_mask(n) = 1 - end if - - ! Make sure sum of land cover types does not exceed 100. If it does, - ! subtract excess from most dominant land cover. - - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - if (suma > 250._r4) then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb and pctgla is greater than 250%' - write (6,*)'n,pctlak,pctwet,pcturb,pctgla= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n) - call shr_sys_abort() - else if (suma > 100._r4) then - pctlak(n) = pctlak(n) * 100._r8/suma - pctwet(n) = pctwet(n) * 100._r8/suma - pcturb(n) = pcturb(n) * 100._r8/suma - pctgla(n) = pctgla(n) * 100._r8/suma - end if - end do - - call normalizencheck_landuse() - - ! Write out sum of PFT's - - do k = natpft_lb,natpft_ub - suma = 0._r8 - do n = 1,lsize_o - suma = suma + pctnatpft(n)%get_one_pct_p2g(k) - enddo - write(6,*) 'sum over domain of pft ',k,suma - enddo - write(6,*) - - do k = cft_lb,cft_ub - suma = 0._r8 - do n = 1,lsize_o - suma = suma + pctcft(n)%get_one_pct_p2g(k) - enddo - write(6,*) 'sum over domain of cft ',k,suma - enddo - write(6,*) - - ! Make final values of percent urban by class - ! This call needs to occur after all corrections are made to pcturb - - call normalize_classes_by_gcell(urban_classes, pcturb, urban_classes_g) - - ! ---------------------------------------------------------------------- - ! Make glacier multiple elevation classes [pctglcmec,topoglcmec] from [fglacier] dataset - ! ---------------------------------------------------------------------- - - ! This call needs to occur after pctgla has been adjusted for the final time - - if ( outnc_3dglc )then - allocate(pctglcmec_gic(lsize_o,nglcec)) - allocate(pctglcmec_icesheet(lsize_o,nglcec)) - allocate(pctglc_gic(lsize_o)) - allocate(pctglc_icesheet(lsize_o)) - - call mkglcmec ( mapfname=map_fglacier, & - datfname_fglacier=mksrf_fglacier, ndiag=ndiag, & - pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, & - pctglcmec_gic_o=pctglcmec_gic, pctglcmec_icesheet_o=pctglcmec_icesheet, & - pctglc_gic_o=pctglc_gic, pctglc_icesheet_o=pctglc_icesheet) - else - call mkglcmec ( mapfname=map_fglacier, & - datfname_fglacier=mksrf_fglacier, ndiag=ndiag, & - pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec ) - end if + ! do n = 1,lsize_o + ! ! Truncate all percentage fields on output grid. This is needed to + ! ! insure that wt is zero (not a very small number such as + ! ! 1e-16) where it really should be zero + + ! do k = 1,nlevsoi + ! pctsand(n,k) = float(nint(pctsand(n,k))) + ! pctclay(n,k) = float(nint(pctclay(n,k))) + ! end do + ! pctlak(n) = float(nint(pctlak(n))) + ! pctwet(n) = float(nint(pctwet(n))) + ! pctgla(n) = float(nint(pctgla(n))) + + ! ! Assume wetland, glacier and/or lake when dataset landmask implies ocean + ! ! (assume medium soil color (15) and loamy texture). + ! ! Also set pftdata_mask here + + ! if (pctlnd_pft(n) < 1.e-6_r8) then + ! pftdata_mask(n) = 0 + ! soicol(n) = 15 + ! if (pctgla(n) < 1.e-6_r8) then + ! pctwet(n) = 100._r8 - pctlak(n) + ! pctgla(n) = 0._r8 + ! else + ! pctwet(n) = max(100._r8 - pctgla(n) - pctlak(n), 0.0_r8) + ! end if + ! pcturb(n) = 0._r8 + ! !call pctnatpft(n)%set_pct_l2g(0._r8) + ! !call pctcft(n)%set_pct_l2g(0._r8) + ! pctsand(n,:) = 43._r8 + ! pctclay(n,:) = 18._r8 + ! organic(n,:) = 0._r8 + ! else + ! pftdata_mask(n) = 1 + ! end if + + ! ! Make sure sum of land cover types does not exceed 100. If it does, + ! ! subtract excess from most dominant land cover. + + ! suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + ! if (suma > 250._r4) then + ! write (6,*) subname, ' error: sum of pctlak, pctwet,', & + ! 'pcturb and pctgla is greater than 250%' + ! write (6,*)'n,pctlak,pctwet,pcturb,pctgla= ', & + ! n,pctlak(n),pctwet(n),pcturb(n),pctgla(n) + ! call shr_sys_abort() + ! else if (suma > 100._r4) then + ! pctlak(n) = pctlak(n) * 100._r8/suma + ! pctwet(n) = pctwet(n) * 100._r8/suma + ! pcturb(n) = pcturb(n) * 100._r8/suma + ! pctgla(n) = pctgla(n) * 100._r8/suma + ! end if + ! end do + + ! call normalizencheck_landuse() + + ! ! Write out sum of PFT's + + ! do k = natpft_lb,natpft_ub + ! suma = 0._r8 + ! do n = 1,lsize_o + ! suma = suma + pctnatpft(n)%get_one_pct_p2g(k) + ! enddo + ! write(6,*) 'sum over domain of pft ',k,suma + ! enddo + ! write(6,*) + + ! do k = cft_lb,cft_ub + ! suma = 0._r8 + ! do n = 1,lsize_o + ! suma = suma + pctcft(n)%get_one_pct_p2g(k) + ! enddo + ! write(6,*) 'sum over domain of cft ',k,suma + ! enddo + ! write(6,*) + + ! ! Make final values of percent urban by class + ! ! This call needs to occur after all corrections are made to pcturb + + ! call normalize_classes_by_gcell(urban_classes, pcturb, urban_classes_g) + + ! ! ---------------------------------------------------------------------- + ! ! Make glacier multiple elevation classes [pctglcmec,topoglcmec] from [fglacier] dataset + ! ! ---------------------------------------------------------------------- + + ! ! This call needs to occur after pctgla has been adjusted for the final time + + ! if ( outnc_3dglc )then + ! allocate(pctglcmec_gic(lsize_o,nglcec)) + ! allocate(pctglcmec_icesheet(lsize_o,nglcec)) + ! allocate(pctglc_gic(lsize_o)) + ! allocate(pctglc_icesheet(lsize_o)) + + ! call mkglcmec ( mapfname=map_fglacier, & + ! datfname_fglacier=mksrf_fglacier, ndiag=ndiag, & + ! pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, & + ! pctglcmec_gic_o=pctglcmec_gic, pctglcmec_icesheet_o=pctglcmec_icesheet, & + ! pctglc_gic_o=pctglc_gic, pctglc_icesheet_o=pctglc_icesheet) + ! else + ! call mkglcmec ( mapfname=map_fglacier, & + ! datfname_fglacier=mksrf_fglacier, ndiag=ndiag, & + ! pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec ) + ! end if - ! Determine fractional land from pft dataset + ! ! Determine fractional land from pft dataset - do n = 1,lsize_o - landfrac_pft(n) = pctlnd_pft(n)/100._r8 - end do + ! do n = 1,lsize_o + ! landfrac_pft(n) = pctlnd_pft(n)/100._r8 + ! end do #endif ! ---------------------------------------------------------------------- @@ -640,7 +642,8 @@ program mksurfdata call ESMF_LogWrite("Calling mkfile_fsurdat", ESMF_LOGMSG_INFO) call mkfile_fsurdat( mksrf_fgrid_mesh_nx, mksrf_fgrid_mesh_ny, mesh_model, dynlanduse=.false., & pctlak=pctlak, pctwet=pctwet, lakedepth=lakedepth, organic=organic, & - urban_classes=urban_classes, urban_region=urban_region) + urban_classes=urban_classes, urban_region=urban_region, & + soil_color=soil_color, nsoilcol=nsoilcol) call ESMF_LogWrite(subname//'successfully created file '//trim(fsurdat), ESMF_LOGMSG_INFO) end if ! if (fsurdat /= ' ') @@ -656,7 +659,7 @@ program mksurfdata deallocate ( elevclass ) deallocate ( fmax ) deallocate ( pctsand, pctclay ) - deallocate ( soicol ) + deallocate ( soil_color ) deallocate ( gdp, fpeat, agfirepkmon ) deallocate ( soildepth ) deallocate ( topo_stddev, slope ) diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 965c1dc133..22464c762f 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -114,12 +114,10 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & logical , intent(in) :: zero_out ! if should zero urban out real(r8) , intent(out) :: urbn_o(:) ! output grid: total % urban real(r8) , intent(out) :: urban_classes_o(:,:) ! output grid: breakdown of total urban into each class - integer , intent(out) :: region_o(:) ! output grid: region ID + integer , intent(inout) :: region_o(:) ! output grid: region ID integer , intent(out) :: rc ! local variables: - integer , pointer :: factorindexlist(:,:) - real(r8), pointer :: factorlist(:) type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i type(ESMF_Field) :: field_i @@ -141,6 +139,8 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & integer :: srcMaskValue = -987987 ! spval for RH mask values integer :: dstMaskValue = -987987 ! spval for RH mask values integer :: srcTermProcessing_Value = 0 + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) character(len=*), parameter :: subname = 'mkurban' !----------------------------------------------------------------------- @@ -202,8 +202,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & !srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_DSTAREA, & srcTermProcessing=srcTermProcessing_Value, & - ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & - factorlist=factorlist, factorindexlist=factorindexlist, rc=rc) + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) @@ -228,6 +227,31 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & urban_classes_gcell_o(n,l) = data_o(l,n) end do end do + + ! Determine frac_o (regrid frac_i to frac_o) + allocate(frac_i(ns_i)) + allocate(frac_o(ns_o)) + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(field_i, field_o, routehandle, frac_i, frac_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regrid_data in data_i "//trim(subname)) + + do n = 1,ns_o + if (frac_o(n) > 0._r8) then + urban_classes_gcell_o(n,:) = urban_classes_gcell_o(n,:) / frac_o(n) + else + urban_classes_gcell_o(n,:) = 0._r8 + end if + end do do n = 1, ns_o urbn_o(n) = sum(urban_classes_gcell_o(n,:)) end do @@ -285,6 +309,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & write (ndiag,'(a)') 'Attempting to make urban region .....' end if +#ifdef TODO ! Read in region field ! Note: we do this here, rather than with the rest of the reads above, because we ! expect the input urban fields to be large, so we're just reading the fields as @@ -333,7 +358,6 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & write (ndiag,*) end if -#ifdef TODO ! Output diagnostics ! call output_diagnostics_index(factorlist, factorindex, region_i, region_o, 'Urban Region ID', & ! 1, max_region, ndiag) @@ -346,7 +370,6 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & deallocate (urban_classes_gcell_i, urban_classes_gcell_o, region_i) call ESMF_VMLogMemInfo("Before destroy operation in "//trim(subname)) - deallocate(factorlist, factorindexlist) call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mkutilsMod.F90 b/tools/mksurfdata_esmf/src/mkutilsMod.F90 index 7a2439972c..77a57b46d3 100644 --- a/tools/mksurfdata_esmf/src/mkutilsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkutilsMod.F90 @@ -15,6 +15,7 @@ module mkutilsMod public :: slightly_above public :: get_filename !Returns filename given full pathname public :: chkerr + public :: mkrank character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -25,7 +26,6 @@ module mkutilsMod subroutine normalize_classes_by_gcell(classes_pct_tot, sums, classes_pct_gcell) ! - ! !DESCRIPTION: ! Renormalizes an array (gcell x class) so that values are given as % of total grid cell area ! ! Specifically: Given (1) an array specifying the % cover of different classes, as a % of @@ -42,10 +42,7 @@ subroutine normalize_classes_by_gcell(classes_pct_tot, sums, classes_pct_gcell) ! classes_pct_gcell(n,i) will give the % of the total area of grid cell n that is in urban ! class #i. ! - ! !USES: - ! ! !ARGUMENTS: - implicit none real(r8), intent(in) :: classes_pct_tot(:,:) ! % cover of classes as % of total real(r8), intent(in) :: sums(:) ! totals, as % of grid cell real(r8), intent(out):: classes_pct_gcell(:,:) ! % cover of classes as % of grid cell @@ -116,18 +113,18 @@ end function slightly_below !=============================================================== logical function slightly_above(a, b, eps) - ! !DESCRIPTION: ! Returns true if a is slightly above b; false if a is significantly above b or if a is ! less than or equal to b - - ! !ARGUMENTS: + ! ! if provided, eps gives the relative error allowed for checking the "slightly" ! condition; if not provided, the tolerance defaults to the value given by eps_default + + ! input/output variables real(r8), intent(in) :: a real(r8), intent(in) :: b real(r8), intent(in), optional :: eps - ! !LOCAL VARIABLES: + ! local variables: real(r8) :: l_eps real(r8), parameter :: eps_default = 1.e-15_r8 ! default relative error tolerance !------------------------------------------------------------------------------ @@ -182,4 +179,73 @@ character(len=256) function get_filename (fulpath) end function get_filename + !=============================================================== + subroutine mkrank (n, a, miss, num, iv) + ! + ! Return indices of largest [num] values in array [a]. + ! + ! input/output variables + integer , intent(in) :: n !array length + real(r8), intent(in) :: a(0:n) !array to be ranked + integer , intent(in) :: miss !missing data value + integer , intent(in) :: num !number of largest values requested + integer , intent(out):: iv(num) !index to [num] largest values in array [a] + + ! local variables: + real(r8) a_max !maximum value in array + integer i !array index + real(r8) delmax !tolerance for finding if larger value + integer m !do loop index + integer k !do loop index + logical exclude !true if data value has already been chosen + !----------------------------------------------------------------------- + + delmax = 1.e-06 + + ! Find index of largest non-zero number + + iv(1) = miss + a_max = -9999. + + do i = 0, n + if (a(i)>0. .and. (a(i)-a_max)>delmax) then + a_max = a(i) + iv(1) = i + end if + end do + + ! iv(1) = miss indicates no values > 0. this is an error + + if (iv(1) == miss) then + write (6,*) 'MKRANK error: iv(1) = missing' + call shr_sys_abort() + end if + + ! Find indices of the next [num]-1 largest non-zero number. + ! iv(m) = miss if there are no more values > 0 + + do m = 2, num + iv(m) = miss + a_max = -9999. + do i = 0, n + + ! exclude if data value has already been chosen + exclude = .false. + do k = 1, m-1 + if (i == iv(k)) exclude = .true. + end do + + ! if not already chosen, see if it is the largest of + ! the remaining values + if (.not. exclude) then + if (a(i)>0. .and. (a(i)-a_max)>delmax) then + a_max = a(i) + iv(m) = i + end if + end if + end do + end do + + end subroutine mkrank + end module mkutilsMod From cf81dee7d713979b39a5382522e8d71a9741374a Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 27 Jan 2022 12:21:35 -0700 Subject: [PATCH 029/614] refactor of mksoilcolMod and introduction of new r4 capability --- tools/mksurfdata_esmf/src/mkesmfMod.F90 | 80 ++++++++- tools/mksurfdata_esmf/src/mkpioMod.F90 | 183 +++++++++++++++++--- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 103 ++++------- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 2 +- tools/mksurfdata_esmf/src/mkutilsMod.F90 | 121 ++++++++++--- tools/mksurfdata_esmf/src/mkvarctl.F90 | 2 + 6 files changed, 363 insertions(+), 128 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkesmfMod.F90 b/tools/mksurfdata_esmf/src/mkesmfMod.F90 index 5515be33c5..23a2ee41d3 100644 --- a/tools/mksurfdata_esmf/src/mkesmfMod.F90 +++ b/tools/mksurfdata_esmf/src/mkesmfMod.F90 @@ -11,8 +11,10 @@ module mkesmfMod public :: regrid_rawdata interface regrid_rawdata - module procedure regrid_rawdata1d - module procedure regrid_rawdata2d + module procedure regrid_rawdata1d_r4 + module procedure regrid_rawdata1d_r8 + module procedure regrid_rawdata2d_r4 + module procedure regrid_rawdata2d_r8 end interface regrid_rawdata character(len=*) , parameter :: u_FILE_u = & @@ -22,7 +24,39 @@ module mkesmfMod contains !=============================================================== - subroutine regrid_rawdata1d(field_i, field_o, routehandle, data_i, data_o, rc) + subroutine regrid_rawdata1d_r4(field_i, field_o, routehandle, data_i, data_o, rc) + + ! input/output variables + type(ESMF_Field) , intent(in) :: field_i + type(ESMF_Field) , intent(inout) :: field_o + type(ESMF_RouteHandle) , intent(inout) :: routehandle + real(r4) , intent(in) :: data_i(:) + real(r4) , intent(inout) :: data_o(:) + integer , intent(out) :: rc + + ! local variables + logical :: checkflag = .false. + real(r4), pointer :: dataptr(:) + ! -------------------------------------------- + + rc = ESMF_SUCCESS + + ! Interpolate data_i to data_o + call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) + dataptr(:) = data_i(:) + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + dataptr(:) = 0._r8 + call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, & + termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + data_o(:) = dataptr(:) + call ESMF_VMLogMemInfo("After field regrid in regrid_data") + + end subroutine regrid_rawdata1d_r4 + + !=============================================================== + subroutine regrid_rawdata1d_r8(field_i, field_o, routehandle, data_i, data_o, rc) ! input/output variables type(ESMF_Field) , intent(in) :: field_i @@ -51,10 +85,44 @@ subroutine regrid_rawdata1d(field_i, field_o, routehandle, data_i, data_o, rc) data_o(:) = dataptr(:) call ESMF_VMLogMemInfo("After field regrid in regrid_data") - end subroutine regrid_rawdata1d + end subroutine regrid_rawdata1d_r8 + + !=============================================================== + subroutine regrid_rawdata2d_r4(field_i, field_o, routehandle, data_i, data_o, rc) + + ! input/output variables + type(ESMF_Field) , intent(in) :: field_i + type(ESMF_Field) , intent(inout) :: field_o + type(ESMF_RouteHandle) , intent(inout) :: routehandle + real(r4) , intent(in) :: data_i(:,:) + real(r4) , intent(inout) :: data_o(:,:) + integer , intent(out) :: rc + + ! local variables + logical :: checkflag = .false. + integer :: n,l + real(r4), pointer :: dataptr(:,:) + ! -------------------------------------------- + + rc = ESMF_SUCCESS + + ! Interpolate data_i to data_o + call ESMF_VMLogMemInfo("Before field regrid in regrid_rawdata2d") + call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) + dataptr(:,:) = data_i(:,:) + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + dataptr(:,:) = 0._r8 + call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, & + termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + data_o(:,:) = dataptr(:,:) + call ESMF_VMLogMemInfo("After field regrid in regrid_rawdata2d") + + end subroutine regrid_rawdata2d_r4 !=============================================================== - subroutine regrid_rawdata2d(field_i, field_o, routehandle, data_i, data_o, rc) + subroutine regrid_rawdata2d_r8(field_i, field_o, routehandle, data_i, data_o, rc) ! input/output variables type(ESMF_Field) , intent(in) :: field_i @@ -85,6 +153,6 @@ subroutine regrid_rawdata2d(field_i, field_o, routehandle, data_i, data_o, rc) data_o(:,:) = dataptr(:,:) call ESMF_VMLogMemInfo("After field regrid in regrid_rawdata2d") - end subroutine regrid_rawdata2d + end subroutine regrid_rawdata2d_r8 end module mkesmfMod diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 316ca1d33b..6a8c22b43c 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -25,8 +25,10 @@ module mkpioMod interface mkpio_get_rawdata module procedure mkpio_get_rawdata1d_int - module procedure mkpio_get_rawdata1d_real - module procedure mkpio_get_rawdata2d_real + module procedure mkpio_get_rawdata1d_real4 + module procedure mkpio_get_rawdata1d_real8 + module procedure mkpio_get_rawdata2d_real4 + module procedure mkpio_get_rawdata2d_real8 end interface mkpio_get_rawdata interface mkpio_def_spatial_var @@ -63,7 +65,7 @@ subroutine mkpio_get_rawdata1d_int(pioid, varname, mesh_i, data_i, rc) ! local variables type(var_desc_t) :: pio_varid integer :: pio_vartype - type(io_desc_t) :: pio_iodesc_data + type(io_desc_t) :: pio_iodesc type(io_desc_t) :: pio_iodesc_mask integer :: lsize integer :: rcode @@ -79,21 +81,21 @@ subroutine mkpio_get_rawdata1d_int(pioid, varname, mesh_i, data_i, rc) ! Create io descriptor for input raw data ! This will query the raw data file for the dimensions of the variable varname and ! create iodesc for either single or multi level input data - call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc_data, rc) + call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Read the input raw data - call ESMF_VMLogMemInfo("After mkpio_iodesc_data for varname "//trim(varname)) - call pio_read_darray(pioid, pio_varid, pio_iodesc_data, data_i, rcode) + call ESMF_VMLogMemInfo("After mkpio_iodesc for varname "//trim(varname)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_i, rcode) call ESMF_VMLogMemInfo("After call to pio_read_darrayy for varname "//trim(varname)) - call pio_freedecomp(pioid, pio_iodesc_data) + call pio_freedecomp(pioid, pio_iodesc) call ESMF_VMLogMemInfo("After call to pio_freedecomp for "//trim(varname)) call ESMF_LogWrite("At end of "//trim(subname), ESMF_LOGMSG_INFO) end subroutine mkpio_get_rawdata1d_int !=============================================================== - subroutine mkpio_get_rawdata1d_real(pioid, varname, mesh_i, data_i, rc) + subroutine mkpio_get_rawdata1d_real8(pioid, varname, mesh_i, data_i, rc) ! input/output variables type(file_desc_t), intent(inout) :: pioid @@ -105,7 +107,7 @@ subroutine mkpio_get_rawdata1d_real(pioid, varname, mesh_i, data_i, rc) ! local variables type(var_desc_t) :: pio_varid integer :: pio_vartype - type(io_desc_t) :: pio_iodesc_data + type(io_desc_t) :: pio_iodesc type(io_desc_t) :: pio_iodesc_mask real(r4), allocatable :: data_real(:) real(r8), allocatable :: data_double(:) @@ -124,15 +126,15 @@ subroutine mkpio_get_rawdata1d_real(pioid, varname, mesh_i, data_i, rc) ! Create io descriptor for input raw data ! This will query the raw data file for the dimensions of the variable varname and ! create iodesc for either single or multi level input data - call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc_data, rc) + call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Read the input raw data - call ESMF_VMLogMemInfo("After mkpio_iodesc_data for varname "//trim(varname)) + call ESMF_VMLogMemInfo("After mkpio_iodesc for varname "//trim(varname)) if (pio_vartype == PIO_REAL) then allocate(data_real(lsize)) call ESMF_VMLogMemInfo("Calling pio_read_darray for varname "//trim(varname)) - call pio_read_darray(pioid, pio_varid, pio_iodesc_data, data_real, rcode) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real, rcode) call ESMF_VMLogMemInfo("Finished pio_read_darray for varname "//trim(varname)) data_i(:) = real(data_real(:), kind=r8) call ESMF_LogWrite("Finished transfer to data_i for varname "//trim(varname)) @@ -140,20 +142,80 @@ subroutine mkpio_get_rawdata1d_real(pioid, varname, mesh_i, data_i, rc) call ESMF_LogWrite("Finished deallocate of data_real for varname "//trim(varname)) else if (pio_vartype == PIO_DOUBLE) then allocate(data_double(lsize)) - call pio_read_darray(pioid, pio_varid, pio_iodesc_data, data_double, rcode) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double, rcode) data_i(:) = data_double(:) deallocate(data_double) else call shr_sys_abort(subName//"ERROR: only real and double types are supported") end if call ESMF_VMLogMemInfo("After call to pio_read_darrayy for varname "//trim(varname)) - call pio_freedecomp(pioid, pio_iodesc_data) + call pio_freedecomp(pioid, pio_iodesc) call ESMF_VMLogMemInfo("After call to pio_freedecomp for "//trim(varname)) - end subroutine mkpio_get_rawdata1d_real + end subroutine mkpio_get_rawdata1d_real8 !=============================================================== - subroutine mkpio_get_rawdata2d_real(pioid, varname, mesh_i, data_i, rc) + subroutine mkpio_get_rawdata1d_real4(pioid, varname, mesh_i, data_i, rc) + + ! input/output variables + type(file_desc_t), intent(inout) :: pioid + character(len=*) , intent(in) :: varname ! field name in rawdata file + type(ESMF_Mesh) , intent(in) :: mesh_i + real(r4) , intent(inout) :: data_i(:) ! input raw data + integer , intent(out) :: rc + + ! local variables + type(var_desc_t) :: pio_varid + integer :: pio_vartype + type(io_desc_t) :: pio_iodesc + type(io_desc_t) :: pio_iodesc_mask + real(r4), allocatable :: data_real(:) + real(r8), allocatable :: data_double(:) + real(r4), allocatable :: landmask(:) + integer :: lsize + integer :: rcode + integer :: n + character(len=*), parameter :: subname = 'mkpio_get_rawdata1d' + !------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Get data_i - Read in varname from filename + lsize = size(data_i) + + ! Create io descriptor for input raw data + ! This will query the raw data file for the dimensions of the variable varname and + ! create iodesc for either single or multi level input data + call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Read the input raw data + call ESMF_VMLogMemInfo("After mkpio_iodesc for varname "//trim(varname)) + if (pio_vartype == PIO_REAL) then + allocate(data_real(lsize)) + call ESMF_VMLogMemInfo("Calling pio_read_darray for varname "//trim(varname)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real, rcode) + call ESMF_VMLogMemInfo("Finished pio_read_darray for varname "//trim(varname)) + data_i(:) = data_real(:) + call ESMF_LogWrite("Finished transfer to data_i for varname "//trim(varname)) + deallocate(data_real) + call ESMF_LogWrite("Finished deallocate of data_real for varname "//trim(varname)) + else if (pio_vartype == PIO_DOUBLE) then + allocate(data_double(lsize)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double, rcode) + data_i(:) = real(data_double(:), kind=r4) + deallocate(data_double) + else + call shr_sys_abort(subName//"ERROR: only real and double types are supported") + end if + call ESMF_VMLogMemInfo("After call to pio_read_darrayy for varname "//trim(varname)) + call pio_freedecomp(pioid, pio_iodesc) + call ESMF_VMLogMemInfo("After call to pio_freedecomp for "//trim(varname)) + + end subroutine mkpio_get_rawdata1d_real4 + + !=============================================================== + subroutine mkpio_get_rawdata2d_real8(pioid, varname, mesh_i, data_i, rc) ! input/output variables type(file_desc_t) , intent(inout) :: pioid @@ -165,7 +227,7 @@ subroutine mkpio_get_rawdata2d_real(pioid, varname, mesh_i, data_i, rc) ! local variables type(var_desc_t) :: pio_varid integer :: pio_vartype - type(io_desc_t) :: pio_iodesc_data + type(io_desc_t) :: pio_iodesc type(io_desc_t) :: pio_iodesc_mask real(r4), allocatable :: data_real1d(:) real(r4), allocatable :: data_real2d(:,:) @@ -189,7 +251,7 @@ subroutine mkpio_get_rawdata2d_real(pioid, varname, mesh_i, data_i, rc) ! This will query the raw data file for the dimensions of the variable varname and ! create iodesc for either single or multi level input data call ESMF_VMLogMemInfo("Before mkpio_iodesc in "//trim(subname)) - call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc_data, rc) + call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_iodesc in "//trim(subname)) @@ -199,7 +261,7 @@ subroutine mkpio_get_rawdata2d_real(pioid, varname, mesh_i, data_i, rc) ! Input data is read into (lsize,nlev) array and then transferred to data_i(nlev,lsize) if (pio_vartype == PIO_REAL) then allocate(data_real2d(lsize,nlev)) - call pio_read_darray(pioid, pio_varid, pio_iodesc_data, data_real2d, rcode) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real2d, rcode) do l = 1,nlev do n = 1,lsize data_i(l,n) = real(data_real2d(n,l), kind=r8) @@ -208,7 +270,7 @@ subroutine mkpio_get_rawdata2d_real(pioid, varname, mesh_i, data_i, rc) deallocate(data_real2d) else if (pio_vartype == PIO_DOUBLE) then allocate(data_double2d(lsize,nlev)) - call pio_read_darray(pioid, pio_varid, pio_iodesc_data, data_double2d, rcode) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double2d, rcode) do l = 1,nlev do n = 1,lsize data_i(l,n) = data_double2d(n,l) @@ -218,9 +280,78 @@ subroutine mkpio_get_rawdata2d_real(pioid, varname, mesh_i, data_i, rc) else call shr_sys_abort(subName//"ERROR: only real and double types are supported") end if - call pio_freedecomp(pioid, pio_iodesc_data) + call pio_freedecomp(pioid, pio_iodesc) - end subroutine mkpio_get_rawdata2d_real + end subroutine mkpio_get_rawdata2d_real8 + + !=============================================================== + subroutine mkpio_get_rawdata2d_real4(pioid, varname, mesh_i, data_i, rc) + + ! input/output variables + type(file_desc_t) , intent(inout) :: pioid + character(len=*) , intent(in) :: varname ! field name in rawdata file + type(ESMF_Mesh) , intent(in) :: mesh_i + real(r4) , intent(inout) :: data_i(:,:) ! input raw data + integer , intent(out) :: rc + + ! local variables + type(var_desc_t) :: pio_varid + integer :: pio_vartype + type(io_desc_t) :: pio_iodesc + real(r4), allocatable :: data_real1d(:) + real(r4), allocatable :: data_real2d(:,:) + real(r8), allocatable :: data_double1d(:) + real(r8), allocatable :: data_double2d(:,:) + real(r4), allocatable :: landmask(:) + integer :: lsize, nlev + integer :: n,l + integer :: rcode + character(len=*), parameter :: subname = ' mkpio_get_rawdata_2d' + !------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Get data_i - Read in varname from filename + ! Note that data_i is coming in as (nlev,lsize) in terms of dimensions + nlev = size(data_i, dim=1) + lsize = size(data_i, dim=2) + + ! Create io descriptor for input raw data + ! This will query the raw data file for the dimensions of the variable varname and + ! create iodesc for either single or multi level input data + call ESMF_VMLogMemInfo("Before mkpio_iodesc in "//trim(subname)) + call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_iodesc in "//trim(subname)) + + ! Read the input raw data (all levels read at once) + ! - levels are the innermost dimension for esmf fields + ! - levels are the outermost dimension in pio reads + ! Input data is read into (lsize,nlev) array and then transferred to data_i(nlev,lsize) + if (pio_vartype == PIO_REAL) then + allocate(data_real2d(lsize,nlev)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real2d, rcode) + do l = 1,nlev + do n = 1,lsize + data_i(l,n) = data_real2d(n,l) + end do + end do + deallocate(data_real2d) + else if (pio_vartype == PIO_DOUBLE) then + allocate(data_double2d(lsize,nlev)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double2d, rcode) + do l = 1,nlev + do n = 1,lsize + data_i(l,n) = real(data_double2d(n,l), kind=r4) + end do + end do + deallocate(data_double2d) + else + call shr_sys_abort(subName//"ERROR: only real and double types are supported") + end if + call pio_freedecomp(pioid, pio_iodesc) + + end subroutine mkpio_get_rawdata2d_real4 !=============================================================== subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, pio_iodesc, rc) @@ -239,7 +370,7 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, ! local variables type(ESMF_DistGrid) :: distGrid integer :: n, ndims - integer, pointer :: compdof(:) + integer, allocatable :: compdof(:) integer, allocatable :: compdof3d(:) integer, allocatable :: dimids(:) integer, allocatable :: dimlens(:) @@ -343,10 +474,10 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, end if ! deallocate memory - ! deallocate(compdof) - ! if (allocated(compdof3d)) deallocate(compdof3d) + deallocate(compdof) + if (allocated(compdof3d)) deallocate(compdof3d) - call ESMF_VMLogMemInfo("Finished setting iodesc for "//trim(varname)) + call ESMF_VMLogMemInfo("Finished setting iodesc for "//trim(varname)//" in "//trim(subname)) end subroutine mkpio_iodesc_rawdata diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index 853e3ddab5..47c54efb76 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -8,7 +8,7 @@ module mksoilcolMod use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_ioformat, pio_iosystem use mkesmfMod , only : regrid_rawdata use mkutilsMod , only : chkerr, mkrank - use mkvarctl , only : root_task, ndiag + use mkvarctl , only : root_task, ndiag, mpicom, MPI_INTEGER, MPI_MAX implicit none private @@ -48,17 +48,13 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r integer :: srcMaskValue = -987987 ! spval for RH mask values integer :: dstMaskValue = -987987 ! spval for RH mask values integer :: srcTermProcessing_Value = 0 - integer :: ndims - real(r8), allocatable :: soilcol_i(:) - real(r8), allocatable :: data_i(:,:) - real(r8), allocatable :: data_o(:,:) - real(r8), allocatable :: mask_i(:) - integer, parameter :: num = 2 ! set soil mapunit number - integer :: wsti(num) ! index to 1st and 2nd largest wst - real(r8) :: wt ! map overlap weight - logical :: has_color ! whether this grid cell has non-zero color - integer, parameter :: miss = 99999 ! missing data indicator - character(len=35), allocatable :: col(:) ! name of each color + real(r4), allocatable :: soilcol_i(:) + real(r4), allocatable :: data_i(:,:) + real(r4), allocatable :: data_o(:,:) + real(r4), allocatable :: mask_i(:) + logical :: has_color ! whether this grid cell has non-zero color + integer :: nsoilcol_local + integer :: maxindex(1) character(len=*), parameter :: subname = 'mksoilcol' !----------------------------------------------------------------------- @@ -100,66 +96,18 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - ! ** TODO: determine the maximum value of soilcol_i - across all processors - doing an all reduce - ! For now hardwire nsoilcol to 20 - nsoilcol = 20 + ! Determine maximum number of soil colors across all processors + ! This will be used for the ungridded dimension of data_o below + nsoilcol_local = maxval(soilcol_i) + call mpi_allreduce(nsoilcol_local, nsoilcol, 1, MPI_INTEGER, MPI_MAX, mpicom, rcode) + ! TODO: MPI_SUCCESS could not be accessed from mkvarctl + !if (rcode /= MPI_SUCCESS) call shr_sys_abort('error for mpi_allredice in '//trim(subname)) ! Determine ns_o and allocate data_o ns_o = size(soil_color_o) allocate(data_o(0:nsoilcol, ns_o),stat=ier) if (ier/=0) call shr_sys_abort() - ! Define the model color classes: 0 to nsoilcol - allocate(col(0:nsoilcol)) - if (nsoilcol == 20) then - col(0) = 'no soil ' - col(1) = 'class 1: light ' - col(2) = 'class 2: ' - col(3) = 'class 3: ' - col(4) = 'class 4: ' - col(5) = 'class 5: ' - col(6) = 'class 6: ' - col(7) = 'class 7: ' - col(8) = 'class 8: ' - col(9) = 'class 9: ' - col(10) = 'class 10: ' - col(11) = 'class 11: ' - col(12) = 'class 12: ' - col(13) = 'class 13: ' - col(14) = 'class 14: ' - col(15) = 'class 15: ' - col(16) = 'class 16: ' - col(17) = 'class 17: ' - col(18) = 'class 18: ' - col(19) = 'class 19: ' - col(20) = 'class 20: dark ' - else if (nsoilcol == 8) then - col(0) = 'no soil ' - col(1) = 'class 1: light ' - col(2) = 'class 2: ' - col(3) = 'class 3: ' - col(4) = 'class 4: ' - col(5) = 'class 5: ' - col(6) = 'class 6: ' - col(7) = 'class 7: ' - col(8) = 'class 8: dark ' - else - write(6,*)'nsoilcol value of ',nsoilcol,' is not currently supported' - call shr_sys_abort() - end if - - ! Create field on input mesh - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/0/), ungriddedUbound=(/nsoilcol/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After field_i creation in "//trim(subname)) - - ! Create field on model model - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/0/), ungriddedUbound=(/nsoilcol/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After field_o creation in "//trim(subname)) - ! Determine input landmask (frac_i) allocate(mask_i(ns_i)) call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, mask_i, rc=rc) @@ -167,15 +115,27 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r ! Now determine data_i as a real 2d array allocate(data_i(0:nsoilcol,ns_i)) - data_i(:,:) = 0._r8 + data_i(:,:) = 0._r4 do l = 1,nsoilcol do n = 1,ns_i if (int(soilcol_i(n)) == l) then - data_i(l,n) = 1._r8 * mask_i(n) + data_i(l,n) = 1._r4 * mask_i(n) end if end do end do + ! Create field on input mesh + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/0/), ungriddedUbound=(/nsoilcol/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After field_i creation in "//trim(subname)) + + ! Create field on model model + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/0/), ungriddedUbound=(/nsoilcol/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After field_o creation in "//trim(subname)) + ! Create route handle to map field_model to field_data call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & @@ -207,8 +167,10 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r ! Rank non-zero weights by color type. wsti(1) is the most extensive color type. if (has_color) then - call mkrank (nsoilcol, data_o(0:nsoilcol,no), miss, num, wsti) - soil_color_o(no) = wsti(1) + !maxindex = maxloc(data_o(0:nsoilcol,no)) + !soil_color_o(no) = maxindex + call mkrank (nsoilcol, data_o(0:nsoilcol,no), 9999, 1, maxindex) + soil_color_o(no) = maxindex(1) end if ! If land but no color, set color to 15 (in older dataset generic soil color 4) @@ -239,7 +201,6 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r write (ndiag,'(a)') end if - deallocate(col) deallocate(data_i) deallocate(data_o) deallocate(soilcol_i) diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 22464c762f..980911fb85 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -294,7 +294,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & ! First, recompute urban_classes_gcell_o, based on any changes we have made to urbn_o ! while handling special cases call ESMF_LogWrite("Before normalize_classes_by_gcell", ESMF_LOGMSG_INFO) - call normalize_classes_by_gcell(urban_classes_o, urbn_o, urban_classes_gcell_o) + !call normalize_classes_by_gcell(urban_classes_o, urbn_o, urban_classes_gcell_o) call ESMF_LogWrite("After normalize_classes_by_gcell", ESMF_LOGMSG_INFO) #ifdef TODO diff --git a/tools/mksurfdata_esmf/src/mkutilsMod.F90 b/tools/mksurfdata_esmf/src/mkutilsMod.F90 index 77a57b46d3..5fe8fd068c 100644 --- a/tools/mksurfdata_esmf/src/mkutilsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkutilsMod.F90 @@ -3,8 +3,8 @@ module mkutilsMod ! General-purpose utilities use ESMF - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod, only : shr_sys_abort + use shr_kind_mod, only : r8 => shr_kind_r8, r4 => shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort implicit none private @@ -17,6 +17,11 @@ module mkutilsMod public :: chkerr public :: mkrank + interface mkrank + module procedure mkrank_r4 + module procedure mkrank_r8 + end interface mkrank + character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -43,9 +48,9 @@ subroutine normalize_classes_by_gcell(classes_pct_tot, sums, classes_pct_gcell) ! class #i. ! ! !ARGUMENTS: - real(r8), intent(in) :: classes_pct_tot(:,:) ! % cover of classes as % of total - real(r8), intent(in) :: sums(:) ! totals, as % of grid cell - real(r8), intent(out):: classes_pct_gcell(:,:) ! % cover of classes as % of grid cell + real(r4), intent(in) :: classes_pct_tot(:,:) ! % cover of classes as % of total + real(r4), intent(in) :: sums(:) ! totals, as % of grid cell + real(r4), intent(out):: classes_pct_gcell(:,:) ! % cover of classes as % of grid cell ! ! !LOCAL VARIABLES: integer :: n, n_max @@ -74,7 +79,7 @@ subroutine normalize_classes_by_gcell(classes_pct_tot, sums, classes_pct_gcell) ! Do the work do n = 1, n_max - classes_pct_gcell(n,:) = classes_pct_tot(n,:) * (sums(n)/100._r8) + classes_pct_gcell(n,:) = classes_pct_tot(n,:) * (sums(n)/100._r4) end do end subroutine normalize_classes_by_gcell @@ -87,13 +92,13 @@ logical function slightly_below(a, b, eps) ! condition; if not provided, the tolerance defaults to the value given by eps_default ! !ARGUMENTS: - real(r8), intent(in) :: a - real(r8), intent(in) :: b - real(r8), intent(in), optional :: eps + real(r4), intent(in) :: a + real(r4), intent(in) :: b + real(r4), intent(in), optional :: eps ! !LOCAL VARIABLES: - real(r8) :: l_eps - real(r8), parameter :: eps_default = 1.e-15_r8 ! default relative error tolerance + real(r4) :: l_eps + real(r4), parameter :: eps_default = 1.e-15_r4 ! default relative error tolerance !------------------------------------------------------------------------------ if (present(eps)) then @@ -120,13 +125,13 @@ logical function slightly_above(a, b, eps) ! condition; if not provided, the tolerance defaults to the value given by eps_default ! input/output variables - real(r8), intent(in) :: a - real(r8), intent(in) :: b - real(r8), intent(in), optional :: eps + real(r4), intent(in) :: a + real(r4), intent(in) :: b + real(r4), intent(in), optional :: eps ! local variables: - real(r8) :: l_eps - real(r8), parameter :: eps_default = 1.e-15_r8 ! default relative error tolerance + real(r4) :: l_eps + real(r4), parameter :: eps_default = 1.e-15_r4 ! default relative error tolerance !------------------------------------------------------------------------------ if (present(eps)) then @@ -180,7 +185,7 @@ character(len=256) function get_filename (fulpath) end function get_filename !=============================================================== - subroutine mkrank (n, a, miss, num, iv) + subroutine mkrank_r8 (n, a, miss, num, iv) ! ! Return indices of largest [num] values in array [a]. ! @@ -192,12 +197,12 @@ subroutine mkrank (n, a, miss, num, iv) integer , intent(out):: iv(num) !index to [num] largest values in array [a] ! local variables: - real(r8) a_max !maximum value in array - integer i !array index - real(r8) delmax !tolerance for finding if larger value - integer m !do loop index - integer k !do loop index - logical exclude !true if data value has already been chosen + real(r8) :: a_max !maximum value in array + real(r8) :: delmax !tolerance for finding if larger value + integer :: i !array index + integer :: m !do loop index + integer :: k !do loop index + logical ::exclude !true if data value has already been chosen !----------------------------------------------------------------------- delmax = 1.e-06 @@ -246,6 +251,74 @@ subroutine mkrank (n, a, miss, num, iv) end do end do - end subroutine mkrank + end subroutine mkrank_r8 + + !=============================================================== + subroutine mkrank_r4 (n, a, miss, num, iv) + ! + ! Return indices of largest [num] values in array [a]. + ! + ! input/output variables + integer , intent(in) :: n !array length + real(r4), intent(in) :: a(0:n) !array to be ranked + integer , intent(in) :: miss !missing data value + integer , intent(in) :: num !number of largest values requested + integer , intent(out):: iv(num) !index to [num] largest values in array [a] + + ! local variables: + real(r4) :: a_max !maximum value in array + real(r4) :: delmax !tolerance for finding if larger value + integer :: i !array index + integer :: m !do loop index + integer :: k !do loop index + logical ::exclude !true if data value has already been chosen + !----------------------------------------------------------------------- + + delmax = 1.e-06 + + ! Find index of largest non-zero number + + iv(1) = miss + a_max = -9999. + + do i = 0, n + if (a(i)>0. .and. (a(i)-a_max)>delmax) then + a_max = a(i) + iv(1) = i + end if + end do + + ! iv(1) = miss indicates no values > 0. this is an error + + if (iv(1) == miss) then + write (6,*) 'MKRANK error: iv(1) = missing' + call shr_sys_abort() + end if + + ! Find indices of the next [num]-1 largest non-zero number. + ! iv(m) = miss if there are no more values > 0 + + do m = 2, num + iv(m) = miss + a_max = -9999. + do i = 0, n + ! exclude if data value has already been chosen + exclude = .false. + do k = 1, m-1 + if (i == iv(k)) exclude = .true. + end do + + ! if not already chosen, see if it is the largest of + ! the remaining values + if (.not. exclude) then + if (a(i)>0. .and. (a(i)-a_max)>delmax) then + a_max = a(i) + iv(m) = i + end if + end if + end do + end do + + end subroutine mkrank_r4 end module mkutilsMod diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index ace024f4c6..38599e0aeb 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -37,6 +37,8 @@ module mkvarctl public :: MPI_LOGICAL public :: MPI_CHARACTER public :: MPI_COMM_WORLD + public :: MPI_MAX + public :: MPI_SUCCESS real(r8), public, parameter :: spval = 1.e36 ! special value integer, public, parameter :: ispval = -9999 ! special value From 6ba56596ec7f1dd0610faa4124c42d9e3a820262 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 27 Jan 2022 22:31:16 -0700 Subject: [PATCH 030/614] added new methods for regridding and routehandle generation --- .../gen_mksurfdata_namelist.xml | 6 +- tools/mksurfdata_esmf/src/mkesmfMod.F90 | 185 +++++++++++++++--- tools/mksurfdata_esmf/src/mkfileMod.F90 | 52 ++++- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 75 +++---- tools/mksurfdata_esmf/src/mkorganicMod.F90 | 52 ++--- tools/mksurfdata_esmf/src/mkpioMod.F90 | 106 +++++----- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 75 +++---- tools/mksurfdata_esmf/src/mksurfdata.F90 | 10 +- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 181 ++++++++--------- tools/mksurfdata_esmf/src/mkutilsMod.F90 | 2 +- 10 files changed, 409 insertions(+), 335 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 2690ec8759..c15242deda 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -97,12 +97,12 @@ - lnd/clm2/rawdata/mksrf_urban_0.05x0.05_simyr2000.c220125.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + lnd/clm2/rawdata/mksrf_urban_0.05x0.05_simyr2000.c220127.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc lnd/clm2/rawdata/mksrf_urban_0.05x0.05_zerourbanpct.c181014.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc diff --git a/tools/mksurfdata_esmf/src/mkesmfMod.F90 b/tools/mksurfdata_esmf/src/mkesmfMod.F90 index 23a2ee41d3..cc7d14c90f 100644 --- a/tools/mksurfdata_esmf/src/mkesmfMod.F90 +++ b/tools/mksurfdata_esmf/src/mkesmfMod.F90 @@ -9,6 +9,8 @@ module mkesmfMod private public :: regrid_rawdata + public :: create_routehandle_r4 + public :: create_routehandle_r8 interface regrid_rawdata module procedure regrid_rawdata1d_r4 @@ -24,134 +26,273 @@ module mkesmfMod contains !=============================================================== - subroutine regrid_rawdata1d_r4(field_i, field_o, routehandle, data_i, data_o, rc) + subroutine create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) ! input/output variables - type(ESMF_Field) , intent(in) :: field_i - type(ESMF_Field) , intent(inout) :: field_o + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o + type(ESMF_RouteHandle) , intent(inout) :: routehandle + integer , intent(out) :: rc + + ! local variables + integer :: srcMaskValue = -987987 ! spval for RH mask values + integer :: dstMaskValue = -987987 ! spval for RH mask values + integer :: srcTermProcessing_Value = 0 + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + character(len=*), parameter :: subname = 'create_routehandle_r8' + ! -------------------------------------------- + + rc = ESMF_SUCCESS + + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create route handle to map field_model to field_data + call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + !srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_DSTAREA, & + srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) + + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + end subroutine create_routehandle_r8 + + !=============================================================== + subroutine create_routehandle_r4(mesh_i, mesh_o, routehandle, rc) + + ! input/output variables + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o + type(ESMF_RouteHandle) , intent(inout) :: routehandle + integer , intent(out) :: rc + + ! local variables + integer :: srcMaskValue = -987987 ! spval for RH mask values + integer :: dstMaskValue = -987987 ! spval for RH mask values + integer :: srcTermProcessing_Value = 0 + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + character(len=*), parameter :: subname = 'create_routehandle_r4' + ! -------------------------------------------- + + rc = ESMF_SUCCESS + + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create route handle to map field_model to field_data + call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + !srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_DSTAREA, & + srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) + + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + end subroutine create_routehandle_r4 + + !=============================================================== + subroutine regrid_rawdata1d_r4(mesh_i, mesh_o, routehandle, data_i, data_o, rc) + + ! input/output variables + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o type(ESMF_RouteHandle) , intent(inout) :: routehandle real(r4) , intent(in) :: data_i(:) real(r4) , intent(inout) :: data_o(:) integer , intent(out) :: rc ! local variables - logical :: checkflag = .false. + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o real(r4), pointer :: dataptr(:) + logical :: checkflag = .false. + character(len=*), parameter :: subname = 'regrid_rawdata1d_r4' ! -------------------------------------------- rc = ESMF_SUCCESS + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Interpolate data_i to data_o call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) dataptr(:) = data_i(:) call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:) = 0._r8 call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, & termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return data_o(:) = dataptr(:) - call ESMF_VMLogMemInfo("After field regrid in regrid_data") + + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() end subroutine regrid_rawdata1d_r4 !=============================================================== - subroutine regrid_rawdata1d_r8(field_i, field_o, routehandle, data_i, data_o, rc) + subroutine regrid_rawdata1d_r8(mesh_i, mesh_o, routehandle, data_i, data_o, rc) ! input/output variables - type(ESMF_Field) , intent(in) :: field_i - type(ESMF_Field) , intent(inout) :: field_o + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o type(ESMF_RouteHandle) , intent(inout) :: routehandle real(r8) , intent(in) :: data_i(:) real(r8) , intent(inout) :: data_o(:) integer , intent(out) :: rc ! local variables - logical :: checkflag = .false. + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o real(r8), pointer :: dataptr(:) + logical :: checkflag = .false. + character(len=*), parameter :: subname = 'regrid_rawdata1d_r8' ! -------------------------------------------- rc = ESMF_SUCCESS + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Interpolate data_i to data_o call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:) = data_i(:) call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:) = 0._r8 call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, & termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return data_o(:) = dataptr(:) - call ESMF_VMLogMemInfo("After field regrid in regrid_data") + + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() end subroutine regrid_rawdata1d_r8 !=============================================================== - subroutine regrid_rawdata2d_r4(field_i, field_o, routehandle, data_i, data_o, rc) + subroutine regrid_rawdata2d_r4(mesh_i, mesh_o, routehandle, data_i, data_o, lbound, ubound, rc) ! input/output variables - type(ESMF_Field) , intent(in) :: field_i - type(ESMF_Field) , intent(inout) :: field_o + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o type(ESMF_RouteHandle) , intent(inout) :: routehandle + integer , intent(in) :: lbound + integer , intent(in) :: ubound real(r4) , intent(in) :: data_i(:,:) real(r4) , intent(inout) :: data_o(:,:) integer , intent(out) :: rc ! local variables + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o logical :: checkflag = .false. - integer :: n,l real(r4), pointer :: dataptr(:,:) ! -------------------------------------------- rc = ESMF_SUCCESS + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/lbound/), ungriddedUbound=(/ubound/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/lbound/), ungriddedUbound=(/ubound/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Interpolate data_i to data_o - call ESMF_VMLogMemInfo("Before field regrid in regrid_rawdata2d") call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:,:) = data_i(:,:) call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:,:) = 0._r8 call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, & termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return data_o(:,:) = dataptr(:,:) - call ESMF_VMLogMemInfo("After field regrid in regrid_rawdata2d") + + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() end subroutine regrid_rawdata2d_r4 !=============================================================== - subroutine regrid_rawdata2d_r8(field_i, field_o, routehandle, data_i, data_o, rc) + subroutine regrid_rawdata2d_r8(mesh_i, mesh_o, routehandle, data_i, data_o, lbound, ubound, rc) ! input/output variables - type(ESMF_Field) , intent(in) :: field_i - type(ESMF_Field) , intent(inout) :: field_o + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o type(ESMF_RouteHandle) , intent(inout) :: routehandle + integer , intent(in) :: lbound + integer , intent(in) :: ubound real(r8) , intent(in) :: data_i(:,:) real(r8) , intent(inout) :: data_o(:,:) integer , intent(out) :: rc ! local variables + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o logical :: checkflag = .false. - integer :: n,l real(r8), pointer :: dataptr(:,:) ! -------------------------------------------- rc = ESMF_SUCCESS + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/lbound/), ungriddedUbound=(/ubound/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/lbound/), ungriddedUbound=(/ubound/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Interpolate data_i to data_o - call ESMF_VMLogMemInfo("Before field regrid in regrid_rawdata2d") call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:,:) = data_i(:,:) call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:,:) = 0._r8 + call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, & termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return data_o(:,:) = dataptr(:,:) - call ESMF_VMLogMemInfo("After field regrid in regrid_rawdata2d") end subroutine regrid_rawdata2d_r8 diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index ef9d45f097..8a749bfa45 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -22,6 +22,7 @@ module mkfileMod interface mkfile_output module procedure mkfile_output_int1d + module procedure mkfile_output_int2d module procedure mkfile_output_real1d module procedure mkfile_output_real2d end interface mkfile_output @@ -125,16 +126,24 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & call mkfile_output(pioid, define_mode, mesh_o, 'SOIL_COLOR', 'soil color', & 'unitless', soil_color, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - write(6,*)'wrote out soil_color' ! call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_URBAN', 'percent urban for each density type', & ! 'unitless', urban_classes, lev1name='numurbl', rc=rc) ! if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! call mkfile_output(pioid, define_mode, mesh_o, PIO_INT, 'URBAN_REGION_ID', 'urban region ID', & + ! call mkfile_output(pioid, define_mode, mesh_o, 'URBAN_REGION_ID', 'urban region ID', & ! 'unitless', urban_region, rc=rc) ! if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! ---------------------------------------------------------------------- + ! Make Urban Parameters from raw input data and write to surface dataset + ! Write to netcdf file is done inside mkurbanpar routine + ! ---------------------------------------------------------------------- + + ! call mkurbanpar(datfname=mksrf_furban, ncido=ncid, region_o=urban_region, & + ! urbn_classes_gcell_o=urbn_classes_g, & + ! urban_skip_abort_on_invalid_data_check=urban_skip_abort_on_invalid_data_check) + end if end do @@ -363,23 +372,48 @@ subroutine mkfile_output_int1d(pioid, define_mode, mesh, varname, longname, unit rc = ESMF_SUCCESS if (define_mode) then - write(6,*)'DEBUG: here1' call mkpio_def_spatial_var(pioid, trim(varname), PIO_INT, trim(longname), trim(units)) - write(6,*)'DEBUG: here2' else - write(6,*)'DEBUG: here3' call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - write(6,*)'DEBUG: here4' rcode = pio_inq_varid(pioid, trim(varname), pio_varid) - write(6,*)'DEBUG: here5' call pio_write_darray(pioid, pio_varid, pio_iodesc, ipointer, rcode) - write(6,*)'DEBUG: here6' call pio_freedecomp(pioid, pio_iodesc) - write(6,*)'DEBUG: here7' end if end subroutine mkfile_output_int1d + !================================================================================= + subroutine mkfile_output_int2d(pioid, define_mode, mesh, varname, longname, units, ipointer, rc) + + ! input/output variables + type(file_desc_t) , intent(inout) :: pioid + logical , intent(in) :: define_mode + type(ESMF_Mesh) , intent(in) :: mesh + character(len=*) , intent(in) :: varname + character(len=*) , intent(in) :: longname + character(len=*) , intent(in) :: units + integer , pointer :: ipointer(:,:) + integer , intent(out) :: rc + + ! local variables + type(io_desc_t) :: pio_iodesc + type(var_desc_t) :: pio_varid + integer :: rcode + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (define_mode) then + call mkpio_def_spatial_var(pioid, trim(varname), PIO_INT, trim(longname), trim(units)) + else + call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + call pio_write_darray(pioid, pio_varid, pio_iodesc, ipointer, rcode) + call pio_freedecomp(pioid, pio_iodesc) + end if + end subroutine mkfile_output_int2d + !================================================================================= subroutine mkfile_output_real1d(pioid, define_mode, mesh, xtype, varname, longname, units, rpointer, rc) diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 4d98f8f4ae..59a3c964d8 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -11,7 +11,7 @@ module mklanwatMod use shr_sys_mod , only : shr_sys_abort use mkvarpar , only : re use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag @@ -53,8 +53,6 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & ! local variables type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i - type(ESMF_Field) :: field_i - type(ESMF_Field) :: field_o type(file_desc_t) :: pioid real(r8), allocatable :: lake_i(:) ! input grid: percent lake real(r8), allocatable :: swmp_i(:) ! input grid: percent wetland @@ -62,9 +60,6 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & integer :: ni,no,k ! indices integer :: ns_i,ns_o ! local sizes integer :: rcode ! error status - integer :: srcMaskValue = -987987 ! spval for RH mask values - integer :: dstMaskValue = -987987 ! spval for RH mask values - integer :: srcTermProcessing_Value = 0 real(r8), parameter :: min_valid_lakedepth = 0._r8 character(len=*), parameter :: subname = ' mklakwat ' !----------------------------------------------------------------------- @@ -78,41 +73,25 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & swmp_o(no) = 0. enddo - ! create field on model mesh - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! ---------------------------------------- - ! Create route handle for rawdata mesh to model mesh - ! ---------------------------------------- + ! Open raw data file + ! ASSUME for now that have only 1 input data file + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) - ! create field on input mesh (first read in input mesh) - call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + ! Read in input mesh mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - ! create route handle to map field_model to field_data - call ESMF_VMLogMemInfo("Before regridstore in "//trim(subname)) - call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & - srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_DSTAREA, & - srcTermProcessing=srcTermProcessing_Value, & - ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) + ! Create a route handle between the input and output mesh + call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - ! ---------------------------------------- - ! Open input data file - ! ---------------------------------------- - ! ASSUME for now that have only 1 input data file - call ESMF_VMLogMemInfo("Before pio_openfile in "//trim(subname)) - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) - call ESMF_VMLogMemInfo("After pio_openfile in "//trim(subname)) + ! Determine number of elements in input mesh + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) ! ---------------------------------------- ! Create %lake @@ -124,17 +103,16 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & write (ndiag,*) 'Attempting to make %lake .....' end if - ! Read in the input data + ! Read in lake_i allocate(lake_i(ns_i), stat=rcode) if (rcode/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid, 'PCT_LAKE', mesh_i, lake_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Regrid lake_i to lake_o - this also returns lake_i to be used in the global sums below - call ESMF_VMLogMemInfo("Before regrid_rawdata for PCT_LAKE") - call regrid_rawdata(field_i, field_o, routehandle, lake_i, lake_o, rc) + ! Regrid lake_i to lake_o + call regrid_rawdata(mesh_i, mesh_o, routehandle, lake_i, lake_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("Before regrid_rawdata for PCT_LAKE") + call ESMF_VMLogMemInfo("After regrid_rawdata for PCT_LAKE in "//trim(subname)) do no = 1,size(lake_o) if (lake_o(no) < 1.) lake_o(no) = 0. enddo @@ -156,15 +134,14 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & write (ndiag,*) 'Attempting to make %wetland .....' end if - ! read in rawdata + ! read in swmp_i allocate(swmp_i(ns_i), stat=rcode) if (rcode/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid, 'PCT_WETLAND', mesh_i, lake_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! regrid swmp_i to swmp_o - this also returns swmp_i to be used in the global sums below - call ESMF_VMLogMemInfo("Before regrid_data for wetland") - call regrid_rawdata(field_i, field_o, routehandle, swmp_i, swmp_o, rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle, swmp_i, swmp_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regrid_data for wetland") if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -180,25 +157,23 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & end if ! ---------------------------------------- - ! Create lake parameter (lakdepth) + ! Create lake parameter (lakedepth) ! ---------------------------------------- if (root_task) then write (ndiag,*) 'Attempting to make lake parameters.....' end if - ! read in rawdata + ! lakedepth allocate(lakedepth_i(ns_i), stat=rcode) if (rcode/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid, 'LAKEDEPTH', mesh_i, lakedepth_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! regrid lakedepth_i to lakedepth_o - this also returns lakedepth_i to be used in the global sums below - call ESMF_VMLogMemInfo("Before regrid_data for lakedepth") - call regrid_rawdata(field_i, field_o, routehandle, lakedepth_i, lakedepth_o, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regrid_data for lakedepth") + call regrid_rawdata(mesh_i, mesh_o, routehandle, lakedepth_i, lakedepth_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regrid_rawdata for lakedepth in "//trim(subname)) ! Check validity of output data if (min_bad(lakedepth_o, min_valid_lakedepth, 'lakedepth')) then @@ -219,7 +194,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & call ESMF_VMLogMemInfo("Before destroy operation for lanwat ") call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_VMLogMemInfo("After destroy operation for lanwat ") diff --git a/tools/mksurfdata_esmf/src/mkorganicMod.F90 b/tools/mksurfdata_esmf/src/mkorganicMod.F90 index cb52f1708a..902fcb1b03 100644 --- a/tools/mksurfdata_esmf/src/mkorganicMod.F90 +++ b/tools/mksurfdata_esmf/src/mkorganicMod.F90 @@ -8,7 +8,7 @@ module mkorganicMod use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag use mkvarpar , only : nlevsoi @@ -37,21 +37,14 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) ! local variables type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i - type(ESMF_Field) :: field_i - type(ESMF_Field) :: field_o type(file_desc_t) :: pioid integer :: ni,no integer :: ns_i, ns_o integer :: nlay integer :: n, l ! indices integer :: rcode, ier ! error status - integer :: srcMaskValue = -987987 ! spval for RH mask values - integer :: dstMaskValue = -987987 ! spval for RH mask values - integer :: srcTermProcessing_Value = 0 integer :: ndims integer , allocatable :: dimlengths(:) - real(r4), allocatable :: data_real(:,:) - real(r8), allocatable :: data_double(:,:) real(r8), allocatable :: data_i(:,:) real(r8), allocatable :: data_o(:,:) real(r8), allocatable :: frac_i(:) @@ -65,7 +58,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) write (ndiag,'(a)') ' Attempting to make organic mater dataset .....' end if - ! Open raw data file - need to do this first to obtain ungridded dimension size + ! Open input data file - need to do this first to obtain ungridded dimension size call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) @@ -87,6 +80,11 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Create a route handle between the input and output mesh + call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) ! Determine ns_i and allocate data_i call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) @@ -108,30 +106,10 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - ! Create field on input mesh - using dimension information from raw data file - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/nlay/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After field_i creation in "//trim(subname)) - - ! Create field on model model - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/nlay/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After field_o creation in "//trim(subname)) - - ! Create route handle to map field_model to field_data - call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & - !srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_FRACAREA, & - srcTermProcessing=srcTermProcessing_Value, & - ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - ! Regrid data_i to data_o and frac_i to frac_o - call regrid_rawdata(field_i, field_o, routehandle, data_i, data_o, rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 1, nlay, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regrid organic_i in "//trim(subname)) do l = 1,nlevsoi do n = 1,size(organic_o, dim=1) @@ -144,17 +122,9 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) allocate(frac_o(ns_o)) call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(field_i, field_o, routehandle, frac_i, frac_o, rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle, frac_i, frac_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regrid_data in data_i "//trim(subname)) + call ESMF_VMLogMemInfo("After regrid landmask in "//trim(subname)) ! Divide organic_o by frac_o do n = 1,ns_o diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 6a8c22b43c..608ab661c0 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -70,7 +70,7 @@ subroutine mkpio_get_rawdata1d_int(pioid, varname, mesh_i, data_i, rc) integer :: lsize integer :: rcode integer :: n - character(len=*), parameter :: subname = 'mkpio_get_rawdata1d' + character(len=*), parameter :: subname = 'mkpio_get_rawdata1d_int' !------------------------------------------------- rc = ESMF_SUCCESS @@ -83,25 +83,31 @@ subroutine mkpio_get_rawdata1d_int(pioid, varname, mesh_i, data_i, rc) ! create iodesc for either single or multi level input data call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_iodesc for "//trim(varname)//" in "//trim(subname)) ! Read the input raw data - call ESMF_VMLogMemInfo("After mkpio_iodesc for varname "//trim(varname)) - call pio_read_darray(pioid, pio_varid, pio_iodesc, data_i, rcode) - call ESMF_VMLogMemInfo("After call to pio_read_darrayy for varname "//trim(varname)) + if (pio_vartype == PIO_INT) then + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_i, rcode) + call ESMF_VMLogMemInfo("After pio_read_darray for "//trim(varname)//" in "//trim(subname)) + else + call shr_sys_abort(subName//"ERROR: only int, real and double types are supported in "//trim(subname)) + end if + + ! Free the memory of the io descriptor + call pio_freedecomp(pioid, pio_iodesc) call ESMF_VMLogMemInfo("After call to pio_freedecomp for "//trim(varname)) - call ESMF_LogWrite("At end of "//trim(subname), ESMF_LOGMSG_INFO) end subroutine mkpio_get_rawdata1d_int !=============================================================== - subroutine mkpio_get_rawdata1d_real8(pioid, varname, mesh_i, data_i, rc) + subroutine mkpio_get_rawdata1d_real4(pioid, varname, mesh_i, data_i, rc) ! input/output variables type(file_desc_t), intent(inout) :: pioid character(len=*) , intent(in) :: varname ! field name in rawdata file type(ESMF_Mesh) , intent(in) :: mesh_i - real(r8) , intent(inout) :: data_i(:) ! input raw data + real(r4) , intent(inout) :: data_i(:) ! input raw data integer , intent(out) :: rc ! local variables @@ -109,13 +115,14 @@ subroutine mkpio_get_rawdata1d_real8(pioid, varname, mesh_i, data_i, rc) integer :: pio_vartype type(io_desc_t) :: pio_iodesc type(io_desc_t) :: pio_iodesc_mask + integer , allocatable :: data_int(:) real(r4), allocatable :: data_real(:) real(r8), allocatable :: data_double(:) real(r4), allocatable :: landmask(:) integer :: lsize integer :: rcode integer :: n - character(len=*), parameter :: subname = 'mkpio_get_rawdata1d' + character(len=*), parameter :: subname = 'mkpio_get_rawdata1d_real4' !------------------------------------------------- rc = ESMF_SUCCESS @@ -128,40 +135,39 @@ subroutine mkpio_get_rawdata1d_real8(pioid, varname, mesh_i, data_i, rc) ! create iodesc for either single or multi level input data call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_iodesc for varname "//trim(varname)) ! Read the input raw data - call ESMF_VMLogMemInfo("After mkpio_iodesc for varname "//trim(varname)) - if (pio_vartype == PIO_REAL) then - allocate(data_real(lsize)) - call ESMF_VMLogMemInfo("Calling pio_read_darray for varname "//trim(varname)) - call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real, rcode) - call ESMF_VMLogMemInfo("Finished pio_read_darray for varname "//trim(varname)) - data_i(:) = real(data_real(:), kind=r8) - call ESMF_LogWrite("Finished transfer to data_i for varname "//trim(varname)) - deallocate(data_real) - call ESMF_LogWrite("Finished deallocate of data_real for varname "//trim(varname)) + if (pio_vartype == PIO_INT) then + allocate(data_int(lsize)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_int, rcode) + data_i(:) = real(data_int(:), kind=r4) + deallocate(data_int) + else if (pio_vartype == PIO_REAL) then + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_i, rcode) else if (pio_vartype == PIO_DOUBLE) then allocate(data_double(lsize)) call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double, rcode) - data_i(:) = data_double(:) + data_i(:) = real(data_double(:), kind=r4) deallocate(data_double) else - call shr_sys_abort(subName//"ERROR: only real and double types are supported") + call shr_sys_abort(subName//"ERROR: only int, real and double types are supported") end if - call ESMF_VMLogMemInfo("After call to pio_read_darrayy for varname "//trim(varname)) + call ESMF_VMLogMemInfo("After call to pio_read_darray for varname "//trim(varname)) + call pio_freedecomp(pioid, pio_iodesc) call ESMF_VMLogMemInfo("After call to pio_freedecomp for "//trim(varname)) - end subroutine mkpio_get_rawdata1d_real8 + end subroutine mkpio_get_rawdata1d_real4 !=============================================================== - subroutine mkpio_get_rawdata1d_real4(pioid, varname, mesh_i, data_i, rc) + subroutine mkpio_get_rawdata1d_real8(pioid, varname, mesh_i, data_i, rc) ! input/output variables type(file_desc_t), intent(inout) :: pioid character(len=*) , intent(in) :: varname ! field name in rawdata file type(ESMF_Mesh) , intent(in) :: mesh_i - real(r4) , intent(inout) :: data_i(:) ! input raw data + real(r8) , intent(inout) :: data_i(:) ! input raw data integer , intent(out) :: rc ! local variables @@ -169,13 +175,13 @@ subroutine mkpio_get_rawdata1d_real4(pioid, varname, mesh_i, data_i, rc) integer :: pio_vartype type(io_desc_t) :: pio_iodesc type(io_desc_t) :: pio_iodesc_mask + integer , allocatable :: data_int(:) real(r4), allocatable :: data_real(:) real(r8), allocatable :: data_double(:) - real(r4), allocatable :: landmask(:) integer :: lsize integer :: rcode integer :: n - character(len=*), parameter :: subname = 'mkpio_get_rawdata1d' + character(len=*), parameter :: subname = 'mkpio_get_rawdata1d_real8' !------------------------------------------------- rc = ESMF_SUCCESS @@ -191,44 +197,42 @@ subroutine mkpio_get_rawdata1d_real4(pioid, varname, mesh_i, data_i, rc) ! Read the input raw data call ESMF_VMLogMemInfo("After mkpio_iodesc for varname "//trim(varname)) - if (pio_vartype == PIO_REAL) then + if (pio_vartype == PIO_INT) then + allocate(data_int(lsize)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_int, rcode) + data_i(:) = real(data_int(:), kind=r8) + deallocate(data_int) + else if (pio_vartype == PIO_REAL) then allocate(data_real(lsize)) - call ESMF_VMLogMemInfo("Calling pio_read_darray for varname "//trim(varname)) call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real, rcode) - call ESMF_VMLogMemInfo("Finished pio_read_darray for varname "//trim(varname)) - data_i(:) = data_real(:) - call ESMF_LogWrite("Finished transfer to data_i for varname "//trim(varname)) + data_i(:) = real(data_real(:), kind=r8) deallocate(data_real) - call ESMF_LogWrite("Finished deallocate of data_real for varname "//trim(varname)) else if (pio_vartype == PIO_DOUBLE) then - allocate(data_double(lsize)) - call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double, rcode) - data_i(:) = real(data_double(:), kind=r4) - deallocate(data_double) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_i, rcode) else - call shr_sys_abort(subName//"ERROR: only real and double types are supported") + call shr_sys_abort(subName//"ERROR: only int, real and double types are supported") end if call ESMF_VMLogMemInfo("After call to pio_read_darrayy for varname "//trim(varname)) + call pio_freedecomp(pioid, pio_iodesc) call ESMF_VMLogMemInfo("After call to pio_freedecomp for "//trim(varname)) - end subroutine mkpio_get_rawdata1d_real4 + end subroutine mkpio_get_rawdata1d_real8 !=============================================================== - subroutine mkpio_get_rawdata2d_real8(pioid, varname, mesh_i, data_i, rc) + subroutine mkpio_get_rawdata2d_real4(pioid, varname, mesh_i, data_i, rc) ! input/output variables type(file_desc_t) , intent(inout) :: pioid character(len=*) , intent(in) :: varname ! field name in rawdata file type(ESMF_Mesh) , intent(in) :: mesh_i - real(r8) , intent(inout) :: data_i(:,:) ! input raw data + real(r4) , intent(inout) :: data_i(:,:) ! input raw data integer , intent(out) :: rc ! local variables type(var_desc_t) :: pio_varid integer :: pio_vartype type(io_desc_t) :: pio_iodesc - type(io_desc_t) :: pio_iodesc_mask real(r4), allocatable :: data_real1d(:) real(r4), allocatable :: data_real2d(:,:) real(r8), allocatable :: data_double1d(:) @@ -264,7 +268,7 @@ subroutine mkpio_get_rawdata2d_real8(pioid, varname, mesh_i, data_i, rc) call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real2d, rcode) do l = 1,nlev do n = 1,lsize - data_i(l,n) = real(data_real2d(n,l), kind=r8) + data_i(l,n) = data_real2d(n,l) end do end do deallocate(data_real2d) @@ -273,7 +277,7 @@ subroutine mkpio_get_rawdata2d_real8(pioid, varname, mesh_i, data_i, rc) call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double2d, rcode) do l = 1,nlev do n = 1,lsize - data_i(l,n) = data_double2d(n,l) + data_i(l,n) = real(data_double2d(n,l), kind=r4) end do end do deallocate(data_double2d) @@ -282,22 +286,23 @@ subroutine mkpio_get_rawdata2d_real8(pioid, varname, mesh_i, data_i, rc) end if call pio_freedecomp(pioid, pio_iodesc) - end subroutine mkpio_get_rawdata2d_real8 + end subroutine mkpio_get_rawdata2d_real4 !=============================================================== - subroutine mkpio_get_rawdata2d_real4(pioid, varname, mesh_i, data_i, rc) + subroutine mkpio_get_rawdata2d_real8(pioid, varname, mesh_i, data_i, rc) ! input/output variables type(file_desc_t) , intent(inout) :: pioid character(len=*) , intent(in) :: varname ! field name in rawdata file type(ESMF_Mesh) , intent(in) :: mesh_i - real(r4) , intent(inout) :: data_i(:,:) ! input raw data + real(r8) , intent(inout) :: data_i(:,:) ! input raw data integer , intent(out) :: rc ! local variables type(var_desc_t) :: pio_varid integer :: pio_vartype type(io_desc_t) :: pio_iodesc + type(io_desc_t) :: pio_iodesc_mask real(r4), allocatable :: data_real1d(:) real(r4), allocatable :: data_real2d(:,:) real(r8), allocatable :: data_double1d(:) @@ -333,7 +338,7 @@ subroutine mkpio_get_rawdata2d_real4(pioid, varname, mesh_i, data_i, rc) call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real2d, rcode) do l = 1,nlev do n = 1,lsize - data_i(l,n) = data_real2d(n,l) + data_i(l,n) = real(data_real2d(n,l), kind=r8) end do end do deallocate(data_real2d) @@ -342,7 +347,7 @@ subroutine mkpio_get_rawdata2d_real4(pioid, varname, mesh_i, data_i, rc) call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double2d, rcode) do l = 1,nlev do n = 1,lsize - data_i(l,n) = real(data_double2d(n,l), kind=r4) + data_i(l,n) = data_double2d(n,l) end do end do deallocate(data_double2d) @@ -351,7 +356,7 @@ subroutine mkpio_get_rawdata2d_real4(pioid, varname, mesh_i, data_i, rc) end if call pio_freedecomp(pioid, pio_iodesc) - end subroutine mkpio_get_rawdata2d_real4 + end subroutine mkpio_get_rawdata2d_real8 !=============================================================== subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, pio_iodesc, rc) @@ -685,14 +690,11 @@ subroutine mkpio_wopen(filename, clobber, pioid) endif else ! only applies to classic NETCDF files. - write(6,*)'DEBUG: here1' nmode = pio_noclobber if (pio_iotype == PIO_IOTYPE_NETCDF .or. pio_iotype == PIO_IOTYPE_PNETCDF) then nmode = ior(nmode,pio_ioformat) endif - write(6,*)'DEBUG: here2' rcode = pio_createfile(pio_iosystem, pioid, pio_iotype, trim(filename), nmode) - write(6,*)'DEBUG: here3' if (root_task) write(ndiag,'(a)') trim(subname) //' creating file '// trim(filename) endif call ESMF_LogWrite("successfully opened output file "//trim(filename), ESMF_LOGMSG_INFO) diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index 47c54efb76..6c60cc8b13 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -6,7 +6,7 @@ module mksoilcolMod use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr, mkrank use mkvarctl , only : root_task, ndiag, mpicom, MPI_INTEGER, MPI_MAX @@ -32,29 +32,24 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o integer , pointer :: soil_color_o(:) ! soil color classes - integer , intent(out) :: nsoilcol ! number of soil colors + integer , intent(out) :: nsoilcol ! number of soil colors integer , intent(out) :: rc ! local variables: type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i - type(ESMF_Field) :: field_i - type(ESMF_Field) :: field_o type(file_desc_t) :: pioid integer :: ni,no integer :: ns_i, ns_o integer :: n,l - integer :: rcode, ier ! error status - integer :: srcMaskValue = -987987 ! spval for RH mask values - integer :: dstMaskValue = -987987 ! spval for RH mask values - integer :: srcTermProcessing_Value = 0 - real(r4), allocatable :: soilcol_i(:) - real(r4), allocatable :: data_i(:,:) - real(r4), allocatable :: data_o(:,:) - real(r4), allocatable :: mask_i(:) + real(r8), allocatable :: soilcol_i(:) + real(r8), allocatable :: data_i(:,:) + real(r8), allocatable :: data_o(:,:) + real(r8), allocatable :: mask_i(:) logical :: has_color ! whether this grid cell has non-zero color integer :: nsoilcol_local integer :: maxindex(1) + integer :: rcode, ier character(len=*), parameter :: subname = 'mksoilcol' !----------------------------------------------------------------------- @@ -77,15 +72,21 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r write (ndiag,'(a)') 'Attempting to make soil color classes .....' end if - ! Open raw data file - need to do this first to obtain ungridded dimension size + ! Open soil color data file call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) - ! Determine ns_i and allocate data_i + ! Read in input mesh call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Create a route handle between the input and output mesh + call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + + ! Determine ns_i and allocate data_i call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return allocate(soilcol_i(ns_i),stat=ier) @@ -95,7 +96,7 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r call mkpio_get_rawdata(pioid, 'SOIL_COLOR', mesh_i, soilcol_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - + ! Determine maximum number of soil colors across all processors ! This will be used for the ungridded dimension of data_o below nsoilcol_local = maxval(soilcol_i) @@ -113,46 +114,22 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, mask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Now determine data_i as a real 2d array + ! Now determine data_i as a real 2d array - for every possible soil color create a global + ! field with gridcells equal to 1 for that soil color and zero elsewhere allocate(data_i(0:nsoilcol,ns_i)) data_i(:,:) = 0._r4 do l = 1,nsoilcol do n = 1,ns_i if (int(soilcol_i(n)) == l) then - data_i(l,n) = 1._r4 * mask_i(n) + data_i(l,n) = 1._r4 * mask_i(n) end if end do end do - ! Create field on input mesh - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/0/), ungriddedUbound=(/nsoilcol/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After field_i creation in "//trim(subname)) - - ! Create field on model model - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/0/), ungriddedUbound=(/nsoilcol/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After field_o creation in "//trim(subname)) - - ! Create route handle to map field_model to field_data - call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & - srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_FRACAREA, & - srcTermProcessing=srcTermProcessing_Value, & - ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - ! Regrid data_i to data_o - call regrid_rawdata(field_i, field_o, routehandle, data_i, data_o, rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, nsoilcol, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call ESMF_LogWrite(subname//'after regrid rawdata') - - ! Determine dominant soil color in each output grid cell - !call dominant_soil_color(data_o, nsoilcol, soil_color_o) + call ESMF_LogWrite(subname//'after regrid rawdata in '//trim(subname)) soil_color_o(:) = 0 do no = 1,ns_o @@ -165,10 +142,8 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r has_color = .false. end if - ! Rank non-zero weights by color type. wsti(1) is the most extensive color type. + ! Rank non-zero weights by color type. wsti(1) is the most extensive color type. if (has_color) then - !maxindex = maxloc(data_o(0:nsoilcol,no)) - !soil_color_o(no) = maxindex call mkrank (nsoilcol, data_o(0:nsoilcol,no), 9999, 1, maxindex) soil_color_o(no) = maxindex(1) end if @@ -205,12 +180,10 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r deallocate(data_o) deallocate(soilcol_i) deallocate(mask_i) - call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_LogWrite(subname//' finished routine mksoilcol') diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 2451957378..511a7d7f68 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -410,6 +410,11 @@ program mksurfdata ! call mkharvest( mapfname=map_fharvest, datfname=mksrf_fhrvtyp, ndiag=ndiag, harvdata=harvdata ) ! end if + ! Make urban fraction [pcturb] from [furban] dataset + ! call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, & + ! zero_out=all_veg, urbn_o=pcturb, urban_classes_o=urban_classes, region_o=urban_region, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') + ! Make soil color classes [soicol] [fsoicol] call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, soil_color, nsoilcol, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilcol') @@ -426,11 +431,6 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) - ! Make urban fraction [pcturb] from [furban] dataset - ! call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, & - ! zero_out=all_veg, urbn_o=pcturb, urban_classes_o=urban_classes, region_o=urban_region, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') - #ifdef TODO ! ! Make glacier fraction [pctgla] from [fglacier] dataset ! call mkglacier ( mapfname=map_fglacier, datfname=mksrf_fglacier, ndiag=ndiag, zero_out=all_urban.or.all_veg, glac_o=pctgla) diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 980911fb85..19dc3866f7 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -6,15 +6,16 @@ module mkurbanparMod use ESMF use pio - use shr_kind_mod , only : r8 => shr_kind_r8, cs => shr_kind_cs + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem use mkpioMod , only : mkpio_iodesc_output, mkpio_def_spatial_var, mkpio_wopen use mkpioMod , only : mkpio_get_dimlengths, mkpio_get_rawdata use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag, ispval, fsurdat, outnc_double + use mkvarctl , only : root_task, ndiag, mpicom, MPI_INTEGER, MPI_MAX implicit none private @@ -30,6 +31,7 @@ module mkurbanparMod ! public data members integer, public :: numurbl ! number of urban classes integer, public :: nlevurb = ispval ! number of urban layers + integer, public :: nregions ! private data members: ! flag to indicate nodata for index variables in output file: @@ -66,6 +68,8 @@ subroutine mkurbanInit(datfname) rcode = pio_inq_dimlen(pioid, dimid, numurbl) rcode = pio_inq_dimid(pioid, 'nlevurb', dimid) rcode = pio_inq_dimlen(pioid, dimid, dimid) + rcode = pio_inq_dimid(pioid, 'region', dimid) + rcode = pio_inq_dimlen(pioid, dimid, nregions) call pio_closefile(pioid) end subroutine mkurbanInit @@ -108,23 +112,21 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & #endif ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh - logical , intent(in) :: zero_out ! if should zero urban out - real(r8) , intent(out) :: urbn_o(:) ! output grid: total % urban - real(r8) , intent(out) :: urban_classes_o(:,:) ! output grid: breakdown of total urban into each class - integer , intent(inout) :: region_o(:) ! output grid: region ID - integer , intent(out) :: rc + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh + logical , intent(in) :: zero_out ! if should zero urban out + real(r8) , intent(out) :: urbn_o(:) ! output grid: total % urban + real(r8) , intent(out) :: urban_classes_o(:,:) ! output grid: breakdown of total urban into each class + integer , intent(inout) :: region_o(:) ! output grid: region ID + integer , intent(out) :: rc ! local variables: type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i - type(ESMF_Field) :: field_i - type(ESMF_Field) :: field_o type(file_desc_t) :: pioid - real(r8), allocatable :: urban_classes_gcell_i(:,:) ! input grid: percent urban in each density class (% of total grid cell area) - real(r8), allocatable :: urban_classes_gcell_o(:,:) ! output grid: percent urban in each density class (% of total grid cell area) + real(r8), allocatable :: urban_classes_gcell_i(:,:) ! % input urban in each density class (% of total grid cell area) + real(r8), allocatable :: urban_classes_gcell_o(:,:) ! % putput urban in each density class (% of total grid cell area) real(r8), allocatable :: data_i(:,:) real(r8), allocatable :: data_o(:,:) integer , allocatable :: region_i(:) ! input grid: region ID @@ -133,14 +135,13 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & integer :: ns_i, ns_o ! array sizes integer :: dimlen ! netCDF dimension length integer, allocatable :: dimlengths(:) - integer :: ndims integer :: max_region ! maximum region index + real(r4), allocatable :: frac_i(:) + real(r4), allocatable :: frac_o(:) + integer :: max_regions_local + integer :: max_regions + integer :: max_index(1) integer :: rcode, ier ! error status - integer :: srcMaskValue = -987987 ! spval for RH mask values - integer :: dstMaskValue = -987987 ! spval for RH mask values - integer :: srcTermProcessing_Value = 0 - real(r8), allocatable :: frac_i(:) - real(r8), allocatable :: frac_o(:) character(len=*), parameter :: subname = 'mkurban' !----------------------------------------------------------------------- @@ -159,14 +160,18 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh - call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Create a route handle between the input and output mesh + call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Determine ns_i and allocate urban_classes_gcell_i + ! Determine ns_i and allocate data_i call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) allocate(data_i(numurbl,ns_i),stat=ier) if (ier/=0) call shr_sys_abort() @@ -180,32 +185,10 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & ! - levels are the innermost dimension for esmf fields ! - levels are the outermost dimension in pio reads ! Input data is read into (ns_i,numurbl) array and then transferred to urban_classes_gcell_i(numurbl,ns_i) - if (ier/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid, 'PCT_URBAN', mesh_i, urban_classes_gcell_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - ! Create field on input mesh - using dimension information from raw data file - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/numurbl/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After field_i creation in "//trim(subname)) - - ! Create field on model model - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/numurbl/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After field_o creation in "//trim(subname)) - - ! Create route handle to map field_model to field_data - call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & - !srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_DSTAREA, & - srcTermProcessing=srcTermProcessing_Value, & - ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - ! Regrid raw data to model resolution ! make percent urban on output grid, given percent urban on input grid ! This assumes that we're neither using all_urban or zero_out @@ -213,9 +196,9 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & ! Area-average percent cover on input grid to output grid ! and correct according to land landmask ! Note that percent cover is in terms of total grid area. - call regrid_rawdata(field_i, field_o, routehandle, data_i, data_o, rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 1, numurbl, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regrid_data in "//trim(subname)) + call ESMF_VMLogMemInfo("After regrid_data for in "//trim(subname)) ! Now Determine total % urban call ESMF_LogWrite("Before allocate of urban_classes_gcell_o", ESMF_LOGMSG_INFO) @@ -233,17 +216,9 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & allocate(frac_o(ns_o)) call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle, frac_i, frac_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(field_i, field_o, routehandle, frac_i, frac_o, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regrid_data in data_i "//trim(subname)) + call ESMF_VMLogMemInfo("After regrid_data for landmask in "//trim(subname)) do n = 1,ns_o if (frac_o(n) > 0._r8) then @@ -258,6 +233,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & call ESMF_LogWrite("After loop", ESMF_LOGMSG_INFO) ! Check for conservation +#ifdef TODO do no = 1, ns_o if ((urbn_o(no)) > 100.000001_r8) then write (6,'(a,i8,a,i8)') 'MKURBAN error: percent urban = ',urbn_o(no), & @@ -266,6 +242,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & end if enddo !call shr_sys_abort() +#endif ! determine urban_classes_o call ESMF_LogWrite("Before normalize_urbn", ESMF_LOGMSG_INFO) @@ -290,14 +267,13 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & end do end if - ! Print diagnostics - ! First, recompute urban_classes_gcell_o, based on any changes we have made to urbn_o - ! while handling special cases - call ESMF_LogWrite("Before normalize_classes_by_gcell", ESMF_LOGMSG_INFO) - !call normalize_classes_by_gcell(urban_classes_o, urbn_o, urban_classes_gcell_o) - call ESMF_LogWrite("After normalize_classes_by_gcell", ESMF_LOGMSG_INFO) + deallocate(data_i) + deallocate(data_o) #ifdef TODO + ! Print diagnostics + ! First, recompute urban_classes_gcell_o, based on any changes we have made to urbn_o + call normalize_classes_by_gcell(urban_classes_o, urbn_o, urban_classes_gcell_o) do k = 1, numurbl call mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, & urban_classes_gcell_i(:,k), urban_classes_gcell_o(:,k), & @@ -309,49 +285,54 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & write (ndiag,'(a)') 'Attempting to make urban region .....' end if -#ifdef TODO + ! ------------------------------------------------------ ! Read in region field - ! Note: we do this here, rather than with the rest of the reads above, because we - ! expect the input urban fields to be large, so we're just reading the fields as - ! they're needed to try to avoid unnecessary memory paging - ! REGION_ID is (lsmlon,lsmlat) but integer - so use pio and create and iodesc to read this in - ! for the local grid points + ! ------------------------------------------------------ allocate(region_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() + call ESMF_LogWrite("Before mkpio_get_rawdata", ESMF_LOGMSG_INFO) call mkpio_get_rawdata(pioid, 'REGION_ID', mesh_i, region_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite("After mkpio_get_rawdata", ESMF_LOGMSG_INFO) - ! Determine max region value, and make sure it doesn't exceed bounds of the lookup tables. - ! - ! (Note: this check assumes that region_i=1 refers to region(1), region_i=2 refers to - ! region(2), etc. The alternative would be to use a coordinate variable associated with - ! the region dimension of the lookup table, which could result in an arbitrary mapping - ! between region values and the indices of the lookup table; however, this use of - ! coordinate variables currently isn't supported by lookup_2d_netcdf [as of 2-8-12].) - - call ESMF_LogWrite("Before allocate dimlengths", ESMF_LOGMSG_INFO) - allocate(dimlengths(2)) - call mkpio_get_dimlengths(pioid, trim('REGION_ID'), ndims, dimlengths) - max_region = maxval(region_i) - if (max_region > dimlengths(2)) then - write(6,*) modname//':'//subname// & - ' ERROR: max region value exceeds length of region dimension' - write(6,*) 'max region value : ', max_region - write(6,*) 'length of region dimension: ', dimlengths(2) - call shr_sys_abort() - end if - deallocate(dimlengths) - call ESMF_LogWrite("After allocate dimlengths", ESMF_LOGMSG_INFO) + max_regions = nregions + + ! Now determine data_i as a real 2d array + allocate(data_i(max_regions, ns_i), stat=ier) + if (ier/=0) call shr_sys_abort('error allocating data_i(max_regions, ns_i)') + allocate(data_o(max_regions, ns_o), stat=ier) + if (ier/=0) call shr_sys_abort('error allocating data_i(max_regions, ns_o)') + + data_i(:,:) = 0._r4 + do l = 1,max_regions + do n = 1,ns_i + if (region_i(n) == l) then + !data_i(l,n) = 1._r4 * mask_i(n) + data_i(l,n) = 1. ! DEBUG + end if + end do + end do - ! Determine dominant region for each output cell - call ESMF_LogWrite("Before get_dominant_indices", ESMF_LOGMSG_INFO) - call get_dominant_indices(factorindexlist, factorlist, & - src_array=region_i, dst_array=region_o, & - minval=1, maxval=max_region, nodata=index_nodata) - call ESMF_LogWrite("After get_dominant_indices", ESMF_LOGMSG_INFO) + ! Regrid data_i to data_o + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 1, nregions, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Now find dominant region in each output gridcell - this is identical to the maximum index + do n = 1,ns_o + max_index = maxloc(data_o(:,n)) + end do + ! do n = 1,ns_o + ! maxindex = 1 + ! maxval = data_o(1,n) + ! do l = 2, max_regions + ! if (data_o(l,n) > maxval) then + ! maxindex = l + ! maxval = data_o(l,n) + ! end if + ! end do + ! end do if (root_task) then write (ndiag,'(a)') 'Successfully made urban region' @@ -361,20 +342,18 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & ! Output diagnostics ! call output_diagnostics_index(factorlist, factorindex, region_i, region_o, 'Urban Region ID', & ! 1, max_region, ndiag) -#endif ! Close the file call pio_closefile(pioid) ! Deallocate dynamic memory & other clean up - deallocate (urban_classes_gcell_i, urban_classes_gcell_o, region_i) + ! TODO: determine what to deallocate + ! deallocate (urban_classes_gcell_i, urban_classes_gcell_o, region_i) call ESMF_VMLogMemInfo("Before destroy operation in "//trim(subname)) call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_VMLogMemInfo("after destroy operation in "//trim(subname)) diff --git a/tools/mksurfdata_esmf/src/mkutilsMod.F90 b/tools/mksurfdata_esmf/src/mkutilsMod.F90 index 5fe8fd068c..8c5cbf8c22 100644 --- a/tools/mksurfdata_esmf/src/mkutilsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkutilsMod.F90 @@ -61,7 +61,7 @@ subroutine normalize_classes_by_gcell(classes_pct_tot, sums, classes_pct_gcell) n_max = size(sums) if (size(classes_pct_tot, 1) /= n_max .or. & - size(classes_pct_gcell, 1) /= n_max) then + size(classes_pct_gcell, 1) /= n_max) then write(6,*) subname//' ERROR: array size mismatch' write(6,*) 'size(sums) = ', n_max write(6,*) 'size(classes_pct_tot, 1) = ', size(classes_pct_tot, 1) From 14dde4672bd95b9bbcc98bd871b2a2b26d52b437 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 28 Jan 2022 12:08:14 -0700 Subject: [PATCH 031/614] git region id working --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 36 +++--- tools/mksurfdata_esmf/src/mkpioMod.F90 | 6 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 18 +-- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 123 +++++++++----------- 4 files changed, 89 insertions(+), 94 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 8a749bfa45..0a58869a27 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -107,33 +107,40 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & if (.not. dynlanduse) then + if (root_task) write(ndiag, '(a)') trim(subname)//"writing out pct_lake" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_LAKE', 'percent_lake', & 'unitless', pctlak, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag, '(a)') trim(subname)//"writing out pct_wetland" call mkfile_output(pioid,define_mode, mesh_o, xtype, 'PCT_WETLAND', 'percent_wetland', & 'unitless', pctwet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag, '(a)') trim(subname)//"writing out lakedepth" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'LAKEDEPTH', 'lake_depth', & 'm', lakedepth, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag, '(a)') trim(subname)//"writing out organic" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'ORGANIC', 'organic matter density at soil levels', & 'kg/m3 (assumed carbon content 0.58 gC per gOM)', organic, lev1name='nlevsoi', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag, '(a)') trim(subname)//"writing out soil color" call mkfile_output(pioid, define_mode, mesh_o, 'SOIL_COLOR', 'soil color', & 'unitless', soil_color, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_URBAN', 'percent urban for each density type', & - ! 'unitless', urban_classes, lev1name='numurbl', rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag, '(a)') trim(subname)//"writing out urban region id" + call mkfile_output(pioid, define_mode, mesh_o, 'URBAN_REGION_ID', 'urban region ID', & + 'unitless', urban_region, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! call mkfile_output(pioid, define_mode, mesh_o, 'URBAN_REGION_ID', 'urban region ID', & - ! 'unitless', urban_region, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag, '(a)') trim(subname)//"writing out percnt urban" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_URBAN', 'percent urban for each density type', & + 'unitless', urban_classes, lev1name='numurbl', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! ---------------------------------------------------------------------- ! Make Urban Parameters from raw input data and write to surface dataset @@ -181,20 +188,19 @@ subroutine mkfile_define_dims(pioid, nx, ny, dynlanduse) rcode = pio_def_dim(pioid, 'lsmlon', nx, dimid) rcode = pio_def_dim(pioid, 'lsmlat', ny, dimid) end if - rcode = pio_def_dim(pioid, 'nlevsoi', nlevsoi, dimid) - rcode = pio_def_dim(pioid, 'time', PIO_UNLIMITED, dimid) + rcode = pio_def_dim(pioid, 'nlevsoi', nlevsoi , dimid) + rcode = pio_def_dim(pioid, 'nlevurb', nlevurb , dimid) + rcode = pio_def_dim(pioid, 'numurbl', numurbl , dimid) - if (.not. dynlanduse) then #ifdef TODO + rcode = pio_def_dim(pioid, 'time' , PIO_UNLIMITED , dimid) + rcode = pio_def_dim(pioid, 'nchar' , 256 , dimid) + rcode = pio_def_dim(pioid, 'numrad' , numrad , dimid) + if (.not. dynlanduse) then rcode = pio_def_dim(pioid, 'nglcec', nglcec, dimid) rcode = pio_def_dim(pioid, 'nglcecp1', nglcec+1, dimid) -#endif - else - rcode = pio_def_dim(pioid, 'numurbl', numurbl, dimid) - rcode = pio_def_dim(pioid, 'nlevurb', nlevurb, dimid) - rcode = pio_def_dim(pioid, 'numrad' , numrad, dimid) - rcode = pio_def_dim(pioid, 'nchar' , 256, dimid) end if +#endif end subroutine mkfile_define_dims diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 608ab661c0..b0eaca615c 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -116,9 +116,7 @@ subroutine mkpio_get_rawdata1d_real4(pioid, varname, mesh_i, data_i, rc) type(io_desc_t) :: pio_iodesc type(io_desc_t) :: pio_iodesc_mask integer , allocatable :: data_int(:) - real(r4), allocatable :: data_real(:) real(r8), allocatable :: data_double(:) - real(r4), allocatable :: landmask(:) integer :: lsize integer :: rcode integer :: n @@ -135,7 +133,7 @@ subroutine mkpio_get_rawdata1d_real4(pioid, varname, mesh_i, data_i, rc) ! create iodesc for either single or multi level input data call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After mkpio_iodesc for varname "//trim(varname)) + call ESMF_VMLogMemInfo("After mkpio_iodesc for varname "//trim(varname)//" in "//trim(subname)) ! Read the input raw data if (pio_vartype == PIO_INT) then @@ -196,7 +194,7 @@ subroutine mkpio_get_rawdata1d_real8(pioid, varname, mesh_i, data_i, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Read the input raw data - call ESMF_VMLogMemInfo("After mkpio_iodesc for varname "//trim(varname)) + call ESMF_VMLogMemInfo("After mkpio_iodesc for varname for "//trim(varname)//" in "//trim(subname)) if (pio_vartype == PIO_INT) then allocate(data_int(lsize)) call pio_read_darray(pioid, pio_varid, pio_iodesc, data_int, rcode) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 511a7d7f68..8b3c2551d9 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -411,9 +411,9 @@ program mksurfdata ! end if ! Make urban fraction [pcturb] from [furban] dataset - ! call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, & - ! zero_out=all_veg, urbn_o=pcturb, urban_classes_o=urban_classes, region_o=urban_region, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') + call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, & + zero_out=all_veg, urbn_o=pcturb, urban_classes_o=urban_classes, region_o=urban_region, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') ! Make soil color classes [soicol] [fsoicol] call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, soil_color, nsoilcol, rc) @@ -424,12 +424,12 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] - zero_out_lake = all_urban .or. all_veg - zero_out_wetland = all_urban .or. all_veg .or. no_inlandwet - call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & - zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') - call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) + ! zero_out_lake = all_urban .or. all_veg + ! zero_out_wetland = all_urban .or. all_veg .or. no_inlandwet + ! call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & + ! zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') + ! call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) #ifdef TODO ! ! Make glacier fraction [pctgla] from [fglacier] dataset diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 19dc3866f7..3829bf14cd 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -48,12 +48,12 @@ module mkurbanparMod contains !=============================================================== - subroutine mkurbanInit(datfname) + subroutine mkurbanInit(datafname) ! ! Initialize variables needed for urban ! ! input variables - character(len=*), intent(in) :: datfname ! input data file name (same as file used in mkurban) + character(len=*), intent(in) :: datafname ! input data file name (same as file used in mkurban) ! ! local variables: type(file_desc_t) :: pioid @@ -62,12 +62,15 @@ subroutine mkurbanInit(datfname) character(len=*), parameter :: subname = 'mkurbanInit' !----------------------------------------------------------------------- - ! Set numurbl and nlevurb - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(datfname), pio_nowrite) + ! Set numurbl, nlevurb and nregions + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(datafname), pio_nowrite) + rcode = pio_inq_dimid(pioid, 'density_class', dimid) rcode = pio_inq_dimlen(pioid, dimid, numurbl) + rcode = pio_inq_dimid(pioid, 'nlevurb', dimid) - rcode = pio_inq_dimlen(pioid, dimid, dimid) + rcode = pio_inq_dimlen(pioid, dimid, nlevurb) + rcode = pio_inq_dimid(pioid, 'region', dimid) rcode = pio_inq_dimlen(pioid, dimid, nregions) call pio_closefile(pioid) @@ -125,7 +128,6 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid - real(r8), allocatable :: urban_classes_gcell_i(:,:) ! % input urban in each density class (% of total grid cell area) real(r8), allocatable :: urban_classes_gcell_o(:,:) ! % putput urban in each density class (% of total grid cell area) real(r8), allocatable :: data_i(:,:) real(r8), allocatable :: data_o(:,:) @@ -136,8 +138,8 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & integer :: dimlen ! netCDF dimension length integer, allocatable :: dimlengths(:) integer :: max_region ! maximum region index - real(r4), allocatable :: frac_i(:) - real(r4), allocatable :: frac_o(:) + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) integer :: max_regions_local integer :: max_regions integer :: max_index(1) @@ -176,35 +178,28 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & if (ier/=0) call shr_sys_abort() ! Determine ns_o and allocate data_o - ns_o = size(urbn_o, dim=1) + ns_o = size(urbn_o) if (ier/=0) call shr_sys_abort() allocate(data_o(numurbl,ns_o),stat=ier) if (ier/=0) call shr_sys_abort() ! Read in input data - ! - levels are the innermost dimension for esmf fields ! - levels are the outermost dimension in pio reads - ! Input data is read into (ns_i,numurbl) array and then transferred to urban_classes_gcell_i(numurbl,ns_i) - call mkpio_get_rawdata(pioid, 'PCT_URBAN', mesh_i, urban_classes_gcell_i, rc=rc) + ! - levels are the innermost dimension for esmf fields + ! Input data is read into (ns_i,numurbl) array and then transferred to data_i(numurbl,ns_i) + call mkpio_get_rawdata(pioid, 'PCT_URBAN', mesh_i, data_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - ! Regrid raw data to model resolution - ! make percent urban on output grid, given percent urban on input grid - ! This assumes that we're neither using all_urban or zero_out - ! Determine urbn_o on ouput grid: - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. + ! Regrid input data to model resolution call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 1, numurbl, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regrid_data for in "//trim(subname)) ! Now Determine total % urban - call ESMF_LogWrite("Before allocate of urban_classes_gcell_o", ESMF_LOGMSG_INFO) + ! urbn_classes_gcell_o is % urban of total grid cell area for each density class allocate(urban_classes_gcell_o(ns_o, numurbl), stat=ier) if (ier/=0) call shr_sys_abort() - call ESMF_LogWrite("Before loop", ESMF_LOGMSG_INFO) do l = 1,numurbl do n = 1,ns_o urban_classes_gcell_o(n,l) = data_o(l,n) @@ -212,14 +207,16 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & end do ! Determine frac_o (regrid frac_i to frac_o) - allocate(frac_i(ns_i)) - allocate(frac_o(ns_o)) + allocate(frac_o(ns_o),stat=ier) + allocate(frac_i(ns_i) ,stat=ier) call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call regrid_rawdata(mesh_i, mesh_o, routehandle, frac_i, frac_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regrid_data for landmask in "//trim(subname)) + deallocate(frac_i) + ! Area-average percent cover on input grid to output grid and correct according to frac_o + ! Note that percent cover is in terms of total grid area. do n = 1,ns_o if (frac_o(n) > 0._r8) then urban_classes_gcell_o(n,:) = urban_classes_gcell_o(n,:) / frac_o(n) @@ -230,30 +227,27 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & do n = 1, ns_o urbn_o(n) = sum(urban_classes_gcell_o(n,:)) end do - call ESMF_LogWrite("After loop", ESMF_LOGMSG_INFO) ! Check for conservation -#ifdef TODO do no = 1, ns_o if ((urbn_o(no)) > 100.000001_r8) then - write (6,'(a,i8,a,i8)') 'MKURBAN error: percent urban = ',urbn_o(no), & + write (6,'(a,d13.5,a,i8)') trim(subname)//' error: percent urban = ',urbn_o(no), & ' greater than 100.000001 for no = ',no - !call shr_sys_abort() + call shr_sys_abort() end if enddo - !call shr_sys_abort() -#endif - ! determine urban_classes_o - call ESMF_LogWrite("Before normalize_urbn", ESMF_LOGMSG_INFO) + ! Determine urban_classes_o + ! Make percent urban on output grid, given percent urban on input grid + ! This assumes that we're neither using all_urban or zero_out + ! Determine urbn_o on ouput grid: call normalize_urbn_by_tot(urban_classes_gcell_o, urbn_o, urban_classes_o) call ESMF_LogWrite("After normalize_urbn", ESMF_LOGMSG_INFO) ! Handle special cases - ! Note that, for all these adjustments of total urban %, we do not change anything - ! about the breakdown into the different urban classes. In particular: when urbn_o is - ! set to 0 for a point, the breakdown into the different urban classes is maintained - ! as it was before. + ! Note that, for all these adjustments of total urban %, we do not change the breakdown + ! into the different urban classes. In particular: when urbn_o is set to 0 for a point, + ! the breakdown into the different urban classes is maintained as it was before. if (all_urban) then urbn_o(:) = 100._r8 else if (zero_out) then @@ -267,19 +261,16 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & end do end if - deallocate(data_i) - deallocate(data_o) - -#ifdef TODO ! Print diagnostics + ! TODO: call to mkurban_pct_diagnostics has to be rewritten ! First, recompute urban_classes_gcell_o, based on any changes we have made to urbn_o - call normalize_classes_by_gcell(urban_classes_o, urbn_o, urban_classes_gcell_o) - do k = 1, numurbl - call mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, & - urban_classes_gcell_i(:,k), urban_classes_gcell_o(:,k), & - ndiag, dens_class=k, frac_dst=frac_dst) - end do -#endif + ! call normalize_classes_by_gcell(urban_classes_o, urbn_o, urban_classes_gcell_o) + ! do k = 1, numurbl + ! call mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, & + ! urban_classes_gcell_i(:,k), urban_classes_gcell_o(:,k), & + ! ndiag, dens_class=k, frac_dst=frac_dst) + ! end do + if (root_task) then write (ndiag,'(a)') 'Successfully made %urban' write (ndiag,'(a)') 'Attempting to make urban region .....' @@ -289,39 +280,44 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & ! Read in region field ! ------------------------------------------------------ + ! Read in region_i allocate(region_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - - call ESMF_LogWrite("Before mkpio_get_rawdata", ESMF_LOGMSG_INFO) call mkpio_get_rawdata(pioid, 'REGION_ID', mesh_i, region_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite("After mkpio_get_rawdata", ESMF_LOGMSG_INFO) - + call ESMF_LogWrite("After reading in region_id in "//trim(subname), ESMF_LOGMSG_INFO) max_regions = nregions + if (root_task) then + write(ndiag,'(a,i8)') trim(subname)//" max urban regions = ",max_regions + end if - ! Now determine data_i as a real 2d array + ! Create a multi-dimensional array (data_i) where each ungridded dimension corresponds to a 2d field + ! where there is a 1 for every gridcell that has region_i equal to a given region + ! TODO: do we need to multiply by mask_i? + if (allocated(data_i)) deallocate(data_i) allocate(data_i(max_regions, ns_i), stat=ier) if (ier/=0) call shr_sys_abort('error allocating data_i(max_regions, ns_i)') - allocate(data_o(max_regions, ns_o), stat=ier) - if (ier/=0) call shr_sys_abort('error allocating data_i(max_regions, ns_o)') - - data_i(:,:) = 0._r4 + data_i(:,:) = 0._r8 do l = 1,max_regions do n = 1,ns_i if (region_i(n) == l) then - !data_i(l,n) = 1._r4 * mask_i(n) - data_i(l,n) = 1. ! DEBUG + !data_i(l,n) = 1._r8 * mask_i(n) ! TODO: + data_i(l,n) = 1._r8 end if end do end do ! Regrid data_i to data_o + if (allocated(data_o)) deallocate(data_o) + allocate(data_o(max_regions, ns_o), stat=ier) + if (ier/=0) call shr_sys_abort('error allocating data_i(max_regions, ns_o)') call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 1, nregions, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Now find dominant region in each output gridcell - this is identical to the maximum index do n = 1,ns_o max_index = maxloc(data_o(:,n)) + region_o(n) = max_index(1) end do ! do n = 1,ns_o ! maxindex = 1 @@ -339,9 +335,8 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & write (ndiag,*) end if - ! Output diagnostics - ! call output_diagnostics_index(factorlist, factorindex, region_i, region_o, 'Urban Region ID', & - ! 1, max_region, ndiag) + ! Output diagnostics + ! TODO: (not currently done) ! Close the file call pio_closefile(pioid) @@ -399,7 +394,6 @@ subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) !----------------------------------------------------------------------- ! Error-check inputs - n_max = size(sums) if (size(classes_pct_tot, 1) /= n_max .or. & size(classes_pct_gcell, 1) /= n_max) then @@ -409,14 +403,12 @@ subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) write(6,*) 'size(classes_pct_gcell, 1) = ', size(classes_pct_gcell, 1) call shr_sys_abort() end if - if (size(classes_pct_tot, 2) /= size(classes_pct_gcell, 2)) then write(6,*) subname//' ERROR: array size mismatch' write(6,*) 'size(classes_pct_tot, 2) = ', size(classes_pct_tot, 2) write(6,*) 'size(classes_pct_gcell, 2) = ', size(classes_pct_gcell, 2) call shr_sys_abort() end if - nclasses = size(classes_pct_gcell, 2) if (MD > nclasses) then write(6,*) subname//' ERROR: MD exceeds nclasses' @@ -426,7 +418,6 @@ subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) end if ! Do the work - do n = 1, n_max if (sums(n) > 0._r8) then classes_pct_tot(n,:) = classes_pct_gcell(n,:)/sums(n) * 100._r8 @@ -467,7 +458,7 @@ subroutine mkurbanpar(datfname_i, mesh_o, & ! use mkindexmapMod, only : dim_slice_type, lookup_2d_netcdf use mkvarpar - ! + ! input/output variables character(len=*) , intent(in) :: datfname_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh From 884e7836321ad3f02b871917a7bcd40baeea2888 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 29 Jan 2022 16:34:11 -0700 Subject: [PATCH 032/614] updates to get all urban output working --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 28 +- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 1454 ++++++++----------- tools/mksurfdata_esmf/src/mkindexmapMod.F90 | 209 +-- tools/mksurfdata_esmf/src/mkpioMod.F90 | 5 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 42 +- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 366 ++--- tools/mksurfdata_esmf/src/mkutilsMod.F90 | 10 +- tools/mksurfdata_esmf/src/mkvarctl.F90 | 2 +- 8 files changed, 838 insertions(+), 1278 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 0a58869a27..bc78a522b8 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -6,7 +6,7 @@ module mkfileMod use shr_sys_mod , only : shr_sys_getenv, shr_sys_abort use mkutilsMod , only : get_filename, chkerr use mkvarpar , only : nlevsoi, numrad, numstdpft - use mkurbanparMod, only : numurbl, nlevurb + use mkurbanparMod, only : numurbl, nlevurb, mkurbanpar #ifdef TODO use mkglcmecMod , only : nglcec use mkpftMod , only : mkpftAtt @@ -37,7 +37,8 @@ module mkfileMod !================================================================================= subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & - pctlak, pctwet, lakedepth, organic, urban_classes, urban_region, soil_color, nsoilcol) + pctlak, pctwet, lakedepth, organic, soil_color, nsoilcol, & + urban_classes_g, urban_region) ! input/output variables integer , intent(in) :: nx @@ -48,10 +49,10 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & real(r8), pointer, intent(in) :: pctwet(:) ! percent of grid cell that is wetland real(r8), pointer, intent(in) :: lakedepth(:) ! lake depth (m) real(r8), pointer, intent(in) :: organic(:,:) ! organic - real(r8), pointer, intent(in) :: urban_classes(:,:) ! percent cover of each urban class, as % of total urban area - integer , pointer, intent(in) :: urban_region(:) ! urban region ID integer , pointer, intent(in) :: soil_color(:) integer , intent(in) :: nsoilcol + real(r8), pointer, intent(in) :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell + integer , pointer, intent(in) :: urban_region(:) ! urban region ID #ifdef TODO type(harvestDataType) , intent(in) :: harvdata #endif @@ -139,21 +140,19 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & if (root_task) write(ndiag, '(a)') trim(subname)//"writing out percnt urban" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_URBAN', 'percent urban for each density type', & - 'unitless', urban_classes, lev1name='numurbl', rc=rc) + 'unitless', urban_classes_g, lev1name='numurbl', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! ---------------------------------------------------------------------- - ! Make Urban Parameters from raw input data and write to surface dataset - ! Write to netcdf file is done inside mkurbanpar routine - ! ---------------------------------------------------------------------- - - ! call mkurbanpar(datfname=mksrf_furban, ncido=ncid, region_o=urban_region, & - ! urbn_classes_gcell_o=urbn_classes_g, & - ! urban_skip_abort_on_invalid_data_check=urban_skip_abort_on_invalid_data_check) - end if end do + ! ---------------------------------------------------------------------- + ! Make Urban Parameters from raw input data and write to surface dataset + ! Write to netcdf file is done inside mkurbanpar routine + ! ---------------------------------------------------------------------- + + call mkurbanpar(pioid, mksrf_furban, mesh_o, urban_region, urban_classes_g, urban_skip_abort_on_invalid_data_check) + ! Close surface dataset call pio_closefile(pioid) @@ -195,7 +194,6 @@ subroutine mkfile_define_dims(pioid, nx, ny, dynlanduse) #ifdef TODO rcode = pio_def_dim(pioid, 'time' , PIO_UNLIMITED , dimid) rcode = pio_def_dim(pioid, 'nchar' , 256 , dimid) - rcode = pio_def_dim(pioid, 'numrad' , numrad , dimid) if (.not. dynlanduse) then rcode = pio_def_dim(pioid, 'nglcec', nglcec, dimid) rcode = pio_def_dim(pioid, 'nglcecp1', nglcec+1, dimid) diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index 6f576b73d4..6f89b4c4ab 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -1,44 +1,38 @@ module mkharvestMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkharvest -! -! !DESCRIPTION: -! Make harvest and grazing data to add to the dynamic PFT file. -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -!----------------------------------------------------------------------- -! !USES: + + !----------------------------------------------------------------------- + ! Make harvest and grazing data to add to the dynamic PFT file. + !----------------------------------------------------------------------- + + use ESMF + use pio + use mkpioMod use shr_kind_mod , only : r8 => shr_kind_r8, CL => shr_kind_CL - use mkdomainMod , only : domain_checksame + use mkvarpar + use mkvarctl implicit none - private -! !PUBLIC DATA MEMBERS: - public :: harvestDataType integer, private, parameter :: numharv = 9 ! number of harvest and grazing fields + ! public types type :: harvestDataType private - real(r8), pointer :: data1D(:,:) ! Input 1D data - real(r8), pointer :: data2DCFT(:,:,:) ! Input 2D data with CFT's - real(r8), pointer :: data2DPFT(:,:,:) ! Input 2D data with PFT's - real(r8), pointer :: OutData1D(:,:) ! Output 1D data - real(r8), pointer :: OutData2DCFT(:,:,:) ! Output 2D data with CFT's - real(r8), pointer :: OutData2DPFT(:,:,:) ! Output 2D data with natural PFT's - integer :: dims2nd(numharv) ! 2nd dimension size - integer :: CFTdimsize ! Size of CFT dimension - integer :: PFTdimsize ! Size of PFT dimension - integer :: indices1D(numharv) ! Field indices for CFT variables - integer :: indicesCFT(numharv) ! Field indices for CFT variables - integer :: indicesPFT(numharv) ! Field indices for PFT variables - contains + real(r8), pointer :: data1D(:,:) ! Input 1D data + real(r8), pointer :: data2DCFT(:,:,:) ! Input 2D data with CFT's + real(r8), pointer :: data2DPFT(:,:,:) ! Input 2D data with PFT's + real(r8), pointer :: OutData1D(:,:) ! Output 1D data + real(r8), pointer :: OutData2DCFT(:,:,:) ! Output 2D data with CFT's + real(r8), pointer :: OutData2DPFT(:,:,:) ! Output 2D data with natural PFT's + integer :: dims2nd(numharv) ! 2nd dimension size + integer :: CFTdimsize ! Size of CFT dimension + integer :: PFTdimsize ! Size of PFT dimension + integer :: indices1D(numharv) ! Field indices for CFT variables + integer :: indicesCFT(numharv) ! Field indices for CFT variables + integer :: indicesPFT(numharv) ! Field indices for PFT variables + contains procedure :: init ! Initialization procedure :: get1DFieldPtr ! Get a pointer to a 1D field procedure :: get2DFieldPtr ! Get a pointer to a 2D field @@ -51,7 +45,7 @@ module mkharvestMod procedure :: clean ! Clean and deallocate everything end type harvestDataType -! !PUBLIC MEMBER FUNCTIONS: + ! public member functions public mkharvest_init ! Initialization public mkharvest ! Calculate the harvest values on output grid public mkharvest_fieldname ! Field name for harvest fields on landuse.timeseries @@ -60,80 +54,64 @@ module mkharvestMod public mkharvest_numtypes ! Number of harvest types public mkharvest_parse_oride ! Parse the over-ride string -! !PRIVATE MEMBER FUNCTIONS: (but public because unit test uses them) + ! private member functions: (but public because unit test uses them) public mkharvest_fieldInBounds ! Check that field index is within bounds -! !PRIVATE DATA MEMBERS: - + ! private data members: integer, parameter :: harlen = 25 ! length of strings for harvest fieldnames character(len=harlen), parameter :: harvest_fieldnames(numharv) = (/ & - 'HARVEST_VH1 ', & - 'HARVEST_VH2 ', & - 'HARVEST_SH1 ', & - 'HARVEST_SH2 ', & - 'HARVEST_SH3 ', & - 'GRAZING ', & - 'FERTNITRO_CFT ', & - 'UNREPRESENTED_PFT_LULCC', & - 'UNREPRESENTED_CFT_LULCC' & - /) + 'HARVEST_VH1 ', & + 'HARVEST_VH2 ', & + 'HARVEST_SH1 ', & + 'HARVEST_SH2 ', & + 'HARVEST_SH3 ', & + 'GRAZING ', & + 'FERTNITRO_CFT ', & + 'UNREPRESENTED_PFT_LULCC', & + 'UNREPRESENTED_CFT_LULCC' & + /) character(len=harlen), parameter :: harvest_const_fieldnames(numharv) = (/ & - 'CONST_HARVEST_VH1 ', & - 'CONST_HARVEST_VH2 ', & - 'CONST_HARVEST_SH1 ', & - 'CONST_HARVEST_SH2 ', & - 'CONST_HARVEST_SH3 ', & - 'CONST_GRAZING ', & - 'CONST_FERTNITRO_CFT ', & - 'UNREPRESENTED_PFT_LULCC', & - 'UNREPRESENTED_CFT_LULCC' & - /) + 'CONST_HARVEST_VH1 ', & + 'CONST_HARVEST_VH2 ', & + 'CONST_HARVEST_SH1 ', & + 'CONST_HARVEST_SH2 ', & + 'CONST_HARVEST_SH3 ', & + 'CONST_GRAZING ', & + 'CONST_FERTNITRO_CFT ', & + 'UNREPRESENTED_PFT_LULCC', & + 'UNREPRESENTED_CFT_LULCC' & + /) + character(len=CL), parameter :: string_undef = 'UNSET' real(r8), parameter :: real_undef = -999.99 - character(len=CL), save :: harvest_longnames(numharv) = string_undef - character(len=CL), save :: harvest_units(numharv) = string_undef - real(r8), pointer :: oride_harv(:) ! array that can override harvesting - logical , save :: initialized = .false. + character(len=CL) :: harvest_longnames(numharv) = string_undef + character(len=CL) :: harvest_units(numharv) = string_undef + real(r8), pointer :: oride_harv(:) ! array that can override harvesting + logical :: initialized = .false. -!EOP -!----------------------------------------------------------------------- +!================================================================================= contains -!----------------------------------------------------------------------- +!================================================================================= -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: init -! -! !INTERFACE: subroutine init( this, dims2nd, ns_i, ns_o, init_value ) -! -! !DESCRIPTION: -! Initialization of the harvestData object -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(INOUT) :: this ! harvestData object - integer, intent(IN) :: dims2nd(:) ! 2nd Dimension sizes - integer, intent(IN) :: ns_i ! Input dimension size - integer, intent(IN) :: ns_o ! Output dimension size - real(r8), intent(IN) :: init_value ! Initial value -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: + ! + ! Initialization of the harvestData object + ! + ! input/output variables + class(harvestDataType), intent(inout) :: this ! harvestData object + integer, intent(in) :: dims2nd(:) ! 2nd Dimension sizes + integer, intent(in) :: ns_i ! Input dimension size + integer, intent(in) :: ns_o ! Output dimension size + real(r8), intent(in) :: init_value ! Initial value + ! + ! !local variables: character(len=*), parameter :: subname = 'harvestData::init' integer :: num2nd ! number of non 1D variables integer :: numCFT, numPFT ! number of CFT and PFT variables respectively integer :: num1D ! number of 1D variables integer :: n ! index -!EOP -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + if ( size(dims2nd) /= numharv )then write(*,*) subname//':ERROR:: dims2nd given to init is not the right size' call shr_sys_abort() @@ -186,38 +164,391 @@ subroutine init( this, dims2nd, ns_i, ns_o, init_value ) end subroutine init -!----------------------------------------------------------------------- + !================================================================================= + subroutine mkharvest_init( ns_o, init_val, harvdata, fharvest, constant ) + ! + ! Initialization of mkharvest module. + ! + ! input/output variables: + integer , intent(in) :: ns_o ! clm output grid resolution + real(r8) , intent(in) :: init_val ! initial value to set to + type(harvestDataType) , intent(inout) :: harvdata ! Harvest data + character(len=*) , intent(in) :: fharvest ! input harvest dataset file name + logical, optional , intent(in) :: constant ! Flag if variables are CONST_ version for surface dataset + + ! local variables: + character(len=CL) :: lunits ! local units read in + integer :: ncid,varid ! input netCDF id's + integer :: ifld ! indices + integer :: ret ! return code + logical :: lconstant ! local version of constant flag + logical :: varexists ! If variable exists on file + integer :: dim_lengths(3) ! Dimension lengths on file + integer :: dims2nd(numharv) ! Dimension lengths of 3rd dimension for each variable on file + integer :: ndims ! Number of dimensions on file + integer :: ns_i ! clm input grid resolution (nlat*nlon) + character(len=*), parameter :: subname = 'mkharvest_init' + !----------------------------------------------------------------------- + + lconstant = .false. + if ( present(constant) ) lconstant = constant + + initialized = .true. + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(fharvest), pio_nowrite) + + dims2nd(:) = 0 + ns_i = 0 + do ifld = 1, numharv + call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) + varname = mkharvest_fieldname(ifld, constant=lconstant) + rCode = pio_inq_varid(varname, pio_varid) + call pio_seterrorhandling(pioid, PIO_INTERNAL_ERROR) + if (rcode /= PIO_NOERR) then + write(*,*) "SKIP: "//mkharvest_fieldname(ifld, constant=lconstant) + harvest_longnames(ifld) = trim(mkharvest_fieldname(ifld, constant=lconstant)) // " (zeroed out)" + harvest_units(ifld) = "not_read_in" + else + call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) + rcode = pio_inq_attname(pioid, pio_varid, attnum, attname) + call pio_seterrorhandling(pioid, PIO_INTERNAL_ERROR) + if (rcode == 'PIO_NOERR') then + rcode = pio_get_att_text( pioid, pio_varid, 'long_name', harvest_longnames(ifld)) + rcode = pio_get_att_text( pioid, pio_varid, 'units', harvest_units(ifld)) + end if + call mkpio_get_dimlengths(pioid, varname, ndims, dim_lengths) + if ( ns_i == 0 )then + ns_i = dim_lengths(1)*dim_lengths(2) + else if ( ns_i /= dim_lengths(1)*dim_lengths(2) )then + write(*,*) 'ERROR:: bad dimension sizes for variable = ', mkharvest_fieldname(ifld, constant=lconstant) + call shr_sys_abort() + end if + if ( ndims == 2 )then + dims2nd(ifld) = 0 + else if ( ndims == 3 )then + dims2nd(ifld) = dim_lengths(3) + else + write(*,*) 'ERROR:: bad dimensionality for variable = ', mkharvest_fieldname(ifld, constant=lconstant) + call shr_sys_abort() + end if + end if + end do + call pio_closefile(pioid) + + ! Initialize harvest datatype + call harvdata%init( dims2nd, ns_i, ns_o, init_val ) -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: get1DFieldPtr -! -! !INTERFACE: + allocate( oride_harv(numharv) ) + oride_harv(:) = real_undef + + end subroutine mkharvest_init + + !================================================================================= + subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, harvdata, rc) + ! + ! Make harvest data for the dynamic PFT dataset. + ! This dataset consists of the normalized harvest or grazing fraction (0-1) of + ! the model. + ! + ! input/output variables: + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh + type(harvestDataType) , intent(inout) :: harvdata ! Harvest data + integer , intent(out) :: rc ! return code + + ! local variables: + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + type(var_desc_t) :: pio_varid + integer :: ni,no,ns_i,ns_o ! indices + integer :: k,l,n,m ! indices + integer :: rcode, ier ! error status + integer :: ndims + integer , allocatable :: dimlengths(:) + real(r8), allocatable :: data_i(:,:) + real(r8), allocatable :: data_o(:,:) + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) + real(r8) :: gharv_o(numharv) ! output grid: global area harvesting + real(r8) :: garea_o ! output grid: global area + real(r8) :: gharv_i(numharv) ! input grid: global area harvesting + real(r8) :: garea_i ! input grid: global area + integer :: ifld ! indices + logical :: varexists ! If variable exists or not + integer, allocatable :: ind1D(:) ! Index of 1D harvest fields + integer, allocatable :: ind2D(:) ! Index of 2D harvest fields + real(r8), pointer :: data1D_i(:) ! 1D input data + real(r8), pointer :: data2D_i(:,:) ! 2D output data + real(r8), pointer :: data1D_o(:) ! 1D output data + real(r8), pointer :: data2D_o(:,:) ! 2D output data + real(r8), allocatable :: read_data2d_i(:,:) ! input 2d data read in + real(r8), allocatable :: read_data2d_o(:,:) ! regridded input 2d data + character(len=CS) :: varname + integer :: nlev ! inner dimension of input 2d data read in + character(len=*), parameter :: unit = '10**6 km**2' ! Output units + real(r8), parameter :: fac = 1.e-06_r8 ! Output factor + real(r8), parameter :: rat = fac/100._r8 ! Output factor divided by 100% + character(len=*), parameter :: subname = 'mkharvest' + !----------------------------------------------------------------------- + + if (root_task) then + write (ndiag,'(a)') 'Attempting to make harvest fields .....' + end if + + ! ----------------------------------------------------------------- + ! Normally read in the harvesting file, and then regrid to output grid + ! ----------------------------------------------------------------- + + call harvdata%getFieldsIdx( ind1D, ind2D ) + + if ( all(oride_harv == real_undef ) )then + + ! ----------------------------------------------------------------- + ! Read input harvesting file + ! ----------------------------------------------------------------- + + ! Open input data file - need to do this first to obtain ungridded dimension size + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) + + ! Read in input mesh + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Create a route handle between the input and output mesh + call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + + ! Determine ns_i and allocate data_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + allocate(data_i(nlay,ns_i),stat=ier) + if (ier/=0) call shr_sys_abort() + + ! Determine ns_o and allocate data_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + allocate(frac_o(ns_o), stat=ier) + if (ier/=0) call shr_sys_abort() + + ! Determine frac_o (regrid frac_i to frac_o) + allocate(frac_i(ns_i)) + allocate(frac_o(ns_o)) + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, frac_i, frac_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regrid landmask in "//trim(subname)) + + ! Read in input 1d fields if they exists and map to output grid + do k = 1, harvdata%num1Dfields() + ifld = ind1D(k) + data1d_i => harvdata%get1DFieldPtr( ifld ) + data1d_o => harvdata%get1DFieldPtr( ifld, output=.true. ) + data1d_i(:) = 0.0_r8 + call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) + varname = mkharvest_fieldname(ifld) + rCode = pio_inq_varid(varname, pio_varid) + call pio_seterrorhandling(pioid, PIO_INTERNAL_ERROR) + if (rcode == PIO_NOERR) then + call mkpio_get_rawdata(pioid, varname, mesh_i, data1d_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, data1d_i, data1d_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do n = 1,ns_o + if (frac_o(n) > 0._r8) then + data1d_o(n) = datda1d_o(n) / frac_o(n) + else + data1d_o(n) = 0._r8 + end if + end do + else + write(*,*) "SKIP: "//mkharvest_fieldname(ifld) + end if + end do + + ! Read in input 1d fields if they exists and map to output grid + ! TODO: enter this in + do k = 1, harvdata%num2Dfields() + ifld = ind2D(k) + data2d_i => harvdata%get2DFieldPtr( ifld ) + data2d_o => harvdata%get2DFieldPtr( ifld, output=.true. ) + data2d_i(:,:) = 0.0_r8 + call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) + varname = mkharvest_fieldname(ifld) + rCode = pio_inq_varid(varname, pio_varid) + call pio_seterrorhandling(pioid, PIO_INTERNAL_ERROR) + if (rcode == PIO_NOERR) then + nlev = size(data2d_i, dim=2) + allocate(read_data2d_i(nlev, ns_i) + allocate(read_data2d_o(nlev, ns_o) + call mkpio_get_rawdata(pioid, varname, mesh_i, read_data2d_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, read_data2d_i, read_data2d_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do n = 1,ns_o + if (frac_o(n) > 0._r8) then + read_data2d_o(:,n) = datda2d_o(:,n) / frac_o(n) + else + read_data2d_o(:,n) = 0._r8 + end if + end do + do l = 1,nlev + do n = 1,ns_o + data2d_o(n,l) = read_data2d_o(l,n) + end do + end do + deallocate(read_data2d_i) + deallocate(read_data2d_o) + else + write(*,*) "SKIP: "//mkharvest_fieldname(ifld) + end if + end do + + call pio_closefile(pioid) + + ! ----------------------------------------------------------------- + ! Error check + ! Compare global areas on input and output grids + ! ----------------------------------------------------------------- + + ! gharv_i(:) = 0. + ! garea_i = 0. + ! do ni = 1, ns_i + ! garea_i = garea_i + area_src(ni)*re**2 + ! do k = 1, harvdata%num1Dfields() + ! m = ind1D(k) + ! data1D_i => harvdata%get1DFieldPtr( m ) + ! gharv_i(m) = gharv_i(m) + data1D_i(ni)*area_src(ni) * mask(ni)*re**2 + ! end do + ! end do + ! gharv_o(:) = 0. + ! garea_o = 0. + ! do no = 1,ns_o + ! garea_o = garea_o + area_dst(no)*re**2 + ! do k = 1, harvdata%num1Dfields() + ! m = ind1D(k) + ! data1D_o => harvdata%get1DFieldPtr( m, output=.true. ) + ! gharv_o(m) = gharv_o(m) + data1D_o(no)*area_dst(no)* frac_dst(no)*re**2 + ! end do + ! end do + + ! Write out to diagnostic output file +! write (ndiag,*) +! write (ndiag,'(1x,70a1)') ('=',k=1,70) +! write (ndiag,*) 'Harvesting Output' +! write (ndiag,'(1x,70a1)') ('=',k=1,70) + +! write (ndiag,*) +! write (ndiag,'(1x,70a1)') ('.',k=1,70) +! write (ndiag,1001) unit, unit +! 1001 format (1x,'harvest type ',20x,' input grid area',' output grid area',/ & +! 1x,33x,' ',A,' ',A) +! write (ndiag,'(1x,70a1)') ('.',k=1,70) +! write (ndiag,*) +! do k = 1, harvdata%num1Dfields() +! m = ind1D(k) +! write (ndiag,1002) mkharvest_fieldname(m), gharv_i(m)*rat,gharv_o(m)*rat +! end do +! 1002 format (1x,a35,f16.3,f17.3) + + else + + ! ----------------------------------------------------------------- + ! Otherwise override the harvesting with the input harvest values + ! ----------------------------------------------------------------- + + if ( any(oride_harv == real_undef ) )then + write(6,*) subname, ' error some override harvesting fields set and others are not = ', oride_harv + call shr_sys_abort() + end if + do k = 1, harvdata%num1Dfields() + m = ind1D(k) + if ( oride_harv(m) < 0.0_r8 .or. oride_harv(m) > 100.0_r8 )then + write(6,*) subname, ' error override harvesting field out of range', & + oride_harv(m), ' field = ', mkharvest_fieldname(m) + call shr_sys_abort() + end if + end do + do no = 1,ns_o + do k = 1, harvdata%num1Dfields() + m = ind1D(k) + data1D_o => harvdata%get1DFieldPtr( m, output=.true. ) + data1D_o(no) = oride_harv(m) + end do + end do + + end if + + deallocate( ind1D, ind2D ) + write (6,*) 'Successfully made harvest and grazing' + write (6,*) + + end subroutine mkharvest + + !================================================================================= + subroutine mkharvest_parse_oride( string ) + ! + ! Parse the string with harvest and grazing information on it, to override + ! the file with this information rather than reading from a file. + ! + use shr_string_mod, only: shr_string_betweenTags + + ! input/output variables: + character(len=256), intent(in) :: string ! String to parse with harvest and grazing data + + ! local variables: + integer :: rc ! error return code + character(len=256) :: substring ! substring between tags + character(len=*), parameter :: harv_start = "" + character(len=*), parameter :: harv_end = "" + character(len=*), parameter :: graz_start = "" + character(len=*), parameter :: graz_end = "" + character(len=*), parameter :: subname = 'mkharvest_parse_oride' + !----------------------------------------------------------------------- + + call shr_string_betweenTags( string, harv_start, harv_end, substring, rc ) + if ( rc /= 0 )then + write(6,*) subname//'Trouble finding harvest start end tags' + call shr_sys_abort() + end if + read(substring,*) oride_harv(1:numharv-1) + call shr_string_betweenTags( string, graz_start, graz_end, substring, rc ) + if ( rc /= 0 )then + write(6,*) subname//'Trouble finding grazing start end tags' + call shr_sys_abort() + end if + read(substring,*) oride_harv(numharv) + if ( harvest_fieldnames(numharv) /= 'GRAZING' )then + write(6,*) subname, ' grazing is NOT last field as was expected' + call shr_sys_abort() + end if + + end subroutine mkharvest_parse_oride + + !================================================================================= function get1DFieldPtr( this, nfield, output ) result(ptr1D) -! -! !DESCRIPTION: -! Returns 2D pointer to field data for this index -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object - integer, intent(in) :: nfield ! field index - real(r8), pointer :: ptr1D(:) ! Pointer to 1D data - logical, optional, intent(in) :: output ! Flag if this is the output pointer or not (input) -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'harvestData::get1DFieldPtr' + ! + ! Returns 2D pointer to field data for this index + ! + ! input/output variables + class(harvestDataType) , intent(in) :: this ! harvestData object + integer , intent(in) :: nfield ! field index + real(r8) , pointer :: ptr1D(:) ! Pointer to 1D data + logical, optional , intent(in) :: output ! Flag if this is the output pointer or not (input) + ! + ! !local variables: logical :: loutput ! Local output flag -!EOP -!----------------------------------------------------------------------- + character(len=*), parameter :: subname = 'harvestData::get1DFieldPtr' + !----------------------------------------------------------------------- + loutput = .false. - if ( present(output) ) loutput = output + if (present(output)) loutput = output + if ( mkharvest_fieldInBounds( nfield ) .and. this%isField1D(nfield) )then if ( .not. loutput ) then ptr1D => this%data1D(:,this%indices1D(nfield)) @@ -229,36 +560,22 @@ function get1DFieldPtr( this, nfield, output ) result(ptr1D) end if end function get1DFieldPtr -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: get2DFieldPtr -! -! !INTERFACE: + !================================================================================= function get2DFieldPtr( this, nfield, output ) result(ptr2D) -! -! !DESCRIPTION: -! Returns 2D pointer to field data for this index -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object - integer, intent(in) :: nfield ! field index - real(r8), pointer :: ptr2D(:,:) ! Pointer to 2D data - logical, optional, intent(in) :: output ! Flag if this is the output pointer or not (input) -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'harvestData::get2DFieldPtr' + ! + ! Returns 2D pointer to field data for this index + ! + ! input/output variables: + class(harvestDataType) , intent(in) :: this ! harvestData object + integer , intent(in) :: nfield ! field index + real(r8) , pointer :: ptr2D(:,:) ! Pointer to 2D data + logical, optional , intent(in) :: output ! Flag if this is the output pointer or not (input) + ! + ! local variables: logical :: loutput ! Local output flag -!EOP -!----------------------------------------------------------------------- + character(len=*), parameter :: subname = 'harvestData::get2DFieldPtr' + !----------------------------------------------------------------------- + loutput = .false. if ( present(output) ) loutput = output if ( mkharvest_fieldInBounds( nfield ) .and. this%isField2D(nfield) )then @@ -280,35 +597,21 @@ function get2DFieldPtr( this, nfield, output ) result(ptr2D) end if end function get2DFieldPtr -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: getFieldsIdx -! -! !INTERFACE: + !================================================================================= subroutine getFieldsIdx( this, indices1D, indices2D ) -! -! !DESCRIPTION: -! Returns list of 1D and 2D fields indices -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object + ! + ! Returns list of 1D and 2D fields indices + ! + ! input/output variables: + class(harvestDataType), intent(in) :: this ! harvestData object integer, allocatable :: indices1D(:) ! List of 1D indices integer, allocatable :: indices2D(:) ! List of 2D indices -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: + ! + ! local variables: character(len=*), parameter :: subname = 'harvestData::getFieldsIdx' integer :: ifld, n1, n2 ! field index and field index -!EOP -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + allocate( indices1D(max(1,this%num1DFields()) ) ) allocate( indices2D(max(1,this%num2DFields()) ) ) indices1D = -1 @@ -326,34 +629,20 @@ subroutine getFieldsIdx( this, indices1D, indices2D ) end do end subroutine getFieldsIdx -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: getFieldsDim -! -! !INTERFACE: + !================================================================================= function getFieldsDim( this, nfield ) result(dimname) -! -! !DESCRIPTION: -! Returns list of 1D and 2D fields indices -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object + ! + ! Returns list of 1D and 2D fields indices + ! + ! input/output variables: + class(harvestDataType), intent(in) :: this ! harvestData object integer, intent(in) :: nfield ! field index character(len=10) :: dimname ! Dimension names -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: + ! + ! local variables: character(len=*), parameter :: subname = 'harvestData::getFieldsDim' -!EOP -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + if ( this%dims2nd(nfield) == this%CFTdimsize )then dimname = "cft" else if ( this%dims2nd(nfield) == this%PFTdimsize )then @@ -363,33 +652,19 @@ function getFieldsDim( this, nfield ) result(dimname) end if end function getFieldsDim -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: isField1D -! -! !INTERFACE: + !================================================================================= logical function isField1D( this, nfield ) -! -! !DESCRIPTION: -! Returns true if this field index is a 1D field -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object + ! + ! Returns true if this field index is a 1D field + ! + ! input/output variables: + class(harvestDataType), intent(in) :: this ! harvestData object integer, intent(in) :: nfield ! field index -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: + ! + ! local variables: character(len=*), parameter :: subname = 'harvestData::isField1D' -!EOP -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + isField1D = .false. if ( mkharvest_fieldInBounds( nfield ) )then if ( this%dims2nd(nfield) == 0 ) isField1D = .true. @@ -398,33 +673,19 @@ logical function isField1D( this, nfield ) end if end function isField1D -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: isField2D -! -! !INTERFACE: + !================================================================================= logical function isField2D( this, nfield ) -! -! !DESCRIPTION: -! Returns true if this field index is a 2D field -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object + ! + ! Returns true if this field index is a 2D field + ! + ! input/output variables: + class(harvestDataType), intent(in) :: this ! harvestData object integer, intent(in) :: nfield ! field index -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: + ! + ! local variables: character(len=*), parameter :: subname = 'harvestData::isField2D' -!EOP -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + isField2D = .false. if ( mkharvest_fieldInBounds( nfield ) )then if ( this%dims2nd(nfield) /= 0 ) isField2D = .true. @@ -433,369 +694,157 @@ logical function isField2D( this, nfield ) end if end function isField2D -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: num1DFields -! -! !INTERFACE: + !================================================================================= integer function num1DFields( this ) -! -! !DESCRIPTION: -! Returns the number of 1D fields -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: + ! + ! Returns the number of 1D fields + ! + ! input/output variables: + class(harvestDataType), intent(in) :: this ! harvestData object + ! + ! local variables: character(len=*), parameter :: subname = 'harvestData::num1DFields' -!EOP -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- num1DFields = count( this%dims2nd == 0) end function num1DFields -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: num2DFields -! -! !INTERFACE: + !================================================================================= integer function num2DFields( this ) -! -! !DESCRIPTION: -! Returns the number of 2D fields -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: + ! + ! Returns the number of 2D fields + ! + ! input/output variables: + class(harvestDataType), intent(in) :: this ! harvestData object + ! + ! local variables: character(len=*), parameter :: subname = 'harvestData::num2DFields' -!EOP -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + num2DFields = count( this%dims2nd /= 0) end function num2DFields -!----------------------------------------------------------------------- -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest_init -! -! !INTERFACE: - subroutine mkharvest_init( ns_o, init_val, harvdata, fharvest, constant ) -! -! !DESCRIPTION: -! Initialization of mkharvest module. -! -! !USES: - use mkncdio - implicit none -! -! !ARGUMENTS: - integer , intent(in) :: ns_o ! clm output grid resolution - real(r8) , intent(in) :: init_val ! initial value to set to - type(harvestDataType), intent(INOUT) :: harvdata ! Harvest data - character(len=*) , intent(in) :: fharvest ! input harvest dataset file name - logical, intent(in), optional :: constant ! Flag if variables are CONST_ version for surface dataset - ! rather than landuse.timeseries -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'mkharvest_init' - character(len=CL) :: lunits ! local units read in - integer :: ncid,varid ! input netCDF id's - integer :: ifld ! indices - integer :: ret ! return code - logical :: lconstant ! local version of constant flag - logical :: varexists ! If variable exists on file - integer :: dim_lengths(3) ! Dimension lengths on file - integer :: dims2nd(numharv) ! Dimension lengths of 3rd dimension for each variable on file - integer :: ndims ! Number of dimensions on file - integer :: ns_i ! clm input grid resolution (nlat*nlon) -!EOP -!----------------------------------------------------------------------- - lconstant = .false. - if ( present(constant) ) lconstant = constant - - initialized = .true. - call check_ret(nf_open(fharvest, 0, ncid), subname) - dims2nd(:) = 0 - ns_i = 0 - do ifld = 1, numharv - call check_ret(nf_inq_varid ( ncid, mkharvest_fieldname(ifld, constant=lconstant), varid), subname, varexists=varexists) - if ( .not. varexists )then - write(*,*) "SKIP: "//mkharvest_fieldname(ifld, constant=lconstant) - harvest_longnames(ifld) = trim(mkharvest_fieldname(ifld, constant=lconstant)) // " (zeroed out)" - harvest_units(ifld) = "not_read_in" - else - call check_ret(nf_get_att_text( ncid, varid, 'long_name', harvest_longnames(ifld)), subname ) - ret = nf_get_att_text( ncid, varid, 'units', harvest_units(ifld)) - if ( ret == nf_enotatt )then - harvest_units(ifld) = "unitless" - else if ( ret == nf_noerr )then - else - write(*,*) 'ERROR:: bad return code from NetCDF get attribute= '// nf_strerror(ret) - call shr_sys_abort() - end if - call get_dim_lengths(ncid, mkharvest_fieldname(ifld, constant=lconstant), ndims, dim_lengths) - if ( ns_i == 0 )then - ns_i = dim_lengths(1)*dim_lengths(2) - else if ( ns_i /= dim_lengths(1)*dim_lengths(2) )then - write(*,*) 'ERROR:: bad dimension sizes for variable = ', mkharvest_fieldname(ifld, constant=lconstant) - call shr_sys_abort() - end if - if ( ndims == 2 )then - dims2nd(ifld) = 0 - else if ( ndims == 3 )then - dims2nd(ifld) = dim_lengths(3) - else - write(*,*) 'ERROR:: bad dimensionality for variable = ', mkharvest_fieldname(ifld, constant=lconstant) - call shr_sys_abort() - end if - - end if - end do - call harvdata%init( dims2nd, ns_i, ns_o, init_val ) - - call check_ret(nf_close(ncid), subname) - - allocate( oride_harv(numharv) ) - oride_harv(:) = real_undef - - end subroutine mkharvest_init - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest_fieldInBounds -! -! !INTERFACE: - logical function mkharvest_fieldInBounds( nfield ) -! -! !DESCRIPTION: -! Return true if field index is in bounds and initialization done -! -! !USES: - implicit none -! -! !ARGUMENTS: + !================================================================================= + logical function mkharvest_fieldInBounds( nfield ) + ! + ! Return true if field index is in bounds and initialization done + ! + ! input/output variables: integer, intent(in) :: nfield ! field index -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: + ! + ! local variables: character(len=*), parameter :: subname = 'mkharvest_fieldInBounds' -!EOP -!----------------------------------------------------------------------- - if ( nfield < 1 )then - write(6,*) subname, ' ERROR nfield < 1' - mkharvest_fieldInBounds = .false. - else if ( nfield > numharv )then - write(6,*) subname, ' ERROR nfield > max fields' - mkharvest_fieldInBounds = .false. - else if ( .not. initialized ) then - write(6,*) subname, ' ERROR mkharvest NOT initialized yet!' - mkharvest_fieldInBounds = .false. - else - mkharvest_fieldInBounds = .true. - end if + !----------------------------------------------------------------------- + + if ( nfield < 1 )then + write(6,*) subname, ' ERROR nfield < 1' + mkharvest_fieldInBounds = .false. + else if ( nfield > numharv )then + write(6,*) subname, ' ERROR nfield > max fields' + mkharvest_fieldInBounds = .false. + else if ( .not. initialized ) then + write(6,*) subname, ' ERROR mkharvest NOT initialized yet!' + mkharvest_fieldInBounds = .false. + else + mkharvest_fieldInBounds = .true. + end if end function mkharvest_fieldInBounds -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest_fieldname -! -! !INTERFACE: + !================================================================================= character(len=harlen) function mkharvest_fieldname( nfield, constant ) -! -! !DESCRIPTION: -! Return harvest fieldname of input field number. -! -! !USES: - implicit none -! -! !ARGUMENTS: + ! + ! Return harvest fieldname of input field number. + ! + ! input/output variables: integer, intent(in) :: nfield logical, intent(in), optional :: constant -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: + ! + ! local variables: character(len=*), parameter :: subname = 'mkharvest_fieldname' logical :: lconstant ! local version of constant flag -!EOP -!----------------------------------------------------------------------- - lconstant = .false. - if ( present(constant) ) lconstant = constant - - if ( mkharvest_fieldInBounds( nfield ) )then - if ( .not. lconstant )then - mkharvest_fieldname = harvest_fieldnames(nfield) - else - mkharvest_fieldname = harvest_const_fieldnames(nfield) - end if - else - call shr_sys_abort() - end if + !----------------------------------------------------------------------- + lconstant = .false. + if ( present(constant) ) lconstant = constant - end function mkharvest_fieldname + if ( mkharvest_fieldInBounds( nfield ) )then + if ( .not. lconstant )then + mkharvest_fieldname = harvest_fieldnames(nfield) + else + mkharvest_fieldname = harvest_const_fieldnames(nfield) + end if + else + call shr_sys_abort() + end if -!----------------------------------------------------------------------- + end function mkharvest_fieldname -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest_units -! -! !INTERFACE: + !================================================================================= character(len=CL) function mkharvest_units( nfield ) -! -! !DESCRIPTION: -! Return units description of harvest fields -! -! !USES: - implicit none -! -! !ARGUMENTS: + ! + ! Return units description of harvest fields + ! + ! input/output variables: integer, intent(in) :: nfield -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: + + ! local variables: character(len=*), parameter :: subname = 'mkharvest_units' -!EOP -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- - if ( mkharvest_fieldInBounds( nfield ) )then - mkharvest_units = harvest_units(nfield) - else - call shr_sys_abort() - end if + if ( mkharvest_fieldInBounds( nfield ) )then + mkharvest_units = harvest_units(nfield) + else + call shr_sys_abort() + end if end function mkharvest_units -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest_longname -! -! !INTERFACE: + !================================================================================= character(len=CL) function mkharvest_longname( nfield ) -! -! !DESCRIPTION: -! Return longname description of given input field number. -! -! !USES: - implicit none -! -! !ARGUMENTS: + ! + ! Return longname description of given input field number. + + ! input/output variables: integer, intent(in) :: nfield -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: + ! + ! local variables: character(len=*), parameter :: subname = 'mkharvest_longname' -!EOP -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- - if ( mkharvest_fieldInBounds( nfield ) )then - mkharvest_longname = harvest_longnames(nfield) - else - call shr_sys_abort() - end if + if ( mkharvest_fieldInBounds( nfield ) )then + mkharvest_longname = harvest_longnames(nfield) + else + call shr_sys_abort() + end if end function mkharvest_longname -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest_numtypes -! -! !INTERFACE: + !================================================================================= integer function mkharvest_numtypes( ) -! -! !DESCRIPTION: -! Return number of different harvest field types. -! -! !USES: - implicit none -! -! !ARGUMENTS: + ! + ! Return number of different harvest field types. + ! + ! input/output variables: character(len=*), parameter :: subname = 'mkharvest_numtypes' -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP -!----------------------------------------------------------------------- - mkharvest_numtypes = numharv - end function mkharvest_numtypes + ! local variables: + !----------------------------------------------------------------------- + mkharvest_numtypes = numharv -!----------------------------------------------------------------------- + end function mkharvest_numtypes -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: clean -! -! !INTERFACE: + !================================================================================= subroutine clean( this ) -! -! !DESCRIPTION: -! Clean and deallocate the harvestData object -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(INOUT) :: this ! harvestData object -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: + ! + ! Clean and deallocate the harvestData object + ! + ! input/output variables: + class(harvestDataType), intent(inout) :: this ! harvestData object + ! + ! local variables: character(len=*), parameter :: subname = 'harvestData::clean' -!EOP -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + this%CFTdimsize = -1 this%PFTdimsize = -1 @@ -810,293 +859,6 @@ subroutine clean( this ) this%OutData2DCFT => null() this%data2DPFT => null() this%OutData2DPFT => null() - end subroutine clean -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest -! -! !INTERFACE: -subroutine mkharvest(ldomain, mapfname, datfname, ndiag, harvdata) -! -! !DESCRIPTION: -! Make harvest data for the dynamic PFT dataset. -! This dataset consists of the normalized harvest or grazing fraction (0-1) of -! the model. -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - implicit none - type(domain_type) , intent(in) :: ldomain ! - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - type(harvestDataType), intent(INOUT) :: harvdata ! Harvest data -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8) :: gharv_o(numharv) ! output grid: global area harvesting - real(r8) :: garea_o ! output grid: global area - real(r8) :: gharv_i(numharv) ! input grid: global area harvesting - real(r8) :: garea_i ! input grid: global area - integer :: ifld ! indices - integer :: k,n,m,ni,no,ns_i,ns_o ! indices - integer :: ncid,varid ! input netCDF id's - logical :: varexists ! If variable exists or not - integer :: ier ! error status - integer, allocatable :: ind1D(:) ! Index of 1D harvest fields - integer, allocatable :: ind2D(:) ! Index of 2D harvest fields - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), pointer :: data1D_i(:) ! 1D input data - real(r8), pointer :: data2D_i(:,:) ! 2D output data - real(r8), pointer :: data1D_o(:) ! 1D output data - real(r8), pointer :: data2D_o(:,:) ! 2D output data - - character(len=*), parameter :: unit = '10**6 km**2' ! Output units - real(r8), parameter :: fac = 1.e-06_r8 ! Output factor - real(r8), parameter :: rat = fac/100._r8 ! Output factor divided by 100% - character(len=*), parameter :: subname = 'mkharvest' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make harvest fields .....' - - ! ----------------------------------------------------------------- - ! Normally read in the harvesting file, and then regrid to output grid - ! ----------------------------------------------------------------- - call harvdata%getFieldsIdx( ind1D, ind2D ) - - if ( all(oride_harv == real_undef ) )then - - ! ----------------------------------------------------------------- - ! Read input harvesting file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read HARVEST_VH1, HARVEST_VH2, ... GRAZING etc. - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - ns_o = ldomain%ns - allocate(frac_dst(ns_o), stat=ier) - if (ier /= 0) call shr_sys_abort() - - write (6,*) 'Open harvest file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - do k = 1, harvdata%num1Dfields() - ifld = ind1D(k) - call check_ret( nf_inq_varid(ncid, mkharvest_fieldname(ifld), varid), subname, varexists=varexists ) - data1D_i => harvdata%get1DFieldPtr( ifld ) - if ( .not. varexists )then - write(*,*) "SKIP: "//mkharvest_fieldname(ifld) - data1D_i(:) = 0.0_r8 - else - call check_ret(nf_get_var_double (ncid, varid, data1D_i), subname) - end if - end do - do k = 1, harvdata%num2Dfields() - ifld = ind2D(k) - call check_ret( nf_inq_varid(ncid, mkharvest_fieldname(ifld), varid), subname, varexists=varexists ) - data2D_i => harvdata%get2DFieldPtr( ifld ) - if ( .not. varexists )then - write(*,*) "SKIP: "//mkharvest_fieldname(ifld) - data2D_i(:,:) = 0.0_r8 - else - call check_ret(nf_get_var_double (ncid, varid, data2D_i), subname) - end if - end do - call check_ret(nf_close(ncid), subname) - - ! Area-average normalized harvest on input grid [data*_i] to output grid [data*_o] - - call gridmap_mapread(tgridmap, mapfname ) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine data* on output grid - - do k = 1, harvdata%num1Dfields() - ifld = ind1D(k) - data1D_i => harvdata%get1DFieldPtr( ifld ) - data1D_o => harvdata%get1DFieldPtr( ifld, output=.true. ) - call gridmap_areaave_srcmask(tgridmap, data1D_i, data1D_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - end do - do k = 1, harvdata%num2Dfields() - ifld = ind2D(k) - data2D_i => harvdata%get2DFieldPtr( ifld ) - data2D_o => harvdata%get2DFieldPtr( ifld, output=.true. ) - do m = lbound(data2D_i(:,:),dim=2), ubound(data2D_i(:,:),dim=2) - call gridmap_areaave_srcmask(tgridmap, data2D_i(:,m), data2D_o(:,m), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - end do - end do - - ! ----------------------------------------------------------------- - ! Error check - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - - gharv_i(:) = 0. - garea_i = 0. - do ni = 1, ns_i - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - do k = 1, harvdata%num1Dfields() - m = ind1D(k) - data1D_i => harvdata%get1DFieldPtr( m ) - gharv_i(m) = gharv_i(m) + data1D_i(ni)*tgridmap%area_src(ni)* & - tdomain%mask(ni)*re**2 - end do - end do - - gharv_o(:) = 0. - garea_o = 0. - do no = 1,ns_o - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - do k = 1, harvdata%num1Dfields() - m = ind1D(k) - data1D_o => harvdata%get1DFieldPtr( m, output=.true. ) - gharv_o(m) = gharv_o(m) + data1D_o(no)*tgridmap%area_dst(no)* & - frac_dst(no)*re**2 - end do - end do - - ! Write out to diagnostic output file - ! - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Harvesting Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,1001) unit, unit -1001 format (1x,'harvest type ',20x,' input grid area',' output grid area',/ & - 1x,33x,' ',A,' ',A) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - do k = 1, harvdata%num1Dfields() - m = ind1D(k) - write (ndiag,1002) mkharvest_fieldname(m), gharv_i(m)*rat,gharv_o(m)*rat - end do -1002 format (1x,a35,f16.3,f17.3) - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - - else - - ! ----------------------------------------------------------------- - ! Otherwise override the harvesting with the input harvest values - ! ----------------------------------------------------------------- - - if ( any(oride_harv == real_undef ) )then - write(6,*) subname, ' error some override harvesting fields set ', & - 'and others are not = ', oride_harv - call shr_sys_abort() - end if - do k = 1, harvdata%num1Dfields() - m = ind1D(k) - if ( oride_harv(m) < 0.0_r8 .or. oride_harv(m) > 100.0_r8 )then - write(6,*) subname, ' error override harvesting field out of range', & - oride_harv(m), ' field = ', mkharvest_fieldname(m) - call shr_sys_abort() - end if - end do - do no = 1,ns_o - do k = 1, harvdata%num1Dfields() - m = ind1D(k) - data1D_o => harvdata%get1DFieldPtr( m, output=.true. ) - data1D_o(no) = oride_harv(m) - end do - end do - - end if - - deallocate( ind1D, ind2D ) - write (6,*) 'Successfully made harvest and grazing' - write (6,*) - -end subroutine mkharvest - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest_parse_oride -! -! !INTERFACE: -subroutine mkharvest_parse_oride( string ) -! -! !DESCRIPTION: -! Parse the string with harvest and grazing information on it, to override -! the file with this information rather than reading from a file. -! -! !USES: - use shr_string_mod, only: shr_string_betweenTags -! !ARGUMENTS: - character(len=256), intent(IN) :: string ! String to parse with harvest and grazing data -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - integer :: rc ! error return code - character(len=256) :: substring ! substring between tags - character(len=*), parameter :: harv_start = "" - character(len=*), parameter :: harv_end = "" - character(len=*), parameter :: graz_start = "" - character(len=*), parameter :: graz_end = "" - character(len=*), parameter :: subname = 'mkharvest_parse_oride' -!----------------------------------------------------------------------- - call shr_string_betweenTags( string, harv_start, harv_end, substring, rc ) - if ( rc /= 0 )then - write(6,*) subname//'Trouble finding harvest start end tags' - call shr_sys_abort() - end if - read(substring,*) oride_harv(1:numharv-1) - call shr_string_betweenTags( string, graz_start, graz_end, substring, rc ) - if ( rc /= 0 )then - write(6,*) subname//'Trouble finding grazing start end tags' - call shr_sys_abort() - end if - read(substring,*) oride_harv(numharv) - if ( harvest_fieldnames(numharv) /= 'GRAZING' )then - write(6,*) subname, ' grazing is NOT last field as was expected' - call shr_sys_abort() - end if - -!----------------------------------------------------------------------- - -end subroutine mkharvest_parse_oride - -!----------------------------------------------------------------------- - end module mkharvestMod diff --git a/tools/mksurfdata_esmf/src/mkindexmapMod.F90 b/tools/mksurfdata_esmf/src/mkindexmapMod.F90 index fdb1ee9ef4..c6de73f9a1 100644 --- a/tools/mksurfdata_esmf/src/mkindexmapMod.F90 +++ b/tools/mksurfdata_esmf/src/mkindexmapMod.F90 @@ -3,10 +3,8 @@ module mkindexmapMod !----------------------------------------------------------------------- ! Module containing subroutines for making maps of index data. ! - ! This includes a routine for making a map using the dominant type among the input grid - ! cells making up a given output cell, as well as routines for using an index map as - ! indices into a lookup table, to essentially paint-by-number some other field, and some - ! other related routines + ! Includes routines for using an index map as indices into a lookup + ! table, to essentially paint-by-number some other field. ! ! WJS (2-1-12): There is a lookup_2d subroutine, but not a lookup_1d (or any other ! dimensionality). That is simply because I needed lookup_2d, but have not yet needed a @@ -33,8 +31,6 @@ module mkindexmapMod public :: dim_slice_type ! public member functions: - public :: get_dominant_indices ! make output map based on dominant type in each grid cell - public :: get_max_indices ! make output map based on maximum type in each grid cell public :: lookup_2d ! create map based on a 2-d lookup table public :: lookup_2d_netcdf ! wrapper to lookup_2d; first read table from netcdf file public :: which_max ! get index of the maximum value in an array @@ -43,158 +39,6 @@ module mkindexmapMod contains !------------------------------------------------------------------------------ - subroutine get_dominant_indices(factorindexlist, factorlist, & - src_array, dst_array, minval, maxval, nodata, filter) - ! - ! Fills an output array on the destination grid (dst_array) whose values are equal to the - ! (weighted) dominant value in the source grid cells overlapping a given destination grid - ! cell - ! - ! Ignores all values in src_array that are less than minval or greater than maxval (treats - ! those values the same as if they had wt=0). (Note: for memory-use efficiency, it is - ! best if the indices are designed such that most values between minval and maxval are - ! actually used, since an array is allocated of size (maxval - minval + 1)*gridmap%nb.) - ! - ! The filter argument can be used to exclude certain overlaps -- if provided, we only - ! consider overlaps where filter is .true. If not provided, filter is treated as being - ! .true. everywhere. - ! - ! Output grid cells with no contributing valid source points are given the nodata value - ! - ! input/output variables - integer , pointer :: factorindexlist(:,:) - real(r8) , pointer :: factorlist(:) - integer , intent(in) :: src_array(:) ! input values; length gridmap%na - integer , intent(out):: dst_array(:) ! output values; length gridmap%nb - integer , intent(in) :: minval ! minimum valid value in src_array - integer , intent(in) :: maxval ! maximum valid value in src_array - integer , intent(in) :: nodata ! value to assign to dst_array where there are no valid source points - logical, optional , intent(in) :: filter(:) ! only consider overlaps where filter is .true.; length gridmap%ns - - ! local variables - logical , allocatable :: lfilter(:) ! local version of filter - logical , allocatable :: hasdata(:) ! true if an output cell has any valid data; - real(r8), allocatable :: weights(:,:) ! summed weight of each index value for each output cell - integer :: n, ni, no - integer :: k - integer :: maxindex - real(r8) :: wt - real(r8) :: maxwt - integer :: ns_o - character(len=*), parameter :: subname = "get_dominant_indices" - !----------------------------------------------------------------------- - - ns_o = size(dst_array) - allocate(lfilter(ns_o)) - - if (present(filter)) then - if (size(filter) /= ns_o) then - write(6,*) subname//' ERROR: incorrect size of filter' - write(6,*) 'size(filter) = ', size(filter) - write(6,*) 'ns_o = ', ns_o - call shr_sys_abort() - end if - lfilter(:) = filter(:) - else - lfilter(:) = .true. - end if - - allocate(hasdata(ns_o)) - hasdata(:) = .false. - allocate(weights(minval:maxval, ns_o)) - weights(minval:maxval,:) = 0. - - ! Determine weight of each index value for each output (destination) cell - do n = 1, size(factorlist) - ni = factorIndexList(1,n) - no = factorIndexList(2,n) - wt = factorList(n) - k = src_array(ni) - if (k >= minval .and. k <= maxval) then - weights(k,no) = weights(k,no) + wt - hasdata(no) = .true. - end if - end do - - ! Determine output values - ! Note: if a given destination cell has no contributing source points (thus - ! hasdata(no) = false), or the max weight of any index overlapping this destination - ! cell is <= 0, then the output value there will be nodata. - ! (I don't think this latter condition -- weight <= 0 -- is possible, but we handle - ! it anyway) - - dst_array(:) = nodata - do no = 1, ns_o - if (hasdata(no)) then - call which_max(weights(:,no), maxwt, maxindex, lbound=minval) - if (maxwt > 0.) then - dst_array(no) = maxindex - end if - end if - end do - - deallocate(lfilter, weights, hasdata) - - end subroutine get_dominant_indices - - !------------------------------------------------------------------------------ - subroutine get_max_indices(factorindexlist, factorlist, src_array, dst_array, nodata) - ! - ! Fills an output array on the destination grid (dst_array) whose values are equal to - ! the maximum value in the source grid cells overlapping a given destination grid cell. - ! - ! The frequency of occurrence of the source values is irrelevant. For example, if the - ! value 1 appears in 99% of source cells overlapping a given destination cell and the - ! value 2 appears in just 1%, we'll put 2 in the destination cell because it is the - ! maximum value. - ! - ! Output grid cells with no contributing valid source points are given the nodata value - ! - ! input/output variables - integer , pointer :: factorindexlist(:,:) - integer , pointer :: factorlist(:) - integer , intent(in) :: src_array(:) ! input values - integer , intent(out) :: dst_array(:) ! output values - integer , intent(in) :: nodata ! value to assign to dst_array where there are no valid source points - - ! local variables: - logical, allocatable :: hasdata(:) ! true if an output cell has any valid data; - integer :: n, ni, no - real(r8) :: wt - integer :: src_val - integer :: ns_o - character(len=*), parameter :: subname = 'get_max_indices' - !----------------------------------------------------------------------- - - ! Initialize local variables - ns_o = size(dst_array) - allocate(hasdata(ns_o)) - hasdata(:) = .false. - - do n = 1, size(factorlist) - ni = factorIndexList(1,n) - no = factorIndexList(2,n) - wt = factorList(n) - if (wt > 0._r8) then - src_val = src_array(ni) - if (.not. hasdata(no)) then - hasdata(no) = .true. - dst_array(no) = src_val - else if (src_val > dst_array(no)) then - dst_array(no) = src_val - end if - end if - end do - - do no = 1, ns_o - if (.not. hasdata(no)) then - dst_array(no) = nodata - end if - end do - - end subroutine get_max_indices - - !------------------------------------------------------------------------------ subroutine lookup_2d(index1, index2, lookup_table, fill_val, data, ierr, & nodata, valid_entries, invalid_okay) ! @@ -392,18 +236,18 @@ subroutine lookup_2d_netcdf(pioid, tablename, lookup_has_invalid, & ! ! input/output variables type(file_desc_t) , intent(inout) :: pioid - character(len=*) , intent(in) :: tablename ! name of the lookup table variable - logical , intent(in) :: lookup_has_invalid ! should we use _FillValue? (see above) - character(len=*) , intent(in) :: dimname1 ! name of the first (fastest-varying) dimension of the lookup table - character(len=*) , intent(in) :: dimname2 ! name of the second dimension of the lookup table - integer , intent(in) :: n_extra_dims ! number of extra dimensions in the lookup table + character(len=*) , intent(in) :: tablename ! name of the lookup table variable + logical , intent(in) :: lookup_has_invalid ! should we use _FillValue? (see above) + character(len=*) , intent(in) :: dimname1 ! name of the first (fastest-varying) dimension of the lookup table + character(len=*) , intent(in) :: dimname2 ! name of the second dimension of the lookup table + integer , intent(in) :: n_extra_dims ! number of extra dimensions in the lookup table ! The following arguments are passed directly to lookup_2d: - integer , intent(in) :: index1(:) ! index into dim 1 of lookup table - integer , intent(in) :: index2(:) ! index into dim 2 of lookup table - real(r8) , intent(in) :: fill_val ! value to put in data where we don't have a valid value - real(r8) , intent(out) :: data(:) ! output array - integer , intent(out) :: ierr ! error return code from the call to lookup_2d + integer , intent(in) :: index1(:) ! index into dim 1 of lookup table + integer , intent(in) :: index2(:) ! index into dim 2 of lookup table + real(r8) , intent(in) :: fill_val ! value to put in data where we don't have a valid value + real(r8) , intent(out) :: data(:) ! output array + integer , intent(out) :: ierr ! error return code from the call to lookup_2d ! slice to use if lookup table variable has more than 2 dimensions: type(dim_slice_type), intent(in), optional :: extra_dims(:) @@ -478,11 +322,23 @@ subroutine lookup_2d_netcdf(pioid, tablename, lookup_has_invalid, & call check_dimsize(dimlens(2+i), extra_dims(i)%val, 2+i) end do + ! Read the lookup table; if the given variable has more than 2 dimensions, we read + ! a single 2-d slice + + allocate(starts(ndims), counts(ndims)) allocate(lookup_table(dimlens(1), dimlens(2))) - rcode = pio_get_var(pioid, pio_varid, lookup_table) + starts(1:2) = 1 + counts(1:2) = dimlens(1:2) + do i = 1, n_extra_dims + starts(2+i) = extra_dims(i)%val + counts(2+i) = 1 + end do + rcode = pio_get_var(pioid, pio_varid, starts, counts, lookup_table) - ! Determine which entries are valid + !allocate(lookup_table(dimlens(1), dimlens(2))) + !rcode = pio_get_var(pioid, pio_varid, lookup_table) + ! Determine which entries are valid allocate(valid_entries(size(lookup_table, 1), size(lookup_table, 2))) valid_entries(:,:) = .true. if (lookup_has_invalid) then @@ -542,31 +398,26 @@ end subroutine lookup_2d_netcdf subroutine which_max(arr, maxval, maxindex, lbound) ! ! Returns maximum value in arr along with the index of the maximum value - ! ! If multiple values are tied, returns index of the first maximum ! - ! !ARGUMENTS: + ! input/output variables real(r8), intent(in) :: arr(:) real(r8), intent(out):: maxval ! maximum value in arr(:) integer , intent(out):: maxindex ! first index of maxval - - ! lower bound of indices of arr; if not supplied, assumed to be 1: - integer , intent(in), optional :: lbound - - ! !LOCAL VARIABLES: + integer , intent(in), optional :: lbound ! lower bound of indices of arr; + ! if not supplied, assumed to be 1: + ! local variables integer :: i !----------------------------------------------------------------------- maxindex = 1 maxval = arr(1) - do i = 2, size(arr) if (arr(i) > maxval) then maxindex = i maxval = arr(i) end if end do - if (present(lbound)) then maxindex = maxindex + (lbound - 1) end if diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index b0eaca615c..a792d4a53d 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -596,8 +596,7 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) end if end if else - ! Assume that can have (lon,lat), (lon,lat,lev), (lon,lat,time), (lon,lat,lev,time) - ! Where lev would correspond to an undistributed dimension in esmf + ! Assume that can have (lon,lat), (lon,lat,lev1), (lon,lat,lev1,lev2), (lon,lat,time) or (lon,lat,lev1,time) if (ndims == 2) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) else if (ndims == 3) then @@ -610,7 +609,7 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) if (trim(dimname) == 'time') then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) else - call shr_sys_abort('for lon/lat support up to 3 spatial dims plus a time dim') + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3),dimlens(4)/), compdof3d, pio_iodesc) end if end if end if diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 8b3c2551d9..097501589a 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -222,10 +222,6 @@ program mksurfdata logical :: create_esmf_pet_files = .true. character(len=32) :: subname = 'mksrfdata' ! program name - ! NOTE(bja, 2015-01) added to work around a ?bug? causing 1x1_urbanc_alpha to abort. See - !/glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 - logical :: urban_skip_abort_on_invalid_data_check - character(len=*) , parameter :: u_FILE_u = & __FILE__ ! ------------------------------------------------------------ @@ -410,9 +406,11 @@ program mksurfdata ! call mkharvest( mapfname=map_fharvest, datfname=mksrf_fhrvtyp, ndiag=ndiag, harvdata=harvdata ) ! end if + ! -------------------------------------------------- + ! begin working + ! Make urban fraction [pcturb] from [furban] dataset - call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, & - zero_out=all_veg, urbn_o=pcturb, urban_classes_o=urban_classes, region_o=urban_region, rc=rc) + call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, all_veg, pcturb, urban_classes, urban_region, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') ! Make soil color classes [soicol] [fsoicol] @@ -424,14 +422,16 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] - ! zero_out_lake = all_urban .or. all_veg - ! zero_out_wetland = all_urban .or. all_veg .or. no_inlandwet - ! call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & - ! zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') - ! call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) + zero_out_lake = all_urban .or. all_veg + zero_out_wetland = all_urban .or. all_veg .or. no_inlandwet + call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & + zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') + call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) + + ! end working + ! -------------------------------------------------- -#ifdef TODO ! ! Make glacier fraction [pctgla] from [fglacier] dataset ! call mkglacier ( mapfname=map_fglacier, datfname=mksrf_fglacier, ndiag=ndiag, zero_out=all_urban.or.all_veg, glac_o=pctgla) @@ -457,9 +457,7 @@ program mksurfdata ! ! Make agricultural fire peak month data [abm] from [abm] ! call mkagfirepkmon ( mapfname=map_fabm, datfname=mksrf_fabm, ndiag=ndiag, agfirepkmon_o=agfirepkmon) -#endif -#ifdef TODO ! ! Make elevation [elev] from [ftopo, ffrac] dataset ! ! Used only to screen pcturb, screen pcturb by elevation threshold from elev dataset ! if ( .not. all_urban .and. .not. all_veg )then @@ -493,7 +491,6 @@ program mksurfdata ! ! Do landuse changes such as for the poles, etc. ! call change_landuse( dynpft=.false. ) -#endif ! ---------------------------------------------------------------------- ! Modify interpolated fields based on additional constrants @@ -505,7 +502,6 @@ program mksurfdata end do call ESMF_LogWrite("After fixes", ESMF_LOGMSG_INFO) -#ifdef TODO ! do n = 1,lsize_o ! ! Truncate all percentage fields on output grid. This is needed to ! ! insure that wt is zero (not a very small number such as @@ -582,10 +578,9 @@ program mksurfdata ! enddo ! write(6,*) - ! ! Make final values of percent urban by class - ! ! This call needs to occur after all corrections are made to pcturb - - ! call normalize_classes_by_gcell(urban_classes, pcturb, urban_classes_g) + ! Make final values of percent urban by class + ! This call needs to occur after all corrections are made to pcturb + call normalize_classes_by_gcell(urban_classes, pcturb, urban_classes_g) ! ! ---------------------------------------------------------------------- ! ! Make glacier multiple elevation classes [pctglcmec,topoglcmec] from [fglacier] dataset @@ -615,7 +610,6 @@ program mksurfdata ! do n = 1,lsize_o ! landfrac_pft(n) = pctlnd_pft(n)/100._r8 ! end do -#endif ! ---------------------------------------------------------------------- ! Create surface dataset @@ -642,8 +636,8 @@ program mksurfdata call ESMF_LogWrite("Calling mkfile_fsurdat", ESMF_LOGMSG_INFO) call mkfile_fsurdat( mksrf_fgrid_mesh_nx, mksrf_fgrid_mesh_ny, mesh_model, dynlanduse=.false., & pctlak=pctlak, pctwet=pctwet, lakedepth=lakedepth, organic=organic, & - urban_classes=urban_classes, urban_region=urban_region, & - soil_color=soil_color, nsoilcol=nsoilcol) + soil_color=soil_color, nsoilcol=nsoilcol, & + urban_classes_g=urban_classes_g, urban_region=urban_region) call ESMF_LogWrite(subname//'successfully created file '//trim(fsurdat), ESMF_LOGMSG_INFO) end if ! if (fsurdat /= ' ') diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 3829bf14cd..dddf8533af 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -79,13 +79,13 @@ end subroutine mkurbanInit !=============================================================== subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & - zero_out, urbn_o, urban_classes_o, region_o, rc) + zero_out, pcturb_o, urban_classes_o, region_o, rc) ! ! make total percent urban, breakdown into urban classes, and region ID on the output grid ! ! urban_classes_o(n, i) gives the percent of the urban area in grid cell n that is in class #i. ! This is normalized so that sum(urban_classes_o(n,:)) = 100 for all n, even for grid - ! cells where urbn_o(n) = 0 (in the case where urbn_o(n) = 0, we come up with an + ! cells where pcturb_o(n) = 0 (in the case where pcturb_o(n) = 0, we come up with an ! arbitrary assignment of urban into the different classes). ! ! See comments under the normalize_urbn_by_tot subroutine for how urban_classes_o is @@ -98,19 +98,16 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & ! better, in terms of maintaining helpful abstractions, there could be a new type to ! handle urban, and both that and pct_pft_type could be build on a single set of shared ! code - either as a single base class or through a "has-a" mechanism). This would allow - ! us to combine urbn_o and urban_classes_o into a single derived type variable. I think + ! us to combine pcturb_o and urban_classes_o into a single derived type variable. I think ! this would also replace the use of normalize_classes_by_gcell, and maybe some other ! urban-specific code. ! - use mkindexmapMod , only : get_dominant_indices -#ifdef TODO - use mkurbanparCommonMod , only : mkurban_pct_diagnostics -#endif use mkurbanparCommonMod , only : MIN_DENS use mkutilsMod , only : normalize_classes_by_gcell use mkvarctl , only : all_urban use mkvarpar #ifdef TODO + use mkurbanparCommonMod , only : mkurban_pct_diagnostics use mkdiagnosticsMod , only : output_diagnostics_index #endif @@ -119,7 +116,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh logical , intent(in) :: zero_out ! if should zero urban out - real(r8) , intent(out) :: urbn_o(:) ! output grid: total % urban + real(r8) , intent(out) :: pcturb_o(:) ! output grid: total % urban real(r8) , intent(out) :: urban_classes_o(:,:) ! output grid: breakdown of total urban into each class integer , intent(inout) :: region_o(:) ! output grid: region ID integer , intent(out) :: rc @@ -178,7 +175,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & if (ier/=0) call shr_sys_abort() ! Determine ns_o and allocate data_o - ns_o = size(urbn_o) + ns_o = size(pcturb_o) if (ier/=0) call shr_sys_abort() allocate(data_o(numurbl,ns_o),stat=ier) if (ier/=0) call shr_sys_abort() @@ -213,7 +210,6 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & if (chkerr(rc,__LINE__,u_FILE_u)) return call regrid_rawdata(mesh_i, mesh_o, routehandle, frac_i, frac_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(frac_i) ! Area-average percent cover on input grid to output grid and correct according to frac_o ! Note that percent cover is in terms of total grid area. @@ -225,13 +221,13 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & end if end do do n = 1, ns_o - urbn_o(n) = sum(urban_classes_gcell_o(n,:)) + pcturb_o(n) = sum(urban_classes_gcell_o(n,:)) end do ! Check for conservation do no = 1, ns_o - if ((urbn_o(no)) > 100.000001_r8) then - write (6,'(a,d13.5,a,i8)') trim(subname)//' error: percent urban = ',urbn_o(no), & + if ((pcturb_o(no)) > 100.000001_r8) then + write (6,'(a,d13.5,a,i8)') trim(subname)//' error: percent urban = ',pcturb_o(no), & ' greater than 100.000001 for no = ',no call shr_sys_abort() end if @@ -240,31 +236,31 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & ! Determine urban_classes_o ! Make percent urban on output grid, given percent urban on input grid ! This assumes that we're neither using all_urban or zero_out - ! Determine urbn_o on ouput grid: - call normalize_urbn_by_tot(urban_classes_gcell_o, urbn_o, urban_classes_o) + ! Determine pcturb_o on ouput grid: + call normalize_urbn_by_tot(urban_classes_gcell_o, pcturb_o, urban_classes_o) call ESMF_LogWrite("After normalize_urbn", ESMF_LOGMSG_INFO) ! Handle special cases ! Note that, for all these adjustments of total urban %, we do not change the breakdown - ! into the different urban classes. In particular: when urbn_o is set to 0 for a point, + ! into the different urban classes. In particular: when pcturb_o is set to 0 for a point, ! the breakdown into the different urban classes is maintained as it was before. if (all_urban) then - urbn_o(:) = 100._r8 + pcturb_o(:) = 100._r8 else if (zero_out) then - urbn_o(:) = 0._r8 + pcturb_o(:) = 0._r8 else ! Set points to 0% if they fall below a given threshold do no = 1, ns_o - if (urbn_o(no) < MIN_DENS) then - urbn_o(no) = 0._r8 + if (pcturb_o(no) < MIN_DENS) then + pcturb_o(no) = 0._r8 end if end do end if ! Print diagnostics ! TODO: call to mkurban_pct_diagnostics has to be rewritten - ! First, recompute urban_classes_gcell_o, based on any changes we have made to urbn_o - ! call normalize_classes_by_gcell(urban_classes_o, urbn_o, urban_classes_gcell_o) + ! First, recompute urban_classes_gcell_o, based on any changes we have made to pcturb_o + ! call normalize_classes_by_gcell(urban_classes_o, pcturb_o, urban_classes_gcell_o) ! do k = 1, numurbl ! call mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, & ! urban_classes_gcell_i(:,k), urban_classes_gcell_o(:,k), & @@ -301,11 +297,12 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & do l = 1,max_regions do n = 1,ns_i if (region_i(n) == l) then - !data_i(l,n) = 1._r8 * mask_i(n) ! TODO: - data_i(l,n) = 1._r8 + data_i(l,n) = 1._r8 * frac_i(n) + !data_i(l,n) = 1._r8 end if end do end do + deallocate(frac_i) ! Regrid data_i to data_o if (allocated(data_o)) deallocate(data_o) @@ -315,20 +312,13 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Now find dominant region in each output gridcell - this is identical to the maximum index + region_o(:) = 0 do n = 1,ns_o max_index = maxloc(data_o(:,n)) - region_o(n) = max_index(1) + if (data_o(max_index(1),n) > 0._r8) then + region_o(n) = max_index(1) + end if end do - ! do n = 1,ns_o - ! maxindex = 1 - ! maxval = data_o(1,n) - ! do l = 2, max_regions - ! if (data_o(l,n) > maxval) then - ! maxindex = l - ! maxval = data_o(l,n) - ! end if - ! end do - ! end do if (root_task) then write (ndiag,'(a)') 'Successfully made urban region' @@ -443,7 +433,7 @@ subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) end subroutine normalize_urbn_by_tot !=============================================================== - subroutine mkurbanpar(datfname_i, mesh_o, & + subroutine mkurbanpar(pioid_o, datfname_i, mesh_o, & region_o, urban_classes_gcell_o, urban_skip_abort_on_invalid_data_check) ! ! Make Urban Parameter data @@ -460,11 +450,12 @@ subroutine mkurbanpar(datfname_i, mesh_o, & use mkvarpar ! input/output variables - character(len=*) , intent(in) :: datfname_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh - integer , intent(in) :: region_o(:) ! output grid: region ID (length: ns_o) + type(file_desc_t) , intent(inout) :: pioid_o + character(len=*) , intent(in) :: datfname_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh + integer , intent(in) :: region_o(:) ! output grid: region ID (length: ns_o) real(r8) , intent(in) :: urban_classes_gcell_o(:,:) ! output grid: percent urban in each density class - ! (% of total grid cell area) (dimensions: ns_o, numurbl) + ! (% of total grid cell area) (dimensions: ns_o, numurbl) logical , intent(in) :: urban_skip_abort_on_invalid_data_check ! local variables @@ -474,23 +465,24 @@ subroutine mkurbanpar(datfname_i, mesh_o, & real(r8) :: fill_val ! value to put where we have no data in output logical :: check_invalid ! should we check whether there are any invalid data in the output? end type param - real(r8), allocatable :: data_scalar_o(:,:) ! output array for parameters with no extra dimensions - real(r8), allocatable :: data_rad_o(:,:,:,:) ! output array for parameters dimensioned by numrad & numsolar - real(r8), allocatable :: data_levurb_o(:,:,:) ! output array for parameters dimensioned by nlevurb - integer , allocatable :: unity_dens_o(:,:) ! artificial density indices - integer :: nlevurb_i ! input grid: number of urban vertical levels - integer :: numsolar_i ! input grid: number of solar type (DIR/DIF) - integer :: numrad_i ! input grid: number of solar bands (VIS/NIR) - integer :: m,n,no,ns_o,p,k ! indices - type(file_desc_t) :: pioid_i - type(file_desc_t) :: pioid_o - type(var_desc_t) :: pio_varid - integer :: pio_vartype - type(io_desc_t) :: pio_iodesc - integer :: dimid - integer :: ier, rcode, rc ! error status - character(len=cs) :: varname ! variable name - integer :: xtype ! external type + integer , allocatable :: idata_scalar_o(:,:) ! output array for parameters with no extra dimensions + real(r8), allocatable :: data_scalar_o(:,:) ! output array for parameters with no extra dimensions + real(r8), allocatable :: data_rad_o(:,:,:,:) ! output array for parameters dimensioned by numrad & numsolar + real(r8), allocatable :: data_levurb_o(:,:,:) ! output array for parameters dimensioned by nlevurb + integer , allocatable :: unity_dens_o(:,:) ! artificial density indices + integer :: nlevurb_i ! input grid: number of urban vertical levels + integer :: numsolar_i ! input grid: number of solar type (DIR/DIF) + integer :: numrad_i ! input grid: number of solar bands (VIS/NIR) + integer :: m,n,no,ns_o,p,k ! indices + type(file_desc_t) :: pioid_i + type(var_desc_t) :: pio_varid + type(io_desc_t) :: pio_iodesc + integer :: pio_vartype + integer :: dimid + integer :: ier, rcode, rc ! error status + character(len=cs) :: varname ! variable name + integer :: xtype ! external type + ! information on extra dimensions for lookup tables greater than 2-d: type(dim_slice_type), allocatable :: extra_dims(:) @@ -544,11 +536,12 @@ subroutine mkurbanpar(datfname_i, mesh_o, & param('CV_IMPROAD', fill_val_real, .false.), & ! 5 param('TK_IMPROAD', fill_val_real, .false.) /) ! 6 - character(len=*), parameter :: subname = 'mkurbanpar' !----------------------------------------------------------------------- - write (6,*) 'Attempting to make Urban Parameters .....' + if (root_task) then + write (ndiag,'(a)') 'Attempting to make Urban Parameters .....' + end if ! Determine & error-check array sizes ns_o = size(region_o) @@ -564,7 +557,6 @@ subroutine mkurbanpar(datfname_i, mesh_o, & write(6,*) 'numurbl = ', numurbl end if - ! Read dimensions from input file if (root_task) then write (ndiag,'(a)') 'Opening input urban parameter file: '//trim(datfname_i) @@ -604,123 +596,97 @@ subroutine mkurbanpar(datfname_i, mesh_o, & unity_dens_o(:,k) = k end do - ! Open output file (this will go into define mode) - call mkpio_wopen(trim(fsurdat), clobber=.false., pioid=pioid_o) - if ( outnc_double ) then xtype = PIO_DOUBLE else xtype = PIO_REAL end if - ! Define urbanoutput variables + ! Put output file back in define mode and define urban parameter output variables + rcode = pio_redef(pioid_o) + + rcode = pio_def_dim(pioid_o, 'numrad' , numrad, dimid) + call mkpio_def_spatial_var(pioid_o, varname='CANYON_HWR', xtype=xtype, & - lev1name='numurbl', & - long_name='canyon height to width ratio', units='unitless') + lev1name='numurbl', long_name='canyon height to width ratio', units='unitless') call mkpio_def_spatial_var(pioid_o, varname='EM_IMPROAD', xtype=xtype, & - lev1name='numurbl', & - long_name='emissivity of impervious road', units='unitless') + lev1name='numurbl', long_name='emissivity of impervious road', units='unitless') call mkpio_def_spatial_var(pioid_o, varname='EM_PERROAD', xtype=xtype, & - lev1name='numurbl', & - long_name='emissivity of pervious road', units='unitless') + lev1name='numurbl', long_name='emissivity of pervious road', units='unitless') call mkpio_def_spatial_var(pioid_o, varname='EM_ROOF', xtype=xtype, & - lev1name='numurbl', & - long_name='emissivity of roof', units='unitless') + lev1name='numurbl', long_name='emissivity of roof', units='unitless') call mkpio_def_spatial_var(pioid_o, varname='EM_WALL', xtype=xtype, & - lev1name='numurbl', & - long_name='emissivity of wall', units='unitless') + lev1name='numurbl', long_name='emissivity of wall', units='unitless') call mkpio_def_spatial_var(pioid_o, varname='HT_ROOF', xtype=xtype, & - lev1name='numurbl', & - long_name='height of roof', units='meters') + lev1name='numurbl', long_name='height of roof', units='meters') call mkpio_def_spatial_var(pioid_o, varname='THICK_ROOF', xtype=xtype, & - lev1name='numurbl', & - long_name='thickness of roof', units='meters') + lev1name='numurbl', long_name='thickness of roof', units='meters') call mkpio_def_spatial_var(pioid_o, varname='THICK_WALL', xtype=xtype, & - lev1name='numurbl', & - long_name='thickness of wall', units='meters') + lev1name='numurbl', long_name='thickness of wall', units='meters') call mkpio_def_spatial_var(pioid_o, varname='T_BUILDING_MIN', xtype=xtype, & - lev1name='numurbl', & - long_name='minimum interior building temperature', units='K') + lev1name='numurbl', long_name='minimum interior building temperature', units='K') call mkpio_def_spatial_var(pioid_o, varname='WIND_HGT_CANYON', xtype=xtype, & - lev1name='numurbl', & - long_name='height of wind in canyon', units='meters') + lev1name='numurbl', long_name='height of wind in canyon', units='meters') call mkpio_def_spatial_var(pioid_o, varname='WTLUNIT_ROOF', xtype=xtype, & - lev1name='numurbl', & - long_name='fraction of roof', units='unitless') + lev1name='numurbl', long_name='fraction of roof', units='unitless') call mkpio_def_spatial_var(pioid_o, varname='WTROAD_PERV', xtype=xtype, & - lev1name='numurbl', & - long_name='fraction of pervious road', units='unitless') + lev1name='numurbl', long_name='fraction of pervious road', units='unitless') call mkpio_def_spatial_var(pioid_o, varname='ALB_IMPROAD_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='direct albedo of impervious road', units='unitless') + lev1name='numurbl', lev2name='numrad', long_name='direct albedo of impervious road', units='unitless') call mkpio_def_spatial_var(pioid_o, varname='ALB_IMPROAD_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='diffuse albedo of impervious road', units='unitless') + lev1name='numurbl', lev2name='numrad', long_name='diffuse albedo of impervious road', units='unitless') call mkpio_def_spatial_var(pioid_o, varname='ALB_PERROAD_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='direct albedo of pervious road', units='unitless') + lev1name='numurbl', lev2name='numrad', long_name='direct albedo of pervious road', units='unitless') call mkpio_def_spatial_var(pioid_o, varname='ALB_PERROAD_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='diffuse albedo of pervious road', units='unitless') + lev1name='numurbl', lev2name='numrad', long_name='diffuse albedo of pervious road', units='unitless') call mkpio_def_spatial_var(pioid_o, varname='ALB_ROOF_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='direct albedo of roof', units='unitless') + lev1name='numurbl', lev2name='numrad', long_name='direct albedo of roof', units='unitless') call mkpio_def_spatial_var(pioid_o, varname='ALB_ROOF_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='diffuse albedo of roof', units='unitless') + lev1name='numurbl', lev2name='numrad', long_name='diffuse albedo of roof', units='unitless') call mkpio_def_spatial_var(pioid_o, varname='ALB_WALL_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='direct albedo of wall', units='unitless') + lev1name='numurbl', lev2name='numrad', long_name='direct albedo of wall', units='unitless') call mkpio_def_spatial_var(pioid_o, varname='ALB_WALL_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='diffuse albedo of wall', units='unitless') + lev1name='numurbl', lev2name='numrad', long_name='diffuse albedo of wall', units='unitless') call mkpio_def_spatial_var(pioid_o, varname='TK_ROOF', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='thermal conductivity of roof', units='W/m*K') + lev1name='numurbl', lev2name='nlevurb', long_name='thermal conductivity of roof', units='W/m*K') call mkpio_def_spatial_var(pioid_o, varname='TK_WALL', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='thermal conductivity of wall', units='W/m*K') + lev1name='numurbl', lev2name='nlevurb', long_name='thermal conductivity of wall', units='W/m*K') call mkpio_def_spatial_var(pioid_o, varname='TK_IMPROAD', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='thermal conductivity of impervious road', units='W/m*K') + lev1name='numurbl', lev2name='nlevurb', long_name='thermal conductivity of impervious road', units='W/m*K') call mkpio_def_spatial_var(pioid_o, varname='CV_ROOF', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='volumetric heat capacity of roof', units='J/m^3*K') + lev1name='numurbl', lev2name='nlevurb', long_name='volumetric heat capacity of roof', units='J/m^3*K') call mkpio_def_spatial_var(pioid_o, varname='CV_WALL', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='volumetric heat capacity of wall', units='J/m^3*K') + lev1name='numurbl', lev2name='nlevurb', long_name='volumetric heat capacity of wall', units='J/m^3*K') call mkpio_def_spatial_var(pioid_o, varname='CV_IMPROAD', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='volumetric heat capacity of impervious road', units='J/m^3*K') + lev1name='numurbl', lev2name='nlevurb', long_name='volumetric heat capacity of impervious road', units='J/m^3*K') call mkpio_def_spatial_var(pioid_o, varname='NLEV_IMPROAD', xtype=PIO_INT, & - lev1name='numurbl', & - long_name='number of impervious road layers', units='unitless') + lev1name='numurbl', long_name='number of impervious road layers', units='unitless') ! End define model rcode = pio_enddef(pioid_o) @@ -728,99 +694,92 @@ subroutine mkurbanpar(datfname_i, mesh_o, & ! ------------------------------------------------ ! Handle urban parameters with no extra dimensions ! ------------------------------------------------ + + allocate(data_scalar_o(ns_o, numurbl), stat=ier) + data_scalar_o(:,:) = 0._r8 + if (ier /= 0) call shr_sys_abort('mkurbanpar allocation error') + + do p = 1, size(params_scalar) + ! get variable output (data_scalar_o) + call lookup_and_check_err(pioid_i, params_scalar(p)%name, params_scalar(p)%fill_val, & + params_scalar(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & + data_scalar_o, n_extra_dims = 0) + + ! get io descriptor for variable output, write out variable and free memory for io descriptor + call mkpio_iodesc_output(pioid_o, mesh_o, params_scalar(p)%name, pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//& + trim(params_scalar(p)%name)) + rcode = pio_inq_varid(pioid_o, params_scalar(p)%name, pio_varid) + rcode = pio_inq_vartype(pioid_o, pio_varid, pio_vartype) + if (pio_vartype == PIO_INT) then + allocate(idata_scalar_o(ns_o, numurbl)) + idata_scalar_o(:,:) = int(data_scalar_o) + call pio_write_darray(pioid_o, pio_varid, pio_iodesc, idata_scalar_o(:,:), rcode) + deallocate(idata_scalar_o) + else + call pio_write_darray(pioid_o, pio_varid, pio_iodesc, data_scalar_o(:,:), rcode) + end if + call pio_freedecomp(pioid_o, pio_iodesc) + end do + + deallocate(data_scalar_o) + + ! ------------------------------------------------ + ! Handle urban parameters dimensioned by numrad & numsolar + ! ------------------------------------------------ - allocate(data_scalar_o(ns_o, numurbl), stat=ier) - if (ier /= 0) then - write(6,*)'mkurbanpar allocation error'; call shr_sys_abort() - end if - - do p = 1, size(params_scalar) - ! get variable output (data_scalar_o) - call lookup_and_check_err(pioid_i, params_scalar(p)%name, params_scalar(p)%fill_val, & - params_scalar(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & - data_scalar_o, 0) - - ! get io descriptor for variable output - call mkpio_iodesc_output(pioid_o, mesh_o, params_scalar(p)%name, pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//& - trim(params_scalar(p)%name)) - - ! write out variable - rcode = pio_inq_varid(pioid_o, params_scalar(p)%name, pio_varid) - call pio_write_darray(pioid_o, pio_varid, pio_iodesc, data_scalar_o(:,:), rcode) - - ! Free memory for io descriptor - call pio_freedecomp(pioid_o, pio_iodesc) - end do - - deallocate(data_scalar_o) - - ! ------------------------------------------------ - ! Handle urban parameters with no extra dimensions - ! ------------------------------------------------ - - ! Handle urban parameters dimensioned by numrad & numsolar - - allocate(data_rad_o(ns_o, numurbl, numrad, numsolar), stat=ier) - if (ier /= 0) then - write(6,*)'mkurbanpar allocation error'; call shr_sys_abort() - end if - - allocate(extra_dims(2)) - extra_dims(1)%name = 'numrad' - extra_dims(2)%name = 'numsolar' - - do p = 1, size(params_rad) - - ! Get variable output (data_rad_o) - do m = 1,numsolar - extra_dims(2)%val = m - do n = 1,numrad - extra_dims(1)%val = n - call lookup_and_check_err(pioid_i, params_rad(p)%name, params_rad(p)%fill_val, & - params_rad(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & - data_rad_o(:,:,n,m), 2, extra_dims) - end do - end do + allocate(data_rad_o(ns_o, numurbl, numrad, numsolar), stat=ier) + if (ier /= 0) call shr_sys_abort('mkurbanpar allocation error for data_rad_o') - ! Special handling of numsolar: rather than outputting variables with a numsolar - ! dimension, we output separate variables for each value of numsolar - do m = 1,numsolar - if (len_trim(params_rad(p)%name) + len_trim(solar_suffix(m)) > len(varname)) then - write(6,*) 'variable name exceeds length of varname' - write(6,*) trim(params_rad(p)%name)//trim(solar_suffix(m)) - call shr_sys_abort() - end if + allocate(extra_dims(2)) + extra_dims(1)%name = 'numrad' + extra_dims(2)%name = 'numsolar' + + do p = 1, size(params_rad) - ! Determine variable name - varname = trim(params_rad(p)%name)//trim(solar_suffix(m)) + ! Get variable output (data_rad_o) + do m = 1,numsolar + extra_dims(2)%val = m + do n = 1,numrad + extra_dims(1)%val = n + call lookup_and_check_err(pioid_i, params_rad(p)%name, params_rad(p)%fill_val, & + params_rad(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & + data_rad_o(:,:,n,m), n_extra_dims=2, extra_dims=extra_dims) + end do + end do - ! get io descriptor for variable output - call mkpio_iodesc_output(pioid_o, mesh_o, varname, pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//& - trim(params_scalar(p)%name)) + ! Special handling of numsolar: rather than outputting variables with a numsolar + ! dimension, we output separate variables for each value of numsolar + do m = 1,numsolar + if (len_trim(params_rad(p)%name) + len_trim(solar_suffix(m)) > len(varname)) then + write(6,*) 'variable name exceeds length of varname' + write(6,*) trim(params_rad(p)%name)//trim(solar_suffix(m)) + call shr_sys_abort() + end if - ! write out variable - rcode = pio_inq_varid(pioid_o, varname, pio_varid) - call pio_write_darray(pioid_o, pio_varid, pio_iodesc, data_rad_o(:,:,:,m), rcode) + ! Determine variable name + varname = trim(params_rad(p)%name)//trim(solar_suffix(m)) - ! Free memory for io descriptor - call pio_freedecomp(pioid_o, pio_iodesc) - end do + ! get io descriptor for variable output, write out variable and free memory for io descriptor + call mkpio_iodesc_output(pioid_o, mesh_o, varname, pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//& + trim(params_scalar(p)%name)) + rcode = pio_inq_varid(pioid_o, varname, pio_varid) + call pio_write_darray(pioid_o, pio_varid, pio_iodesc, data_rad_o(:,:,:,m), rcode) + call pio_freedecomp(pioid_o, pio_iodesc) + end do - end do + end do - deallocate(data_rad_o) - deallocate(extra_dims) + deallocate(data_rad_o) + deallocate(extra_dims) ! ------------------------------------------------ ! Handle urban parameters dimensioned by nlevurb ! ------------------------------------------------ allocate(data_levurb_o(ns_o, numurbl, nlevurb), stat=ier) - if (ier /= 0) then - write(6,*)'mkurbanpar allocation error'; call shr_sys_abort() - end if + if (ier /= 0) call shr_sys_abort('mkurbanpar allocation error for data_levurb_o') allocate(extra_dims(1)) extra_dims(1)%name = 'nlevurb' @@ -830,28 +789,24 @@ subroutine mkurbanpar(datfname_i, mesh_o, & extra_dims(1)%val = n call lookup_and_check_err(pioid_i, params_levurb(p)%name, params_levurb(p)%fill_val, & params_levurb(p)%check_invalid, & - urban_skip_abort_on_invalid_data_check, data_levurb_o(:,:,n), 1, extra_dims) + urban_skip_abort_on_invalid_data_check, data_levurb_o(:,:,n), & + n_extra_dims=1, extra_dims=extra_dims) end do - ! get io descriptor for variable output + ! get io descriptor for variable output, write out variable and free memory for io descriptor call mkpio_iodesc_output(pioid_o, mesh_o, params_levurb(p)%name, pio_iodesc, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//& trim(params_levurb(p)%name)) - - ! write out variable rcode = pio_inq_varid(pioid_o, params_levurb(p)%name, pio_varid) call pio_write_darray(pioid_o, pio_varid, pio_iodesc, data_levurb_o(:,:,:), rcode) - - ! Free memory for io descriptor call pio_freedecomp(pioid_o, pio_iodesc) end do deallocate(data_levurb_o) deallocate(extra_dims) - ! Close input data file and output surface dataset + ! Close input data file call pio_closefile(pioid_i) - call pio_closefile(pioid_o) if (root_task) then write (ndiag,'(a)') 'Successfully made Urban Parameters' @@ -861,6 +816,7 @@ subroutine mkurbanpar(datfname_i, mesh_o, & deallocate(unity_dens_o) contains + !------------------------------------------------------------------------------ subroutine lookup_and_check_err(pioid, varname, fill_val, check_invalid, & urban_skip_abort_on_invalid_data_check, data, n_extra_dims, extra_dims) diff --git a/tools/mksurfdata_esmf/src/mkutilsMod.F90 b/tools/mksurfdata_esmf/src/mkutilsMod.F90 index 8c5cbf8c22..ae6daaaa8f 100644 --- a/tools/mksurfdata_esmf/src/mkutilsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkutilsMod.F90 @@ -47,12 +47,12 @@ subroutine normalize_classes_by_gcell(classes_pct_tot, sums, classes_pct_gcell) ! classes_pct_gcell(n,i) will give the % of the total area of grid cell n that is in urban ! class #i. ! - ! !ARGUMENTS: - real(r4), intent(in) :: classes_pct_tot(:,:) ! % cover of classes as % of total - real(r4), intent(in) :: sums(:) ! totals, as % of grid cell - real(r4), intent(out):: classes_pct_gcell(:,:) ! % cover of classes as % of grid cell + ! input/output variables + real(r8), intent(in) :: classes_pct_tot(:,:) ! % cover of classes as % of total + real(r8), intent(in) :: sums(:) ! totals, as % of grid cell + real(r8), intent(out):: classes_pct_gcell(:,:) ! % cover of classes as % of grid cell ! - ! !LOCAL VARIABLES: + ! local variables integer :: n, n_max character(len=*), parameter :: subname = "normalize_classes_by_gcell" !------------------------------------------------------------------------------ diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index 38599e0aeb..7c323a694f 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -53,7 +53,7 @@ module mkvarctl ! NOTE(bja, 2015-01) added to work around a ?bug? causing 1x1_urbanc_alpha to abort. See !/glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 - logical :: urban_skip_abort_on_invalid_data_check + logical, public :: urban_skip_abort_on_invalid_data_check logical, public :: outnc_large_files ! output files in 64-bit format for large files logical, public :: outnc_double ! output ALL data in files as 64-bit From 75d038520db9f762ac13f6bfff6ea23b5ddbb644 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 30 Jan 2022 22:14:34 -0700 Subject: [PATCH 033/614] changes for soiltex almost working - pctsand output is still problematic --- tools/mksurfdata_esmf/src/CMakeLists.txt | 3 + tools/mksurfdata_esmf/src/mkesmfMod.F90 | 32 + tools/mksurfdata_esmf/src/mkfileMod.F90 | 101 ++- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 148 ++-- tools/mksurfdata_esmf/src/mksoilMod.F90 | 673 ------------------- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 14 +- tools/mksurfdata_esmf/src/mksoildepthMod.F90 | 306 +++++---- tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 | 213 ++++++ tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 355 ++++++++++ tools/mksurfdata_esmf/src/mksurfdata.F90 | 142 ++-- tools/mksurfdata_esmf/src/mkvarctl.F90 | 218 +++--- tools/mksurfdata_esmf/src/mkvocefMod.F90 | 80 +-- 12 files changed, 1148 insertions(+), 1137 deletions(-) delete mode 100644 tools/mksurfdata_esmf/src/mksoilMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 create mode 100644 tools/mksurfdata_esmf/src/mksoiltexMod.F90 diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 1e0438c3e6..62c71204e8 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -23,6 +23,9 @@ set(SRCFILES mkvarctl.F90 mklanwatMod.F90 mkorganicMod.F90 mksoilcolMod.F90 + mksoilfmaxMod.F90 + mksoiltexMod.F90 + mksoildepthMod.F90 mkurbanparMod.F90 mkurbanparCommonMod.F90 mkesmfMod.F90 diff --git a/tools/mksurfdata_esmf/src/mkesmfMod.F90 b/tools/mksurfdata_esmf/src/mkesmfMod.F90 index cc7d14c90f..7398d327ef 100644 --- a/tools/mksurfdata_esmf/src/mkesmfMod.F90 +++ b/tools/mksurfdata_esmf/src/mkesmfMod.F90 @@ -11,6 +11,7 @@ module mkesmfMod public :: regrid_rawdata public :: create_routehandle_r4 public :: create_routehandle_r8 + public :: get_meshareas interface regrid_rawdata module procedure regrid_rawdata1d_r4 @@ -294,6 +295,37 @@ subroutine regrid_rawdata2d_r8(mesh_i, mesh_o, routehandle, data_i, data_o, lbo if (chkerr(rc,__LINE__,u_FILE_u)) return data_o(:,:) = dataptr(:,:) + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + end subroutine regrid_rawdata2d_r8 + !=============================================================== + subroutine get_meshareas(mesh, areas, rc) + + ! input/output variables + type(ESMF_Mesh) , intent(in) :: mesh + real(r8) , intent(inout) :: areas(:) + integer , intent(out) :: rc + + ! local variables + real(r8), pointer :: dataptr(:) + type(ESMF_Field) :: lfield + ! -------------------------------------------- + + rc = ESMF_SUCCESS + + lfield = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + areas(:) = dataptr(:) + + call ESMF_FieldDestroy(lfield, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + end subroutine get_meshareas + end module mkesmfMod diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index bc78a522b8..3c2c807df1 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -8,11 +8,9 @@ module mkfileMod use mkvarpar , only : nlevsoi, numrad, numstdpft use mkurbanparMod, only : numurbl, nlevurb, mkurbanpar #ifdef TODO - use mkglcmecMod , only : nglcec use mkpftMod , only : mkpftAtt - use mksoilMod , only : mksoilAtt - use mkharvestMod , only : mkharvest_fieldname, mkharvest_numtypes, mkharvest_longname - use mkharvestMod , only : mkharvest_units, harvestDataType + use mkglcmecMod , only : nglcec + use mkharvestMod , only : mkharvest_fieldname, mkharvest_numtypes, mkharvest_longname, mkharvest_units, harvestDataType #endif use mkpioMod ! TODO: add only use mkvarctl @@ -38,21 +36,26 @@ module mkfileMod subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & pctlak, pctwet, lakedepth, organic, soil_color, nsoilcol, & - urban_classes_g, urban_region) + urban_classes_g, urban_region, pctsand, pctclay, mapunits, fmaxsoil, soildepth) ! input/output variables - integer , intent(in) :: nx - integer , intent(in) :: ny - logical , intent(in) :: dynlanduse - type(ESMF_Mesh) , intent(in) :: mesh_o - real(r8), pointer, intent(in) :: pctlak(:) ! percent of grid cell that is lake - real(r8), pointer, intent(in) :: pctwet(:) ! percent of grid cell that is wetland - real(r8), pointer, intent(in) :: lakedepth(:) ! lake depth (m) - real(r8), pointer, intent(in) :: organic(:,:) ! organic - integer , pointer, intent(in) :: soil_color(:) - integer , intent(in) :: nsoilcol - real(r8), pointer, intent(in) :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell - integer , pointer, intent(in) :: urban_region(:) ! urban region ID + integer , intent(in) :: nx + integer , intent(in) :: ny + logical , intent(in) :: dynlanduse + type(ESMF_Mesh) , intent(in) :: mesh_o + real(r8), pointer , intent(in) :: pctlak(:) ! percent of grid cell that is lake + real(r8), pointer , intent(in) :: pctwet(:) ! percent of grid cell that is wetland + real(r8), pointer , intent(in) :: lakedepth(:) ! lake depth (m) + real(r8), pointer , intent(in) :: organic(:,:) ! organic + integer , pointer , intent(in) :: soil_color(:) + integer , intent(in) :: nsoilcol + real(r8), pointer , intent(in) :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell + integer , pointer , intent(in) :: urban_region(:) ! urban region ID + real(r8), pointer , intent(in) :: fmaxsoil(:) ! soil_fractional saturated area + real(r8), pointer , intent(in) :: pctsand(:,:) ! soil texture: percent sand + real(r8), pointer , intent(in) :: pctclay(:,:) ! soil texture: percent clay + integer , pointer , intent(in) :: mapunits(:) + real(r8), pointer , intent(in) :: soildepth(:) ! soil depth (m) #ifdef TODO type(harvestDataType) , intent(in) :: harvdata #endif @@ -99,6 +102,8 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & xtype = PIO_REAL end if + ! call mkpftAtt( ncid, dynlanduse, xtype ) + do n = 1,2 define_mode = (n == 1) @@ -108,37 +113,62 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & if (.not. dynlanduse) then - if (root_task) write(ndiag, '(a)') trim(subname)//"writing out pct_lake" + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_lake" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_LAKE', 'percent_lake', & 'unitless', pctlak, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag, '(a)') trim(subname)//"writing out pct_wetland" + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_wetland" call mkfile_output(pioid,define_mode, mesh_o, xtype, 'PCT_WETLAND', 'percent_wetland', & 'unitless', pctwet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag, '(a)') trim(subname)//"writing out lakedepth" + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out lakedepth" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'LAKEDEPTH', 'lake_depth', & 'm', lakedepth, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag, '(a)') trim(subname)//"writing out organic" + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil organic matter density" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'ORGANIC', 'organic matter density at soil levels', & 'kg/m3 (assumed carbon content 0.58 gC per gOM)', organic, lev1name='nlevsoi', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag, '(a)') trim(subname)//"writing out soil color" + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_SAND', 'percent sand', & + 'unitless', pctsand, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_CLAY', 'percent sand', & + 'unitless', pctclay, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil mapunits" + call mkfile_output(pioid, define_mode, mesh_o, 'mapunits', 'igbp mapunits', & + 'unitless', mapunits, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil fmax (maximum fraction saturated area)" + call mkfile_output (pioid, define_mode, mesh_o, xtype, 'FMAX', 'maximum fractional saturated area', & + 'unitless', fmaxsoil, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil depth" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'zbedrock', 'soil depth', & + 'm', soildepth, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil color" call mkfile_output(pioid, define_mode, mesh_o, 'SOIL_COLOR', 'soil color', & 'unitless', soil_color, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag, '(a)') trim(subname)//"writing out urban region id" + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out urban region id" call mkfile_output(pioid, define_mode, mesh_o, 'URBAN_REGION_ID', 'urban region ID', & 'unitless', urban_region, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag, '(a)') trim(subname)//"writing out percnt urban" + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out percnt urban" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_URBAN', 'percent urban for each density type', & 'unitless', urban_classes_g, lev1name='numurbl', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -352,6 +382,29 @@ subroutine mkfile_define_atts(pioid, dynlanduse) rcode = pio_put_att(pioid, pio_global, 'mesh_vic_file', trim(str)) end if + if (.not. dynlanduse) then + if ( soil_color_override /= unsetcol )then + rcode = pio_put_att(pioid, pio_global, 'soil_color_override', 'TRUE') + else + str = get_filename(mksrf_fsoicol) + rcode = pio_put_att(pioid, pio_global, 'soil_color_raw_data_file_name', trim(str)) + end if + if ( soil_clay_override /= unsetsoil .and. soil_sand_override /= unsetsoil) then + rcode = pio_put_att(pioid, pio_global, 'soil_clay_override', 'TRUE') + else + str = get_filename(mksrf_fsoitex) + rcode = pio_put_att(pioid, pio_global, 'soil_texture_raw_data_file_name', trim(str)) + end if + if ( soil_fmax_override /= unsetsoil )then + rcode = pio_put_att(pioid, pio_global, 'soil_fmax_override', 'TRUE') + else + str = get_filename(mksrf_fmax) + rcode = pio_put_att(pioid, pio_global, 'fmax_raw_data_file_name', trim(str)) + end if + str = get_filename(mksrf_forganic) + rcode = pio_put_att(pioid, pio_global, 'organic_matter_raw_data_file_name', trim(str)) + end if + end subroutine mkfile_define_atts !================================================================================= diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index 6f89b4c4ab..452c6fc68d 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -6,8 +6,8 @@ module mkharvestMod use ESMF use pio - use mkpioMod use shr_kind_mod , only : r8 => shr_kind_r8, CL => shr_kind_CL + use mkpioMod use mkvarpar use mkvarctl @@ -20,18 +20,22 @@ module mkharvestMod ! public types type :: harvestDataType private - real(r8), pointer :: data1D(:,:) ! Input 1D data - real(r8), pointer :: data2DCFT(:,:,:) ! Input 2D data with CFT's - real(r8), pointer :: data2DPFT(:,:,:) ! Input 2D data with PFT's - real(r8), pointer :: OutData1D(:,:) ! Output 1D data - real(r8), pointer :: OutData2DCFT(:,:,:) ! Output 2D data with CFT's - real(r8), pointer :: OutData2DPFT(:,:,:) ! Output 2D data with natural PFT's - integer :: dims2nd(numharv) ! 2nd dimension size - integer :: CFTdimsize ! Size of CFT dimension - integer :: PFTdimsize ! Size of PFT dimension - integer :: indices1D(numharv) ! Field indices for CFT variables - integer :: indicesCFT(numharv) ! Field indices for CFT variables - integer :: indicesPFT(numharv) ! Field indices for PFT variables + type(ESMF_Routehandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + integer :: ns_i + integer :: ns_o + integer :: dims2nd(numharv) ! 2nd dimension size + integer :: CFTdimsize ! Size of CFT dimension + integer :: PFTdimsize ! Size of PFT dimension + integer :: indices1D(numharv) ! Field indices for CFT variables + integer :: indicesCFT(numharv) ! Field indices for CFT variables + integer :: indicesPFT(numharv) ! Field indices for PFT variables + real(r8), pointer :: data1D(:,:) ! Input 1D data + real(r8), pointer :: data2DCFT(:,:,:) ! Input 2D data with CFT's + real(r8), pointer :: data2DPFT(:,:,:) ! Input 2D data with PFT's + real(r8), pointer :: OutData1D(:,:) ! Output 1D data + real(r8), pointer :: OutData2DCFT(:,:,:) ! Output 2D data with CFT's + real(r8), pointer :: OutData2DPFT(:,:,:) ! Output 2D data with natural PFT's contains procedure :: init ! Initialization procedure :: get1DFieldPtr ! Get a pointer to a 1D field @@ -46,13 +50,13 @@ module mkharvestMod end type harvestDataType ! public member functions - public mkharvest_init ! Initialization - public mkharvest ! Calculate the harvest values on output grid - public mkharvest_fieldname ! Field name for harvest fields on landuse.timeseries - public mkharvest_longname ! Long name - public mkharvest_units ! units - public mkharvest_numtypes ! Number of harvest types - public mkharvest_parse_oride ! Parse the over-ride string + public :: mkharvest_init ! Initialization + public :: mkharvest ! Calculate the harvest values on output grid + public :: mkharvest_fieldname ! Field name for harvest fields on landuse.timeseries + public :: mkharvest_longname ! Long name + public :: mkharvest_units ! units + public :: mkharvest_numtypes ! Number of harvest types + public :: mkharvest_parse_oride ! Parse the over-ride string ! private member functions: (but public because unit test uses them) public mkharvest_fieldInBounds ! Check that field index is within bounds @@ -116,6 +120,7 @@ subroutine init( this, dims2nd, ns_i, ns_o, init_value ) write(*,*) subname//':ERROR:: dims2nd given to init is not the right size' call shr_sys_abort() end if + this%CFTdimsize = 64 this%PFTdimsize = 15 this%dims2nd = dims2nd @@ -126,13 +131,14 @@ subroutine init( this, dims2nd, ns_i, ns_o, init_value ) this%indices1D = -1 this%indicesPFT = -1 this%indicesCFT = -1 + do n = 1, numharv if ( dims2nd(n) == 0 )then num1D = num1D + 1 this%indices1D(n) = num1D else num2nd = num2nd + 1 - if ( dims2nd(n) == this%CFTdimsize )then + if (dims2nd(n) == this%CFTdimsize) then numCFT = numCFT + 1 this%indicesCFT(n) = numCFT else if ( dims2nd(n) == this%PFTdimsize )then @@ -165,20 +171,19 @@ subroutine init( this, dims2nd, ns_i, ns_o, init_value ) end subroutine init !================================================================================= - subroutine mkharvest_init( ns_o, init_val, harvdata, fharvest, constant ) + subroutine mkharvest_init(file_mesh_i, file_data_i, mesh_o, init_val, harvdata, pioid, constant) ! ! Initialization of mkharvest module. ! ! input/output variables: - integer , intent(in) :: ns_o ! clm output grid resolution real(r8) , intent(in) :: init_val ! initial value to set to - type(harvestDataType) , intent(inout) :: harvdata ! Harvest data character(len=*) , intent(in) :: fharvest ! input harvest dataset file name + type(file_desc_t) , intent(out) :: pioid + type(harvestDataType) , intent(inout) :: harvdata ! Harvest data logical, optional , intent(in) :: constant ! Flag if variables are CONST_ version for surface dataset ! local variables: character(len=CL) :: lunits ! local units read in - integer :: ncid,varid ! input netCDF id's integer :: ifld ! indices integer :: ret ! return code logical :: lconstant ! local version of constant flag @@ -186,28 +191,50 @@ subroutine mkharvest_init( ns_o, init_val, harvdata, fharvest, constant ) integer :: dim_lengths(3) ! Dimension lengths on file integer :: dims2nd(numharv) ! Dimension lengths of 3rd dimension for each variable on file integer :: ndims ! Number of dimensions on file - integer :: ns_i ! clm input grid resolution (nlat*nlon) + integer :: rcode character(len=*), parameter :: subname = 'mkharvest_init' !----------------------------------------------------------------------- + ! TODO: check that number of global elements in mesh is identical to number of global elements in input data + lconstant = .false. if ( present(constant) ) lconstant = constant - initialized = .true. + + ! Open fharvest + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(fharvest), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) + + ! Read in input mesh + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_o and allocate data_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Create a route handle between the input and output mesh + call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - dims2nd(:) = 0 - ns_i = 0 do ifld = 1, numharv call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) + ! Determine if variable is on input dataset (fharvest) varname = mkharvest_fieldname(ifld, constant=lconstant) rCode = pio_inq_varid(varname, pio_varid) call pio_seterrorhandling(pioid, PIO_INTERNAL_ERROR) - if (rcode /= PIO_NOERR) then - write(*,*) "SKIP: "//mkharvest_fieldname(ifld, constant=lconstant) - harvest_longnames(ifld) = trim(mkharvest_fieldname(ifld, constant=lconstant)) // " (zeroed out)" - harvest_units(ifld) = "not_read_in" + if (rcode == PIO_NOERR) then + varexists = .true. else + varexists = .false. + end if + if (varexists) then + ! Get variable attributes if they exist call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) rcode = pio_inq_attname(pioid, pio_varid, attnum, attname) call pio_seterrorhandling(pioid, PIO_INTERNAL_ERROR) @@ -215,14 +242,10 @@ subroutine mkharvest_init( ns_o, init_val, harvdata, fharvest, constant ) rcode = pio_get_att_text( pioid, pio_varid, 'long_name', harvest_longnames(ifld)) rcode = pio_get_att_text( pioid, pio_varid, 'units', harvest_units(ifld)) end if + + ! get dims2nd for variable call mkpio_get_dimlengths(pioid, varname, ndims, dim_lengths) - if ( ns_i == 0 )then - ns_i = dim_lengths(1)*dim_lengths(2) - else if ( ns_i /= dim_lengths(1)*dim_lengths(2) )then - write(*,*) 'ERROR:: bad dimension sizes for variable = ', mkharvest_fieldname(ifld, constant=lconstant) - call shr_sys_abort() - end if - if ( ndims == 2 )then + if ( ndims == 2 )then dims2nd(ifld) = 0 else if ( ndims == 3 )then dims2nd(ifld) = dim_lengths(3) @@ -230,12 +253,18 @@ subroutine mkharvest_init( ns_o, init_val, harvdata, fharvest, constant ) write(*,*) 'ERROR:: bad dimensionality for variable = ', mkharvest_fieldname(ifld, constant=lconstant) call shr_sys_abort() end if + else + if (root_task) then + write(ndiag,'(a)') "SKIPPING: "//mkharvest_fieldname(ifld, constant=lconstant) + end if + harvest_longnames(ifld) = trim(mkharvest_fieldname(ifld, constant=lconstant)) // " (zeroed out)" + harvest_units(ifld) = "not_read_in" end if end do call pio_closefile(pioid) ! Initialize harvest datatype - call harvdata%init( dims2nd, ns_i, ns_o, init_val ) + call harvdata%init( dims2nd, ns_i, ns_o, init_val, routehandle, mesh_i ) allocate( oride_harv(numharv) ) oride_harv(:) = real_undef @@ -243,22 +272,19 @@ subroutine mkharvest_init( ns_o, init_val, harvdata, fharvest, constant ) end subroutine mkharvest_init !================================================================================= - subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, harvdata, rc) + subroutine mkharvest(file_data_i, mesh_o, harvdata, rc) ! ! Make harvest data for the dynamic PFT dataset. ! This dataset consists of the normalized harvest or grazing fraction (0-1) of ! the model. ! ! input/output variables: - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh type(harvestDataType) , intent(inout) :: harvdata ! Harvest data integer , intent(out) :: rc ! return code ! local variables: - type(ESMF_RouteHandle) :: routehandle - type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid type(var_desc_t) :: pio_varid integer :: ni,no,ns_i,ns_o ! indices @@ -307,34 +333,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, harvdata, rc) ! ----------------------------------------------------------------- ! Read input harvesting file ! ----------------------------------------------------------------- - - ! Open input data file - need to do this first to obtain ungridded dimension size - call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) - call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) - - ! Read in input mesh - call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) - mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - - ! Create a route handle between the input and output mesh - call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - ! Determine ns_i and allocate data_i - call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - allocate(data_i(nlay,ns_i),stat=ier) - if (ier/=0) call shr_sys_abort() - - ! Determine ns_o and allocate data_o - call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) - allocate(frac_o(ns_o), stat=ier) - if (ier/=0) call shr_sys_abort() - ! Determine frac_o (regrid frac_i to frac_o) allocate(frac_i(ns_i)) allocate(frac_o(ns_o)) @@ -372,7 +371,6 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, harvdata, rc) end do ! Read in input 1d fields if they exists and map to output grid - ! TODO: enter this in do k = 1, harvdata%num2Dfields() ifld = ind2D(k) data2d_i => harvdata%get2DFieldPtr( ifld ) @@ -384,8 +382,8 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, harvdata, rc) call pio_seterrorhandling(pioid, PIO_INTERNAL_ERROR) if (rcode == PIO_NOERR) then nlev = size(data2d_i, dim=2) - allocate(read_data2d_i(nlev, ns_i) - allocate(read_data2d_o(nlev, ns_o) + allocate(read_data2d_i(nlev, ns_i)) + allocate(read_data2d_o(nlev, ns_o)) call mkpio_get_rawdata(pioid, varname, mesh_i, read_data2d_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call regrid_rawdata(mesh_i, mesh_o, routehandle, read_data2d_i, read_data2d_o, rc) diff --git a/tools/mksurfdata_esmf/src/mksoilMod.F90 b/tools/mksurfdata_esmf/src/mksoilMod.F90 deleted file mode 100644 index cdcfb6c71f..0000000000 --- a/tools/mksurfdata_esmf/src/mksoilMod.F90 +++ /dev/null @@ -1,673 +0,0 @@ -module mksoilMod - - implicit none - private ! By default make data private - - !----------------------------------------------------------------------- - ! Make soil data (texture) - !----------------------------------------------------------------------- - - use shr_kind_mod, only : r8 => shr_kind_r8, r4=>shr_kind_r4 - use mksoilUtilsMod, only : mkrank - - implicit none - private ! By default make data private - - public mksoilInit ! Soil Initialization - public mksoilAtt ! Add attributes to output file - public mksoiltex ! Set soil texture - public mkfmax ! Make percent fmax - - private :: mksoiltexInit ! Soil texture Initialization - private :: mksoilcolInit ! Soil color Initialization - private :: mksoilfmaxInit ! Soil fmax Initialization - - real(r8), public, parameter :: unset = -999.99_r8 ! Flag to signify soil texture override not set - real(r8), public :: soil_sand = unset ! soil texture sand % to override with - real(r8), public :: soil_clay = unset ! soil texture clay % to override with - real(r8), public :: soil_fmax = unset ! soil max saturation frac to override with - integer , parameter :: unsetcol = -999 ! flag to indicate soil color NOT set - integer , public :: soil_color= unsetcol ! soil color to override with - -!================================================================================= -contains -!================================================================================= - - subroutine mksoilInit( ) - - ! Initialize the different soil types - - call mksoiltexInit() - call mksoilcolInit() - call mksoilfmaxInit() - - end subroutine mksoilInit - - !========================================================================== - subroutine mksoiltexInit( ) - ! - ! Initialize of make soil texture - ! - ! local variables: - real(r8) :: sumtex - character(len=32) :: subname = 'mksoiltexInit' - !----------------------------------------------------------------------- - if ( soil_clay /= unset )then - write(6,*) 'Replace soil clay % for all points with: ', soil_clay - if ( soil_sand == unset )then - write (6,*) subname//':error: soil_clay set, but NOT soil_sand' - call shr_sys_abort() - end if - end if - if ( soil_sand /= unset )then - write(6,*) 'Replace soil sand % for all points with: ', soil_sand - if ( soil_clay == unset )then - write (6,*) subname//':error: soil_sand set, but NOT soil_clay' - call shr_sys_abort() - end if - sumtex = soil_sand + soil_clay - if ( sumtex < 0.0_r8 .or. sumtex > 100.0_r8 )then - write (6,*) subname//':error: soil_sand and soil_clay out of bounds: sand, clay = ', & - soil_sand, soil_clay - call shr_sys_abort() - end if - end if - - end subroutine mksoiltexInit - - !========================================================================== - subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) - - ! make %sand and %clay from IGBP soil data, which includes - ! igbp soil 'mapunits' and their corresponding textures - - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio - - ! input/output variables - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: sand_o(:,:) ! % sand (output grid) - real(r8) , intent(out):: clay_o(:,:) ! % clay (output grid) - - ! local variables - character(len=38) :: typ ! soil texture based on ... - integer :: nlay ! number of soil layers - integer :: mapunitmax ! max value of igbp soil mapunits - integer :: mapunittemp ! temporary igbp soil mapunit - integer :: maxovr - integer , allocatable :: novr(:) - integer , allocatable :: kmap(:,:) - real(r8), allocatable :: kwgt(:,:) - integer , allocatable :: kmax(:) - real(r8), allocatable :: wst(:) - real(r8), allocatable :: sand_i(:,:) ! input grid: percent sand - real(r8), allocatable :: clay_i(:,:) ! input grid: percent clay - real(r8), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer, parameter :: num=2 ! set soil mapunit number - integer :: wsti(num) ! index to 1st and 2nd largest wst - integer, parameter :: nlsm=4 ! number of soil textures - character(len=38) :: soil(0:nlsm) ! name of each soil texture - real(r8) :: gast_i(0:nlsm) ! global area, by texture type - real(r8) :: gast_o(0:nlsm) ! global area, by texture type - real(r8) :: wt ! map overlap weight - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - integer :: l,k,n,m,ni,no,ns_i,ns_o ! indices - integer :: k1,k2 ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - integer :: miss = 99999 ! missing data indicator - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - logical :: found ! temporary - integer :: kmap_max ! maximum overlap weights - integer, parameter :: kmap_max_min = 90 ! kmap_max mininum value - integer, parameter :: km_mx_ns_prod = 160000 ! product of kmap_max*ns_o to keep constant - character(len=32) :: subname = 'mksoiltex' - !----------------------------------------------------------------------- - - write (6,*) 'Attempting to make %sand and %clay .....' - - ! ----------------------------------------------------------------- - ! Define the model surface types: 0 to nlsm - ! ----------------------------------------------------------------- - - soil(0) = 'no soil: ocean, glacier, lake, no data' - soil(1) = 'clays ' - soil(2) = 'sands ' - soil(3) = 'loams ' - soil(4) = 'silts ' - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - ns_o = ldomain%ns - - write (6,*) 'Open soil texture file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_dimid (ncid, 'number_of_layers', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, nlay), subname) - - call check_ret(nf_inq_dimid (ncid, 'max_value_mapunit', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, mapunitmax), subname) - - allocate(sand_i(mapunitmax,nlay), & - clay_i(mapunitmax,nlay), & - mapunit_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - - call check_ret(nf_inq_varid (ncid, 'MAPUNITS', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, mapunit_i), subname) - - call check_ret(nf_inq_varid (ncid, 'PCT_SAND', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, sand_i), subname) - - call check_ret(nf_inq_varid (ncid, 'PCT_CLAY', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, clay_i), subname) - - call check_ret(nf_close(ncid), subname) - - ! TODO: create an array that is size of (ns_i,mapunits) - ! read in mapunits - allocate(mask_mapuntis(ns_i, mapunits)) - mask_mapunits_i(:,:) = 0._r8 - do ni = 1,ns_i - do nmap = 1,mapunits - if (mapunits(ni,nmap) == nmap) then - mask_mapunits_i(ni,nmap) = 1._r8 - end if - end do - end do - - - ! Compute local fields _o - if (soil_sand==unset .and. soil_clay==unset) then - ! Now map mask_mapunits_i to mask_mapunits_o - ! result is mask_mapunits_o(no_nmap) - - do no = 1,ns_o - do nmap = 1,mapunits - kmap(no) = maxval(mask_mapunits_o(no,:)) - end do - end do - end if - - do no = 1,ns_o - - if (soil_sand==unset .and. soil_clay==unset) then - wst(:) = 0. - wst(0:kmax(no)) = kwgt(0:kmax(no),no) - - ! Rank non-zero weights by soil mapunit. - ! k1 is the most extensive mapunit. - ! k2 is the second most extensive mapunit. - - if (maxval(wst(:)) > 0) then - call mkrank (kmax(no)+1, wst(0:kmax(no)), miss, wsti, num) - k1 = kmap(wsti(1),no) - if (wsti(2) == miss) then - k2 = miss - else - k2 = kmap(wsti(2),no) - end if - else - k1 = 0 - k2 = 0 - end if - - end if - - ! Set soil texture as follows: - ! a. Use dominant igbp soil mapunit based on area of overlap unless - ! 'no data' is dominant - ! b. In this case use second most dominant mapunit if it has data - ! c. If this has no data or if there isn't a second most dominant - ! mapunit, use loam for soil texture - - if (soil_sand/=unset .and. soil_clay/=unset) then - ! force soil texture to be input - do l = 1, nlay - sand_o(no,l) = soil_sand - clay_o(no,l) = soil_clay - end do - else if (kmap(no) /= 0) then - do l = 1, nlay - sand_o(no,l) = sand_i(k1,l) - clay_o(no,l) = clay_i(k1,l) - end do - else - ! kmap(no) = 0 - do l = 1, nlay - sand_o(no,l) = 43. !---use loam - clay_o(no,l) = 18. - end do - end if !---end of k1 if-block - enddo - - if (soil_sand==unset .and. soil_clay==unset) then - - ! Global sum of output field - - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global area of each soil type on input and output grids - ! ----------------------------------------------------------------- - - ! input grid: global areas by texture class - - gast_i(:) = 0. - do l = 1, nlay - do ni = 1,ns_i - mapunittemp = nint(mapunit_i(ni)) - if (mapunittemp==0) then - typ = 'no soil: ocean, glacier, lake, no data' - else if (clay_i(mapunittemp,l) >= 40.) then - typ = 'clays' - else if (sand_i(mapunittemp,l) >= 50.) then - typ = 'sands' - else if (clay_i(mapunittemp,l)+sand_i(mapunittemp,l) < 50.) then - if (tdomain%mask(ni) /= 0.) then - typ = 'silts' - else !if (tdomain%mask(ni) == 0.) then no data - typ = 'no soil: ocean, glacier, lake, no data' - end if - else - typ = 'loams' - end if - do m = 0, nlsm - if (typ == soil(m)) go to 101 - end do - write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunittemp,l), & - ' clay = ',clay_i(mapunittemp,l), & - ' not assigned to soil type for input grid lon,lat,layer = ',ni,l - call shr_sys_abort() -101 continue - gast_i(m) = gast_i(m) + tgridmap%area_src(ni)*tdomain%mask(ni)*re**2 - end do - end do - - ! output grid: global areas by texture class - - gast_o(:) = 0. - do l = 1, nlay - do no = 1,ns_o - if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then - typ = 'no soil: ocean, glacier, lake, no data' - else if (clay_o(no,l) >= 40.) then - typ = 'clays' - else if (sand_o(no,l) >= 50.) then - typ = 'sands' - else if (clay_o(no,l)+sand_o(no,l) < 50.) then - typ = 'silts' - else - typ = 'loams' - end if - do m = 0, nlsm - if (typ == soil(m)) go to 102 - end do - write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & - ' clay = ',clay_o(no,l), & - ' not assigned to soil type for output grid lon,lat,layer = ',no,l - call shr_sys_abort() -102 continue - gast_o(m) = gast_o(m) + tgridmap%area_dst(no)*frac_dst(no)*re**2 - end do - end do - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',l=1,70) - write (ndiag,*) 'Soil Texture Output' - write (ndiag,'(1x,70a1)') ('=',l=1,70) - write (ndiag,*) - - write (ndiag,*) 'The following table of soil texture classes is for comparison only.' - write (ndiag,*) 'The actual data is continuous %sand, %silt and %clay not textural classes' - write (ndiag,*) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',l=1,70) - write (ndiag,1001) -1001 format (1x,'soil texture class',17x,' input grid area output grid area',/ & - 1x,33x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',l=1,70) - write (ndiag,*) - - do l = 0, nlsm - write (ndiag,1002) soil(l),gast_i(l)*1.e-6,gast_o(l)*1.e-6 -1002 format (1x,a38,f16.3,f17.3) - end do - - end if - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - if (soil_sand==unset .and. soil_clay==unset) then - call gridmap_clean(tgridmap) - deallocate (kmap, kwgt, kmax, wst) - deallocate (sand_i,clay_i,mapunit_i) - deallocate (frac_dst) - deallocate (mask_r8) - end if - - - write (6,*) 'Successfully made %sand and %clay' - write (6,*) - - end subroutine mksoiltex - - !========================================================================== - subroutine mksoilcolInit( ) - ! - ! Initialize of make soil color - - ! local variables - real(r8) :: sumtex - character(len=32) :: subname = 'mksoilcolInit' - !----------------------------------------------------------------------- - - ! Error check soil_color if it is set - if ( soil_color /= unsetcol )then - if ( soil_color < 0 .or. soil_color > 20 )then - write(6,*)'soil_color is out of range = ', soil_color - call shr_sys_abort() - end if - write(6,*) 'Replace soil color for all points with: ', soil_color - end if - - end subroutine mksoilcolInit - - !========================================================================== - subroutine mksoilfmaxInit( ) - ! - ! Initialize of make soil fmax - ! - ! local variables: - real(r8) :: sumtex - character(len=32) :: subname = 'mksoilfmaxInit' - !----------------------------------------------------------------------- - - ! Error check soil_fmax if it is set - if ( soil_fmax /= unset )then - if ( soil_fmax < 0.0 .or. soil_fmax > 1.0 )then - write(6,*)'soil_fmax is out of range = ', soil_fmax - call shr_sys_abort() - end if - write(6,*) 'Replace soil fmax for all points with: ', soil_fmax - end if - - end subroutine mksoilfmaxInit - - !========================================================================== - subroutine mkfmax(ldomain, mapfname, datfname, ndiag, fmax_o) - ! - ! !DESCRIPTION: - ! make percent fmax - ! - ! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio - ! - ! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: fmax_o(:) ! output grid: %fmax - ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Revised: Nan Rosenbloom - used mkglacier.F90 as template. - ! Original Author: Mariana Vertenstein - ! - ! - ! !LOCAL VARIABLES: - !EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: fmax_i(:) ! input grid: percent fmax - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: gfmax_i ! input grid: global fmax - real(r8) :: garea_i ! input grid: global area - real(r8) :: gfmax_o ! output grid: global fmax - real(r8) :: garea_o ! output grid: global area - integer :: k,n,m,ni,no,ns_i,ns_o ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mkfmax' - !----------------------------------------------------------------------- - - write (6,*) 'Attempting to make %fmax .....' - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - ns_o = ldomain%ns - allocate(fmax_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call shr_sys_abort() - - write (6,*) 'Open soil fmax file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'FMAX', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, fmax_i), subname) - call check_ret(nf_close(ncid), subname) - - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. - - call gridmap_mapread(tgridmap, mapfname ) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine fmax_o on output grid - - ! In points with no data, use globalAvg - ! (WJS (3-11-13): use real(.365783,r8) rather than .365783_r8 to maintain bfb results - ! with old code) - call gridmap_areaave_srcmask(tgridmap, fmax_i, fmax_o, nodata=real(.365783,r8), mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check for conservation - - do no = 1, ns_o - if ((fmax_o(no)) > 1.000001_r8) then - write (6,*) 'MKFMAX error: fmax = ',fmax_o(no), & - ' greater than 1.000001 for column, row = ',no - call shr_sys_abort() - end if - enddo - - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - - gfmax_i = 0. - garea_i = 0. - do ni = 1,ns_i - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - gfmax_i = gfmax_i + fmax_i(ni)*(tgridmap%area_src(ni)/100.)* & - tdomain%mask(ni)*re**2 - end do - - gfmax_o = 0. - garea_o = 0. - do no = 1,ns_o - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - gfmax_o = gfmax_o + fmax_o(no)*(tgridmap%area_dst(no)/100.) * & - frac_dst(no)*re**2 - if ((frac_dst(no) < 0.0) .or. (frac_dst(no) > 1.0001)) then - write(6,*) "ERROR:: frac_dst out of range: ", frac_dst(no),no - call shr_sys_abort () - end if - end do - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Maximum Fractional Saturated Area Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) -2001 format (1x,'surface type input grid area output grid area'/ & - 1x,' 10**6 km**2 10**6 km**2 ') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2002) gfmax_i*1.e-06,gfmax_o*1.e-06 - write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 -2002 format (1x,'fmax ',f14.3,f17.3) -2004 format (1x,'all surface ',f14.3,f17.3) - - write (6,*) 'Successfully made %fmax' - write (6,*) - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (fmax_i) - deallocate (frac_dst) - deallocate (mask_r8) - - end subroutine mkfmax - - !----------------------------------------------------------------------- - subroutine mksoilAtt( ncid, dynlanduse, xtype ) - - ! add atttributes to output file regarding the soil module - - use mkutilsMod , only : get_filename - use mkncdio , only : check_ret, ncd_defvar, ncd_def_spatial_var - use mkvarpar - use mkvarctl - - ! !ARGUMENTS: - integer, intent(in) :: ncid ! NetCDF file ID to write out to - logical, intent(in) :: dynlanduse ! if dynamic land-use file - integer, intent(in) :: xtype ! external type to output real data as - - ! !LOCAL VARIABLES: - integer :: dimid ! temporary - character(len=256) :: str ! global attribute string - character(len=32) :: subname = 'mksoilAtt' - !----------------------------------------------------------------------- - - if (.not. dynlanduse) then - - ! Define dimensions unique to soil - - call check_ret(nf_def_dim (ncid, 'nlevsoi', & - nlevsoi , dimid), subname) - - ! Add global attributes to file - - if ( soil_clay /= unset .and. soil_sand /= unset )then - str = 'TRUE' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'soil_clay_override', len_trim(str), trim(str)), subname) - str = 'TRUE' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'soil_sand_override', len_trim(str), trim(str)), subname) - else - str = get_filename(mksrf_fsoitex) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Soil_texture_raw_data_file_name', len_trim(str), trim(str)), subname) - end if - if ( soil_color /= unsetcol )then - str = 'TRUE' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'soil_color_override', len_trim(str), trim(str)), subname) - else - str = get_filename(mksrf_fsoicol) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Soil_color_raw_data_file_name', len_trim(str), trim(str)), subname) - end if - if ( soil_fmax /= unset )then - str = 'TRUE' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'soil_fmax_override', len_trim(str), trim(str)), subname) - else - str = get_filename(mksrf_fmax) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Fmax_raw_data_file_name', len_trim(str), trim(str)), subname) - end if - str = get_filename(mksrf_forganic) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Organic_matter_raw_data_file_name', len_trim(str), trim(str)), subname) - - ! Define variables - - call ncd_defvar(ncid=ncid, varname='mxsoil_color', xtype=nf_int, & - long_name='maximum numbers of soil colors', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='SOIL_COLOR', xtype=nf_int, & - long_name='soil color', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_SAND', xtype=xtype, & - lev1name='nlevsoi', & - long_name='percent sand', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CLAY', xtype=xtype, & - lev1name='nlevsoi', & - long_name='percent clay', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='FMAX', xtype=xtype, & - long_name='maximum fractional saturated area', units='unitless') - - end if - - end subroutine mksoilAtt - -end module mksoilMod diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index 6c60cc8b13..ef07aaaab9 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -9,15 +9,13 @@ module mksoilcolMod use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr, mkrank use mkvarctl , only : root_task, ndiag, mpicom, MPI_INTEGER, MPI_MAX + use mkvarctl , only : soil_color_override, unsetcol implicit none private public :: mksoilcol ! Set soil colors - integer , parameter :: unsetcol = -999 ! flag to indicate soil color NOT set - integer , private :: soil_color= unsetcol ! soil color to override with - character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -56,14 +54,14 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r rc = ESMF_SUCCESS ! Error check soil_color if it is set - if ( soil_color /= unsetcol )then - if ( soil_color < 0 .or. soil_color > 20 )then - write(6,*)'soil_color is out of range = ', soil_color + if ( soil_color_override /= unsetcol )then + if ( soil_color_override < 0 .or. soil_color_override > 20 )then + write(6,*)'soil_color is out of range = ', soil_color_override call shr_sys_abort() end if - write(6,*) 'Replace soil color for all points with: ', soil_color + write(6,*) 'Replace soil color for all points with: ', soil_color_override do no = 1,size(soil_color_o) - soil_color_o(no) = soil_color + soil_color_o(no) = soil_color_override end do RETURN end if diff --git a/tools/mksurfdata_esmf/src/mksoildepthMod.F90 b/tools/mksurfdata_esmf/src/mksoildepthMod.F90 index 0a2182bb1f..54021cb08c 100644 --- a/tools/mksurfdata_esmf/src/mksoildepthMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoildepthMod.F90 @@ -1,169 +1,163 @@ module mksoildepthMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mksoildepthMod -! -! !DESCRIPTION: -! make fraction soildepth from input soildepth data -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -!----------------------------------------------------------------------- -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkdomainMod , only : domain_checksame + !----------------------------------------------------------------------- + ! make fraction soildepth from input soildepth data + !----------------------------------------------------------------------- + ! + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4, cs => shr_kind_cs + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 + use mkutilsMod , only : chkerr + use mkchecksMod , only : min_bad, max_bad + use mkvarctl implicit none - private -! !PUBLIC MEMBER FUNCTIONS: public mksoildepth ! regrid soildepth data -! -!EOP + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + !=============================================================== contains !=============================================================== -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoildepth -! -! !INTERFACE: -subroutine mksoildepth(ldomain, mapfname, datfname, ndiag, soildepth_o) -! -! !DESCRIPTION: -! make soildepth -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_area - use mkchecksMod, only : min_bad, max_bad -! -! !ARGUMENTS: - - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: soildepth_o(:) ! output grid: fraction soildepth -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: data_i(:) ! data on input grid - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - - real(r8), parameter :: min_valid = 0._r8 ! minimum valid value - real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value - character(len=32) :: subname = 'mksoildepth' - character(len=32) :: varname - integer :: varnum -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make soildepth .....' - - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - call domain_read( tdomain, datfname ) - - call gridmap_mapread( tgridmap, mapfname ) - - ! Obtain frac_dst - allocate(frac_dst(ldomain%ns), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write(6,*)'Open soildepth file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(data_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() - - ! ----------------------------------------------------------------- - ! Regrid soildepth - ! ----------------------------------------------------------------- - - varnum = 1 - select case (varnum) - case(1) - varname = 'Avg_Depth_Median' - case(2) - varname = 'Avg_Depth_Mean' - case(3) - varname = 'Upland_Valley_Depth_Median' - case(4) - varname = 'Upland_Valley_Depth_Mean' - case(5) - varname = 'Upland_Hillslope_Depth_Median' - case(6) - varname = 'Upland_Hillslope_Depth_Mean' - case(7) - varname = 'Lowland_Depth_Mean' - case(8) - varname = 'Lowland_Depth_Mean' - end select - -! call check_ret(nf_inq_varid (ncid, 'Avg_Depth_Median', varid), subname) - call check_ret(nf_inq_varid (ncid, varname, varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, soildepth_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(soildepth_o, min_valid, 'soildepth') .or. & - max_bad(soildepth_o, max_valid, 'soildepth')) then - call abort() - end if - - call output_diagnostics_area(data_i, soildepth_o, tgridmap, "Soildepth", percent=.false., ndiag=ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- - - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (data_i) - deallocate (frac_dst) - deallocate (mask_r8) - - write (6,*) 'Successfully made soildepth' - write (6,*) - -end subroutine mksoildepth - + subroutine mksoildepth(file_mesh_i, file_data_i, mesh_o, soildepth_o, rc) + ! + ! make soildepth + ! + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + real(r8) , intent(out) :: soildepth_o(:) ! output grid: fraction soildepth + integer , intent(out) :: rc + + ! local variables: + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + integer :: ns_i, ns_o + integer :: n + real(r8), allocatable :: soildepth_i(:) + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) + integer :: ier, rcode ! error status + character(len=CS) :: varname + integer :: varnum + real(r8), parameter :: min_valid = 0._r8 ! minimum valid value + real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value + character(len=*), parameter :: subname = 'mksoildepth' + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (root_task) then + write (ndiag,'(a)') 'Attempting to make soildepth .....' + end if + + ! Open input data file + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + + ! Read in input mesh + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Create a route handle between the input and output mesh + call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + + ! Determine ns_i and allocate soildepth_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(soildepth_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + + ! Determine frac_o (regrid frac_i to frac_o) + allocate(frac_i(ns_i)) + allocate(frac_o(ns_o)) + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, frac_i, frac_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do n = 1, ns_o + if ((frac_o(n) < 0.0) .or. (frac_o(n) > 1.0001)) then + write(6,*) "ERROR:: frac_o out of range: ", frac_o(n),n + call shr_sys_abort () + end if + end do + call ESMF_VMLogMemInfo("After regrid landmask in "//trim(subname)) + + ! Determine variable name to read in + varnum = 1 + select case (varnum) + case(1) + varname = 'Avg_Depth_Median' + case(2) + varname = 'Avg_Depth_Mean' + case(3) + varname = 'Upland_Valley_Depth_Median' + case(4) + varname = 'Upland_Valley_Depth_Mean' + case(5) + varname = 'Upland_Hillslope_Depth_Median' + case(6) + varname = 'Upland_Hillslope_Depth_Mean' + case(7) + varname = 'Lowland_Depth_Mean' + case(8) + varname = 'Lowland_Depth_Mean' + end select + + ! Read in input data + call mkpio_get_rawdata(pioid, trim(varname), mesh_i, soildepth_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + + ! Regrid soildepth_i to soildepth_o and scale by 1/frac_o + call regrid_rawdata(mesh_i, mesh_o, routehandle, soildepth_i, soildepth_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite(subname//'after regrid rawdata in '//trim(subname)) + do n = 1,ns_o + if (frac_o(n) > 0._r8) then + soildepth_o(n) = soildepth_o(n) / frac_o(n) + else + soildepth_o(n) = 0._r8 + end if + end do + + ! Check validity of output data + if ( min_bad(soildepth_o, min_valid, 'soildepth') .or. max_bad(soildepth_o, max_valid, 'soildepth')) then + call shr_sys_abort() + end if + + ! Close the input file + call pio_closefile(pioid) + call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) + + ! Release memory + deallocate(soildepth_i) + deallocate(frac_i) + deallocate(frac_o) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) + + if (root_task) then + write (ndiag,'(a)') 'Successfully made soildepth' + write (ndiag,*) + end if + + end subroutine mksoildepth end module mksoildepthMod diff --git a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 new file mode 100644 index 0000000000..ba6ee132a6 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 @@ -0,0 +1,213 @@ +module mksoilfmaxMod + + !----------------------------------------------------------------------- + ! Make soil fmax + !----------------------------------------------------------------------- + + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkutilsMod , only : chkerr + use mkvarpar + use mkvarctl + + implicit none + private ! By default make data private + + public :: mksoilfmax ! Make percent fmax + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + +!================================================================================= +contains +!================================================================================= + + subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) + ! + ! make percent fmax + ! + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + real(r8) , intent(out) :: fmax_o(:) ! output grid: %fmax + integer , intent(out) :: rc + + ! local variables: + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + integer :: ni,no + integer :: ns_i, ns_o + integer :: n,l,k + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: fmax_i(:) ! input grid: percent fmax + real(r8), allocatable :: areas_i(:) ! input mesh areas + real(r8), allocatable :: areas_o(:) ! output mesh areas + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: gfmax_i ! input grid: global fmax + real(r8) :: garea_i ! input grid: global area + real(r8) :: gfmax_o ! output grid: global fmax + real(r8) :: garea_o ! output grid: global area + integer :: ier, rcode ! error status + character(len=32) :: subname = 'mksoilfmax' + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (root_task) then + write (ndiag,'(a)') 'Attempting to make %fmax .....' + end if + + ! Error check soil_fmax if it is set + if ( soil_fmax_override /= unsetsoil )then + if ( soil_fmax_override < 0.0 .or. soil_fmax_override > 1.0 )then + write(6,*)'soil_fmax is out of range = ', soil_fmax_override + call shr_sys_abort() + end if + write(6,*) 'Replace soil fmax for all points with: ', soil_fmax_override + end if + + ! Open input data file + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + + ! Read in input mesh + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Create a route handle between the input and output mesh + call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + + ! Determine ns_i and allocate fmax_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(fmax_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine frac_o (regrid frac_i to frac_o) + allocate(frac_i(ns_i)) + allocate(frac_o(ns_o)) + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, frac_i, frac_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do n = 1, ns_o + if ((frac_o(n) < 0.0) .or. (frac_o(n) > 1.0001)) then + write(6,*) "ERROR:: frac_o out of range: ", frac_o(n),n + call shr_sys_abort () + end if + end do + call ESMF_VMLogMemInfo("After regrid landmask in "//trim(subname)) + + ! Read in input data + call mkpio_get_rawdata(pioid, 'FMAX', mesh_i, fmax_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + + ! Regrid fmax_i to fmax_o and scale by 1/frac_o + ! In points with no data, use globalAvg + ! Check for conservation + call regrid_rawdata(mesh_i, mesh_o, routehandle, fmax_i, fmax_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite(subname//'after regrid rawdata in '//trim(subname)) + + do n = 1,ns_o + if (frac_o(n) > 0._r8) then + fmax_o(n) = fmax_o(n) / frac_o(n) + else + fmax_o(n) = .365783_r8 + end if + end do + do no = 1, ns_o + if ((fmax_o(no)) > 1.000001_r8) then + write (6,*) 'MKFMAX error: fmax = ',fmax_o(no),' greater than 1.000001 for no = ',no + call shr_sys_abort() + end if + enddo + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global areas on input and output grids + ! ----------------------------------------------------------------- + +! allocate(areas_i(ns_i)) +! call get_meshareas(mesh_i, areas_i, rc) +! if (ChkErr(rc,__LINE__,u_FILE_u)) return + +! allocate(areas_o(ns_o)) +! call get_meshareas(mesh_o, areas_o, rc) +! if (ChkErr(rc,__LINE__,u_FILE_u)) return + +! gfmax_i = 0. +! garea_i = 0. +! do ni = 1,ns_i +! garea_i = garea_i + areas_i(ni)*re**2 +! gfmax_i = gfmax_i + fmax_i(ni)*(areas_i(ni)/100.) * frac_i(ni)*re**2 +! end do + +! gfmax_o = 0. +! garea_o = 0. +! do no = 1,ns_o +! garea_o = garea_o + areas_o(no)*re**2 +! gfmax_o = gfmax_o + fmax_o(no)*(areas_o(no)/100.) * frac_o(no)*re**2 +! end do +! deallocate(areas_i) +! deallocate(areas_o) + +! ! Diagnostic output +! if (root_task) then +! write (ndiag,*) +! write (ndiag,'(1x,70a1)') ('=',k=1,70) +! write (ndiag,*) 'Maximum Fractional Saturated Area Output' +! write (ndiag,'(1x,70a1)') ('=',k=1,70) + +! write (ndiag,*) +! write (ndiag,'(1x,70a1)') ('.',k=1,70) +! write (ndiag,2001) +! write (ndiag,'(1x,70a1)') ('.',k=1,70) +! write (ndiag,*) +! write (ndiag,2002) gfmax_i*1.e-06,gfmax_o*1.e-06 +! write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 +! 2001 format (1x,'surface type input grid area output grid area'/& +! 1x,' 10**6 km**2 10**6 km**2 ') +! 2002 format (1x,'fmax ',f14.3,f17.3) +! 2004 format (1x,'all surface ',f14.3,f17.3) +! end if + + ! Close the input file + call pio_closefile(pioid) + call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) + + ! Release memory + deallocate (fmax_i) + deallocate (frac_i) + deallocate (frac_o) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) + + if (root_task) then + write (ndiag,'(a)') 'Successfully made %fmax' + write (ndiag,*) + end if + + end subroutine mksoilfmax + +end module mksoilfmaxMod diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 new file mode 100644 index 0000000000..868060c1a2 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -0,0 +1,355 @@ +module mksoiltexMod + + !----------------------------------------------------------------------- + ! Make soil data (texture) + !----------------------------------------------------------------------- + + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkutilsMod , only : chkerr + use mkvarctl + use mkvarpar + + implicit none + private ! By default make data private + + public :: mksoiltex ! Set soil texture + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + +!================================================================================= +contains +!================================================================================= + + subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o, rc) + ! + ! make %sand and %clay from IGBP soil data, which includes + ! igbp soil 'mapunits' and their corresponding textures + ! + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + real(r8) , intent(inout) :: sand_o(:,:) ! % sand (output grid) + real(r8) , intent(inout) :: clay_o(:,:) ! % clay (output grid) + integer , intent(inout) :: mapunit_o(:) + integer , intent(out) :: rc + + ! local variables + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + type(var_desc_t) :: pio_varid + integer :: pio_vartype + integer :: dimid + integer :: ni,no + integer :: ns_i, ns_o + integer :: n,l,m + integer :: gindex, lindex + character(len=38) :: typ ! soil texture based on ... + integer :: nlay ! number of soil layers + integer :: mapunittemp ! temporary igbp soil mapunit + integer :: maxovr + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: sand_i(:,:) ! input grid: percent sand + real(r8), allocatable :: clay_i(:,:) ! input grid: percent clay + integer, parameter :: num=2 ! set soil mapunit number + integer, parameter :: nlsm=4 ! number of soil textures + character(len=38) :: soil(0:nlsm) ! name of each soil texture + real(r8) :: gast_i(0:nlsm) ! global area, by texture type + real(r8) :: gast_o(0:nlsm) ! global area, by texture type + real(r8) :: wt ! map overlap weight + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + integer :: rcode, ier ! error status + real(r8) :: sumtex + integer :: mapunit_value_max + integer :: mapunit_value_min + integer :: mapunit_value + integer :: nmax + integer :: loop, nloops + real(r4) :: max_value + integer :: max_index(1) + real(r8), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits + real(r8), allocatable :: data_i(:,:) + real(r8), allocatable :: data_o(:,:) + real(r8), allocatable :: global_max_value(:) + real(r8), allocatable :: global_max_index(:) + character(len=*), parameter :: subname = 'mksoiltex' + !----------------------------------------------------------------------- + + if (root_task) then + write (ndiag,'(a)') 'Attempting to make %sand and %clay .....' + end if + + if ( soil_clay_override /= unsetsoil )then + write(6,*) 'Replace soil clay % for all points with: ', soil_clay_override + if ( soil_sand_override == unsetsoil )then + write (6,*) subname//':error: soil_clay set, but NOT soil_sand' + call shr_sys_abort() + end if + end if + if ( soil_sand_override /= unsetsoil )then + write(6,*) 'Replace soil sand % for all points with: ', soil_sand_override + if ( soil_clay_override == unsetsoil )then + write (6,*) subname//':error: soil_sand set, but NOT soil_clay' + call shr_sys_abort() + end if + sumtex = soil_sand_override + soil_clay_override + if ( sumtex < 0.0_r8 .or. sumtex > 100.0_r8 )then + write (6,*) subname//':error: soil_sand and soil_clay out of bounds: sand, clay = ', & + soil_sand_override, soil_clay_override + call shr_sys_abort() + end if + end if + + if (soil_sand_override /= unsetsoil .and. soil_clay_override /= unsetsoil) then + if (root_task) then + write(ndiag,'(a,i8)') ' Overriding soil color for all points with: ', soil_color_override + end if + sand_o(:,:) = soil_sand_override + clay_o(:,:) = soil_clay_override + RETURN + end if + + ! Define the model surface types: 0:4 + soil(0) = 'no soil: ocean, glacier, lake, no data' + soil(1) = 'clays ' + soil(2) = 'sands ' + soil(3) = 'loams ' + soil(4) = 'silts ' + + ! Open input data file + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + + ! Read in input mesh + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Create a route handle between the input and output mesh + call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + + ! Determine ns_i and allocate data_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_o and allocate data_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Read in mapunit data + allocate(mapunit_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'MAPUNITS', mesh_i, mapunit_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + + ! TODO: Determine minimum and maximum mapunit values across all processors- for now hardwire + + ! Now determine data_i as a real 2d array - for every possible soil color create a global + ! field with gridcells equal to 1 for that soil color and zero elsewhere + rcode = pio_inq_dimid (pioid, 'max_value_mapunit', dimid) + rcode = pio_inq_dimlen (pioid, dimid, mapunit_value_max) + + mapunit_value_min = 0 + nmax = 100 + nloops = (mapunit_value_max - mapunit_value_min + nmax)/nmax + !write(6,*)'nloops = ',nloops + + allocate(global_max_value(ns_o)) ; global_max_value(:) = -999. + if (ier/=0) call shr_sys_abort() + allocate(global_max_index(ns_o)) ; global_max_index(:) = 0 + if (ier/=0) call shr_sys_abort() + allocate(data_i(nmax,ns_i)) + if (ier/=0) call shr_sys_abort() + allocate(data_o(nmax,ns_o)) + if (ier/=0) call shr_sys_abort() + + mapunit_o(:) = 0 + do loop = 1,nloops + data_i(:,:) = 0._r8 + do lindex = 0,nmax-1 + mapunit_value = lindex + (nmax*(loop-1)) + if (mapunit_value <= mapunit_value_max) then + do ni = 1,ns_i + if (int(mapunit_i(ni)) == mapunit_value) then + data_i(lindex+1,ni) = 1._r4 + end if + end do + end if + end do + + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 1, nmax, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + do no = 1,ns_o + max_index = maxloc(data_o(:,no)) + max_value = data_o(max_index(1),no) + if ( max_value > global_max_value(no)) then + global_max_value(no) = max_value + mapunit_o(no) = max_index(1) + (nmax*(loop-1)) - 1 + if (mapunit_o(no) < 0 .or. mapunit_o(no) > mapunit_value_max) then + call shr_sys_abort('mapunit_o is invalid') + end if + end if + end do + end do + + deallocate(data_i) + deallocate(data_o) + + ! Get dimensions from input file and allocate memory for sand_i and clay_i + rcode = pio_inq_dimid (pioid, 'number_of_layers', dimid) + rcode = pio_inq_dimlen (pioid, dimid, nlay) + allocate(sand_i(mapunit_value_max,nlay), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(clay_i(mapunit_value_max,nlay), stat=ier) + if (ier/=0) call shr_sys_abort() + + ! read in sand_i and clay_i (they will read in total on all processors) + rcode = pio_inq_varid(pioid, 'PCT_SAND', pio_varid) + rcode = pio_get_var(pioid, pio_varid, sand_i) + rcode = pio_inq_varid(pioid, 'PCT_CLAY', pio_varid) + rcode = pio_get_var(pioid, pio_varid, clay_i) + + ! Set soil texture as follows: + ! a. Use dominant igbp soil mapunit based on area of overlap unless 'no data' is dominant + ! b. If this has no data, use loam for soil texture + + do no = 1,ns_o + if (mapunit_o(no) > 0) then + ! valid value is obtained + if (mapunit_o(no) > mapunit_value_max) then + call shr_sys_abort("mapunit_o is out of bounds") + end if + do l = 1, nlay + sand_o(no,l) = sand_i(mapunit_o(no),l) + clay_o(no,l) = clay_i(mapunit_o(no),l) + end do + else + ! use loam + do l = 1, nlay + sand_o(no,l) = 43. + clay_o(no,l) = 18. + end do + end if + end do + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global area of each soil type on input and output grids + ! ----------------------------------------------------------------- + + ! input grid: global areas by texture class + +! gast_i(:) = 0. +! do l = 1, nlay +! do ni = 1,ns_i +! mapunittemp = nint(mapunit_i(ni)) +! if (mapunittemp==0) then +! typ = 'no soil: ocean, glacier, lake, no data' +! else if (clay_i(mapunittemp,l) >= 40.) then +! typ = 'clays' +! else if (sand_i(mapunittemp,l) >= 50.) then +! typ = 'sands' +! else if (clay_i(mapunittemp,l)+sand_i(mapunittemp,l) < 50.) then +! if (mask(ni) /= 0.) then +! typ = 'silts' +! else !if (mask(ni) == 0.) then no data +! typ = 'no soil: ocean, glacier, lake, no data' +! end if +! else +! typ = 'loams' +! end if +! do m = 0, nlsm +! if (typ == soil(m)) go to 101 +! end do +! write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunittemp,l), & +! ' clay = ',clay_i(mapunittemp,l), & +! ' not assigned to soil type for input grid lon,lat,layer = ',ni,l +! call shr_sys_abort() +! 101 continue +! gast_i(m) = gast_i(m) + area_src(ni)*mask(ni)*re**2 +! end do +! end do + +! ! output grid: global areas by texture class + +! gast_o(:) = 0. +! do l = 1, nlay +! do no = 1,ns_o +! if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then +! typ = 'no soil: ocean, glacier, lake, no data' +! else if (clay_o(no,l) >= 40.) then +! typ = 'clays' +! else if (sand_o(no,l) >= 50.) then +! typ = 'sands' +! else if (clay_o(no,l)+sand_o(no,l) < 50.) then +! typ = 'silts' +! else +! typ = 'loams' +! end if +! do m = 0, nlsm +! if (typ == soil(m)) go to 102 +! end do +! write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & +! ' clay = ',clay_o(no,l), & +! ' not assigned to soil type for output grid lon,lat,layer = ',no,l +! call shr_sys_abort() +! 102 continue +! gast_o(m) = gast_o(m) + area_dst(no)*frac_o(no)*re**2 +! end do +! end do + +! ! Diagnostic output + +! write (ndiag,*) +! write (ndiag,'(1x,70a1)') ('=',l=1,70) +! write (ndiag,*) 'Soil Texture Output' +! write (ndiag,'(1x,70a1)') ('=',l=1,70) +! write (ndiag,*) + +! write (ndiag,*) 'The following table of soil texture classes is for comparison only.' +! write (ndiag,*) 'The actual data is continuous %sand, %silt and %clay not textural classes' +! write (ndiag,*) + +! write (ndiag,*) +! write (ndiag,'(1x,70a1)') ('.',l=1,70) +! write (ndiag,1001) +! 1001 format (1x,'soil texture class',17x,' input grid area output grid area',/ & +! 1x,33x,' 10**6 km**2',' 10**6 km**2') +! write (ndiag,'(1x,70a1)') ('.',l=1,70) +! write (ndiag,*) + +! do l = 0, nlsm +! write (ndiag,1002) soil(l),gast_i(l)*1.e-6,gast_o(l)*1.e-6 +! 1002 format (1x,a38,f16.3,f17.3) +! end do + + ! Deallocate dynamic memory + deallocate (sand_i,clay_i,mapunit_i) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) + + if (root_task) then + write (ndiag,'(a)') 'Successfully made %sand and %clay' + write (ndiag,*) + end if + + end subroutine mksoiltex + +end module mksoiltexMod diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 097501589a..1d516b8a2b 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -76,6 +76,10 @@ program mksurfdata ! all_urban --------- If entire area is urban ! all_veg ----------- If entire area is to be vegetated (pft_idx and pft_frc then required) ! no_inlandwet ------ If wetland should be set to 0% over land + ! soil_color_override -------- If you want to change the soil_color to this value everywhere + ! soil_clay --------- If you want to change the soil_clay % to this value everywhere + ! soil_fmax --------- If you want to change the soil_fmax to this value everywhere + ! soil_sand --------- If you want to change the soil_sand % to this value everywhere ! pft_idx ----------- If you want to change to 100% veg covered with given PFT indices ! pft_frc ----------- Fractions that correspond to the pft_idx above ! ================== @@ -92,14 +96,11 @@ program mksurfdata use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs use shr_sys_mod , only : shr_sys_abort -#ifdef TODO +#ifdef TODO use mklaiMod , only : mklai use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride - use mksoilMod , only : soil_sand, soil_clay, mksoiltex, mksoilInit - use mksoilMod , only : soil_fmax, mkfmax - use mksoildepthMod , only : mksoildepth use mkvocefMod , only : mkvocef use mkglacierregionMod , only : mkglacierregion use mkglcmecMod , only : nglcec, mkglcmec, mkglcmecInit, mkglacier @@ -115,6 +116,9 @@ program mksurfdata #else use mkurbanparCommonMod #endif + use mksoiltexMod , only : mksoiltex + use mksoilfmaxMod , only : mksoilfmax + use mksoildepthMod , only : mksoildepth use mksoilcolMod , only : mksoilcol use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, numurbl use mklanwatMod , only : mklakwat @@ -130,12 +134,12 @@ program mksurfdata implicit none ! local variables - type(ESMF_Mesh) :: mesh_model + type(ESMF_Mesh) :: mesh_model type(ESMF_Field) :: field_model integer :: nsoilcol ! number of model color classes integer :: k,m,n ! indices integer :: ni,nj,ns_o ! indices - integer :: lsize_o + integer :: lsize_o integer :: ier ! error status integer :: nfdyn ! unit numbers integer :: omode ! netCDF output mode @@ -150,7 +154,7 @@ program mksurfdata ! pio variables type(file_desc_t) :: pioid type(var_desc_t) :: pio_varid - type(io_desc_t) :: pio_iodesc + type(io_desc_t) :: pio_iodesc ! data arrays real(r8), pointer :: landfrac_pft(:) ! PFT data: % land per gridcell @@ -182,10 +186,11 @@ program mksurfdata real(r8), pointer :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell integer , pointer :: urban_region(:) ! urban region ID real(r8), pointer :: elev(:) ! glc elevation (m) - real(r8), pointer :: fmax(:) ! fractional saturated area integer , pointer :: soil_color(:) ! soil color + real(r8), pointer :: fmaxsoil(:) ! soil_fractional saturated area real(r8), pointer :: pctsand(:,:) ! soil texture: percent sand real(r8), pointer :: pctclay(:,:) ! soil texture: percent clay + integer , pointer :: mapunits(:) ! input grid: igbp soil mapunits real(r8), pointer :: ef1_btr(:) ! Isoprene emission factor for broadleaf real(r8), pointer :: ef1_fet(:) ! Isoprene emission factor for fine/everg real(r8), pointer :: ef1_fdt(:) ! Isoprene emission factor for fine/dec @@ -313,11 +318,10 @@ program mksurfdata ! ---------------------------------------------------------------------- #ifdef TODO - call mksoilInit( ) call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) allocate ( elevclass(nglcec+1) ) call mkglcmecInit (elevclass) -#endif +#endif call mkurbanInit (mksrf_furban) ! ---------------------------------------------------------------------- @@ -353,24 +357,6 @@ program mksurfdata allocate ( topoglcmec(lsize_o,nglcec)) ; topoglcmec(:,:) = spval #endif - ! lake/wetland properties - allocate ( pctlak(lsize_o)) ; pctlak(:) = spval - allocate ( pctwet(lsize_o)) ; pctwet(:) = spval - allocate ( lakedepth(lsize_o)) ; lakedepth(:) = spval - - ! urban properties - allocate ( pcturb(lsize_o)) ; pcturb(:) = spval - allocate ( urban_classes(lsize_o,numurbl)) ; urban_classes(:,:) = spval - allocate ( urban_classes_g(lsize_o,numurbl)); urban_classes_g(:,:) = spval - allocate ( urban_region(lsize_o)) ; urban_region(:) = -999 - - ! soil properties - allocate ( pctsand(lsize_o,nlevsoi)) ; pctsand(:,:) = spval - allocate ( pctclay(lsize_o,nlevsoi)) ; pctclay(:,:) = spval - allocate ( soil_color(lsize_o)) ; soil_color(:) = -999 - allocate ( soildepth(lsize_o)) ; soildepth(:) = spval - allocate ( organic(lsize_o,nlevsoi)) ; organic(:,:) = spval - ! vic properties allocate ( vic_binfl(lsize_o)) ; vic_binfl(:) = spval allocate ( vic_ws(lsize_o)) ; vic_ws(:) = spval @@ -393,7 +379,7 @@ program mksurfdata ! call mkpft( mapfname=map_fpft, fpft=mksrf_fvegtyp, ndiag=ndiag, & ! pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft) - ! ! Create harvesting data at model resolution + ! Create harvesting data at model resolution ! if (all_veg) then ! ! In this case, we don't call mkharvest, so we want the harvest variables to be ! ! initialized reasonably. @@ -409,24 +395,50 @@ program mksurfdata ! -------------------------------------------------- ! begin working + ! Make soil texture [pctsand, pctclay] + allocate(mapunits(lsize_o)) ; mapunits(:) = 0 + allocate(pctsand(lsize_o,nlevsoi)) ; pctsand(:,:) = spval + allocate(pctclay(lsize_o,nlevsoi)) ; pctclay(:,:) = spval + call mksoiltex( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pctsand, pctclay, mapunits, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') + + ! Make soil fmax [fmaxsoil] + allocate(fmaxsoil(lsize_o)); fmaxsoil(:) = spval + !call mksoilfmax( mksrf_fmax_mesh, mksrf_fmax, mesh_model, fmaxsoil, rc) + !if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') + + ! Make soil depth data [soildepth] from [soildepthf] + allocate ( soildepth(lsize_o)); soildepth(:) = spval + !call mksoildepth( mksrf_fsoildepth_mesh, mksrf_fsoildepth, mesh_model, soildepth, rc) + !if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') + ! Make urban fraction [pcturb] from [furban] dataset - call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, all_veg, pcturb, urban_classes, urban_region, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') + allocate (pcturb(lsize_o)) ; pcturb(:) = spval + allocate (urban_classes(lsize_o,numurbl)) ; urban_classes(:,:) = spval + allocate (urban_classes_g(lsize_o,numurbl)); urban_classes_g(:,:) = spval + allocate (urban_region(lsize_o)) ; urban_region(:) = -999 + ! call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, all_veg, pcturb, urban_classes, urban_region, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') ! Make soil color classes [soicol] [fsoicol] - call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, soil_color, nsoilcol, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilcol') + allocate (soil_color(lsize_o)); soil_color(:) = -999 + ! call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, soil_color, nsoilcol, rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilcol') ! Make organic matter density [organic] [forganic] - call mkorganic( mksrf_forganic_mesh, mksrf_forganic, mesh_model, organic, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') + allocate ( organic(lsize_o,nlevsoi)); organic(:,:) = spval + ! call mkorganic( mksrf_forganic_mesh, mksrf_forganic, mesh_model, organic, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] - zero_out_lake = all_urban .or. all_veg - zero_out_wetland = all_urban .or. all_veg .or. no_inlandwet - call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & - zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') + allocate ( pctlak(lsize_o)) ; pctlak(:) = spval + allocate ( pctwet(lsize_o)) ; pctwet(:) = spval + allocate ( lakedepth(lsize_o)) ; lakedepth(:) = spval + zero_out_lake = (all_urban .or. all_veg) + zero_out_wetland = (all_urban .or. all_veg .or. no_inlandwet) + ! call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & + ! zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) ! end working @@ -439,22 +451,12 @@ program mksurfdata ! call mkglacierregion ( mapfname=map_fglacierregion, & ! datfname=mksrf_fglacierregion, ndiag=ndiag, glacier_region_o = glacier_region) - ! ! Make soil texture [pctsand, pctclay] [fsoitex] - ! call mksoiltex ( mapfname=map_fsoitex, datfname=mksrf_fsoitex, ndiag=ndiag, sand_o=pctsand, clay_o=pctclay) - - ! ! Make fmax [fmax] from [fmax] dataset - ! allocate(fmax(lsize_o)); fmax(:) = spval - ! call mkfmax ( mapfname=map_fmax, datfname=mksrf_fmax, ndiag=ndiag, fmax_o=fmax) - ! ! Make GDP data [gdp] from [gdp] ! call mkgdp ( mapfname=map_fgdp, datfname=mksrf_fgdp, ndiag=ndiag, gdp_o=gdp) ! ! Make peat data [fpeat] from [peatf] ! call mkpeat ( mapfname=map_fpeat, datfname=mksrf_fpeat, ndiag=ndiag, peat_o=fpeat) - ! ! Make soil depth data [soildepth] from [soildepthf] - ! call mksoildepth ( mapfname=map_fsoildepth, datfname=mksrf_fsoildepth, ndiag=ndiag, soildepth_o=soildepth) - ! ! Make agricultural fire peak month data [abm] from [abm] ! call mkagfirepkmon ( mapfname=map_fabm, datfname=mksrf_fabm, ndiag=ndiag, agfirepkmon_o=agfirepkmon) @@ -496,10 +498,25 @@ program mksurfdata ! Modify interpolated fields based on additional constrants ! ---------------------------------------------------------------------- + ! ! Truncate all percentage fields on output grid. This is needed to + ! ! insure that wt is zero (not a very small number such as + ! ! 1e-16) where it really should be zero + + !DEBUG do n = 1,lsize_o - !pctlak(n) = float(nint(pctlak(n))) - !pctwet(n) = float(nint(pctwet(n))) + if (pctlak(n) < 101.) then + pctlak(n) = float(nint(pctlak(n))) + pctwet(n) = float(nint(pctwet(n))) + end if + do k = 1,nlevsoi + if (pctsand(n,k) < 101.) then + pctsand(n,k) = float(nint(pctsand(n,k))) + pctclay(n,k) = float(nint(pctclay(n,k))) + end if + end do end do + !DEBUG + call ESMF_LogWrite("After fixes", ESMF_LOGMSG_INFO) ! do n = 1,lsize_o @@ -507,13 +524,13 @@ program mksurfdata ! ! insure that wt is zero (not a very small number such as ! ! 1e-16) where it really should be zero - ! do k = 1,nlevsoi - ! pctsand(n,k) = float(nint(pctsand(n,k))) - ! pctclay(n,k) = float(nint(pctclay(n,k))) - ! end do - ! pctlak(n) = float(nint(pctlak(n))) - ! pctwet(n) = float(nint(pctwet(n))) - ! pctgla(n) = float(nint(pctgla(n))) + ! do k = 1,nlevsoi + ! pctsand(n,k) = float(nint(pctsand(n,k))) + ! pctclay(n,k) = float(nint(pctclay(n,k))) + ! end do + ! pctlak(n) = float(nint(pctlak(n))) + ! pctwet(n) = float(nint(pctwet(n))) + ! pctgla(n) = float(nint(pctgla(n))) ! ! Assume wetland, glacier and/or lake when dataset landmask implies ocean ! ! (assume medium soil color (15) and loamy texture). @@ -637,13 +654,15 @@ program mksurfdata call mkfile_fsurdat( mksrf_fgrid_mesh_nx, mksrf_fgrid_mesh_ny, mesh_model, dynlanduse=.false., & pctlak=pctlak, pctwet=pctwet, lakedepth=lakedepth, organic=organic, & soil_color=soil_color, nsoilcol=nsoilcol, & - urban_classes_g=urban_classes_g, urban_region=urban_region) + urban_classes_g=urban_classes_g, urban_region=urban_region, & + pctsand=pctsand, pctclay=pctclay, mapunits=mapunits, fmaxsoil=fmaxsoil, soildepth=soildepth) call ESMF_LogWrite(subname//'successfully created file '//trim(fsurdat), ESMF_LOGMSG_INFO) end if ! if (fsurdat /= ' ') ! Deallocate arrays NOT needed for dynamic-pft section of code deallocate ( lakedepth ) + deallocate ( soil_color ) #ifdef TODO deallocate ( organic ) @@ -653,7 +672,6 @@ program mksurfdata deallocate ( elevclass ) deallocate ( fmax ) deallocate ( pctsand, pctclay ) - deallocate ( soil_color ) deallocate ( gdp, fpeat, agfirepkmon ) deallocate ( soildepth ) deallocate ( topo_stddev, slope ) @@ -871,7 +889,7 @@ subroutine change_landuse( dynpft, lsize_o, mesh_o) character(len=32) :: subname = 'change_landuse' ! subroutine name !----------------------------------------------------------------------- - ! + ! do n = 1,lsize_o ! TODO: define latc diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index 7c323a694f..5ab9bf0979 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -40,8 +40,15 @@ module mkvarctl public :: MPI_MAX public :: MPI_SUCCESS - real(r8), public, parameter :: spval = 1.e36 ! special value - integer, public, parameter :: ispval = -9999 ! special value + real(r8), public, parameter :: spval = 1.e36 ! special value + integer, public, parameter :: ispval = -9999 ! special value + integer , public, parameter :: unsetcol = -999 ! flag to indicate soil color NOT set + real(r8), public, parameter :: unsetsoil = -999.99_r8 ! Flag to signify soil texture override not set + + integer , public :: soil_color_override + real(r8), public :: soil_sand_override + real(r8), public :: soil_clay_override + real(r8), public :: soil_fmax_override character(len=256) , public :: fgrddat ! grid data file character(len=256) , public :: fsurdat ! output surface data file name (if blank, do not output a surface dataset) @@ -69,54 +76,73 @@ module mkvarctl integer , public :: mksrf_fgrid_mesh_ny character(len=512), public :: mksrf_fvegtyp = ' ' ! vegetation data file name + character(len=512), public :: mksrf_fvegtyp_mesh = ' ' ! vegetation mesh file name + character(len=512), public :: mksrf_fhrvtyp = ' ' ! harvest data file name - character(len=512), public :: mksrf_fsoitex = ' ' ! soil texture data file name + character(len=512), public :: mksrf_fhrvtyp_mesh = ' ' ! harvest mesh file name + character(len=512), public :: mksrf_forganic = ' ' ! organic matter data file name + character(len=512), public :: mksrf_forganic_mesh = ' ' ! organic matter mesh file name + character(len=512), public :: mksrf_fsoicol = ' ' ! soil color data file name - character(len=512), public :: mksrf_fabm = ' ' ! ag fire peak month and - character(len=512), public :: mksrf_fpeat = ' ' ! peatlands and - character(len=512), public :: mksrf_fsoildepth = ' ' ! soil depth file name - character(len=512), public :: mksrf_fgdp = ' ' ! gdp data file names - character(len=512), public :: mksrf_flakwat = ' ' ! inland lake data file name - character(len=512), public :: mksrf_fwetlnd = ' ' ! inland wetlands data file name - character(len=512), public :: mksrf_furban = ' ' ! urban data file name - character(len=512), public :: mksrf_fglacier = ' ' ! glacier data file name - character(len=512), public :: mksrf_fglacierregion = ' ' ! glacier region data file name - character(len=512), public :: mksrf_furbtopo = ' ' ! urban topography data file name - character(len=512), public :: mksrf_fmax = ' ' ! fmax data file name - character(len=512), public :: mksrf_flai = ' ' ! lai data filename - character(len=512), public :: mksrf_fdynuse = ' ' ! ascii file containing names of dynamic land use files - character(len=512), public :: mksrf_fvocef = ' ' ! VOC Emission Factor data file name - character(len=512), public :: mksrf_ftopostats = ' ' ! topography statistics data file name - character(len=512), public :: mksrf_fvic = ' ' ! VIC parameters data file name - character(len=512), public :: mksrf_irrig = ' ' ! TODO: should this namelist be here? + character(len=512), public :: mksrf_fsoicol_mesh = ' ' ! soil color mesh file name - character(len=512), public :: mksrf_fvegtyp_mesh = ' ' ! vegetation mesh file name - character(len=512), public :: mksrf_fhrvtyp_mesh = ' ' ! harvest mesh file name + character(len=512), public :: mksrf_fsoitex = ' ' ! soil texture data file name character(len=512), public :: mksrf_fsoitex_mesh = ' ' ! soil texture mesh file name - character(len=512), public :: mksrf_forganic_mesh = ' ' ! organic matter mesh file name - character(len=512), public :: mksrf_fsoicol_mesh = ' ' ! soil color mesh file name + + character(len=512), public :: mksrf_fmax = ' ' ! fmax data file name + character(len=512), public :: mksrf_fmax_mesh = ' ' ! fmax mesh file name + + character(len=512), public :: mksrf_fsoildepth = ' ' ! soil depth file name + character(len=512), public :: mksrf_fsoildepth_mesh = ' ' ! soil depth file name + + character(len=512), public :: mksrf_fabm = ' ' ! ag fire peak month and character(len=512), public :: mksrf_fabm_mesh = ' ' ! ag fire peak month and + + character(len=512), public :: mksrf_fpeat = ' ' ! peatlands and character(len=512), public :: mksrf_fpeat_mesh = ' ' ! peatlands and - character(len=512), public :: mksrf_fsoildepth_mesh = ' ' ! soil depth file name + + character(len=512), public :: mksrf_fgdp = ' ' ! gdp data file names character(len=512), public :: mksrf_fgdp_mesh = ' ' ! gdp mesh file names + + character(len=512), public :: mksrf_flakwat = ' ' ! inland lake data file name character(len=512), public :: mksrf_flakwat_mesh = ' ' ! inland lake mesh file name + + character(len=512), public :: mksrf_fwetlnd = ' ' ! inland wetlands data file name character(len=512), public :: mksrf_fwetlnd_mesh = ' ' ! inland wetlands mesh file name + + character(len=512), public :: mksrf_furban = ' ' ! urban data file name character(len=512), public :: mksrf_furban_mesh = ' ' ! urban mesh file name + + character(len=512), public :: mksrf_fglacier = ' ' ! glacier data file name character(len=512), public :: mksrf_fglacier_mesh = ' ' ! glacier mesh file name + + character(len=512), public :: mksrf_fglacierregion = ' ' ! glacier region data file name character(len=512), public :: mksrf_fglacierregion_mesh = ' ' ! glacier region mesh file name + + character(len=512), public :: mksrf_furbtopo = ' ' ! urban topography data file name character(len=512), public :: mksrf_furbtopo_mesh = ' ' ! urban topography mesh file name - character(len=512), public :: mksrf_fmax_mesh = ' ' ! fmax mesh file name + + character(len=512), public :: mksrf_flai = ' ' ! lai data filename character(len=512), public :: mksrf_flai_mesh = ' ' ! lai mesh filename - character(len=512), public :: mksrf_fhrv_mesh = ' ' ! harvest mesh filename - character(len=512), public :: mksrf_fdynuse_mesh_mesh_mesh = ' ' ! ascii file containing names of dynamic land use files + + character(len=512), public :: mksrf_fdynuse = ' ' ! ascii file containing names of dynamic land use files + character(len=512), public :: mksrf_fdynuse_mesh = ' ' ! ascii file containing names of dynamic land use files + + character(len=512), public :: mksrf_fvocef = ' ' ! VOC Emission Factor data file name character(len=512), public :: mksrf_fvocef_mesh = ' ' ! VOC Emission Factor mesh file name + + character(len=512), public :: mksrf_ftopostats = ' ' ! topography statistics data file name character(len=512), public :: mksrf_ftopostats_mesh = ' ' ! topography statistics mesh file name + + character(len=512), public :: mksrf_fvic = ' ' ! VIC parameters data file name character(len=512), public :: mksrf_fvic_mesh = ' ' ! VIC parameters mesh file name + + character(len=512), public :: mksrf_irrig = ' ' ! TODO: should this namelist be here? character(len=512), public :: mksrf_irrig_mesh = ' ' ! TODO: should this namelist be here? integer , public :: numpft = 16 ! number of plant types - ! + ! Variables to override data read in with ! (all_urban is mostly for single-point mode, but could be used for sensitivity studies) logical, public :: all_urban ! output ALL data as 100% covered in urban @@ -139,46 +165,47 @@ subroutine read_namelist_input() namelist /mksurfdata_input/ & mksrf_fvegtyp, & + mksrf_fvegtyp_mesh, & mksrf_fhrvtyp, & + mksrf_fhrvtyp_mesh, & mksrf_fsoitex, & + mksrf_fsoitex_mesh, & mksrf_forganic, & + mksrf_forganic_mesh, & mksrf_fsoicol, & + mksrf_fsoicol_mesh, & mksrf_fvocef, & + mksrf_fvocef_mesh, & mksrf_flakwat, & + mksrf_flakwat_mesh, & mksrf_fwetlnd, & + mksrf_fwetlnd_mesh, & mksrf_fglacier, & + mksrf_fglacier_mesh, & mksrf_fglacierregion, & + mksrf_fglacierregion_mesh, & mksrf_furbtopo, & + mksrf_furbtopo_mesh, & mksrf_fmax, & + mksrf_fmax_mesh, & mksrf_furban, & + mksrf_furban_mesh, & mksrf_flai, & + mksrf_flai_mesh, & mksrf_fdynuse, & + mksrf_fdynuse_mesh, & mksrf_fgdp, & - mksrf_fpeat, & - mksrf_fsoildepth, & - mksrf_fabm, & - mksrf_ftopostats, & - mksrf_fvic, & - mksrf_flai_mesh, & - mksrf_fhrv_mesh, & - mksrf_forganic_mesh, & - mksrf_fsoicol_mesh, & - mksrf_fsoitex_mesh, & - mksrf_fmax_mesh, & - mksrf_flakwat_mesh, & - mksrf_fwetlnd_mesh, & - mksrf_fvocef_mesh, & - mksrf_furban_mesh, & - mksrf_furbtopo_mesh, & - mksrf_fglacier_mesh, & - mksrf_fglacierregion_mesh, & mksrf_fgdp_mesh, & + mksrf_fpeat, & mksrf_fpeat_mesh, & + mksrf_fsoildepth, & mksrf_fsoildepth_mesh, & + mksrf_fabm, & mksrf_fabm_mesh, & + mksrf_ftopostats, & mksrf_ftopostats_mesh, & + mksrf_fvic, & mksrf_fvic_mesh, & - mksrf_fvegtyp_mesh, & mksrf_fgrid_mesh, & mksrf_fgrid_mesh_nx, & mksrf_fgrid_mesh_ny, & @@ -186,6 +213,10 @@ subroutine read_namelist_input() all_veg, & all_urban, & no_inlandwet, & + soil_color_override, & + soil_sand_override, & + soil_clay_override, & + soil_fmax_override, & #ifdef TODO nglcec, & pft_idx, & @@ -212,6 +243,10 @@ subroutine read_namelist_input() all_urban = .false. all_veg = .false. no_inlandwet = .true. + soil_color_override = unsetcol + soil_sand_override = unsetsoil + soil_clay_override = unsetsoil + soil_fmax_override = unsetsoil urban_skip_abort_on_invalid_data_check = .false. ! default value for bug work around if (root_task) then @@ -232,52 +267,73 @@ subroutine read_namelist_input() end if call mpi_bcast (mksrf_fgrid_mesh, len(mksrf_fgrid_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fgrid_mesh_nx, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (mksrf_fgrid_mesh_ny, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (mksrf_fvegtyp, len(mksrf_fvegtyp), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fhrvtyp, len(mksrf_fhrvtyp), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fsoitex, len(mksrf_fsoitex), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_forganic, len(mksrf_forganic), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fsoicol, len(mksrf_fsoicol), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fabm, len(mksrf_fabm), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fpeat, len(mksrf_fpeat), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fsoildepth, len(mksrf_fsoildepth), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fgdp, len(mksrf_fgdp), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_flakwat, len(mksrf_flakwat), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fwetlnd, len(mksrf_fwetlnd), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_furban, len(mksrf_furban), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fglacier, len(mksrf_fglacier), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fglacierregion, len(mksrf_fglacierregion), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_furbtopo, len(mksrf_furbtopo), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fmax, len(mksrf_fmax), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_flai, len(mksrf_flai), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fdynuse, len(mksrf_fdynuse), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fvocef, len(mksrf_fvocef), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_ftopostats, len(mksrf_ftopostats), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fvic, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fvegtyp_mesh, len(mksrf_fvegtyp_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fhrvtyp, len(mksrf_fhrvtyp), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fhrvtyp_mesh, len(mksrf_fhrvtyp_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fsoitex, len(mksrf_fsoitex), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fsoitex_mesh, len(mksrf_fsoitex_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fmax, len(mksrf_fmax), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fmax_mesh, len(mksrf_fmax_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_forganic, len(mksrf_forganic), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_forganic_mesh, len(mksrf_forganic_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fsoicol, len(mksrf_fsoicol), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fsoicol_mesh, len(mksrf_fsoicol_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fsoildepth, len(mksrf_fsoildepth), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fsoildepth_mesh, len(mksrf_fsoildepth_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fabm, len(mksrf_fabm), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fabm_mesh, len(mksrf_fabm_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fpeat, len(mksrf_fpeat), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fpeat_mesh, len(mksrf_fpeat_mesh), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fsoildepth_mesh, len(mksrf_fsoildepth_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fgdp, len(mksrf_fgdp), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fgdp_mesh, len(mksrf_fgdp_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_flakwat, len(mksrf_flakwat), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_flakwat_mesh, len(mksrf_flakwat_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fwetlnd, len(mksrf_fwetlnd), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fwetlnd_mesh, len(mksrf_fwetlnd_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_furban, len(mksrf_furban), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_furban_mesh, len(mksrf_furban_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_furbtopo, len(mksrf_furbtopo), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_furbtopo_mesh, len(mksrf_furbtopo_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fglacier, len(mksrf_fglacier), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fglacier_mesh, len(mksrf_fglacier_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fglacierregion, len(mksrf_fglacierregion), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fglacierregion_mesh, len(mksrf_fglacierregion_mesh), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_furbtopo_mesh, len(mksrf_furbtopo_mesh), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fmax_mesh, len(mksrf_fmax_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_flai, len(mksrf_flai), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_flai_mesh, len(mksrf_flai_mesh), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fdynuse_mesh_mesh_mesh, len(mksrf_fdynuse_mesh_mesh_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fvocef, len(mksrf_fvocef), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fvocef, len(mksrf_fvocef), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_ftopostats, len(mksrf_ftopostats), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_ftopostats, len(mksrf_ftopostats), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fvic, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (fsurdat, len(fsurdat), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fvic_mesh, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fgrid_mesh_nx, 1, MPI_INTEGER, 0, mpicom, ier) - call mpi_bcast (mksrf_fgrid_mesh_ny, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (mksrf_fdynuse, len(mksrf_fdynuse), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fdynuse_mesh, len(mksrf_fdynuse_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (fsurdat, len(fsurdat), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (outnc_dims, 1, MPI_INTEGER, 0, mpicom, ier) call mpi_bcast (outnc_large_files, 1, MPI_LOGICAL, 0, mpicom, ier) @@ -285,9 +341,15 @@ subroutine read_namelist_input() call mpi_bcast (outnc_1d, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (outnc_vic, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (outnc_3dglc, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (all_urban, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (all_veg, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (no_inlandwet, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (soil_color_override, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (soil_sand_override, 1, MPI_REAL, 0, mpicom, ier) + call mpi_bcast (soil_clay_override, 1, MPI_REAL, 0, mpicom, ier) + call mpi_bcast (soil_fmax_override, 1, MPI_REAL, 0, mpicom, ier) + call mpi_bcast (urban_skip_abort_on_invalid_data_check, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (numpft, 1, MPI_INTEGER, 0, mpicom, ier) @@ -366,7 +428,7 @@ subroutine write_namelist_input() write(ndiag,'(a)')' mesh for peatlands '//trim(mksrf_fpeat_mesh) write(ndiag,*) write(ndiag,'(a)')' harvest from: '//trim(mksrf_fhrvtyp) - write(ndiag,'(a)')' mesh for harvest '//trim(mksrf_fhrv_mesh) + write(ndiag,'(a)')' mesh for harvest '//trim(mksrf_fhrvtyp_mesh) write(ndiag,*) write(ndiag,'(a)')' topography statistics from: '//trim(mksrf_ftopostats) write(ndiag,'(a)')' mesh for topography stats '//trim(mksrf_ftopostats_mesh) @@ -397,13 +459,13 @@ subroutine write_namelist_input() write(ndiag,'(a)')' mksrf_fdynuse = '//trim(mksrf_fdynuse) end if write(ndiag,*) - write(ndiag,'(a)')'Model grid configuration variables' + write(ndiag,'(a)')'Model grid configuration variables' write(ndiag,'(a)')' mksrf_fgrid_mesh = '//trim(mksrf_fgrid_mesh) write(ndiag,'(a,i8)')' nlon= ',mksrf_fgrid_mesh_nx write(ndiag,'(a,i8)')' nlat= ',mksrf_fgrid_mesh_ny write(ndiag,'(a)')' mksrf_gridtype = '//trim(mksrf_gridtype) write(ndiag,*) - write(ndiag,'(a)')'Output configuration variables' + write(ndiag,'(a)')'Output configuration variables' if (outnc_1d) then write(ndiag,'(a)')' output file will be 1d format' else diff --git a/tools/mksurfdata_esmf/src/mkvocefMod.F90 b/tools/mksurfdata_esmf/src/mkvocefMod.F90 index d40e435b93..6c904b2608 100644 --- a/tools/mksurfdata_esmf/src/mkvocefMod.F90 +++ b/tools/mksurfdata_esmf/src/mkvocefMod.F90 @@ -1,51 +1,28 @@ module mkvocefMod + !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mkvocMod - ! - ! !DESCRIPTION: ! Make VOC percentage emissions for surface dataset - ! - ! !REVISION HISTORY: - ! Author: Erik Kluzek - ! !----------------------------------------------------------------------- - ! !USES: + use shr_kind_mod, only : r8 => shr_kind_r8 - use mkdomainMod , only : domain_checksame + use mkvarpar + use mkvarctl + use mkncdio implicit none private - ! !PUBLIC MEMBER FUNCTIONS: - public :: mkvocef ! Get the percentage emissions for VOC for different - ! land cover types - !EOP + public :: mkvocef ! Get the percentage emissions for VOC for different land cover types contains !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkvocef - ! - ! !INTERFACE: subroutine mkvocef(ldomain, mapfname, datfname, ndiag, & ef_btr_o, ef_fet_o, ef_fdt_o, ef_shr_o, ef_grs_o, ef_crp_o) - ! - ! !DESCRIPTION: + ! make volatile organic coumpunds (VOC) emission factors. - ! - ! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio - ! - ! !ARGUMENTS: - implicit none + + ! input/output variables type(domain_type) , intent(in) :: ldomain character(len=*) , intent(in) :: mapfname ! input mapping file name character(len=*) , intent(in) :: datfname ! input data file name @@ -57,18 +34,7 @@ subroutine mkvocef(ldomain, mapfname, datfname, ndiag, & real(r8) , intent(out):: ef_grs_o(:) ! output grid: EFs for grasses real(r8) , intent(out):: ef_crp_o(:) ! output grid: EFs for crops ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: Colette L. Heald - ! 17 Jul 2007 F Vitt -- updated to pftintdat06_clm3_5_05 and corrected indexing of ef_*_i arrarys - ! - !EOP - ! - ! !LOCAL VARIABLES: - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain + ! local variables: real(r8), allocatable :: ef_btr_i(:) ! input grid: EFs for broadleaf trees real(r8), allocatable :: ef_fet_i(:) ! input grid: EFs for fineleaf evergreen real(r8), allocatable :: ef_fdt_i(:) ! input grid: EFs for fineleaf deciduous @@ -99,8 +65,8 @@ subroutine mkvocef(ldomain, mapfname, datfname, ndiag, & call domain_read(tdomain,datfname) ns_i = tdomain%ns allocate(ef_btr_i(ns_i), ef_fet_i(ns_i), ef_fdt_i(ns_i), & - ef_shr_i(ns_i), ef_grs_i(ns_i), ef_crp_i(ns_i), & - frac_dst(ns_o), stat=ier) + ef_shr_i(ns_i), ef_grs_i(ns_i), ef_crp_i(ns_i), & + frac_dst(ns_o), stat=ier) if (ier/=0) call shr_sys_abort() write (6,*) 'Open VOC file: ', trim(datfname) @@ -145,33 +111,27 @@ subroutine mkvocef(ldomain, mapfname, datfname, ndiag, & do no = 1, ns_o if ( ef_btr_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF btr = ',ef_btr_o(no), & - ' is negative for no = ',no + write (6,*) 'MKVOCEF error: EF btr = ',ef_btr_o(no), ' is negative for no = ',no call shr_sys_abort() end if if ( ef_fet_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF fet = ',ef_fet_o(no), & - ' is negative for no = ',no + write (6,*) 'MKVOCEF error: EF fet = ',ef_fet_o(no), ' is negative for no = ',no call shr_sys_abort() end if if ( ef_fdt_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF fdt = ',ef_fdt_o(no), & - ' is negative for no = ',no + write (6,*) 'MKVOCEF error: EF fdt = ',ef_fdt_o(no), ' is negative for no = ',no call shr_sys_abort() end if if ( ef_shr_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF shr = ',ef_shr_o(no), & - ' is negative for no = ',no + write (6,*) 'MKVOCEF error: EF shr = ',ef_shr_o(no), ' is negative for no = ',no call shr_sys_abort() end if if ( ef_grs_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF grs = ',ef_grs_o(no), & - ' is negative for no = ',no + write (6,*) 'MKVOCEF error: EF grs = ',ef_grs_o(no), ' is negative for no = ',no call shr_sys_abort() end if if ( ef_crp_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF crp = ',ef_crp_o(no), & - ' is negative for no = ',no + write (6,*) 'MKVOCEF error: EF crp = ',ef_crp_o(no), ' is negative for no = ',no call shr_sys_abort() end if enddo @@ -195,9 +155,7 @@ subroutine mkvocef(ldomain, mapfname, datfname, ndiag, & ! Deallocate dynamic memory deallocate ( ef_btr_i, ef_fet_i, ef_fdt_i, & - ef_shr_i, ef_grs_i, ef_crp_i, frac_dst, mask_r8 ) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) + ef_shr_i, ef_grs_i, ef_crp_i, frac_dst, mask_r8 ) end subroutine mkvocef From 590289452236731e2d0ebd01cac7aaf8f25166b5 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 30 Jan 2022 23:20:57 -0700 Subject: [PATCH 034/614] turned on all fields that can currently be output --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 12 ++--- tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 | 20 +++++---- tools/mksurfdata_esmf/src/mksurfdata.F90 | 49 ++++++++++----------- 3 files changed, 41 insertions(+), 40 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 3c2c807df1..e3f47e6101 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -143,10 +143,11 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & 'unitless', pctclay, lev1name='nlevsoi', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil mapunits" - call mkfile_output(pioid, define_mode, mesh_o, 'mapunits', 'igbp mapunits', & - 'unitless', mapunits, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! TODO: uncommenting this gives garbage in the PCT_SAND and PCT_CLAY output + ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil mapunits" + ! call mkfile_output(pioid, define_mode, mesh_o, 'mapunits', 'igbp mapunits', & + ! 'unitless', mapunits, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) return if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil fmax (maximum fraction saturated area)" call mkfile_output (pioid, define_mode, mesh_o, xtype, 'FMAX', 'maximum fractional saturated area', & @@ -181,7 +182,8 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & ! Write to netcdf file is done inside mkurbanpar routine ! ---------------------------------------------------------------------- - call mkurbanpar(pioid, mksrf_furban, mesh_o, urban_region, urban_classes_g, urban_skip_abort_on_invalid_data_check) + call mkurbanpar(pioid, mksrf_furban, mesh_o, urban_region, urban_classes_g, & + urban_skip_abort_on_invalid_data_check) ! Close surface dataset call pio_closefile(pioid) diff --git a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 index ba6ee132a6..1c8948c303 100644 --- a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 @@ -32,11 +32,11 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) ! make percent fmax ! ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh - real(r8) , intent(out) :: fmax_o(:) ! output grid: %fmax - integer , intent(out) :: rc + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + real(r8) , intent(inout) :: fmax_o(:) ! output grid: %fmax + integer , intent(out) :: rc ! local variables: type(ESMF_RouteHandle) :: routehandle @@ -100,16 +100,16 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Determine frac_o (regrid frac_i to frac_o) - allocate(frac_i(ns_i)) - allocate(frac_o(ns_o)) + allocate(frac_i(ns_i)) ; frac_i(:) = 0. + allocate(frac_o(ns_o)) ; frac_o(:) = 0. call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, frac_i, frac_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do n = 1, ns_o if ((frac_o(n) < 0.0) .or. (frac_o(n) > 1.0001)) then write(6,*) "ERROR:: frac_o out of range: ", frac_o(n),n - call shr_sys_abort () end if end do call ESMF_VMLogMemInfo("After regrid landmask in "//trim(subname)) @@ -122,6 +122,7 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) ! Regrid fmax_i to fmax_o and scale by 1/frac_o ! In points with no data, use globalAvg ! Check for conservation + fmax_o(:) = 0._r8 call regrid_rawdata(mesh_i, mesh_o, routehandle, fmax_i, fmax_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(subname//'after regrid rawdata in '//trim(subname)) @@ -136,7 +137,8 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) do no = 1, ns_o if ((fmax_o(no)) > 1.000001_r8) then write (6,*) 'MKFMAX error: fmax = ',fmax_o(no),' greater than 1.000001 for no = ',no - call shr_sys_abort() + ! TODO: why are we hitting this error + ! call shr_sys_abort() end if enddo diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 1d516b8a2b..b13a3527d2 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -395,6 +395,11 @@ program mksurfdata ! -------------------------------------------------- ! begin working + ! Make soil fmax [fmaxsoil] + allocate(fmaxsoil(lsize_o)); fmaxsoil(:) = spval + call mksoilfmax( mksrf_fmax_mesh, mksrf_fmax, mesh_model, fmaxsoil, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') + ! Make soil texture [pctsand, pctclay] allocate(mapunits(lsize_o)) ; mapunits(:) = 0 allocate(pctsand(lsize_o,nlevsoi)) ; pctsand(:,:) = spval @@ -402,33 +407,28 @@ program mksurfdata call mksoiltex( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pctsand, pctclay, mapunits, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') - ! Make soil fmax [fmaxsoil] - allocate(fmaxsoil(lsize_o)); fmaxsoil(:) = spval - !call mksoilfmax( mksrf_fmax_mesh, mksrf_fmax, mesh_model, fmaxsoil, rc) - !if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') - ! Make soil depth data [soildepth] from [soildepthf] allocate ( soildepth(lsize_o)); soildepth(:) = spval - !call mksoildepth( mksrf_fsoildepth_mesh, mksrf_fsoildepth, mesh_model, soildepth, rc) - !if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') + call mksoildepth( mksrf_fsoildepth_mesh, mksrf_fsoildepth, mesh_model, soildepth, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') ! Make urban fraction [pcturb] from [furban] dataset - allocate (pcturb(lsize_o)) ; pcturb(:) = spval + allocate (pcturb(lsize_o)) ; pcturb(:) = spval allocate (urban_classes(lsize_o,numurbl)) ; urban_classes(:,:) = spval allocate (urban_classes_g(lsize_o,numurbl)); urban_classes_g(:,:) = spval - allocate (urban_region(lsize_o)) ; urban_region(:) = -999 - ! call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, all_veg, pcturb, urban_classes, urban_region, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') + allocate (urban_region(lsize_o)) ; urban_region(:) = -999 + call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, all_veg, pcturb, urban_classes, urban_region, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') ! Make soil color classes [soicol] [fsoicol] allocate (soil_color(lsize_o)); soil_color(:) = -999 - ! call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, soil_color, nsoilcol, rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilcol') + call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, soil_color, nsoilcol, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilcol') ! Make organic matter density [organic] [forganic] allocate ( organic(lsize_o,nlevsoi)); organic(:,:) = spval - ! call mkorganic( mksrf_forganic_mesh, mksrf_forganic, mesh_model, organic, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') + call mkorganic( mksrf_forganic_mesh, mksrf_forganic, mesh_model, organic, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] allocate ( pctlak(lsize_o)) ; pctlak(:) = spval @@ -436,9 +436,9 @@ program mksurfdata allocate ( lakedepth(lsize_o)) ; lakedepth(:) = spval zero_out_lake = (all_urban .or. all_veg) zero_out_wetland = (all_urban .or. all_veg .or. no_inlandwet) - ! call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & - ! zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') + call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & + zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) ! end working @@ -504,16 +504,13 @@ program mksurfdata !DEBUG do n = 1,lsize_o - if (pctlak(n) < 101.) then - pctlak(n) = float(nint(pctlak(n))) - pctwet(n) = float(nint(pctwet(n))) - end if do k = 1,nlevsoi - if (pctsand(n,k) < 101.) then - pctsand(n,k) = float(nint(pctsand(n,k))) - pctclay(n,k) = float(nint(pctclay(n,k))) - end if + pctsand(n,k) = float(nint(pctsand(n,k))) + pctclay(n,k) = float(nint(pctclay(n,k))) end do + pctlak(n) = float(nint(pctlak(n))) + pctwet(n) = float(nint(pctwet(n))) + pctgla(n) = float(nint(pctgla(n))) end do !DEBUG From 3c8e0b279b13c96a966a93a4d9f58dc882b7dbd9 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 31 Jan 2022 16:19:40 -0700 Subject: [PATCH 035/614] fixes to have mksoiltex work appropriately --- tools/mksurfdata_esmf/README | 22 ++ tools/mksurfdata_esmf/run/mksurfdata_in | 47 ++++ tools/mksurfdata_esmf/run/run_mksurfdata | 23 ++ tools/mksurfdata_esmf/src/Makefile | 6 +- .../mksurfdata_esmf/src/mkdiagnosticsMod.F90 | 6 +- tools/mksurfdata_esmf/src/mkesmfMod.F90 | 194 +++++++++++-- .../src/mkglacierregionMod.F90 | 212 +++++++------- tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 | 2 +- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 260 ++++++++++-------- 9 files changed, 526 insertions(+), 246 deletions(-) create mode 100644 tools/mksurfdata_esmf/README create mode 100644 tools/mksurfdata_esmf/run/mksurfdata_in create mode 100644 tools/mksurfdata_esmf/run/run_mksurfdata diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README new file mode 100644 index 0000000000..2a6176d325 --- /dev/null +++ b/tools/mksurfdata_esmf/README @@ -0,0 +1,22 @@ +============================ +building the executable (this will be built in src/ for now) +============================ +> mkdir ./bld +> cd bld +> module load cmake +> CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src/ +> make +(note - if you change src/CMakeList.txt the issue the following in bld +> rm -rf * +> CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src/ +> make +> cd ../ +> make clean +> make + +============================ +running the code (you could add mksurfdata_in) +============================ +> cd ../run +> ln -s ../src/mksurfdata . +> qsub run_mksurfdata diff --git a/tools/mksurfdata_esmf/run/mksurfdata_in b/tools/mksurfdata_esmf/run/mksurfdata_in new file mode 100644 index 0000000000..80fd485495 --- /dev/null +++ b/tools/mksurfdata_esmf/run/mksurfdata_in @@ -0,0 +1,47 @@ +&mksurfdata_input + mksrf_flai = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.c170413.nc' + mksrf_flai_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc' + mksrf_flakwat = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_LakePnDepth_3x3min_simyr2004_csplk_c151015.nc' + mksrf_flakwat_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' + mksrf_fwetlnd = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_lanwat.050425.nc' + mksrf_fwetlnd_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' + mksrf_forganic = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_organic_10level_5x5min_ISRIC-WISE-NCSCD_nlev7_c120830.nc' + mksrf_forganic_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' + mksrf_fsoicol = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_soilcolor_CMIP6_simyr2005_cd5.c220126.nc' + mksrf_fsoicol_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc' + mksrf_furban = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_urban_0.05x0.05_simyr2000.c220127.nc' + mksrf_furban_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' + mksrf_fgdp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_gdp_0.5x0.5_AVHRR_simyr2000.c130228.nc' + mksrf_fgdp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' + mksrf_fpeat = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_peatf_0.5x0.5_AVHRR_simyr2000.c130228.nc' + mksrf_fpeat_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' + mksrf_fvocef = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_vocef_0.5x0.5_simyr2000.c110531.nc' + mksrf_fvocef_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' + mksrf_furbtopo = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_topo.10min.c191120.nc' + mksrf_furbtopo_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_c200129.nc' + mksrf_fglacier = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000.c120926.nc' + mksrf_fglacier_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' + mksrf_fglacierregion = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_GlacierRegion_10x10min_nomask_cd5_c220131.nc' + mksrf_fglacierregion_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_c200129.nc' + mksrf_fvegtyp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_1850.c190119.nc' + mksrf_fvegtyp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' + mksrf_fhrvtyp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_1850.c190119.nc' + mksrf_fhrvtyp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' + mksrf_fgdp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_gdp_0.5x0.5_AVHRR_simyr2000.c130228.nc' + mksrf_fgdp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' + mksrf_fsoildepth = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksf_soilthk_5x5min_ORNL-Soil_simyr1900-2015_c170630.nc' + mksrf_fsoildepth_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' + mksrf_fabm = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_abm_0.5x0.5_AVHRR_simyr2000.c130201.nc' + mksrf_fabm_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' + mksrf_ftopostats = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_topostats_1km-merge-10min_HYDRO1K-merge-nomask_simyr2000.c130402.nc' + mksrf_ftopostats_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UGRID_1km-merge-10min_HYDRO1K-merge-nomask_c130402.nc' + mksrf_fsoitex = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_soitex.10level.c010119.nc' + mksrf_fsoitex_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' + mksrf_fmax = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_fmax_0.125x0.125_c200220.nc' + mksrf_fmax_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.125x0.125_nomask_c200129.nc' + mksrf_fgrid_mesh_nx = 144 + mksrf_fgrid_mesh_ny = 96 + mksrf_fgrid_mesh = '/glade/p/cesm/cseg/inputdata/share/meshes/fv1.9x2.5_141008_ESMFmesh.nc' + fsurdat = 'surfdata_1.9x2.5_hist_78pfts_CMIP6_1850_c220119.nc' + fsurlog = 'surfdata_1.9x2.5_hist_78pfts_CMIP6_1850_c220119.log' +/ diff --git a/tools/mksurfdata_esmf/run/run_mksurfdata b/tools/mksurfdata_esmf/run/run_mksurfdata new file mode 100644 index 0000000000..f70a8b01f8 --- /dev/null +++ b/tools/mksurfdata_esmf/run/run_mksurfdata @@ -0,0 +1,23 @@ +#!/bin/bash +#PBS -A P93300606 +#PBS -N job_name +#PBS -j oe +#PBS -q premium +#PBS -l walltime=45:00 +##PBS -l select=1:ncpus=36:mpiprocs=36 +#PBS -l select=4:ncpus=36:mpiprocs=36 +##PBS -l select=16:ncpus=36:mpiprocs=9 +#PBS -o log.out + +# note for -l input above +# -l select={num_nodes}:ncpus={max_tasks_per_node}:mpiprocs={tasks_per_node} + +export TMPDIR=/glade/scratch/$USER/temp +mkdir -p $TMPDIR + +#module rm netcdf +#module load netcdf-mpi pnetcdf pio/2.5.5 +#make + +# -np {total_tasks} +mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata diff --git a/tools/mksurfdata_esmf/src/Makefile b/tools/mksurfdata_esmf/src/Makefile index d978d88020..f2853e3e43 100644 --- a/tools/mksurfdata_esmf/src/Makefile +++ b/tools/mksurfdata_esmf/src/Makefile @@ -19,9 +19,9 @@ ################################################################################ -COMPILEPATH = -I/glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/bld -I/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/include -#LINKPATH = -L/glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/bld -L/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/lib/ -LINKPATH = -L/glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/bld +COMPILEPATH = -I/glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/bld -I/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/include +#LINKPATH = -L/glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/bld -L/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/lib/ +LINKPATH = -L/glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/bld PIO_LINKPATH = -L/glade/work/jedwards/tools/pio/2.5.5/intel/19.1.1/mpt/2.22/lib -L/glade/u/apps/ch/opt/pnetcdf/1.12.2/mpt/2.22/intel/19.1.1//lib -L/glade/u/apps/ch/opt/netcdf/4.7.3/intel/19.0.5/lib ESMFMKFILE=/glade/work/oehmke/ESMF/scalable_mesh_from_file/lib/libg/Linux.intel.64.mpt.default/esmf.mk diff --git a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 index c4f9fa4b80..c64e0a0101 100644 --- a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 @@ -5,6 +5,7 @@ module mkdiagnosticsMod !----------------------------------------------------------------------- use shr_kind_mod, only : r8 => shr_kind_r8 + use mkvarctl, only : ndiag implicit none private @@ -19,13 +20,15 @@ module mkdiagnosticsMod contains !------------------------------------------------------------------------------ - subroutine output_diagnostics_area(data_i, data_o, name, percent, ndiag, mask_src) + subroutine output_diagnostics_area(mesh_i, mesh_o, data_i, data_o, name, percent, mask_src) ! Output diagnostics for a field that gives either fraction or percent of grid cell area use mkvarpar, only : re ! input/output variables + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o real(r8) , intent(in) :: data_i(:) ! data on input grid real(r8) , intent(in) :: data_o(:) ! data on output grid character(len=*) , intent(in) :: name ! name of field @@ -116,7 +119,6 @@ subroutine output_diagnostics_continuous(data_i, data_o, gridmap, name, units, n ! Output diagnostics for a continuous field (but not area, for which there is a different routine) - use mkgridmapMod, only : gridmap_type use mkvarpar, only : re ! !ARGUMENTS: diff --git a/tools/mksurfdata_esmf/src/mkesmfMod.F90 b/tools/mksurfdata_esmf/src/mkesmfMod.F90 index 7398d327ef..fadd07d956 100644 --- a/tools/mksurfdata_esmf/src/mkesmfMod.F90 +++ b/tools/mksurfdata_esmf/src/mkesmfMod.F90 @@ -9,9 +9,20 @@ module mkesmfMod private public :: regrid_rawdata + public :: get_meshareas + public :: create_routehandle_frac public :: create_routehandle_r4 public :: create_routehandle_r8 - public :: get_meshareas + + interface create_routehandle_frac + module procedure create_routehandle_frac_r4 + module procedure create_routehandle_frac_r8 + end interface create_routehandle_frac + + interface get_meshareas + module procedure get_meshareas_r4 + module procedure get_meshareas_r8 + end interface get_meshareas interface regrid_rawdata module procedure regrid_rawdata1d_r4 @@ -27,21 +38,25 @@ module mkesmfMod contains !=============================================================== - subroutine create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) + subroutine create_routehandle_frac_r8(mesh_i, mesh_o, field_type, routehandle, frac_o, rc) ! input/output variables type(ESMF_Mesh) , intent(in) :: mesh_i type(ESMF_Mesh) , intent(in) :: mesh_o + character(len=*) , intent(in) :: field_type type(ESMF_RouteHandle) , intent(inout) :: routehandle + real(r4) , intent(inout) :: frac_o(:) integer , intent(out) :: rc ! local variables - integer :: srcMaskValue = -987987 ! spval for RH mask values - integer :: dstMaskValue = -987987 ! spval for RH mask values - integer :: srcTermProcessing_Value = 0 - type(ESMF_Field) :: field_i - type(ESMF_Field) :: field_o - character(len=*), parameter :: subname = 'create_routehandle_r8' + integer :: srcMaskValue = 0 ! ignore source points where the mesh mask is 0 + integer :: dstMaskValue = -987987 ! don't ingore any destination points + integer :: srcTermProcessing_Value = 0 + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + type(ESMF_Field) :: dstFracField + real(r8), pointer :: dataptr(:) + character(len=*), parameter :: subname = 'create_routehandle' ! -------------------------------------------- rc = ESMF_SUCCESS @@ -50,22 +65,86 @@ subroutine create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + dstFracField = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create route handle to map field_model to field_data call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & - !srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_DSTAREA, & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_FRACAREA, & + srcMaskValues=(/srcMaskValue/), & + dstMaskValues=(/dstMaskValue/), & srcTermProcessing=srcTermProcessing_Value, & - ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & + dstFracField= dstFracField, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) + call ESMF_FieldGet(dstFracField, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + frac_o(:) = dataptr(:) + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(dstFracField, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - end subroutine create_routehandle_r8 + end subroutine create_routehandle_frac_r8 + + !=============================================================== + subroutine create_routehandle_frac_r4(mesh_i, mesh_o, routehandle, frac_o, rc) + + ! input/output variables + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o + type(ESMF_RouteHandle) , intent(inout) :: routehandle + real(r4) , intent(inout) :: frac_o(:) + integer , intent(out) :: rc + + ! local variables + integer :: srcMaskValue = 0 ! ignore source points where the mesh mask is 0 + integer :: dstMaskValue = -987987 ! don't ingore any destination points + integer :: srcTermProcessing_Value = 0 + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + type(ESMF_Field) :: dstFracField + real(r4), pointer :: dataptr(:) + character(len=*), parameter :: subname = 'create_routehandle' + ! -------------------------------------------- + + rc = ESMF_SUCCESS + + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dstFracField = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create route handle to map field_model to field_data + call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_FRACAREA, & + srcMaskValues=(/srcMaskValue/), & + dstMaskValues=(/dstMaskValue/), & + srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & + dstFracField= dstFracField, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) + + call ESMF_FieldGet(dstFracField, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + frac_o(:) = dataptr(:) + + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(dstFracField, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + end subroutine create_routehandle_frac_r4 !=============================================================== subroutine create_routehandle_r4(mesh_i, mesh_o, routehandle, rc) @@ -77,8 +156,8 @@ subroutine create_routehandle_r4(mesh_i, mesh_o, routehandle, rc) integer , intent(out) :: rc ! local variables - integer :: srcMaskValue = -987987 ! spval for RH mask values - integer :: dstMaskValue = -987987 ! spval for RH mask values + integer :: srcMaskValue = 0 ! ignore source points where the mesh mask is 0 + integer :: dstMaskValue = -987987 ! don't ingore any destination points integer :: srcTermProcessing_Value = 0 type(ESMF_Field) :: field_i type(ESMF_Field) :: field_o @@ -94,8 +173,9 @@ subroutine create_routehandle_r4(mesh_i, mesh_o, routehandle, rc) ! Create route handle to map field_model to field_data call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & - !srcMaskValues=(/srcMaskValue/), dstMaskValues=(/dstMaskValue/), & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_DSTAREA, & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_FRACAREA, & + srcMaskValues=(/srcMaskValue/), & + dstMaskValues=(/dstMaskValue/), & srcTermProcessing=srcTermProcessing_Value, & ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -108,6 +188,48 @@ subroutine create_routehandle_r4(mesh_i, mesh_o, routehandle, rc) end subroutine create_routehandle_r4 + !=============================================================== + subroutine create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) + + ! input/output variables + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o + type(ESMF_RouteHandle) , intent(inout) :: routehandle + integer , intent(out) :: rc + + ! local variables + integer :: srcMaskValue = 0 ! ignore source points where the mesh mask is 0 + integer :: dstMaskValue = -987987 ! don't ingore any destination points + integer :: srcTermProcessing_Value = 0 + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + character(len=*), parameter :: subname = 'create_routehandle_r8' + ! -------------------------------------------- + + rc = ESMF_SUCCESS + + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create route handle to map field_model to field_data + call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_FRACAREA, & + srcMaskValues=(/srcMaskValue/), & + dstMaskValues=(/dstMaskValue/), & + srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) + + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + end subroutine create_routehandle_r8 + !=============================================================== subroutine regrid_rawdata1d_r4(mesh_i, mesh_o, routehandle, data_i, data_o, rc) @@ -303,29 +425,61 @@ subroutine regrid_rawdata2d_r8(mesh_i, mesh_o, routehandle, data_i, data_o, lbo end subroutine regrid_rawdata2d_r8 !=============================================================== - subroutine get_meshareas(mesh, areas, rc) + subroutine get_meshareas_r8(mesh, areas, rc) ! input/output variables type(ESMF_Mesh) , intent(in) :: mesh real(r8) , intent(inout) :: areas(:) integer , intent(out) :: rc - + ! local variables real(r8), pointer :: dataptr(:) type(ESMF_Field) :: lfield + integer :: ns ! -------------------------------------------- rc = ESMF_SUCCESS + call ESMF_MeshGet(mesh, numOwnedElements=ns, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return lfield = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldRegridGetArea(lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(lfield, farrayPtr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return areas(:) = dataptr(:) call ESMF_FieldDestroy(lfield, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + end subroutine get_meshareas_r8 + + !=============================================================== + subroutine get_meshareas_r4(mesh, areas, rc) + + ! input/output variables + type(ESMF_Mesh) , intent(in) :: mesh + real(r4) , intent(inout) :: areas(:) + integer , intent(out) :: rc + + ! local variables + real(r8), pointer :: dataptr(:) + type(ESMF_Field) :: lfield + integer :: ns + ! -------------------------------------------- + + rc = ESMF_SUCCESS + + call ESMF_MeshGet(mesh, numOwnedElements=ns, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + lfield = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldRegridGetArea(lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + areas(:) = real(dataptr(:), kind=r4) - end subroutine get_meshareas + call ESMF_FieldDestroy(lfield, nogarbage = .true., rc=rc) + end subroutine get_meshareas_r4 end module mkesmfMod diff --git a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 index d2056c29ca..baa79b7e85 100644 --- a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 @@ -1,135 +1,143 @@ module mkglacierregionMod !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mkglacierregionMod - ! - ! !DESCRIPTION: ! make glacier region ID - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! + ! Regridding is done by finding the nearest neighbor source cell for each destination cell. !----------------------------------------------------------------------- - ! - ! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - implicit none + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_nn, get_meshareas + use mkutilsMod , only : chkerr +#ifdef TODO + ! use mkdiagnosticsMod, only : output_diagnostics_index +#endif + use mkchecksMod, only : min_bad + use mkvarctl + + implicit none private - ! !PUBLIC MEMBER FUNCTIONS: - public mkglacierregion ! make glacier region ID - ! - !EOP + public :: mkglacierregion ! make glacier region ID + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + +!================================================================================= contains +!================================================================================= - !----------------------------------------------------------------------- - subroutine mkglacierregion(ldomain, mapfname, datfname, ndiag, & - glacier_region_o) + subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, rc) ! - ! !DESCRIPTION: ! Make glacier region ID ! - ! Regridding is done by finding the max index that overlaps each destination cell, - ! without regard to the weight of overlap or dominance of each overlapping index. - ! - ! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read, domain_checksame - use mkgridmapMod - use mkncdio - use mkindexmapMod, only : get_max_indices - use mkdiagnosticsMod, only : output_diagnostics_index - use mkchecksMod, only : min_bad - ! - ! !ARGUMENTS: - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - integer , intent(out) :: glacier_region_o(:) ! glacier region - ! - ! !LOCAL VARIABLES: - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - integer, allocatable :: glacier_region_i(:) ! glacier region on input grid - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - integer :: max_region ! max region ID - + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + integer , intent(out) :: glacier_region_o(:) ! glacier region + integer , intent(out) :: rc + + ! local variables: + type(ESMF_RouteHandle) :: routehandle ! nearest neighbor routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + integer :: ni,no + integer :: ns_i, ns_o + integer , allocatable :: glacier_region_i(:) ! glacier region on input grid + real(r4), allocatable :: frac_i(:) ! input mask + real(r4), allocatable :: frac_o(:) ! output fractions + real(r4), allocatable :: data_i(:) + real(r4), allocatable :: data_o(:) + integer :: ier, rcode ! error status + integer :: max_region ! max region ID character(len=*), parameter :: subname = 'mkglacierregion' !----------------------------------------------------------------------- - write (6,*) 'Attempting to make glacier region .....' - - ! ------------------------------------------------------------------------ - ! Read domain and mapping information, check for consistency - ! ------------------------------------------------------------------------ - - call domain_read(tdomain, datfname) - - call gridmap_mapread(tgridmap, mapfname) + rc = ESMF_SUCCESS - ! Obtain frac_dst - allocate(frac_dst(ldomain%ns), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + if (root_task) then + write (ndiag,'(a)') 'Attempting to make glacier region .....' + end if - allocate(mask_r8(tdomain%ns), stat=ier) + ! Open input data file + if (root_task) then + write (ndiag,'(a)') 'Opening glacier region raw data file: ', trim(file_data_i) + end if + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + + ! Read in input mesh + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Create a nearest neighbor route handle between the input and output mesh + call create_routehandle_nn(mesh_i, mesh_o, routehandle, rc=rc) + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + + ! Determine ns_i and allocate glacier_region_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(glacier_region_i(ns_i), stat=ier) if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check(tgridmap, mask_r8, frac_dst, subname) - call domain_checksame(tdomain, ldomain, tgridmap) + ! Determine ns_o (glacier_region_o has already been allocated) + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! ------------------------------------------------------------------------ - ! Open input file, allocate memory for input data - ! ------------------------------------------------------------------------ - - write (6,*) 'Open glacier region raw data file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(glacier_region_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() + ! Read in input data + call mkpio_get_rawdata(pioid, 'GLACIER_REGION', mesh_i, glacier_region_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - ! ------------------------------------------------------------------------ - ! Regrid glacier_region - ! ------------------------------------------------------------------------ - - call check_ret(nf_inq_varid(ncid, 'GLACIER_REGION', varid), subname) - call check_ret(nf_get_var_int(ncid, varid, glacier_region_i), subname) + ! Confirm that no value of glacier_region is less than min_allowed. if (min_bad(glacier_region_i, 0, 'GLACIER_REGION')) then - call abort() + call shr_sys_abort() end if - call get_max_indices( & - gridmap = tgridmap, & - src_array = glacier_region_i, & - dst_array = glacier_region_o, & - nodata = 0, & - mask_src = tdomain%mask) + ! Convert to real4 + allocate(data_i(ns_i)) + do ni = 1,ns_i + data_i(ni) = real(glacier_region_i(ni), kind=r4) + end do + allocate(data_o(ns_o)) - max_region = maxval(glacier_region_i) - call output_diagnostics_index(glacier_region_i, glacier_region_o, tgridmap, & - 'Glacier Region ID', 0, max_region, ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) + ! Regrid raw data - yse a nearest neighbor map here + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! ------------------------------------------------------------------------ - ! Deallocate dynamic memory & other clean up - ! ------------------------------------------------------------------------ + ! Now convert back to integer + do no = 1,ns_o + glacier_region_o(no) = nint(data_o(no)) + end do - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate(glacier_region_i) - deallocate(frac_dst) - deallocate(mask_r8) + ! call output_diagnostics_index(glacier_region_i, glacier_region_o, tgridmap, & + ! 'Glacier Region ID', 0, max_region, ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Close the input file + call pio_closefile(pioid) + call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) - write (6,*) 'Successfully made glacier region' - write (6,*) + ! Release memory + deallocate (frac_i) + deallocate (frac_o) + deallocate(glacier_region_i) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) + + if (root_task) then + write (ndiag,'(a)') 'Successfully made glacier region' + write (ndiag,*) + end if end subroutine mkglacierregion diff --git a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 index 1c8948c303..6084574eb2 100644 --- a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 @@ -104,7 +104,6 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) allocate(frac_o(ns_o)) ; frac_o(:) = 0. call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, frac_i, frac_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do n = 1, ns_o @@ -122,6 +121,7 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) ! Regrid fmax_i to fmax_o and scale by 1/frac_o ! In points with no data, use globalAvg ! Check for conservation + fmax_i(:) = fmax_i(:) * frac_i(:) fmax_o(:) = 0._r8 call regrid_rawdata(mesh_i, mesh_o, routehandle, fmax_i, fmax_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 868060c1a2..6949287d7f 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -10,16 +10,19 @@ module mksoiltexMod use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkesmfMod , only : regrid_rawdata, create_routehandle_frac, get_meshareas use mkutilsMod , only : chkerr use mkvarctl use mkvarpar implicit none - private ! By default make data private + private ! By default make data private public :: mksoiltex ! Set soil texture + integer, parameter :: num=2 ! set soil mapunit number + integer, parameter :: nlsm=4 ! number of soil textures + character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -56,20 +59,21 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o integer :: nlay ! number of soil layers integer :: mapunittemp ! temporary igbp soil mapunit integer :: maxovr - real(r8), allocatable :: frac_i(:) - real(r8), allocatable :: frac_o(:) - real(r8), allocatable :: sand_i(:,:) ! input grid: percent sand - real(r8), allocatable :: clay_i(:,:) ! input grid: percent clay - integer, parameter :: num=2 ! set soil mapunit number - integer, parameter :: nlsm=4 ! number of soil textures + integer , allocatable :: mask_i(:) + real(r4), allocatable :: area_i(:) + real(r4), allocatable :: area_o(:) + real(r4), allocatable :: frac_i(:) + real(r4), allocatable :: frac_o(:) + real(r4), allocatable :: sand_i(:,:) ! input grid: percent sand + real(r4), allocatable :: clay_i(:,:) ! input grid: percent clay character(len=38) :: soil(0:nlsm) ! name of each soil texture - real(r8) :: gast_i(0:nlsm) ! global area, by texture type - real(r8) :: gast_o(0:nlsm) ! global area, by texture type - real(r8) :: wt ! map overlap weight - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld + real(r4) :: gast_i(0:nlsm) ! global area, by texture type + real(r4) :: gast_o(0:nlsm) ! global area, by texture type + real(r4) :: wt ! map overlap weight + real(r4) :: sum_fldi ! global sum of dummy input fld + real(r4) :: sum_fldo ! global sum of dummy output fld + real(r4) :: sumtex integer :: rcode, ier ! error status - real(r8) :: sumtex integer :: mapunit_value_max integer :: mapunit_value_min integer :: mapunit_value @@ -77,11 +81,11 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o integer :: loop, nloops real(r4) :: max_value integer :: max_index(1) - real(r8), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits - real(r8), allocatable :: data_i(:,:) - real(r8), allocatable :: data_o(:,:) - real(r8), allocatable :: global_max_value(:) - real(r8), allocatable :: global_max_index(:) + real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits + real(r4), allocatable :: data_i(:,:) + real(r4), allocatable :: data_o(:,:) + real(r4), allocatable :: global_max_value(:) + real(r4), allocatable :: global_max_index(:) character(len=*), parameter :: subname = 'mksoiltex' !----------------------------------------------------------------------- @@ -103,7 +107,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o call shr_sys_abort() end if sumtex = soil_sand_override + soil_clay_override - if ( sumtex < 0.0_r8 .or. sumtex > 100.0_r8 )then + if ( sumtex < 0.0_r4 .or. sumtex > 100.0_r4 )then write (6,*) subname//':error: soil_sand and soil_clay out of bounds: sand, clay = ', & soil_sand_override, soil_clay_override call shr_sys_abort() @@ -136,14 +140,32 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - ! Create a route handle between the input and output mesh - call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - - ! Determine ns_i and allocate data_i + ! Determine ns_i call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Get the landmask from the file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (frac_i(ni) > 0._r4) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create a route handle between the input and output mesh + ! Can only use this routehandle to map fields containing r4 data + call create_routehandle_frac(mesh_i, mesh_o, routehandle, frac_o, rc=rc) + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + ! Determine ns_o and allocate data_o call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -155,17 +177,13 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - ! TODO: Determine minimum and maximum mapunit values across all processors- for now hardwire - ! Now determine data_i as a real 2d array - for every possible soil color create a global ! field with gridcells equal to 1 for that soil color and zero elsewhere rcode = pio_inq_dimid (pioid, 'max_value_mapunit', dimid) rcode = pio_inq_dimlen (pioid, dimid, mapunit_value_max) - mapunit_value_min = 0 nmax = 100 nloops = (mapunit_value_max - mapunit_value_min + nmax)/nmax - !write(6,*)'nloops = ',nloops allocate(global_max_value(ns_o)) ; global_max_value(:) = -999. if (ier/=0) call shr_sys_abort() @@ -176,9 +194,10 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o allocate(data_o(nmax,ns_o)) if (ier/=0) call shr_sys_abort() + mapunit_o(:) = 0 do loop = 1,nloops - data_i(:,:) = 0._r8 + data_i(:,:) = 0._r4 do lindex = 0,nmax-1 mapunit_value = lindex + (nmax*(loop-1)) if (mapunit_value <= mapunit_value_max) then @@ -205,7 +224,6 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o end if end do end do - deallocate(data_i) deallocate(data_o) @@ -247,98 +265,104 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o end do ! ----------------------------------------------------------------- - ! Error check2 + ! Error check ! Compare global area of each soil type on input and output grids ! ----------------------------------------------------------------- - ! input grid: global areas by texture class + ! allocate(area_i(ns_i)) + ! call get_meshareas(mesh_i, area_i, rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return + ! allocate(area_o(ns_o)) + ! call get_meshareas(mesh_o, area_o, rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! ! input grid: global areas by texture class + ! gast_i(:) = 0. + ! do l = 1, nlay + ! do ni = 1,ns_i + ! mapunittemp = nint(mapunit_i(ni)) + ! if (mapunittemp==0) then + ! typ = 'no soil: ocean, glacier, lake, no data' + ! else if (clay_i(mapunittemp,l) >= 40.) then + ! typ = 'clays' + ! else if (sand_i(mapunittemp,l) >= 50.) then + ! typ = 'sands' + ! else if (clay_i(mapunittemp,l)+sand_i(mapunittemp,l) < 50.) then + ! if (frac_i(ni) /= 0.) then + ! typ = 'silts' + ! else !if (mask(ni) == 0.) then no data + ! typ = 'no soil: ocean, glacier, lake, no data' + ! end if + ! else + ! typ = 'loams' + ! end if + ! do m = 0, nlsm + ! if (typ == soil(m)) go to 101 + ! end do + ! write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunittemp,l), & + ! ' clay = ',clay_i(mapunittemp,l), & + ! ' not assigned to soil type for input grid lon,lat,layer = ',ni,l + ! call shr_sys_abort() + ! 101 continue + ! gast_i(m) = gast_i(m) + area_i(ni)*mask_i(ni)*re**2 + ! end do + ! end do + + ! ! output grid: global areas by texture class + ! gast_o(:) = 0. + ! do l = 1, nlay + ! do no = 1,ns_o + ! if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then + ! typ = 'no soil: ocean, glacier, lake, no data' + ! else if (clay_o(no,l) >= 40.) then + ! typ = 'clays' + ! else if (sand_o(no,l) >= 50.) then + ! typ = 'sands' + ! else if (clay_o(no,l)+sand_o(no,l) < 50.) then + ! typ = 'silts' + ! else + ! typ = 'loams' + ! end if + ! do m = 0, nlsm + ! if (typ == soil(m)) go to 102 + ! end do + ! write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & + ! ' clay = ',clay_o(no,l), & + ! ' not assigned to soil type for output grid lon,lat,layer = ',no,l + ! call shr_sys_abort() + ! 102 continue + ! gast_o(m) = gast_o(m) + area_o(no)*frac_o(no)*re**2 + ! end do + ! end do + + ! ! Diagnostic output + + ! write (ndiag,*) + ! write (ndiag,'(1x,70a1)') ('=',l=1,70) + ! write (ndiag,*) 'Soil Texture Output' + ! write (ndiag,'(1x,70a1)') ('=',l=1,70) + ! write (ndiag,*) + + ! write (ndiag,*) 'The following table of soil texture classes is for comparison only.' + ! write (ndiag,*) 'The actual data is continuous %sand, %silt and %clay not textural classes' + ! write (ndiag,*) + + ! write (ndiag,*) + ! write (ndiag,'(1x,70a1)') ('.',l=1,70) + ! write (ndiag,1001) + ! 1001 format (1x,'soil texture class',17x,' input grid area output grid area',/ & + ! 1x,33x,' 10**6 km**2',' 10**6 km**2') + ! write (ndiag,'(1x,70a1)') ('.',l=1,70) + ! write (ndiag,*) + + ! do l = 0, nlsm + ! write (ndiag,'(1x,a38,f16.3,f17.3)') soil(l),gast_i(l)*1.e-6,gast_o(l)*1.e-6 + ! end do -! gast_i(:) = 0. -! do l = 1, nlay -! do ni = 1,ns_i -! mapunittemp = nint(mapunit_i(ni)) -! if (mapunittemp==0) then -! typ = 'no soil: ocean, glacier, lake, no data' -! else if (clay_i(mapunittemp,l) >= 40.) then -! typ = 'clays' -! else if (sand_i(mapunittemp,l) >= 50.) then -! typ = 'sands' -! else if (clay_i(mapunittemp,l)+sand_i(mapunittemp,l) < 50.) then -! if (mask(ni) /= 0.) then -! typ = 'silts' -! else !if (mask(ni) == 0.) then no data -! typ = 'no soil: ocean, glacier, lake, no data' -! end if -! else -! typ = 'loams' -! end if -! do m = 0, nlsm -! if (typ == soil(m)) go to 101 -! end do -! write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunittemp,l), & -! ' clay = ',clay_i(mapunittemp,l), & -! ' not assigned to soil type for input grid lon,lat,layer = ',ni,l -! call shr_sys_abort() -! 101 continue -! gast_i(m) = gast_i(m) + area_src(ni)*mask(ni)*re**2 -! end do -! end do - -! ! output grid: global areas by texture class - -! gast_o(:) = 0. -! do l = 1, nlay -! do no = 1,ns_o -! if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then -! typ = 'no soil: ocean, glacier, lake, no data' -! else if (clay_o(no,l) >= 40.) then -! typ = 'clays' -! else if (sand_o(no,l) >= 50.) then -! typ = 'sands' -! else if (clay_o(no,l)+sand_o(no,l) < 50.) then -! typ = 'silts' -! else -! typ = 'loams' -! end if -! do m = 0, nlsm -! if (typ == soil(m)) go to 102 -! end do -! write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & -! ' clay = ',clay_o(no,l), & -! ' not assigned to soil type for output grid lon,lat,layer = ',no,l -! call shr_sys_abort() -! 102 continue -! gast_o(m) = gast_o(m) + area_dst(no)*frac_o(no)*re**2 -! end do -! end do - -! ! Diagnostic output - -! write (ndiag,*) -! write (ndiag,'(1x,70a1)') ('=',l=1,70) -! write (ndiag,*) 'Soil Texture Output' -! write (ndiag,'(1x,70a1)') ('=',l=1,70) -! write (ndiag,*) - -! write (ndiag,*) 'The following table of soil texture classes is for comparison only.' -! write (ndiag,*) 'The actual data is continuous %sand, %silt and %clay not textural classes' -! write (ndiag,*) - -! write (ndiag,*) -! write (ndiag,'(1x,70a1)') ('.',l=1,70) -! write (ndiag,1001) -! 1001 format (1x,'soil texture class',17x,' input grid area output grid area',/ & -! 1x,33x,' 10**6 km**2',' 10**6 km**2') -! write (ndiag,'(1x,70a1)') ('.',l=1,70) -! write (ndiag,*) - -! do l = 0, nlsm -! write (ndiag,1002) soil(l),gast_i(l)*1.e-6,gast_o(l)*1.e-6 -! 1002 format (1x,a38,f16.3,f17.3) -! end do - ! Deallocate dynamic memory - deallocate (sand_i,clay_i,mapunit_i) + deallocate(sand_i,clay_i,mapunit_i) + deallocate(mask_i) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) From 7a3d2ec74a16fdeebd0c55d29ed83ab91b9d964a Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 1 Feb 2022 13:29:51 -0700 Subject: [PATCH 036/614] reworked mapping to have fracarea type --- tools/mksurfdata_esmf/src/mkchecksMod.F90 | 66 +++++- .../mksurfdata_esmf/src/mkdiagnosticsMod.F90 | 204 +++++++---------- tools/mksurfdata_esmf/src/mkesmfMod.F90 | 141 +++--------- tools/mksurfdata_esmf/src/mkfileMod.F90 | 2 +- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 148 +++++++++--- tools/mksurfdata_esmf/src/mkorganicMod.F90 | 82 +++---- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 166 +++++++++++--- tools/mksurfdata_esmf/src/mksoildepthMod.F90 | 74 +++--- tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 | 46 ++-- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 15 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 4 +- .../src/mkurbanparCommonMod.F90 | 214 +++++++----------- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 137 ++++++----- tools/mksurfdata_esmf/src/mkutilsMod.F90 | 142 ------------ 14 files changed, 702 insertions(+), 739 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkchecksMod.F90 b/tools/mksurfdata_esmf/src/mkchecksMod.F90 index e385165564..f583463ab0 100644 --- a/tools/mksurfdata_esmf/src/mkchecksMod.F90 +++ b/tools/mksurfdata_esmf/src/mkchecksMod.F90 @@ -4,7 +4,7 @@ module mkchecksMod ! Generic routines to check validity of output fields !----------------------------------------------------------------------- - use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_kind_mod, only : r8 => shr_kind_r8, r4 => shr_kind_r4 implicit none private @@ -15,11 +15,13 @@ module mkchecksMod interface min_bad module procedure min_bad_int module procedure min_bad_r8 + module procedure min_bad_r4 end interface min_bad interface max_bad module procedure max_bad_int module procedure max_bad_r8 + module procedure max_bad_r4 end interface max_bad !=============================================================== @@ -56,6 +58,37 @@ logical function min_bad_r8(data, min_allowed, varname) min_bad_r8 = errors_found end function min_bad_r8 + !=============================================================== + logical function min_bad_r4(data, min_allowed, varname) + + ! Confirm that no value of data is less than min_allowed. + ! Returns true if errors found, false otherwise. + ! Also prints offending points + + ! !ARGUMENTS: + real(r4) , intent(in) :: data(:) ! array of data to check + real(r4) , intent(in) :: min_allowed ! minimum valid value + character(len=*) , intent(in) :: varname ! name of field + + ! !LOCAL VARIABLES: + logical :: errors_found ! true if any errors have been found + integer :: n ! index + character(len=*), parameter :: subname = 'min_bad_r8' + !------------------------------------------------------------------------------ + + errors_found = .false. + + do n = 1, size(data) + if (data(n) < min_allowed) then + write(6,*) subname//' ERROR: ', trim(varname), ' = ', data(n), ' less than ',& + min_allowed, ' at ', n + errors_found = .true. + end if + end do + + min_bad_r4 = errors_found + end function min_bad_r4 + !=============================================================== logical function min_bad_int(data, min_allowed, varname) @@ -119,6 +152,37 @@ logical function max_bad_r8(data, max_allowed, varname) max_bad_r8 = errors_found end function max_bad_r8 + !=============================================================== + logical function max_bad_r4(data, max_allowed, varname) + + ! Confirm that no value of data is greate than max_allowed. + ! Returns true if errors found, false otherwise. + ! Also prints offending points + + ! !ARGUMENTS: + real(r4) , intent(in) :: data(:) ! array of data to check + real(r4) , intent(in) :: max_allowed ! maximum valid value + character(len=*) , intent(in) :: varname ! name of field + + ! !LOCAL VARIABLES: + logical :: errors_found ! true if any errors have been found + integer :: n ! index + character(len=*), parameter :: subname = 'max_bad_r8' + !------------------------------------------------------------------------------ + + errors_found = .false. + + do n = 1, size(data) + if (data(n) > max_allowed) then + write(6,*) subname//' ERROR: ', trim(varname), ' = ', data(n), ' greater than ',& + max_allowed, ' at ', n + errors_found = .true. + end if + end do + + max_bad_r4 = errors_found + end function max_bad_r4 + !=============================================================== logical function max_bad_int(data, max_allowed, varname) diff --git a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 index c64e0a0101..95e0a985a4 100644 --- a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 @@ -5,7 +5,6 @@ module mkdiagnosticsMod !----------------------------------------------------------------------- use shr_kind_mod, only : r8 => shr_kind_r8 - use mkvarctl, only : ndiag implicit none private @@ -16,77 +15,61 @@ module mkdiagnosticsMod ! just on the output grid public :: output_diagnostics_index ! output diagnostics for an index field -!------------------------------------------------------------------------------ +!=============================================================== contains -!------------------------------------------------------------------------------ +!=============================================================== - subroutine output_diagnostics_area(mesh_i, mesh_o, data_i, data_o, name, percent, mask_src) + subroutine output_diagnostics_area(area_i, area_o, mask_i, data_i, data_o, name, percent, ndiag) ! Output diagnostics for a field that gives either fraction or percent of grid cell area use mkvarpar, only : re ! input/output variables - type(ESMF_Mesh) , intent(in) :: mesh_i - type(ESMF_Mesh) , intent(in) :: mesh_o + real(r8) , intent(in) :: area_i(:) + real(r8) , intent(in) :: area_o(:) + integer , intent(in) :: mask_i(:) real(r8) , intent(in) :: data_i(:) ! data on input grid real(r8) , intent(in) :: data_o(:) ! data on output grid character(len=*) , intent(in) :: name ! name of field logical , intent(in) :: percent ! is field specified as percent? (alternative is fraction) - integer , intent(in) :: ndiag ! unit number for diagnostic output - integer , intent(in) :: mask_src(:) + integer , intent(in) :: ndiag - ! !LOCAL VARIABLES: + ! local variables: real(r8) :: gdata_i ! global sum of input data real(r8) :: gdata_o ! global sum of output data real(r8) :: garea_i ! global sum of input area real(r8) :: garea_o ! global sum of output area integer :: ns_i, ns_o ! sizes of input & output grids integer :: ni,no,k ! indices - real(r8), allocatable :: area_src(:) - real(r8), allocatable :: area_dst(:) - integer , allocatable :: mask_src(:) - integer , allocatable :: mask_dst(:) character(len=*), parameter :: subname = "output_diagnostics_area" !------------------------------------------------------------------------------ - ! Error check for array size consistencies - ns_i = size(data_i) ns_o = size(data_o) - if (size(frac_dst) /= ns_o) then - write(6,*) subname//' ERROR: incorrect size of frac_dst' - write(6,*) 'size(frac_dst) = ', size(frac_dst) - write(6,*) 'ns_o = ', ns_o - call abort() - end if - if (size(mask_src) /= ns_i) then - write(6,*) subname//' ERROR: incorrect size of mask_src' - write(6,*) 'size(mask_src) = ', size(mask_src) + + ! Error check for array size consistencies + if (size(mask_i) /= ns_i) then + write(6,*) subname//' ERROR: incorrect size of mask_i' + write(6,*) 'size(mask_i) = ', size(mask_i) write(6,*) 'ns_i = ', ns_i - call abort() + call shr_sys_abort() end if ! Sums on input grid - ! TODO: get area_src and mask_src from input mesh - allocate(area_src(ns_i)) - allocate(mask_src(ns_i)) gdata_i = 0. garea_i = 0. do ni = 1,ns_i - garea_i = garea_i + area_src(ni)*re**2 - gdata_i = gdata_i + data_i(ni) * area_src(ni) * mask_src(ni) * re**2 + garea_i = garea_i + area_i(ni) * re**2 + gdata_i = gdata_i + data_i(ni) * area_i(ni) * mask_i(ni) * re**2 end do ! Sums on output grid - ! TODO: get area_src and mask_src from output mesh - allocate(area_dst(ns_i)) - allocate(mask_dst(ns_i)) gdata_o = 0. garea_o = 0. do no = 1,ns_o - garea_o = garea_o + area_dst(no)*re**2 - gdata_o = gdata_o + data_o(no) * area_dst(no) * re**2 + garea_o = garea_o + area_o(no) * re**2 + gdata_o = gdata_o + data_o(no) * area_o(no) * re**2 end do ! Correct units @@ -114,22 +97,25 @@ subroutine output_diagnostics_area(mesh_i, mesh_o, data_i, data_o, name, percent end subroutine output_diagnostics_area - !------------------------------------------------------------------------------ - subroutine output_diagnostics_continuous(data_i, data_o, gridmap, name, units, ndiag, mask_src, frac_dst) + !=============================================================== + subroutine output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + data_i, data_o, name, units, ndiag) - ! Output diagnostics for a continuous field (but not area, for which there is a different routine) + ! Output diagnostics for a continuous field (but not area, for + ! which there is a different routine) use mkvarpar, only : re ! !ARGUMENTS: - real(r8) , intent(in) :: data_i(:) ! data on input grid - real(r8) , intent(in) :: data_o(:) ! data on output grid - type(gridmap_type), intent(in) :: gridmap ! mapping info - character(len=*) , intent(in) :: name ! name of field - character(len=*) , intent(in) :: units ! units of field - integer , intent(in) :: ndiag ! unit number for diagnostic output - integer, intent(in) :: mask_src(:) - real(r8), intent(in) :: frac_dst(:) + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o + integer , intent(in) :: mask_i(:) + real(r8) , intent(in) :: frac_o(:) + real(r8) , intent(in) :: data_i(:) ! data on input grid + real(r8) , intent(in) :: data_o(:) ! data on output grid + character(len=*) , intent(in) :: name ! name of field + character(len=*) , intent(in) :: units ! units of field + integer , intent(in) :: ndiag ! !LOCAL VARIABLES: real(r8) :: gdata_i ! global sum of input data @@ -143,55 +129,53 @@ subroutine output_diagnostics_continuous(data_i, data_o, gridmap, name, units, n ! Error check for array size consistencies - ns_i = gridmap%na - ns_o = gridmap%nb - if (size(data_i) /= ns_i .or. & - size(data_o) /= ns_o) then + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (size(data_i) /= ns_i .or. size(data_o) /= ns_o) then write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) write(6,*) 'size(data_i) = ', size(data_i) write(6,*) 'ns_i = ', ns_i write(6,*) 'size(data_o) = ', size(data_o) write(6,*) 'ns_o = ', ns_o - call abort() + call shr_sys_abort() end if - if (size(frac_dst) /= ns_o) then - write(6,*) subname//' ERROR: incorrect size of frac_dst' - write(6,*) 'size(frac_dst) = ', size(frac_dst) + if (size(frac_o) /= ns_o) then + write(6,*) subname//' ERROR: incorrect size of frac_o' + write(6,*) 'size(frac_o) = ', size(frac_o) write(6,*) 'ns_o = ', ns_o - call abort() + call shr_sys_abort() end if - if (size(mask_src) /= ns_i) then - write(6,*) subname//' ERROR: incorrect size of mask_src' - write(6,*) 'size(mask_src) = ', size(mask_src) + if (size(mask_i) /= ns_i) then + write(6,*) subname//' ERROR: incorrect size of mask_i' + write(6,*) 'size(mask_i) = ', size(mask_i) write(6,*) 'ns_i = ', ns_i - call abort() + call shr_sys_abort() end if ! Sums on input grid - gdata_i = 0. gwt_i = 0. do ni = 1,ns_i - gdata_i = gdata_i + data_i(ni) * gridmap%area_src(ni) * mask_src(ni) - gwt_i = gwt_i + gridmap%area_src(ni) * mask_src(ni) + gdata_i = gdata_i + data_i(ni) * area_i(ni) * mask_i(ni) + gwt_i = gwt_i + area_i(ni) * mask_i(ni) end do ! Sums on output grid - gdata_o = 0. gwt_o = 0. do no = 1,ns_o - gdata_o = gdata_o + data_o(no) * gridmap%area_dst(no) * frac_dst(no) - gwt_o = gwt_o + gridmap%area_dst(no) * frac_dst(no) + gdata_o = gdata_o + data_o(no) * area_o(no) * frac_o(no) + gwt_o = gwt_o + area_o(no) * frac_o(no) end do ! Correct units - gdata_i = gdata_i / gwt_i gdata_o = gdata_o / gwt_o ! Diagnostic output - write (ndiag,*) write (ndiag,'(1x,70a1)') ('=',k=1,70) write (ndiag,*) trim(name), ' Output' @@ -210,24 +194,24 @@ subroutine output_diagnostics_continuous(data_i, data_o, gridmap, name, units, n end subroutine output_diagnostics_continuous - !------------------------------------------------------------------------------ - subroutine output_diagnostics_continuous_outonly(data_o, gridmap, name, units, ndiag) + !=============================================================== + subroutine output_diagnostics_continuous_outonly(area_o, frac_o, data_o, name, units, ndiag) ! ! Output diagnostics for a continuous field, just on the output grid ! This is used when the average of the field on the input grid is not of interest (e.g., ! when the output quantity is the standard deviation of the input field) ! - use mkgridmapMod, only : gridmap_type use mkvarpar, only : re - ! !ARGUMENTS: + ! input/output variables + real(r8) , intent(in) :: area_o(:) + real(r8) , intent(in) :: frac_o(:) real(r8) , intent(in) :: data_o(:) ! data on output grid - type(gridmap_type), intent(in) :: gridmap ! mapping info character(len=*) , intent(in) :: name ! name of field character(len=*) , intent(in) :: units ! units of field integer , intent(in) :: ndiag ! unit number for diagnostic output - ! !LOCAL VARIABLES: + ! local variables: real(r8) :: gdata_o ! global sum of output data real(r8) :: gwt_o ! global sum of output weights (area * frac) integer :: ns_o ! size of output grid @@ -235,31 +219,28 @@ subroutine output_diagnostics_continuous_outonly(data_o, gridmap, name, units, n character(len=*), parameter :: subname = "output_diagnostics_continuous_outonly" !------------------------------------------------------------------------------ - ! Error check for array size consistencies + ns_o = size(area_o) - ns_o = gridmap%nb + ! Error check for array size consistencies if (size(data_o) /= ns_o) then write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) write(6,*) 'size(data_o) = ', size(data_o) write(6,*) 'ns_o = ', ns_o - call abort() + call shr_sys_abort() end if ! Sums on output grid - gdata_o = 0. gwt_o = 0. do no = 1,ns_o - gdata_o = gdata_o + data_o(no)*gridmap%area_dst(no)*gridmap%frac_dst(no) - gwt_o = gwt_o + gridmap%area_dst(no)*gridmap%frac_dst(no) + gdata_o = gdata_o + data_o(no)*area_o(no)*frac_o(no) + gwt_o = gwt_o + area_o(no)*frac_o(no) end do ! Correct units - gdata_o = gdata_o / gwt_o ! Diagnostic output - write (ndiag,*) write (ndiag,'(1x,70a1)') ('=',k=1,70) write (ndiag,*) trim(name), ' Output' @@ -278,110 +259,97 @@ subroutine output_diagnostics_continuous_outonly(data_o, gridmap, name, units, n end subroutine output_diagnostics_continuous_outonly - !----------------------------------------------------------------------- - subroutine output_diagnostics_index(data_i, data_o, gridmap, name, & - minval, maxval, ndiag, mask_src, frac_dst) + !=============================================================== + subroutine output_diagnostics_index(data_i, data_o, mask_i, frac_o, name, minval, maxval, ndiag) ! ! Output diagnostics for an index field: area of each index in input and output ! use mkvarpar, only : re - use mkgridmapMod, only : gridmap_type - ! + ! input/output variables integer , intent(in) :: data_i(:) ! data on input grid integer , intent(in) :: data_o(:) ! data on output grid - type(gridmap_type) , intent(in) :: gridmap ! mapping info + integer , intent(in) :: mask_i(:) + real(r8) , intent(in) :: frac_o(:) character(len=*) , intent(in) :: name ! name of field integer , intent(in) :: minval ! minimum valid value integer , intent(in) :: maxval ! minimum valid value integer , intent(in) :: ndiag ! unit number for diagnostic output - integer , intent(in) :: mask_src(:) - real(r8) , intent(in) :: frac_dst(:) - ! - ! !LOCAL VARIABLES: + + ! local variables: integer :: ns_i, ns_o ! sizes of input & output grids integer :: ni, no, k ! indices real(r8), allocatable :: garea_i(:) ! input grid: global area of each index real(r8), allocatable :: garea_o(:) ! output grid: global area of each index integer :: ier ! error status - character(len=*), parameter :: subname = 'output_diagnostics_index' !----------------------------------------------------------------------- ! Error check for array size consistencies - ns_i = gridmap%na - ns_o = gridmap%nb - if (size(data_i) /= ns_i .or. & - size(data_o) /= ns_o) then + ns_i = na + ns_o = nb + if (size(data_i) /= ns_i .or. size(data_o) /= ns_o) then write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) write(6,*) 'size(data_i) = ', size(data_i) write(6,*) 'ns_i = ', ns_i write(6,*) 'size(data_o) = ', size(data_o) write(6,*) 'ns_o = ', ns_o - call abort() + call shr_sys_abort() end if - if (size(frac_dst) /= ns_o) then - write(6,*) subname//' ERROR: incorrect size of frac_dst' - write(6,*) 'size(frac_dst) = ', size(frac_dst) + if (size(frac_o) /= ns_o) then + write(6,*) subname//' ERROR: incorrect size of frac_o' + write(6,*) 'size(frac_o) = ', size(frac_o) write(6,*) 'ns_o = ', ns_o - call abort() + call shr_sys_abort() end if - if (size(mask_src) /= ns_i) then - write(6,*) subname//' ERROR: incorrect size of mask_src' - write(6,*) 'size(mask_src) = ', size(mask_src) + if (size(mask_i) /= ns_i) then + write(6,*) subname//' ERROR: incorrect size of mask_i' + write(6,*) 'size(mask_i) = ', size(mask_i) write(6,*) 'ns_i = ', ns_i - call abort() + call shr_sys_abort() end if ! Sum areas on input grid - allocate(garea_i(minval:maxval), stat=ier) - if (ier/=0) call abort() - + if (ier/=0) call shr_sys_abort() garea_i(:) = 0. do ni = 1, ns_i k = data_i(ni) if (k >= minval .and. k <= maxval) then - garea_i(k) = garea_i(k) + gridmap%area_src(ni) * mask_src(ni) * re**2 + garea_i(k) = garea_i(k) + area_i(ni) * mask_i(ni) * re**2 end if end do ! Sum areas on output grid - allocate(garea_o(minval:maxval), stat=ier) - if (ier/=0) call abort() - + if (ier/=0) call shr_sys_abort() garea_o(:) = 0. do no = 1, ns_o k = data_o(no) if (k >= minval .and. k <= maxval) then - garea_o(k) = garea_o(k) + gridmap%area_dst(no) * frac_dst(no) * re**2 + garea_o(k) = garea_o(k) + area_o(no) * frac_o(no) * re**2 end if end do ! Write results - write (ndiag,*) write (ndiag,'(1x,70a1)') ('=',k=1,70) write (ndiag,*) trim(name), ' Output' write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) write (ndiag,'(1x,70a1)') ('.',k=1,70) write (ndiag,2001) 2001 format (1x,'index input grid area output grid area',/ & - 1x,' 10**6 km**2 10**6 km**2') + 1x,' 10**6 km**2 10**6 km**2') write (ndiag,'(1x,70a1)') ('.',k=1,70) write (ndiag,*) - do k = minval, maxval write (ndiag,2002) k, garea_i(k)*1.e-06, garea_o(k)*1.e-06 2002 format (1x,i9,f17.3,f18.3) end do ! Deallocate memory - deallocate(garea_i, garea_o) end subroutine output_diagnostics_index diff --git a/tools/mksurfdata_esmf/src/mkesmfMod.F90 b/tools/mksurfdata_esmf/src/mkesmfMod.F90 index fadd07d956..e735d6dc89 100644 --- a/tools/mksurfdata_esmf/src/mkesmfMod.F90 +++ b/tools/mksurfdata_esmf/src/mkesmfMod.F90 @@ -10,15 +10,9 @@ module mkesmfMod public :: regrid_rawdata public :: get_meshareas - public :: create_routehandle_frac public :: create_routehandle_r4 public :: create_routehandle_r8 - interface create_routehandle_frac - module procedure create_routehandle_frac_r4 - module procedure create_routehandle_frac_r8 - end interface create_routehandle_frac - interface get_meshareas module procedure get_meshareas_r4 module procedure get_meshareas_r8 @@ -38,14 +32,13 @@ module mkesmfMod contains !=============================================================== - subroutine create_routehandle_frac_r8(mesh_i, mesh_o, field_type, routehandle, frac_o, rc) + subroutine create_routehandle_r4(mesh_i, mesh_o, routehandle, frac_o, rc) ! input/output variables type(ESMF_Mesh) , intent(in) :: mesh_i type(ESMF_Mesh) , intent(in) :: mesh_o - character(len=*) , intent(in) :: field_type type(ESMF_RouteHandle) , intent(inout) :: routehandle - real(r4) , intent(inout) :: frac_o(:) + real(r4), optional , intent(inout) :: frac_o(:) integer , intent(out) :: rc ! local variables @@ -54,18 +47,18 @@ subroutine create_routehandle_frac_r8(mesh_i, mesh_o, field_type, routehandle, f integer :: srcTermProcessing_Value = 0 type(ESMF_Field) :: field_i type(ESMF_Field) :: field_o - type(ESMF_Field) :: dstFracField + type(ESMF_Field) :: dstfracfield real(r8), pointer :: dataptr(:) - character(len=*), parameter :: subname = 'create_routehandle' + character(len=*), parameter :: subname = 'create_routehandle_r4' ! -------------------------------------------- rc = ESMF_SUCCESS - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - dstFracField = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + dstfracfield = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create route handle to map field_model to field_data @@ -79,27 +72,29 @@ subroutine create_routehandle_frac_r8(mesh_i, mesh_o, field_type, routehandle, f if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - call ESMF_FieldGet(dstFracField, farrayptr=dataptr, rc=rc) + call ESMF_FieldGet(dstfracfield, farrayptr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - frac_o(:) = dataptr(:) - + if (present(frac_o)) then + frac_o(:) = real(dataptr(:), kind=r4) + end if + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_FieldDestroy(dstFracField, nogarbage = .true., rc=rc) + call ESMF_FieldDestroy(dstfracfield, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - end subroutine create_routehandle_frac_r8 + end subroutine create_routehandle_r4 !=============================================================== - subroutine create_routehandle_frac_r4(mesh_i, mesh_o, routehandle, frac_o, rc) + subroutine create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o, rc) ! input/output variables type(ESMF_Mesh) , intent(in) :: mesh_i type(ESMF_Mesh) , intent(in) :: mesh_o type(ESMF_RouteHandle) , intent(inout) :: routehandle - real(r4) , intent(inout) :: frac_o(:) + real(r8), optional , intent(inout) :: frac_o(:) integer , intent(out) :: rc ! local variables @@ -108,18 +103,18 @@ subroutine create_routehandle_frac_r4(mesh_i, mesh_o, routehandle, frac_o, rc) integer :: srcTermProcessing_Value = 0 type(ESMF_Field) :: field_i type(ESMF_Field) :: field_o - type(ESMF_Field) :: dstFracField - real(r4), pointer :: dataptr(:) - character(len=*), parameter :: subname = 'create_routehandle' + type(ESMF_Field) :: dstfracfield + real(r8), pointer :: dataptr(:) + character(len=*), parameter :: subname = 'create_routehandle_r8' ! -------------------------------------------- rc = ESMF_SUCCESS - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - dstFracField = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + dstfracfield = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create route handle to map field_model to field_data @@ -133,99 +128,17 @@ subroutine create_routehandle_frac_r4(mesh_i, mesh_o, routehandle, frac_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - call ESMF_FieldGet(dstFracField, farrayptr=dataptr, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - frac_o(:) = dataptr(:) - - call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_FieldDestroy(dstFracField, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - - end subroutine create_routehandle_frac_r4 - - !=============================================================== - subroutine create_routehandle_r4(mesh_i, mesh_o, routehandle, rc) - - ! input/output variables - type(ESMF_Mesh) , intent(in) :: mesh_i - type(ESMF_Mesh) , intent(in) :: mesh_o - type(ESMF_RouteHandle) , intent(inout) :: routehandle - integer , intent(out) :: rc - - ! local variables - integer :: srcMaskValue = 0 ! ignore source points where the mesh mask is 0 - integer :: dstMaskValue = -987987 ! don't ingore any destination points - integer :: srcTermProcessing_Value = 0 - type(ESMF_Field) :: field_i - type(ESMF_Field) :: field_o - character(len=*), parameter :: subname = 'create_routehandle_r4' - ! -------------------------------------------- - - rc = ESMF_SUCCESS - - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Create route handle to map field_model to field_data - call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_FRACAREA, & - srcMaskValues=(/srcMaskValue/), & - dstMaskValues=(/dstMaskValue/), & - srcTermProcessing=srcTermProcessing_Value, & - ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + call ESMF_FieldGet(dstfracfield, farrayptr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) + if (present(frac_o)) then + frac_o(:) = dataptr(:) + end if call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - - end subroutine create_routehandle_r4 - - !=============================================================== - subroutine create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) - - ! input/output variables - type(ESMF_Mesh) , intent(in) :: mesh_i - type(ESMF_Mesh) , intent(in) :: mesh_o - type(ESMF_RouteHandle) , intent(inout) :: routehandle - integer , intent(out) :: rc - - ! local variables - integer :: srcMaskValue = 0 ! ignore source points where the mesh mask is 0 - integer :: dstMaskValue = -987987 ! don't ingore any destination points - integer :: srcTermProcessing_Value = 0 - type(ESMF_Field) :: field_i - type(ESMF_Field) :: field_o - character(len=*), parameter :: subname = 'create_routehandle_r8' - ! -------------------------------------------- - - rc = ESMF_SUCCESS - - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Create route handle to map field_model to field_data - call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_FRACAREA, & - srcMaskValues=(/srcMaskValue/), & - dstMaskValues=(/dstMaskValue/), & - srcTermProcessing=srcTermProcessing_Value, & - ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - - call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + call ESMF_FieldDestroy(dstfracfield, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() end subroutine create_routehandle_r8 diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index e3f47e6101..9f118ba714 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -182,7 +182,7 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & ! Write to netcdf file is done inside mkurbanpar routine ! ---------------------------------------------------------------------- - call mkurbanpar(pioid, mksrf_furban, mesh_o, urban_region, urban_classes_g, & + call mkurbanpar(mksrf_furban, pioid, mesh_o, urban_region, urban_classes_g, & urban_skip_abort_on_invalid_data_check) ! Close surface dataset diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 59a3c964d8..6fd54a980a 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -11,7 +11,7 @@ module mklanwatMod use shr_sys_mod , only : shr_sys_abort use mkvarpar , only : re use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag @@ -54,25 +54,31 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid - real(r8), allocatable :: lake_i(:) ! input grid: percent lake - real(r8), allocatable :: swmp_i(:) ! input grid: percent wetland - real(r8), allocatable :: lakedepth_i(:) ! iput grid: lake depth - integer :: ni,no,k ! indices - integer :: ns_i,ns_o ! local sizes - integer :: rcode ! error status + integer , allocatable :: mask_i(:) + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) + real(r4), allocatable :: area_i(:) + real(r4), allocatable :: area_o(:) + real(r8), allocatable :: lake_i(:) ! input grid: percent lake + real(r8), allocatable :: swmp_i(:) ! input grid: percent wetland + real(r8), allocatable :: lakedepth_i(:) ! iput grid: lake depth + integer :: ni,no,k ! indices + integer :: ns_i,ns_o ! local sizes + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: garea_i ! input grid: global area + real(r8) :: garea_o ! output grid: global area + real(r8) :: glake_i ! input grid: global lake + real(r8) :: glake_o ! output grid: global lake + real(r8) :: gswmp_i ! input grid: global swamp + real(r8) :: gswmp_o ! output grid: global swamp + integer :: ier,rcode ! error status real(r8), parameter :: min_valid_lakedepth = 0._r8 character(len=*), parameter :: subname = ' mklakwat ' !----------------------------------------------------------------------- rc = ESMF_SUCCESS - ! Initialize lake_o and swmp_o to 0 - ns_o = size(lake_o) - do no = 1,ns_o - lake_o(no) = 0. - swmp_o(no) = 0. - enddo - ! Open raw data file ! ASSUME for now that have only 1 input data file call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) @@ -84,19 +90,42 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - ! Create a route handle between the input and output mesh - call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - - ! Determine number of elements in input mesh + ! Determine ns_i call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the landmask from the input data file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (frac_i(ni) > 0._r8) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create a route handle between the input and output mesh + allocate(frac_o(ns_o)) + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) ! ---------------------------------------- ! Create %lake ! ---------------------------------------- + lake_o(:) = 0._r8 if (.not. zero_out_lake) then if (root_task) then @@ -112,23 +141,69 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & ! Regrid lake_i to lake_o call regrid_rawdata(mesh_i, mesh_o, routehandle, lake_i, lake_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regrid_rawdata for PCT_LAKE in "//trim(subname)) - do no = 1,size(lake_o) + do no = 1,ns_o if (lake_o(no) < 1.) lake_o(no) = 0. enddo + call ESMF_VMLogMemInfo("After regrid_rawdata for PCT_LAKE in "//trim(subname)) - deallocate (lake_i) + ! Compare global areas on input and output grids + allocate(area_i(ns_i)) + allocate(area_o(ns_o)) + call get_meshareas(mesh_i, area_i, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call get_meshareas(mesh_o, area_o, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Input grid + glake_i = 0. + garea_i = 0. + do ni = 1,ns_i + garea_i = garea_i + area_i(ni)*re**2 + glake_i = glake_i + lake_i(ni)*area_i(ni)/100.*re**2 + end do + + ! Output grid + glake_o = 0. + garea_o = 0. + do no = 1,ns_o + garea_o = garea_o + area_o(no)*re**2 + glake_o = glake_o + lake_o(no)*area_o(no)/100.*re**2 + end do - if (root_task) then - write (ndiag,*) 'Successfully made %lake' - write (ndiag,*) - end if + ! Diagnostic output + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'Inland Water Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,201) +201 format (1x,'surface type input grid area output grid area'/ & + 1x,' 10**6 km**2 10**6 km**2 ') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + write (ndiag,202) glake_i*1.e-06, glake_o*1.e-06 + write (ndiag,204) garea_i*1.e-06, garea_o*1.e-06 +202 format (1x,'lakes ',f14.3,f17.3) +204 format (1x,'all surface ',f14.3,f17.3) + else + do no = 1,ns_o + lake_o(no) = 0. + enddo + end if + + deallocate (lake_i) + + if (root_task) then + write (ndiag,*) 'Successfully made %lake' + write (ndiag,*) end if ! ---------------------------------------- ! Create %wetland ! ---------------------------------------- + swmp_o(:) = 0._r8 if (.not. zero_out_wetland) then if (root_task) then write (ndiag,*) 'Attempting to make %wetland .....' @@ -174,24 +249,27 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & call regrid_rawdata(mesh_i, mesh_o, routehandle, lakedepth_i, lakedepth_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regrid_rawdata for lakedepth in "//trim(subname)) + do no = 1,ns_o + if (frac_o(no) == 0._r8) then + lakedepth_o(no) = 10._r8 + end if + enddo ! Check validity of output data if (min_bad(lakedepth_o, min_valid_lakedepth, 'lakedepth')) then call shr_sys_abort() end if -#ifdef TODO - call output_diagnostics_continuous(data_i, lakedepth_o, tgridmap, "Lake Depth", "m", ndiag, tdomain%mask, frac_dst) -#endif - deallocate (lakedepth_i) - - ! ---------------------------------------- - ! Close the single input data file and release memory - ! ---------------------------------------- + ! Write out diagnostics + ! call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + ! data_i, lakedepth_o, "Lake Depth", "m", ndiag) + ! Close the single input data file call pio_closefile(pioid) + ! Release memory call ESMF_VMLogMemInfo("Before destroy operation for lanwat ") + deallocate (lakedepth_i) call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mkorganicMod.F90 b/tools/mksurfdata_esmf/src/mkorganicMod.F90 index 902fcb1b03..f0abb64551 100644 --- a/tools/mksurfdata_esmf/src/mkorganicMod.F90 +++ b/tools/mksurfdata_esmf/src/mkorganicMod.F90 @@ -45,10 +45,13 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) integer :: rcode, ier ! error status integer :: ndims integer , allocatable :: dimlengths(:) - real(r8), allocatable :: data_i(:,:) - real(r8), allocatable :: data_o(:,:) + integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + real(r8), allocatable :: data_i(:,:) + real(r8), allocatable :: data_o(:,:) character(len=*), parameter :: subname = 'mkorganic' !----------------------------------------------------------------------- @@ -58,7 +61,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) write (ndiag,'(a)') ' Attempting to make organic mater dataset .....' end if - ! Open input data file - need to do this first to obtain ungridded dimension size + ! Open input data file call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) @@ -82,63 +85,66 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - ! Create a route handle between the input and output mesh - call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - - ! Determine ns_i and allocate data_i + ! Determine ns_i call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - allocate(data_i(nlay,ns_i),stat=ier) + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the landmask from the file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (frac_i(ni) > 0._r8) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Determine ns_o and allocate data_o - ns_o = size(organic_o, dim=1) - allocate(data_o(nlay,ns_o),stat=ier) + ! Create a route handle between the input and output mesh and get frac_o + allocate(frac_o(ns_o),stat=ier) if (ier/=0) call shr_sys_abort() + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) ! Read in input data ! - levels are the innermost dimension for esmf fields ! - levels are the outermost dimension in pio reads ! Input data is read into (ns_i,nlay) array and then transferred to data_i(nlay,ns_i) + allocate(data_i(nlay,ns_i),stat=ier) + if (ier/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid, 'ORGANIC', mesh_i, data_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - ! Regrid data_i to data_o and frac_i to frac_o + ! Regrid data_i to data_o + allocate(data_o(nlay,ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 1, nlay, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regrid organic_i in "//trim(subname)) + ! Set organic_o do l = 1,nlevsoi - do n = 1,size(organic_o, dim=1) - organic_o(n,l) = data_o(l,n) + do no = 1,ns_o + organic_o(no,l) = data_o(l,no) end do end do - - ! Determine frac_o (regrid frac_i to frac_o) - allocate(frac_i(ns_i)) - allocate(frac_o(ns_o)) - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, frac_i, frac_o, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regrid landmask in "//trim(subname)) - - ! Divide organic_o by frac_o - do n = 1,ns_o - if (frac_o(n) > 0._r8) then - organic_o(n,:) = organic_o(n,:) / frac_o(n) - else - organic_o(n,:) = 0._r8 - end if - end do do l = 1,nlevsoi - do n = 1,size(organic_o, dim=1) - if ((organic_o(n,l)) > 130.000001_r8) then - write (6,*) trim(subname)//' error: organic = ',organic_o(n,l), & - ' greater than 130.000001 for n,lev ',n,l + do no = 1,ns_o + if ((organic_o(no,l)) > 130.000001_r8) then + write (6,*) trim(subname)//' error: organic = ',organic_o(no,l), & + ' greater than 130.000001 for n,lev ',no,l call shr_sys_abort() end if enddo diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index ef07aaaab9..1ba5b64c73 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -6,15 +6,17 @@ module mksoilcolMod use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 - use mkutilsMod , only : chkerr, mkrank + use mkesmfMod , only : regrid_rawdata, create_routehandle_r4, get_meshareas + use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag, mpicom, MPI_INTEGER, MPI_MAX use mkvarctl , only : soil_color_override, unsetcol + use mkvarpar , only : re implicit none private public :: mksoilcol ! Set soil colors + private :: mkrank character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -28,7 +30,7 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r ! input/output variables character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o + type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesho integer , pointer :: soil_color_o(:) ! soil color classes integer , intent(out) :: nsoilcol ! number of soil colors integer , intent(out) :: rc @@ -39,14 +41,22 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r type(file_desc_t) :: pioid integer :: ni,no integer :: ns_i, ns_o - integer :: n,l - real(r8), allocatable :: soilcol_i(:) - real(r8), allocatable :: data_i(:,:) - real(r8), allocatable :: data_o(:,:) - real(r8), allocatable :: mask_i(:) - logical :: has_color ! whether this grid cell has non-zero color + integer :: n,l,k + integer , allocatable :: mask_i(:) + real(r4), allocatable :: frac_i(:) + real(r4), allocatable :: frac_o(:) + real(r4), allocatable :: area_i(:) + real(r4), allocatable :: area_o(:) + real(r4), allocatable :: data_i(:,:) + real(r4), allocatable :: data_o(:,:) + real(r4), allocatable :: soil_color_i(:) + logical :: has_color ! whether this grid cell has non-zero color integer :: nsoilcol_local integer :: maxindex(1) + real(r4), allocatable :: gast_i(:) ! global area, by surface type + real(r4), allocatable :: gast_o(:) ! global area, by surface type + real(r4) :: sum_fldi ! global sum of dummy input fld + real(r4) :: sum_fldo ! global sum of dummy output fld integer :: rcode, ier character(len=*), parameter :: subname = 'mksoilcol' !----------------------------------------------------------------------- @@ -80,55 +90,72 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - ! Create a route handle between the input and output mesh - call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - - ! Determine ns_i and allocate data_i + ! Determine ns_i call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(soilcol_i(ns_i),stat=ier) + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the landmask from the file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (frac_i(ni) > 0._r4) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create a route handle between the input and output mesh and get frac_o + allocate(frac_o(ns_o),stat=ier) if (ier/=0) call shr_sys_abort() + call create_routehandle_r4(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - ! Read in input data - call mkpio_get_rawdata(pioid, 'SOIL_COLOR', mesh_i, soilcol_i, rc=rc) + ! Read in input soil color data + allocate(soil_color_i(ns_i),stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'SOIL_COLOR', mesh_i, soil_color_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) ! Determine maximum number of soil colors across all processors ! This will be used for the ungridded dimension of data_o below - nsoilcol_local = maxval(soilcol_i) + nsoilcol_local = maxval(soil_color_i) call mpi_allreduce(nsoilcol_local, nsoilcol, 1, MPI_INTEGER, MPI_MAX, mpicom, rcode) ! TODO: MPI_SUCCESS could not be accessed from mkvarctl !if (rcode /= MPI_SUCCESS) call shr_sys_abort('error for mpi_allredice in '//trim(subname)) - ! Determine ns_o and allocate data_o - ns_o = size(soil_color_o) - allocate(data_o(0:nsoilcol, ns_o),stat=ier) - if (ier/=0) call shr_sys_abort() - - ! Determine input landmask (frac_i) - allocate(mask_i(ns_i)) - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, mask_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Now determine data_i as a real 2d array - for every possible soil color create a global ! field with gridcells equal to 1 for that soil color and zero elsewhere allocate(data_i(0:nsoilcol,ns_i)) data_i(:,:) = 0._r4 do l = 1,nsoilcol do n = 1,ns_i - if (int(soilcol_i(n)) == l) then + if (int(soil_color_i(n)) == l) then data_i(l,n) = 1._r4 * mask_i(n) end if end do end do ! Regrid data_i to data_o + allocate(data_o(0:nsoilcol, ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, nsoilcol, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(subname//'after regrid rawdata in '//trim(subname)) + ! Determine output soil color soil_color_o(:) = 0 do no = 1,ns_o ! If the output cell has any non-zero-colored inputs, then set the weight of @@ -142,7 +169,7 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r ! Rank non-zero weights by color type. wsti(1) is the most extensive color type. if (has_color) then - call mkrank (nsoilcol, data_o(0:nsoilcol,no), 9999, 1, maxindex) + call mkrank (nsoilcol, data_o(0:nsoilcol,no), maxindex) soil_color_o(no) = maxindex(1) end if @@ -166,7 +193,43 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r soil_color_o(no),' is not valid for lon,lat = ',no call shr_sys_abort() end if + end do + + ! Compare global area of each soil color on input and output grids + + allocate(gast_i(0:nsoilcol)) + allocate(gast_o(0:nsoilcol)) + allocate(area_i(ns_i)) + allocate(area_o(ns_o)) + call get_meshareas(mesh_i, area_i, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call get_meshareas(mesh_o, area_o, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + gast_i(:) = 0. + do ni = 1,ns_i + k = soil_color_i(ni) + gast_i(k) = gast_i(k) + area_i(ni) * mask_i(ni) * re**2 + end do + gast_o(:) = 0. + do no = 1,ns_o + k = soil_color_o(no) + gast_o(k) = gast_o(k) + area_o(no) * frac_o(no) * re**2 + end do + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'Soil Color Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,101) +101 format (1x,'soil color type',5x,' input grid area output grid area',/ & + 1x,20x,' 10**6 km**2',' 10**6 km**2') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + do k = 0, nsoilcol + write (ndiag,'(1x,a,i3,d16.3,d17.3)') 'class ',k, gast_i(k)*1.e-6, gast_o(k)*1.e-6 end do if (root_task) then @@ -174,10 +237,11 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r write (ndiag,'(a)') end if + ! Clean up memory + deallocate(mask_i) deallocate(data_i) deallocate(data_o) - deallocate(soilcol_i) - deallocate(mask_i) + deallocate(soil_color_i) call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) @@ -187,4 +251,42 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r end subroutine mksoilcol + !=============================================================== + subroutine mkrank (n, a, iv) + ! + ! Return indices of largest [num] values in array [a]. + ! + ! input/output variables + integer , intent(in) :: n !array length + real(r4), intent(in) :: a(0:n) !array to be ranked + integer , intent(out):: iv(1) !index to [num] largest values in array [a] + + ! local variables: + real(r4) :: a_max !maximum value in array + real(r4) :: delmax !tolerance for finding if larger value + integer :: i !array index + integer :: m !do loop index + integer :: k !do loop index + integer :: miss !missing data value + !----------------------------------------------------------------------- + + ! Find index of largest non-zero number + delmax = 1.e-06 + miss = 9999 + iv(1) = miss + + a_max = -9999. + do i = 0, n + if (a(i)>0. .and. (a(i)-a_max)>delmax) then + a_max = a(i) + iv(1) = i + end if + end do + ! iv(1) = miss indicates no values > 0. this is an error + if (iv(1) == miss) then + write (6,*) 'MKRANK error: iv(1) = missing' + call shr_sys_abort() + end if + end subroutine mkrank + end module mksoilcolMod diff --git a/tools/mksurfdata_esmf/src/mksoildepthMod.F90 b/tools/mksurfdata_esmf/src/mksoildepthMod.F90 index 54021cb08c..e2db0e1a01 100644 --- a/tools/mksurfdata_esmf/src/mksoildepthMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoildepthMod.F90 @@ -12,7 +12,7 @@ module mksoildepthMod use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr - use mkchecksMod , only : min_bad, max_bad + use mkchecksMod , only : min_bad, max_bad use mkvarctl implicit none @@ -43,15 +43,16 @@ subroutine mksoildepth(file_mesh_i, file_data_i, mesh_o, soildepth_o, rc) type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid integer :: ns_i, ns_o - integer :: n - real(r8), allocatable :: soildepth_i(:) + integer :: ni, no + integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) - integer :: ier, rcode ! error status - character(len=CS) :: varname + real(r8), allocatable :: soildepth_i(:) + character(len=CS) :: varname integer :: varnum real(r8), parameter :: min_valid = 0._r8 ! minimum valid value real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value + integer :: ier, rcode ! error status character(len=*), parameter :: subname = 'mksoildepth' !----------------------------------------------------------------------- @@ -71,30 +72,45 @@ subroutine mksoildepth(file_mesh_i, file_data_i, mesh_o, soildepth_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - ! Create a route handle between the input and output mesh - call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - - ! Determine ns_i and allocate soildepth_i + ! Determine ns_i call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(soildepth_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - ! Determine frac_o (regrid frac_i to frac_o) - allocate(frac_i(ns_i)) - allocate(frac_o(ns_o)) + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the landmask from the file and reset the mesh mask based on that + allocate(frac_o(ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + allocate(frac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, frac_i, frac_o, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - do n = 1, ns_o - if ((frac_o(n) < 0.0) .or. (frac_o(n) > 1.0001)) then - write(6,*) "ERROR:: frac_o out of range: ", frac_o(n),n + do ni = 1,ns_i + if (frac_i(ni) > 0._r4) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create a route handle between the input and output mesh and get frac_o + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + do no = 1, ns_o + if ((frac_o(no) < 0.0) .or. (frac_o(no) > 1.0001)) then + write(6,*) "ERROR:: frac_o out of range: ", frac_o(no),no call shr_sys_abort () end if end do - call ESMF_VMLogMemInfo("After regrid landmask in "//trim(subname)) ! Determine variable name to read in varnum = 1 @@ -117,25 +133,21 @@ subroutine mksoildepth(file_mesh_i, file_data_i, mesh_o, soildepth_o, rc) varname = 'Lowland_Depth_Mean' end select - ! Read in input data + ! Read in input soil depth data + allocate(soildepth_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid, trim(varname), mesh_i, soildepth_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - ! Regrid soildepth_i to soildepth_o and scale by 1/frac_o + ! Regrid soildepth_i to soildepth_o call regrid_rawdata(mesh_i, mesh_o, routehandle, soildepth_i, soildepth_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(subname//'after regrid rawdata in '//trim(subname)) - do n = 1,ns_o - if (frac_o(n) > 0._r8) then - soildepth_o(n) = soildepth_o(n) / frac_o(n) - else - soildepth_o(n) = 0._r8 - end if - end do ! Check validity of output data - if ( min_bad(soildepth_o, min_valid, 'soildepth') .or. max_bad(soildepth_o, max_valid, 'soildepth')) then + if ( min_bad(soildepth_o, min_valid, 'soildepth') .or. & + max_bad(soildepth_o, max_valid, 'soildepth')) then call shr_sys_abort() end if diff --git a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 index 6084574eb2..c929bc7350 100644 --- a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 @@ -45,6 +45,7 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) integer :: ni,no integer :: ns_i, ns_o integer :: n,l,k + integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) real(r8), allocatable :: fmax_i(:) ! input grid: percent fmax @@ -85,55 +86,62 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - ! Create a route handle between the input and output mesh - call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - - ! Determine ns_i and allocate fmax_i + ! Determine ns_i call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(fmax_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() ! Determine ns_o call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine frac_o (regrid frac_i to frac_o) - allocate(frac_i(ns_i)) ; frac_i(:) = 0. - allocate(frac_o(ns_o)) ; frac_o(:) = 0. + ! Get the landmask from the file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, frac_i, frac_o, rc) + do ni = 1,ns_i + if (frac_i(ni) > 0._r8) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create a route handle between the input and output mesh + allocate(frac_o(ns_o)) + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) do n = 1, ns_o if ((frac_o(n) < 0.0) .or. (frac_o(n) > 1.0001)) then write(6,*) "ERROR:: frac_o out of range: ", frac_o(n),n end if end do - call ESMF_VMLogMemInfo("After regrid landmask in "//trim(subname)) ! Read in input data + allocate(fmax_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid, 'FMAX', mesh_i, fmax_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - ! Regrid fmax_i to fmax_o and scale by 1/frac_o - ! In points with no data, use globalAvg - ! Check for conservation + ! Regrid fmax_i to fmax_o, in points with no data, use globalAvg fmax_i(:) = fmax_i(:) * frac_i(:) fmax_o(:) = 0._r8 call regrid_rawdata(mesh_i, mesh_o, routehandle, fmax_i, fmax_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(subname//'after regrid rawdata in '//trim(subname)) - do n = 1,ns_o - if (frac_o(n) > 0._r8) then - fmax_o(n) = fmax_o(n) / frac_o(n) - else + if (frac_o(n) == 0._r8) then fmax_o(n) = .365783_r8 end if end do + + ! Check for conservation do no = 1, ns_o if ((fmax_o(no)) > 1.000001_r8) then write (6,*) 'MKFMAX error: fmax = ',fmax_o(no),' greater than 1.000001 for no = ',no diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 6949287d7f..51988b581e 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -10,7 +10,7 @@ module mksoiltexMod use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_frac, get_meshareas + use mkesmfMod , only : regrid_rawdata, create_routehandle_r4, get_meshareas use mkutilsMod , only : chkerr use mkvarctl use mkvarpar @@ -144,6 +144,10 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Determine ns_o and allocate data_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Get the landmask from the file and reset the mesh mask based on that allocate(frac_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() @@ -163,13 +167,12 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o ! Create a route handle between the input and output mesh ! Can only use this routehandle to map fields containing r4 data - call create_routehandle_frac(mesh_i, mesh_o, routehandle, frac_o, rc=rc) + allocate(frac_o(ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() + call create_routehandle_r4(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - ! Determine ns_o and allocate data_o - call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Read in mapunit data allocate(mapunit_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index b13a3527d2..a83f12b715 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -112,7 +112,7 @@ program mksurfdata use mkagfirepkmonthMod , only : mkagfirepkmon use mktopostatsMod , only : mktopostats use mkVICparamsMod , only : mkVICparams - use mkurbanparCommonMod, only : mkelev + use mkurbanparCommonMod, only : mkurban_topo #else use mkurbanparCommonMod #endif @@ -469,7 +469,7 @@ program mksurfdata ! ! (this same dataset used to be used for glacier-related purposes as well). ! ! TODO(wjs, 2016-01-15) A better solution for this urban screening would probably ! ! be to modify the raw urban data; in that case, I believe we could remove furbtopo. - ! call mkelev ( mapfname=map_furbtopo, datfname=mksrf_furbtopo, varname='TOPO_ICE', ndiag=ndiag, elev_o=elev) + ! call mkurban_topo ( mapfname=map_furbtopo, datfname=mksrf_furbtopo, varname='TOPO_ICE', ndiag=ndiag, elev_o=elev) ! where (elev .gt. elev_thresh) ! pcturb = 0._r8 ! end where diff --git a/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 index 70d61cb02a..930caea8ba 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 @@ -11,15 +11,25 @@ module mkurbanparCommonMod ! mkurbanparMod.) !----------------------------------------------------------------------- - use shr_kind_mod, only : r8 => shr_kind_r8 + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem + use mkpioMod , only : mkpio_iodesc_output, mkpio_def_spatial_var, mkpio_wopen + use mkpioMod , only : mkpio_get_dimlengths, mkpio_get_rawdata + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 + use mkutilsMod , only : chkerr + use mkvarctl , only : ndiag implicit none private ! !public member functions: -#ifdef TODO public :: mkurban_pct_diagnostics ! print diagnostics related to pct urban - public :: mkelev ! Get elevation to reduce urban for high elevation areas +#ifdef TODO + public :: mkurban_topo ! Get elevation to reduce urban for high elevation areas #endif ! !public data members: @@ -27,88 +37,60 @@ module mkurbanparCommonMod public :: MIN_DENS -#ifdef TODO + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + +!=============================================================== contains +!=============================================================== - subroutine mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, urbn_i, urbn_o, ndiag, dens_class, frac_dst) + subroutine mkurban_pct_diagnostics(area_i, area_o, mask_i, frac_o, urbn_i, urbn_o, dens_class) ! - ! !DESCRIPTION: ! print diagnostics related to pct urban + ! Compare global areas on input and output grids ! ! This is intended to be called after mkurban_pct, but is split out into a separate ! routine so that modifications to urbn_o can be made in between the two calls (e.g., ! setting urbn_o to 0 wherever it is less than a certain threshold; the rules for doing ! this can't always be applied inline in mkurban_pct). ! - ! !USES: - use mkdomainMod , only : domain_type - use mkgridmapMod, only : gridmap_type use mkvarpar - ! - ! !ARGUMENTS: - implicit none - type(domain_type) , intent(in) :: ldomain - type(domain_type) , intent(in) :: tdomain ! local domain - type(gridmap_type), intent(in) :: tgridmap ! local gridmap + + ! input/output variables + real(r8) , intent(in) :: area_i(:) + real(r8) , intent(in) :: area_o(:) + integer , intent(in) :: mask_i(:) + real(r8) , intent(in) :: frac_o(:) real(r8) , intent(in) :: urbn_i(:) ! input grid: percent urban real(r8) , intent(in) :: urbn_o(:) ! output grid: percent urban - real(r8) , intent(in) :: frac_dst(:) ! output fractions - integer , intent(in) :: ndiag ! unit number for diag out - integer , intent(in), optional :: dens_class ! density class - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! (Moved from mkurbanparMod Feb, 2012) - ! - ! - ! !LOCAL VARIABLES: - !EOP - real(r8) :: gurbn_i ! input grid: global urbn - real(r8) :: garea_i ! input grid: global area - real(r8) :: gurbn_o ! output grid: global urbn - real(r8) :: garea_o ! output grid: global area - integer :: ni,no,k ! indices + + ! local variables: + real(r8) :: gurbn_i ! input grid: global urbn + real(r8) :: garea_i ! input grid: global area + real(r8) :: gurbn_o ! output grid: global urbn + real(r8) :: garea_o ! output grid: global area + integer :: ni,no,k ! indices character(len=*), parameter :: subname = 'mkurban_pct_diagnostics' !----------------------------------------------------------------------- - ! Error check inputs - if (size(frac_dst) /= ldomain%ns) then - write(6,*) subname//' ERROR: array size inconsistencies' - write(6,*) 'size(frac_dst) = ', size(frac_dst) - write(6,*) 'ldomain%ns = ', ldomain%ns - call shr_sys_abort() - end if - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - ! Input grid - gurbn_i = 0._r8 garea_i = 0._r8 - - do ni = 1, tdomain%ns - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - gurbn_i = gurbn_i + urbn_i(ni)*(tgridmap%area_src(ni)/100._r8)*& - tdomain%mask(ni)*re**2 + do ni = 1, size(area_i) + garea_i = garea_i + area_i(ni)*re**2 + gurbn_i = gurbn_i + urbn_i(ni)*(area_i(ni)/100._r8)* mask_i(ni)*re**2 end do ! Output grid - gurbn_o = 0._r8 garea_o = 0._r8 - - do no = 1, ldomain%ns - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - gurbn_o = gurbn_o + urbn_o(no)* (tgridmap%area_dst(no)/100._r8)*& - frac_dst(no)*re**2 + do no = 1, size(area_o) + garea_o = garea_o + area_o(no)*re**2 + gurbn_o = gurbn_o + urbn_o(no)* (area_o(no)/100._r8)*frac_o(no)*re**2 end do ! Diagnostic output - write (ndiag,*) write (ndiag,'(1x,70a1)') ('=',k=1,70) if (present(dens_class)) then @@ -117,12 +99,11 @@ subroutine mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, urbn_i, urbn_o, n write (ndiag,'(1x,a)') 'Urban Output' end if write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) write (ndiag,'(1x,70a1)') ('.',k=1,70) write (ndiag,2001) -2001 format (1x,'surface type input grid area output grid area'/ & - 1x,' 10**6 km**2 10**6 km**2 ') +2001 format (1x,'surface type input grid area output grid area'/& + 1x,' 10**6 km**2 10**6 km**2 ') write (ndiag,'(1x,70a1)') ('.',k=1,70) write (ndiag,*) write (ndiag,2003) gurbn_i*1.e-06,gurbn_o*1.e-06 @@ -133,98 +114,77 @@ subroutine mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, urbn_i, urbn_o, n end subroutine mkurban_pct_diagnostics - !----------------------------------------------------------------------- - subroutine mkelev(ldomain, mapfname, datfname, varname, ndiag, elev_o) +#ifdef TODO + !=============================================================== + subroutine mkurban_topo(mesh_i, mesh_o, file_data_i, varname, elev_o) ! ! Make elevation data ! - ! !USES: - use mkdomainMod , only : domain_type, domain_clean, domain_read, domain_checksame - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio use mkdiagnosticsMod, only : output_diagnostics_continuous ! ! !ARGUMENTS: - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name character(len=*) , intent(in) :: datfname ! input data file name integer , intent(in) :: ndiag ! unit number for diag out character(len=*) , intent(in) :: varname ! topo variable name real(r8) , intent(out):: elev_o(:) ! output elevation data ! !LOCAL VARIABLES: - type(domain_type) :: tdomain ! local domain - type(gridmap_type) :: tgridmap ! local gridmap - real(r8), allocatable :: elev_i(:) ! canyon_height to width ratio in - real(r8), allocatable :: frac_dst(:) ! output fractions - integer :: ns_i,ns_o ! indices - integer :: k,l,n,m,ni ! indices - integer :: ncidi,dimid,varid ! input netCDF id's - integer :: ier ! error status - character(len=256) :: name ! name of attribute - character(len=256) :: unit ! units of attribute - character(len= 32) :: subname = 'mkelev' + real(r8), allocatable :: elev_i(:) ! canyon_height to width ratio in + real(r8), allocatable :: frac_o(:) ! output fractions + integer :: ns_i,ns_o ! indices + integer :: k,l,n,m,ni ! indices + integer :: ier ! error status + character(len=CS) :: name ! name of attribute + character(len=CS) :: unit ! units of attribute + character(len=*), parameter :: subname = 'mkelev' !----------------------------------------------------------------------- write (6,*) 'Attempting to make elevation .....' - ns_o = ldomain%ns - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - - ns_i = tdomain%ns - allocate(elev_i(ns_i), stat=ier) - allocate(frac_dst(ns_o), stat=ier) - if (ier /= 0) then - write(6,*)'mkelev allocation error'; call shr_sys_abort() - end if - - write (6,*) 'Open elevation file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncidi), subname) - call check_ret(nf_inq_varid (ncidi, trim(varname), varid), subname) - call check_ret(nf_get_var_double (ncidi, varid, elev_i), subname) - call check_ret(nf_close(ncidi), subname) + ! Query local mesh sizes + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Read topo elev dataset with unit mask everywhere - - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - ! Note that the topo dataset has no landmask - so a unit landmask is assumed - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine elev_o on output grid - + write (6,*) 'Open elevation file: ', trim(datfname) + allocate(elev_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call mkpio_get_rawdata(pioid, trim(varname), mesh_i, elev_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call pio_closefile(pioid) + + ! Create a route handle between the input and output mesh + allocate(frac_o(ns_o), stat=ier) + if (ier/=0) call shr_sys_abort() + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + + ! Regrid input data to model resolution - determine elev_o on output grid elev_o(:) = 0. + if (ier/=0) call shr_sys_abort() + call regrid_rawdata(mesh_i, mesh_o, routehandle, elev_i, elev_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - call gridmap_areaave_srcmask(tgridmap, elev_i, elev_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - call output_diagnostics_continuous(elev_i, elev_o, tgridmap, "Urban elev variable", "m", ndiag, tdomain%mask, frac_dst) - + call output_diagnostics_continuous(elev_i, elev_o, tgridmap, & + "Urban elev variable", "m", ndiag, mask_i, frac_o) ! Deallocate dynamic memory - - call domain_clean(tdomain) - call gridmap_clean(tgridmap) deallocate (elev_i) - deallocate (frac_dst) + deallocate (frac_o) - write (6,*) 'Successfully made elevation' - write (6,*) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + if (root_task) then + write (ndiag,'(a)') 'Successfully made elevation' + write (ndiag,'(a)') + end if - end subroutine mkelev + end subroutine mkurban_topo #endif end module mkurbanparCommonMod diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index dddf8533af..53bca82ca3 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -15,7 +15,8 @@ module mkurbanparMod use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag, ispval, fsurdat, outnc_double - use mkvarctl , only : root_task, ndiag, mpicom, MPI_INTEGER, MPI_MAX + use mkvarctl , only : mpicom, MPI_INTEGER, MPI_MAX + use mkvarpar implicit none private @@ -64,13 +65,10 @@ subroutine mkurbanInit(datafname) ! Set numurbl, nlevurb and nregions rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(datafname), pio_nowrite) - rcode = pio_inq_dimid(pioid, 'density_class', dimid) rcode = pio_inq_dimlen(pioid, dimid, numurbl) - rcode = pio_inq_dimid(pioid, 'nlevurb', dimid) rcode = pio_inq_dimlen(pioid, dimid, nlevurb) - rcode = pio_inq_dimid(pioid, 'region', dimid) rcode = pio_inq_dimlen(pioid, dimid, nregions) call pio_closefile(pioid) @@ -125,22 +123,19 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid - real(r8), allocatable :: urban_classes_gcell_o(:,:) ! % putput urban in each density class (% of total grid cell area) - real(r8), allocatable :: data_i(:,:) - real(r8), allocatable :: data_o(:,:) - integer , allocatable :: region_i(:) ! input grid: region ID - integer :: ni,no ! indices - integer :: n,k,l ! indices - integer :: ns_i, ns_o ! array sizes - integer :: dimlen ! netCDF dimension length - integer, allocatable :: dimlengths(:) - integer :: max_region ! maximum region index + integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) - integer :: max_regions_local - integer :: max_regions + real(r8), allocatable :: data_i(:,:) + real(r8), allocatable :: data_o(:,:) + real(r8), allocatable :: urban_classes_gcell_o(:,:) ! % putput urban in each density class (% of total grid cell area) + integer , allocatable :: region_i(:) ! input grid: region ID + integer :: ni,no ! indices + integer :: ns_i, ns_o ! array sizes + integer :: n,k,l ! indices + integer :: max_regions ! maximum region index integer :: max_index(1) - integer :: rcode, ier ! error status + integer :: rcode, ier ! error status character(len=*), parameter :: subname = 'mkurban' !----------------------------------------------------------------------- @@ -148,42 +143,59 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & if (root_task) then write (ndiag,'(a)') 'Attempting to make %urban .....' - end if - - ! Open raw data file - need to do this first to obtain ungridded dimension size - if (root_task) then write (ndiag,'(a)') 'Opening urban file: '//trim(file_data_i) end if + + ! Open input data file call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - ! Create a route handle between the input and output mesh - call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Determine ns_i and allocate data_i + ! Determine ns_i call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(data_i(numurbl,ns_i),stat=ier) - if (ier/=0) call shr_sys_abort() - ! Determine ns_o and allocate data_o - ns_o = size(pcturb_o) + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the landmask from the input data file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - allocate(data_o(numurbl,ns_o),stat=ier) + allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (frac_i(ni) > 0._r8) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create a route handle between the input and output mesh + allocate(frac_o(ns_o)) + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) ! Read in input data ! - levels are the outermost dimension in pio reads ! - levels are the innermost dimension for esmf fields ! Input data is read into (ns_i,numurbl) array and then transferred to data_i(numurbl,ns_i) + allocate(data_i(numurbl,ns_i),stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(data_o(numurbl,ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid, 'PCT_URBAN', mesh_i, data_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -198,32 +210,13 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & allocate(urban_classes_gcell_o(ns_o, numurbl), stat=ier) if (ier/=0) call shr_sys_abort() do l = 1,numurbl - do n = 1,ns_o - urban_classes_gcell_o(n,l) = data_o(l,n) + do no = 1,ns_o + urban_classes_gcell_o(no,l) = data_o(l,no) end do end do - - ! Determine frac_o (regrid frac_i to frac_o) - allocate(frac_o(ns_o),stat=ier) - allocate(frac_i(ns_i) ,stat=ier) - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, frac_i, frac_o, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Area-average percent cover on input grid to output grid and correct according to frac_o - ! Note that percent cover is in terms of total grid area. - do n = 1,ns_o - if (frac_o(n) > 0._r8) then - urban_classes_gcell_o(n,:) = urban_classes_gcell_o(n,:) / frac_o(n) - else - urban_classes_gcell_o(n,:) = 0._r8 - end if - end do - do n = 1, ns_o - pcturb_o(n) = sum(urban_classes_gcell_o(n,:)) + do no = 1, ns_o + pcturb_o(no) = sum(urban_classes_gcell_o(no,:)) end do - ! Check for conservation do no = 1, ns_o if ((pcturb_o(no)) > 100.000001_r8) then @@ -289,16 +282,14 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & ! Create a multi-dimensional array (data_i) where each ungridded dimension corresponds to a 2d field ! where there is a 1 for every gridcell that has region_i equal to a given region - ! TODO: do we need to multiply by mask_i? if (allocated(data_i)) deallocate(data_i) allocate(data_i(max_regions, ns_i), stat=ier) if (ier/=0) call shr_sys_abort('error allocating data_i(max_regions, ns_i)') data_i(:,:) = 0._r8 do l = 1,max_regions - do n = 1,ns_i - if (region_i(n) == l) then - data_i(l,n) = 1._r8 * frac_i(n) - !data_i(l,n) = 1._r8 + do ni = 1,ns_i + if (region_i(ni) == l) then + data_i(l,ni) = 1._r8 * frac_i(ni) end if end do end do @@ -313,10 +304,10 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & ! Now find dominant region in each output gridcell - this is identical to the maximum index region_o(:) = 0 - do n = 1,ns_o - max_index = maxloc(data_o(:,n)) - if (data_o(max_index(1),n) > 0._r8) then - region_o(n) = max_index(1) + do no = 1,ns_o + max_index = maxloc(data_o(:,no)) + if (data_o(max_index(1),no) > 0._r8) then + region_o(no) = max_index(1) end if end do @@ -433,10 +424,10 @@ subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) end subroutine normalize_urbn_by_tot !=============================================================== - subroutine mkurbanpar(pioid_o, datfname_i, mesh_o, & + subroutine mkurbanpar(datfname_i, pioid_o, mesh_o, & region_o, urban_classes_gcell_o, urban_skip_abort_on_invalid_data_check) ! - ! Make Urban Parameter data + ! Make Urban Parameter data using the information from region_o input ! ! Note that, in a grid cell with region_o==r, parameter values are filled from region r ! for ALL density classes. Thus, the parameter variables have a numurbl dimension along @@ -450,13 +441,13 @@ subroutine mkurbanpar(pioid_o, datfname_i, mesh_o, & use mkvarpar ! input/output variables - type(file_desc_t) , intent(inout) :: pioid_o - character(len=*) , intent(in) :: datfname_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh - integer , intent(in) :: region_o(:) ! output grid: region ID (length: ns_o) - real(r8) , intent(in) :: urban_classes_gcell_o(:,:) ! output grid: percent urban in each density class - ! (% of total grid cell area) (dimensions: ns_o, numurbl) - logical , intent(in) :: urban_skip_abort_on_invalid_data_check + character(len=*) , intent(in) :: datfname_i ! input data file name + type(file_desc_t) , intent(inout) :: pioid_o ! output file pio id + type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh + integer , intent(in) :: region_o(:) ! output grid: region ID (length: ns_o) + real(r8) , intent(in) :: urban_classes_gcell_o(:,:) ! output grid: percent urban in each density class + ! (% of total grid cell area) (dimensions: ns_o, numurbl) + logical , intent(in) :: urban_skip_abort_on_invalid_data_check ! local variables ! Type to store information about each urban parameter diff --git a/tools/mksurfdata_esmf/src/mkutilsMod.F90 b/tools/mksurfdata_esmf/src/mkutilsMod.F90 index ae6daaaa8f..f2b920fc85 100644 --- a/tools/mksurfdata_esmf/src/mkutilsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkutilsMod.F90 @@ -15,12 +15,6 @@ module mkutilsMod public :: slightly_above public :: get_filename !Returns filename given full pathname public :: chkerr - public :: mkrank - - interface mkrank - module procedure mkrank_r4 - module procedure mkrank_r8 - end interface mkrank character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -184,141 +178,5 @@ character(len=256) function get_filename (fulpath) end function get_filename - !=============================================================== - subroutine mkrank_r8 (n, a, miss, num, iv) - ! - ! Return indices of largest [num] values in array [a]. - ! - ! input/output variables - integer , intent(in) :: n !array length - real(r8), intent(in) :: a(0:n) !array to be ranked - integer , intent(in) :: miss !missing data value - integer , intent(in) :: num !number of largest values requested - integer , intent(out):: iv(num) !index to [num] largest values in array [a] - - ! local variables: - real(r8) :: a_max !maximum value in array - real(r8) :: delmax !tolerance for finding if larger value - integer :: i !array index - integer :: m !do loop index - integer :: k !do loop index - logical ::exclude !true if data value has already been chosen - !----------------------------------------------------------------------- - - delmax = 1.e-06 - - ! Find index of largest non-zero number - - iv(1) = miss - a_max = -9999. - - do i = 0, n - if (a(i)>0. .and. (a(i)-a_max)>delmax) then - a_max = a(i) - iv(1) = i - end if - end do - - ! iv(1) = miss indicates no values > 0. this is an error - - if (iv(1) == miss) then - write (6,*) 'MKRANK error: iv(1) = missing' - call shr_sys_abort() - end if - - ! Find indices of the next [num]-1 largest non-zero number. - ! iv(m) = miss if there are no more values > 0 - - do m = 2, num - iv(m) = miss - a_max = -9999. - do i = 0, n - - ! exclude if data value has already been chosen - exclude = .false. - do k = 1, m-1 - if (i == iv(k)) exclude = .true. - end do - - ! if not already chosen, see if it is the largest of - ! the remaining values - if (.not. exclude) then - if (a(i)>0. .and. (a(i)-a_max)>delmax) then - a_max = a(i) - iv(m) = i - end if - end if - end do - end do - - end subroutine mkrank_r8 - - !=============================================================== - subroutine mkrank_r4 (n, a, miss, num, iv) - ! - ! Return indices of largest [num] values in array [a]. - ! - ! input/output variables - integer , intent(in) :: n !array length - real(r4), intent(in) :: a(0:n) !array to be ranked - integer , intent(in) :: miss !missing data value - integer , intent(in) :: num !number of largest values requested - integer , intent(out):: iv(num) !index to [num] largest values in array [a] - - ! local variables: - real(r4) :: a_max !maximum value in array - real(r4) :: delmax !tolerance for finding if larger value - integer :: i !array index - integer :: m !do loop index - integer :: k !do loop index - logical ::exclude !true if data value has already been chosen - !----------------------------------------------------------------------- - - delmax = 1.e-06 - - ! Find index of largest non-zero number - - iv(1) = miss - a_max = -9999. - - do i = 0, n - if (a(i)>0. .and. (a(i)-a_max)>delmax) then - a_max = a(i) - iv(1) = i - end if - end do - - ! iv(1) = miss indicates no values > 0. this is an error - - if (iv(1) == miss) then - write (6,*) 'MKRANK error: iv(1) = missing' - call shr_sys_abort() - end if - - ! Find indices of the next [num]-1 largest non-zero number. - ! iv(m) = miss if there are no more values > 0 - - do m = 2, num - iv(m) = miss - a_max = -9999. - do i = 0, n - ! exclude if data value has already been chosen - exclude = .false. - do k = 1, m-1 - if (i == iv(k)) exclude = .true. - end do - - ! if not already chosen, see if it is the largest of - ! the remaining values - if (.not. exclude) then - if (a(i)>0. .and. (a(i)-a_max)>delmax) then - a_max = a(i) - iv(m) = i - end if - end if - end do - end do - - end subroutine mkrank_r4 end module mkutilsMod From b531023e64bd30b0d41ac66409116f74437fd54e Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 1 Feb 2022 23:36:55 -0700 Subject: [PATCH 037/614] more pudates for voc and glacier --- .../gen_mksurfdata_namelist.xml | 4 +- tools/mksurfdata_esmf/run/mksurfdata_in | 4 +- tools/mksurfdata_esmf/run/run_mksurfdata | 0 tools/mksurfdata_esmf/src/CMakeLists.txt | 2 +- tools/mksurfdata_esmf/src/ESMF_RegridEx.F90 | 93 - tools/mksurfdata_esmf/src/mkfileMod.F90 | 165 +- .../src/mkglacierregionMod.F90 | 86 +- tools/mksurfdata_esmf/src/mkglcmecMod.F90 | 1544 ++++++++--------- tools/mksurfdata_esmf/src/mklaiMod.F90 | 524 +++--- tools/mksurfdata_esmf/src/mkpioMod.F90 | 8 +- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 4 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 250 +-- .../src/mkurbanparCommonMod.F90 | 191 -- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 221 ++- tools/mksurfdata_esmf/src/mkvocefMod.F90 | 227 +-- 15 files changed, 1682 insertions(+), 1641 deletions(-) mode change 100644 => 100755 tools/mksurfdata_esmf/run/run_mksurfdata delete mode 100644 tools/mksurfdata_esmf/src/ESMF_RegridEx.F90 delete mode 100644 tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index c15242deda..2b8229ab91 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -109,7 +109,7 @@ - lnd/clm2/rawdata/mksrf_topo.10min.c191120.nc + lnd/clm2/rawdata/mksrf_topo.10min.cdf5.c220201.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_c200129.nc @@ -146,7 +146,7 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/mksrf_GlacierRegion_10x10min_nomask_c191120.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_cdf5_c200129.nc diff --git a/tools/mksurfdata_esmf/run/mksurfdata_in b/tools/mksurfdata_esmf/run/mksurfdata_in index 80fd485495..289c151263 100644 --- a/tools/mksurfdata_esmf/run/mksurfdata_in +++ b/tools/mksurfdata_esmf/run/mksurfdata_in @@ -17,12 +17,12 @@ mksrf_fpeat_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' mksrf_fvocef = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_vocef_0.5x0.5_simyr2000.c110531.nc' mksrf_fvocef_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' - mksrf_furbtopo = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_topo.10min.c191120.nc' + mksrf_furbtopo = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_topo.10min.cdf5.c220201.nc' mksrf_furbtopo_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_c200129.nc' mksrf_fglacier = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000.c120926.nc' mksrf_fglacier_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' mksrf_fglacierregion = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_GlacierRegion_10x10min_nomask_cd5_c220131.nc' - mksrf_fglacierregion_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_c200129.nc' + mksrf_fglacierregion_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_cdf5_c200129.nc' mksrf_fvegtyp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_1850.c190119.nc' mksrf_fvegtyp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' mksrf_fhrvtyp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_1850.c190119.nc' diff --git a/tools/mksurfdata_esmf/run/run_mksurfdata b/tools/mksurfdata_esmf/run/run_mksurfdata old mode 100644 new mode 100755 diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 62c71204e8..54057f4125 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -20,6 +20,7 @@ set(SRCFILES mkvarctl.F90 mkvarpar.F90 mkpioMod.F90 mkfileMod.F90 + mkglacierregionMod.F90 mklanwatMod.F90 mkorganicMod.F90 mksoilcolMod.F90 @@ -27,7 +28,6 @@ set(SRCFILES mkvarctl.F90 mksoiltexMod.F90 mksoildepthMod.F90 mkurbanparMod.F90 - mkurbanparCommonMod.F90 mkesmfMod.F90 mkutilsMod.F90 mkchecksMod.F90 diff --git a/tools/mksurfdata_esmf/src/ESMF_RegridEx.F90 b/tools/mksurfdata_esmf/src/ESMF_RegridEx.F90 deleted file mode 100644 index 2da6b6b57b..0000000000 --- a/tools/mksurfdata_esmf/src/ESMF_RegridEx.F90 +++ /dev/null @@ -1,93 +0,0 @@ -program ESMF_RegridEx - - !============================================================================== - ! This program shows examples of using Regrid on Field data - !----------------------------------------------------------------------------- - use ESMF - - implicit none - - ! Local variables to be used in the Regrid method calls. - ! The code creating and filling these variables is not included in the - ! example documentation because those interfaces are not specific to - ! Regrid. - type(ESMF_Field) :: field1, field2 - type(ESMF_IGrid) :: srcigrid, dstigrid - type(ESMF_RouteHandle) :: regrid_rh - type(ESMF_DELayout) :: layout1, layout2 - integer :: rc - integer :: finalrc, npets - integer :: i, j, lb(2), ub(2), halo - type(ESMF_ArraySpec) :: arrayspec - type(ESMF_VM) :: vm - real (ESMF_KIND_R8), dimension(:,:), pointer :: f90ptr1 - real (ESMF_KIND_R8), dimension(2) :: mincoords, maxcoords - - finalrc = ESMF_SUCCESS - - !------------------------------------------------------------------------- - ! ! Setup: - ! ! - ! ! Create a source and destination igrid with data on it, to use - ! ! in the Regrid calls below. - - call ESMF_Initialize(rc=rc) - call ESMF_VMGetGlobal(vm, rc=rc) - call ESMF_VMGet(vm, petCount=npets, rc=rc) - - layout1 = ESMF_DELayoutCreate(vm, (/ 1, npets /), rc=rc) - layout2 = ESMF_DELayoutCreate(vm, (/ npets, 1 /), rc=rc) - - mincoords = (/ 0.0, 0.0 /) - maxcoords = (/ 20.0, 30.0 /) - srcigrid = ESMF_IGridCreateHorzXYUni((/ 90, 180 /), mincoords, maxcoords, & - horzStagger=ESMF_IGRID_HORZ_STAGGER_A, name="srcigrid", rc=rc) - call ESMF_IGridDistribute(srcigrid, delayout=layout1, rc=rc) - - ! same igrid coordinates, but different layout - dstigrid = ESMF_IGridCreateHorzXYUni((/ 90, 180 /), mincoords, maxcoords, horzStagger=ESMF_IGRID_HORZ_STAGGER_A, name="srcigrid", rc=rc) - call ESMF_IGridDistribute(dstigrid, delayout=layout2, rc=rc) - call ESMF_ArraySpecSet(arrayspec, 2, ESMF_TYPEKIND_R8, rc) - - ! allow for a halo width of 3, let field create data space - halo = 3 - field1 = ESMF_FieldCreate(srcigrid, arrayspec, horzRelloc=ESMF_CELL_CENTER, haloWidth=3, name="src pressure", rc=rc) - - ! get a fortran pointer to the data spacd - call ESMF_FieldGetDataPointer(field1, f90ptr1, ESMF_DATACOPY_REFERENCE, rc=rc) - - lb(:) = lbound(f90ptr1) - ub(:) = ubound(f90ptr1) - - f90ptr1(:,:) = 0.0 - do j=lb(2)+halo, ub(2)-halo - do i=lb(1)+halo, ub(1)-halo - f90ptr1(i, j) = i*1000 + j - enddo - enddo - - field2 = ESMF_FieldCreate(dstigrid, arrayspec, horzRelloc=ESMF_CELL_CENTER, name="dst pressure", rc=rc) - - ! fields all ready to go - ! The user has already created an {\tt ESMF\_IGrid}, an - ! {\tt ESMF\_Array} with data, and put them together in an {\tt ESMF\_Field}. - ! An {\tt ESMF\_RouteHandle} is created by the regrid store call - ! and the data movement needed to - ! execute the regrid is stored with that handle by the store method. - ! To actually execute the operation, the source and destination data - ! objects must be supplied, along with the same {\tt ESMF\_RouteHandle}. - - call ESMF_FieldRegridStore(field1, field2, vm, routehandle=regrid_rh, regridmethod=ESMF_REGRIDMETHOD_BILINEAR, rc=rc) - call ESMF_FieldRegrid(field1, field2, regrid_rh, rc=rc) - call ESMF_FieldRegridRelease(regrid_rh, rc=rc) - - call ESMF_FieldDestroy(field1, rc=rc) - call ESMF_FieldDestroy(field2, rc=rc) - call ESMF_IGridDestroy(srcigrid, rc=rc) - call ESMF_IGridDestroy(dstigrid, rc=rc) - call ESMF_Finalize(rc=rc) - -end program ESMF_RegridEx - - - diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 9f118ba714..70ef4343b0 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -10,7 +10,7 @@ module mkfileMod #ifdef TODO use mkpftMod , only : mkpftAtt use mkglcmecMod , only : nglcec - use mkharvestMod , only : mkharvest_fieldname, mkharvest_numtypes, mkharvest_longname, mkharvest_units, harvestDataType + use mkharvestMod , only : mkharvest_fieldname, mkharvest_numtypes, mkharvest_longname, mkharvest_units, harvestDataType #endif use mkpioMod ! TODO: add only use mkvarctl @@ -36,26 +36,35 @@ module mkfileMod subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & pctlak, pctwet, lakedepth, organic, soil_color, nsoilcol, & - urban_classes_g, urban_region, pctsand, pctclay, mapunits, fmaxsoil, soildepth) + urban_classes_g, urban_region, pctsand, pctclay, mapunits, fmaxsoil, soildepth, & + glacier_region, ef_btr, ef_fet, ef_fdt, ef_shr, ef_grs, ef_crp, rc) ! input/output variables - integer , intent(in) :: nx - integer , intent(in) :: ny - logical , intent(in) :: dynlanduse - type(ESMF_Mesh) , intent(in) :: mesh_o - real(r8), pointer , intent(in) :: pctlak(:) ! percent of grid cell that is lake - real(r8), pointer , intent(in) :: pctwet(:) ! percent of grid cell that is wetland - real(r8), pointer , intent(in) :: lakedepth(:) ! lake depth (m) - real(r8), pointer , intent(in) :: organic(:,:) ! organic - integer , pointer , intent(in) :: soil_color(:) - integer , intent(in) :: nsoilcol - real(r8), pointer , intent(in) :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell - integer , pointer , intent(in) :: urban_region(:) ! urban region ID - real(r8), pointer , intent(in) :: fmaxsoil(:) ! soil_fractional saturated area - real(r8), pointer , intent(in) :: pctsand(:,:) ! soil texture: percent sand - real(r8), pointer , intent(in) :: pctclay(:,:) ! soil texture: percent clay - integer , pointer , intent(in) :: mapunits(:) - real(r8), pointer , intent(in) :: soildepth(:) ! soil depth (m) + integer , intent(in) :: nx + integer , intent(in) :: ny + type(ESMF_Mesh) , intent(in) :: mesh_o + logical , intent(in) :: dynlanduse + real(r8) , intent(in) :: pctlak(:) ! percent of grid cell that is lake + real(r8) , intent(in) :: pctwet(:) ! percent of grid cell that is wetland + real(r8) , intent(in) :: lakedepth(:) ! lake depth (m) + real(r8) , intent(in) :: organic(:,:) ! organic + integer , intent(in) :: soil_color(:) + integer , intent(in) :: nsoilcol + real(r8) , intent(in) :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell + integer , intent(in) :: urban_region(:) ! urban region ID + real(r8) , intent(in) :: fmaxsoil(:) ! soil_fractional saturated area + real(r8) , intent(in) :: pctsand(:,:) ! soil texture: percent sand + real(r8) , intent(in) :: pctclay(:,:) ! soil texture: percent clay + integer , intent(in) :: mapunits(:) + real(r8) , intent(in) :: soildepth(:) ! soil depth (m) + integer , intent(in) :: glacier_region(:) + real(r8) , intent(in) :: ef_btr(:) + real(r8) , intent(in) :: ef_fet(:) + real(r8) , intent(in) :: ef_fdt(:) + real(r8) , intent(in) :: ef_shr(:) + real(r8) , intent(in) :: ef_grs(:) + real(r8) , intent(in) :: ef_crp(:) + integer , intent(out):: rc #ifdef TODO type(harvestDataType) , intent(in) :: harvdata #endif @@ -69,7 +78,6 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & integer, allocatable :: ind1D(:) ! Indices of 1D harvest variables integer, allocatable :: ind2D(:) ! Indices of 2D harvest variables integer :: rcode - integer :: rc integer :: n, i logical :: define_mode character(len=256) :: lev1name @@ -81,20 +89,22 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & !--------------------------- ! TODO: what about setting no fill values? - call mkpio_wopen(trim(fsurdat), clobber=.true., pioid=pioid) + call mkpio_wopen(trim(fsurdat), clobber=.true., pioid=pioid) ! ---------------------------------------------------------------------- ! Define dimensions and global attributes ! ---------------------------------------------------------------------- - call mkfile_define_dims(pioid, nx, ny, dynlanduse) - call mkfile_define_atts(pioid, dynlanduse) + call mkfile_define_dims(pioid, nx, ny, dynlanduse) + call mkfile_define_atts(pioid, dynlanduse) ! ---------------------------------------------------------------------- ! Define and outut variables ! ---------------------------------------------------------------------- - call ESMF_LogWrite(subname//'defining variables', ESMF_LOGMSG_INFO) + if (root_task) then + write(ndiag,'(a)') 'Writing out output variables' + end if if ( outnc_double ) then xtype = PIO_DOUBLE @@ -174,17 +184,68 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & 'unitless', urban_classes_g, lev1name='numurbl', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'EF1_BTR', 'EF btr (isoprene)', & + 'unitless', ef_btr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'EF1_FET', 'EF fet (isoprene)', & + 'unitless', ef_fet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'EF1_FDT', 'EF fdt (isoprene)', & + 'unitless', ef_fdt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'EF1_SHR', 'EF shr (isoprene)', & + 'unitless', ef_shr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'EF1_GRS', 'EF grs (isoprene)', & + 'unitless', ef_grs, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'EF1_CRP', 'EF crp (isoprene)', & + 'unitless', ef_crp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if end do ! ---------------------------------------------------------------------- - ! Make Urban Parameters from raw input data and write to surface dataset + ! Make Urban Parameters from raw input data and write to surface dataset ! Write to netcdf file is done inside mkurbanpar routine ! ---------------------------------------------------------------------- - + call mkurbanpar(mksrf_furban, pioid, mesh_o, urban_region, urban_classes_g, & urban_skip_abort_on_invalid_data_check) + ! ---------------------------------------------------------------------- + ! Make LAI and SAI from 1/2 degree data and write to surface dataset + ! Write to netcdf file is done inside mklai routine + ! ---------------------------------------------------------------------- + ! if (root_task) then + ! write(ndiag,'(a)')'calling mklai' + ! end if + ! call mklai(mksrf_lai, mksrf_lai_mesh, pioid, mesh_o, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! ---------------------------------------------------------------------- + ! TODO: Write out variables that did not work in the loop + ! ---------------------------------------------------------------------- + do n = 1,2 + if (n == 1) then + define_mode = .true. + rcode = pio_redef(pioid) + else + define_mode = .false. + rcode = pio_enddef(pioid) + end if + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out glacier_region" + call mkfile_output(pioid, define_mode, mesh_o, 'GLACIER_REGION', 'glacier region ID', & + 'unitless', glacier_region, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end do + ! Close surface dataset call pio_closefile(pioid) @@ -410,17 +471,17 @@ subroutine mkfile_define_atts(pioid, dynlanduse) end subroutine mkfile_define_atts !================================================================================= - subroutine mkfile_output_int1d(pioid, define_mode, mesh, varname, longname, units, ipointer, rc) + subroutine mkfile_output_int1d(pioid, define_mode, mesh, varname, longname, units, data, rc) ! input/output variables - type(file_desc_t) , intent(inout) :: pioid - logical , intent(in) :: define_mode - type(ESMF_Mesh) , intent(in) :: mesh - character(len=*) , intent(in) :: varname - character(len=*) , intent(in) :: longname - character(len=*) , intent(in) :: units - integer , pointer :: ipointer(:) - integer , intent(out) :: rc + type(file_desc_t) , intent(inout) :: pioid + logical , intent(in) :: define_mode + type(ESMF_Mesh) , intent(in) :: mesh + character(len=*) , intent(in) :: varname + character(len=*) , intent(in) :: longname + character(len=*) , intent(in) :: units + integer , intent(in) :: data(:) + integer , intent(out) :: rc ! local variables type(io_desc_t) :: pio_iodesc @@ -436,23 +497,23 @@ subroutine mkfile_output_int1d(pioid, define_mode, mesh, varname, longname, unit call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) rcode = pio_inq_varid(pioid, trim(varname), pio_varid) - call pio_write_darray(pioid, pio_varid, pio_iodesc, ipointer, rcode) + call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) call pio_freedecomp(pioid, pio_iodesc) end if end subroutine mkfile_output_int1d !================================================================================= - subroutine mkfile_output_int2d(pioid, define_mode, mesh, varname, longname, units, ipointer, rc) + subroutine mkfile_output_int2d(pioid, define_mode, mesh, varname, longname, units, data, rc) ! input/output variables - type(file_desc_t) , intent(inout) :: pioid - logical , intent(in) :: define_mode - type(ESMF_Mesh) , intent(in) :: mesh - character(len=*) , intent(in) :: varname - character(len=*) , intent(in) :: longname - character(len=*) , intent(in) :: units - integer , pointer :: ipointer(:,:) - integer , intent(out) :: rc + type(file_desc_t) , intent(inout) :: pioid + logical , intent(in) :: define_mode + type(ESMF_Mesh) , intent(in) :: mesh + character(len=*) , intent(in) :: varname + character(len=*) , intent(in) :: longname + character(len=*) , intent(in) :: units + integer , intent(in) :: data(:,:) + integer , intent(out) :: rc ! local variables type(io_desc_t) :: pio_iodesc @@ -468,13 +529,13 @@ subroutine mkfile_output_int2d(pioid, define_mode, mesh, varname, longname, unit call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) rcode = pio_inq_varid(pioid, trim(varname), pio_varid) - call pio_write_darray(pioid, pio_varid, pio_iodesc, ipointer, rcode) + call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) call pio_freedecomp(pioid, pio_iodesc) end if end subroutine mkfile_output_int2d !================================================================================= - subroutine mkfile_output_real1d(pioid, define_mode, mesh, xtype, varname, longname, units, rpointer, rc) + subroutine mkfile_output_real1d(pioid, define_mode, mesh, xtype, varname, longname, units, data, rc) ! input/output variables type(file_desc_t), intent(inout) :: pioid @@ -484,7 +545,7 @@ subroutine mkfile_output_real1d(pioid, define_mode, mesh, xtype, varname, longna character(len=*), intent(in) :: varname character(len=*), intent(in) :: longname character(len=*), intent(in) :: units - real(r8) , pointer :: rpointer(:) + real(r8) , intent(in) :: data(:) integer , intent(out) :: rc ! local variables @@ -501,13 +562,13 @@ subroutine mkfile_output_real1d(pioid, define_mode, mesh, xtype, varname, longna call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) rcode = pio_inq_varid(pioid, trim(varname), pio_varid) - call pio_write_darray(pioid, pio_varid, pio_iodesc, rpointer, rcode) + call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) call pio_freedecomp(pioid, pio_iodesc) end if end subroutine mkfile_output_real1d !================================================================================= - subroutine mkfile_output_real2d(pioid, define_mode, mesh, xtype, varname, longname, units, rpointer, lev1name, rc) + subroutine mkfile_output_real2d(pioid, define_mode, mesh, xtype, varname, longname, units, data, lev1name, rc) ! input/output variables type(file_desc_t), intent(inout) :: pioid @@ -518,7 +579,7 @@ subroutine mkfile_output_real2d(pioid, define_mode, mesh, xtype, varname, longna character(len=*), intent(in) :: longname character(len=*), intent(in) :: units character(len=*), intent(in) :: lev1name - real(r8) , pointer :: rpointer(:,:) + real(r8) , intent(in) :: data(:,:) integer , intent(out) :: rc ! local variables @@ -535,7 +596,7 @@ subroutine mkfile_output_real2d(pioid, define_mode, mesh, xtype, varname, longna call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) rcode = pio_inq_varid(pioid, trim(varname), pio_varid) - call pio_write_darray(pioid, pio_varid, pio_iodesc, rpointer, rcode) + call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) call pio_freedecomp(pioid, pio_iodesc) end if end subroutine mkfile_output_real2d diff --git a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 index baa79b7e85..eaa5283a2c 100644 --- a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 @@ -11,7 +11,7 @@ module mkglacierregionMod use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_nn, get_meshareas + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas use mkutilsMod , only : chkerr #ifdef TODO ! use mkdiagnosticsMod, only : output_diagnostics_index @@ -24,6 +24,8 @@ module mkglacierregionMod public :: mkglacierregion ! make glacier region ID + integer, private :: nglacier_regions = 3 + character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -46,30 +48,31 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r type(ESMF_RouteHandle) :: routehandle ! nearest neighbor routehandle type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid - integer :: ni,no + integer :: ni,no,l integer :: ns_i, ns_o + integer , allocatable :: mask_i(:) + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: data_i(:,:) + real(r8), allocatable :: data_o(:,:) integer , allocatable :: glacier_region_i(:) ! glacier region on input grid - real(r4), allocatable :: frac_i(:) ! input mask - real(r4), allocatable :: frac_o(:) ! output fractions - real(r4), allocatable :: data_i(:) - real(r4), allocatable :: data_o(:) integer :: ier, rcode ! error status - integer :: max_region ! max region ID + integer :: max_index(1) character(len=*), parameter :: subname = 'mkglacierregion' !----------------------------------------------------------------------- rc = ESMF_SUCCESS if (root_task) then - write (ndiag,'(a)') 'Attempting to make glacier region .....' + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make glacier region .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) end if ! Open input data file - if (root_task) then - write (ndiag,'(a)') 'Opening glacier region raw data file: ', trim(file_data_i) - end if call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) @@ -77,21 +80,40 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - ! Create a nearest neighbor route handle between the input and output mesh - call create_routehandle_nn(mesh_i, mesh_o, routehandle, rc=rc) - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - - ! Determine ns_i and allocate glacier_region_i + ! Determine ns_i call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(glacier_region_i(ns_i), stat=ier) - if (ier/=0) call abort() - ! Determine ns_o (glacier_region_o has already been allocated) + ! Determine ns_o call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Get the landmask from the input data file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (frac_i(ni) > 0._r8) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create a route handle between the input and output mesh + allocate(frac_o(ns_o)) + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + ! Read in input data + allocate(glacier_region_i(ns_i), stat=ier) + if (ier/=0) call abort() call mkpio_get_rawdata(pioid, 'GLACIER_REGION', mesh_i, glacier_region_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -101,20 +123,28 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r call shr_sys_abort() end if - ! Convert to real4 - allocate(data_i(ns_i)) - do ni = 1,ns_i - data_i(ni) = real(glacier_region_i(ni), kind=r4) + ! Now determine data_i as a real 2d array - for every possible soil color create a global + ! field with gridcells equal to 1 for that soil color and zero elsewhere + allocate(data_i(0:nglacier_regions,ns_i)) + data_i(:,:) = 0._r4 + do l = 0,nglacier_regions + do ni = 1,ns_i + if (glacier_region_i(ni) == l) then + data_i(l,ni) = 1._r4 + end if + end do end do - allocate(data_o(ns_o)) - ! Regrid raw data - yse a nearest neighbor map here - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, rc) + ! Regrid data_i to data_o + allocate(data_o(0:nglacier_regions, ns_o), stat=ier) + if (ier/=0) call shr_sys_abort('error allocating data_i(max_regions, ns_o)') + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, nglacier_regions, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Now convert back to integer + glacier_region_o(:) = 0 do no = 1,ns_o - glacier_region_o(no) = nint(data_o(no)) + max_index = maxloc(data_o(:,no)) + glacier_region_o(no) = max_index(1) - 1 end do ! call output_diagnostics_index(glacier_region_i, glacier_region_o, tgridmap, & diff --git a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 index 1f9164afe9..d60f735cfa 100644 --- a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 @@ -1,787 +1,787 @@ module mkglcmecMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkglcmecMod -! -! !DESCRIPTION: -! Make glacier multi-elevation class data -! -! !REVISION HISTORY: -! Author: Erik Kluzek, Mariana Vertenstein -! -!----------------------------------------------------------------------- -!!USES: + !----------------------------------------------------------------------- + !BOP + ! + ! !MODULE: mkglcmecMod + ! + ! !DESCRIPTION: + ! Make glacier multi-elevation class data + ! + ! !REVISION HISTORY: + ! Author: Erik Kluzek, Mariana Vertenstein + ! + !----------------------------------------------------------------------- + !!USES: use shr_kind_mod, only : r8 => shr_kind_r8 use mkdomainMod , only : domain_checksame implicit none private ! By default make data private -! -! !PUBLIC MEMBER FUNCTIONS: -! + ! + ! !PUBLIC MEMBER FUNCTIONS: + ! public mkglcmecInit ! Initialization public mkglcmec ! Set glacier multi-elevation class public mkglacier ! Set percent glacier -! -! !PUBLIC DATA MEMBERS: -! + ! + ! !PUBLIC DATA MEMBERS: + ! integer, public :: nglcec = 10 ! number of elevation classes for glaciers - real(r8), pointer :: elevclass(:) ! elevation classes -! -! !PRIVATE MEMBER FUNCTIONS: + real(r8), allocatable :: elevclass(:) ! elevation classes + ! + ! !PRIVATE MEMBER FUNCTIONS: private get_elevclass ! get elevation class index private mean_elevation_vc ! get the elevation of a virtual column -!EOP -!=============================================================== + !EOP + !=============================================================== contains -!=============================================================== - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkglcmecInit -! -! !INTERFACE: -subroutine mkglcmecInit( elevclass_o ) -! -! !DESCRIPTION: -! Initialize of Make glacier multi-elevation class data -! !USES: -! -! !ARGUMENTS: - implicit none - real(r8), intent(OUT) :: elevclass_o(:) ! elevation classes -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - character(len=32) :: subname = 'mkglcmecInit:: ' -!----------------------------------------------------------------------- - allocate( elevclass(nglcec+1) ) - - ! ----------------------------------------------------------------- - ! Define elevation classes, represents lower boundary of each class - ! ----------------------------------------------------------------- - - if ( nglcec == 36 )then - elevclass(:) = (/ 0., 200., 400., 600., 800., & - 1000., 1200., 1400., 1600., 1800., & - 2000., 2200., 2400., 2600., 2800., & - 3000., 3200., 3400., 3600., 3800., & - 4000., 4200., 4400., 4600., 4800., & - 5000., 5200., 5400., 5600., 5800., & - 6000., 6200., 6400., 6600., 6800., & - 7000., 10000./) - else if ( nglcec == 10 )then - elevclass(1) = 0. - elevclass(2) = 200. - elevclass(3) = 400. - elevclass(4) = 700. - elevclass(5) = 1000. - elevclass(6) = 1300. - elevclass(7) = 1600. - elevclass(8) = 2000. - elevclass(9) = 2500. - elevclass(10) = 3000. - elevclass(11) = 10000. - else if ( nglcec == 5 )then - elevclass(1) = 0. - elevclass(2) = 500. - elevclass(3) = 1000. - elevclass(4) = 1500. - elevclass(5) = 2000. - elevclass(6) = 10000. - else if ( nglcec == 3 )then - elevclass(1) = 0. - elevclass(2) = 1000. - elevclass(3) = 2000. - elevclass(4) = 10000. - else if ( nglcec == 1 )then - elevclass(1) = 0. - elevclass(2) = 10000. - else - write(6,*) subname//"ERROR:: nglcec must be 1, 3, 5, 10 or 36",& - " to work with CLM: " - call abort() - end if - - elevclass_o(:) = elevclass(:) - -end subroutine mkglcmecInit - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkglcmec -! -! !INTERFACE: -subroutine mkglcmec(ldomain, mapfname, & - datfname_fglacier, ndiag, & - pctglcmec_o, topoglcmec_o, & - pctglcmec_gic_o, pctglcmec_icesheet_o, & - pctglc_gic_o, pctglc_icesheet_o) -! -! !DESCRIPTION: -! make percent glacier on multiple elevation classes, mean elevation for each -! elevation class, and associated fields -! -! Note that the raw glacier data are specified by level, and thus implicitly include the -! necessary topo data for breaking pct glacier into elevation classes. Each level in the -! input data is assigned to an elevation (given by BIN_CENTERS in the input data). Thus, -! all of the input glacier in level 1 is treated as being at the same elevation, and -! likewise for each other level. These elevations are then used in assigning pct_glacier -! to the appropriate elevation class in the output data, as well as determining the mean -! topographic height of each elevation class in the output data. -! -! Note that the various percentages computed here are given as % of the glc_mec landunit. -! If the input glacier area is 0 for a given grid cell, this requires setting these % -! variables in an arbitrary way. -! -! !USES: - use shr_sys_mod, only : shr_sys_abort - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkutilsMod, only : slightly_below, slightly_above - use mkncdio - use mkvarctl , only : outnc_3dglc -! -! !ARGUMENTS: - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname_fglacier ! raw glacier data - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: pctglcmec_o (:,:) ! % for each elevation class on output glacier grid (% of landunit) - real(r8) , intent(out):: topoglcmec_o(:,:) ! mean elevation for each elevation classs on output glacier grid - real(r8), optional, intent(out):: pctglcmec_gic_o(:,:) ! % glc gic on output grid, by elevation class (% of landunit) - real(r8), optional, intent(out):: pctglcmec_icesheet_o(:,:) ! % glc ice sheet on output grid, by elevation class (% of landunit) - real(r8), optional, intent(out):: pctglc_gic_o(:) ! % glc gic on output grid, summed across elevation classes (% of landunit) - real(r8), optional, intent(out):: pctglc_icesheet_o(:) ! % glc ice sheet on output grid, summed across elevation classes (% of landunit) -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: David Lawrence -! 7/12/11: Bill Sacks: substantial rewrite to use input topo and % glacier at same resolution -! 9/25/12: Bill Sacks: substantial rewrite to use new format of fglacier, which provides -! percent by elevation bin (thus the separate topo dataset is no longer needed -! in this routine) -! -! -! !LOCAL VARIABLES: -!EOP - type(domain_type) :: tdomain ! local domain - type(gridmap_type) :: tgridmap ! local gridmap - real(r8), allocatable :: pctglc_gic_i(:) ! input GIC percentage for a single level - real(r8), allocatable :: pctglc_icesheet_i(:) ! input icesheet percentage for a single level - real(r8), allocatable :: topoglcmec_unnorm_o(:,:) ! same as topoglcmec_o, but unnormalized - real(r8), allocatable :: pctglc_tot_o(:) ! total glacier cover for the grid cell - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8) :: topoice_i ! topographic height of this level - real(r8) :: pctglc_i ! input total pct glacier for a single level & single point - real(r8) :: wt, frac ! weighting factors for remapping - integer :: ndims ! number of dimensions in input variables - integer :: dim_lengths(nf_max_var_dims) ! lengths of dimensions in input variables - integer, allocatable :: starts(:), counts(:) ! start indices & counts for reading variable slices - integer :: ni,no,ns_o,nst,lev ! indices - integer :: n,m ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: nlev ! number of levels in input file - real(r8) :: glc_sum ! temporary - integer :: ier ! error status - logical :: errors ! error status - - real(r8), parameter :: eps = 2.e-5_r8 ! epsilon for error checks (note that we use a large-ish value - ! because data are stored as single-precision floats in the - ! raw dataset) - real(r8), parameter :: eps_small = 1.e-12_r8 ! epsilon for error checks that expect close match - character(len=32) :: subname = 'mkglcmec' -!----------------------------------------------------------------------- - - ! Initialize all output fields to zero - - pctglcmec_o(:,:) = 0. - topoglcmec_o(:,:) = 0. - if ( outnc_3dglc )then - if ( (.not. present(pctglcmec_gic_o)) .or. (.not. present(pctglcmec_icesheet_o)) .or. & - (.not. present(pctglc_gic_o) ) .or. (.not. present(pctglc_icesheet_o) ) )then - call shr_sys_abort( subname//' ERROR: 3D glacier fields were NOT sent in and they are required' ) - end if - pctglcmec_gic_o(:,:) = 0. - pctglcmec_icesheet_o(:,:) = 0. - pctglc_gic_o(:) = 0. - pctglc_icesheet_o(:) = 0. - end if - - ! Set number of output points - - ns_o = ldomain%ns - - write (6,*) 'Attempting to make percent elevation class ',& - 'and mean elevation for glaciers .....' - - ! ----------------------------------------------------------------- - ! Read domain and dimension information from glacier raw data file - ! ----------------------------------------------------------------- - - call domain_read(tdomain,datfname_fglacier) - nst = tdomain%ns - - ! Read z dimension size - write (6,*) 'Open glacier file: ', trim(datfname_fglacier) - call check_ret(nf_open(datfname_fglacier, 0, ncid), subname) - ier = nf_inq_dimid (ncid, 'z', dimid) - if (ier /= NF_NOERR) then - write (6,*) trim(subname), ' ERROR: z dimension not found on glacier file:' - write (6,*) trim(datfname_fglacier) - write (6,*) 'Perhaps you are trying to use an old-format glacier file?' - write (6,*) '(prior to Sept., 2012)' - call abort() - end if - call check_ret(nf_inq_dimlen (ncid, dimid, nlev), subname) - - ! ----------------------------------------------------------------- - ! Read mapping data, check for consistency with domains - ! ----------------------------------------------------------------- - - ! Mapping for raw glacier -> model output grid - call gridmap_mapread(tgridmap, mapfname ) - - ! Error checks for domain and map consistencies - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Determine dimension lengths and create start & count arrays - ! for later reading one level at a time - ! ----------------------------------------------------------------- - - call get_dim_lengths(ncid, 'PCT_GLC_GIC', ndims, dim_lengths) - - allocate(starts(ndims), counts(ndims), stat=ier) - if (ier/=0) call abort() - - starts(1:ndims) = 1 - - ! We assume that the last dimension is the level dimension - counts(1:ndims-1) = dim_lengths(1:ndims-1) - counts(ndims) = 1 - - ! -------------------------------------------------------------------- - ! Compute fields on the output grid - ! -------------------------------------------------------------------- - - allocate(pctglc_gic_i(nst), pctglc_icesheet_i(nst), stat=ier) - if (ier/=0) call abort() - - allocate(topoglcmec_unnorm_o(ns_o,nglcec), stat=ier) - if (ier/=0) call abort() - - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() - - topoglcmec_unnorm_o(:,:) = 0. - - write(6,'(a,i4,a)',advance='no') 'Level (out of ', nlev, '): ' - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - do lev = 1, nlev - write(6,'(i4)',advance='no') lev - - ! Read this level's data - ! We assume that the last dimension is the level dimension - starts(ndims) = lev - call check_ret(nf_inq_varid (ncid, 'BIN_CENTERS', varid), subname) - call check_ret(nf_get_vara_double (ncid, varid, (/lev/), (/1/), topoice_i), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_GLC_GIC', varid), subname) - call check_ret(nf_get_vara_double (ncid, varid, starts, counts, pctglc_gic_i), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_GLC_ICESHEET', varid), subname) - call check_ret(nf_get_vara_double (ncid, varid, starts, counts, pctglc_icesheet_i), subname) - - ! Determine elevation class - m = get_elevclass(topoice_i) - if (m < 1 .or. m > nglcec) then - call abort() - end if - - do n = 1,tgridmap%ns - ni = tgridmap%src_indx(n) - no = tgridmap%dst_indx(n) - wt = tgridmap%wovr(n) * tdomain%mask(ni) - - ! fraction of this destination cell that is covered by source cells that are within the source landmask - frac = frac_dst(no) - - ! If frac == 0, then we can't do this, to avoid divide by 0. In this case, the - ! outputs remain equal to 0 (their initialized value). - if (frac > 0) then - pctglc_i = pctglc_gic_i(ni) + pctglc_icesheet_i(ni) - pctglcmec_o(no,m) = pctglcmec_o(no,m) + wt*pctglc_i / frac - if ( outnc_3dglc )then - pctglcmec_gic_o(no,m) = pctglcmec_gic_o(no,m) + wt*pctglc_gic_i(ni) / frac - pctglcmec_icesheet_o(no,m) = pctglcmec_icesheet_o(no,m) + wt*pctglc_icesheet_i(ni) / frac - end if - - ! note that, by weighting the following by pctglc_i, we are getting something - ! like the average topographic height over glaciated areas - NOT the average - ! topographic height of the entire grid cell - topoglcmec_unnorm_o(no,m) = topoglcmec_unnorm_o(no,m) + wt*pctglc_i*topoice_i / frac - end if - end do - end do - - ! Note: at this point, the various percentages are given as % of grid cell; below, we - ! renormalize these to be given as % of landunit. - - ! advance to next line (needed because of 'advance=no' writes above) - write(6,*) ' ' - - ! Close glacier input file - call check_ret(nf_close(ncid), subname) - - ! Normalize topoglcmec_o. To do this, note that pctglcmec_o(n,m) is equal to the sum of - ! the weights used in doing the weighted average of topoice_i (weight = - ! wt*pctglc_i/frac); hence pctglcmec_o(n,m) is the correct normalization factor - do no = 1,ns_o - do m = 1,nglcec - if (pctglcmec_o(no,m) > 0) then - topoglcmec_o(no,m) = topoglcmec_unnorm_o(no,m) / pctglcmec_o(no,m) - else - topoglcmec_o(no,m) = mean_elevation_vc(m) - end if - - ! Correct for rounding errors that put topoglcmec_o(no,m) slightly outside the - ! allowed bounds for this elevation class - if (slightly_below(topoglcmec_o(no,m), elevclass(m))) then - write(6,*) 'Warning: topoglcmec_o was slightly lower than lower bound; setting equal& - & to lower bound; for: ', no, m, topoglcmec_o(no,m), elevclass(m) - write(6,*) '(this is informational only, and probably just indicates rounding error)' - topoglcmec_o(no,m) = elevclass(m) - else if (slightly_above(topoglcmec_o(no,m), elevclass(m+1))) then - write(6,*) 'Warning: topoglcmec_o was slightly higher than upper bound; setting equal& - & to upper bound; for: ', no, m, topoglcmec_o(no,m), elevclass(m+1) - write(6,*) '(this is informational only, and probably just indicates rounding error)' - topoglcmec_o(no,m) = elevclass(m+1) - end if - end do - end do - - ! Renormalize percentages to be given as % of landunit rather than % of grid cell. - - allocate(pctglc_tot_o(ns_o), stat=ier) - if (ier/=0) call abort() - - do no = 1,ns_o - pctglc_tot_o(no) = sum(pctglcmec_o(no,:)) - - if (pctglc_tot_o(no) > 0._r8) then - pctglcmec_o(no,:) = pctglcmec_o(no,:) / pctglc_tot_o(no) * 100._r8 - if ( outnc_3dglc )then - pctglcmec_gic_o(no,:) = pctglcmec_gic_o(no,:) / pctglc_tot_o(no) * 100._r8 - pctglcmec_icesheet_o(no,:) = pctglcmec_icesheet_o(no,:) / pctglc_tot_o(no) * 100._r8 - end if - - else - ! Division of landunit is ambiguous. Apply the rule that all area is assigned to - ! the lowest elevation class, and all GIC. - pctglcmec_o(no,1) = 100._r8 - if ( outnc_3dglc )then - pctglcmec_gic_o(no,1) = 100._r8 - end if - end if - end do - - ! Set pctglc_gic_o to sum of pctglcmec_gic_o across elevation classes, and similarly for pctglc_icesheet_o - if ( outnc_3dglc )then - pctglc_gic_o = sum(pctglcmec_gic_o, dim=2) - pctglc_icesheet_o = sum(pctglcmec_icesheet_o, dim=2) - end if - - ! -------------------------------------------------------------------- - ! Perform various sanity checks - ! -------------------------------------------------------------------- - - errors = .false. - - ! Confirm that the sum over pctglcmec_o (from 1 to nglcec) is 100% - do no = 1,ns_o - glc_sum = sum(pctglcmec_o(no,:)) - if (abs(glc_sum - 100._r8) > eps_small) then - write(6,*)'glc_sum differs from 100% at no,pctglc= ',no,glc_sum - errors = .true. - end if - end do - - ! Confirm that GIC + ICESHEET = 100% - if ( outnc_3dglc )then - do no = 1,ns_o - if (abs((pctglc_gic_o(no) + pctglc_icesheet_o(no)) - 100._r8) > eps) then - write(6,*)'GIC + ICESHEET differs from 100% at no,pctglc_gic,pctglc_icesheet,lon,lat=', & - no,pctglc_gic_o(no),pctglc_icesheet_o(no),& - tgridmap%xc_dst(no),tgridmap%yc_dst(no) - errors = .true. - end if - end do - - ! Check that GIC + ICESHEET = total glacier at each elevation class - do m = 1, nglcec - do no = 1,ns_o - if (abs((pctglcmec_gic_o(no,m) + pctglcmec_icesheet_o(no,m)) - & - pctglcmec_o(no,m)) > eps) then - write(6,*)'GIC + ICESHEET differs from total GLC ' - write(6,*)'at no,m,pctglcmec,pctglcmec_gic,pctglcmec_icesheet = ' - write(6,*) no,m,pctglcmec_o(no,m),pctglcmec_gic_o(no,m),pctglcmec_icesheet_o(no,m) - errors = .true. - end if - end do - end do - end if - - - ! Error check: are all elevations within elevation class range - do no = 1,ns_o - do m = 1,nglcec - if (topoglcmec_o(no,m) < elevclass(m) .or. topoglcmec_o(no,m) > elevclass(m+1)) then - write(6,*) 'Error: mean elevation does not fall within elevation class ' - write(6,*) elevclass(m),elevclass(m+1),topoglcmec_o(no,m),m,no - errors = .true. - endif - end do - end do - - if (errors) then - call abort() - end if - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate(pctglc_gic_i, pctglc_icesheet_i) - deallocate(topoglcmec_unnorm_o) - deallocate(pctglc_tot_o) - deallocate(frac_dst) - deallocate(starts, counts) - - write (6,*) 'Successfully made percent elevation class and mean elevation for glaciers' - write (6,*) - -end subroutine mkglcmec - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkglacier -! -! !INTERFACE: -subroutine mkglacier(ldomain, mapfname, datfname, ndiag, zero_out, glac_o) -! -! !DESCRIPTION: -! make percent glacier -! -! In contrast to mkglcmec, this uses a "flat" PCT_GLACIER field (not separated by -! elevation class, and not separated into icesheet vs GIC). -! -! This simpler routine is sufficient for cases when we run without multiple elevation -! classes. This routine is also used when running with multiple elevation classes: we -! first regrid the flat PCT_GLACIER field, then later create the multiple elevation class -! data. This multi-step process makes it easier to do corrections on the total -! PCT_GLACIER, and make sure these corrections apply appropriately to the multi-level -! output. The assumption is that PCT_GLACIER is the sum of both PCT_GLC_GIC and -! PCT_GLC_ICESHEET across all elevation bins. -! -! !USES: - use mkdomainMod , only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - logical , intent(in) :: zero_out ! if should zero glacier out - real(r8) , intent(out):: glac_o(:) ! output grid: %glacier -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: glac_i(:) ! input grid: percent glac - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: gglac_i ! input grid: global glac - real(r8) :: garea_i ! input grid: global area - real(r8) :: gglac_o ! output grid: global glac - real(r8) :: garea_o ! output grid: global area - integer :: ni,no,k,n,m,ns, ns_o ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mkglacier' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make %glacier .....' - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns = tdomain%ns - ns_o = ldomain%ns - allocate(glac_i(ns), & - frac_dst(ns_o), & - stat=ier) - if (ier/=0) call abort() - - write (6,*) 'Open glacier file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_GLACIER', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, glac_i), subname) - call check_ret(nf_close(ncid), subname) - - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. - - if ( zero_out )then - - do no = 1, ns_o - glac_o(no) = 0. - enddo - - else - - call gridmap_mapread(tgridmap, mapfname ) - - ! Error checks for domain and map consistencies - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine glac_o on output grid - - call gridmap_areaave_srcmask(tgridmap, glac_i, glac_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - do no = 1, ns_o - if (glac_o(no) < 1.) glac_o(no) = 0. - enddo - end if - - ! Check for conservation - - do no = 1, ns_o - if ((glac_o(no)) > 100.000001_r8) then - write (6,*) 'MKGLACIER error: glacier = ',glac_o(no), & - ' greater than 100.000001 for column, row = ',no - call abort() - end if - enddo - - ! Some error checking and writing of global values before and after the regrid - - if ( .not. zero_out )then - - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - - allocate(mask_r8(ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - - ! Input grid - - gglac_i = 0. - garea_i = 0. - do ni = 1, ns - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - gglac_i = gglac_i + glac_i(ni)*(tgridmap%area_src(ni)/100.)*& - tdomain%mask(ni)*re**2 - end do - - ! Output grid - - gglac_o = 0. - garea_o = 0. - do no = 1, ns_o - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - gglac_o = gglac_o + glac_o(no)*(tgridmap%area_dst(no)/100.)*& - frac_dst(no)*re**2 - end do - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Glacier Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) -2001 format (1x,'surface type input grid area output grid area'/ & - 1x,' 10**6 km**2 10**6 km**2 ') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2002) gglac_i*1.e-06,gglac_o*1.e-06 - write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 -2002 format (1x,'glaciers ',f14.3,f17.3) -2004 format (1x,'all surface ',f14.3,f17.3) - - end if - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - if ( .not. zero_out )then - call gridmap_clean(tgridmap) - deallocate (glac_i, frac_dst, mask_r8) - end if - - write (6,*) 'Successfully made %glacier' - write (6,*) - -end subroutine mkglacier - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: get_elevclass -! -! !INTERFACE: -integer function get_elevclass(topo, writewarn) -! -! !DESCRIPTION: -! Returns elevation class index (1..nglcec) given the topographic height. -! If topo is lower than the lowest elevation class, returns 0. -! If topo is higher than the highest elevation class, returns (nglcec+1). -! In either of the two latter cases, the function also writes a warning message, unless -! writewarn is present and false. -! -! !ARGUMENTS: - implicit none - real(r8), intent(in) :: topo ! topographic height (m) - logical, intent(in), optional :: writewarn ! should warning messages be written? (default: true) -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! !LOCAL VARIABLES: -!EOP - integer :: m - logical :: my_writewarn - character(len=32) :: subname = 'get_elevclass' -!----------------------------------------------------------------------- - - if (present(writewarn)) then - my_writewarn = writewarn - else - my_writewarn = .true. - end if - - if (topo < elevclass(1)) then - if (my_writewarn) then - write(6,*) 'WARNING in ', trim(subname) - write(6,*) 'topo out of bounds' - write(6,*) 'topo = ', topo - write(6,*) 'elevclass(1) = ', elevclass(1) - end if - get_elevclass = 0 - return - end if - - do m = 1, nglcec - if (topo < elevclass(m+1)) then - ! note that we already know that topo >= elevclass(m), otherwise we would have - ! returned earlier - get_elevclass = m - return - end if - end do - - if (my_writewarn) then - write(6,*) 'WARNING in ', trim(subname) - write(6,*) 'topo out of bounds' - write(6,*) 'topo = ', topo - write(6,*) 'elevclass(nglcec+1) = ', elevclass(nglcec+1) - end if - get_elevclass = nglcec+1 - -end function get_elevclass - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mean_elevation_vc -! -! !INTERFACE: -real(r8) function mean_elevation_vc(class) -! -! !DESCRIPTION: -! For a virtual column (thus, a column that has no true elevation data), return the -! "mean" elevation of the given elevation class. -! -! !ARGUMENTS: - implicit none - integer, intent(in) :: class ! elevation class -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! !LOCAL VARIABLES: -!EOP - character(len=32) :: subname = 'mean_elevation_vc' -!----------------------------------------------------------------------- - - if (class < nglcec) then - mean_elevation_vc = 0.5_r8 * (elevclass(class) + elevclass(class+1)) - else if (class == nglcec) then - ! In the top elevation class; in this case, assignment of a "mean" elevation is - ! somewhat arbitrary - - if (nglcec > 1) then - mean_elevation_vc = 2.0_r8*elevclass(class) - elevclass(class-1) - else - ! entirely arbitrary - mean_elevation_vc = 1000._r8 - end if - else - write(6,*) 'ERROR in ', trim(subname), ': class out of bounds= ', class - call abort() - end if - -end function mean_elevation_vc + !=============================================================== + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mkglcmecInit + ! + ! !INTERFACE: + subroutine mkglcmecInit( elevclass_o ) + ! + ! !DESCRIPTION: + ! Initialize of Make glacier multi-elevation class data + ! !USES: + ! + ! !ARGUMENTS: + implicit none + real(r8), intent(OUT) :: elevclass_o(:) ! elevation classes + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: Erik Kluzek + ! + ! + ! !LOCAL VARIABLES: + !EOP + character(len=32) :: subname = 'mkglcmecInit:: ' + !----------------------------------------------------------------------- + allocate( elevclass(nglcec+1) ) + + ! ----------------------------------------------------------------- + ! Define elevation classes, represents lower boundary of each class + ! ----------------------------------------------------------------- + + if ( nglcec == 36 )then + elevclass(:) = (/ 0., 200., 400., 600., 800., & + 1000., 1200., 1400., 1600., 1800., & + 2000., 2200., 2400., 2600., 2800., & + 3000., 3200., 3400., 3600., 3800., & + 4000., 4200., 4400., 4600., 4800., & + 5000., 5200., 5400., 5600., 5800., & + 6000., 6200., 6400., 6600., 6800., & + 7000., 10000./) + else if ( nglcec == 10 )then + elevclass(1) = 0. + elevclass(2) = 200. + elevclass(3) = 400. + elevclass(4) = 700. + elevclass(5) = 1000. + elevclass(6) = 1300. + elevclass(7) = 1600. + elevclass(8) = 2000. + elevclass(9) = 2500. + elevclass(10) = 3000. + elevclass(11) = 10000. + else if ( nglcec == 5 )then + elevclass(1) = 0. + elevclass(2) = 500. + elevclass(3) = 1000. + elevclass(4) = 1500. + elevclass(5) = 2000. + elevclass(6) = 10000. + else if ( nglcec == 3 )then + elevclass(1) = 0. + elevclass(2) = 1000. + elevclass(3) = 2000. + elevclass(4) = 10000. + else if ( nglcec == 1 )then + elevclass(1) = 0. + elevclass(2) = 10000. + else + write(6,*) subname//"ERROR:: nglcec must be 1, 3, 5, 10 or 36",& + " to work with CLM: " + call abort() + end if + + elevclass_o(:) = elevclass(:) + + end subroutine mkglcmecInit + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mkglcmec + ! + ! !INTERFACE: + subroutine mkglcmec(ldomain, mapfname, & + datfname_fglacier, ndiag, & + pctglcmec_o, topoglcmec_o, & + pctglcmec_gic_o, pctglcmec_icesheet_o, & + pctglc_gic_o, pctglc_icesheet_o) + ! + ! !DESCRIPTION: + ! make percent glacier on multiple elevation classes, mean elevation for each + ! elevation class, and associated fields + ! + ! Note that the raw glacier data are specified by level, and thus implicitly include the + ! necessary topo data for breaking pct glacier into elevation classes. Each level in the + ! input data is assigned to an elevation (given by BIN_CENTERS in the input data). Thus, + ! all of the input glacier in level 1 is treated as being at the same elevation, and + ! likewise for each other level. These elevations are then used in assigning pct_glacier + ! to the appropriate elevation class in the output data, as well as determining the mean + ! topographic height of each elevation class in the output data. + ! + ! Note that the various percentages computed here are given as % of the glc_mec landunit. + ! If the input glacier area is 0 for a given grid cell, this requires setting these % + ! variables in an arbitrary way. + ! + ! !USES: + use shr_sys_mod, only : shr_sys_abort + use mkdomainMod, only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkutilsMod, only : slightly_below, slightly_above + use mkncdio + use mkvarctl , only : outnc_3dglc + ! + ! !ARGUMENTS: + implicit none + type(domain_type) , intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname_fglacier ! raw glacier data + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: pctglcmec_o (:,:) ! % for each elevation class on output glacier grid (% of landunit) + real(r8) , intent(out):: topoglcmec_o(:,:) ! mean elevation for each elevation classs on output glacier grid + real(r8), optional, intent(out):: pctglcmec_gic_o(:,:) ! % glc gic on output grid, by elevation class (% of landunit) + real(r8), optional, intent(out):: pctglcmec_icesheet_o(:,:) ! % glc ice sheet on output grid, by elevation class (% of landunit) + real(r8), optional, intent(out):: pctglc_gic_o(:) ! % glc gic on output grid, summed across elevation classes (% of landunit) + real(r8), optional, intent(out):: pctglc_icesheet_o(:) ! % glc ice sheet on output grid, summed across elevation classes (% of landunit) + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: David Lawrence + ! 7/12/11: Bill Sacks: substantial rewrite to use input topo and % glacier at same resolution + ! 9/25/12: Bill Sacks: substantial rewrite to use new format of fglacier, which provides + ! percent by elevation bin (thus the separate topo dataset is no longer needed + ! in this routine) + ! + ! + ! !LOCAL VARIABLES: + !EOP + type(domain_type) :: tdomain ! local domain + type(gridmap_type) :: tgridmap ! local gridmap + real(r8), allocatable :: pctglc_gic_i(:) ! input GIC percentage for a single level + real(r8), allocatable :: pctglc_icesheet_i(:) ! input icesheet percentage for a single level + real(r8), allocatable :: topoglcmec_unnorm_o(:,:) ! same as topoglcmec_o, but unnormalized + real(r8), allocatable :: pctglc_tot_o(:) ! total glacier cover for the grid cell + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8) :: topoice_i ! topographic height of this level + real(r8) :: pctglc_i ! input total pct glacier for a single level & single point + real(r8) :: wt, frac ! weighting factors for remapping + integer :: ndims ! number of dimensions in input variables + integer :: dim_lengths(nf_max_var_dims) ! lengths of dimensions in input variables + integer, allocatable :: starts(:), counts(:) ! start indices & counts for reading variable slices + integer :: ni,no,ns_o,nst,lev ! indices + integer :: n,m ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: nlev ! number of levels in input file + real(r8) :: glc_sum ! temporary + integer :: ier ! error status + logical :: errors ! error status + + real(r8), parameter :: eps = 2.e-5_r8 ! epsilon for error checks (note that we use a large-ish value + ! because data are stored as single-precision floats in the + ! raw dataset) + real(r8), parameter :: eps_small = 1.e-12_r8 ! epsilon for error checks that expect close match + character(len=32) :: subname = 'mkglcmec' + !----------------------------------------------------------------------- + + ! Initialize all output fields to zero + + pctglcmec_o(:,:) = 0. + topoglcmec_o(:,:) = 0. + if ( outnc_3dglc )then + if ( (.not. present(pctglcmec_gic_o)) .or. (.not. present(pctglcmec_icesheet_o)) .or. & + (.not. present(pctglc_gic_o) ) .or. (.not. present(pctglc_icesheet_o) ) )then + call shr_sys_abort( subname//' ERROR: 3D glacier fields were NOT sent in and they are required' ) + end if + pctglcmec_gic_o(:,:) = 0. + pctglcmec_icesheet_o(:,:) = 0. + pctglc_gic_o(:) = 0. + pctglc_icesheet_o(:) = 0. + end if + + ! Set number of output points + + ns_o = ldomain%ns + + write (6,*) 'Attempting to make percent elevation class ',& + 'and mean elevation for glaciers .....' + + ! ----------------------------------------------------------------- + ! Read domain and dimension information from glacier raw data file + ! ----------------------------------------------------------------- + + call domain_read(tdomain,datfname_fglacier) + nst = tdomain%ns + + ! Read z dimension size + write (6,*) 'Open glacier file: ', trim(datfname_fglacier) + call check_ret(nf_open(datfname_fglacier, 0, ncid), subname) + ier = nf_inq_dimid (ncid, 'z', dimid) + if (ier /= NF_NOERR) then + write (6,*) trim(subname), ' ERROR: z dimension not found on glacier file:' + write (6,*) trim(datfname_fglacier) + write (6,*) 'Perhaps you are trying to use an old-format glacier file?' + write (6,*) '(prior to Sept., 2012)' + call abort() + end if + call check_ret(nf_inq_dimlen (ncid, dimid, nlev), subname) + + ! ----------------------------------------------------------------- + ! Read mapping data, check for consistency with domains + ! ----------------------------------------------------------------- + + ! Mapping for raw glacier -> model output grid + call gridmap_mapread(tgridmap, mapfname ) + + ! Error checks for domain and map consistencies + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! ----------------------------------------------------------------- + ! Determine dimension lengths and create start & count arrays + ! for later reading one level at a time + ! ----------------------------------------------------------------- + + call get_dim_lengths(ncid, 'PCT_GLC_GIC', ndims, dim_lengths) + + allocate(starts(ndims), counts(ndims), stat=ier) + if (ier/=0) call abort() + + starts(1:ndims) = 1 + + ! We assume that the last dimension is the level dimension + counts(1:ndims-1) = dim_lengths(1:ndims-1) + counts(ndims) = 1 + + ! -------------------------------------------------------------------- + ! Compute fields on the output grid + ! -------------------------------------------------------------------- + + allocate(pctglc_gic_i(nst), pctglc_icesheet_i(nst), stat=ier) + if (ier/=0) call abort() + + allocate(topoglcmec_unnorm_o(ns_o,nglcec), stat=ier) + if (ier/=0) call abort() + + allocate(frac_dst(ns_o), stat=ier) + if (ier/=0) call abort() + + topoglcmec_unnorm_o(:,:) = 0. + + write(6,'(a,i4,a)',advance='no') 'Level (out of ', nlev, '): ' + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + do lev = 1, nlev + write(6,'(i4)',advance='no') lev + + ! Read this level's data + ! We assume that the last dimension is the level dimension + starts(ndims) = lev + call check_ret(nf_inq_varid (ncid, 'BIN_CENTERS', varid), subname) + call check_ret(nf_get_vara_double (ncid, varid, (/lev/), (/1/), topoice_i), subname) + call check_ret(nf_inq_varid (ncid, 'PCT_GLC_GIC', varid), subname) + call check_ret(nf_get_vara_double (ncid, varid, starts, counts, pctglc_gic_i), subname) + call check_ret(nf_inq_varid (ncid, 'PCT_GLC_ICESHEET', varid), subname) + call check_ret(nf_get_vara_double (ncid, varid, starts, counts, pctglc_icesheet_i), subname) + + ! Determine elevation class + m = get_elevclass(topoice_i) + if (m < 1 .or. m > nglcec) then + call abort() + end if + + do n = 1,tgridmap%ns + ni = tgridmap%src_indx(n) + no = tgridmap%dst_indx(n) + wt = tgridmap%wovr(n) * tdomain%mask(ni) + + ! fraction of this destination cell that is covered by source cells that are within the source landmask + frac = frac_dst(no) + + ! If frac == 0, then we can't do this, to avoid divide by 0. In this case, the + ! outputs remain equal to 0 (their initialized value). + if (frac > 0) then + pctglc_i = pctglc_gic_i(ni) + pctglc_icesheet_i(ni) + pctglcmec_o(no,m) = pctglcmec_o(no,m) + wt*pctglc_i / frac + if ( outnc_3dglc )then + pctglcmec_gic_o(no,m) = pctglcmec_gic_o(no,m) + wt*pctglc_gic_i(ni) / frac + pctglcmec_icesheet_o(no,m) = pctglcmec_icesheet_o(no,m) + wt*pctglc_icesheet_i(ni) / frac + end if + + ! note that, by weighting the following by pctglc_i, we are getting something + ! like the average topographic height over glaciated areas - NOT the average + ! topographic height of the entire grid cell + topoglcmec_unnorm_o(no,m) = topoglcmec_unnorm_o(no,m) + wt*pctglc_i*topoice_i / frac + end if + end do + end do + + ! Note: at this point, the various percentages are given as % of grid cell; below, we + ! renormalize these to be given as % of landunit. + + ! advance to next line (needed because of 'advance=no' writes above) + write(6,*) ' ' + + ! Close glacier input file + call check_ret(nf_close(ncid), subname) + + ! Normalize topoglcmec_o. To do this, note that pctglcmec_o(n,m) is equal to the sum of + ! the weights used in doing the weighted average of topoice_i (weight = + ! wt*pctglc_i/frac); hence pctglcmec_o(n,m) is the correct normalization factor + do no = 1,ns_o + do m = 1,nglcec + if (pctglcmec_o(no,m) > 0) then + topoglcmec_o(no,m) = topoglcmec_unnorm_o(no,m) / pctglcmec_o(no,m) + else + topoglcmec_o(no,m) = mean_elevation_vc(m) + end if + + ! Correct for rounding errors that put topoglcmec_o(no,m) slightly outside the + ! allowed bounds for this elevation class + if (slightly_below(topoglcmec_o(no,m), elevclass(m))) then + write(6,*) 'Warning: topoglcmec_o was slightly lower than lower bound; setting equal& + & to lower bound; for: ', no, m, topoglcmec_o(no,m), elevclass(m) + write(6,*) '(this is informational only, and probably just indicates rounding error)' + topoglcmec_o(no,m) = elevclass(m) + else if (slightly_above(topoglcmec_o(no,m), elevclass(m+1))) then + write(6,*) 'Warning: topoglcmec_o was slightly higher than upper bound; setting equal& + & to upper bound; for: ', no, m, topoglcmec_o(no,m), elevclass(m+1) + write(6,*) '(this is informational only, and probably just indicates rounding error)' + topoglcmec_o(no,m) = elevclass(m+1) + end if + end do + end do + + ! Renormalize percentages to be given as % of landunit rather than % of grid cell. + + allocate(pctglc_tot_o(ns_o), stat=ier) + if (ier/=0) call abort() + + do no = 1,ns_o + pctglc_tot_o(no) = sum(pctglcmec_o(no,:)) + + if (pctglc_tot_o(no) > 0._r8) then + pctglcmec_o(no,:) = pctglcmec_o(no,:) / pctglc_tot_o(no) * 100._r8 + if ( outnc_3dglc )then + pctglcmec_gic_o(no,:) = pctglcmec_gic_o(no,:) / pctglc_tot_o(no) * 100._r8 + pctglcmec_icesheet_o(no,:) = pctglcmec_icesheet_o(no,:) / pctglc_tot_o(no) * 100._r8 + end if + + else + ! Division of landunit is ambiguous. Apply the rule that all area is assigned to + ! the lowest elevation class, and all GIC. + pctglcmec_o(no,1) = 100._r8 + if ( outnc_3dglc )then + pctglcmec_gic_o(no,1) = 100._r8 + end if + end if + end do + + ! Set pctglc_gic_o to sum of pctglcmec_gic_o across elevation classes, and similarly for pctglc_icesheet_o + if ( outnc_3dglc )then + pctglc_gic_o = sum(pctglcmec_gic_o, dim=2) + pctglc_icesheet_o = sum(pctglcmec_icesheet_o, dim=2) + end if + + ! -------------------------------------------------------------------- + ! Perform various sanity checks + ! -------------------------------------------------------------------- + + errors = .false. + + ! Confirm that the sum over pctglcmec_o (from 1 to nglcec) is 100% + do no = 1,ns_o + glc_sum = sum(pctglcmec_o(no,:)) + if (abs(glc_sum - 100._r8) > eps_small) then + write(6,*)'glc_sum differs from 100% at no,pctglc= ',no,glc_sum + errors = .true. + end if + end do + + ! Confirm that GIC + ICESHEET = 100% + if ( outnc_3dglc )then + do no = 1,ns_o + if (abs((pctglc_gic_o(no) + pctglc_icesheet_o(no)) - 100._r8) > eps) then + write(6,*)'GIC + ICESHEET differs from 100% at no,pctglc_gic,pctglc_icesheet,lon,lat=', & + no,pctglc_gic_o(no),pctglc_icesheet_o(no),& + tgridmap%xc_dst(no),tgridmap%yc_dst(no) + errors = .true. + end if + end do + + ! Check that GIC + ICESHEET = total glacier at each elevation class + do m = 1, nglcec + do no = 1,ns_o + if (abs((pctglcmec_gic_o(no,m) + pctglcmec_icesheet_o(no,m)) - & + pctglcmec_o(no,m)) > eps) then + write(6,*)'GIC + ICESHEET differs from total GLC ' + write(6,*)'at no,m,pctglcmec,pctglcmec_gic,pctglcmec_icesheet = ' + write(6,*) no,m,pctglcmec_o(no,m),pctglcmec_gic_o(no,m),pctglcmec_icesheet_o(no,m) + errors = .true. + end if + end do + end do + end if + + + ! Error check: are all elevations within elevation class range + do no = 1,ns_o + do m = 1,nglcec + if (topoglcmec_o(no,m) < elevclass(m) .or. topoglcmec_o(no,m) > elevclass(m+1)) then + write(6,*) 'Error: mean elevation does not fall within elevation class ' + write(6,*) elevclass(m),elevclass(m+1),topoglcmec_o(no,m),m,no + errors = .true. + endif + end do + end do + + if (errors) then + call abort() + end if + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate(pctglc_gic_i, pctglc_icesheet_i) + deallocate(topoglcmec_unnorm_o) + deallocate(pctglc_tot_o) + deallocate(frac_dst) + deallocate(starts, counts) + + write (6,*) 'Successfully made percent elevation class and mean elevation for glaciers' + write (6,*) + + end subroutine mkglcmec + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mkglacier + ! + ! !INTERFACE: + subroutine mkglacier(ldomain, mapfname, datfname, ndiag, zero_out, glac_o) + ! + ! !DESCRIPTION: + ! make percent glacier + ! + ! In contrast to mkglcmec, this uses a "flat" PCT_GLACIER field (not separated by + ! elevation class, and not separated into icesheet vs GIC). + ! + ! This simpler routine is sufficient for cases when we run without multiple elevation + ! classes. This routine is also used when running with multiple elevation classes: we + ! first regrid the flat PCT_GLACIER field, then later create the multiple elevation class + ! data. This multi-step process makes it easier to do corrections on the total + ! PCT_GLACIER, and make sure these corrections apply appropriately to the multi-level + ! output. The assumption is that PCT_GLACIER is the sum of both PCT_GLC_GIC and + ! PCT_GLC_ICESHEET across all elevation bins. + ! + ! !USES: + use mkdomainMod , only : domain_type, domain_clean, domain_read + use mkgridmapMod + use mkvarpar + use mkvarctl + use mkncdio + ! + ! !ARGUMENTS: + implicit none + type(domain_type), intent(in) :: ldomain + character(len=*) , intent(in) :: mapfname ! input mapping file name + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + logical , intent(in) :: zero_out ! if should zero glacier out + real(r8) , intent(out):: glac_o(:) ! output grid: %glacier + ! + ! !CALLED FROM: + ! subroutine mksrfdat in module mksrfdatMod + ! + ! !REVISION HISTORY: + ! Author: Mariana Vertenstein + ! + ! + ! !LOCAL VARIABLES: + !EOP + type(gridmap_type) :: tgridmap + type(domain_type) :: tdomain ! local domain + real(r8), allocatable :: glac_i(:) ! input grid: percent glac + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: gglac_i ! input grid: global glac + real(r8) :: garea_i ! input grid: global area + real(r8) :: gglac_o ! output grid: global glac + real(r8) :: garea_o ! output grid: global area + integer :: ni,no,k,n,m,ns, ns_o ! indices + integer :: ncid,dimid,varid ! input netCDF id's + integer :: ier ! error status + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + character(len=32) :: subname = 'mkglacier' + !----------------------------------------------------------------------- + + write (6,*) 'Attempting to make %glacier .....' + + ! ----------------------------------------------------------------- + ! Read input file + ! ----------------------------------------------------------------- + + ! Obtain input grid info, read local fields + + call domain_read(tdomain,datfname) + ns = tdomain%ns + ns_o = ldomain%ns + allocate(glac_i(ns), & + frac_dst(ns_o), & + stat=ier) + if (ier/=0) call abort() + + write (6,*) 'Open glacier file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + call check_ret(nf_inq_varid (ncid, 'PCT_GLACIER', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, glac_i), subname) + call check_ret(nf_close(ncid), subname) + + ! Area-average percent cover on input grid to output grid + ! and correct according to land landmask + ! Note that percent cover is in terms of total grid area. + + if ( zero_out )then + + do no = 1, ns_o + glac_o(no) = 0. + enddo + + else + + call gridmap_mapread(tgridmap, mapfname ) + + ! Error checks for domain and map consistencies + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! Obtain frac_dst + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + ! Determine glac_o on output grid + + call gridmap_areaave_srcmask(tgridmap, glac_i, glac_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + do no = 1, ns_o + if (glac_o(no) < 1.) glac_o(no) = 0. + enddo + end if + + ! Check for conservation + + do no = 1, ns_o + if ((glac_o(no)) > 100.000001_r8) then + write (6,*) 'MKGLACIER error: glacier = ',glac_o(no), & + ' greater than 100.000001 for column, row = ',no + call abort() + end if + enddo + + ! Some error checking and writing of global values before and after the regrid + + if ( .not. zero_out )then + + ! Global sum of output field -- must multiply by fraction of + ! output grid that is land as determined by input grid + + allocate(mask_r8(ns), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + ! ----------------------------------------------------------------- + ! Error check2 + ! Compare global areas on input and output grids + ! ----------------------------------------------------------------- + + ! Input grid + + gglac_i = 0. + garea_i = 0. + do ni = 1, ns + garea_i = garea_i + tgridmap%area_src(ni)*re**2 + gglac_i = gglac_i + glac_i(ni)*(tgridmap%area_src(ni)/100.)*& + tdomain%mask(ni)*re**2 + end do + + ! Output grid + + gglac_o = 0. + garea_o = 0. + do no = 1, ns_o + garea_o = garea_o + tgridmap%area_dst(no)*re**2 + gglac_o = gglac_o + glac_o(no)*(tgridmap%area_dst(no)/100.)*& + frac_dst(no)*re**2 + end do + + ! Diagnostic output + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'Glacier Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,2001) +2001 format (1x,'surface type input grid area output grid area'/ & + 1x,' 10**6 km**2 10**6 km**2 ') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + write (ndiag,2002) gglac_i*1.e-06,gglac_o*1.e-06 + write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 +2002 format (1x,'glaciers ',f14.3,f17.3) +2004 format (1x,'all surface ',f14.3,f17.3) + + end if + + ! Deallocate dynamic memory + + call domain_clean(tdomain) + if ( .not. zero_out )then + call gridmap_clean(tgridmap) + deallocate (glac_i, frac_dst, mask_r8) + end if + + write (6,*) 'Successfully made %glacier' + write (6,*) + + end subroutine mkglacier + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: get_elevclass + ! + ! !INTERFACE: + integer function get_elevclass(topo, writewarn) + ! + ! !DESCRIPTION: + ! Returns elevation class index (1..nglcec) given the topographic height. + ! If topo is lower than the lowest elevation class, returns 0. + ! If topo is higher than the highest elevation class, returns (nglcec+1). + ! In either of the two latter cases, the function also writes a warning message, unless + ! writewarn is present and false. + ! + ! !ARGUMENTS: + implicit none + real(r8), intent(in) :: topo ! topographic height (m) + logical, intent(in), optional :: writewarn ! should warning messages be written? (default: true) + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! + ! !LOCAL VARIABLES: + !EOP + integer :: m + logical :: my_writewarn + character(len=32) :: subname = 'get_elevclass' + !----------------------------------------------------------------------- + + if (present(writewarn)) then + my_writewarn = writewarn + else + my_writewarn = .true. + end if + + if (topo < elevclass(1)) then + if (my_writewarn) then + write(6,*) 'WARNING in ', trim(subname) + write(6,*) 'topo out of bounds' + write(6,*) 'topo = ', topo + write(6,*) 'elevclass(1) = ', elevclass(1) + end if + get_elevclass = 0 + return + end if + + do m = 1, nglcec + if (topo < elevclass(m+1)) then + ! note that we already know that topo >= elevclass(m), otherwise we would have + ! returned earlier + get_elevclass = m + return + end if + end do + + if (my_writewarn) then + write(6,*) 'WARNING in ', trim(subname) + write(6,*) 'topo out of bounds' + write(6,*) 'topo = ', topo + write(6,*) 'elevclass(nglcec+1) = ', elevclass(nglcec+1) + end if + get_elevclass = nglcec+1 + + end function get_elevclass + + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: mean_elevation_vc + ! + ! !INTERFACE: + real(r8) function mean_elevation_vc(class) + ! + ! !DESCRIPTION: + ! For a virtual column (thus, a column that has no true elevation data), return the + ! "mean" elevation of the given elevation class. + ! + ! !ARGUMENTS: + implicit none + integer, intent(in) :: class ! elevation class + ! + ! !REVISION HISTORY: + ! Author: Bill Sacks + ! + ! !LOCAL VARIABLES: + !EOP + character(len=32) :: subname = 'mean_elevation_vc' + !----------------------------------------------------------------------- + + if (class < nglcec) then + mean_elevation_vc = 0.5_r8 * (elevclass(class) + elevclass(class+1)) + else if (class == nglcec) then + ! In the top elevation class; in this case, assignment of a "mean" elevation is + ! somewhat arbitrary + + if (nglcec > 1) then + mean_elevation_vc = 2.0_r8*elevclass(class) - elevclass(class-1) + else + ! entirely arbitrary + mean_elevation_vc = 1000._r8 + end if + else + write(6,*) 'ERROR in ', trim(subname), ': class out of bounds= ', class + call abort() + end if + + end function mean_elevation_vc end module mkglcmecMod diff --git a/tools/mksurfdata_esmf/src/mklaiMod.F90 b/tools/mksurfdata_esmf/src/mklaiMod.F90 index 6e544c66f7..3625bf78bd 100644 --- a/tools/mksurfdata_esmf/src/mklaiMod.F90 +++ b/tools/mksurfdata_esmf/src/mklaiMod.F90 @@ -1,261 +1,241 @@ module mklaiMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mklai -! -! !DESCRIPTION: -! Make LAI/SAI/height data -! -! !REVISION HISTORY: -! Author: Sam Levis -! -!EOP -!----------------------------------------------------------------------- - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkdomainMod , only : domain_checksame - use mkvarctl - implicit none + !----------------------------------------------------------------------- + ! Make LAI/SAI/height data + !----------------------------------------------------------------------- + + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkutilsMod , only : chkerr + use mkvarctl + + implicit none private public :: mklai private :: pft_laicheck +!================================================================================= contains +!================================================================================= -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mklai -! -! !INTERFACE: subroutine mklai(ldomain, mapfname, datfname, ndiag, ncido) ! - ! !DESCRIPTION: ! Make LAI/SAI/height data ! Portions of this code could be moved out of the month loop ! for improved efficiency ! - ! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar , only : re - use mkvarctl - use mkncdio + use mkvarpar, only : re use mkpftConstantsMod, only : c3cropindex, c3irrcropindex ! - ! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - integer , intent(in) :: ncido ! output netcdf file id - ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: Mariana Vertenstein + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + integer , intent(out) :: glacier_region_o(:) ! glacier region + integer , intent(out) :: rc ! - ! - ! !LOCAL VARIABLES: - !EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - integer :: numpft_i ! number of plant types on input - real(r8) :: glai_o(0:numpft) ! output grid: global area pfts - real(r8) :: gsai_o(0:numpft) ! output grid: global area pfts - real(r8) :: ghgtt_o(0:numpft) ! output grid: global area pfts - real(r8) :: ghgtb_o(0:numpft) ! output grid: global area pfts - real(r8) :: glai_i(0:numpft) ! input grid: global area pfts - real(r8) :: gsai_i(0:numpft) ! input grid: global area pfts - real(r8) :: ghgtt_i(0:numpft) ! input grid: global area pfts - real(r8) :: ghgtb_i(0:numpft) ! input grid: global area pfts - - real(r8), allocatable :: mlai_o(:,:) ! monthly lai - real(r8), allocatable :: msai_o(:,:) ! monthly sai - real(r8), allocatable :: mhgtt_o(:,:) ! monthly height (top) - real(r8), allocatable :: mhgtb_o(:,:) ! monthly height (bottom) - real(r8), allocatable :: mlai_max(:,:) ! monthly lai - real(r8), allocatable :: msai_max(:,:) ! monthly sai - real(r8), allocatable :: mhgtt_max(:,:) ! monthly height (top) - real(r8), allocatable :: mhgtb_max(:,:) ! monthly height (bottom) - real(r8), allocatable :: mlai_i(:,:) ! monthly lai in - real(r8), allocatable :: msai_i(:,:) ! monthly sai in - real(r8), allocatable :: mhgtt_i(:,:) ! monthly height (top) in - real(r8), allocatable :: mhgtb_i(:,:) ! monthly height (bottom) in - real(r8), allocatable :: frac_dst(:) ! output fractions: same as frac_dst - integer, pointer :: laimask(:,:) ! lai+sai output mask for each plant function type - real(r8) :: garea_i ! input grid: global area - real(r8) :: garea_o ! output grid: global area - integer :: mwts ! number of weights - integer :: ni,no,ns_i,ns_o ! indices - integer :: k,l,n,m ! indices - integer :: ncidi,dimid,varid ! input netCDF id's - integer :: ndimsi,ndimso ! netCDF dimension sizes - integer :: dimids(4) ! netCDF dimension ids - integer :: bego(4),leno(4) ! netCDF bounds - integer :: begi(4),leni(4) ! netCDF bounds - integer :: ntim ! number of input time samples - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=256) :: name ! name of attribute - character(len=256) :: unit ! units of attribute + ! local variables + integer :: numpft_i ! number of plant types on input + type(ESMF_RouteHandle) :: routehandle ! nearest neighbor routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + integer :: ni,no,l + integer :: ns_i, ns_o + integer , allocatable :: mask_i(:) + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: data_i(:,:) + real(r8), allocatable :: data_o(:,:) + real(r8), allocatable :: mlai_o(:,:) ! monthly lai + real(r8), allocatable :: msai_o(:,:) ! monthly sai + real(r8), allocatable :: mhgtt_o(:,:) ! monthly height (top) + real(r8), allocatable :: mhgtb_o(:,:) ! monthly height (bottom) + real(r8), allocatable :: mlai_max(:,:) ! monthly lai + real(r8), allocatable :: msai_max(:,:) ! monthly sai + real(r8), allocatable :: mhgtt_max(:,:) ! monthly height (top) + real(r8), allocatable :: mhgtb_max(:,:) ! monthly height (bottom) + real(r8), allocatable :: mlai_i(:,:) ! monthly lai in + real(r8), allocatable :: msai_i(:,:) ! monthly sai in + real(r8), allocatable :: mhgtt_i(:,:) ! monthly height (top) in + real(r8), allocatable :: mhgtb_i(:,:) ! monthly height (bottom) in + real(r8), allocatable :: frac_dst(:) ! output fractions: same as frac_dst + integer, allocatable :: laimask(:,:) ! lai+sai output mask for each plant function type + real(r8) :: glai_o(0:numpft) ! output grid: global area pfts + real(r8) :: gsai_o(0:numpft) ! output grid: global area pfts + real(r8) :: ghgtt_o(0:numpft) ! output grid: global area pfts + real(r8) :: ghgtb_o(0:numpft) ! output grid: global area pfts + real(r8) :: glai_i(0:numpft) ! input grid: global area pfts + real(r8) :: gsai_i(0:numpft) ! input grid: global area pfts + real(r8) :: ghgtt_i(0:numpft) ! input grid: global area pfts + real(r8) :: ghgtb_i(0:numpft) ! input grid: global area pfts + real(r8) :: garea_i ! input grid: global area + real(r8) :: garea_o ! output grid: global area + integer :: mwts ! number of weights + integer :: ni,no,ns_i,ns_o ! indices + integer :: k,l,n,m ! indices + integer :: dimids(4) ! netCDF dimension ids + integer :: bego(4),leno(4) ! netCDF bounds + integer :: begi(4),leni(4) ! netCDF bounds + integer :: ntim ! number of input time samples + integer :: ier ! error status + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + character(len=256) :: name ! name of attribute + character(len=256) :: unit ! units of attribute character(len= 32) :: subname = 'mklai' !----------------------------------------------------------------------- - write (6,*) 'Attempting to make LAIs/SAIs/heights .....' + rc = ESMF_SUCCESS - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- + if (root_task) then + write(ndiag,*) + write (ndiag,'(a)') 'Attempting to make LAIs/SAIs/heights .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + end if - ! Obtain input grid info, read local fields - ns_o = ldomain%ns + ! Open input data file + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) + + ! Read in input mesh + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Determine ns_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the landmask from the input data file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (frac_i(ni) > 0._r8) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - call domain_read(tdomain,datfname) - ns_i = tdomain%ns + ! Create a route handle between the input and output mesh + allocate(frac_o(ns_o)) + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - write (6,*) 'Open LAI file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncidi), subname) - call check_ret(nf_inq_dimid(ncidi, 'pft', dimid), subname) - call check_ret(nf_inq_dimlen(ncidi, dimid, numpft_i), subname) - call check_ret(nf_inq_dimid(ncidi, 'time', dimid), subname) - call check_ret(nf_inq_dimlen(ncidi, dimid, ntim), subname) + rcode = pio_inq_dimid(pioid 'pft', dimid) + rcode = pio_inq_dimlen(pioid, dimid, numpft_i) + rcode = pio_inq_dimid(pioid, 'time', dimid) + rcode = pio_inq_dimlen(pioid, dimid, ntim) if (numpft_i /= numpft+1) then write(6,*) 'WARNING: ' // trim(subname) // '(): parameter numpft+1 = ', numpft+1, & 'does not equal input dataset numpft = ', numpft_i write(6,*)'This inconsistency used to stop the program. Now we allow it ' write(6,*)'because crop pfts 17-last are assumed to never use satellite lai data.' - ! stop if (numpft_i > numpft + 1) then ! NOTE(bja, 2015-01) If this error check is determined to be ! invalid, all the loop bounds over output data in this ! routine will need to be double checked! write(6, *) "ERROR:" // trim(subname) // "(): input numpft must be less than or equal to output numpft+1." - call abort() + call shr_sys_abort() end if endif if (ntim /= 12) then write(6,*)'MKLAI: must have 12 time samples on input data' - call abort() + call shr_sys_abort() endif - ! NOTE - close data set at bottom of routine - - ! Dynamic allocation of variables - + ! Dynamic allocation of variables of size 0:numpft_i allocate(mlai_i(ns_i,0:numpft_i), & - msai_i(ns_i,0:numpft_i), & - mhgtt_i(ns_i,0:numpft_i), & - mhgtb_i(ns_i,0:numpft_i), & - frac_dst(ns_o), & - mlai_o(ns_o,0:numpft), & - msai_o(ns_o,0:numpft), & - mhgtt_o(ns_o,0:numpft), & - mhgtb_o(ns_o,0:numpft), & - laimask(ns_i,0:numpft), stat=ier ) + msai_i(ns_i,0:numpft_i), & + mhgtt_i(ns_i,0:numpft_i), & + mhgtb_i(ns_i,0:numpft_i), stat=ier) if (ier /= 0) then - write(6,*)'mklai allocation error'; call abort() + write(6,*)'mklai allocation error'; call shr_sys_abort() end if - ! Determine mapping weights and map - - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Determine number of dimensions in input by querying MONTHLY_LAI - - call check_ret(nf_inq_varid(ncidi, 'MONTHLY_LAI', varid), subname) - call check_ret(nf_inq_vardimid(ncidi, varid, dimids), subname) - call check_ret(nf_inq_varndims(ncidi, varid, ndimsi), subname) - if (ndimsi ==4) then - begi(1) = 1 - begi(2) = 1 - begi(3) = 1 - leni(4) = 1 - call check_ret(nf_inq_dimlen(ncidi, dimids(1), leni(1)), subname) - call check_ret(nf_inq_dimlen(ncidi, dimids(2), leni(2)), subname) - call check_ret(nf_inq_dimlen(ncidi, dimids(3), leni(3)), subname) - else if (ndimsi== 3) then - begi(1) = 1 - begi(2) = 1 - leni(3) = 1 - call check_ret(nf_inq_dimlen(ncidi, dimids(1), leni(1)), subname) - call check_ret(nf_inq_dimlen(ncidi, dimids(2), leni(2)), subname) + ! Dynamic allocation of variables of size 0:numpft + allocate(mlai_o(ns_o,0:numpft), & + msai_o(ns_o,0:numpft), & + mhgtt_o(ns_o,0:numpft), & + mhgtb_o(ns_o,0:numpft), & + laimask(ns_i,0:numpft), stat=ier ) + if (ier /= 0) then + write(6,*)'mklai allocation error'; call shr_sys_abort() end if + allocate(data_i(0:numpft_i,ns_i),stat=ier) + if (ier/=0) call shr_sys_abort() + ! Determine number of dimensions in output by querying MONTHLY_LAI - call check_ret(nf_inq_varid(ncido, 'MONTHLY_LAI', varid), subname) - call check_ret(nf_inq_varndims(ncido, varid, ndimso), subname) - call check_ret(nf_inq_vardimid(ncido, varid, dimids), subname) - if (ndimso ==4) then - bego(1) = 1 - bego(2) = 1 - bego(3) = 1 - leno(4) = 1 - call check_ret(nf_inq_dimlen(ncido, dimids(1), leno(1)), subname) - call check_ret(nf_inq_dimlen(ncido, dimids(2), leno(2)), subname) - call check_ret(nf_inq_dimlen(ncido, dimids(3), leno(3)), subname) - else if (ndimso== 3) then - bego(1) = 1 - bego(2) = 1 - leno(3) = 1 - call check_ret(nf_inq_dimlen(ncido, dimids(1), leno(1)), subname) - call check_ret(nf_inq_dimlen(ncido, dimids(2), leno(2)), subname) - end if ! Loop over months + mlai_o(:,:) = 0. + msai_o(:,:) = 0. + mhgtt_o(:,:) = 0. + mhgtb_o(:,:) = 0. + + do nt = 1, ntim + call mkpio_get_rawdata(pioid, 'MONTHLY_LAI', mesh_i, data_i, nt=nt, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do l = 0,numpft_i-1 + do no = 1,ns_o + mlai_o(no,l) = data_o(l,no) + end do + end do - do m = 1, ntim - - if (ndimsi == 4) begi(4)=m - if (ndimsi == 3) begi(3)=m - - call check_ret(nf_inq_varid (ncidi, 'MONTHLY_LAI', varid), subname) - call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & - mlai_i), subname) - - call check_ret(nf_inq_varid (ncidi, 'MONTHLY_SAI', varid), subname) - call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & - msai_i), subname) - - call check_ret(nf_inq_varid (ncidi, 'MONTHLY_HEIGHT_TOP', varid), subname) - call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & - mhgtt_i), subname) - - call check_ret(nf_inq_varid (ncidi, 'MONTHLY_HEIGHT_BOT', varid), subname) - call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & - mhgtb_i), subname) - - mlai_o(:,:) = 0. - msai_o(:,:) = 0. - mhgtt_o(:,:) = 0. - mhgtb_o(:,:) = 0. - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Loop over pft types to do mapping - do l = 0, numpft_i - 1 - call gridmap_areaave_srcmask(tgridmap, mlai_i(:,l) , mlai_o(:,l) , nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, msai_i(:,l) , msai_o(:,l) , nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, mhgtt_i(:,l), mhgtt_o(:,l), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, mhgtb_i(:,l), mhgtb_o(:,l), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - enddo + call mkpio_get_rawdata(pioid, 'MONTHLY_SAI', mesh_i, data_i, nt=nt, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do l = 0,numpft_i-1 + do no = 1,ns_o + lai_o(no,l) = data_o(l,no) + end do + end do - ! Determine laimask + call mkpio_get_rawdata(pioid, 'MONTHLY_HEIGHT_TOP', mesh_i, data_i, nt=nt, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do l = 0,numpft_i-1 + do no = 1,ns_o + mhgtt_o(no,l) = data_o(l,no) + end do + end do - laimask(:,:) = 0 + call mkpio_get_rawdata(pioid, 'MONTHLY_HEIGHT_BOT', mesh_i, data_i, nt=nt, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do l = 0,numpft_i-1 + do no = 1,ns_o + mhgtb_o(no,l) = data_o(l,no) + end do + end do ! copy LAI, SAI, & heights from the C3 crop (pft15) ! to the irrigated (pft16) whether crop is on or off @@ -264,35 +244,57 @@ subroutine mklai(ldomain, mapfname, datfname, ndiag, ncido) mhgtt_o(:,c3irrcropindex) = mhgtt_o(:,c3cropindex) mhgtb_o(:,c3irrcropindex) = mhgtb_o(:,c3cropindex) + ! Determine laimask + laimask(:,:) = 0 + ! ----------------------------------------------------------------- ! Output model resolution LAI/SAI/HEIGHT data ! ----------------------------------------------------------------- - ! Now write out all variables + if ( outnc_double ) then + xtype = PIO_DOUBLE + else + xtype = PIO_REAL + end if + + rcode = pio_redef(pioid_o) - if (ndimso == 4) bego(4)=m - if (ndimso == 3) bego(3)=m + call mkpio_def_spatial_var(pioid_o, varname='MONTHLY_LAI', xtype=xtype, & + lev1name='lsmpft', lev2name='time', long_name='monthly leaf area index', units='unitless') - call check_ret(nf_inq_varid(ncido, 'MONTHLY_LAI', varid), subname) - call check_ret(nf_put_vara_double(ncido, varid, bego, leno, mlai_o), subname) + call mkpio_def_spatial_var(pioid_o, varname='MONTHLY_SAI', xtype=xtype, & + lev1name='lsmpft', lev2name='time', long_name='monthly stem area index', units='unitless') - call check_ret(nf_inq_varid(ncido, 'MONTHLY_SAI', varid), subname) - call check_ret(nf_put_vara_double(ncido, varid, bego, leno, msai_o), subname) + call mkpio_def_spatial_var(pioid_o, varname='MONTHLY_HEIGHT_TOP', xtype=xtype, & + lev1name='lsmpft', lev2name='time',long_name='monthly height top', units='meters') - call check_ret(nf_inq_varid(ncido, 'MONTHLY_HEIGHT_TOP', varid), subname) - call check_ret(nf_put_vara_double(ncido, varid, bego, leno, mhgtt_o), subname) + call mkpio_def_spatial_var(pioid_o, varname='MONTHLY_HEIGHT_BOT', xtype=xtype, & + lev1name='lsmpft', lev2name='time', long_name='monthly height bottom', units='meters') - call check_ret(nf_inq_varid(ncido, 'MONTHLY_HEIGHT_BOT', varid), subname) - call check_ret(nf_put_vara_double(ncido, varid, bego, leno, mhgtb_o), subname) + ! End define model + rcode = pio_enddef(pioid_o) - call check_ret(nf_inq_varid(ncido, 'time', varid), subname) - call check_ret(nf_put_vara_int(ncido, varid, bego(ndimso), leno(ndimso), m), subname) + ! Only need to define 1 PIO descriptor here + call mkpio_iodesc_output(pioid_o, mesh_o, 'MONTHLY_LAI', pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for MONTHLY_LAI') - call check_ret(nf_sync(ncido), subname) + rcode = pio_inq_varid(pioid_o, 'MONTHLY_LAI', pio_varid) + call pio_write_darray(pioid_o, pio_varid, pio_iodesc, mlai_o, rcode) + rcode = pio_inq_varid(pioid_o, 'MONTHLY_SAI', pio_varid) + call pio_write_darray(pioid_o, pio_varid, pio_iodesc, msai_o, rcode) + + rcode = pio_inq_varid(pioid_o, 'MONTHLY_HEIGHT_TOP', pio_varid) + call pio_write_darray(pioid_o, pio_varid, pio_iodesc, mhgtt_o, rcode) + + rcode = pio_inq_varid(pioid_o, 'MONTHLY_HEIGHT_BOT', pio_varid) + call pio_write_darray(pioid_o, pio_varid, pio_iodesc, mhgtt_o, rcode) + + ! TODO - output time - write out the wholE time array at once + !rcode = pio_inq_varid(pioid_o, 'time', pio_varid) + !rcode = pio_put_var(pioid_o, pio_varid, bego(ndimso), leno(ndimso), m) ! ----------------------------------------------------------------- - ! Error check2 ! Compare global areas on input and output grids ! ----------------------------------------------------------------- @@ -391,52 +393,46 @@ subroutine mklai(ldomain, mapfname, datfname, ndiag, ncido) end subroutine mklai -!----------------------------------------------------------------------- -!BOP -! -! !INTERFACE: -subroutine pft_laicheck( ni_s, pctpft_i, laimask ) - -! !USES: -! -! !DESCRIPTION: -! -! consistency check that PFT and LAI+SAI make sense -! -! !ARGUMENTS: - implicit none - integer , intent(in) :: ni_s ! input PFT grid resolution - real(r8), pointer :: pctpft_i(:,:) ! % plant function types - integer, pointer :: laimask(:,:) ! mask where LAI+SAI > 0 -!EOP - - character(len=*), parameter :: subName="pft_laicheck" - integer :: ni,l,n,nc ! Indices -!----------------------------------------------------------------------- - - do l = 0, numpft - n = 0 - nc = 0 - do ni = 1,ni_s - if ( pctpft_i(ni,l) > 0.0_r8 ) nc = nc + 1 - if ( (pctpft_i(ni,l) > 0.0_r8) .and. (laimask(ni,l) /= 1) )then - write (6,*) subName//' :: warning: pft and LAI+SAI mask not consistent!' - write (6,*) 'ni,l = ', ni, l - write (6,*) 'pctpft_i = ',pctpft_i(ni,l) - write (6,*) 'laimask = ', laimask(ni,l) - n = n + 1 - end if - end do - if ( n > max(4,nc/4) ) then - write (6,*) subName//' :: pft/LAI+SAI inconsistency over more than 25% land-cover' - write (6,*) '# inconsistent points, total PFT pts, total LAI+SAI pts = ', & - n, nc, sum(laimask(:,l)) - call abort() - end if - end do - -end subroutine pft_laicheck - -!----------------------------------------------------------------------- - + !----------------------------------------------------------------------- + subroutine pft_laicheck( ni_s, pctpft_i, laimask ) + + ! !USES: + ! + ! !DESCRIPTION: + ! + ! consistency check that PFT and LAI+SAI make sense + ! + ! !ARGUMENTS: + integer , intent(in) :: ni_s ! input PFT grid resolution + real(r8), intent(in) :: pctpft_i(:,:) ! % plant function types + integer, intent(in) :: laimask(:,:) ! mask where LAI+SAI > 0 + + ! local variables + character(len=*), parameter :: subName="pft_laicheck" + integer :: ni,l,n,nc ! Indices + !----------------------------------------------------------------------- + + do l = 0, numpft + n = 0 + nc = 0 + do ni = 1,ni_s + if ( pctpft_i(ni,l) > 0.0_r8 ) nc = nc + 1 + if ( (pctpft_i(ni,l) > 0.0_r8) .and. (laimask(ni,l) /= 1) )then + write (6,*) subName//' :: warning: pft and LAI+SAI mask not consistent!' + write (6,*) 'ni,l = ', ni, l + write (6,*) 'pctpft_i = ',pctpft_i(ni,l) + write (6,*) 'laimask = ', laimask(ni,l) + n = n + 1 + end if + end do + if ( n > max(4,nc/4) ) then + write (6,*) subName//' :: pft/LAI+SAI inconsistency over more than 25% land-cover' + write (6,*) '# inconsistent points, total PFT pts, total LAI+SAI pts = ', & + n, nc, sum(laimask(:,l)) + call abort() + end if + end do + + end subroutine pft_laicheck + end module mklaiMod diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index a792d4a53d..37ffc84968 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -159,15 +159,17 @@ subroutine mkpio_get_rawdata1d_real4(pioid, varname, mesh_i, data_i, rc) end subroutine mkpio_get_rawdata1d_real4 !=============================================================== - subroutine mkpio_get_rawdata1d_real8(pioid, varname, mesh_i, data_i, rc) + subroutine mkpio_get_rawdata1d_real8(pioid, varname, mesh_i, data_i, nt, rc) ! input/output variables type(file_desc_t), intent(inout) :: pioid character(len=*) , intent(in) :: varname ! field name in rawdata file type(ESMF_Mesh) , intent(in) :: mesh_i real(r8) , intent(inout) :: data_i(:) ! input raw data + integer, optional, intent(in) :: nt integer , intent(out) :: rc + ! local variables type(var_desc_t) :: pio_varid integer :: pio_vartype @@ -193,6 +195,10 @@ subroutine mkpio_get_rawdata1d_real8(pioid, varname, mesh_i, data_i, rc) call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (present(nt)) then + call pio_setframe(pioid, pio_varid, int(nt,kind=Pio_Offset_Kind)) + end if + ! Read the input raw data call ESMF_VMLogMemInfo("After mkpio_iodesc for varname for "//trim(varname)//" in "//trim(subname)) if (pio_vartype == PIO_INT) then diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index 1ba5b64c73..1d6500f95a 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -31,7 +31,7 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesho - integer , pointer :: soil_color_o(:) ! soil color classes + integer , intent(inout) :: soil_color_o(:) ! soil color classes integer , intent(out) :: nsoilcol ! number of soil colors integer , intent(out) :: rc @@ -140,7 +140,7 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r ! field with gridcells equal to 1 for that soil color and zero elsewhere allocate(data_i(0:nsoilcol,ns_i)) data_i(:,:) = 0._r4 - do l = 1,nsoilcol + do l = 0,nsoilcol do n = 1,ns_i if (int(soil_color_i(n)) == l) then data_i(l,n) = 1._r4 * mask_i(n) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index a83f12b715..a9ca078c8f 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -101,8 +101,6 @@ program mksurfdata use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride - use mkvocefMod , only : mkvocef - use mkglacierregionMod , only : mkglacierregion use mkglcmecMod , only : nglcec, mkglcmec, mkglcmecInit, mkglacier use mkharvestMod , only : mkharvest, mkharvest_init, mkharvest_fieldname use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride @@ -112,15 +110,14 @@ program mksurfdata use mkagfirepkmonthMod , only : mkagfirepkmon use mktopostatsMod , only : mktopostats use mkVICparamsMod , only : mkVICparams - use mkurbanparCommonMod, only : mkurban_topo -#else - use mkurbanparCommonMod + use mkvocefMod , only : mkvocef #endif + use mkglacierregionMod , only : mkglacierregion use mksoiltexMod , only : mksoiltex use mksoilfmaxMod , only : mksoilfmax use mksoildepthMod , only : mksoildepth use mksoilcolMod , only : mksoilcol - use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, numurbl + use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, mkurban_topo, numurbl use mklanwatMod , only : mklakwat use mkOrganicMod , only : mkorganic use mkutilsMod , only : normalize_classes_by_gcell, chkerr @@ -157,66 +154,66 @@ program mksurfdata type(io_desc_t) :: pio_iodesc ! data arrays - real(r8), pointer :: landfrac_pft(:) ! PFT data: % land per gridcell - real(r8), pointer :: pctlnd_pft(:) ! PFT data: % of gridcell for PFTs - real(r8), pointer :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs - integer , pointer :: pftdata_mask(:) ! mask indicating real or fake land type + real(r8), allocatable :: landfrac_pft(:) ! PFT data: % land per gridcell + real(r8), allocatable :: pctlnd_pft(:) ! PFT data: % of gridcell for PFTs + real(r8), allocatable :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs + integer , allocatable :: pftdata_mask(:) ! mask indicating real or fake land type #ifdef TODO - type(pct_pft_type), pointer :: pctnatpft(:) ! % of grid cell that is nat veg, and breakdown into PFTs - type(pct_pft_type), pointer :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series - type(pct_pft_type), pointer :: pctcft(:) ! % of grid cell that is crop, and breakdown into CFTs - type(pct_pft_type), pointer :: pctcft_max(:) ! % of grid cell maximum CFTs of the time series + type(pct_pft_type), allocatable :: pctnatpft(:) ! % of grid cell that is nat veg, and breakdown into PFTs + type(pct_pft_type), allocatable :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series + type(pct_pft_type), allocatable :: pctcft(:) ! % of grid cell that is crop, and breakdown into CFTs + type(pct_pft_type), allocatable :: pctcft_max(:) ! % of grid cell maximum CFTs of the time series #endif - real(r8) :: harvest_initval ! initial value for harvest variables - real(r8), pointer :: harvest1D(:) ! harvest 1D data: normalized harvesting - real(r8), pointer :: harvest2D(:,:) ! harvest 1D data: normalized harvesting - real(r8), pointer :: pctgla(:) ! percent of grid cell that is glacier - real(r8), pointer :: pctglc_gic(:) ! percent of grid cell that is gic (% of glc landunit) - real(r8), pointer :: pctglc_icesheet(:) ! percent of grid cell that is ice sheet (% of glc landunit) - real(r8), pointer :: pctglcmec(:,:) ! glacier_mec pct coverage in each class (% of landunit) - real(r8), pointer :: topoglcmec(:,:) ! glacier_mec sfc elevation in each gridcell and class - real(r8), pointer :: pctglcmec_gic(:,:) ! GIC pct coverage in each class (% of landunit) - real(r8), pointer :: pctglcmec_icesheet(:,:) ! icesheet pct coverage in each class (% of landunit) - real(r8), pointer :: elevclass(:) ! glacier_mec elevation classes - integer, pointer :: glacier_region(:) ! glacier region ID - real(r8), pointer :: pctlak(:) ! percent of grid cell that is lake - real(r8), pointer :: pctwet(:) ! percent of grid cell that is wetland - real(r8), pointer :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) - real(r8), pointer :: urban_classes(:,:) ! percent cover of each urban class, as % of total urban area - real(r8), pointer :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell - integer , pointer :: urban_region(:) ! urban region ID - real(r8), pointer :: elev(:) ! glc elevation (m) - integer , pointer :: soil_color(:) ! soil color - real(r8), pointer :: fmaxsoil(:) ! soil_fractional saturated area - real(r8), pointer :: pctsand(:,:) ! soil texture: percent sand - real(r8), pointer :: pctclay(:,:) ! soil texture: percent clay - integer , pointer :: mapunits(:) ! input grid: igbp soil mapunits - real(r8), pointer :: ef1_btr(:) ! Isoprene emission factor for broadleaf - real(r8), pointer :: ef1_fet(:) ! Isoprene emission factor for fine/everg - real(r8), pointer :: ef1_fdt(:) ! Isoprene emission factor for fine/dec - real(r8), pointer :: ef1_shr(:) ! Isoprene emission factor for shrubs - real(r8), pointer :: ef1_grs(:) ! Isoprene emission factor for grasses - real(r8), pointer :: ef1_crp(:) ! Isoprene emission factor for crops - real(r8), pointer :: organic(:,:) ! organic matter density (kg/m3) - real(r8), pointer :: gdp(:) ! GDP (x1000 1995 US$/capita) - real(r8), pointer :: fpeat(:) ! peatland fraction of gridcell - real(r8), pointer :: soildepth(:) ! soil depth (m) - integer , pointer :: agfirepkmon(:) ! agricultural fire peak month - real(r8), pointer :: topo_stddev(:) ! standard deviation of elevation (m) - real(r8), pointer :: slope(:) ! topographic slope (degrees) - real(r8), pointer :: vic_binfl(:) ! VIC b + real(r8) :: harvest_initval ! initial value for harvest variables + real(r8), allocatable :: harvest1D(:) ! harvest 1D data: normalized harvesting + real(r8), allocatable :: harvest2D(:,:) ! harvest 1D data: normalized harvesting + real(r8), allocatable :: pctgla(:) ! percent of grid cell that is glacier + real(r8), allocatable :: pctglc_gic(:) ! percent of grid cell that is gic (% of glc landunit) + real(r8), allocatable :: pctglc_icesheet(:) ! percent of grid cell that is ice sheet (% of glc landunit) + real(r8), allocatable :: pctglcmec(:,:) ! glacier_mec pct coverage in each class (% of landunit) + real(r8), allocatable :: topoglcmec(:,:) ! glacier_mec sfc elevation in each gridcell and class + real(r8), allocatable :: pctglcmec_gic(:,:) ! GIC pct coverage in each class (% of landunit) + real(r8), allocatable :: pctglcmec_icesheet(:,:) ! icesheet pct coverage in each class (% of landunit) + real(r8), allocatable :: elevclass(:) ! glacier_mec elevation classes + integer, allocatable :: glacier_region(:) ! glacier region ID + real(r8), allocatable :: pctlak(:) ! percent of grid cell that is lake + real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland + real(r8), allocatable :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) + real(r8), allocatable :: urban_classes(:,:) ! percent cover of each urban class, as % of total urban area + real(r8), allocatable :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell + integer , allocatable :: urban_region(:) ! urban region ID + real(r8), allocatable :: elev(:) ! glc elevation (m) + integer , allocatable :: soil_color(:) ! soil color + real(r8), allocatable :: fmaxsoil(:) ! soil_fractional saturated area + real(r8), allocatable :: pctsand(:,:) ! soil texture: percent sand + real(r8), allocatable :: pctclay(:,:) ! soil texture: percent clay + integer , allocatable :: mapunits(:) ! input grid: igbp soil mapunits + real(r8), allocatable :: ef1_btr(:) ! Isoprene emission factor for broadleaf + real(r8), allocatable :: ef1_fet(:) ! Isoprene emission factor for fine/everg + real(r8), allocatable :: ef1_fdt(:) ! Isoprene emission factor for fine/dec + real(r8), allocatable :: ef1_shr(:) ! Isoprene emission factor for shrubs + real(r8), allocatable :: ef1_grs(:) ! Isoprene emission factor for grasses + real(r8), allocatable :: ef1_crp(:) ! Isoprene emission factor for crops + real(r8), allocatable :: organic(:,:) ! organic matter density (kg/m3) + real(r8), allocatable :: gdp(:) ! GDP (x1000 1995 US$/capita) + real(r8), allocatable :: fpeat(:) ! peatland fraction of gridcell + real(r8), allocatable :: soildepth(:) ! soil depth (m) + integer , allocatable :: agfirepkmon(:) ! agricultural fire peak month + real(r8), allocatable :: topo_stddev(:) ! standard deviation of elevation (m) + real(r8), allocatable :: slope(:) ! topographic slope (degrees) + real(r8), allocatable :: vic_binfl(:) ! VIC b ! parameters (unitless) - real(r8), pointer :: vic_ws(:) ! VIC Ws parameter (unitless) - real(r8), pointer :: vic_dsmax(:) ! VIC Dsmax parameter (mm/day) - real(r8), pointer :: vic_ds(:) ! VIC Ds parameter (unitless) - real(r8), pointer :: lakedepth(:) ! lake depth (m) - integer , pointer :: harvind1D(:) ! Indices of 1D harvest fields - integer , pointer :: harvind2D(:) ! Indices of 2D harvest fields - logical :: zero_out_lake ! if should zero glacier out - logical :: zero_out_wetland ! if should zero glacier out + real(r8), allocatable :: vic_ws(:) ! VIC Ws parameter (unitless) + real(r8), allocatable :: vic_dsmax(:) ! VIC Dsmax parameter (mm/day) + real(r8), allocatable :: vic_ds(:) ! VIC Ds parameter (unitless) + real(r8), allocatable :: lakedepth(:) ! lake depth (m) + integer , allocatable :: harvind1D(:) ! Indices of 1D harvest fields + integer , allocatable :: harvind2D(:) ! Indices of 2D harvest fields + logical :: zero_out_lake ! if should zero glacier out + logical :: zero_out_wetland ! if should zero glacier out #ifdef TODO - type(harvestDataType) :: harvdata + type(harvestDataType) :: harvdata #endif ! esmf variables @@ -351,7 +348,6 @@ program mksurfdata ! glacier properties allocate ( pctgla(lsize_o)) ; pctgla(:) = spval - allocate ( glacier_region(lsize_o)) ; glacier_region(:) = -999 #ifdef TODO allocate ( pctglcmec(lsize_o,nglcec)) ; pctglcmec(:,:) = spval allocate ( topoglcmec(lsize_o,nglcec)) ; topoglcmec(:,:) = spval @@ -364,12 +360,6 @@ program mksurfdata allocate ( vic_ds(lsize_o)) ; vic_ds(:) = spval ! voc emission factors - allocate (ef1_btr(lsize_o)) ; ef1_btr(:) = 0._r8 - allocate (ef1_fet(lsize_o)) ; ef1_fet(:) = 0._r8 - allocate (ef1_fdt(lsize_o)) ; ef1_fdt(:) = 0._r8 - allocate (ef1_shr(lsize_o)) ; ef1_shr(:) = 0._r8 - allocate (ef1_grs(lsize_o)) ; ef1_grs(:) = 0._r8 - allocate (ef1_crp(lsize_o)) ; ef1_crp(:) = 0._r8 ! ---------------------------------------------------------------------- ! Read in and interpolate surface data set fields @@ -395,10 +385,56 @@ program mksurfdata ! -------------------------------------------------- ! begin working + ! ! Make VOC emission factors for isoprene [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] + write(6,*)'DEBUG: i am here1' + call flush(6) + allocate (ef1_btr(lsize_o)) ; ef1_btr(:) = 0._r8 + allocate (ef1_fet(lsize_o)) ; ef1_fet(:) = 0._r8 + allocate (ef1_fdt(lsize_o)) ; ef1_fdt(:) = 0._r8 + allocate (ef1_shr(lsize_o)) ; ef1_shr(:) = 0._r8 + allocate (ef1_grs(lsize_o)) ; ef1_grs(:) = 0._r8 + allocate (ef1_crp(lsize_o)) ; ef1_crp(:) = 0._r8 + ! call mkvocef ( mksrf_fvocef, mksrf_fvocef_mesh, mesh_model, & + ! ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & + ! ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkvocef') + write(6,*)'DEBUG: i am here2' + call flush(6) + + ! Make glacier region ID [glacier_region] from [fglacierregion] dataset + allocate (glacier_region(lsize_o)) ; glacier_region(:) = -999 + call mkglacierregion(mksrf_fglacierregion_mesh, mksrf_fglacierregion, mesh_model, glacier_region, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacierregion') + + ! Make urban fraction [pcturb] from [furban] dataset + allocate (pcturb(lsize_o)) ; pcturb(:) = spval + allocate (urban_classes(lsize_o,numurbl)) ; urban_classes(:,:) = spval + allocate (urban_classes_g(lsize_o,numurbl)); urban_classes_g(:,:) = spval + allocate (urban_region(lsize_o)) ; urban_region(:) = -999 + call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, all_veg, pcturb, urban_classes, urban_region, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') + + ! Make elevation [elev] from [ftopo, ffrac] dataset + ! Used only to screen pcturb, screen pcturb by elevation threshold from elev dataset + if ( .not. all_urban .and. .not. all_veg )then + allocate(elev(lsize_o)) + elev(:) = spval + ! NOTE(wjs, 2016-01-15) This uses the 'TOPO_ICE' variable for historical reasons + ! (this same dataset used to be used for glacier-related purposes as well). + ! TODO(wjs, 2016-01-15) A better solution for this urban screening would probably + ! be to modify the raw urban data; in that case, I believe we could remove furbtopo. + call mkurban_topo ( mksrf_furbtopo_mesh, mksrf_furbtopo, mesh_model, varname='TOPO_ICE', elev_o=elev, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban_topo') + where (elev > elev_thresh) + pcturb = 0._r8 + end where + deallocate(elev) + end if + ! Make soil fmax [fmaxsoil] allocate(fmaxsoil(lsize_o)); fmaxsoil(:) = spval call mksoilfmax( mksrf_fmax_mesh, mksrf_fmax, mesh_model, fmaxsoil, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilfmax') ! Make soil texture [pctsand, pctclay] allocate(mapunits(lsize_o)) ; mapunits(:) = 0 @@ -410,15 +446,7 @@ program mksurfdata ! Make soil depth data [soildepth] from [soildepthf] allocate ( soildepth(lsize_o)); soildepth(:) = spval call mksoildepth( mksrf_fsoildepth_mesh, mksrf_fsoildepth, mesh_model, soildepth, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') - - ! Make urban fraction [pcturb] from [furban] dataset - allocate (pcturb(lsize_o)) ; pcturb(:) = spval - allocate (urban_classes(lsize_o,numurbl)) ; urban_classes(:,:) = spval - allocate (urban_classes_g(lsize_o,numurbl)); urban_classes_g(:,:) = spval - allocate (urban_region(lsize_o)) ; urban_region(:) = -999 - call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, all_veg, pcturb, urban_classes, urban_region, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoildepth') ! Make soil color classes [soicol] [fsoicol] allocate (soil_color(lsize_o)); soil_color(:) = -999 @@ -447,10 +475,6 @@ program mksurfdata ! ! Make glacier fraction [pctgla] from [fglacier] dataset ! call mkglacier ( mapfname=map_fglacier, datfname=mksrf_fglacier, ndiag=ndiag, zero_out=all_urban.or.all_veg, glac_o=pctgla) - ! ! Make glacier region ID [glacier_region] from [fglacierregion] dataset - ! call mkglacierregion ( mapfname=map_fglacierregion, & - ! datfname=mksrf_fglacierregion, ndiag=ndiag, glacier_region_o = glacier_region) - ! ! Make GDP data [gdp] from [gdp] ! call mkgdp ( mapfname=map_fgdp, datfname=mksrf_fgdp, ndiag=ndiag, gdp_o=gdp) @@ -460,22 +484,6 @@ program mksurfdata ! ! Make agricultural fire peak month data [abm] from [abm] ! call mkagfirepkmon ( mapfname=map_fabm, datfname=mksrf_fabm, ndiag=ndiag, agfirepkmon_o=agfirepkmon) - ! ! Make elevation [elev] from [ftopo, ffrac] dataset - ! ! Used only to screen pcturb, screen pcturb by elevation threshold from elev dataset - ! if ( .not. all_urban .and. .not. all_veg )then - ! allocate(elev(lsize_o)) - ! elev(:) = spval - ! ! NOTE(wjs, 2016-01-15) This uses the 'TOPO_ICE' variable for historical reasons - ! ! (this same dataset used to be used for glacier-related purposes as well). - ! ! TODO(wjs, 2016-01-15) A better solution for this urban screening would probably - ! ! be to modify the raw urban data; in that case, I believe we could remove furbtopo. - ! call mkurban_topo ( mapfname=map_furbtopo, datfname=mksrf_furbtopo, varname='TOPO_ICE', ndiag=ndiag, elev_o=elev) - ! where (elev .gt. elev_thresh) - ! pcturb = 0._r8 - ! end where - ! deallocate(elev) - ! end if - ! ! Compute topography statistics [topo_stddev, slope] from [ftopostats] ! call mktopostats ( mapfname=map_ftopostats, datfname=mksrf_ftopostats, & ! ndiag=ndiag, topo_stddev_o=topo_stddev, slope_o=slope, std_elev=std_elev) @@ -486,11 +494,6 @@ program mksurfdata ! binfl_o=vic_binfl, ws_o=vic_ws, dsmax_o=vic_dsmax, ds_o=vic_ds) ! end if - ! ! Make VOC emission factors for isoprene [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] - ! call mkvocef ( mapfname=map_fvocef, datfname=mksrf_fvocef, ndiag=ndiag, & - ! ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & - ! ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp) - ! ! Do landuse changes such as for the poles, etc. ! call change_landuse( dynpft=.false. ) @@ -647,13 +650,39 @@ program mksurfdata end if else !call mkfile_fsurdat( mksrf_fgrid_mesh_nx, mksrf_fgrid_mesh_ny, mesh_model, dynlanduse=.false., harvdata) - call ESMF_LogWrite("Calling mkfile_fsurdat", ESMF_LOGMSG_INFO) - call mkfile_fsurdat( mksrf_fgrid_mesh_nx, mksrf_fgrid_mesh_ny, mesh_model, dynlanduse=.false., & - pctlak=pctlak, pctwet=pctwet, lakedepth=lakedepth, organic=organic, & - soil_color=soil_color, nsoilcol=nsoilcol, & - urban_classes_g=urban_classes_g, urban_region=urban_region, & - pctsand=pctsand, pctclay=pctclay, mapunits=mapunits, fmaxsoil=fmaxsoil, soildepth=soildepth) - call ESMF_LogWrite(subname//'successfully created file '//trim(fsurdat), ESMF_LOGMSG_INFO) + if (root_task)then + write(ndiag,'(a)')"Calling mkfile_fsurdat" + end if + call mkfile_fsurdat( nx=mksrf_fgrid_mesh_nx, & + ny=mksrf_fgrid_mesh_ny, & + mesh_o=mesh_model, & + dynlanduse=.false., & + pctlak=pctlak, & + pctwet=pctwet, & + lakedepth=lakedepth, & + organic=organic, & + soil_color=soil_color, & + nsoilcol=nsoilcol, & + urban_classes_g=urban_classes_g, & + urban_region=urban_region, & + pctsand=pctsand, & + pctclay=pctclay, & + mapunits=mapunits, & + fmaxsoil=fmaxsoil, & + soildepth=soildepth, & + glacier_region=glacier_region, & + ef_btr=ef1_btr, & + ef_fet=ef1_fet, & + ef_fdt=ef1_fdt, & + ef_shr=ef1_shr, & + ef_grs=ef1_grs, & + ef_crp=ef1_crp, & + rc = rc) + if (root_task) then + write(ndiag,*) + write(ndiag,'(a)')'successfully created file '//trim(fsurdat) + end if + end if ! if (fsurdat /= ' ') ! Deallocate arrays NOT needed for dynamic-pft section of code @@ -674,7 +703,6 @@ program mksurfdata deallocate ( topo_stddev, slope ) deallocate ( vic_binfl, vic_ws, vic_dsmax, vic_ds ) deallocate ( glacier_region ) - call harvdata%clean() #endif diff --git a/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 deleted file mode 100644 index 930caea8ba..0000000000 --- a/tools/mksurfdata_esmf/src/mkurbanparCommonMod.F90 +++ /dev/null @@ -1,191 +0,0 @@ -module mkurbanparCommonMod - - !----------------------------------------------------------------------- - ! Common routines for making urban parameter data, independent of the method used for - ! making the urban parameters (e.g., averages, dominant type, etc.) - ! - ! (WJS 4-18-12: In the past, this contained routines shared between mkurbanparDomMod and - ! mkurbanparAvgMod; now there is just a single module, mkurbanparMod, but I am keeping the - ! separate mkurbanparCommonMod in case a similar split comes back in the future. However, - ! if such a split seems unlikely in the future, these routines could be moved back into - ! mkurbanparMod.) - !----------------------------------------------------------------------- - - use ESMF - use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs - use shr_sys_mod , only : shr_sys_abort - use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkpioMod , only : mkpio_iodesc_output, mkpio_def_spatial_var, mkpio_wopen - use mkpioMod , only : mkpio_get_dimlengths, mkpio_get_rawdata - use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 - use mkutilsMod , only : chkerr - use mkvarctl , only : ndiag - - implicit none - private - - ! !public member functions: - public :: mkurban_pct_diagnostics ! print diagnostics related to pct urban -#ifdef TODO - public :: mkurban_topo ! Get elevation to reduce urban for high elevation areas -#endif - - ! !public data members: - real(r8), parameter :: MIN_DENS = 0.1_r8 ! minimum urban density (% of grid cell) - below this value, urban % is set to 0 - - public :: MIN_DENS - - character(len=*) , parameter :: u_FILE_u = & - __FILE__ - -!=============================================================== -contains -!=============================================================== - - subroutine mkurban_pct_diagnostics(area_i, area_o, mask_i, frac_o, urbn_i, urbn_o, dens_class) - ! - ! print diagnostics related to pct urban - ! Compare global areas on input and output grids - ! - ! This is intended to be called after mkurban_pct, but is split out into a separate - ! routine so that modifications to urbn_o can be made in between the two calls (e.g., - ! setting urbn_o to 0 wherever it is less than a certain threshold; the rules for doing - ! this can't always be applied inline in mkurban_pct). - ! - use mkvarpar - - ! input/output variables - real(r8) , intent(in) :: area_i(:) - real(r8) , intent(in) :: area_o(:) - integer , intent(in) :: mask_i(:) - real(r8) , intent(in) :: frac_o(:) - real(r8) , intent(in) :: urbn_i(:) ! input grid: percent urban - real(r8) , intent(in) :: urbn_o(:) ! output grid: percent urban - integer , intent(in), optional :: dens_class ! density class - - ! local variables: - real(r8) :: gurbn_i ! input grid: global urbn - real(r8) :: garea_i ! input grid: global area - real(r8) :: gurbn_o ! output grid: global urbn - real(r8) :: garea_o ! output grid: global area - integer :: ni,no,k ! indices - character(len=*), parameter :: subname = 'mkurban_pct_diagnostics' - !----------------------------------------------------------------------- - - ! Input grid - gurbn_i = 0._r8 - garea_i = 0._r8 - do ni = 1, size(area_i) - garea_i = garea_i + area_i(ni)*re**2 - gurbn_i = gurbn_i + urbn_i(ni)*(area_i(ni)/100._r8)* mask_i(ni)*re**2 - end do - - ! Output grid - gurbn_o = 0._r8 - garea_o = 0._r8 - do no = 1, size(area_o) - garea_o = garea_o + area_o(no)*re**2 - gurbn_o = gurbn_o + urbn_o(no)* (area_o(no)/100._r8)*frac_o(no)*re**2 - end do - - ! Diagnostic output - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - if (present(dens_class)) then - write (ndiag,'(1x,a,i0)') 'Urban Output -- class ', dens_class - else - write (ndiag,'(1x,a)') 'Urban Output' - end if - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) -2001 format (1x,'surface type input grid area output grid area'/& - 1x,' 10**6 km**2 10**6 km**2 ') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2003) gurbn_i*1.e-06,gurbn_o*1.e-06 - write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 -2002 format (1x,'urban ',f14.3,f17.3) -2003 format (1x,'urban ',f14.3,f22.8) -2004 format (1x,'all surface ',f14.3,f17.3) - - end subroutine mkurban_pct_diagnostics - -#ifdef TODO - !=============================================================== - subroutine mkurban_topo(mesh_i, mesh_o, file_data_i, varname, elev_o) - ! - ! Make elevation data - ! - use mkdiagnosticsMod, only : output_diagnostics_continuous - ! - ! !ARGUMENTS: - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - character(len=*) , intent(in) :: varname ! topo variable name - real(r8) , intent(out):: elev_o(:) ! output elevation data - - ! !LOCAL VARIABLES: - real(r8), allocatable :: elev_i(:) ! canyon_height to width ratio in - real(r8), allocatable :: frac_o(:) ! output fractions - integer :: ns_i,ns_o ! indices - integer :: k,l,n,m,ni ! indices - integer :: ier ! error status - character(len=CS) :: name ! name of attribute - character(len=CS) :: unit ! units of attribute - character(len=*), parameter :: subname = 'mkelev' - !----------------------------------------------------------------------- - - write (6,*) 'Attempting to make elevation .....' - - ! Query local mesh sizes - call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Read topo elev dataset with unit mask everywhere - write (6,*) 'Open elevation file: ', trim(datfname) - allocate(elev_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) - call mkpio_get_rawdata(pioid, trim(varname), mesh_i, elev_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call pio_closefile(pioid) - - ! Create a route handle between the input and output mesh - allocate(frac_o(ns_o), stat=ier) - if (ier/=0) call shr_sys_abort() - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - - ! Regrid input data to model resolution - determine elev_o on output grid - elev_o(:) = 0. - if (ier/=0) call shr_sys_abort() - call regrid_rawdata(mesh_i, mesh_o, routehandle, elev_i, elev_o, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call output_diagnostics_continuous(elev_i, elev_o, tgridmap, & - "Urban elev variable", "m", ndiag, mask_i, frac_o) - - ! Deallocate dynamic memory - deallocate (elev_i) - deallocate (frac_o) - - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - - if (root_task) then - write (ndiag,'(a)') 'Successfully made elevation' - write (ndiag,'(a)') - end if - - end subroutine mkurban_topo -#endif - -end module mkurbanparCommonMod - diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 53bca82ca3..0c6917fff7 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -16,7 +16,7 @@ module mkurbanparMod use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag, ispval, fsurdat, outnc_double use mkvarctl , only : mpicom, MPI_INTEGER, MPI_MAX - use mkvarpar + use mkvarpar implicit none private @@ -25,6 +25,8 @@ module mkurbanparMod public :: mkurban public :: mkurbanpar public :: normalize_urbn_by_tot + public :: mkurban_topo ! Get elevation to reduce urban for high elevation areas + public :: mkurban_pct_diagnostics ! print diagnostics related to pct urban ! Note: normalize_urbn_by_tot could be private, but because there ! are associated test routines in a separate module, it needs to be public @@ -34,6 +36,8 @@ module mkurbanparMod integer, public :: nlevurb = ispval ! number of urban layers integer, public :: nregions + real(r8), parameter :: MIN_DENS = 0.1_r8 ! minimum urban density (% of grid cell) - below this value, urban % is set to 0 + ! private data members: ! flag to indicate nodata for index variables in output file: integer , parameter :: index_nodata = 0 @@ -100,13 +104,11 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & ! this would also replace the use of normalize_classes_by_gcell, and maybe some other ! urban-specific code. ! - use mkurbanparCommonMod , only : MIN_DENS use mkutilsMod , only : normalize_classes_by_gcell use mkvarctl , only : all_urban use mkvarpar #ifdef TODO - use mkurbanparCommonMod , only : mkurban_pct_diagnostics - use mkdiagnosticsMod , only : output_diagnostics_index + !use mkdiagnosticsMod , only : output_diagnostics_index #endif ! input/output variables @@ -114,8 +116,8 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh logical , intent(in) :: zero_out ! if should zero urban out - real(r8) , intent(out) :: pcturb_o(:) ! output grid: total % urban - real(r8) , intent(out) :: urban_classes_o(:,:) ! output grid: breakdown of total urban into each class + real(r8) , intent(inout) :: pcturb_o(:) ! output grid: total % urban + real(r8) , intent(inout) :: urban_classes_o(:,:) ! output grid: breakdown of total urban into each class integer , intent(inout) :: region_o(:) ! output grid: region ID integer , intent(out) :: rc @@ -123,7 +125,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid - integer , allocatable :: mask_i(:) + integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) real(r8), allocatable :: data_i(:,:) @@ -132,7 +134,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & integer , allocatable :: region_i(:) ! input grid: region ID integer :: ni,no ! indices integer :: ns_i, ns_o ! array sizes - integer :: n,k,l ! indices + integer :: n,k,l ! indices integer :: max_regions ! maximum region index integer :: max_index(1) integer :: rcode, ier ! error status @@ -142,8 +144,9 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & rc = ESMF_SUCCESS if (root_task) then - write (ndiag,'(a)') 'Attempting to make %urban .....' - write (ndiag,'(a)') 'Opening urban file: '//trim(file_data_i) + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make %urban .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) end if ! Open input data file @@ -206,7 +209,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & call ESMF_VMLogMemInfo("After regrid_data for in "//trim(subname)) ! Now Determine total % urban - ! urbn_classes_gcell_o is % urban of total grid cell area for each density class + ! urbn_classes_gcell_o is % urban of total grid cell area for each density class allocate(urban_classes_gcell_o(ns_o, numurbl), stat=ier) if (ier/=0) call shr_sys_abort() do l = 1,numurbl @@ -235,7 +238,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & ! Handle special cases ! Note that, for all these adjustments of total urban %, we do not change the breakdown - ! into the different urban classes. In particular: when pcturb_o is set to 0 for a point, + ! into the different urban classes. In particular: when pcturb_o is set to 0 for a point, ! the breakdown into the different urban classes is maintained as it was before. if (all_urban) then pcturb_o(:) = 100._r8 @@ -262,13 +265,18 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & if (root_task) then write (ndiag,'(a)') 'Successfully made %urban' - write (ndiag,'(a)') 'Attempting to make urban region .....' end if ! ------------------------------------------------------ ! Read in region field ! ------------------------------------------------------ + if (root_task) then + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make urban region .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + end if + ! Read in region_i allocate(region_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() @@ -277,7 +285,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & call ESMF_LogWrite("After reading in region_id in "//trim(subname), ESMF_LOGMSG_INFO) max_regions = nregions if (root_task) then - write(ndiag,'(a,i8)') trim(subname)//" max urban regions = ",max_regions + write(ndiag,'(a,i8)')" max urban regions = ",max_regions end if ! Create a multi-dimensional array (data_i) where each ungridded dimension corresponds to a 2d field @@ -316,7 +324,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & write (ndiag,*) end if - ! Output diagnostics + ! Output diagnostics ! TODO: (not currently done) ! Close the file @@ -354,9 +362,9 @@ subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) ! The returned array satisfies sum(classes_pct_tot(n,:))==100 for all n (within rounding error) ! input/output variables - real(r8), intent(in) :: classes_pct_gcell(:,:) ! % cover of classes as % of grid cell - real(r8), intent(in) :: sums(:) ! totals, as % of grid cell - real(r8), intent(out):: classes_pct_tot(:,:) ! % cover of classes as % of total + real(r8), intent(in) :: classes_pct_gcell(:,:) ! % cover of classes as % of grid cell + real(r8), intent(in) :: sums(:) ! totals, as % of grid cell + real(r8), intent(inout):: classes_pct_tot(:,:) ! % cover of classes as % of total ! local variables: integer :: n ! index @@ -469,7 +477,7 @@ subroutine mkurbanpar(datfname_i, pioid_o, mesh_o, & type(var_desc_t) :: pio_varid type(io_desc_t) :: pio_iodesc integer :: pio_vartype - integer :: dimid + integer :: dimid integer :: ier, rcode, rc ! error status character(len=cs) :: varname ! variable name integer :: xtype ! external type @@ -681,11 +689,11 @@ subroutine mkurbanpar(datfname_i, pioid_o, mesh_o, & ! End define model rcode = pio_enddef(pioid_o) - + ! ------------------------------------------------ ! Handle urban parameters with no extra dimensions ! ------------------------------------------------ - + allocate(data_scalar_o(ns_o, numurbl), stat=ier) data_scalar_o(:,:) = 0._r8 if (ier /= 0) call shr_sys_abort('mkurbanpar allocation error') @@ -696,7 +704,7 @@ subroutine mkurbanpar(datfname_i, pioid_o, mesh_o, & params_scalar(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & data_scalar_o, n_extra_dims = 0) - ! get io descriptor for variable output, write out variable and free memory for io descriptor + ! get io descriptor for variable output, write out variable and free memory for io descriptor call mkpio_iodesc_output(pioid_o, mesh_o, params_scalar(p)%name, pio_iodesc, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//& trim(params_scalar(p)%name)) @@ -751,7 +759,7 @@ subroutine mkurbanpar(datfname_i, pioid_o, mesh_o, & ! Determine variable name varname = trim(params_rad(p)%name)//trim(solar_suffix(m)) - ! get io descriptor for variable output, write out variable and free memory for io descriptor + ! get io descriptor for variable output, write out variable and free memory for io descriptor call mkpio_iodesc_output(pioid_o, mesh_o, varname, pio_iodesc, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//& trim(params_scalar(p)%name)) @@ -784,7 +792,7 @@ subroutine mkurbanpar(datfname_i, pioid_o, mesh_o, & n_extra_dims=1, extra_dims=extra_dims) end do - ! get io descriptor for variable output, write out variable and free memory for io descriptor + ! get io descriptor for variable output, write out variable and free memory for io descriptor call mkpio_iodesc_output(pioid_o, mesh_o, params_levurb(p)%name, pio_iodesc, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//& trim(params_levurb(p)%name)) @@ -830,7 +838,7 @@ subroutine lookup_and_check_err(pioid, varname, fill_val, check_invalid, & real(r8) , intent(in) :: fill_val ! value to put where we have no data in output variables logical , intent(in) :: check_invalid ! should we check whether there are any invalid data in the output? logical , intent(in) :: urban_skip_abort_on_invalid_data_check - real(r8) , intent(out) :: data(:,:) ! output from lookup_2d_netcdf + real(r8) , intent(inout) :: data(:,:) ! output from lookup_2d_netcdf integer , intent(in) :: n_extra_dims ! number of extra dimensions in the lookup table ! slice to use if lookup table variable has more than 2 dimensions: @@ -886,4 +894,167 @@ end subroutine lookup_and_check_err end subroutine mkurbanpar + subroutine mkurban_pct_diagnostics(area_i, area_o, mask_i, frac_o, urbn_i, urbn_o, dens_class) + ! + ! print diagnostics related to pct urban + ! Compare global areas on input and output grids + ! + ! This is intended to be called after mkurban_pct, but is split out into a separate + ! routine so that modifications to urbn_o can be made in between the two calls (e.g., + ! setting urbn_o to 0 wherever it is less than a certain threshold; the rules for doing + ! this can't always be applied inline in mkurban_pct). + ! + use mkvarpar + + ! input/output variables + real(r8) , intent(in) :: area_i(:) + real(r8) , intent(in) :: area_o(:) + integer , intent(in) :: mask_i(:) + real(r8) , intent(in) :: frac_o(:) + real(r8) , intent(in) :: urbn_i(:) ! input grid: percent urban + real(r8) , intent(in) :: urbn_o(:) ! output grid: percent urban + integer , intent(in), optional :: dens_class ! density class + + ! local variables: + real(r8) :: gurbn_i ! input grid: global urbn + real(r8) :: garea_i ! input grid: global area + real(r8) :: gurbn_o ! output grid: global urbn + real(r8) :: garea_o ! output grid: global area + integer :: ni,no,k ! indices + character(len=*), parameter :: subname = 'mkurban_pct_diagnostics' + !----------------------------------------------------------------------- + + ! Input grid + gurbn_i = 0._r8 + garea_i = 0._r8 + do ni = 1, size(area_i) + garea_i = garea_i + area_i(ni)*re**2 + gurbn_i = gurbn_i + urbn_i(ni)*(area_i(ni)/100._r8)* mask_i(ni)*re**2 + end do + + ! Output grid + gurbn_o = 0._r8 + garea_o = 0._r8 + do no = 1, size(area_o) + garea_o = garea_o + area_o(no)*re**2 + gurbn_o = gurbn_o + urbn_o(no)* (area_o(no)/100._r8)*frac_o(no)*re**2 + end do + + ! Diagnostic output + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + if (present(dens_class)) then + write (ndiag,'(1x,a,i0)') 'Urban Output -- class ', dens_class + else + write (ndiag,'(1x,a)') 'Urban Output' + end if + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,2001) +2001 format (1x,'surface type input grid area output grid area'/& + 1x,' 10**6 km**2 10**6 km**2 ') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + write (ndiag,2003) gurbn_i*1.e-06,gurbn_o*1.e-06 + write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 +2002 format (1x,'urban ',f14.3,f17.3) +2003 format (1x,'urban ',f14.3,f22.8) +2004 format (1x,'all surface ',f14.3,f17.3) + + end subroutine mkurban_pct_diagnostics + + !=============================================================== + subroutine mkurban_topo(file_mesh_i, file_data_i, mesh_o, varname, elev_o, rc) + ! + ! Make elevation data + ! + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh + character(len=*) , intent(in) :: varname ! topo variable name + real(r8) , intent(inout) :: elev_o(:) ! output elevation data + integer , intent(out) :: rc + + ! local variables: + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: data_i(:,:) + real(r8), allocatable :: data_o(:,:) + real(r8), allocatable :: elev_i(:) ! canyon_height to width ratio in + integer :: ns_i,ns_o ! bounds + integer :: ni, no ! indices + integer :: k,l,n,m ! indices + character(len=CS) :: name ! name of attribute + character(len=CS) :: unit ! units of attribute + integer :: ier,rcode ! error status + character(len=*), parameter :: subname = 'mkelev' + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (root_task) then + write(ndiag,'(a)') 'Attempting to make urban topo elevation .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + end if + + ! Open input data file + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) + + ! Read in input mesh + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Determine ns_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Read topo elev dataset with unit mask everywhere + write (6,*) 'Open elevation file: ', trim(file_data_i) + allocate(elev_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, trim(varname), mesh_i, elev_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call pio_closefile(pioid) + + ! Create a route handle between the input and output mesh + allocate(frac_o(ns_o), stat=ier) + if (ier/=0) call shr_sys_abort() + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + + ! Regrid input data to model resolution - determine elev_o on output grid + elev_o(:) = 0. + if (ier/=0) call shr_sys_abort() + call regrid_rawdata(mesh_i, mesh_o, routehandle, elev_i, elev_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + ! data_i, data_o, "Urban elev variable", "m", ndiag) + + ! Deallocate dynamic memory + deallocate (elev_i) + deallocate (frac_o) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + if (root_task) then + write (ndiag,'(a)') 'Successfully made elevation' + write (ndiag,'(a)') + end if + + end subroutine mkurban_topo + end module mkurbanparMod diff --git a/tools/mksurfdata_esmf/src/mkvocefMod.F90 b/tools/mksurfdata_esmf/src/mkvocefMod.F90 index 6c904b2608..02be43d5c2 100644 --- a/tools/mksurfdata_esmf/src/mkvocefMod.F90 +++ b/tools/mksurfdata_esmf/src/mkvocefMod.F90 @@ -4,111 +4,155 @@ module mkvocefMod ! Make VOC percentage emissions for surface dataset !----------------------------------------------------------------------- - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkvarpar - use mkvarctl - use mkncdio + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata + use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_ioformat, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkutilsMod , only : chkerr + use mkvarctl , only : root_task, ndiag, mpicom, MPI_INTEGER, MPI_MAX + use mkvarctl , only : soil_color_override, unsetcol + use mkvarpar , only : re implicit none private public :: mkvocef ! Get the percentage emissions for VOC for different land cover types + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + +!================================================================================= contains +!================================================================================= - !----------------------------------------------------------------------- - subroutine mkvocef(ldomain, mapfname, datfname, ndiag, & - ef_btr_o, ef_fet_o, ef_fdt_o, ef_shr_o, ef_grs_o, ef_crp_o) + subroutine mkvocef(file_data_i, file_mesh_i, mesh_o, & + ef_btr_o, ef_fet_o, ef_fdt_o, ef_shr_o, ef_grs_o, ef_crp_o, rc) ! make volatile organic coumpunds (VOC) emission factors. ! input/output variables - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diagnostic output - real(r8) , intent(out):: ef_btr_o(:) ! output grid: EFs for broadleaf trees - real(r8) , intent(out):: ef_fet_o(:) ! output grid: EFs for fineleaf evergreen - real(r8) , intent(out):: ef_fdt_o(:) ! output grid: EFs for fineleaf deciduous - real(r8) , intent(out):: ef_shr_o(:) ! output grid: EFs for shrubs - real(r8) , intent(out):: ef_grs_o(:) ! output grid: EFs for grasses - real(r8) , intent(out):: ef_crp_o(:) ! output grid: EFs for crops - ! + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesho + real(r8) , intent(out) :: ef_btr_o(:) ! output grid: EFs for broadleaf trees + real(r8) , intent(out) :: ef_fet_o(:) ! output grid: EFs for fineleaf evergreen + real(r8) , intent(out) :: ef_fdt_o(:) ! output grid: EFs for fineleaf deciduous + real(r8) , intent(out) :: ef_shr_o(:) ! output grid: EFs for shrubs + real(r8) , intent(out) :: ef_grs_o(:) ! output grid: EFs for grasses + real(r8) , intent(out) :: ef_crp_o(:) ! output grid: EFs for crops + integer , intent(out) :: rc + ! local variables: - real(r8), allocatable :: ef_btr_i(:) ! input grid: EFs for broadleaf trees - real(r8), allocatable :: ef_fet_i(:) ! input grid: EFs for fineleaf evergreen - real(r8), allocatable :: ef_fdt_i(:) ! input grid: EFs for fineleaf deciduous - real(r8), allocatable :: ef_shr_i(:) ! input grid: EFs for shrubs - real(r8), allocatable :: ef_grs_i(:) ! input grid: EFs for grasses - real(r8), allocatable :: ef_crp_i(:) ! input grid: EFs for crops - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldo ! global sum of dummy input fld - real(r8) :: sum_fldi ! global sum of dummy input fld - integer :: k,n,no,ni,ns_o,ns_i ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001_r8 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mkvocef' + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + integer :: ni,no + integer :: ns_i, ns_o + integer :: n,l,k + integer , allocatable :: mask_i(:) + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + real(r8), allocatable :: ef_btr_i(:) ! input grid: EFs for broadleaf trees + real(r8), allocatable :: ef_fet_i(:) ! input grid: EFs for fineleaf evergreen + real(r8), allocatable :: ef_fdt_i(:) ! input grid: EFs for fineleaf deciduous + real(r8), allocatable :: ef_shr_i(:) ! input grid: EFs for shrubs + real(r8), allocatable :: ef_grs_i(:) ! input grid: EFs for grasses + real(r8), allocatable :: ef_crp_i(:) ! input grid: EFs for crops + real(r8) :: sum_fldo ! global sum of dummy input fld + real(r8) :: sum_fldi ! global sum of dummy input fld + integer :: ier, rcode ! error status + real(r8) :: relerr = 0.00001_r8 ! max error: sum overlap wts ne 1 + character(len=*), parameter :: subname = 'mkvocef' !----------------------------------------------------------------------- - write (6,*) 'Attempting to make VOC emission factors .....' - - ns_o = ldomain%ns - - ! ----------------------------------------------------------------- - ! Read input Emission Factors - ! ----------------------------------------------------------------- + rc = ESMF_SUCCESS - ! Obtain input grid info, read local fields + if (root_task) then + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make VOC emission factors .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + end if - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - allocate(ef_btr_i(ns_i), ef_fet_i(ns_i), ef_fdt_i(ns_i), & - ef_shr_i(ns_i), ef_grs_i(ns_i), ef_crp_i(ns_i), & - frac_dst(ns_o), stat=ier) - if (ier/=0) call shr_sys_abort() + ! Open input data file + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) - write (6,*) 'Open VOC file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'ef_btr', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_btr_i), subname) - call check_ret(nf_inq_varid (ncid, 'ef_fet', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_fet_i), subname) - call check_ret(nf_inq_varid (ncid, 'ef_fdt', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_fdt_i), subname) - call check_ret(nf_inq_varid (ncid, 'ef_shr', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_shr_i), subname) - call check_ret(nf_inq_varid (ncid, 'ef_grs', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_grs_i), subname) - call check_ret(nf_inq_varid (ncid, 'ef_crp', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_crp_i), subname) - call check_ret(nf_close(ncid), subname) + ! Read in input mesh + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. + ! Determine ns_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - call gridmap_mapread(tgridmap, mapfname ) + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) + ! Get the landmask from the input data file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (frac_i(ni) > 0._r8) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + ! Create a route handle between the input and output mesh + allocate(frac_o(ns_o)) + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - ! Do mapping from input to output grid + ! Read input Emission Factors + allocate(ef_btr_i(ns_i), ef_fet_i(ns_i), ef_fdt_i(ns_i), & + ef_shr_i(ns_i), ef_grs_i(ns_i), ef_crp_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() - call gridmap_areaave_srcmask(tgridmap, ef_btr_i, ef_btr_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, ef_fet_i, ef_fet_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, ef_fdt_i, ef_fdt_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, ef_shr_i, ef_shr_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, ef_grs_i, ef_grs_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, ef_crp_i, ef_crp_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + call mkpio_get_rawdata(pioid, 'ef_btr', mesh_i, ef_btr_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call mkpio_get_rawdata(pioid, 'ef_fet', mesh_i, ef_fet_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call mkpio_get_rawdata(pioid, 'ef_fdt', mesh_i, ef_fdt_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call mkpio_get_rawdata(pioid, 'ef_shr', mesh_i, ef_shr_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call mkpio_get_rawdata(pioid, 'ef_grs', mesh_i, ef_grs_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call mkpio_get_rawdata(pioid, 'ef_crp', mesh_i, ef_crp_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Regrid input data to model resolution + call regrid_rawdata(mesh_i, mesh_o, routehandle, ef_btr_i, ef_btr_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, ef_fet_i, ef_fet_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, ef_fdt_i, ef_fdt_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, ef_shr_i, ef_shr_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, ef_grs_i, ef_grs_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, ef_btr_i, ef_crp_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Check for conservation - do no = 1, ns_o if ( ef_btr_o(no) < 0._r8 ) then write (6,*) 'MKVOCEF error: EF btr = ',ef_btr_o(no), ' is negative for no = ',no @@ -136,26 +180,15 @@ subroutine mkvocef(ldomain, mapfname, datfname, ndiag, & end if enddo - ! ----------------------------------------------------------------- - ! Error check1 - ! Compare global sum fld_o to global sum fld_i. - ! ----------------------------------------------------------------- - - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - write (6,*) 'Successfully made VOC Emission Factors' - write (6,*) + if (root_task) then + write (ndiag,'(a)') 'Successfully made VOC Emission Factors' + write (ndiag,*) + end if - ! Deallocate dynamic memory + deallocate ( ef_btr_i, ef_fet_i, ef_fdt_i, ef_shr_i, ef_grs_i, ef_crp_i, frac_o) - deallocate ( ef_btr_i, ef_fet_i, ef_fdt_i, & - ef_shr_i, ef_grs_i, ef_crp_i, frac_dst, mask_r8 ) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() end subroutine mkvocef From 8a8b0957807c0cb922d01d82c57f7db657579ab9 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 2 Feb 2022 12:22:44 -0700 Subject: [PATCH 038/614] fixed problems with glacierregion and mkvoc --- tools/mksurfdata_esmf/run/run_mksurfdata | 3 +- tools/mksurfdata_esmf/src/CMakeLists.txt | 1 + .../mksurfdata_esmf/src/mkdiagnosticsMod.F90 | 8 +- tools/mksurfdata_esmf/src/mkesmfMod.F90 | 44 +--- .../src/mkglacierregionMod.F90 | 66 +++--- tools/mksurfdata_esmf/src/mkglcmecMod.F90 | 188 ++++++------------ tools/mksurfdata_esmf/src/mklanwatMod.F90 | 4 +- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 15 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 106 +++++----- tools/mksurfdata_esmf/src/mkvarctl.F90 | 4 +- tools/mksurfdata_esmf/src/mkvocefMod.F90 | 18 +- 11 files changed, 179 insertions(+), 278 deletions(-) diff --git a/tools/mksurfdata_esmf/run/run_mksurfdata b/tools/mksurfdata_esmf/run/run_mksurfdata index f70a8b01f8..b845ca7dcc 100755 --- a/tools/mksurfdata_esmf/run/run_mksurfdata +++ b/tools/mksurfdata_esmf/run/run_mksurfdata @@ -3,11 +3,10 @@ #PBS -N job_name #PBS -j oe #PBS -q premium -#PBS -l walltime=45:00 +#PBS -l walltime=20:00 ##PBS -l select=1:ncpus=36:mpiprocs=36 #PBS -l select=4:ncpus=36:mpiprocs=36 ##PBS -l select=16:ncpus=36:mpiprocs=9 -#PBS -o log.out # note for -l input above # -l select={num_nodes}:ncpus={max_tasks_per_node}:mpiprocs={tasks_per_node} diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 54057f4125..a26b58aa72 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -28,6 +28,7 @@ set(SRCFILES mkvarctl.F90 mksoiltexMod.F90 mksoildepthMod.F90 mkurbanparMod.F90 + mkvocefMod.F90 mkesmfMod.F90 mkutilsMod.F90 mkchecksMod.F90 diff --git a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 index 95e0a985a4..325a2c6cd1 100644 --- a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 @@ -260,17 +260,19 @@ subroutine output_diagnostics_continuous_outonly(area_o, frac_o, data_o, name, u end subroutine output_diagnostics_continuous_outonly !=============================================================== - subroutine output_diagnostics_index(data_i, data_o, mask_i, frac_o, name, minval, maxval, ndiag) + subroutine output_diagnostics_index(area_i, area_o, mask_i, frac_o, data_i, data_o, name, minval, maxval, ndiag) ! ! Output diagnostics for an index field: area of each index in input and output ! use mkvarpar, only : re ! input/output variables - integer , intent(in) :: data_i(:) ! data on input grid - integer , intent(in) :: data_o(:) ! data on output grid + real(r8) , intent(in) :: area_i(:) + real(r8) , intent(in) :: area_o(:) integer , intent(in) :: mask_i(:) real(r8) , intent(in) :: frac_o(:) + integer , intent(in) :: data_i(:) ! data on input grid + integer , intent(in) :: data_o(:) ! data on output grid character(len=*) , intent(in) :: name ! name of field integer , intent(in) :: minval ! minimum valid value integer , intent(in) :: maxval ! minimum valid value diff --git a/tools/mksurfdata_esmf/src/mkesmfMod.F90 b/tools/mksurfdata_esmf/src/mkesmfMod.F90 index e735d6dc89..7f478241e8 100644 --- a/tools/mksurfdata_esmf/src/mkesmfMod.F90 +++ b/tools/mksurfdata_esmf/src/mkesmfMod.F90 @@ -13,11 +13,6 @@ module mkesmfMod public :: create_routehandle_r4 public :: create_routehandle_r8 - interface get_meshareas - module procedure get_meshareas_r4 - module procedure get_meshareas_r8 - end interface get_meshareas - interface regrid_rawdata module procedure regrid_rawdata1d_r4 module procedure regrid_rawdata1d_r8 @@ -338,7 +333,9 @@ subroutine regrid_rawdata2d_r8(mesh_i, mesh_o, routehandle, data_i, data_o, lbo end subroutine regrid_rawdata2d_r8 !=============================================================== - subroutine get_meshareas_r8(mesh, areas, rc) + subroutine get_meshareas(mesh, areas, rc) + + use mkvarpar, only : re ! input/output variables type(ESMF_Mesh) , intent(in) :: mesh @@ -348,51 +345,20 @@ subroutine get_meshareas_r8(mesh, areas, rc) ! local variables real(r8), pointer :: dataptr(:) type(ESMF_Field) :: lfield - integer :: ns ! -------------------------------------------- rc = ESMF_SUCCESS - call ESMF_MeshGet(mesh, numOwnedElements=ns, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return lfield = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldRegridGetArea(lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(lfield, farrayPtr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - areas(:) = dataptr(:) + areas(:) = dataptr(:) * re**2 call ESMF_FieldDestroy(lfield, nogarbage = .true., rc=rc) - end subroutine get_meshareas_r8 - !=============================================================== - subroutine get_meshareas_r4(mesh, areas, rc) - - ! input/output variables - type(ESMF_Mesh) , intent(in) :: mesh - real(r4) , intent(inout) :: areas(:) - integer , intent(out) :: rc - - ! local variables - real(r8), pointer :: dataptr(:) - type(ESMF_Field) :: lfield - integer :: ns - ! -------------------------------------------- - - rc = ESMF_SUCCESS - - call ESMF_MeshGet(mesh, numOwnedElements=ns, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - lfield = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldRegridGetArea(lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - areas(:) = real(dataptr(:), kind=r4) - - call ESMF_FieldDestroy(lfield, nogarbage = .true., rc=rc) - end subroutine get_meshareas_r4 + end subroutine get_meshareas end module mkesmfMod diff --git a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 index eaa5283a2c..ccaff35ad8 100644 --- a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 @@ -13,11 +13,11 @@ module mkglacierregionMod use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas use mkutilsMod , only : chkerr + use mkchecksMod , only : min_bad + use mkvarctl , only : ndiag, root_task #ifdef TODO ! use mkdiagnosticsMod, only : output_diagnostics_index #endif - use mkchecksMod, only : min_bad - use mkvarctl implicit none private @@ -53,6 +53,8 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) real(r8), allocatable :: data_i(:,:) real(r8), allocatable :: data_o(:,:) integer , allocatable :: glacier_region_i(:) ! glacier region on input grid @@ -67,6 +69,7 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r write(ndiag,*) write(ndiag,'(a)') 'Attempting to make glacier region .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if ! Open input data file @@ -88,18 +91,26 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Get the landmask from the input data file and reset the mesh mask based on that + ! Read in input data (Confirm that no value of glacier_region is less than min_allowed) + allocate(glacier_region_i(ns_i), stat=ier) + if (ier/=0) call abort() + call mkpio_get_rawdata(pioid, 'GLACIER_REGION', mesh_i, glacier_region_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (min_bad(glacier_region_i, 0, 'GLACIER_REGION')) then + call shr_sys_abort() + end if + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + + ! Reset mesh mask to zero where glacier_region_i is zero allocate(frac_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i - if (frac_i(ni) > 0._r8) then - mask_i(ni) = 1 - else + if (glacier_region_i(ni) == 0) then mask_i(ni) = 0 + else + mask_i(ni) = 1 end if end do call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) @@ -107,24 +118,13 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r ! Create a route handle between the input and output mesh allocate(frac_o(ns_o)) + if (ier/=0) call abort() call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - ! Read in input data - allocate(glacier_region_i(ns_i), stat=ier) - if (ier/=0) call abort() - call mkpio_get_rawdata(pioid, 'GLACIER_REGION', mesh_i, glacier_region_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - - ! Confirm that no value of glacier_region is less than min_allowed. - if (min_bad(glacier_region_i, 0, 'GLACIER_REGION')) then - call shr_sys_abort() - end if - - ! Now determine data_i as a real 2d array - for every possible soil color create a global - ! field with gridcells equal to 1 for that soil color and zero elsewhere + ! Now determine data_i as a real 2d array - for every possible glacier region create a global + ! field with gridcells equal to 1 for that region and zero elsewhere allocate(data_i(0:nglacier_regions,ns_i)) data_i(:,:) = 0._r4 do l = 0,nglacier_regions @@ -141,22 +141,36 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, nglacier_regions, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Determine glacier_region_o glacier_region_o(:) = 0 do no = 1,ns_o max_index = maxloc(data_o(:,no)) glacier_region_o(no) = max_index(1) - 1 end do - ! call output_diagnostics_index(glacier_region_i, glacier_region_o, tgridmap, & - ! 'Glacier Region ID', 0, max_region, ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) + ! Determine mesh areas + allocate(area_i(ns_i)) + allocate(area_o(ns_o)) + call get_meshareas(mesh_i, area_i, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call get_meshareas(mesh_o, area_o, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + +#ifdef TODO + ! call output_diagnostic_index(area_i, area_o, mask_i, frac_o, & + ! glacier_region_i, glacier_region_o, 'Glacier Region ID', 0, max_region, ndiag) +#endif ! Close the input file call pio_closefile(pioid) call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) ! Release memory - deallocate (frac_i) - deallocate (frac_o) + deallocate(mask_i) + deallocate(frac_i) + deallocate(frac_o) + deallocate(area_i) + deallocate(area_o) deallocate(glacier_region_i) call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() diff --git a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 index d60f735cfa..e6948d5bfc 100644 --- a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 @@ -1,84 +1,59 @@ module mkglcmecMod + !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mkglcmecMod - ! - ! !DESCRIPTION: ! Make glacier multi-elevation class data - ! - ! !REVISION HISTORY: - ! Author: Erik Kluzek, Mariana Vertenstein - ! !----------------------------------------------------------------------- - !!USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkdomainMod , only : domain_checksame - implicit none + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkutilsMod , only : chkerr + use mkvarctl , only : ndiag, root_task + + implicit none private ! By default make data private - ! - ! !PUBLIC MEMBER FUNCTIONS: - ! - public mkglcmecInit ! Initialization - public mkglcmec ! Set glacier multi-elevation class - public mkglacier ! Set percent glacier - ! - ! !PUBLIC DATA MEMBERS: - ! - integer, public :: nglcec = 10 ! number of elevation classes for glaciers + + public :: mkglcmecInit ! Initialization + public :: mkglcmec ! Set glacier multi-elevation class + public :: mkglacier ! Set percent glacier + private :: get_elevclass ! get elevation class index + private :: mean_elevation_vc ! get the elevation of a virtual column + + integer, public :: nglcec = 10 ! number of elevation classes for glaciers real(r8), allocatable :: elevclass(:) ! elevation classes - ! - ! !PRIVATE MEMBER FUNCTIONS: - private get_elevclass ! get elevation class index - private mean_elevation_vc ! get the elevation of a virtual column - !EOP - !=============================================================== + +!================================================================================= contains - !=============================================================== +!================================================================================= - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkglcmecInit - ! - ! !INTERFACE: subroutine mkglcmecInit( elevclass_o ) ! - ! !DESCRIPTION: ! Initialize of Make glacier multi-elevation class data - ! !USES: - ! - ! !ARGUMENTS: - implicit none - real(r8), intent(OUT) :: elevclass_o(:) ! elevation classes - ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: Erik Kluzek - ! ! + ! input/output variables + real(r8), intent(out) :: elevclass_o(:) ! elevation classes + ! !LOCAL VARIABLES: - !EOP - character(len=32) :: subname = 'mkglcmecInit:: ' + character(len=*), parameter :: subname = 'mkglcmecInit:: ' !----------------------------------------------------------------------- + allocate( elevclass(nglcec+1) ) - ! ----------------------------------------------------------------- ! Define elevation classes, represents lower boundary of each class - ! ----------------------------------------------------------------- - if ( nglcec == 36 )then - elevclass(:) = (/ 0., 200., 400., 600., 800., & - 1000., 1200., 1400., 1600., 1800., & - 2000., 2200., 2400., 2600., 2800., & - 3000., 3200., 3400., 3600., 3800., & - 4000., 4200., 4400., 4600., 4800., & - 5000., 5200., 5400., 5600., 5800., & - 6000., 6200., 6400., 6600., 6800., & - 7000., 10000./) + if ( nglcec == 36 )then + elevclass(:) = (/ 0., 200., 400., 600., 800., & + 1000., 1200., 1400., 1600., 1800., & + 2000., 2200., 2400., 2600., 2800., & + 3000., 3200., 3400., 3600., 3800., & + 4000., 4200., 4400., 4600., 4800., & + 5000., 5200., 5400., 5600., 5800., & + 6000., 6200., 6400., 6600., 6800., & + 7000., 10000./) else if ( nglcec == 10 )then elevclass(1) = 0. elevclass(2) = 200. @@ -109,19 +84,14 @@ subroutine mkglcmecInit( elevclass_o ) else write(6,*) subname//"ERROR:: nglcec must be 1, 3, 5, 10 or 36",& " to work with CLM: " - call abort() + call shr_sys_abort() end if elevclass_o(:) = elevclass(:) end subroutine mkglcmecInit - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkglcmec - ! - ! !INTERFACE: + !================================================================================= subroutine mkglcmec(ldomain, mapfname, & datfname_fglacier, ndiag, & pctglcmec_o, topoglcmec_o, & @@ -145,16 +115,11 @@ subroutine mkglcmec(ldomain, mapfname, & ! variables in an arbitrary way. ! ! !USES: - use shr_sys_mod, only : shr_sys_abort - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod use mkvarpar use mkutilsMod, only : slightly_below, slightly_above - use mkncdio use mkvarctl , only : outnc_3dglc ! ! !ARGUMENTS: - implicit none type(domain_type) , intent(in) :: ldomain character(len=*) , intent(in) :: mapfname ! input mapping file name character(len=*) , intent(in) :: datfname_fglacier ! raw glacier data @@ -166,21 +131,7 @@ subroutine mkglcmec(ldomain, mapfname, & real(r8), optional, intent(out):: pctglc_gic_o(:) ! % glc gic on output grid, summed across elevation classes (% of landunit) real(r8), optional, intent(out):: pctglc_icesheet_o(:) ! % glc ice sheet on output grid, summed across elevation classes (% of landunit) ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: David Lawrence - ! 7/12/11: Bill Sacks: substantial rewrite to use input topo and % glacier at same resolution - ! 9/25/12: Bill Sacks: substantial rewrite to use new format of fglacier, which provides - ! percent by elevation bin (thus the separate topo dataset is no longer needed - ! in this routine) - ! - ! - ! !LOCAL VARIABLES: - !EOP - type(domain_type) :: tdomain ! local domain - type(gridmap_type) :: tgridmap ! local gridmap + ! local variables: real(r8), allocatable :: pctglc_gic_i(:) ! input GIC percentage for a single level real(r8), allocatable :: pctglc_icesheet_i(:) ! input icesheet percentage for a single level real(r8), allocatable :: topoglcmec_unnorm_o(:,:) ! same as topoglcmec_o, but unnormalized @@ -201,8 +152,7 @@ subroutine mkglcmec(ldomain, mapfname, & logical :: errors ! error status real(r8), parameter :: eps = 2.e-5_r8 ! epsilon for error checks (note that we use a large-ish value - ! because data are stored as single-precision floats in the - ! raw dataset) + ! because data are stored as single-precision floats in the raw dataset) real(r8), parameter :: eps_small = 1.e-12_r8 ! epsilon for error checks that expect close match character(len=32) :: subname = 'mkglcmec' !----------------------------------------------------------------------- @@ -245,7 +195,7 @@ subroutine mkglcmec(ldomain, mapfname, & write (6,*) trim(datfname_fglacier) write (6,*) 'Perhaps you are trying to use an old-format glacier file?' write (6,*) '(prior to Sept., 2012)' - call abort() + call shr_sys_abort() end if call check_ret(nf_inq_dimlen (ncid, dimid, nlev), subname) @@ -267,7 +217,7 @@ subroutine mkglcmec(ldomain, mapfname, & call get_dim_lengths(ncid, 'PCT_GLC_GIC', ndims, dim_lengths) allocate(starts(ndims), counts(ndims), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() starts(1:ndims) = 1 @@ -280,13 +230,13 @@ subroutine mkglcmec(ldomain, mapfname, & ! -------------------------------------------------------------------- allocate(pctglc_gic_i(nst), pctglc_icesheet_i(nst), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() allocate(topoglcmec_unnorm_o(ns_o,nglcec), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() topoglcmec_unnorm_o(:,:) = 0. @@ -311,7 +261,7 @@ subroutine mkglcmec(ldomain, mapfname, & ! Determine elevation class m = get_elevclass(topoice_i) if (m < 1 .or. m > nglcec) then - call abort() + call shr_sys_abort() end if do n = 1,tgridmap%ns @@ -379,7 +329,7 @@ subroutine mkglcmec(ldomain, mapfname, & ! Renormalize percentages to be given as % of landunit rather than % of grid cell. allocate(pctglc_tot_o(ns_o), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() do no = 1,ns_o pctglc_tot_o(no) = sum(pctglcmec_o(no,:)) @@ -460,7 +410,7 @@ subroutine mkglcmec(ldomain, mapfname, & end do if (errors) then - call abort() + call shr_sys_abort() end if ! Deallocate dynamic memory @@ -478,15 +428,9 @@ subroutine mkglcmec(ldomain, mapfname, & end subroutine mkglcmec - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkglacier - ! - ! !INTERFACE: + !================================================================================= subroutine mkglacier(ldomain, mapfname, datfname, ndiag, zero_out, glac_o) ! - ! !DESCRIPTION: ! make percent glacier ! ! In contrast to mkglcmec, this uses a "flat" PCT_GLACIER field (not separated by @@ -557,7 +501,7 @@ subroutine mkglacier(ldomain, mapfname, datfname, ndiag, zero_out, glac_o) allocate(glac_i(ns), & frac_dst(ns_o), & stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() write (6,*) 'Open glacier file: ', trim(datfname) call check_ret(nf_open(datfname, 0, ncid), subname) @@ -600,7 +544,7 @@ subroutine mkglacier(ldomain, mapfname, datfname, ndiag, zero_out, glac_o) if ((glac_o(no)) > 100.000001_r8) then write (6,*) 'MKGLACIER error: glacier = ',glac_o(no), & ' greater than 100.000001 for column, row = ',no - call abort() + call shr_sys_abort() end if enddo @@ -612,7 +556,7 @@ subroutine mkglacier(ldomain, mapfname, datfname, ndiag, zero_out, glac_o) ! output grid that is land as determined by input grid allocate(mask_r8(ns), stat=ier) - if (ier/=0) call abort() + if (ier/=0) call shr_sys_abort() mask_r8 = tdomain%mask call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) @@ -675,31 +619,20 @@ subroutine mkglacier(ldomain, mapfname, datfname, ndiag, zero_out, glac_o) end subroutine mkglacier - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: get_elevclass - ! - ! !INTERFACE: + !================================================================================= integer function get_elevclass(topo, writewarn) ! - ! !DESCRIPTION: ! Returns elevation class index (1..nglcec) given the topographic height. ! If topo is lower than the lowest elevation class, returns 0. ! If topo is higher than the highest elevation class, returns (nglcec+1). ! In either of the two latter cases, the function also writes a warning message, unless ! writewarn is present and false. ! - ! !ARGUMENTS: - implicit none + ! input/output variables real(r8), intent(in) :: topo ! topographic height (m) logical, intent(in), optional :: writewarn ! should warning messages be written? (default: true) ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! - ! !LOCAL VARIABLES: - !EOP + ! local variables integer :: m logical :: my_writewarn character(len=32) :: subname = 'get_elevclass' @@ -741,12 +674,7 @@ integer function get_elevclass(topo, writewarn) end function get_elevclass - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mean_elevation_vc - ! - ! !INTERFACE: + !================================================================================= real(r8) function mean_elevation_vc(class) ! ! !DESCRIPTION: @@ -779,7 +707,7 @@ real(r8) function mean_elevation_vc(class) end if else write(6,*) 'ERROR in ', trim(subname), ': class out of bounds= ', class - call abort() + call shr_sys_abort() end if end function mean_elevation_vc diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 6fd54a980a..4cca362225 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -57,8 +57,8 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) - real(r4), allocatable :: area_i(:) - real(r4), allocatable :: area_o(:) + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) real(r8), allocatable :: lake_i(:) ! input grid: percent lake real(r8), allocatable :: swmp_i(:) ! input grid: percent wetland real(r8), allocatable :: lakedepth_i(:) ! iput grid: lake depth diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index 1d6500f95a..563482b895 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -10,7 +10,6 @@ module mksoilcolMod use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag, mpicom, MPI_INTEGER, MPI_MAX use mkvarctl , only : soil_color_override, unsetcol - use mkvarpar , only : re implicit none private @@ -45,8 +44,8 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r integer , allocatable :: mask_i(:) real(r4), allocatable :: frac_i(:) real(r4), allocatable :: frac_o(:) - real(r4), allocatable :: area_i(:) - real(r4), allocatable :: area_o(:) + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) real(r4), allocatable :: data_i(:,:) real(r4), allocatable :: data_o(:,:) real(r4), allocatable :: soil_color_i(:) @@ -209,18 +208,14 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r gast_i(:) = 0. do ni = 1,ns_i k = soil_color_i(ni) - gast_i(k) = gast_i(k) + area_i(ni) * mask_i(ni) * re**2 + gast_i(k) = gast_i(k) + area_i(ni) * mask_i(ni) end do gast_o(:) = 0. do no = 1,ns_o k = soil_color_o(no) - gast_o(k) = gast_o(k) + area_o(no) * frac_o(no) * re**2 + gast_o(k) = gast_o(k) + area_o(no) * frac_o(no) end do - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Soil Color Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) write (ndiag,*) write (ndiag,'(1x,70a1)') ('.',k=1,70) write (ndiag,101) @@ -241,6 +236,8 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r deallocate(mask_i) deallocate(data_i) deallocate(data_o) + deallocate(area_i) + deallocate(area_o) deallocate(soil_color_i) call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index a9ca078c8f..b4f73f1f29 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -14,51 +14,48 @@ program mksurfdata ! ====================================== ! mksrf_fgrid_mesh -- mesh for output grid ! ====================================== - ! Must specify settings for input high resolution datafiles + ! Must specify settings for input high resolution datafiles and corresponding meshes ! ====================================== - ! mksrf_fglacier - Glacier dataset - ! mksrf_fglacierregion - Glacier region ID dataset - ! mksrf_flai ----- Leaf Area Index dataset - ! mksrf_flakwat -- Lake water dataset - ! mksrf_fwetlnd -- Wetland water dataset - ! mksrf_forganic - Organic soil carbon dataset - ! mksrf_fmax ----- Max fractional saturated area dataset - ! mksrf_fsoicol -- Soil color dataset - ! mksrf_fsoitex -- Soil texture dataset - ! mksrf_furbtopo-- Topography dataset (for limiting urban areas) - ! mksrf_furban --- Urban dataset - ! mksrf_fvegtyp -- PFT vegetation type dataset - ! mksrf_fhrvtyp -- harvest type dataset - ! mksrf_fvocef -- Volatile Organic Compund Emission Factor dataset - ! mksrf_fgdp ----- GDP dataset - ! mksrf_fpeat ---- Peatland dataset - ! mksrf_fsoildepth Soil depth dataset - ! mksrf_fabm ----- Agricultural fire peak month dataset - ! mksrf_ftopostats Topography statistics dataset - ! mksrf_fvic ----- VIC parameters dataset - ! ====================================== - ! Must specify meshes for input high resolutin datasets - ! ====================================== - ! mksrf_fpft_mesh -------- Mesh for mksrf_fvegtyp - ! mksrf_flakwat_mesh ----- Mesh for mksrf_flakwat - ! mksrf_fwetlnd_mesh ----- Mesh for mksrf_fwetlnd - ! mksrf_fglacier_mesh ---- Mesh for mksrf_fglacier - ! mksrf_fglacierregion_mesh Mesh for mksrf_fglacierregion - ! mksrf_fsoitex_mesh ----- Mesh for mksrf_fsoitex - ! mksrf_fsoicol_mesh ----- Mesh for mksrf_fsoicol - ! mksrf_furban_mesh ------ Mesh for mksrf_furban - ! mksrf_furbtopo_mesh ---- Mesh for mksrf_furbtopo - ! mksrf_fmax_mesh -------- Mesh for mksrf_fmax - ! mksrf_forganic_mesh ---- Mesh for mksrf_forganic - ! mksrf_fvocef_mesh ------ Mesh for mksrf_fvocef - ! mksrf_flai_mesh -------- Mesh for mksrf_flai - ! mksrf_fhrv_mesh -------- Mesh for mksrf_flai harvesting - ! mksrf_fgdp_mesh -------- Mesh for mksrf_fgdp - ! mksrf_fpeat_mesh ------- Mesh for mksrf_fpeat - ! mksrf_fsoildepth_mesh -- Mesh for mksrf_fsoildepth - ! mksrf_fabm_mesh -------- Mesh for mksrf_fabm - ! mksrf_ftopostats_mesh -- Mesh for mksrf_ftopostats - ! mksrf_fvic_mesh -------- Mesh for mksrf_fvic + ! mksrf_fglacier - Glacier dataset + ! mksrf_fglacier_mesh - Mesh for mksrf_fglacier + ! mksrf_fglacierregion - Glacier region ID dataset + ! mksrf_fglacierregion_mesh - Mesh for mksrf_fglacierregion + ! mksrf_flai - Leaf Area Index dataset + ! mksrf_flai_mesh - Mesh for mksrf_flai + ! mksrf_flakwat - Lake water dataset + ! mksrf_flakwat_mesh - Mesh for mksrf_flakwat + ! mksrf_fwetlnd - Wetland water dataset + ! mksrf_fwetlnd_mesh - Mesh for mksrf_fwetlnd + ! mksrf_forganic - Organic soil carbon dataset + ! mksrf_forganic_mesh - Mesh for mksrf_forganic + ! mksrf_fmax - Max fractional saturated area dataset + ! mksrf_fmax_mesh - Mesh for mksrf_fmax + ! mksrf_fsoicol - Soil color dataset + ! mksrf_fsoicol_mesh - Mesh for mksrf_fsoicol + ! mksrf_fsoitex - Soil texture dataset + ! mksrf_fsoitex_mesh - Mesh for mksrf_fsoitex + ! mksrf_furbtopo - Topography dataset (for limiting urban areas) + ! mksrf_furbtopo_mesh - Mesh for mksrf_furbtopo + ! mksrf_furban - Urban dataset + ! mksrf_furban_mesh - Mesh for mksrf_furban + ! mksrf_fvegtyp - PFT vegetation type dataset + ! mksrf_fpft_mesh - Mesh for mksrf_fvegtyp + ! mksrf_fhrvtyp - harvest type dataset + ! mksrf_fhrvtyp_mesh - Mesh for mksrf_flai harvesting + ! mksrf_fvocef - Volatile Organic Compund Emission Factor dataset + ! mksrf_fvocef_mesh - Mesh for mksrf_fvocef + ! mksrf_fgdp - GDP dataset + ! mksrf_fgdp_mesh - Mesh for mksrf_fgdp + ! mksrf_fpeat - Peatland dataset + ! mksrf_fpeat_mesh - Mesh for mksrf_fpeat + ! mksrf_fsoildepth - Soil depth dataset + ! mksrf_fsoildepth_mesh - Mesh for mksrf_fsoildepth + ! mksrf_fabm - Agricultural fire peak month dataset + ! mksrf_fabm_mesh - Mesh for mksrf_fabm + ! mksrf_ftopostats - Topography statistics dataset + ! mksrf_ftopostats_mesh - Mesh for mksrf_ftopostats + ! mksrf_fvic - VIC parameters dataset + ! mksrf_fvic_mesh - Mesh for mksrf_fvic ! ====================================== ! Optionally specify setting for: ! ====================================== @@ -110,10 +107,10 @@ program mksurfdata use mkagfirepkmonthMod , only : mkagfirepkmon use mktopostatsMod , only : mktopostats use mkVICparamsMod , only : mkVICparams - use mkvocefMod , only : mkvocef #endif + use mkvocefMod , only : mkvocef use mkglacierregionMod , only : mkglacierregion - use mksoiltexMod , only : mksoiltex + use mksoiltexMod , only : mksoiltex use mksoilfmaxMod , only : mksoilfmax use mksoildepthMod , only : mksoildepth use mksoilcolMod , only : mksoilcol @@ -386,27 +383,24 @@ program mksurfdata ! begin working ! ! Make VOC emission factors for isoprene [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] - write(6,*)'DEBUG: i am here1' - call flush(6) allocate (ef1_btr(lsize_o)) ; ef1_btr(:) = 0._r8 allocate (ef1_fet(lsize_o)) ; ef1_fet(:) = 0._r8 allocate (ef1_fdt(lsize_o)) ; ef1_fdt(:) = 0._r8 allocate (ef1_shr(lsize_o)) ; ef1_shr(:) = 0._r8 allocate (ef1_grs(lsize_o)) ; ef1_grs(:) = 0._r8 allocate (ef1_crp(lsize_o)) ; ef1_crp(:) = 0._r8 - ! call mkvocef ( mksrf_fvocef, mksrf_fvocef_mesh, mesh_model, & - ! ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & - ! ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkvocef') - write(6,*)'DEBUG: i am here2' - call flush(6) + call ESMF_LogWrite("DEBUG: mksrf_fvocef_mesh is "//trim(mksrf_fvocef_mesh), ESMF_LOGMSG_INFO) + call mkvocef ( mksrf_fvocef, mksrf_fvocef_mesh, mesh_model, & + ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & + ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkvocef') ! Make glacier region ID [glacier_region] from [fglacierregion] dataset allocate (glacier_region(lsize_o)) ; glacier_region(:) = -999 call mkglacierregion(mksrf_fglacierregion_mesh, mksrf_fglacierregion, mesh_model, glacier_region, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacierregion') - ! Make urban fraction [pcturb] from [furban] dataset + ! ! Make urban fraction [pcturb] from [furban] dataset allocate (pcturb(lsize_o)) ; pcturb(:) = spval allocate (urban_classes(lsize_o,numurbl)) ; urban_classes(:,:) = spval allocate (urban_classes_g(lsize_o,numurbl)); urban_classes_g(:,:) = spval @@ -515,7 +509,7 @@ program mksurfdata pctwet(n) = float(nint(pctwet(n))) pctgla(n) = float(nint(pctgla(n))) end do - !DEBUG + !Debug call ESMF_LogWrite("After fixes", ESMF_LOGMSG_INFO) diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index 5ab9bf0979..e566de7184 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -322,10 +322,10 @@ subroutine read_namelist_input() call mpi_bcast (mksrf_flai_mesh, len(mksrf_flai_mesh), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fvocef, len(mksrf_fvocef), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fvocef, len(mksrf_fvocef), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fvocef_mesh, len(mksrf_fvocef_mesh), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_ftopostats, len(mksrf_ftopostats), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_ftopostats, len(mksrf_ftopostats), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_ftopostats_mesh, len(mksrf_ftopostats_mesh), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fvic, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fvic_mesh, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) diff --git a/tools/mksurfdata_esmf/src/mkvocefMod.F90 b/tools/mksurfdata_esmf/src/mkvocefMod.F90 index 02be43d5c2..237076c34e 100644 --- a/tools/mksurfdata_esmf/src/mkvocefMod.F90 +++ b/tools/mksurfdata_esmf/src/mkvocefMod.F90 @@ -71,20 +71,20 @@ subroutine mkvocef(file_data_i, file_mesh_i, mesh_o, & !----------------------------------------------------------------------- rc = ESMF_SUCCESS + call ESMF_VMLogMemInfo("At start of "//trim(subname)) if (root_task) then write(ndiag,*) write(ndiag,'(a)') 'Attempting to make VOC emission factors .....' - write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input data file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if ! Open input data file - call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh - call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) @@ -149,7 +149,7 @@ subroutine mkvocef(file_data_i, file_mesh_i, mesh_o, & if (ChkErr(rc,__LINE__,u_FILE_u)) return call regrid_rawdata(mesh_i, mesh_o, routehandle, ef_grs_i, ef_grs_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, ef_btr_i, ef_crp_o, rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle, ef_crp_i, ef_crp_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Check for conservation @@ -180,16 +180,16 @@ subroutine mkvocef(file_data_i, file_mesh_i, mesh_o, & end if enddo + ! Deallocate memory + deallocate ( ef_btr_i, ef_fet_i, ef_fdt_i, ef_shr_i, ef_grs_i, ef_crp_i, frac_o) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + if (root_task) then write (ndiag,'(a)') 'Successfully made VOC Emission Factors' write (ndiag,*) end if - deallocate ( ef_btr_i, ef_fet_i, ef_fdt_i, ef_shr_i, ef_grs_i, ef_crp_i, frac_o) - - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - end subroutine mkvocef end module mkvocefMod From 36b6c5737eedb2f5932018a4928c8e8e6db78373 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 3 Feb 2022 22:31:14 -0700 Subject: [PATCH 039/614] output for mkglcmec --- .../gen_mksurfdata_namelist.xml | 2 +- tools/mksurfdata_esmf/run/mksurfdata_in | 2 +- tools/mksurfdata_esmf/src/CMakeLists.txt | 1 + .../src/mkagfirepkmonthMod.F90 | 501 ++++++------ tools/mksurfdata_esmf/src/mkfileMod.F90 | 74 +- tools/mksurfdata_esmf/src/mkglcmecMod.F90 | 710 +++++++++--------- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 7 + tools/mksurfdata_esmf/src/mkorganicMod.F90 | 10 +- tools/mksurfdata_esmf/src/mkpeatMod.F90 | 244 +++--- tools/mksurfdata_esmf/src/mkpioMod.F90 | 238 ++++-- tools/mksurfdata_esmf/src/mksurfdata.F90 | 110 ++- tools/mksurfdata_esmf/src/mkutilsMod.F90 | 20 +- tools/mksurfdata_esmf/src/mkvocefMod.F90 | 2 +- tools/mksurfdata_esmf/src/shr_kind_mod.F90 | 1 + tools/mksurfdata_map/src/mksurfdat.F90 | 4 +- 15 files changed, 1074 insertions(+), 852 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 2b8229ab91..42bf9412d7 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -134,7 +134,7 @@ version of the raw dataset will probably go away. - lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000.c120926.nc + lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000.cdf5.c120926.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc diff --git a/tools/mksurfdata_esmf/run/mksurfdata_in b/tools/mksurfdata_esmf/run/mksurfdata_in index 289c151263..dc4332629b 100644 --- a/tools/mksurfdata_esmf/run/mksurfdata_in +++ b/tools/mksurfdata_esmf/run/mksurfdata_in @@ -19,7 +19,7 @@ mksrf_fvocef_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' mksrf_furbtopo = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_topo.10min.cdf5.c220201.nc' mksrf_furbtopo_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_c200129.nc' - mksrf_fglacier = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000.c120926.nc' + mksrf_fglacier = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000.cdf5.c120926.nc' mksrf_fglacier_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' mksrf_fglacierregion = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_GlacierRegion_10x10min_nomask_cd5_c220131.nc' mksrf_fglacierregion_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_cdf5_c200129.nc' diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index a26b58aa72..2dc2c69882 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -21,6 +21,7 @@ set(SRCFILES mkvarctl.F90 mkpioMod.F90 mkfileMod.F90 mkglacierregionMod.F90 + mkglcmecMod.F90 mklanwatMod.F90 mkorganicMod.F90 mksoilcolMod.F90 diff --git a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 index 2086f5dc10..bc93fdb8e7 100644 --- a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 +++ b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 @@ -1,270 +1,257 @@ module mkagfirepkmonthMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkagfirepkmonthMod -! -! !DESCRIPTION: -! Make agricultural fire peak month data -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -!----------------------------------------------------------------------- -!!USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkdomainMod , only : domain_checksame - implicit none - SAVE + !----------------------------------------------------------------------- + ! Make agricultural fire peak month data + !----------------------------------------------------------------------- + + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkpioMod , only : mkpio_iodesc_rawdata, mkpio_get_rawdata_level + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkutilsMod , only : chkerr + use mkvarctl , only : ndiag, root_task, outnc_3dglc + use mkvarpar , only : re + + implicit none private ! By default make data private -! -! !PUBLIC MEMBER FUNCTIONS: -! - public mkagfirepkmon ! Set agricultural fire peak month -! -! !PRIVATE MEMBER FUNCTIONS: - private define_months ! define month strings -! -! !PRIVATE DATA MEMBERS: -! + + public :: mkagfirepkmon ! Set agricultural fire peak month + private :: define_months ! define month strings + integer , parameter :: min_valid_value = 1 integer , parameter :: max_valid_value = 12 integer , parameter :: unsetmon = 13 ! flag to indicate agricultural fire peak month NOT set -! -! !PRIVATE DATA MEMBERS: -! -!EOP + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + !=============================================================== contains !=============================================================== -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkagfirepkmon -! -! !INTERFACE: -subroutine mkagfirepkmon(ldomain, mapfname, datfname, ndiag, & - agfirepkmon_o) -! -! !DESCRIPTION: -! Make agricultural fire peak month data from higher resolution data -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkindexmapMod, only : get_dominant_indices - use mkvarpar, only : re - use mkncdio - use mkchecksMod, only : min_bad, max_bad -! -! !ARGUMENTS: - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - integer , intent(out):: agfirepkmon_o(:) ! agricultural fire peak month -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: gast_i(:) ! global area, by surface type - real(r8), allocatable :: gast_o(:) ! global area, by surface type - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer , allocatable :: agfirepkmon_i(:) ! input grid: agricultural fire peak month - integer :: nagfirepkmon ! number of peak months - character(len=35), allocatable :: month(:)! name of each month - integer :: k,ni,no,ns_i,ns_o ! indices - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - - integer, parameter :: miss = unsetmon ! missing data indicator - integer, parameter :: min_valid = 1 ! minimum valid value - integer, parameter :: max_valid = 13 ! maximum valid value - character(len=32) :: subname = 'mkagfirepkmon' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make agricultural fire peak month data .....' - - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - call domain_read( tdomain,datfname ) - - call gridmap_mapread( tgridmap, mapfname ) - - ! Obtain frac_dst - ns_o = ldomain%ns - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ns_i = tdomain%ns - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write (6,*) 'Open agricultural fire peak month file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(agfirepkmon_i(ns_i), stat=ier) - if (ier/=0) call abort() - - ! ----------------------------------------------------------------- - ! Regrid ag fire peak month - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'abm', varid), subname) - call check_ret(nf_get_var_int (ncid, varid, agfirepkmon_i), subname) - ! Note that any input point that is outside the range [min_valid_value,max_valid_value] - ! will be ignored; this ignores input points with value of unsetmon - call get_dominant_indices(tgridmap, agfirepkmon_i, agfirepkmon_o, & - min_valid_value, max_valid_value, miss, mask_src=tdomain%mask) - - ! Check validity of output data - if (min_bad(agfirepkmon_o, min_valid, 'agfirepkmon') .or. & - max_bad(agfirepkmon_o, max_valid, 'agfirepkmon')) then - call abort() - end if - - - ! ----------------------------------------------------------------- - ! Output diagnostics comparing global area of each peak month on input and output grids - ! - ! WJS (3-4-13): I am trying to generally put these diagnostics in mkdiagnosticsMod, but - ! so far there isn't a general diagnostics routine for categorical data - ! - ! TODO(wjs, 2016-01-22) Now there is a routine for this: output_diagnostics_index. - ! However, it currently doesn't provide the capability for named months. Either add - ! that capability or decide it's not important, then delete the below code, instead - ! calling output_diagnostics_index. - ! ----------------------------------------------------------------- - - nagfirepkmon = maxval(agfirepkmon_i) - allocate(gast_i(1:nagfirepkmon),gast_o(1:nagfirepkmon),month(1:nagfirepkmon)) - call define_months(nagfirepkmon, month) - - gast_i(:) = 0.0_r8 - do ni = 1,ns_i - k = agfirepkmon_i(ni) - gast_i(k) = gast_i(k) + tgridmap%area_src(ni)*tdomain%mask(ni)*re**2 - end do - - gast_o(:) = 0.0_r8 - do no = 1,ns_o - k = agfirepkmon_o(no) - gast_o(k) = gast_o(k) + tgridmap%area_dst(no)*frac_dst(no)*re**2 - end do - - ! area comparison - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Agricultural fire peak month Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,1001) + subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) + ! + ! Make agricultural fire peak month data from higher resolution data + ! + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + integer , intent(out) :: agfirepkmon_o(:) ! agricultural fire peak month + integer , intent(out) :: rc + ! + ! local variables: + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + integer :: ni,no,k + integer :: ns_i, ns_o + integer , allocatable :: mask_i(:) + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + real(r8), allocatable :: gast_i(:) ! global area, by surface type + real(r8), allocatable :: gast_o(:) ! global area, by surface type + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r4), allocatable :: data_i(:,:) + real(r4), allocatable :: data_o(:,:) + integer , allocatable :: agfirepkmon_i(:) ! input grid: agricultural fire peak month + integer :: nagfirepkmon ! number of peak months + character(len=35), allocatable :: month(:) ! name of each month + integer :: rcode, ier ! error status + integer, parameter :: miss = unsetmon ! missing data indicator + integer, parameter :: min_valid = 1 ! minimum valid value + integer, parameter :: max_valid = 13 ! maximum valid value + character(len=*), parameter :: subname = 'mkagfirepkmon' + !----------------------------------------------------------------------- + + if (root_task) then + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make agricultural fire peak month data .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) + end if + + ! Open input data file + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) + + ! Read in input mesh + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Determine ns_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the landmask from the file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" ERROR in allocating frac_i") + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" ERROR in allocating mask_i") + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (frac_i(ni) > 0._r4) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Read in agfirepkmon_i + allocate(agfirepkmon_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" error in allocating agfirepkmon_i") + call mkpio_get_rawdata(pioid, 'abm', mesh_i, agfirepkmon_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + + ! Create a route handle between the input and output mesh and get frac_o + allocate(frac_o(ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + + ! Now determine data_i as a real 2d array - for every possible soil color create a global + ! field with gridcells equal to 1 for that soil color and zero elsewhere + allocate(data_i(min_valid_value:max_valid_value,ns_i)) + data_i(:,:) = 0._r4 + do l = min_valid_value,max_valid_value + do n = 1,ns_i + if (int(soil_color_i(n)) == l) then + data_i(l,n) = 1._r4 * mask_i(n) + end if + end do + end do + + ! Regrid data_i to data_o + allocate(data_o(0:nsoilcol, ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, nsoilcol, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite(subname//'after regrid rawdata in '//trim(subname)) + + + + + ! Note that any input point that is outside the range [min_valid_value,max_valid_value] + ! will be ignored; this ignores input points with value of unsetmon + call get_dominant_indices(tgridmap, agfirepkmon_i, agfirepkmon_o, & + min_valid_value, max_valid_value, miss, mask_src=tdomain%mask) + + ! Check validity of output data + if (min_bad(agfirepkmon_o, min_valid, 'agfirepkmon') .or. & + max_bad(agfirepkmon_o, max_valid, 'agfirepkmon')) then + call shr_sys_abort() + end if + + ! ----------------------------------------------------------------- + ! Output diagnostics comparing global area of each peak month on input and output grids + ! + ! WJS (3-4-13): I am trying to generally put these diagnostics in mkdiagnosticsMod, but + ! so far there isn't a general diagnostics routine for categorical data + ! + ! TODO(wjs, 2016-01-22) Now there is a routine for this: output_diagnostics_index. + ! However, it currently doesn't provide the capability for named months. Either add + ! that capability or decide it's not important, then delete the below code, instead + ! calling output_diagnostics_index. + ! ----------------------------------------------------------------- + + nagfirepkmon = maxval(agfirepkmon_i) + allocate(gast_i(1:nagfirepkmon),gast_o(1:nagfirepkmon),month(1:nagfirepkmon)) + call define_months(nagfirepkmon, month) + + gast_i(:) = 0.0_r8 + do ni = 1,ns_i + k = agfirepkmon_i(ni) + gast_i(k) = gast_i(k) + area_src(ni)*mask(ni)*re**2 + end do + gast_o(:) = 0.0_r8 + do no = 1,ns_o + k = agfirepkmon_o(no) + gast_o(k) = gast_o(k) + area_dst(no)*frac_dst(no)*re**2 + end do + + ! area comparison + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'Agricultural fire peak month Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,1001) 1001 format (1x,'peak month',20x,' input grid area output grid area',/ & - 1x,33x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - - do k = 1, nagfirepkmon - write (ndiag,1002) month(k),gast_i(k)*1.e-6,gast_o(k)*1.e-6 -1002 format (1x,a35,f16.3,f17.3) - end do - - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- - - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (agfirepkmon_i,gast_i,gast_o,month, frac_dst, mask_r8) - - write (6,*) 'Successfully made Agricultural fire peak month' - write (6,*) - -end subroutine mkagfirepkmon - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: define_months -! -! !INTERFACE: -subroutine define_months(nagfirepkmon, month) -! -! !DESCRIPTION: -! Define month strings -! -! !USES: -! -! !ARGUMENTS: - implicit none - integer , intent(in) :: nagfirepkmon ! max input value (including the 'unset' special value) - character(len=*), intent(out):: month(:) ! name of each month value -! -! !CALLED FROM: -! subroutine mkagfirepkmon -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP -!----------------------------------------------------------------------- - - if (nagfirepkmon == unsetmon) then - if (size(month) < 13) then - write(6,*) 'month array too small: ', size(month), ' < 13' - call abort() - end if - month(1) = 'January ' - month(2) = 'February ' - month(3) = 'March ' - month(4) = 'April ' - month(5) = 'May ' - month(6) = 'June ' - month(7) = 'July ' - month(8) = 'August ' - month(9) = 'September ' - month(10) = 'October ' - month(11) = 'November ' - month(12) = 'December ' - month(13) = 'no agricultural fire peak month data' - else - write(6,*)'nagfirepkmon value of ',nagfirepkmon,' not supported' - call abort() - end if - -end subroutine define_months -!----------------------------------------------------------------------- - + 1x,33x,' 10**6 km**2',' 10**6 km**2') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + + do k = 1, nagfirepkmon + write (ndiag,1002) month(k),gast_i(k)*1.e-6,gast_o(k)*1.e-6 +1002 format (1x,a35,f16.3,f17.3) + end do + + ! ----------------------------------------------------------------- + ! Close files and deallocate dynamic memory + ! ----------------------------------------------------------------- + + call check_ret(nf_close(ncid), subname) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (agfirepkmon_i,gast_i,gast_o,month, frac_dst, mask_r8) + + write (6,*) 'Successfully made Agricultural fire peak month' + write (6,*) + + end subroutine mkagfirepkmon + + !=============================================================== + subroutine define_months(nagfirepkmon, month) + ! + ! Define month strings + ! + ! input/output variables + integer , intent(in) :: nagfirepkmon ! max input value (including the 'unset' special value) + character(len=*), intent(out):: month(:) ! name of each month value + !----------------------------------------------------------------------- + + if (nagfirepkmon == unsetmon) then + if (size(month) < 13) then + write(6,*) 'month array too small: ', size(month), ' < 13' + call shr_sys_abort() + end if + month(1) = 'January ' + month(2) = 'February ' + month(3) = 'March ' + month(4) = 'April ' + month(5) = 'May ' + month(6) = 'June ' + month(7) = 'July ' + month(8) = 'August ' + month(9) = 'September ' + month(10) = 'October ' + month(11) = 'November ' + month(12) = 'December ' + month(13) = 'no agricultural fire peak month data' + else + write(6,*)'nagfirepkmon value of ',nagfirepkmon,' not supported' + call shr_sys_abort() + end if + + end subroutine define_months end module mkagfirepkmonthMod diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 70ef4343b0..3ddc952c73 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -7,9 +7,9 @@ module mkfileMod use mkutilsMod , only : get_filename, chkerr use mkvarpar , only : nlevsoi, numrad, numstdpft use mkurbanparMod, only : numurbl, nlevurb, mkurbanpar + use mkglcmecMod , only : nglcec #ifdef TODO use mkpftMod , only : mkpftAtt - use mkglcmecMod , only : nglcec use mkharvestMod , only : mkharvest_fieldname, mkharvest_numtypes, mkharvest_longname, mkharvest_units, harvestDataType #endif use mkpioMod ! TODO: add only @@ -37,7 +37,9 @@ module mkfileMod subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & pctlak, pctwet, lakedepth, organic, soil_color, nsoilcol, & urban_classes_g, urban_region, pctsand, pctclay, mapunits, fmaxsoil, soildepth, & - glacier_region, ef_btr, ef_fet, ef_fdt, ef_shr, ef_grs, ef_crp, rc) + glacier_region, ef_btr, ef_fet, ef_fdt, ef_shr, ef_grs, ef_crp, & + pctgla, pctglcmec, topoglcmec, pctglcmec_gic, pctglcmec_icesheet, pctglc_gic, & + pctglc_icesheet, rc) ! input/output variables integer , intent(in) :: nx @@ -64,6 +66,13 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & real(r8) , intent(in) :: ef_shr(:) real(r8) , intent(in) :: ef_grs(:) real(r8) , intent(in) :: ef_crp(:) + real(r8) , intent(in) :: pctgla(:) + real(r8) , intent(in) :: pctglcmec(:,:) + real(r8) , intent(in) :: topoglcmec(:,:) + real(r8) , intent(in) :: pctglcmec_gic(:,:) + real(r8) , intent(in) :: pctglcmec_icesheet(:,:) + real(r8) , intent(in) :: pctglc_gic(:) + real(r8) , intent(in) :: pctglc_icesheet(:) integer , intent(out):: rc #ifdef TODO type(harvestDataType) , intent(in) :: harvdata @@ -123,6 +132,46 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & if (.not. dynlanduse) then + ! TODO: implement this with pio + ! call ncd_defvar(ncid=ncid, 'GLC_MEC', xtype=xtype, & + ! dim1name='nglcecp1', long_name='Glacier elevation class', units='m') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glacier" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLACIER', 'percent glacier', 'unitless', & + pctgla, rc=rc) + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLC_MEC', & + 'percent glacier for each glacier elevation class (% of landunit)', 'unitless', & + pctglcmec, lev1name='nglcec', rc=rc) + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out topo_glc_mec" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'TOPO_GLC_MEC', & + 'mean elevation on glacier elevation classes', 'm', & + topoglcmec, lev1name='nglcec', rc=rc) + + if ( outnc_3dglc ) then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec_gic" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLC_MEC_GIC', & + 'percent smaller glaciers and ice caps for each glacier elevation class (% of landunit)', 'unitless', & + pctglcmec_gic, lev1name='nglcec', rc=rc) + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec_icesheet" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLC_MEC_ICESHEET', & + 'percent ice sheet for each glacier elevation class (% of landunit)', 'unitless', & + pctglcmec_icesheet, lev1name='nglcec', rc=rc) + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_gic" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLC_GIC', & + 'percent ice caps/glaciers (% of landunit)', 'unitless', & + pctglc_gic, rc=rc) + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_icesheet" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLC_ICESHEET', & + 'percent ice sheet (% of landunit)', 'unitless', & + pctglc_icesheet, rc=rc) + end if + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_lake" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_LAKE', 'percent_lake', & 'unitless', pctlak, rc=rc) @@ -220,13 +269,13 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & urban_skip_abort_on_invalid_data_check) ! ---------------------------------------------------------------------- - ! Make LAI and SAI from 1/2 degree data and write to surface dataset + ! Make LAI and SAI from 1/2 degree data and write to surface dataset ! Write to netcdf file is done inside mklai routine ! ---------------------------------------------------------------------- ! if (root_task) then ! write(ndiag,'(a)')'calling mklai' ! end if - ! call mklai(mksrf_lai, mksrf_lai_mesh, pioid, mesh_o, rc=rc) + ! call mklai(mksrf_lai, mksrf_lai_mesh, pioid, mesh_o, rc=rc) ! if (ChkErr(rc,__LINE__,u_FILE_u)) return ! ---------------------------------------------------------------------- @@ -258,17 +307,17 @@ end subroutine mkfile_fsurdat !================================================================================= subroutine mkfile_define_dims(pioid, nx, ny, dynlanduse) - + ! ! Define dimensions. - + ! ! input/output variables type(file_desc_t) , intent(in) :: pioid integer , intent(in) :: nx, ny logical , intent(in) :: dynlanduse ! local variables - integer :: dimid ! temporary - integer :: rcode + integer :: dimid ! temporary + integer :: rcode ! error status character(len=*), parameter :: subname = 'mkfile_define_dims' !----------------------------------------------------------------------- @@ -283,15 +332,12 @@ subroutine mkfile_define_dims(pioid, nx, ny, dynlanduse) rcode = pio_def_dim(pioid, 'nlevsoi', nlevsoi , dimid) rcode = pio_def_dim(pioid, 'nlevurb', nlevurb , dimid) rcode = pio_def_dim(pioid, 'numurbl', numurbl , dimid) - -#ifdef TODO - rcode = pio_def_dim(pioid, 'time' , PIO_UNLIMITED , dimid) - rcode = pio_def_dim(pioid, 'nchar' , 256 , dimid) if (.not. dynlanduse) then - rcode = pio_def_dim(pioid, 'nglcec', nglcec, dimid) + rcode = pio_def_dim(pioid, 'nglcec' , nglcec , dimid) rcode = pio_def_dim(pioid, 'nglcecp1', nglcec+1, dimid) end if -#endif + rcode = pio_def_dim(pioid, 'time' , PIO_UNLIMITED , dimid) + rcode = pio_def_dim(pioid, 'nchar' , 256 , dimid) end subroutine mkfile_define_dims diff --git a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 index e6948d5bfc..6ecdb290a3 100644 --- a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 @@ -10,9 +10,11 @@ module mkglcmecMod use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkpioMod , only : mkpio_iodesc_rawdata, mkpio_get_rawdata_level use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas use mkutilsMod , only : chkerr - use mkvarctl , only : ndiag, root_task + use mkvarctl , only : ndiag, root_task, outnc_3dglc + use mkvarpar implicit none private ! By default make data private @@ -20,12 +22,16 @@ module mkglcmecMod public :: mkglcmecInit ! Initialization public :: mkglcmec ! Set glacier multi-elevation class public :: mkglacier ! Set percent glacier + private :: get_elevclass ! get elevation class index private :: mean_elevation_vc ! get the elevation of a virtual column integer, public :: nglcec = 10 ! number of elevation classes for glaciers real(r8), allocatable :: elevclass(:) ! elevation classes + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + !================================================================================= contains !================================================================================= @@ -37,8 +43,8 @@ subroutine mkglcmecInit( elevclass_o ) ! input/output variables real(r8), intent(out) :: elevclass_o(:) ! elevation classes - ! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'mkglcmecInit:: ' + ! local variables: + character(len=*), parameter :: subname = 'mkglcmecInit' !----------------------------------------------------------------------- allocate( elevclass(nglcec+1) ) @@ -82,7 +88,7 @@ subroutine mkglcmecInit( elevclass_o ) elevclass(1) = 0. elevclass(2) = 10000. else - write(6,*) subname//"ERROR:: nglcec must be 1, 3, 5, 10 or 36",& + write(6,*) subname//"error:: nglcec must be 1, 3, 5, 10 or 36",& " to work with CLM: " call shr_sys_abort() end if @@ -92,16 +98,13 @@ subroutine mkglcmecInit( elevclass_o ) end subroutine mkglcmecInit !================================================================================= - subroutine mkglcmec(ldomain, mapfname, & - datfname_fglacier, ndiag, & - pctglcmec_o, topoglcmec_o, & - pctglcmec_gic_o, pctglcmec_icesheet_o, & - pctglc_gic_o, pctglc_icesheet_o) + subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & + pctglcmec_o, topoglcmec_o, pctglcmec_gic_o, pctglcmec_icesheet_o, & + pctglc_gic_o, pctglc_icesheet_o, rc) ! - ! !DESCRIPTION: ! make percent glacier on multiple elevation classes, mean elevation for each ! elevation class, and associated fields - ! + ! ! Note that the raw glacier data are specified by level, and thus implicitly include the ! necessary topo data for breaking pct glacier into elevation classes. Each level in the ! input data is assigned to an elevation (given by BIN_CENTERS in the input data). Thus, @@ -114,194 +117,217 @@ subroutine mkglcmec(ldomain, mapfname, & ! If the input glacier area is 0 for a given grid cell, this requires setting these % ! variables in an arbitrary way. ! - ! !USES: - use mkvarpar use mkutilsMod, only : slightly_below, slightly_above - use mkvarctl , only : outnc_3dglc - ! - ! !ARGUMENTS: - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname_fglacier ! raw glacier data - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: pctglcmec_o (:,:) ! % for each elevation class on output glacier grid (% of landunit) - real(r8) , intent(out):: topoglcmec_o(:,:) ! mean elevation for each elevation classs on output glacier grid - real(r8), optional, intent(out):: pctglcmec_gic_o(:,:) ! % glc gic on output grid, by elevation class (% of landunit) - real(r8), optional, intent(out):: pctglcmec_icesheet_o(:,:) ! % glc ice sheet on output grid, by elevation class (% of landunit) - real(r8), optional, intent(out):: pctglc_gic_o(:) ! % glc gic on output grid, summed across elevation classes (% of landunit) - real(r8), optional, intent(out):: pctglc_icesheet_o(:) ! % glc ice sheet on output grid, summed across elevation classes (% of landunit) ! + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + real(r8) , intent(out) :: pctglcmec_o (:,:) ! % for each elevation class on output glacier grid (% of landunit) + real(r8) , intent(out) :: topoglcmec_o(:,:) ! mean elevation for each elevation classs on output glacier grid + real(r8), optional , intent(out) :: pctglcmec_gic_o(:,:) ! % glc gic on output grid, by elevation class (% of landunit) + real(r8), optional , intent(out) :: pctglcmec_icesheet_o(:,:) ! % glc ice sheet on output grid, by elevation class (% of landunit) + real(r8), optional , intent(out) :: pctglc_gic_o(:) ! % glc gic on output grid, summed across elevation classes (% of landunit) + real(r8), optional , intent(out) :: pctglc_icesheet_o(:) ! % glc ice sheet on output grid, summed across elevation classes (% of landunit) + integer , intent(out) :: rc + ! local variables: - real(r8), allocatable :: pctglc_gic_i(:) ! input GIC percentage for a single level - real(r8), allocatable :: pctglc_icesheet_i(:) ! input icesheet percentage for a single level - real(r8), allocatable :: topoglcmec_unnorm_o(:,:) ! same as topoglcmec_o, but unnormalized - real(r8), allocatable :: pctglc_tot_o(:) ! total glacier cover for the grid cell - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8) :: topoice_i ! topographic height of this level - real(r8) :: pctglc_i ! input total pct glacier for a single level & single point - real(r8) :: wt, frac ! weighting factors for remapping - integer :: ndims ! number of dimensions in input variables - integer :: dim_lengths(nf_max_var_dims) ! lengths of dimensions in input variables - integer, allocatable :: starts(:), counts(:) ! start indices & counts for reading variable slices - integer :: ni,no,ns_o,nst,lev ! indices - integer :: n,m ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: nlev ! number of levels in input file - real(r8) :: glc_sum ! temporary - integer :: ier ! error status - logical :: errors ! error status - - real(r8), parameter :: eps = 2.e-5_r8 ! epsilon for error checks (note that we use a large-ish value - ! because data are stored as single-precision floats in the raw dataset) - real(r8), parameter :: eps_small = 1.e-12_r8 ! epsilon for error checks that expect close match - character(len=32) :: subname = 'mkglcmec' + type(ESMF_RouteHandle) :: routehandle ! nearest neighbor routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + type(var_desc_t) :: pio_varid + type(io_desc_t) :: pio_iodesc + integer :: pio_vartype + integer :: ni,no,lev + integer :: ns_i, ns_o + integer :: n,m ! indices + integer :: dimid ! dimension ids + integer :: ndims ! number of dimensions in input variables + integer :: nlev ! number of levels in input file + integer , allocatable :: mask_i(:) + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + real(r8), allocatable :: data_pctglc_i(:) + real(r8), allocatable :: data_pctglc_o(:) + real(r8), allocatable :: data_pctglc_icesheet_i(:) ! input icesheet percentage + real(r8), allocatable :: data_pctglc_icesheet_o(:) ! input icesheet percentage + real(r8), allocatable :: data_pctglc_gic_i(:) + real(r8), allocatable :: data_pctglc_gic_o(:) + real(r8), allocatable :: topoglcmec_unnorm_o(:,:) ! same as topoglcmec_o, but unnormalized + real(r8), allocatable :: pctglc_tot_o(:) ! total glacier cover for the grid cell + real(r4), allocatable :: topoice_i(:) ! topographic height of this level + integer :: unlimited_index ! z level + real(r8) :: glc_sum ! temporary + integer :: ier, rcode ! error status + logical :: errors ! error status + + real(r8), parameter :: eps = 2.e-5_r8 ! epsilon for error checks (note that we use a large-ish value + ! because data are stored as single-precision floats in the raw dataset) + real(r8), parameter :: eps_small = 1.e-12_r8 ! epsilon for error checks that expect close match + character(len=*), parameter :: subname = 'mkglcmec' !----------------------------------------------------------------------- - ! Initialize all output fields to zero + rc = ESMF_SUCCESS + + if (root_task) then + write(ndiag,*) + write (ndiag,'(a)') 'Attempting to make percent elevation class ',& + 'and mean elevation for glaciers .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) + end if - pctglcmec_o(:,:) = 0. - topoglcmec_o(:,:) = 0. + ! Initialize all output fields to zero + pctglcmec_o(:,:) = 0. + topoglcmec_o(:,:) = 0. if ( outnc_3dglc )then if ( (.not. present(pctglcmec_gic_o)) .or. (.not. present(pctglcmec_icesheet_o)) .or. & (.not. present(pctglc_gic_o) ) .or. (.not. present(pctglc_icesheet_o) ) )then - call shr_sys_abort( subname//' ERROR: 3D glacier fields were NOT sent in and they are required' ) + call shr_sys_abort( subname//' error: 3D glacier fields were NOT sent in and they are required' ) end if - pctglcmec_gic_o(:,:) = 0. + pctglcmec_gic_o(:,:) = 0. pctglcmec_icesheet_o(:,:) = 0. - pctglc_gic_o(:) = 0. - pctglc_icesheet_o(:) = 0. - end if - - ! Set number of output points - - ns_o = ldomain%ns - - write (6,*) 'Attempting to make percent elevation class ',& - 'and mean elevation for glaciers .....' - - ! ----------------------------------------------------------------- - ! Read domain and dimension information from glacier raw data file - ! ----------------------------------------------------------------- - - call domain_read(tdomain,datfname_fglacier) - nst = tdomain%ns - - ! Read z dimension size - write (6,*) 'Open glacier file: ', trim(datfname_fglacier) - call check_ret(nf_open(datfname_fglacier, 0, ncid), subname) - ier = nf_inq_dimid (ncid, 'z', dimid) - if (ier /= NF_NOERR) then - write (6,*) trim(subname), ' ERROR: z dimension not found on glacier file:' - write (6,*) trim(datfname_fglacier) - write (6,*) 'Perhaps you are trying to use an old-format glacier file?' - write (6,*) '(prior to Sept., 2012)' - call shr_sys_abort() + pctglc_gic_o(:) = 0. + pctglc_icesheet_o(:) = 0. end if - call check_ret(nf_inq_dimlen (ncid, dimid, nlev), subname) - - ! ----------------------------------------------------------------- - ! Read mapping data, check for consistency with domains - ! ----------------------------------------------------------------- - - ! Mapping for raw glacier -> model output grid - call gridmap_mapread(tgridmap, mapfname ) - ! Error checks for domain and map consistencies - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Determine dimension lengths and create start & count arrays - ! for later reading one level at a time - ! ----------------------------------------------------------------- - - call get_dim_lengths(ncid, 'PCT_GLC_GIC', ndims, dim_lengths) - - allocate(starts(ndims), counts(ndims), stat=ier) - if (ier/=0) call shr_sys_abort() - - starts(1:ndims) = 1 + ! Open input data file + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) + + ! Read in input mesh + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Determine ns_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the landmask from the file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" error in allocating frac_i") + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" error in allocating mask_i") + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (frac_i(ni) > 0._r8) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Read in BIN_CENTERS on all tasks and check validity + rcode = pio_inq_dimid (pioid, 'z', dimid) + rcode = pio_inq_dimlen(pioid, dimid, nlev) + ! TODO: hard-wiring topoice to be r4 - this needs to be generalized to query the variable type + ! on the netcdf file + allocate(topoice_i(nlev)) + rcode = pio_inq_varid (pioid, 'BIN_CENTERS', pio_varid) + rcode = pio_get_var(pioid, pio_varid, topoice_i) + do lev = 1,nlev + m = get_elevclass(topoice_i(lev)) + if (m < 1 .or. m > nglcec) then + call shr_sys_abort(subname//" error m<1 or m > nglcec") + end if + end do - ! We assume that the last dimension is the level dimension - counts(1:ndims-1) = dim_lengths(1:ndims-1) - counts(ndims) = 1 + ! Allocate memory for reading in one level at a time + allocate(data_pctglc_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" error in allocating data_pctglc_i") + allocate(data_pctglc_o(ns_o), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" error in allocating data_pctglc_o") - ! -------------------------------------------------------------------- - ! Compute fields on the output grid - ! -------------------------------------------------------------------- + allocate(data_pctglc_gic_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" error in allocating data_pctglc_gic_i") + allocate(data_pctglc_gic_o(ns_o), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" error in allocating data_pctglc_gic_o") - allocate(pctglc_gic_i(nst), pctglc_icesheet_i(nst), stat=ier) - if (ier/=0) call shr_sys_abort() + allocate(data_pctglc_icesheet_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" error in allocating data_pctglc_icesheet_i") + allocate(data_pctglc_icesheet_o(ns_o), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" error in allocating data_pctglc_icesheet_o") allocate(topoglcmec_unnorm_o(ns_o,nglcec), stat=ier) - if (ier/=0) call shr_sys_abort() - - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call shr_sys_abort() - + if (ier/=0) call shr_sys_abort(subname//" error in allocating topoglcmec_unnorm_o") topoglcmec_unnorm_o(:,:) = 0. - write(6,'(a,i4,a)',advance='no') 'Level (out of ', nlev, '): ' + ! Create iodescriptor for a single level of the input data + call mkpio_iodesc_rawdata(mesh_i, 'PCT_GLC_GIC', pioid, pio_varid, pio_vartype, pio_iodesc, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + ! Create a route handle between the input and output mesh and get frac_o + allocate(frac_o(ns_o),stat=ier) + if (ier/=0) call shr_sys_abort(subname//" error in allocating frac_o") + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + ! Compute pctglcmec_gic_o, pctglcmec_gic_o, pctglcmec_icesheet_o and topoglcmec_unnorm_o + ! Note that topoglcmec_unnorm_o is the average topographic height over glaciated areas - + ! NOT the average topographic height of the entire grid cell do lev = 1, nlev write(6,'(i4)',advance='no') lev - ! Read this level's data - ! We assume that the last dimension is the level dimension - starts(ndims) = lev - call check_ret(nf_inq_varid (ncid, 'BIN_CENTERS', varid), subname) - call check_ret(nf_get_vara_double (ncid, varid, (/lev/), (/1/), topoice_i), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_GLC_GIC', varid), subname) - call check_ret(nf_get_vara_double (ncid, varid, starts, counts, pctglc_gic_i), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_GLC_ICESHEET', varid), subname) - call check_ret(nf_get_vara_double (ncid, varid, starts, counts, pctglc_icesheet_i), subname) - - ! Determine elevation class - m = get_elevclass(topoice_i) - if (m < 1 .or. m > nglcec) then - call shr_sys_abort() - end if - - do n = 1,tgridmap%ns - ni = tgridmap%src_indx(n) - no = tgridmap%dst_indx(n) - wt = tgridmap%wovr(n) * tdomain%mask(ni) - - ! fraction of this destination cell that is covered by source cells that are within the source landmask - frac = frac_dst(no) - - ! If frac == 0, then we can't do this, to avoid divide by 0. In this case, the - ! outputs remain equal to 0 (their initialized value). - if (frac > 0) then - pctglc_i = pctglc_gic_i(ni) + pctglc_icesheet_i(ni) - pctglcmec_o(no,m) = pctglcmec_o(no,m) + wt*pctglc_i / frac - if ( outnc_3dglc )then - pctglcmec_gic_o(no,m) = pctglcmec_gic_o(no,m) + wt*pctglc_gic_i(ni) / frac - pctglcmec_icesheet_o(no,m) = pctglcmec_icesheet_o(no,m) + wt*pctglc_icesheet_i(ni) / frac - end if - - ! note that, by weighting the following by pctglc_i, we are getting something - ! like the average topographic height over glaciated areas - NOT the average - ! topographic height of the entire grid cell - topoglcmec_unnorm_o(no,m) = topoglcmec_unnorm_o(no,m) + wt*pctglc_i*topoice_i / frac + call ESMF_LogWrite("DEBUG here0") + ! Read in one level of data + rcode = pio_inq_varid(pioid, 'PCT_GLC_GIC', pio_varid) + call pio_setframe(pioid, pio_varid, int(lev,kind=Pio_Offset_Kind)) + call mkpio_get_rawdata_level(pioid, pio_iodesc, lev, 'PCT_GLC_GIC', data_pctglc_gic_i) + + rcode = pio_inq_varid(pioid, 'PCT_GLC_ICESHEET', pio_varid) + call pio_setframe(pioid, pio_varid, int(lev,kind=Pio_Offset_Kind)) + call mkpio_get_rawdata_level(pioid, pio_iodesc, lev, 'PCT_GLC_ICESHEET', data_pctglc_icesheet_i) + + ! Compute derived input data + data_pctglc_i(:) = data_pctglc_gic_i(:) + data_pctglc_icesheet_i(:) + + ! Map level of data to output grid + call ESMF_LogWrite("DEBUG here1") + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_pctglc_i, data_pctglc_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_pctglc_gic_i, data_pctglc_gic_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_pctglc_icesheet_i, data_pctglc_icesheet_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite("DEBUG here2") + + ! Compute output variables + m = get_elevclass(topoice_i(lev)) + write(6,*)'DEBUG: m= ',m + do no = 1,ns_o + pctglcmec_o(no,m) = pctglcmec_o(no,m) + data_pctglc_o(no) + if (outnc_3dglc) then + pctglcmec_gic_o(no,m) = pctglcmec_gic_o(no,m) + data_pctglc_gic_o(no) + pctglcmec_icesheet_o(no,m) = pctglcmec_icesheet_o(no,m) + data_pctglc_icesheet_o(no) end if + topoglcmec_unnorm_o(no,m) = topoglcmec_unnorm_o(no,m) + data_pctglc_o(no)*topoice_i(lev) end do + call ESMF_LogWrite("DEBUG here4") end do - ! Note: at this point, the various percentages are given as % of grid cell; below, we - ! renormalize these to be given as % of landunit. - - ! advance to next line (needed because of 'advance=no' writes above) - write(6,*) ' ' - ! Close glacier input file - call check_ret(nf_close(ncid), subname) + call pio_closefile(pioid) + call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) + + ! At this point, the various percentages are given as % of grid cell. + ! We now renormalize these to be given as % of landunit. ! Normalize topoglcmec_o. To do this, note that pctglcmec_o(n,m) is equal to the sum of - ! the weights used in doing the weighted average of topoice_i (weight = - ! wt*pctglc_i/frac); hence pctglcmec_o(n,m) is the correct normalization factor + ! the weights used in doing the weighted average of topoice_i (weight = wt*pctglc_i/frac); + ! hence pctglcmec_o(n,m) is the correct normalization factor do no = 1,ns_o do m = 1,nglcec if (pctglcmec_o(no,m) > 0) then @@ -327,25 +353,21 @@ subroutine mkglcmec(ldomain, mapfname, & end do ! Renormalize percentages to be given as % of landunit rather than % of grid cell. - allocate(pctglc_tot_o(ns_o), stat=ier) - if (ier/=0) call shr_sys_abort() - + if (ier/=0) call shr_sys_abort(subname//" error in allocating pctglc_tot") do no = 1,ns_o pctglc_tot_o(no) = sum(pctglcmec_o(no,:)) - if (pctglc_tot_o(no) > 0._r8) then - pctglcmec_o(no,:) = pctglcmec_o(no,:) / pctglc_tot_o(no) * 100._r8 + pctglcmec_o(no,:) = pctglcmec_o(no,:) / pctglc_tot_o(no) * 100._r8 if ( outnc_3dglc )then - pctglcmec_gic_o(no,:) = pctglcmec_gic_o(no,:) / pctglc_tot_o(no) * 100._r8 + pctglcmec_gic_o(no,:) = pctglcmec_gic_o(no,:) / pctglc_tot_o(no) * 100._r8 pctglcmec_icesheet_o(no,:) = pctglcmec_icesheet_o(no,:) / pctglc_tot_o(no) * 100._r8 end if - else ! Division of landunit is ambiguous. Apply the rule that all area is assigned to ! the lowest elevation class, and all GIC. pctglcmec_o(no,1) = 100._r8 - if ( outnc_3dglc )then + if ( outnc_3dglc ) then pctglcmec_gic_o(no,1) = 100._r8 end if end if @@ -357,13 +379,12 @@ subroutine mkglcmec(ldomain, mapfname, & pctglc_icesheet_o = sum(pctglcmec_icesheet_o, dim=2) end if - ! -------------------------------------------------------------------- + ! -------------------------------------------------------------------- ! Perform various sanity checks - ! -------------------------------------------------------------------- - - errors = .false. + ! -------------------------------------------------------------------- ! Confirm that the sum over pctglcmec_o (from 1 to nglcec) is 100% + errors = .false. do no = 1,ns_o glc_sum = sum(pctglcmec_o(no,:)) if (abs(glc_sum - 100._r8) > eps_small) then @@ -376,10 +397,10 @@ subroutine mkglcmec(ldomain, mapfname, & if ( outnc_3dglc )then do no = 1,ns_o if (abs((pctglc_gic_o(no) + pctglc_icesheet_o(no)) - 100._r8) > eps) then - write(6,*)'GIC + ICESHEET differs from 100% at no,pctglc_gic,pctglc_icesheet,lon,lat=', & - no,pctglc_gic_o(no),pctglc_icesheet_o(no),& - tgridmap%xc_dst(no),tgridmap%yc_dst(no) + write(6,*)'GIC + ICESHEET differs from 100% at no,pctglc_gic,pctglc_icesheet =', & + no,pctglc_gic_o(no),pctglc_icesheet_o(no) errors = .true. + ! TODO: output lat and lon out above end if end do @@ -397,7 +418,6 @@ subroutine mkglcmec(ldomain, mapfname, & end do end if - ! Error check: are all elevations within elevation class range do no = 1,ns_o do m = 1,nglcec @@ -410,31 +430,30 @@ subroutine mkglcmec(ldomain, mapfname, & end do if (errors) then - call shr_sys_abort() + call shr_sys_abort(subname//" error in error checks") end if ! Deallocate dynamic memory - - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate(pctglc_gic_i, pctglc_icesheet_i) - deallocate(topoglcmec_unnorm_o) - deallocate(pctglc_tot_o) - deallocate(frac_dst) - deallocate(starts, counts) - - write (6,*) 'Successfully made percent elevation class and mean elevation for glaciers' - write (6,*) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) + + if (root_task) then + write (ndiag,'(a)') 'Successfully made percent elevation class and mean elevation for glaciers' + write (ndiag,'(a)') + end if end subroutine mkglcmec !================================================================================= - subroutine mkglacier(ldomain, mapfname, datfname, ndiag, zero_out, glac_o) + subroutine mkglacier(file_mesh_i, file_data_i, mesh_o, glac_o, rc) ! ! make percent glacier ! ! In contrast to mkglcmec, this uses a "flat" PCT_GLACIER field (not separated by - ! elevation class, and not separated into icesheet vs GIC). + ! elevation class, and not separated into icesheet vs GIC). ! ! This simpler routine is sufficient for cases when we run without multiple elevation ! classes. This routine is also used when running with multiple elevation classes: we @@ -444,103 +463,100 @@ subroutine mkglacier(ldomain, mapfname, datfname, ndiag, zero_out, glac_o) ! output. The assumption is that PCT_GLACIER is the sum of both PCT_GLC_GIC and ! PCT_GLC_ICESHEET across all elevation bins. ! - ! !USES: - use mkdomainMod , only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio - ! - ! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - logical , intent(in) :: zero_out ! if should zero glacier out - real(r8) , intent(out):: glac_o(:) ! output grid: %glacier - ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: Mariana Vertenstein - ! + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + real(r8) , intent(out) :: glac_o(:) ! output grid: %glacier + integer , intent(out) :: rc ! - ! !LOCAL VARIABLES: - !EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: glac_i(:) ! input grid: percent glac - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: gglac_i ! input grid: global glac - real(r8) :: garea_i ! input grid: global area - real(r8) :: gglac_o ! output grid: global glac - real(r8) :: garea_o ! output grid: global area - integer :: ni,no,k,n,m,ns, ns_o ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mkglacier' + ! local variables + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + integer :: ni,no,k + integer :: ns_i, ns_o + integer , allocatable :: mask_i(:) + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + real(r8), allocatable :: glac_i(:) ! input grid: percent glac + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: gglac_i ! input grid: global glac + real(r8) :: garea_i ! input grid: global area + real(r8) :: gglac_o ! output grid: global glac + real(r8) :: garea_o ! output grid: global area + integer :: ier, rcode ! error status + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 + character(len=*), parameter :: subname = 'mkglacier' !----------------------------------------------------------------------- - write (6,*) 'Attempting to make %glacier .....' - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields + if (root_task) then + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make %glacier .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) + end if - call domain_read(tdomain,datfname) - ns = tdomain%ns - ns_o = ldomain%ns - allocate(glac_i(ns), & - frac_dst(ns_o), & - stat=ier) + ! Open input data file + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) + + ! Read in input mesh + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Determine ns_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the landmask from the file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" ERROR in allocating frac_i") + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" ERROR in allocating mask_i") + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (frac_i(ni) > 0._r4) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Read in glac_i + allocate(glac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" error in allocating glac_i") + call mkpio_get_rawdata(pioid, 'PCT_GLACIER', mesh_i, glac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + + ! Create a route handle between the input and output mesh and get frac_o + allocate(frac_o(ns_o),stat=ier) if (ier/=0) call shr_sys_abort() + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - write (6,*) 'Open glacier file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_GLACIER', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, glac_i), subname) - call check_ret(nf_close(ncid), subname) - - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask + ! Area-average percent cover on input grid to output grid (with correction for landmask) ! Note that percent cover is in terms of total grid area. - - if ( zero_out )then - - do no = 1, ns_o - glac_o(no) = 0. - enddo - - else - - call gridmap_mapread(tgridmap, mapfname ) - - ! Error checks for domain and map consistencies - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine glac_o on output grid - - call gridmap_areaave_srcmask(tgridmap, glac_i, glac_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - do no = 1, ns_o - if (glac_o(no) < 1.) glac_o(no) = 0. - enddo - end if - - ! Check for conservation - - do no = 1, ns_o + ! Regrid glac_i to glac_o + call regrid_rawdata(mesh_i, mesh_o, routehandle, glac_i, glac_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do no = 1,ns_o + if (glac_o(no) < 1.) glac_o(no) = 0. + enddo + do no = 1,ns_o if ((glac_o(no)) > 100.000001_r8) then write (6,*) 'MKGLACIER error: glacier = ',glac_o(no), & ' greater than 100.000001 for column, row = ',no @@ -548,75 +564,51 @@ subroutine mkglacier(ldomain, mapfname, datfname, ndiag, zero_out, glac_o) end if enddo + ! Compare global areas on input and output grids ! Some error checking and writing of global values before and after the regrid - - if ( .not. zero_out )then - - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - - allocate(mask_r8(ns), stat=ier) - if (ier/=0) call shr_sys_abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - - ! Input grid - - gglac_i = 0. - garea_i = 0. - do ni = 1, ns - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - gglac_i = gglac_i + glac_i(ni)*(tgridmap%area_src(ni)/100.)*& - tdomain%mask(ni)*re**2 - end do - - ! Output grid - - gglac_o = 0. - garea_o = 0. - do no = 1, ns_o - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - gglac_o = gglac_o + glac_o(no)*(tgridmap%area_dst(no)/100.)*& - frac_dst(no)*re**2 - end do - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Glacier Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) -2001 format (1x,'surface type input grid area output grid area'/ & - 1x,' 10**6 km**2 10**6 km**2 ') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2002) gglac_i*1.e-06,gglac_o*1.e-06 - write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 -2002 format (1x,'glaciers ',f14.3,f17.3) -2004 format (1x,'all surface ',f14.3,f17.3) - - end if + ! ! Input grid + ! gglac_i = 0. + ! garea_i = 0. + ! do ni = 1,ns_i + ! garea_i = garea_i + area_i(ni) + ! gglac_i = gglac_i + glac_i(ni)*(area_i(ni)/100.) * mask_i(ni) + ! end do + + ! ! Output grid + ! gglac_o = 0. + ! garea_o = 0. + ! do no = 1,ns_o + ! garea_o = garea_o + area_o(no) + ! gglac_o = gglac_o + glac_o(no)*(area_o(no)/100.) * frac_o(no) + ! end do + + ! ! Diagnostic output + + ! write (ndiag,*) + ! write (ndiag,*) + ! write (ndiag,'(1x,70a1)') ('.',k=1,70) + ! write (ndiag,2001) + ! 2001 format (1x,'surface type input grid area output grid area'/ & + ! 1x,' 10**6 km**2 10**6 km**2 ') + ! write (ndiag,'(1x,70a1)') ('.',k=1,70) + ! write (ndiag,*) + ! write (ndiag,2002) gglac_i*1.e-06,gglac_o*1.e-06 + ! write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 + ! 2002 format (1x,'glaciers ',f14.3,f17.3) + ! 2004 format (1x,'all surface ',f14.3,f17.3) ! Deallocate dynamic memory - - call domain_clean(tdomain) - if ( .not. zero_out )then - call gridmap_clean(tgridmap) - deallocate (glac_i, frac_dst, mask_r8) + deallocate (glac_i, frac_o, mask_i) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + if (root_task) then + write (ndiag,'(a)') 'Successfully made %glacier' + write (ndiag,*) end if - write (6,*) 'Successfully made %glacier' - write (6,*) - end subroutine mkglacier !================================================================================= @@ -629,13 +621,13 @@ integer function get_elevclass(topo, writewarn) ! writewarn is present and false. ! ! input/output variables - real(r8), intent(in) :: topo ! topographic height (m) + real(r4), intent(in) :: topo ! topographic height (m) logical, intent(in), optional :: writewarn ! should warning messages be written? (default: true) ! ! local variables integer :: m logical :: my_writewarn - character(len=32) :: subname = 'get_elevclass' + character(len=*), parameter :: subname = 'get_elevclass' !----------------------------------------------------------------------- if (present(writewarn)) then @@ -677,20 +669,14 @@ end function get_elevclass !================================================================================= real(r8) function mean_elevation_vc(class) ! - ! !DESCRIPTION: ! For a virtual column (thus, a column that has no true elevation data), return the ! "mean" elevation of the given elevation class. ! - ! !ARGUMENTS: - implicit none + ! input/output variables integer, intent(in) :: class ! elevation class ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! - ! !LOCAL VARIABLES: - !EOP - character(len=32) :: subname = 'mean_elevation_vc' + ! local variables + character(len=*), parameter :: subname = 'mean_elevation_vc' !----------------------------------------------------------------------- if (class < nglcec) then diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 4cca362225..38d717e3f6 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -79,6 +79,13 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & rc = ESMF_SUCCESS + if (root_task) then + write(ndiag,*) + write(ndiag,'(a)')'Attempting to %lake, %wetland and lakdepth data' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) + end if + ! Open raw data file ! ASSUME for now that have only 1 input data file call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) diff --git a/tools/mksurfdata_esmf/src/mkorganicMod.F90 b/tools/mksurfdata_esmf/src/mkorganicMod.F90 index f0abb64551..3b04ada05d 100644 --- a/tools/mksurfdata_esmf/src/mkorganicMod.F90 +++ b/tools/mksurfdata_esmf/src/mkorganicMod.F90 @@ -16,7 +16,7 @@ module mkorganicMod implicit none private - public mkorganic ! Set organic soil + public :: mkorganic ! Set organic soil character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -38,6 +38,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid + type(var_desc_t) :: pio_varid integer :: ni,no integer :: ns_i, ns_o integer :: nlay @@ -58,7 +59,10 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) rc = ESMF_SUCCESS if (root_task) then - write (ndiag,'(a)') ' Attempting to make organic mater dataset .....' + write(ndiag,*) + write (ndiag,'(a)')'Attempting to make organic mater dataset .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if ! Open input data file @@ -162,7 +166,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) if (root_task) then - write (ndiag,'(a,i8)') 'Successfully made organic matter ' + write (ndiag,'(a)') 'Successfully made organic matter ' end if end subroutine mkorganic diff --git a/tools/mksurfdata_esmf/src/mkpeatMod.F90 b/tools/mksurfdata_esmf/src/mkpeatMod.F90 index 180f2ccb75..610a62d89f 100644 --- a/tools/mksurfdata_esmf/src/mkpeatMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpeatMod.F90 @@ -1,144 +1,154 @@ module mkpeatMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkpeatMod -! -! !DESCRIPTION: -! make fraction peat from input peat data -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -!----------------------------------------------------------------------- -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkdomainMod , only : domain_checksame + !----------------------------------------------------------------------- + ! make fraction peat from input peat data + !----------------------------------------------------------------------- + ! + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkpioMod , only : mkpio_iodesc_rawdata, mkpio_get_rawdata_level + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkutilsMod , only : chkerr + use mkvarctl , only : ndiag, root_task, outnc_3dglc implicit none - private -! !PUBLIC MEMBER FUNCTIONS: - public mkpeat ! regrid peat data -! -!EOP + public :: mkpeat ! regrid peat data + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + !=============================================================== contains !=============================================================== -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkpeat -! -! !INTERFACE: - subroutine mkpeat(ldomain, mapfname, datfname, ndiag, peat_o) - ! - ! !DESCRIPTION: - ! make peat - ! - ! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkncdio + subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, organic_o, rc) + use mkdiagnosticsMod, only : output_diagnostics_area - use mkchecksMod, only : min_bad, max_bad - ! - ! !ARGUMENTS: - - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: peat_o(:) ! output grid: fraction peat - ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: Sam Levis and Bill Sacks - ! - ! - ! !LOCAL VARIABLES: - !EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain + use mkchecksMod , only : min_bad, max_bad + + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o + real(r8) , intent(out) :: peat_o(:,:) ! output grid: fraction peat + integer , intent(out) :: rc + + ! local variables: + type(ESMF_RouteHandle) :: routehandle ! nearest neighbor routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + integer :: ni,no,k + integer :: ns_i, ns_o + integer , allocatable :: mask_i(:) + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + real(r8), allocatable :: peat_i(:) ! input grid: percent glac + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: gglac_i ! input grid: global glac + real(r8) :: garea_i ! input grid: global area + real(r8) :: gglac_o ! output grid: global glac + real(r8) :: garea_o ! output grid: global area + integer :: ier, rcode ! error status + real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 real(r8), allocatable :: data_i(:) ! data on input grid - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - real(r8), parameter :: min_valid = 0._r8 ! minimum valid value real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value - character(len=32) :: subname = 'mkpeat' + character(len=*), parameter :: subname = 'mkpeat' !----------------------------------------------------------------------- - write (6,*) 'Attempting to make peat .....' - - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - call domain_read( tdomain, datfname ) - - call gridmap_mapread( tgridmap, mapfname ) - - ! Obtain frac_dst - allocate(frac_dst(ldomain%ns), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write(6,*)'Open peat file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) + if (root_task) + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make peat .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) + end if - allocate(data_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() + ! Open input data file + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) + + ! Read in input mesh + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Determine ns_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the landmask from the file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (frac_i(ni) > 0._r4) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Read in peat_i + allocate(peat_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'peat', mesh_i, peat_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + + ! Create a route handle between the input and output mesh and get frac_o + allocate(frac_o(ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - ! ----------------------------------------------------------------- ! Regrid peat - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'peatf', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, peat_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(peat_o, min_valid, 'peat') .or. & - max_bad(peat_o, max_valid, 'peat')) then - call abort() + call regrid_rawdata(mesh_i, mesh_o, routehandle, peat_i, peat_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (min_bad(peat_o, min_valid, 'peat') .or. max_bad(peat_o, max_valid, 'peat')) then + call shr_abort() end if - call output_diagnostics_area(data_i, peat_o, tgridmap, "Peat", percent=.false., ndiag=ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) +#ifdef TODO + ! call output_diagnostics_area(area_i, area_o, mask_i, peat_i, peat_o, 'peat', .true., ndiag) +#endif + + ! Close the file + call pio_closefile(pioid) + call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- + ! Release memory + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (data_i) - deallocate (frac_dst) - deallocate (mask_r8) + if (root_task) then + write (ndiag,'(a)') 'Successfully made organic matter ' + end if - write (6,*) 'Successfully made peat' - write (6,*) + if (root_task) then + write (ndiag,'(a)') 'Successfully made peat' + end if end subroutine mkpeat diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 37ffc84968..a7eacbe87c 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -2,7 +2,9 @@ module mkpioMod use ESMF ! TODO: put in only statements use pio ! TODO: put in only statements - use shr_kind_mod , only : r8 => shr_kind_r8, cl => shr_kind_cl, cs => shr_kind_cs, r4 => shr_kind_r4 + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 + use shr_kind_mod , only : i2 => shr_kind_i2, i4 => shr_kind_i4 + use shr_kind_mod , only : cl => shr_kind_cl, cs => shr_kind_cs use shr_sys_mod , only : shr_sys_abort use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag, mpicom, outnc_1d @@ -13,6 +15,7 @@ module mkpioMod #include public :: mkpio_get_rawdata + public :: mkpio_get_rawdata_level public :: mkpio_iodesc_rawdata public :: mkpio_iodesc_output public :: mkpio_wopen @@ -23,6 +26,11 @@ module mkpioMod private :: mkpio_defvar + interface mkpio_get_rawdata_level + module procedure mkpio_get_rawdata1d_level_real4 + module procedure mkpio_get_rawdata1d_level_real8 + end interface mkpio_get_rawdata_level + interface mkpio_get_rawdata module procedure mkpio_get_rawdata1d_int module procedure mkpio_get_rawdata1d_real4 @@ -70,6 +78,7 @@ subroutine mkpio_get_rawdata1d_int(pioid, varname, mesh_i, data_i, rc) integer :: lsize integer :: rcode integer :: n + integer(i2), allocatable :: data_short(:) character(len=*), parameter :: subname = 'mkpio_get_rawdata1d_int' !------------------------------------------------- @@ -88,13 +97,17 @@ subroutine mkpio_get_rawdata1d_int(pioid, varname, mesh_i, data_i, rc) ! Read the input raw data if (pio_vartype == PIO_INT) then call pio_read_darray(pioid, pio_varid, pio_iodesc, data_i, rcode) - call ESMF_VMLogMemInfo("After pio_read_darray for "//trim(varname)//" in "//trim(subname)) + else if (pio_vartype == PIO_SHORT) then + allocate(data_short(lsize)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_short, rcode) + data_i = int(data_short, i4) + deallocate(data_short) else - call shr_sys_abort(subName//"ERROR: only int, real and double types are supported in "//trim(subname)) + call shr_sys_abort(subName//" ERROR: only int and short is supported for "//trim(varname)) end if + call ESMF_VMLogMemInfo("After pio_read_darray for "//trim(varname)//" in "//trim(subname)) ! Free the memory of the io descriptor - call pio_freedecomp(pioid, pio_iodesc) call ESMF_VMLogMemInfo("After call to pio_freedecomp for "//trim(varname)) @@ -111,15 +124,16 @@ subroutine mkpio_get_rawdata1d_real4(pioid, varname, mesh_i, data_i, rc) integer , intent(out) :: rc ! local variables - type(var_desc_t) :: pio_varid - integer :: pio_vartype - type(io_desc_t) :: pio_iodesc - type(io_desc_t) :: pio_iodesc_mask - integer , allocatable :: data_int(:) - real(r8), allocatable :: data_double(:) - integer :: lsize - integer :: rcode - integer :: n + type(var_desc_t) :: pio_varid + integer :: pio_vartype + type(io_desc_t) :: pio_iodesc + type(io_desc_t) :: pio_iodesc_mask + integer(i2) , allocatable :: data_short(:) + integer(i4) , allocatable :: data_int(:) + real(r8) , allocatable :: data_double(:) + integer :: lsize + integer :: rcode + integer :: n character(len=*), parameter :: subname = 'mkpio_get_rawdata1d_real4' !------------------------------------------------- @@ -136,7 +150,12 @@ subroutine mkpio_get_rawdata1d_real4(pioid, varname, mesh_i, data_i, rc) call ESMF_VMLogMemInfo("After mkpio_iodesc for varname "//trim(varname)//" in "//trim(subname)) ! Read the input raw data - if (pio_vartype == PIO_INT) then + if (pio_vartype == PIO_SHORT) then + allocate(data_short(lsize)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_short, rcode) + data_i(:) = real(data_short(:), kind=r8) + deallocate(data_short) + else if (pio_vartype == PIO_INT) then allocate(data_int(lsize)) call pio_read_darray(pioid, pio_varid, pio_iodesc, data_int, rcode) data_i(:) = real(data_int(:), kind=r4) @@ -149,7 +168,7 @@ subroutine mkpio_get_rawdata1d_real4(pioid, varname, mesh_i, data_i, rc) data_i(:) = real(data_double(:), kind=r4) deallocate(data_double) else - call shr_sys_abort(subName//"ERROR: only int, real and double types are supported") + call shr_sys_abort(subName//" ERROR: only real and double types are supported for "//trim(varname)) end if call ESMF_VMLogMemInfo("After call to pio_read_darray for varname "//trim(varname)) @@ -171,16 +190,17 @@ subroutine mkpio_get_rawdata1d_real8(pioid, varname, mesh_i, data_i, nt, rc) ! local variables - type(var_desc_t) :: pio_varid - integer :: pio_vartype - type(io_desc_t) :: pio_iodesc - type(io_desc_t) :: pio_iodesc_mask - integer , allocatable :: data_int(:) - real(r4), allocatable :: data_real(:) - real(r8), allocatable :: data_double(:) - integer :: lsize - integer :: rcode - integer :: n + type(var_desc_t) :: pio_varid + integer :: pio_vartype + type(io_desc_t) :: pio_iodesc + type(io_desc_t) :: pio_iodesc_mask + integer(i2) , allocatable :: data_short(:) + integer(i4) , allocatable :: data_int(:) + real(r4) , allocatable :: data_real(:) + real(r8) , allocatable :: data_double(:) + integer :: lsize + integer :: rcode + integer :: n character(len=*), parameter :: subname = 'mkpio_get_rawdata1d_real8' !------------------------------------------------- @@ -201,7 +221,12 @@ subroutine mkpio_get_rawdata1d_real8(pioid, varname, mesh_i, data_i, nt, rc) ! Read the input raw data call ESMF_VMLogMemInfo("After mkpio_iodesc for varname for "//trim(varname)//" in "//trim(subname)) - if (pio_vartype == PIO_INT) then + if (pio_vartype == PIO_SHORT) then + allocate(data_short(lsize)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_short, rcode) + data_i(:) = real(data_short(:), kind=r8) + deallocate(data_short) + else if (pio_vartype == PIO_INT) then allocate(data_int(lsize)) call pio_read_darray(pioid, pio_varid, pio_iodesc, data_int, rcode) data_i(:) = real(data_int(:), kind=r8) @@ -214,7 +239,7 @@ subroutine mkpio_get_rawdata1d_real8(pioid, varname, mesh_i, data_i, nt, rc) else if (pio_vartype == PIO_DOUBLE) then call pio_read_darray(pioid, pio_varid, pio_iodesc, data_i, rcode) else - call shr_sys_abort(subName//"ERROR: only int, real and double types are supported") + call shr_sys_abort(subName//" ERROR: supported variable type not found for "//trim(varname)) end if call ESMF_VMLogMemInfo("After call to pio_read_darrayy for varname "//trim(varname)) @@ -286,7 +311,7 @@ subroutine mkpio_get_rawdata2d_real4(pioid, varname, mesh_i, data_i, rc) end do deallocate(data_double2d) else - call shr_sys_abort(subName//"ERROR: only real and double types are supported") + call shr_sys_abort(subName//" ERROR: only real and double types are supported for "//trim(varname)) end if call pio_freedecomp(pioid, pio_iodesc) @@ -389,6 +414,8 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, integer :: cnt, m integer :: offset integer :: rCode ! pio return code (only used when pio error handling is PIO_BCAST_ERROR) + integer :: unlimdim + logical :: unlimited_dim character(*), parameter :: subname = '(mkpio_iodesc_rawdata) ' !------------------------------------------------------------------------------- @@ -405,33 +432,30 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, call ESMF_VMLogMemInfo("Ending setting compdof for "//trim(varname)) ! get pio variable id, type and number of dimensions - call ESMF_VMLogMemInfo("Beginning getting variable id for "//trim(varname)) rcode = pio_inq_varid(pioid, trim(varname), pio_varid) rcode = pio_inq_vartype(pioid, pio_varid, pio_vartype) rcode = pio_inq_varndims(pioid, pio_varid, ndims) - call ESMF_VMLogMemInfo("Ending getting variable id" //trim(varname)) ! get variable dimension sizes - call ESMF_VMLogMemInfo("Beginning getting dims for" //trim(varname)) allocate(dimids(ndims)) allocate(dimlens(ndims)) rcode = pio_inq_vardimid(pioid, pio_varid, dimids(1:ndims)) do n = 1, ndims rcode = pio_inq_dimlen(pioid, dimids(n), dimlens(n)) end do - rcode = pio_inq_dimname(pioid, dimids(ndims), dimname) - call ESMF_VMLogMemInfo("End getting dims for "//trim(varname)) + rcode = pio_inq_unlimdim(pioid, unlimdim) + unlimited_dim = (dimids(ndims) == unlimdim) ! Create compdof3d if needed ! Assume that input data is always lon,lat as first two dimensions nlev = 0 - if (ndims == 3 .and. trim(dimname) /= 'time') then + if (ndims == 3 .and. .not. unlimited_dim) then nlev = dimlens(3) - else if (ndims == 3 .and. trim(dimname) == 'time') then + else if (ndims == 3 .and. unlimited_dim) then ! do nothing - keep nlev at 0 - else if (ndims == 4 .and. trim(dimname) /= 'time') then + else if (ndims == 4 .and. .not. unlimited_dim) then nlev = dimlens(3)*dimlens(4) - else if (ndims == 4 .and. trim(dimname) == 'time') then + else if (ndims == 4 .and. unlimited_dim) then nlev = dimlens(3) end if @@ -455,7 +479,7 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, dimlens(1),dimlens(2) end if else if (ndims == 3) then - if (trim(dimname) == 'time') then + if (unlimited_dim) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) if (root_task) then write(ndiag,'(a,i8,i8)') ' set iodesc for rawdata: '//trim(varname)//' with dim(1),dim(2) = ',& @@ -469,7 +493,7 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, end if end if else if (ndims == 4) then - if (trim(dimname) == 'time') then + if (unlimited_dim) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) if (root_task) then write(ndiag,'(a,i8,i8,i8)') ' set iodesc for rawdata: '//trim(varname)//' with dim(1),dim(2),dim(3) = ',& @@ -485,7 +509,6 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, ! deallocate memory deallocate(compdof) if (allocated(compdof3d)) deallocate(compdof3d) - call ESMF_VMLogMemInfo("Finished setting iodesc for "//trim(varname)//" in "//trim(subname)) end subroutine mkpio_iodesc_rawdata @@ -517,6 +540,7 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) type(var_desc_t) :: pio_varid integer :: pio_vartype integer :: rCode ! pio return code (only used when pio error handling is PIO_BCAST_ERROR) + logical :: unlimited_dim character(*), parameter :: subname = '(shr_strdata_set_stream_iodesc) ' !------------------------------------------------------------------------------- @@ -537,6 +561,7 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) rcode = pio_inq_dimlen(pioid, dimids(n), dimlens(n)) end do rcode = pio_inq_dimname(pioid, dimids(ndims), dimname) + unlimited_dim = (dimids(ndims) == PIO_UNLIMITED) ! Get compdof from mesh call ESMF_MeshGet(mesh, elementdistGrid=distGrid, rc=rc) @@ -551,22 +576,22 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) nlev = 0 if (outnc_1d) then offset = dimlens(1) - if (ndims == 2 .and. trim(dimname) /= 'time') then + if (ndims == 2 .and. .not. unlimited_dim) then nlev = dimlens(2) - else if (ndims == 3 .and. trim(dimname) == 'time') then + else if (ndims == 3 .and. unlimited_dim) then nlev = dimlens(2) - else if (ndims == 3 .and. trim(dimname) /= 'time') then + else if (ndims == 3 .and. .not. unlimited_dim) then nlev = dimlens(2)*dimlens(3) end if else offset = dimlens(1)*dimlens(2) - if (ndims == 3 .and. trim(dimname) /= 'time') then + if (ndims == 3 .and. .not. unlimited_dim) then nlev = dimlens(3) - else if (ndims == 3 .and. trim(dimname) == 'time') then + else if (ndims == 3 .and. unlimited_dim) then ! do nothing - keep nlev at 0 - else if (ndims == 4 .and. trim(dimname) /= 'time') then + else if (ndims == 4 .and. .not. unlimited_dim) then nlev = dimlens(3)*dimlens(4) - else if (ndims == 4 .and. trim(dimname) == 'time') then + else if (ndims == 4 .and. unlimited_dim) then nlev = dimlens(3) end if end if @@ -589,13 +614,13 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) if (ndims == 1) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) else if (ndims == 2) then - if (trim(dimname) == 'time') then + if (unlimited_dim) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) else call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) end if else if (ndims == 3) then - if (trim(dimname) == 'time') then + if (unlimited_dim) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) else call shr_sys_abort('support on 2 dimensions in addition to a time dimension when outnc_1d is true') @@ -606,13 +631,13 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) if (ndims == 2) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) else if (ndims == 3) then - if (trim(dimname) == 'time') then + if (unlimited_dim) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) else call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) end if else if (ndims == 4) then - if (trim(dimname) == 'time') then + if (unlimited_dim) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) else call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3),dimlens(4)/), compdof3d, pio_iodesc) @@ -950,7 +975,7 @@ subroutine mkpio_put_time_slice_1d(pioid, pio_varid, pio_iodesc, time_index, dat end subroutine mkpio_put_time_slice_1d - !----------------------------------------------------------------------- + ! ======================================================================== subroutine mkpio_put_time_slice_2d(pioid, pio_varid, pio_iodesc, time_index, data) ! Write a single time slice of a 2-d variable @@ -1011,4 +1036,113 @@ subroutine mkpio_get_dimlengths(pioid, varname, ndims, dimlengths) end subroutine mkpio_get_dimlengths + ! ======================================================================== + subroutine mkpio_get_rawdata1d_level_real4(pioid, pio_iodesc, unlimited_index, varname, data_i) + + ! input/output variables + type(file_desc_t), intent(inout) :: pioid + type(io_desc_t) , intent(inout) :: pio_iodesc + integer , intent(in) :: unlimited_index + character(len=*) , intent(in) :: varname ! field name in rawdata file + real(r4) , intent(inout) :: data_i(:) ! input raw data + + ! local variables + type(var_desc_t) :: pio_varid + integer :: pio_vartype + integer(i2) , allocatable :: data_short(:) + integer(i4) , allocatable :: data_int(:) + real(r8) , allocatable :: data_double(:) + integer :: ns_i + integer :: rcode + character(len=*), parameter :: subname = 'mkpio_get_rawdata1d_real4' + !------------------------------------------------- + + ! Get variable id and type + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + rcode = pio_inq_vartype(pioid, pio_varid, pio_vartype) + + ! Set unlimited frame index + call pio_setframe(pioid, pio_varid, int(unlimited_index, kind=Pio_Offset_Kind)) + + ! Read the input raw data + ns_i = size(data_i) + if (pio_vartype == PIO_SHORT) then + allocate(data_short(ns_i)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_short, rcode) + data_i(:) = real(data_short(:), kind=r8) + deallocate(data_short) + else if (pio_vartype == PIO_INT) then + allocate(data_int(ns_i)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_int, rcode) + data_i(:) = real(data_int(:), kind=r4) + deallocate(data_int) + else if (pio_vartype == PIO_REAL) then + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_i, rcode) + else if (pio_vartype == PIO_DOUBLE) then + ns_i = size(data_i) + allocate(data_double(ns_i)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double, rcode) + data_i(:) = real(data_double(:), kind=r4) + deallocate(data_double) + else + call shr_sys_abort(subName//" ERROR: vartype not supported for "//trim(varname)) + end if + call ESMF_VMLogMemInfo("After call to pio_read_darray for varname "//trim(varname)) + + end subroutine mkpio_get_rawdata1d_level_real4 + + ! ======================================================================== + subroutine mkpio_get_rawdata1d_level_real8(pioid, pio_iodesc, unlimited_index, varname, data_i) + + ! input/output variables + type(file_desc_t), intent(inout) :: pioid + type(io_desc_t) , intent(inout) :: pio_iodesc + integer , intent(in) :: unlimited_index + character(len=*) , intent(in) :: varname ! field name in rawdata file + real(r8) , intent(inout) :: data_i(:) ! input raw data + + ! local variables + type(var_desc_t) :: pio_varid + integer :: pio_vartype + integer(i2) , allocatable :: data_short(:) + integer(i4) , allocatable :: data_int(:) + real(r4) , allocatable :: data_real(:) + integer :: ns_i + integer :: rcode + character(len=*), parameter :: subname = 'mkpio_get_rawdata1d_real4' + !------------------------------------------------- + + ! Get variable id and type + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + rcode = pio_inq_vartype(pioid, pio_varid, pio_vartype) + + ! Set unlimited frame index + call pio_setframe(pioid, pio_varid, int(unlimited_index, kind=Pio_Offset_Kind)) + + ! Read the input raw data + ns_i = size(data_i) + if (pio_vartype == PIO_SHORT) then + allocate(data_short(ns_i)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_short, rcode) + data_i(:) = real(data_short(:), kind=r8) + deallocate(data_short) + else if (pio_vartype == PIO_INT) then + allocate(data_int(ns_i)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_int, rcode) + data_i(:) = real(data_int(:), kind=r4) + deallocate(data_int) + else if (pio_vartype == PIO_REAL) then + allocate(data_real(ns_i)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real, rcode) + data_i(:) = real(data_real(:), kind=r8) + deallocate(data_real) + else if (pio_vartype == PIO_DOUBLE) then + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_i, rcode) + else + call shr_sys_abort(subName//" ERROR: vartype not supported for "//trim(varname)) + end if + call ESMF_VMLogMemInfo("After call to pio_read_darray for varname "//trim(varname)) + + end subroutine mkpio_get_rawdata1d_level_real8 + end module mkpioMod diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index b4f73f1f29..1cb2a57036 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -98,7 +98,6 @@ program mksurfdata use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride - use mkglcmecMod , only : nglcec, mkglcmec, mkglcmecInit, mkglacier use mkharvestMod , only : mkharvest, mkharvest_init, mkharvest_fieldname use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride use mkharvestMod , only : harvestDataType @@ -109,6 +108,7 @@ program mksurfdata use mkVICparamsMod , only : mkVICparams #endif use mkvocefMod , only : mkvocef + use mkglcmecMod , only : mkglcmecInit, mkglcmec, mkglacier, nglcec use mkglacierregionMod , only : mkglacierregion use mksoiltexMod , only : mksoiltex use mksoilfmaxMod , only : mksoilfmax @@ -209,6 +209,7 @@ program mksurfdata integer , allocatable :: harvind2D(:) ! Indices of 2D harvest fields logical :: zero_out_lake ! if should zero glacier out logical :: zero_out_wetland ! if should zero glacier out + logical :: zero_out #ifdef TODO type(harvestDataType) :: harvdata #endif @@ -313,9 +314,9 @@ program mksurfdata #ifdef TODO call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) +#endif allocate ( elevclass(nglcec+1) ) call mkglcmecInit (elevclass) -#endif call mkurbanInit (mksrf_furban) ! ---------------------------------------------------------------------- @@ -344,10 +345,7 @@ program mksurfdata allocate ( slope(lsize_o)) ; slope(:) = spval ! glacier properties - allocate ( pctgla(lsize_o)) ; pctgla(:) = spval #ifdef TODO - allocate ( pctglcmec(lsize_o,nglcec)) ; pctglcmec(:,:) = spval - allocate ( topoglcmec(lsize_o,nglcec)) ; topoglcmec(:,:) = spval #endif ! vic properties @@ -382,15 +380,50 @@ program mksurfdata ! -------------------------------------------------- ! begin working - ! ! Make VOC emission factors for isoprene [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] + !DEBUG - place here for debugging + ! Make glacier multiple elevation classes [pctglcmec,topoglcmec] from [fglacier] dataset + allocate ( pctglcmec(lsize_o,nglcec)) ; pctglcmec(:,:) = spval + allocate ( topoglcmec(lsize_o,nglcec)) ; topoglcmec(:,:)= spval + if ( outnc_3dglc )then + allocate(pctglcmec_gic(lsize_o,nglcec)) + allocate(pctglcmec_icesheet(lsize_o,nglcec)) + allocate(pctglc_gic(lsize_o)) + allocate(pctglc_icesheet(lsize_o)) + + call mkglcmec(mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, & + pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, & + pctglcmec_gic_o=pctglcmec_gic, pctglcmec_icesheet_o=pctglcmec_icesheet, & + pctglc_gic_o=pctglc_gic, pctglc_icesheet_o=pctglc_icesheet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglcmec') + else + call mkglcmec(mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, & + pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglcmec') + end if + !DEBUG + + ! Make glacier fraction [pctgla] from [fglacier] dataset + allocate ( pctgla(lsize_o)) ; pctgla(:) = spval + zero_out = (all_urban .or. all_veg) + if (.not. zero_out) then + call mkglacier ( mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, glac_o=pctgla, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacier') + else + if (root_task) then + write (ndiag,'(a)') 'Attempting to make %glacier .....' + write(ndiag, '(a)') ' zeroing out all pct glacier data' + pctgla(:) = 0. + end if + end if + + ! Make VOC emission factors for isoprene [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] allocate (ef1_btr(lsize_o)) ; ef1_btr(:) = 0._r8 allocate (ef1_fet(lsize_o)) ; ef1_fet(:) = 0._r8 allocate (ef1_fdt(lsize_o)) ; ef1_fdt(:) = 0._r8 allocate (ef1_shr(lsize_o)) ; ef1_shr(:) = 0._r8 allocate (ef1_grs(lsize_o)) ; ef1_grs(:) = 0._r8 allocate (ef1_crp(lsize_o)) ; ef1_crp(:) = 0._r8 - call ESMF_LogWrite("DEBUG: mksrf_fvocef_mesh is "//trim(mksrf_fvocef_mesh), ESMF_LOGMSG_INFO) - call mkvocef ( mksrf_fvocef, mksrf_fvocef_mesh, mesh_model, & + call mkvocef ( mksrf_fvocef_mesh, mksrf_fvocef, mesh_model, & ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkvocef') @@ -466,9 +499,6 @@ program mksurfdata ! end working ! -------------------------------------------------- - ! ! Make glacier fraction [pctgla] from [fglacier] dataset - ! call mkglacier ( mapfname=map_fglacier, datfname=mksrf_fglacier, ndiag=ndiag, zero_out=all_urban.or.all_veg, glac_o=pctgla) - ! ! Make GDP data [gdp] from [gdp] ! call mkgdp ( mapfname=map_fgdp, datfname=mksrf_fgdp, ndiag=ndiag, gdp_o=gdp) @@ -593,30 +623,34 @@ program mksurfdata ! This call needs to occur after all corrections are made to pcturb call normalize_classes_by_gcell(urban_classes, pcturb, urban_classes_g) - ! ! ---------------------------------------------------------------------- - ! ! Make glacier multiple elevation classes [pctglcmec,topoglcmec] from [fglacier] dataset - ! ! ---------------------------------------------------------------------- + ! ---------------------------------------------------------------------- + ! Make glacier multiple elevation classes [pctglcmec,topoglcmec] from [fglacier] dataset + ! ---------------------------------------------------------------------- - ! ! This call needs to occur after pctgla has been adjusted for the final time + ! This call needs to occur after pctgla has been adjusted for the final time + ! allocate ( pctglcmec(lsize_o,nglcec)) ; pctglcmec(:,:) = spval + ! allocate ( topoglcmec(lsize_o,nglcec)) ; topoglcmec(:,:)= spval ! if ( outnc_3dglc )then ! allocate(pctglcmec_gic(lsize_o,nglcec)) ! allocate(pctglcmec_icesheet(lsize_o,nglcec)) ! allocate(pctglc_gic(lsize_o)) ! allocate(pctglc_icesheet(lsize_o)) - ! call mkglcmec ( mapfname=map_fglacier, & - ! datfname_fglacier=mksrf_fglacier, ndiag=ndiag, & + ! call mkglcmec(mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, & ! pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, & ! pctglcmec_gic_o=pctglcmec_gic, pctglcmec_icesheet_o=pctglcmec_icesheet, & - ! pctglc_gic_o=pctglc_gic, pctglc_icesheet_o=pctglc_icesheet) + ! pctglc_gic_o=pctglc_gic, pctglc_icesheet_o=pctglc_icesheet, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglcmec') ! else - ! call mkglcmec ( mapfname=map_fglacier, & - ! datfname_fglacier=mksrf_fglacier, ndiag=ndiag, & - ! pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec ) + ! call mkglcmec(mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, & + ! pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, rc=rc ) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglcmec') ! end if - ! ! Determine fractional land from pft dataset + ! ---------------------------------------------------------------------- + ! Determine fractional land from pft dataset + ! ---------------------------------------------------------------------- ! do n = 1,lsize_o ! landfrac_pft(n) = pctlnd_pft(n)/100._r8 @@ -643,7 +677,6 @@ program mksurfdata write (ndiag,'(a)') ' fsurdat is blank: skipping writing surface dataset' end if else - !call mkfile_fsurdat( mksrf_fgrid_mesh_nx, mksrf_fgrid_mesh_ny, mesh_model, dynlanduse=.false., harvdata) if (root_task)then write(ndiag,'(a)')"Calling mkfile_fsurdat" end if @@ -671,7 +704,14 @@ program mksurfdata ef_shr=ef1_shr, & ef_grs=ef1_grs, & ef_crp=ef1_crp, & - rc = rc) + pctgla=pctgla, & + pctglcmec=pctglcmec, & + topoglcmec=topoglcmec, & + pctglcmec_gic=pctglcmec_gic, & + pctglcmec_icesheet=pctglcmec_icesheet, & + pctglc_gic=pctglc_gic, & + pctglc_icesheet=pctglc_icesheet, & + rc=rc) if (root_task) then write(ndiag,*) write(ndiag,'(a)')'successfully created file '//trim(fsurdat) @@ -679,24 +719,28 @@ program mksurfdata end if ! if (fsurdat /= ' ') + ! ---------------------------------------------------------------------- ! Deallocate arrays NOT needed for dynamic-pft section of code + ! ---------------------------------------------------------------------- - deallocate ( lakedepth ) - deallocate ( soil_color ) - -#ifdef TODO deallocate ( organic ) deallocate ( ef1_btr, ef1_fet, ef1_fdt, ef1_shr, ef1_grs, ef1_crp ) + deallocate ( lakedepth ) + deallocate ( soil_color ) + deallocate ( soildepth ) + deallocate ( pctsand, pctclay ) + deallocate ( glacier_region ) deallocate ( pctglcmec, topoglcmec) - if ( outnc_3dglc ) deallocate ( pctglc_gic, pctglc_icesheet) deallocate ( elevclass ) - deallocate ( fmax ) - deallocate ( pctsand, pctclay ) + deallocate ( fmaxsoil ) + if ( outnc_3dglc ) then + deallocate ( pctglc_gic, pctglc_icesheet) + end if + +#ifdef TODO deallocate ( gdp, fpeat, agfirepkmon ) - deallocate ( soildepth ) deallocate ( topo_stddev, slope ) deallocate ( vic_binfl, vic_ws, vic_dsmax, vic_ds ) - deallocate ( glacier_region ) call harvdata%clean() #endif diff --git a/tools/mksurfdata_esmf/src/mkutilsMod.F90 b/tools/mksurfdata_esmf/src/mkutilsMod.F90 index f2b920fc85..5b61540a14 100644 --- a/tools/mksurfdata_esmf/src/mkutilsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkutilsMod.F90 @@ -86,13 +86,13 @@ logical function slightly_below(a, b, eps) ! condition; if not provided, the tolerance defaults to the value given by eps_default ! !ARGUMENTS: - real(r4), intent(in) :: a - real(r4), intent(in) :: b - real(r4), intent(in), optional :: eps + real(r8), intent(in) :: a + real(r8), intent(in) :: b + real(r8), intent(in), optional :: eps ! !LOCAL VARIABLES: - real(r4) :: l_eps - real(r4), parameter :: eps_default = 1.e-15_r4 ! default relative error tolerance + real(r8) :: l_eps + real(r8), parameter :: eps_default = 1.e-15_r8 ! default relative error tolerance !------------------------------------------------------------------------------ if (present(eps)) then @@ -119,13 +119,13 @@ logical function slightly_above(a, b, eps) ! condition; if not provided, the tolerance defaults to the value given by eps_default ! input/output variables - real(r4), intent(in) :: a - real(r4), intent(in) :: b - real(r4), intent(in), optional :: eps + real(r8), intent(in) :: a + real(r8), intent(in) :: b + real(r8), intent(in), optional :: eps ! local variables: - real(r4) :: l_eps - real(r4), parameter :: eps_default = 1.e-15_r4 ! default relative error tolerance + real(r8) :: l_eps + real(r8), parameter :: eps_default = 1.e-15_r8 ! default relative error tolerance !------------------------------------------------------------------------------ if (present(eps)) then diff --git a/tools/mksurfdata_esmf/src/mkvocefMod.F90 b/tools/mksurfdata_esmf/src/mkvocefMod.F90 index 237076c34e..19d42458ee 100644 --- a/tools/mksurfdata_esmf/src/mkvocefMod.F90 +++ b/tools/mksurfdata_esmf/src/mkvocefMod.F90 @@ -28,7 +28,7 @@ module mkvocefMod contains !================================================================================= - subroutine mkvocef(file_data_i, file_mesh_i, mesh_o, & + subroutine mkvocef(file_mesh_i, file_data_i, mesh_o, & ef_btr_o, ef_fet_o, ef_fdt_o, ef_shr_o, ef_grs_o, ef_crp_o, rc) ! make volatile organic coumpunds (VOC) emission factors. diff --git a/tools/mksurfdata_esmf/src/shr_kind_mod.F90 b/tools/mksurfdata_esmf/src/shr_kind_mod.F90 index d1219223da..74f6d18b07 100644 --- a/tools/mksurfdata_esmf/src/shr_kind_mod.F90 +++ b/tools/mksurfdata_esmf/src/shr_kind_mod.F90 @@ -11,6 +11,7 @@ MODULE shr_kind_mod integer,parameter :: SHR_KIND_RN = kind(1.0) ! native real integer,parameter :: SHR_KIND_I8 = selected_int_kind (13) ! 8 byte integer integer,parameter :: SHR_KIND_I4 = selected_int_kind ( 6) ! 4 byte integer + integer,parameter :: SHR_KIND_I2 = selected_int_kind ( 4) ! 2 byte integer integer,parameter :: SHR_KIND_IN = kind(1) ! native integer integer,parameter :: SHR_KIND_CS = 80 ! short char integer,parameter :: SHR_KIND_CL = 256 ! long char diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index aa965f097d..f075bd3421 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -140,6 +140,8 @@ program mksurfdat integer, allocatable :: harvind1D(:) ! Indices of 1D harvest fields integer, allocatable :: harvind2D(:) ! Indices of 2D harvest fields + logical :: zero_out + ! NOTE(bja, 2015-01) added to work around a ?bug? causing 1x1_urbanc_alpha to abort. See !/glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 logical :: urban_skip_abort_on_invalid_data_check @@ -379,7 +381,7 @@ program mksurfdat ! Call module initialization routines ! call mksoilInit( ) - call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) + !call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) allocate ( elevclass(nglcec+1) ) call mkglcmecInit (elevclass) call mkurbanInit (mksrf_furban) From 7f970921978c7d662cffcdd8cd5a81550421d73a Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 4 Feb 2022 15:27:40 -0700 Subject: [PATCH 040/614] got peatf working --- tools/mksurfdata_esmf/src/CMakeLists.txt | 3 + .../src/mkagfirepkmonthMod.F90 | 122 ++--- .../mksurfdata_esmf/src/mkdiagnosticsMod.F90 | 227 ++++----- tools/mksurfdata_esmf/src/mkdomainMod.F90 | 53 +++ tools/mksurfdata_esmf/src/mkfileMod.F90 | 69 ++- tools/mksurfdata_esmf/src/mkpeatMod.F90 | 35 +- tools/mksurfdata_esmf/src/mkpftMod.F90 | 444 ++++++++---------- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 68 +-- tools/mksurfdata_esmf/src/mksurfdata.F90 | 134 +++--- tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 117 +++-- 10 files changed, 677 insertions(+), 595 deletions(-) create mode 100644 tools/mksurfdata_esmf/src/mkdomainMod.F90 diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 2dc2c69882..4f24f5aea4 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -20,10 +20,12 @@ set(SRCFILES mkvarctl.F90 mkvarpar.F90 mkpioMod.F90 mkfileMod.F90 + mkdomainMod.F90 mkglacierregionMod.F90 mkglcmecMod.F90 mklanwatMod.F90 mkorganicMod.F90 + mkpeatMod.F90 mksoilcolMod.F90 mksoilfmaxMod.F90 mksoiltexMod.F90 @@ -33,6 +35,7 @@ set(SRCFILES mkvarctl.F90 mkesmfMod.F90 mkutilsMod.F90 mkchecksMod.F90 + mkdiagnosticsMod.F90 mkindexmapMod.F90 nanMod.F90 shr_const_mod.F90 diff --git a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 index bc93fdb8e7..4585e33f14 100644 --- a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 +++ b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 @@ -19,6 +19,8 @@ module mkagfirepkmonthMod implicit none private ! By default make data private +#include + public :: mkagfirepkmon ! Set agricultural fire peak month private :: define_months ! define month strings @@ -55,13 +57,15 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) real(r8), allocatable :: frac_o(:) real(r8), allocatable :: area_i(:) real(r8), allocatable :: area_o(:) + real(r8), allocatable :: loc_gast_i(:) ! local global area, by surface type + real(r8), allocatable :: loc_gast_i(:) ! local global area, by surface type real(r8), allocatable :: gast_i(:) ! global area, by surface type real(r8), allocatable :: gast_o(:) ! global area, by surface type real(r8), allocatable :: frac_dst(:) ! output fractions real(r4), allocatable :: data_i(:,:) real(r4), allocatable :: data_o(:,:) integer , allocatable :: agfirepkmon_i(:) ! input grid: agricultural fire peak month - integer :: nagfirepkmon ! number of peak months + integer :: nagfirepkmon ! number of peak months character(len=35), allocatable :: month(:) ! name of each month integer :: rcode, ier ! error status integer, parameter :: miss = unsetmon ! missing data indicator @@ -130,27 +134,26 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) allocate(data_i(min_valid_value:max_valid_value,ns_i)) data_i(:,:) = 0._r4 do l = min_valid_value,max_valid_value - do n = 1,ns_i - if (int(soil_color_i(n)) == l) then + do ni = 1,ns_i + if (int(agfilepkmon_i(ni)) == l .and. int(agfilepkmon_i(ni)) /= miss) then data_i(l,n) = 1._r4 * mask_i(n) end if end do end do ! Regrid data_i to data_o - allocate(data_o(0:nsoilcol, ns_o),stat=ier) + ! Note that any input point that is outside the range [min_valid_value,max_valid_value] + ! will be ignored; this ignores input points with value of unsetmon + allocate(data_o(min_valid_value:max_valid_value, ns_o),stat=ier) if (ier/=0) call shr_sys_abort() - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, nsoilcol, rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, min_valid_value, max_valid_value, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(subname//'after regrid rawdata in '//trim(subname)) - - - - ! Note that any input point that is outside the range [min_valid_value,max_valid_value] - ! will be ignored; this ignores input points with value of unsetmon - call get_dominant_indices(tgridmap, agfirepkmon_i, agfirepkmon_o, & - min_valid_value, max_valid_value, miss, mask_src=tdomain%mask) + do no = 1,ns_o + max_index = maxloc(data_o(:,no)) + agfirepkmon_o(no) = max_index(1) + end do ! Check validity of output data if (min_bad(agfirepkmon_o, min_valid, 'agfirepkmon') .or. & @@ -170,58 +173,61 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) ! calling output_diagnostics_index. ! ----------------------------------------------------------------- - nagfirepkmon = maxval(agfirepkmon_i) - allocate(gast_i(1:nagfirepkmon),gast_o(1:nagfirepkmon),month(1:nagfirepkmon)) - call define_months(nagfirepkmon, month) +! nagfirepkmon = maxval(agfirepkmon_i) +! allocate(gast_i(1:nagfirepkmon),gast_o(1:nagfirepkmon),month(1:nagfirepkmon)) +! call define_months(nagfirepkmon, month) + +! gast_i(:) = 0.0_r8 +! do ni = 1,ns_i +! k = agfirepkmon_i(ni) +! gast_i(k) = gast_i(k) + area_src(ni)*mask(ni)*re**2 +! end do +! gast_o(:) = 0.0_r8 +! do no = 1,ns_o +! k = agfirepkmon_o(no) +! gast_o(k) = gast_o(k) + area_dst(no)*frac_dst(no)*re**2 +! end do + +! area comparison + +! write (ndiag,*) +! write (ndiag,'(1x,70a1)') ('=',k=1,70) +! write (ndiag,*) 'Agricultural fire peak month Output' +! write (ndiag,'(1x,70a1)') ('=',k=1,70) + +! write (ndiag,*) +! write (ndiag,'(1x,70a1)') ('.',k=1,70) +! write (ndiag,1001) +! 1001 format (1x,'peak month',20x,' input grid area output grid area',/ & +! 1x,33x,' 10**6 km**2',' 10**6 km**2') +! write (ndiag,'(1x,70a1)') ('.',k=1,70) +! write (ndiag,*) + +! do k = 1, nagfirepkmon +! write (ndiag,1002) month(k),gast_i(k)*1.e-6,gast_o(k)*1.e-6 +! 1002 format (1x,a35,f16.3,f17.3) +! end do + + ! Close the file + call pio_closefile(pioid) + call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) + + ! Release memory + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) - gast_i(:) = 0.0_r8 - do ni = 1,ns_i - k = agfirepkmon_i(ni) - gast_i(k) = gast_i(k) + area_src(ni)*mask(ni)*re**2 - end do - gast_o(:) = 0.0_r8 - do no = 1,ns_o - k = agfirepkmon_o(no) - gast_o(k) = gast_o(k) + area_dst(no)*frac_dst(no)*re**2 - end do - - ! area comparison - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Agricultural fire peak month Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,1001) -1001 format (1x,'peak month',20x,' input grid area output grid area',/ & - 1x,33x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - - do k = 1, nagfirepkmon - write (ndiag,1002) month(k),gast_i(k)*1.e-6,gast_o(k)*1.e-6 -1002 format (1x,a35,f16.3,f17.3) - end do - - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- - - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (agfirepkmon_i,gast_i,gast_o,month, frac_dst, mask_r8) - - write (6,*) 'Successfully made Agricultural fire peak month' - write (6,*) + if (root_task) then + write (ndiag,'(a)') 'Successfully made Agricultural fire peak month' + end if end subroutine mkagfirepkmon !=============================================================== subroutine define_months(nagfirepkmon, month) - ! + ! ! Define month strings ! ! input/output variables diff --git a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 index 325a2c6cd1..c3806abda4 100644 --- a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 @@ -4,17 +4,26 @@ module mkdiagnosticsMod ! Output diagnostics to log file !----------------------------------------------------------------------- - use shr_kind_mod, only : r8 => shr_kind_r8 + use ESMF + use shr_kind_mod , only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_abort + use mkutilsMod , only : chkerr + use mkvarctl , only : mpicom, root_task implicit none private +#include + public :: output_diagnostics_area ! output diagnostics for field that is % of grid area public :: output_diagnostics_continuous ! output diagnostics for a continuous (real-valued) field public :: output_diagnostics_continuous_outonly ! output diagnostics for a continuous (real-valued) field ! just on the output grid public :: output_diagnostics_index ! output diagnostics for an index field + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + !=============================================================== contains !=============================================================== @@ -36,12 +45,17 @@ subroutine output_diagnostics_area(area_i, area_o, mask_i, data_i, data_o, name, integer , intent(in) :: ndiag ! local variables: - real(r8) :: gdata_i ! global sum of input data - real(r8) :: gdata_o ! global sum of output data - real(r8) :: garea_i ! global sum of input area - real(r8) :: garea_o ! global sum of output area - integer :: ns_i, ns_o ! sizes of input & output grids - integer :: ni,no,k ! indices + real(r8) :: loc_gdata_i ! local_global sum of input data + real(r8) :: loc_gdata_o ! local_global sum of output data + real(r8) :: gdata_i ! global sum of input data + real(r8) :: gdata_o ! global sum of output data + real(r8) :: loc_garea_i ! local global sum of input area + real(r8) :: loc_garea_o ! local global sum of output area + real(r8) :: garea_i ! global sum of input area + real(r8) :: garea_o ! global sum of output area + integer :: ns_i, ns_o ! sizes of input & output grids + integer :: ni,no,k ! indices + integer :: ier ! error code character(len=*), parameter :: subname = "output_diagnostics_area" !------------------------------------------------------------------------------ @@ -57,20 +71,22 @@ subroutine output_diagnostics_area(area_i, area_o, mask_i, data_i, data_o, name, end if ! Sums on input grid - gdata_i = 0. - garea_i = 0. + loc_gdata_i = 0. + loc_garea_i = 0. do ni = 1,ns_i - garea_i = garea_i + area_i(ni) * re**2 - gdata_i = gdata_i + data_i(ni) * area_i(ni) * mask_i(ni) * re**2 + loc_garea_i = loc_garea_i + area_i(ni) * re**2 + loc_gdata_i = loc_gdata_i + data_i(ni) * area_i(ni) * mask_i(ni) * re**2 end do + call mpi_reduce(loc_gdata_i,gdata_i,1,MPI_REAL8,MPI_SUM,0,mpicom,ier) ! Sums on output grid - gdata_o = 0. - garea_o = 0. + loc_gdata_o = 0. + loc_garea_o = 0. do no = 1,ns_o - garea_o = garea_o + area_o(no) * re**2 - gdata_o = gdata_o + data_o(no) * area_o(no) * re**2 + loc_garea_o = loc_garea_o + area_o(no) * re**2 + loc_gdata_o = loc_gdata_o + data_o(no) * area_o(no) * re**2 end do + call mpi_reduce(loc_gdata_o,gdata_o,1,MPI_REAL8,MPI_SUM,0,mpicom,ier) ! Correct units if (percent) then @@ -79,26 +95,25 @@ subroutine output_diagnostics_area(area_i, area_o, mask_i, data_i, data_o, name, end if ! Diagnostic output - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) trim(name), ' Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) -2001 format (1x,'surface type input grid area output grid area'/ & - 1x,' 10**6 km**2 10**6 km**2 ') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2002) name, gdata_i*1.e-06, gdata_o*1.e-06 - write (ndiag,2002) 'all surface', garea_i*1.e-06, garea_o*1.e-06 -2002 format (1x,a12, f14.3,f17.3) + if (root_task) then + write(ndiag,*) + write(ndiag,*) + write(ndiag,'(1x,70a1)') ('.',k=1,70) + write(ndiag,'(a)') ' diagnostics for '//trim(name) + write (ndiag,201) +201 format (1x,'surface type input grid area output grid area'/ & + 1x,' 10**6 km**2 10**6 km**2 ') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + write (ndiag,202) name, gdata_i*1.e-06, gdata_o*1.e-06 + write (ndiag,202) 'all surface', garea_i*1.e-06, garea_o*1.e-06 +202 format (1x,a12, f14.3,f17.3) + end if end subroutine output_diagnostics_area !=============================================================== - subroutine output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + subroutine output_diagnostics_continuous(area_i, area_o, mask_i, frac_o, & data_i, data_o, name, units, ndiag) ! Output diagnostics for a continuous field (but not area, for @@ -107,8 +122,8 @@ subroutine output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & use mkvarpar, only : re ! !ARGUMENTS: - type(ESMF_Mesh) , intent(in) :: mesh_i - type(ESMF_Mesh) , intent(in) :: mesh_o + real(r8) , intent(in) :: area_i(:) + real(r8) , intent(in) :: area_o(:) integer , intent(in) :: mask_i(:) real(r8) , intent(in) :: frac_o(:) real(r8) , intent(in) :: data_i(:) ! data on input grid @@ -118,22 +133,21 @@ subroutine output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & integer , intent(in) :: ndiag ! !LOCAL VARIABLES: + real(r8) :: loc_gdata_i ! local sum of input data + real(r8) :: loc_gdata_o ! local sum of output data real(r8) :: gdata_i ! global sum of input data real(r8) :: gdata_o ! global sum of output data + real(r8) :: loc_gwt_i ! local global sum of input weights (area * frac) + real(r8) :: loc_gwt_o ! local global sum of output weights (area * frac) real(r8) :: gwt_i ! global sum of input weights (area * frac) real(r8) :: gwt_o ! global sum of output weights (area * frac) integer :: ns_i, ns_o ! sizes of input & output grids integer :: ni,no,k ! indices + integer :: ier ! error code character(len=*), parameter :: subname = "output_diagnostics_continuous" !------------------------------------------------------------------------------ ! Error check for array size consistencies - - call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (size(data_i) /= ns_i .or. size(data_o) /= ns_o) then write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) write(6,*) 'size(data_i) = ', size(data_i) @@ -156,41 +170,40 @@ subroutine output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & end if ! Sums on input grid - gdata_i = 0. - gwt_i = 0. + loc_gdata_i = 0. + loc_gwt_i = 0. do ni = 1,ns_i - gdata_i = gdata_i + data_i(ni) * area_i(ni) * mask_i(ni) - gwt_i = gwt_i + area_i(ni) * mask_i(ni) + loc_gdata_i = loc_gdata_i + data_i(ni) * area_i(ni) * mask_i(ni) + loc_gwt_i = loc_gwt_i + area_i(ni) * mask_i(ni) end do + call mpi_reduce(loc_gdata_i,gdata_i,1,MPI_REAL8,MPI_SUM,0,mpicom,ier) ! Sums on output grid - gdata_o = 0. - gwt_o = 0. + loc_gdata_o = 0. + loc_gwt_o = 0. do no = 1,ns_o - gdata_o = gdata_o + data_o(no) * area_o(no) * frac_o(no) - gwt_o = gwt_o + area_o(no) * frac_o(no) + loc_gdata_o = loc_gdata_o + data_o(no) * area_o(no) * frac_o(no) + loc_gwt_o = loc_gwt_o + area_o(no) * frac_o(no) end do + call mpi_reduce(loc_gdata_o,gdata_o,1,MPI_REAL8,MPI_SUM,0,mpicom,ier) ! Correct units gdata_i = gdata_i / gwt_i gdata_o = gdata_o / gwt_o ! Diagnostic output - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) trim(name), ' Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) - write (ndiag,2002) units, units -2001 format (1x,' parameter input grid output grid') -2002 format (1x,' ', a24, a24) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2003) name, gdata_i, gdata_o -2003 format (1x,a12, f22.3,f17.3) + if (root_task) then + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,2001) + write (ndiag,2002) units, units +2001 format (1x,' parameter input grid output grid') +2002 format (1x,' ', a24, a24) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + write (ndiag,2003) name, gdata_i, gdata_o +2003 format (1x,a12, f22.3,f17.3) + end if end subroutine output_diagnostics_continuous @@ -241,22 +254,20 @@ subroutine output_diagnostics_continuous_outonly(area_o, frac_o, data_o, name, u gdata_o = gdata_o / gwt_o ! Diagnostic output - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) trim(name), ' Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) - write (ndiag,2002) units -2001 format (1x,' parameter output grid') -2002 format (1x,' ', a24) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2003) name, gdata_o -2003 format (1x,a12, f22.3) - + if (root_task) then + write (ndiag,*) + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,2001) + write (ndiag,2002) units +2001 format (1x,' parameter output grid') +2002 format (1x,' ', a24) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + write (ndiag,2003) name, gdata_o +2003 format (1x,a12, f22.3) + end if + end subroutine output_diagnostics_continuous_outonly !=============================================================== @@ -279,18 +290,21 @@ subroutine output_diagnostics_index(area_i, area_o, mask_i, frac_o, data_i, data integer , intent(in) :: ndiag ! unit number for diagnostic output ! local variables: - integer :: ns_i, ns_o ! sizes of input & output grids - integer :: ni, no, k ! indices - real(r8), allocatable :: garea_i(:) ! input grid: global area of each index - real(r8), allocatable :: garea_o(:) ! output grid: global area of each index - integer :: ier ! error status + integer :: ns_i, ns_o ! sizes of input & output grids + integer :: ni, no, k ! indices + real(r8), allocatable :: loc_garea_i(:) ! input grid: global area of each index + real(r8), allocatable :: loc_garea_o(:) ! output grid: global area of each index + real(r8), allocatable :: garea_i(:) ! input grid: global area of each index + real(r8), allocatable :: garea_o(:) ! output grid: global area of each index + integer :: ier ! error status character(len=*), parameter :: subname = 'output_diagnostics_index' !----------------------------------------------------------------------- ! Error check for array size consistencies - ns_i = na - ns_o = nb + ns_i = size(area_i) + ns_o = size(area_o) + if (size(data_i) /= ns_i .or. size(data_o) /= ns_o) then write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) write(6,*) 'size(data_i) = ', size(data_i) @@ -313,46 +327,45 @@ subroutine output_diagnostics_index(area_i, area_o, mask_i, frac_o, data_i, data end if ! Sum areas on input grid + allocate(loc_garea_i(minval:maxval), stat=ier) allocate(garea_i(minval:maxval), stat=ier) if (ier/=0) call shr_sys_abort() - garea_i(:) = 0. + loc_garea_i(:) = 0. do ni = 1, ns_i k = data_i(ni) if (k >= minval .and. k <= maxval) then - garea_i(k) = garea_i(k) + area_i(ni) * mask_i(ni) * re**2 + loc_garea_i(k) = loc_garea_i(k) + area_i(ni) * mask_i(ni) * re**2 end if end do + call mpi_reduce(loc_garea_i, garea_i, size(garea_i), size(garea_i), MPI_REAL8, MPI_SUM, 0, mpicom, ier) ! Sum areas on output grid + allocate(loc_garea_o(minval:maxval), stat=ier) allocate(garea_o(minval:maxval), stat=ier) if (ier/=0) call shr_sys_abort() - garea_o(:) = 0. + loc_garea_o(:) = 0. do no = 1, ns_o k = data_o(no) if (k >= minval .and. k <= maxval) then - garea_o(k) = garea_o(k) + area_o(no) * frac_o(no) * re**2 + loc_garea_o(k) = garea_o(k) + area_o(no) * frac_o(no) * re**2 end if end do + call mpi_reduce(loc_garea_o, garea_o, size(garea_o), size(garea_o), MPI_REAL8, MPI_SUM, 0, mpicom, ier) ! Write results - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) trim(name), ' Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) -2001 format (1x,'index input grid area output grid area',/ & - 1x,' 10**6 km**2 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - do k = minval, maxval - write (ndiag,2002) k, garea_i(k)*1.e-06, garea_o(k)*1.e-06 -2002 format (1x,i9,f17.3,f18.3) - end do - - ! Deallocate memory - deallocate(garea_i, garea_o) + if (root_task) then + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,2001) +2001 format (1x,'index input grid area output grid area',/ & + 1x,' 10**6 km**2 10**6 km**2') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + do k = minval, maxval + write (ndiag,2002) k, garea_i(k)*1.e-06, garea_o(k)*1.e-06 +2002 format (1x,i9,f17.3,f18.3) + end do + end if end subroutine output_diagnostics_index diff --git a/tools/mksurfdata_esmf/src/mkdomainMod.F90 b/tools/mksurfdata_esmf/src/mkdomainMod.F90 new file mode 100644 index 0000000000..f994265a11 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkdomainMod.F90 @@ -0,0 +1,53 @@ +module mkdomainMod + + !------------------------------- + ! Determine lon/lat of model + !------------------------------- + + use ESMF + use shr_kind_mod, only : r8 => shr_kind_r8 + use mkutilsMod , only : chkerr + + implicit none + private + + public :: mkdomain + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + +!================================================================================= +contains +!================================================================================= + + subroutine mkdomain(mesh_o, lon_o, lat_o, rc) + + ! input output variables + type(ESMF_Mesh) , intent(in) :: mesh_o + real(r8) , intent(out) :: lon_o(:) + real(r8) , intent(out) :: lat_o(:) + integer , intent(out) :: rc + + ! local variables: + integer :: no + integer :: ns_o + integer :: spatialDim + real(r8), allocatable :: ownedElemCoords(:) + character(len=*), parameter :: subname = 'mkdomain' + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + call ESMF_MeshGet(mesh_o, spatialDim=spatialDim, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(ownedElemCoords(spatialDim*ns_o)) + call ESMF_MeshGet(mesh_o, ownedElemCoords=ownedElemCoords, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do no = 1,ns_o + lon_o(no) = ownedElemCoords(2*no-1) + lat_o(no) = ownedElemCoords(2*no) + end do + + end subroutine mkdomain + +end module mkdomainMod diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 3ddc952c73..e5cb211e6b 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -34,17 +34,19 @@ module mkfileMod contains !================================================================================= - subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & + subroutine mkfile_fsurdat(nx, ny, mesh_o, lon, lat, dynlanduse, & pctlak, pctwet, lakedepth, organic, soil_color, nsoilcol, & urban_classes_g, urban_region, pctsand, pctclay, mapunits, fmaxsoil, soildepth, & glacier_region, ef_btr, ef_fet, ef_fdt, ef_shr, ef_grs, ef_crp, & pctgla, pctglcmec, topoglcmec, pctglcmec_gic, pctglcmec_icesheet, pctglc_gic, & - pctglc_icesheet, rc) + pctglc_icesheet, fpeat, rc) ! input/output variables integer , intent(in) :: nx integer , intent(in) :: ny type(ESMF_Mesh) , intent(in) :: mesh_o + real(r8) , intent(in) :: lon(:) + real(r8) , intent(in) :: lat(:) logical , intent(in) :: dynlanduse real(r8) , intent(in) :: pctlak(:) ! percent of grid cell that is lake real(r8) , intent(in) :: pctwet(:) ! percent of grid cell that is wetland @@ -73,6 +75,7 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & real(r8) , intent(in) :: pctglcmec_icesheet(:,:) real(r8) , intent(in) :: pctglc_gic(:) real(r8) , intent(in) :: pctglc_icesheet(:) + real(r8) , intent(in) :: fpeat(:) integer , intent(out):: rc #ifdef TODO type(harvestDataType) , intent(in) :: harvdata @@ -80,16 +83,18 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & ! local variables type(file_desc_t) :: pioid + type(var_desc_t) :: pio_varid character(len=256) :: varname character(len=256) :: longname character(len=256) :: units integer :: xtype ! external type - integer, allocatable :: ind1D(:) ! Indices of 1D harvest variables - integer, allocatable :: ind2D(:) ! Indices of 2D harvest variables - integer :: rcode - integer :: n, i + integer :: dimid logical :: define_mode character(len=256) :: lev1name + integer, allocatable :: ind1D(:) ! Indices of 1D harvest variables + integer, allocatable :: ind2D(:) ! Indices of 2D harvest variables + integer :: n, i ! Indices + integer :: rcode ! Error status character(len=*), parameter :: subname=' (mkfile_fsurdat) ' !----------------------------------------------------------------------- @@ -130,46 +135,90 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & rcode = pio_enddef(pioid) end if + ! Write out non-spatial variables + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out mksoil_color" + if (define_mode) then + rcode = pio_def_var(pioid, 'mxsoil_color', PIO_INT, pio_varid) + rcode = pio_put_att(pioid, pio_varid, 'long_name', 'maximum numbers of soil colors') + rcode = pio_put_att(pioid, pio_varid, 'units', 'unitless') + else + rcode = pio_inq_varid(pioid, 'mxsoil_color', pio_varid) + rcode = pio_put_var(pioid, pio_varid, nsoilcol) + end if + + if (.not. dynlanduse) then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out GLC_MEC" + if (define_mode) then + rcode = pio_inq_dimid(pioid, 'nglcecp1', dimid) + rcode = pio_def_var(pioid, 'GLC_MEC', PIO_INT, (/dimid/), pio_varid) + rcode = pio_put_att(pioid, pio_varid, 'long_name', 'Glacier elevation class') + rcode = pio_put_att(pioid, pio_varid, 'm', 'unitless') + else + rcode = pio_inq_varid(pioid, 'GLC_MEC', pio_varid) + rcode = pio_put_var(pioid, pio_varid, nsoilcol) + end if + end if + + ! Write out model grid + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'LONGXY', 'model longitudes', & + 'degrees', lat, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LATIXY" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'LATIXY', 'model latitudes', & + 'degrees', lon, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Write out spatial mapped variables if (.not. dynlanduse) then - ! TODO: implement this with pio - ! call ncd_defvar(ncid=ncid, 'GLC_MEC', xtype=xtype, & - ! dim1name='nglcecp1', long_name='Glacier elevation class', units='m') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out peatland fraction" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'peatf', 'peatland fraction', & + 'unitless', fpeat, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glacier" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLACIER', 'percent glacier', 'unitless', & pctgla, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLC_MEC', & 'percent glacier for each glacier elevation class (% of landunit)', 'unitless', & pctglcmec, lev1name='nglcec', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return if (root_task) write(ndiag, '(a)') trim(subname)//" writing out topo_glc_mec" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'TOPO_GLC_MEC', & 'mean elevation on glacier elevation classes', 'm', & topoglcmec, lev1name='nglcec', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return if ( outnc_3dglc ) then if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec_gic" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLC_MEC_GIC', & 'percent smaller glaciers and ice caps for each glacier elevation class (% of landunit)', 'unitless', & pctglcmec_gic, lev1name='nglcec', rc=rc) - + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec_icesheet" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLC_MEC_ICESHEET', & 'percent ice sheet for each glacier elevation class (% of landunit)', 'unitless', & pctglcmec_icesheet, lev1name='nglcec', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_gic" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLC_GIC', & 'percent ice caps/glaciers (% of landunit)', 'unitless', & pctglc_gic, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_icesheet" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLC_ICESHEET', & 'percent ice sheet (% of landunit)', 'unitless', & pctglc_icesheet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_lake" diff --git a/tools/mksurfdata_esmf/src/mkpeatMod.F90 b/tools/mksurfdata_esmf/src/mkpeatMod.F90 index 610a62d89f..70a0b5e00f 100644 --- a/tools/mksurfdata_esmf/src/mkpeatMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpeatMod.F90 @@ -13,11 +13,13 @@ module mkpeatMod use mkpioMod , only : mkpio_iodesc_rawdata, mkpio_get_rawdata_level use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas use mkutilsMod , only : chkerr - use mkvarctl , only : ndiag, root_task, outnc_3dglc + use mkvarctl , only : ndiag, root_task, mpicom implicit none private +#include + public :: mkpeat ! regrid peat data character(len=*) , parameter :: u_FILE_u = & @@ -27,20 +29,20 @@ module mkpeatMod contains !=============================================================== - subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, organic_o, rc) + subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) use mkdiagnosticsMod, only : output_diagnostics_area use mkchecksMod , only : min_bad, max_bad ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o - real(r8) , intent(out) :: peat_o(:,:) ! output grid: fraction peat + real(r8) , intent(inout) :: peat_o(:) ! output grid: fraction peat integer , intent(out) :: rc ! local variables: - type(ESMF_RouteHandle) :: routehandle ! nearest neighbor routehandle + type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid integer :: ni,no,k @@ -65,7 +67,7 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, organic_o, rc) character(len=*), parameter :: subname = 'mkpeat' !----------------------------------------------------------------------- - if (root_task) + if (root_task) then write(ndiag,*) write(ndiag,'(a)') 'Attempting to make peat .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) @@ -109,7 +111,7 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, organic_o, rc) ! Read in peat_i allocate(peat_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'peat', mesh_i, peat_i, rc=rc) + call mkpio_get_rawdata(pioid, 'peatf', mesh_i, peat_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -124,17 +126,22 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, organic_o, rc) call regrid_rawdata(mesh_i, mesh_o, routehandle, peat_i, peat_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (min_bad(peat_o, min_valid, 'peat') .or. max_bad(peat_o, max_valid, 'peat')) then - call shr_abort() + call shr_sys_abort(subname//" peat_o does not fall in range of min_valid/max_valid") end if -#ifdef TODO - ! call output_diagnostics_area(area_i, area_o, mask_i, peat_i, peat_o, 'peat', .true., ndiag) -#endif - - ! Close the file + ! Close the file call pio_closefile(pioid) call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) + ! Output diagnostic info + allocate(area_i(ns_i)) + allocate(area_o(ns_o)) + call get_meshareas(mesh_i, area_i, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call get_meshareas(mesh_o, area_o, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call output_diagnostics_area(area_i, area_o, mask_i, peat_i, peat_o, 'peat', .true., ndiag) + ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index 92806d7ec7..1704f56055 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -1,18 +1,26 @@ module mkpftMod - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkvarpar , only : noveg - use mkvarctl , only : numpft - use mkdomainMod , only : domain_checksame + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkpioMod , only : mkpio_iodesc_rawdata, mkpio_get_rawdata_level + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkutilsMod , only : chkerr + use mkvarctl , only : ndiag, root_task, outnc_3dglc, numpft + use mkvarpar , only : noveg + use mkvarctl , only : numpft use mkpftConstantsMod implicit none private ! By default make data private - public mkpftInit ! Initialization - public mkpft ! Set PFT - public mkpft_parse_oride ! Parse the string with PFT fraction/index info to override - public mkpftAtt ! Write out attributes to output file on pft + public :: mkpftInit ! Initialization + public :: mkpft ! Set PFT + public :: mkpft_parse_oride ! Parse the string with PFT fraction/index info to override + public :: mkpftAtt ! Write out attributes to output file on pft private :: mkpft_check_oride ! Check the pft_frc and pft_idx values for correctness @@ -61,11 +69,11 @@ subroutine mkpftInit( zero_out_l, all_veg_l ) ! use mkvarpar, only : numstdpft, numstdcft - ! !ARGUMENTS: - logical, intent(IN) :: zero_out_l ! If veg should be zero'ed out - logical, intent(IN) :: all_veg_l ! If should zero out other fractions so that all land-cover is vegetation + ! input/output variables + logical, intent(in) :: zero_out_l ! If veg should be zero'ed out + logical, intent(in) :: all_veg_l ! If should zero out other fractions so that all land-cover is vegetation - ! !LOCAL VARIABLES: + ! local variables: logical :: error_happened ! If an error was triggered so should return real(r8), parameter :: hndrd = 100.0_r8 ! A hundred percent character(len=*), parameter :: subname = ' (mkpftInit) ' @@ -162,14 +170,8 @@ subroutine mkpftInit( zero_out_l, all_veg_l ) end subroutine mkpftInit - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkpft - ! - ! !INTERFACE: - subroutine mkpft(ldomain, mapfname, fpft, ndiag, & - pctlnd_o, pctnatpft_o, pctcft_o) + !=============================================================== + subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft_o, rc) ! ! Make PFT data ! @@ -183,73 +185,74 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & ! Upon return from this routine, the % cover of the natural veg + crop landunits is ! generally 100% everywhere; this will be normalized later to account for special landunits. ! - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio use mkpctPftTypeMod, only : pct_pft_type use mkpftConstantsMod, only : natpft_lb, natpft_ub, num_cft, cft_lb, cft_ub ! - ! !ARGUMENTS: - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: fpft ! input pft dataset file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: pctlnd_o(:) ! output grid:%land/gridcell - type(pct_pft_type), intent(out):: pctnatpft_o(:) ! natural PFT cover - type(pct_pft_type), intent(out):: pctcft_o(:) ! crop (CFT) cover + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o + real(r8) , intent(out) :: pctlnd_o(:) ! output grid:%land/gridcell + type(pct_pft_type), intent(out) :: pctnatpft_o(:) ! natural PFT cover + type(pct_pft_type), intent(out) :: pctcft_o(:) ! crop (CFT) cover ! - ! !LOCAL VARIABLES: - type(pct_pft_type), allocatable:: pctnatpft_i(:) ! input grid: natural PFT cover - type(pct_pft_type), allocatable:: pctcft_i(:) ! input grid: crop (CFT) cover - type(domain_type) :: tdomain ! local domain - type(gridmap_type) :: tgridmap ! local gridmap - real(r8), allocatable :: pctpft_i(:,:) ! input grid: PFT percent - real(r8), allocatable :: pctpft_o(:,:) ! output grid: PFT percent (% of grid cell) - real(r8), allocatable :: pctnatveg_i(:) ! input grid: natural veg percent (% of grid cell) - real(r8), allocatable :: pctnatveg_o(:) ! output grid: natural veg percent (% of grid cell) - real(r8), allocatable :: pctcrop_i(:) ! input grid: all crop percent (% of grid cell) - real(r8), allocatable :: pctcrop_o(:) ! output grid: all crop percent (% of grid cell) - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: pct_cft_i(:,:) ! input grid: CFT (Crop Functional Type) percent (% of landunit cell) - real(r8), allocatable :: temp_i(:,:) ! input grid: temporary 2D variable to read in - real(r8), allocatable :: pct_cft_o(:,:) ! output grid: CFT (Crop Functional Type) percent (% of landunit cell) - real(r8), allocatable :: pct_nat_pft_i(:,:) ! input grid: natural PFT percent (% of landunit cell) - real(r8), allocatable :: pct_nat_pft_o(:,:) ! output grid: natural PFT percent (% of landunit cell) - integer :: numpft_i ! num of plant types input data - integer :: natpft_i ! num of natural plant types input data - integer :: ncft_i ! num of crop types input data - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: wst_sum ! sum of %pft - real(r8), allocatable :: gpft_o(:) ! output grid: global area pfts - real(r8) :: garea_o ! output grid: global area - real(r8), allocatable :: gpft_i(:) ! input grid: global area pfts - real(r8) :: garea_i ! input grid: global area - integer :: k,n,m,ni,no,ns_i,ns_o ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ndims ! number of dimensions for a variable on the file - integer :: dimlens(3) ! dimension lengths for a variable on the file - integer :: ier ! error status - real(r8) :: relerr = 0.0001_r8 ! max error: sum overlap wts ne 1 - logical :: oldformat ! if input file is in the old format or not (based on what variables exist) - logical :: error_happened ! If an error was triggered so should return - - character(len=35) veg(0:maxpft) ! vegetation types - character(len=32) :: subname = 'mkpftMod::mkpft()' + ! local variables: + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + integer :: ni,no,k + integer :: ns_i, ns_o + integer , allocatable :: mask_i(:) + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + type(pct_pft_type), allocatable :: pctnatpft_i(:) ! input grid: natural PFT cover + type(pct_pft_type), allocatable :: pctcft_i(:) ! input grid: crop (CFT) cover + real(r8), allocatable :: pctpft_i(:,:) ! input grid: PFT percent + real(r8), allocatable :: pctpft_o(:,:) ! output grid: PFT percent (% of grid cell) + real(r8), allocatable :: pctnatveg_i(:) ! input grid: natural veg percent (% of grid cell) + real(r8), allocatable :: pctnatveg_o(:) ! output grid: natural veg percent (% of grid cell) + real(r8), allocatable :: pctcrop_i(:) ! input grid: all crop percent (% of grid cell) + real(r8), allocatable :: pctcrop_o(:) ! output grid: all crop percent (% of grid cell) + real(r8), allocatable :: pct_cft_i(:,:) ! input grid: CFT (Crop Functional Type) percent (% of landunit cell) + real(r8), allocatable :: pct_cft_o(:,:) ! output grid: CFT (Crop Functional Type) percent (% of landunit cell) + real(r8), allocatable :: pct_nat_pft_i(:,:) ! input grid: natural PFT percent (% of landunit cell) + real(r8), allocatable :: pct_nat_pft_o(:,:) ! output grid: natural PFT percent (% of landunit cell) + real(r8), allocatable :: temp_i(:,:) ! input grid: temporary 2D variable to read in + integer :: numpft_i ! num of plant types input data + integer :: natpft_i ! num of natural plant types input data + integer :: ncft_i ! num of crop types input data + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: wst_sum ! sum of %pft + real(r8), allocatable :: gpft_o(:) ! output grid: global area pfts + real(r8) :: garea_o ! output grid: global area + real(r8), allocatable :: gpft_i(:) ! input grid: global area pfts + real(r8) :: garea_i ! input grid: global area + integer :: k,n,m,ni,no,ns_i,ns_o ! indices + integer :: ndims ! number of dimensions for a variable on the file + integer :: dimlens(3) ! dimension lengths for a variable on the file + integer :: ier ! error status + real(r8) :: relerr = 0.0001_r8 ! max error: sum overlap wts ne 1 + logical :: error_happened ! If an error was triggered so should return + character(len=35) :: veg(0:maxpft) ! vegetation types + character(len=*), parameter :: subname = 'mkpf' !----------------------------------------------------------------------- - write (6,*) - write (6, '(a, a, a)') "In ", subname, "..." - write (6,*) 'Attempting to make PFTs .....' + if (root_task) + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make PFTs .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) + end if ! ----------------------------------------------------------------- ! Set the vegetation types ! ----------------------------------------------------------------- - if ( numpft >= numstdpft )then - veg(0:maxpft) = (/ & + if ( numpft >= numstdpft ) then + veg(0:maxpft) = (/ & 'not vegetated ', & 'needleleaf evergreen temperate tree', & 'needleleaf evergreen boreal tree ', & @@ -346,141 +349,132 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & ! Read input PFT file ! ----------------------------------------------------------------- - ns_o = size(pctlnd_o) + ! Open input data file + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) + + ! Read in input mesh + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Determine ns_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the landmask from the file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (frac_i(ni) > 0._r4) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return if ( .not. presc_cover ) then - ! Obtain input grid info, read PCT_PFT - - ! create field on input mesh (first read in input mesh) - call ESMF_VMLogMemInfo("Before create mesh_i in lanwat") - mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create mesh_i in lanwat") - - if (root_task) then - write (ndiag,'(a)') 'Opening PFT file: '//trim(fpft) - end if - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(fpft), pio_nowrite) - - call check_ret(nf_inq_dimid (ncid, 'natpft', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, natpft_i), subname) - call check_ret(nf_inq_dimid (ncid, 'cft', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, ncft_i), subname) + ! get dimensions + rcode = pio_inq_dimid(pioid, 'natpft', dimid) + rcode = pio_inq_dimlen(pioid, dimid, natpft_i) + rcode = pio_inq_dimid(pioid, 'cft', dimid) + rcode = pio_inq_dimlen(pioid, dimid, ncfg_i) numpft_i = natpft_i + ncft_i ! Check if the number of pfts on the input matches the expected number. A mismatch ! is okay if the input raw dataset has prognostic crops and the output does not. - if (numpft_i .ne. numpft+1) then - if (numpft_i .eq. numstdpft+1) then + if (numpft_i /= numpft+1) then + if (numpft_i == numstdpft+1) then write(6,*) subname//' ERROR: trying to use non-crop input file' write(6,*) 'for a surface dataset with crops.' call shr_sys_abort() - return else if (numpft_i > numstdpft+1 .and. numpft_i == maxpft+1) then write(6,*) subname//' WARNING: using a crop input raw dataset for a non-crop output surface dataset' else write(6,*) subname//': parameter numpft+1= ',numpft+1, & 'does not equal input dataset numpft= ',numpft_i call shr_sys_abort() - return end if endif - ! TODO: create a route handle - ! for starts just do everything on one processor to make sure it works - - ! TODO: determine local number of points and allocate memory only for the local number - ! the local number can be determined from the mesh - ! TODO: initialize pio and set global decomposition + ! Create a route handle between the input and output mesh and get frac_o + allocate(frac_o(ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - ! If file is in the new format, expect the following variables: - ! PCT_NATVEG, PCT_CROP, PCT_NAT_PFT, PCT_CFT + ! Allocate memory allocate(pctnatveg_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - allocate(pctnatveg_o(ns_o), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(pctcrop_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() allocate(pctcrop_o(ns_o), stat=ier) - allocate(frac_dst(ns_o), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(pct_cft_i(ns_i,1:num_cft), stat=ier) + if (ier/=0) call shr_sys_abort() allocate(pct_cft_o(ns_o,1:num_cft), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(pct_nat_pft_i(ns_i,0:num_natpft), stat=ier) + if (ier/=0) call shr_sys_abort() allocate(pct_nat_pft_o(ns_o,0:num_natpft), stat=ier) + if (ier/=0) call shr_sys_abort() - ! Open the raw data file - call ESMF_VMLogMemInfo("Before pio_openfile in regrid_data for "//trim(filename)) - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(filename), pio_nowrite) - - ! Create an io descriptor - call ESMF_VMLogMemInfo("After pio_openfile in mkpftMod") - call mkpio_iodesc_rawdata(mesh_i, 'PCT_NATVEG', pioid, pio_varid, pio_vartype, pio_iodesc, rc) + ! Read in 1d data + call mkpio_get_rawdata(pioid, 'PCT_NATVEG', mesh_i, pctnatveg_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call mkpio_get_rawdata(pioid, 'PCT_CROP', mesh_i, pctcrop_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After mkpio_iodesc in mkpftMod") - - ! Read in - if (pio_vartype == PIO_REAL) then - allocate(data_real(ns_i)) - call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real, rcode) - data_i(:) = real(data_real(:), kind=r8) - deallocate(data_real) - else if (pio_vartype == PIO_DOUBLE) then - allocate(data_double(ns_i)) - call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double, rcode) - data_i(:) = data_double(:) - deallocate(data_double) - else - call shr_sys_abort(subName//"ERROR: only real and double types are supported") - end if - - - call pio_freedecomp(pioid, pio_iodesc) - call pio_closefile(pioid) - call ESMF_VMLogMemInfo("After pio_read_darry in regrid_data") - - - - call check_ret(nf_inq_varid (ncid, 'PCT_NATVEG', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, pctnatveg_i), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_CROP', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, pctcrop_i), subname) + ! Read in 2d data if ( .not. use_input_pft )then - call check_ret(nf_inq_varid (ncid, 'PCT_CFT', varid), subname) - call get_dim_lengths(ncid, 'PCT_CFT', ndims, dimlens(:) ) - if ( ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) == num_cft )then - call check_ret(nf_get_var_double (ncid, varid, pct_cft_i), subname) + allocate(data_cft_i(1:numcft, ns_i) + if (ier/=0) call shr_sys_abort() + + call mkpio_get_dimlengths(pioid, 'PCT_CFT', ndims, dimlens(:)) + if (ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) == num_cft )then + call mkpio_get_rawdata(pioid, 'PCT_CFT', mesh_i, data_cft_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return else if ( ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) > num_cft )then - ! Read in the whole array: then sum the rainfed and irrigated - ! seperately - allocate( temp_i(ns_i,dimlens(3)) ) - call check_ret(nf_get_var_double (ncid, varid, temp_i), subname) + ! Read in the whole array: then sum the rainfed and irrigated seperately + allocate(temp_i(dimlens(3),ns_i)) + call mkpio_get_rawdata(pioid, 'PCT_CFT', mesh_i, temp_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return do n = 1, num_cft - pct_cft_i(:,n) = 0.0_r8 + data_cft_i(n,:) = 0.0_r8 do m = n, dimlens(3), 2 - pct_cft_i(:,n) = pct_cft_i(:,n) + temp_i(:,m) + data_cft_i(n,:) = data_cft_i(n,:) + temp_i(m,:) end do end do deallocate( temp_i ) else - write(6,*) subname//': ERROR: dimensions for PCT_CROP are NOT what is expected' - call shr_sys_abort() - return + call shr_sys_abort(subname//' error: dimensions for PCT_CROP are NOT what is expected') end if - call check_ret(nf_inq_varid (ncid, 'PCT_NAT_PFT', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, pct_nat_pft_i), subname) - end if - call check_ret(nf_close(ncid), subname) + allocate(data_nat_pft_i(0:num_natpft,ns_i) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'PCT_NAT_PFT', mesh_i, data_nat_pft_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if - ! ----------------------------------------------------------------- - ! Otherwise if vegetation is prescribed everywhere - ! ----------------------------------------------------------------- else + ns_i = 1 numpft_i = numpft+1 allocate(pctnatveg_i(ns_i), & @@ -508,8 +502,8 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & end if ! Determine pctpft_o on output grid - ! If total vegetation cover is prescribed from input... + if ( use_input_pft .and. presc_cover ) then do no = 1,ns_o @@ -518,39 +512,32 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & pctcrop_o(no) = pft_override%crop end do - ! otherewise if total cover isn't prescribed read it from the datasets + ! otherewise if total cover isn't prescribed read it from the datasets else ! Compute pctlnd_o, pctpft_o - - ! TODO: create a route handle here - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - ! TODO: remove this check - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + call regrid_rawdata(mesh_i, mesh_o, routehandle, pctnatveg_i, pctnatveg_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, pctcrop_i, pctcrop_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Area-average percent cover on input grid [pctpft_i] to output grid ! [pctpft_o] and correct [pctpft_o] according to land landmask ! Note that percent cover is in terms of total grid area. - pctlnd_o(:) = frac_dst(:) * 100._r8 - - ! New format with extra variables on input - call gridmap_areaave_srcmask(tgridmap, pctnatveg_i, pctnatveg_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, pctcrop_i, pctcrop_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + pctlnd_o(:) = frac_dst(:) * 100._r8 ! ???? - ! ! If specific PFT/CFT's are NOT prescribed set them from the input file - ! if ( .not. use_input_pft )then do m = 0, num_natpft + + ! multiply data_pct_nat_pft_i(m,:) by pctnatveg_i*0.01_r8*mask_i + ! then regrid that + call gridmap_areaave_scs(tgridmap, pct_nat_pft_i(:,m), & - pct_nat_pft_o(:,m), nodata=0._r8, & - src_wt=pctnatveg_i*0.01_r8*tdomain%mask, & - dst_wt=pctnatveg_o*0.01_r8, frac_dst=frac_dst) + pct_nat_pft_o(:,m), nodata=0._r8, & + src_wt = pctnatveg_i(:)*0.01_r8*mask(:), & + dst_wt = pctnatveg_o(:)*0.01_r8, frac_dst=frac_dst) + do no = 1,ns_o if (pctlnd_o(no) < 1.0e-6 .or. pctnatveg_o(no) < 1.0e-6) then if (m == 0) then @@ -766,34 +753,18 @@ subroutine mkpft(ldomain, mapfname, fpft, ndiag, & end subroutine mkpft !----------------------------------------------------------------------- - - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkpft_parse_oride - ! - ! !INTERFACE: subroutine mkpft_parse_oride( string ) ! - ! !DESCRIPTION: ! Parse the string with pft fraction and index information on it, to override ! the file with this information rather than reading from a file. ! - ! !USES: + use shr_string_mod, only: shr_string_betweenTags, shr_string_countChar + ! !ARGUMENTS: - character(len=256), intent(IN) :: string ! String to parse with PFT fraction - ! and index data - ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: Erik Kluzek - ! + character(len=256), intent(IN) :: string ! String to parse with PFT fraction and index data ! ! !LOCAL VARIABLES: - !EOP integer :: rc ! error return code integer :: num_elms ! number of elements character(len=256) :: substring ! string between tags @@ -836,28 +807,14 @@ subroutine mkpft_parse_oride( string ) end subroutine mkpft_parse_oride !----------------------------------------------------------------------- - - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mkpft_check_oride - ! - ! !INTERFACE: subroutine mkpft_check_oride( error_happened ) ! - ! !DESCRIPTION: ! Check that the pft override values are valid - ! !USES: - implicit none + ! !ARGUMENTS: logical, intent(out) :: error_happened ! Result, true if there was a problem ! - ! !REVISION HISTORY: - ! Author: Erik Kluzek - ! - ! ! !LOCAL VARIABLES: - !EOP integer :: i, j ! indices real(r8) :: sumpft ! Sum of pft_frc real(r8), parameter :: hndrd = 100.0_r8 ! A hundred percent @@ -931,7 +888,6 @@ end subroutine mkpft_check_oride !----------------------------------------------------------------------- subroutine mkpftAtt( ncid, dynlanduse, xtype ) - ! !DESCRIPTION: ! make PFT attributes on the output file use mkutilsMod , only : get_filename @@ -1090,20 +1046,12 @@ subroutine mkpftAtt( ncid, dynlanduse, xtype ) end subroutine mkpftAtt !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: constructor - ! - ! !INTERFACE: function constructor( ) result(this) ! - ! !DESCRIPTION: ! Construct a new PFT override object ! ! !ARGUMENTS: - implicit none type(pft_oride) :: this - !EOP character(len=32) :: subname = 'mkpftMod::constructor() ' this%crop = -1.0_r8 @@ -1123,24 +1071,17 @@ function constructor( ) result(this) this%natpft(:) = -1.0_r8 this%cft(:) = -1.0_r8 call this%InitZeroOut() - end function constructor + end function constructor !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: InitZeroOut - ! - ! !INTERFACE: subroutine InitZeroOut( this ) ! - ! !DESCRIPTION: ! Initialize a pft_oride object with vegetation that's zeroed out ! ! !ARGUMENTS: - implicit none class(pft_oride), intent(inout) :: this - !EOP + this%crop = 0.0_r8 this%natveg = 0.0_r8 @@ -1148,23 +1089,17 @@ subroutine InitZeroOut( this ) this%natpft(noveg) = 100.0_r8 this%cft = 0.0_r8 this%cft(1) = 100.0_r8 + end subroutine InitZeroOut !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: InitZeroOut - ! - ! !INTERFACE: subroutine InitAllPFTIndex( this ) ! - ! !DESCRIPTION: ! Initialize a pft_oride object with vegetation that's zeroed out ! ! !ARGUMENTS: - implicit none class(pft_oride), intent(inout) :: this - !EOP + integer :: m, i ! Indices real(r8) :: croptot ! Total of crop real(r8) :: natvegtot ! Total of natural vegetation @@ -1205,20 +1140,13 @@ subroutine InitAllPFTIndex( this ) end subroutine InitAllPFTIndex !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: clean - ! - ! !INTERFACE: subroutine Clean( this ) ! - ! !DESCRIPTION: ! Clean up a PFT Oride object ! ! !ARGUMENTS: - implicit none class(pft_oride), intent(inout) :: this - !EOP + this%crop = -1.0_r8 this%natveg = -1.0_r8 deallocate( this%natpft ) @@ -1226,6 +1154,4 @@ subroutine Clean( this ) end subroutine Clean - !----------------------------------------------------------------------- - end module mkpftMod diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index 563482b895..65fad7ffb0 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -14,6 +14,8 @@ module mksoilcolMod implicit none private +#include + public :: mksoilcol ! Set soil colors private :: mkrank @@ -49,13 +51,13 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r real(r4), allocatable :: data_i(:,:) real(r4), allocatable :: data_o(:,:) real(r4), allocatable :: soil_color_i(:) - logical :: has_color ! whether this grid cell has non-zero color + logical :: has_color ! whether this grid cell has non-zero color integer :: nsoilcol_local integer :: maxindex(1) - real(r4), allocatable :: gast_i(:) ! global area, by surface type - real(r4), allocatable :: gast_o(:) ! global area, by surface type - real(r4) :: sum_fldi ! global sum of dummy input fld - real(r4) :: sum_fldo ! global sum of dummy output fld + real(r4), allocatable :: loc_gast_i(:) ! local global area, by surface type + real(r4), allocatable :: loc_gast_o(:) ! local global area, by surface type + real(r4), allocatable :: gast_i(:) ! global area, by surface type + real(r4), allocatable :: gast_o(:) ! global area, by surface type integer :: rcode, ier character(len=*), parameter :: subname = 'mksoilcol' !----------------------------------------------------------------------- @@ -196,8 +198,6 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r ! Compare global area of each soil color on input and output grids - allocate(gast_i(0:nsoilcol)) - allocate(gast_o(0:nsoilcol)) allocate(area_i(ns_i)) allocate(area_o(ns_o)) call get_meshareas(mesh_i, area_i, rc) @@ -205,27 +205,33 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r call get_meshareas(mesh_o, area_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - gast_i(:) = 0. - do ni = 1,ns_i - k = soil_color_i(ni) - gast_i(k) = gast_i(k) + area_i(ni) * mask_i(ni) - end do - gast_o(:) = 0. - do no = 1,ns_o - k = soil_color_o(no) - gast_o(k) = gast_o(k) + area_o(no) * frac_o(no) - end do - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,101) -101 format (1x,'soil color type',5x,' input grid area output grid area',/ & - 1x,20x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - do k = 0, nsoilcol - write (ndiag,'(1x,a,i3,d16.3,d17.3)') 'class ',k, gast_i(k)*1.e-6, gast_o(k)*1.e-6 - end do +! allocate(loc_gast_i(0:nsoilcol)) +! allocate(loc_gast_o(0:nsoilcol)) +! allocate(gast_i(0:nsoilcol)) +! allocate(gast_o(0:nsoilcol)) +! loc_gast_i(:) = 0. +! do ni = 1,ns_i +! k = soil_color_i(ni) +! loc_gast_i(k) = loc_gast_i(k) + area_i(ni) * mask_i(ni) +! end do +! call mpi_reduce(loc_gast_i, gast_i, nsoilcol+1, nsoilcol+1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) +! loc_gast_o(:) = 0. +! do no = 1,ns_o +! k = soil_color_o(no) +! loc_gast_o(k) = loc_gast_o(k) + area_o(no) * frac_o(no) +! end do +! call mpi_reduce(loc_gast_o, gast_o, nsoilcol+1, nsoilcol+1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) + +! write (ndiag,*) +! write (ndiag,'(1x,70a1)') ('.',k=1,70) +! write (ndiag,101) +! 101 format (1x,'soil color type',5x,' input grid area output grid area',/ & +! 1x,20x,' 10**6 km**2',' 10**6 km**2') +! write (ndiag,'(1x,70a1)') ('.',k=1,70) +! write (ndiag,*) +! do k = 0, nsoilcol +! write (ndiag,'(1x,a,i3,d16.3,d17.3)') 'class ',k, gast_i(k)*1.e-6, gast_o(k)*1.e-6 +! end do if (root_task) then write (ndiag,'(a)') 'Successfully made soil color classes' @@ -233,12 +239,6 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r end if ! Clean up memory - deallocate(mask_i) - deallocate(data_i) - deallocate(data_o) - deallocate(area_i) - deallocate(area_o) - deallocate(soil_color_i) call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 1cb2a57036..80f045e276 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -92,21 +92,21 @@ program mksurfdata use pio use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs use shr_sys_mod , only : shr_sys_abort - #ifdef TODO use mklaiMod , only : mklai use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array - use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride use mkharvestMod , only : mkharvest, mkharvest_init, mkharvest_fieldname use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride use mkharvestMod , only : harvestDataType use mkgdpMod , only : mkgdp - use mkpeatMod , only : mkpeat use mkagfirepkmonthMod , only : mkagfirepkmon use mktopostatsMod , only : mktopostats use mkVICparamsMod , only : mkVICparams + use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft #endif + use mkdomainMod , only : mkdomain + use mkpeatMod , only : mkpeat use mkvocefMod , only : mkvocef use mkglcmecMod , only : mkglcmecInit, mkglcmec, mkglacier, nglcec use mkglacierregionMod , only : mkglacierregion @@ -151,6 +151,8 @@ program mksurfdata type(io_desc_t) :: pio_iodesc ! data arrays + real(r8), allocatable :: lon(:) + real(r8), allocatable :: lat(:) real(r8), allocatable :: landfrac_pft(:) ! PFT data: % land per gridcell real(r8), allocatable :: pctlnd_pft(:) ! PFT data: % of gridcell for PFTs real(r8), allocatable :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs @@ -339,16 +341,8 @@ program mksurfdata !allocate ( pctcft(lsize_o)) ; !allocate ( pctcft_max(lsize_o)) ; allocate ( gdp(lsize_o)) ; gdp(:) = spval - allocate ( fpeat(lsize_o)) ; fpeat(:) = spval - allocate ( agfirepkmon(lsize_o)) ; agfirepkmon(:) = -999 allocate ( topo_stddev(lsize_o)) ; topo_stddev(:) = spval allocate ( slope(lsize_o)) ; slope(:) = spval - - ! glacier properties -#ifdef TODO -#endif - - ! vic properties allocate ( vic_binfl(lsize_o)) ; vic_binfl(:) = spval allocate ( vic_ws(lsize_o)) ; vic_ws(:) = spval allocate ( vic_dsmax(lsize_o)) ; vic_dsmax(:) = spval @@ -380,27 +374,21 @@ program mksurfdata ! -------------------------------------------------- ! begin working - !DEBUG - place here for debugging - ! Make glacier multiple elevation classes [pctglcmec,topoglcmec] from [fglacier] dataset - allocate ( pctglcmec(lsize_o,nglcec)) ; pctglcmec(:,:) = spval - allocate ( topoglcmec(lsize_o,nglcec)) ; topoglcmec(:,:)= spval - if ( outnc_3dglc )then - allocate(pctglcmec_gic(lsize_o,nglcec)) - allocate(pctglcmec_icesheet(lsize_o,nglcec)) - allocate(pctglc_gic(lsize_o)) - allocate(pctglc_icesheet(lsize_o)) + ! Make lats/lons of model + allocate (lon(lsize_o)) ; lon(:) = spval + allocate (lat(lsize_o)) ; lat(:) = spval + call mkdomain(mesh_model, lon_o=lon, lat_o=lat, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') - call mkglcmec(mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, & - pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, & - pctglcmec_gic_o=pctglcmec_gic, pctglcmec_icesheet_o=pctglcmec_icesheet, & - pctglc_gic_o=pctglc_gic, pctglc_icesheet_o=pctglc_icesheet, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglcmec') - else - call mkglcmec(mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, & - pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, rc=rc ) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglcmec') - end if - !DEBUG + ! Make peat data [fpeat] from [peatf] + allocate (fpeat(lsize_o)) ; fpeat(:) = spval + call mkpeat ( mksrf_fpeat_mesh, mksrf_fpeat, mesh_model, peat_o=fpeat, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpeat') + + ! Make agricultural fire peak month data [abm] from [abm] + allocate ( agfirepkmon(lsize_o)); agfirepkmon(:) = -999 + ! call mkagfirepkmon (mksrf_fabm_mesh, mksrf_fabm, mesh_model, agfirepkmon_o=agfirepkmon, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkagfirepkmon') ! Make glacier fraction [pctgla] from [fglacier] dataset allocate ( pctgla(lsize_o)) ; pctgla(:) = spval @@ -502,12 +490,6 @@ program mksurfdata ! ! Make GDP data [gdp] from [gdp] ! call mkgdp ( mapfname=map_fgdp, datfname=mksrf_fgdp, ndiag=ndiag, gdp_o=gdp) - ! ! Make peat data [fpeat] from [peatf] - ! call mkpeat ( mapfname=map_fpeat, datfname=mksrf_fpeat, ndiag=ndiag, peat_o=fpeat) - - ! ! Make agricultural fire peak month data [abm] from [abm] - ! call mkagfirepkmon ( mapfname=map_fabm, datfname=mksrf_fabm, ndiag=ndiag, agfirepkmon_o=agfirepkmon) - ! ! Compute topography statistics [topo_stddev, slope] from [ftopostats] ! call mktopostats ( mapfname=map_ftopostats, datfname=mksrf_ftopostats, & ! ndiag=ndiag, topo_stddev_o=topo_stddev, slope_o=slope, std_elev=std_elev) @@ -629,24 +611,25 @@ program mksurfdata ! This call needs to occur after pctgla has been adjusted for the final time - ! allocate ( pctglcmec(lsize_o,nglcec)) ; pctglcmec(:,:) = spval - ! allocate ( topoglcmec(lsize_o,nglcec)) ; topoglcmec(:,:)= spval - ! if ( outnc_3dglc )then - ! allocate(pctglcmec_gic(lsize_o,nglcec)) - ! allocate(pctglcmec_icesheet(lsize_o,nglcec)) - ! allocate(pctglc_gic(lsize_o)) - ! allocate(pctglc_icesheet(lsize_o)) - - ! call mkglcmec(mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, & - ! pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, & - ! pctglcmec_gic_o=pctglcmec_gic, pctglcmec_icesheet_o=pctglcmec_icesheet, & - ! pctglc_gic_o=pctglc_gic, pctglc_icesheet_o=pctglc_icesheet, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglcmec') - ! else - ! call mkglcmec(mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, & - ! pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, rc=rc ) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglcmec') - ! end if + allocate ( pctglcmec(lsize_o,nglcec)) ; pctglcmec(:,:) = spval + allocate ( topoglcmec(lsize_o,nglcec)) ; topoglcmec(:,:)= spval + if ( outnc_3dglc )then + allocate(pctglcmec_gic(lsize_o,nglcec)) + allocate(pctglcmec_icesheet(lsize_o,nglcec)) + allocate(pctglc_gic(lsize_o)) + allocate(pctglc_icesheet(lsize_o)) + end if + if ( outnc_3dglc )then + call mkglcmec(mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, & + pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, & + pctglcmec_gic_o=pctglcmec_gic, pctglcmec_icesheet_o=pctglcmec_icesheet, & + pctglc_gic_o=pctglc_gic, pctglc_icesheet_o=pctglc_icesheet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglcmec') + else + call mkglcmec(mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, & + pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglcmec') + end if ! ---------------------------------------------------------------------- ! Determine fractional land from pft dataset @@ -683,6 +666,8 @@ program mksurfdata call mkfile_fsurdat( nx=mksrf_fgrid_mesh_nx, & ny=mksrf_fgrid_mesh_ny, & mesh_o=mesh_model, & + lon=lon, & + lat=lat, & dynlanduse=.false., & pctlak=pctlak, & pctwet=pctwet, & @@ -711,6 +696,7 @@ program mksurfdata pctglcmec_icesheet=pctglcmec_icesheet, & pctglc_gic=pctglc_gic, & pctglc_icesheet=pctglc_icesheet, & + fpeat=fpeat, & rc=rc) if (root_task) then write(ndiag,*) @@ -723,24 +709,30 @@ program mksurfdata ! Deallocate arrays NOT needed for dynamic-pft section of code ! ---------------------------------------------------------------------- - deallocate ( organic ) - deallocate ( ef1_btr, ef1_fet, ef1_fdt, ef1_shr, ef1_grs, ef1_crp ) - deallocate ( lakedepth ) - deallocate ( soil_color ) - deallocate ( soildepth ) - deallocate ( pctsand, pctclay ) - deallocate ( glacier_region ) - deallocate ( pctglcmec, topoglcmec) - deallocate ( elevclass ) - deallocate ( fmaxsoil ) - if ( outnc_3dglc ) then - deallocate ( pctglc_gic, pctglc_icesheet) + deallocate (organic ) + deallocate (ef1_btr, ef1_fet, ef1_fdt, ef1_shr, ef1_grs, ef1_crp ) + deallocate (lakedepth ) + deallocate (soil_color ) + deallocate (soildepth ) + deallocate (pctsand, pctclay ) + deallocate (glacier_region ) + deallocate (pctglcmec, topoglcmec) + deallocate (elevclass ) + deallocate (fmaxsoil ) + if (outnc_3dglc) then + deallocate (pctglc_gic, pctglc_icesheet) end if - + deallocate(fpeat) #ifdef TODO - deallocate ( gdp, fpeat, agfirepkmon ) - deallocate ( topo_stddev, slope ) - deallocate ( vic_binfl, vic_ws, vic_dsmax, vic_ds ) + deallocate(gdp) + deallocate(agfirepkmon) + deallocate(topo_stddev + deallocate(slope) + deallocate(vic_binfl) + deallocate(vic_ws) + deallocate(vic_dsmax) + deallocate(vic_ds) + deallocate(vic_binfl, vic_ws, vic_dsmax, vic_ds ) call harvdata%clean() #endif diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index 01583af1b6..349260a390 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -1,49 +1,27 @@ module mktopostatsMod !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mktopostatsMod - ! - ! !DESCRIPTION: ! make various topography statistics - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! !----------------------------------------------------------------------- - ! - ! !USES: + use shr_kind_mod, only : r8 => shr_kind_r8 use mkdomainMod , only : domain_checksame implicit none - private - ! !PUBLIC MEMBER FUNCTIONS: - public mktopostats ! make topo stddev & mean slope - ! - !EOP - !=============================================================== + public :: mktopostats ! make topo stddev & mean slope + + type(ESMF_DynamicMask) :: dynamicMask + +!=============================================================== contains - !=============================================================== +!=============================================================== - !----------------------------------------------------------------------- - !BOP - ! - ! !IROUTINE: mktopostats - ! - ! !INTERFACE: subroutine mktopostats(ldomain, mapfname, datfname, ndiag, topo_stddev_o, slope_o, std_elev) ! - ! !DESCRIPTION: ! make various topography statistics ! - ! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkncdio use mkdiagnosticsMod, only : output_diagnostics_continuous, output_diagnostics_continuous_outonly use mkchecksMod, only : min_bad, max_bad ! @@ -90,19 +68,31 @@ subroutine mktopostats(ldomain, mapfname, datfname, ndiag, topo_stddev_o, slope_ bypass_reading = .false. end if - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - if ( .not. bypass_reading )then - call domain_read(tdomain,datfname) - - call gridmap_mapread(tgridmap, mapfname ) - - call gridmap_check( tgridmap, tgridmap%frac_src, tgridmap%frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - + ! Create a dynamic mask object + ! The dynamic mask object further holds a pointer to the routine that will be called in order to + ! handle dynamically masked elements - in this case its DynMaskProc (see below) + call ESMF_DynamicMaskSetR8R8R8(dynamicMask, dynamicSrcMaskValue=czero, dynamicMaskRoutine=DynMaskProc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create a route handle - the normal way + + ! Do the regridding the normal way to create the mean + + ! Compute the standard deviation + ! Use the dynamic masking could be used to do this. + ! dst_array(no) = dst_array(no) + wt * (src_array(ni) - weighted_means(no))**2 part, + ! and then just do a plain sparse matrix multiply on a src Field of all 1.0 to do the + ! weight sum part, and then do the divide and sqrt locally on each PET. + + ! One issue is how to get the weight_means() in for each + ! dest. location. I think that you could pass them in via the + ! dst_array and then pull them out before doing the calculation, but + ! to do so that you to stop it from zeroing out the + ! dst array which you can do by setting + ! zeroregion=ESMF_REGION_EMPTY.This would also depend on the + ! calculation happening only once for each destination location, + ! which I would guess is true, but Gerhard can confirm. + ! ----------------------------------------------------------------- ! Open input file, allocate memory for input data ! ----------------------------------------------------------------- @@ -176,5 +166,48 @@ subroutine mktopostats(ldomain, mapfname, datfname, ndiag, topo_stddev_o, slope_ end subroutine mktopostats + !================================================================================================ + subroutine dynMaskProc(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, rc) + + use ESMF, only : ESMF_RC_ARG_BAD + + ! input/output arguments + type(ESMF_DynamicMaskElementR8R8R8) , pointer :: dynamicMaskList(:) + real(ESMF_KIND_R8) , intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R8) , intent(in), optional :: dynamicDstMaskValue + integer , intent(out) :: rc + + ! local variables + integer :: i, j + real(ESMF_KIND_R8) :: renorm + !--------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Below - ONLY if you do NOT have the source masked out then do + ! the regridding (which is done explicitly here) + + if (associated(dynamicMaskList)) then + do i=1, size(dynamicMaskList) + dynamicMaskList(i)%dstElement = czero ! set to zero + renorm = 0.d0 ! reset + if (dynamicSrcMaskValue /= dynamicMaskList(i)%srcElement(j)) then + do j = 1, size(dynamicMaskList(i)%factor) + dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement + & + (dynamicMaskList(i)%factor(j) * dynamicMaskList(i)%srcElement(j)) + renorm = renorm + dynamicMaskList(i)%factor(j) + enddo + if (renorm > 0.d0) then + dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement / renorm + else if (present(dynamicSrcMaskValue)) then + dynamicMaskList(i)%dstElement = dynamicSrcMaskValue + else + rc = ESMF_RC_ARG_BAD ! error detected + return + endif + enddo + endif + + end subroutine DynOcnMaskProc end module mktopostatsMod From eba95154e062d34dc2d2a25dcc7b341afb751bc8 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 5 Feb 2022 13:16:14 -0700 Subject: [PATCH 041/614] added gdp and fire --- tools/mksurfdata_esmf/src/CMakeLists.txt | 2 + .../src/mkagfirepkmonthMod.F90 | 128 ++++---- tools/mksurfdata_esmf/src/mkdomainMod.F90 | 10 + tools/mksurfdata_esmf/src/mkesmfMod.F90 | 8 +- tools/mksurfdata_esmf/src/mkfileMod.F90 | 61 +++- tools/mksurfdata_esmf/src/mkgdpMod.F90 | 276 +++++++++--------- tools/mksurfdata_esmf/src/mkpeatMod.F90 | 54 ++-- tools/mksurfdata_esmf/src/mkpftMod.F90 | 95 +++--- tools/mksurfdata_esmf/src/mkpioMod.F90 | 4 - tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 10 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 72 +++-- tools/mksurfdata_esmf/src/mkvarctl.F90 | 21 +- 12 files changed, 402 insertions(+), 339 deletions(-) diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 4f24f5aea4..12e906ca8f 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -21,6 +21,8 @@ set(SRCFILES mkvarctl.F90 mkpioMod.F90 mkfileMod.F90 mkdomainMod.F90 + mkagfirepkmonthMod.F90 + mkgdpMod.F90 mkglacierregionMod.F90 mkglcmecMod.F90 mklanwatMod.F90 diff --git a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 index 4585e33f14..c1bd84f3df 100644 --- a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 +++ b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 @@ -11,10 +11,11 @@ module mkagfirepkmonthMod use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem use mkpioMod , only : mkpio_iodesc_rawdata, mkpio_get_rawdata_level - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkesmfMod , only : regrid_rawdata, create_routehandle_r4, get_meshareas use mkutilsMod , only : chkerr - use mkvarctl , only : ndiag, root_task, outnc_3dglc + use mkvarctl , only : ndiag, root_task use mkvarpar , only : re + use mkchecksMod , only : min_bad, max_bad implicit none private ! By default make data private @@ -40,37 +41,38 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) ! Make agricultural fire peak month data from higher resolution data ! ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh - integer , intent(out) :: agfirepkmon_o(:) ! agricultural fire peak month - integer , intent(out) :: rc + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + integer , intent(inout) :: agfirepkmon_o(:) ! agricultural fire peak month + integer , intent(out) :: rc ! ! local variables: type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid - integer :: ni,no,k + integer :: ni,no,l integer :: ns_i, ns_o integer , allocatable :: mask_i(:) - real(r8), allocatable :: frac_i(:) - real(r8), allocatable :: frac_o(:) + real(r4), allocatable :: frac_i(:) + real(r4), allocatable :: frac_o(:) real(r8), allocatable :: area_i(:) real(r8), allocatable :: area_o(:) - real(r8), allocatable :: loc_gast_i(:) ! local global area, by surface type - real(r8), allocatable :: loc_gast_i(:) ! local global area, by surface type - real(r8), allocatable :: gast_i(:) ! global area, by surface type - real(r8), allocatable :: gast_o(:) ! global area, by surface type - real(r8), allocatable :: frac_dst(:) ! output fractions real(r4), allocatable :: data_i(:,:) real(r4), allocatable :: data_o(:,:) + integer :: max_index(1) integer , allocatable :: agfirepkmon_i(:) ! input grid: agricultural fire peak month integer :: nagfirepkmon ! number of peak months character(len=35), allocatable :: month(:) ! name of each month integer :: rcode, ier ! error status - integer, parameter :: miss = unsetmon ! missing data indicator + integer, parameter :: unsetmon = 13 ! flag to indicate agricultural fire peak month NOT set + integer, parameter :: miss = unsetmon ! missing data indicator integer, parameter :: min_valid = 1 ! minimum valid value integer, parameter :: max_valid = 13 ! maximum valid value + real(r8), allocatable :: loc_gast_i(:) ! local global area, by surface type + real(r8), allocatable :: loc_gast_o(:) ! local global area, by surface type + real(r8), allocatable :: gast_i(:) ! global area, by surface type + real(r8), allocatable :: gast_o(:) ! global area, by surface type character(len=*), parameter :: subname = 'mkagfirepkmon' !----------------------------------------------------------------------- @@ -106,7 +108,7 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i - if (frac_i(ni) > 0._r4) then + if (frac_i(ni) > 0.) then mask_i(ni) = 1 else mask_i(ni) = 0 @@ -125,18 +127,19 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) ! Create a route handle between the input and output mesh and get frac_o allocate(frac_o(ns_o),stat=ier) if (ier/=0) call shr_sys_abort() - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call create_routehandle_r4(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) ! Now determine data_i as a real 2d array - for every possible soil color create a global ! field with gridcells equal to 1 for that soil color and zero elsewhere - allocate(data_i(min_valid_value:max_valid_value,ns_i)) + allocate(data_i(min_valid_value:max_valid,ns_i),stat=ier) + if (ier/=0) call shr_sys_abort(subname//' error in allocating data_i') data_i(:,:) = 0._r4 - do l = min_valid_value,max_valid_value + do l = min_valid,max_valid do ni = 1,ns_i - if (int(agfilepkmon_i(ni)) == l .and. int(agfilepkmon_i(ni)) /= miss) then - data_i(l,n) = 1._r4 * mask_i(n) + if (int(agfirepkmon_i(ni)) == l .and. int(agfirepkmon_i(ni)) /= miss) then + data_i(l,ni) = 1._r4 * mask_i(ni) end if end do end do @@ -144,14 +147,15 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) ! Regrid data_i to data_o ! Note that any input point that is outside the range [min_valid_value,max_valid_value] ! will be ignored; this ignores input points with value of unsetmon - allocate(data_o(min_valid_value:max_valid_value, ns_o),stat=ier) - if (ier/=0) call shr_sys_abort() - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, min_valid_value, max_valid_value, rc) + allocate(data_o(min_valid:max_valid, ns_o),stat=ier) + if (ier/=0) call shr_sys_abort(subname//' error in allocating data_o') + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, min_valid, max_valid, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(subname//'after regrid rawdata in '//trim(subname)) do no = 1,ns_o max_index = maxloc(data_o(:,no)) + write(6,*)'DEBUG: no,max_index = ',no,max_index agfirepkmon_o(no) = max_index(1) end do @@ -173,55 +177,55 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) ! calling output_diagnostics_index. ! ----------------------------------------------------------------- -! nagfirepkmon = maxval(agfirepkmon_i) -! allocate(gast_i(1:nagfirepkmon),gast_o(1:nagfirepkmon),month(1:nagfirepkmon)) -! call define_months(nagfirepkmon, month) - -! gast_i(:) = 0.0_r8 -! do ni = 1,ns_i -! k = agfirepkmon_i(ni) -! gast_i(k) = gast_i(k) + area_src(ni)*mask(ni)*re**2 -! end do -! gast_o(:) = 0.0_r8 -! do no = 1,ns_o -! k = agfirepkmon_o(no) -! gast_o(k) = gast_o(k) + area_dst(no)*frac_dst(no)*re**2 -! end do - -! area comparison - -! write (ndiag,*) -! write (ndiag,'(1x,70a1)') ('=',k=1,70) -! write (ndiag,*) 'Agricultural fire peak month Output' -! write (ndiag,'(1x,70a1)') ('=',k=1,70) - -! write (ndiag,*) -! write (ndiag,'(1x,70a1)') ('.',k=1,70) -! write (ndiag,1001) -! 1001 format (1x,'peak month',20x,' input grid area output grid area',/ & -! 1x,33x,' 10**6 km**2',' 10**6 km**2') -! write (ndiag,'(1x,70a1)') ('.',k=1,70) -! write (ndiag,*) - -! do k = 1, nagfirepkmon -! write (ndiag,1002) month(k),gast_i(k)*1.e-6,gast_o(k)*1.e-6 -! 1002 format (1x,a35,f16.3,f17.3) -! end do - + ! nagfirepkmon = maxval(agfirepkmon_i) + ! allocate(gast_i(1:nagfirepkmon),gast_o(1:nagfirepkmon),month(1:nagfirepkmon)) + ! call define_months(nagfirepkmon, month) + + ! gast_i(:) = 0.0_r8 + ! do ni = 1,ns_i + ! k = agfirepkmon_i(ni) + ! gast_i(k) = gast_i(k) + area_src(ni)*mask(ni)*re**2 + ! end do + ! gast_o(:) = 0.0_r8 + ! do no = 1,ns_o + ! k = agfirepkmon_o(no) + ! gast_o(k) = gast_o(k) + area_dst(no)*frac_dst(no)*re**2 + ! end do + + ! area comparison + + ! write (ndiag,*) + ! write (ndiag,'(1x,70a1)') ('=',k=1,70) + ! write (ndiag,*) 'Agricultural fire peak month Output' + ! write (ndiag,'(1x,70a1)') ('=',k=1,70) + + ! write (ndiag,*) + ! write (ndiag,'(1x,70a1)') ('.',k=1,70) + ! write (ndiag,1001) + ! 1001 format (1x,'peak month',20x,' input grid area output grid area',/ & + ! 1x,33x,' 10**6 km**2',' 10**6 km**2') + ! write (ndiag,'(1x,70a1)') ('.',k=1,70) + ! write (ndiag,*) + + ! do k = 1, nagfirepkmon + ! write (ndiag,1002) month(k),gast_i(k)*1.e-6,gast_o(k)*1.e-6 + ! 1002 format (1x,a35,f16.3,f17.3) + ! end do + ! Close the file call pio_closefile(pioid) - call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) + !call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) if (root_task) then write (ndiag,'(a)') 'Successfully made Agricultural fire peak month' end if + write(6,*)'finished mkagfirepkmon' end subroutine mkagfirepkmon diff --git a/tools/mksurfdata_esmf/src/mkdomainMod.F90 b/tools/mksurfdata_esmf/src/mkdomainMod.F90 index f994265a11..f14b85a3f1 100644 --- a/tools/mksurfdata_esmf/src/mkdomainMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdomainMod.F90 @@ -7,6 +7,7 @@ module mkdomainMod use ESMF use shr_kind_mod, only : r8 => shr_kind_r8 use mkutilsMod , only : chkerr + use mkvarctl , only : root_task, ndiag implicit none private @@ -38,6 +39,11 @@ subroutine mkdomain(mesh_o, lon_o, lat_o, rc) rc = ESMF_SUCCESS + if (root_task) then + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to create model lats and lons from model mesh .....' + end if + call ESMF_MeshGet(mesh_o, spatialDim=spatialDim, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return allocate(ownedElemCoords(spatialDim*ns_o)) @@ -48,6 +54,10 @@ subroutine mkdomain(mesh_o, lon_o, lat_o, rc) lat_o(no) = ownedElemCoords(2*no) end do + if (root_task) then + write (ndiag,'(a)') 'Successfully made model lats and lons' + end if + end subroutine mkdomain end module mkdomainMod diff --git a/tools/mksurfdata_esmf/src/mkesmfMod.F90 b/tools/mksurfdata_esmf/src/mkesmfMod.F90 index 7f478241e8..ee31104b80 100644 --- a/tools/mksurfdata_esmf/src/mkesmfMod.F90 +++ b/tools/mksurfdata_esmf/src/mkesmfMod.F90 @@ -238,10 +238,10 @@ subroutine regrid_rawdata2d_r4(mesh_i, mesh_o, routehandle, data_i, data_o, lbo type(ESMF_Mesh) , intent(in) :: mesh_i type(ESMF_Mesh) , intent(in) :: mesh_o type(ESMF_RouteHandle) , intent(inout) :: routehandle - integer , intent(in) :: lbound - integer , intent(in) :: ubound real(r4) , intent(in) :: data_i(:,:) real(r4) , intent(inout) :: data_o(:,:) + integer , intent(in) :: lbound + integer , intent(in) :: ubound integer , intent(out) :: rc ! local variables @@ -288,10 +288,10 @@ subroutine regrid_rawdata2d_r8(mesh_i, mesh_o, routehandle, data_i, data_o, lbo type(ESMF_Mesh) , intent(in) :: mesh_i type(ESMF_Mesh) , intent(in) :: mesh_o type(ESMF_RouteHandle) , intent(inout) :: routehandle - integer , intent(in) :: lbound - integer , intent(in) :: ubound real(r8) , intent(in) :: data_i(:,:) real(r8) , intent(inout) :: data_o(:,:) + integer , intent(in) :: lbound + integer , intent(in) :: ubound integer , intent(out) :: rc ! local variables diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index e5cb211e6b..30fce8d726 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -38,8 +38,8 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, lon, lat, dynlanduse, & pctlak, pctwet, lakedepth, organic, soil_color, nsoilcol, & urban_classes_g, urban_region, pctsand, pctclay, mapunits, fmaxsoil, soildepth, & glacier_region, ef_btr, ef_fet, ef_fdt, ef_shr, ef_grs, ef_crp, & - pctgla, pctglcmec, topoglcmec, pctglcmec_gic, pctglcmec_icesheet, pctglc_gic, & - pctglc_icesheet, fpeat, rc) + elevclass, pctgla, pctglcmec, topoglcmec, pctglcmec_gic, pctglcmec_icesheet, pctglc_gic, & + pctglc_icesheet, fpeat, agfirepkmon, gdp, rc) ! input/output variables integer , intent(in) :: nx @@ -68,6 +68,7 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, lon, lat, dynlanduse, & real(r8) , intent(in) :: ef_shr(:) real(r8) , intent(in) :: ef_grs(:) real(r8) , intent(in) :: ef_crp(:) + real(r8) , intent(in) :: elevclass(:) real(r8) , intent(in) :: pctgla(:) real(r8) , intent(in) :: pctglcmec(:,:) real(r8) , intent(in) :: topoglcmec(:,:) @@ -76,6 +77,8 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, lon, lat, dynlanduse, & real(r8) , intent(in) :: pctglc_gic(:) real(r8) , intent(in) :: pctglc_icesheet(:) real(r8) , intent(in) :: fpeat(:) + integer , intent(in) :: agfirepkmon(:) + real(r8) , intent(in) :: gdp(:) integer , intent(out):: rc #ifdef TODO type(harvestDataType) , intent(in) :: harvdata @@ -135,7 +138,26 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, lon, lat, dynlanduse, & rcode = pio_enddef(pioid) end if + ! -------------------------------- + ! Write out model grid + ! -------------------------------- + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out model grid" + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'LONGXY', 'model longitudes', & + 'degrees', lat, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LATIXY" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'LATIXY', 'model latitudes', & + 'degrees', lon, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! -------------------------------- ! Write out non-spatial variables + ! -------------------------------- + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out non-spatial variables" + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out mksoil_color" if (define_mode) then rcode = pio_def_var(pioid, 'mxsoil_color', PIO_INT, pio_varid) @@ -150,28 +172,31 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, lon, lat, dynlanduse, & if (root_task) write(ndiag, '(a)') trim(subname)//" writing out GLC_MEC" if (define_mode) then rcode = pio_inq_dimid(pioid, 'nglcecp1', dimid) - rcode = pio_def_var(pioid, 'GLC_MEC', PIO_INT, (/dimid/), pio_varid) + rcode = pio_def_var(pioid, 'GLC_MEC', PIO_DOUBLE, (/dimid/), pio_varid) rcode = pio_put_att(pioid, pio_varid, 'long_name', 'Glacier elevation class') rcode = pio_put_att(pioid, pio_varid, 'm', 'unitless') else rcode = pio_inq_varid(pioid, 'GLC_MEC', pio_varid) - rcode = pio_put_var(pioid, pio_varid, nsoilcol) + rcode = pio_put_var(pioid, pio_varid, elevclass) end if end if - ! Write out model grid - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'LONGXY', 'model longitudes', & - 'degrees', lat, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! -------------------------------- + ! Write out spatial variables + ! -------------------------------- + if (.not. dynlanduse) then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LATIXY" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'LATIXY', 'model latitudes', & - 'degrees', lon, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out spatial variables" - ! Write out spatial mapped variables - if (.not. dynlanduse) then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out gdp" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'gdp', 'gdp', & + 'unitless', gdp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out peatland fraction" + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'peatf', 'peatland fraction', & + 'unitless', fpeat, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return if (root_task) write(ndiag, '(a)') trim(subname)//" writing out peatland fraction" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'peatf', 'peatland fraction', & @@ -342,6 +367,12 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, lon, lat, dynlanduse, & call mkfile_output(pioid, define_mode, mesh_o, 'GLACIER_REGION', 'glacier region ID', & 'unitless', glacier_region, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing abm (agricultural fire peak month)" + call mkfile_output(pioid, define_mode, mesh_o, 'abm', 'agricultural fire peak month', & + 'unitless', agfirepkmon, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end do ! Close surface dataset diff --git a/tools/mksurfdata_esmf/src/mkgdpMod.F90 b/tools/mksurfdata_esmf/src/mkgdpMod.F90 index 1babb411bf..7da1418035 100644 --- a/tools/mksurfdata_esmf/src/mkgdpMod.F90 +++ b/tools/mksurfdata_esmf/src/mkgdpMod.F90 @@ -1,144 +1,156 @@ module mkgdpMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkgdpMod -! -! !DESCRIPTION: -! make GDP from input GDP data -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -!----------------------------------------------------------------------- -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkdomainMod , only : domain_checksame + !----------------------------------------------------------------------- + ! make GDP from input GDP data + !----------------------------------------------------------------------- + ! + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkutilsMod , only : chkerr + use mkvarctl , only : ndiag, root_task, mpicom implicit none - private -! !PUBLIC MEMBER FUNCTIONS: - public mkgdp ! regrid gdp data -! -!EOP +#include + + public :: mkgdp ! regrid gdp data + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + !=============================================================== contains !=============================================================== -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkgdp -! -! !INTERFACE: -subroutine mkgdp(ldomain, mapfname, datfname, ndiag, gdp_o) -! -! !DESCRIPTION: -! make GDP from input GDP data -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_continuous - use mkchecksMod, only : min_bad -! -! !ARGUMENTS: - - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: gdp_o(:) ! output grid: GDP (x1000 1995 US$ per capita) -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: data_i(:) ! data on input grid - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - - real(r8), parameter :: min_valid = 0._r8 ! minimum valid value - - character(len=32) :: subname = 'mkgdp' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make GDP.....' - - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - call domain_read(tdomain,datfname) - - call gridmap_mapread(tgridmap, mapfname ) - - ! Obtain frac_dst - allocate(frac_dst(ldomain%ns), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write(6,*)'Open GDP file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(data_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() - - ! ----------------------------------------------------------------- - ! Regrid gdp - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'gdp', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, gdp_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(gdp_o, min_valid, 'gdp')) then - call abort() - end if - - call output_diagnostics_continuous(data_i, gdp_o, tgridmap, "GDP", "x1000 US$ per capita", ndiag, tdomain%mask, frac_dst) - - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- - - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (data_i) - deallocate (frac_dst) - deallocate (mask_r8) - - write (6,*) 'Successfully made GDP' - write (6,*) - -end subroutine mkgdp + subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, gdp_o, rc) + ! + ! make GDP from input GDP data + ! + use mkdiagnosticsMod, only : output_diagnostics_continuous + use mkchecksMod, only : min_bad + ! + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! input model mesh + real(r8) , intent(inout) :: gdp_o(:) ! output grid: GDP (x1000 1995 US$ per capita) + integer , intent(out) :: rc + + ! local variables: + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + integer :: ni,no,k + integer :: ns_i, ns_o + integer , allocatable :: mask_i(:) + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + real(r8), allocatable :: gdp_i(:) ! input grid: percent gdp + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: gglac_i ! input grid: global glac + real(r8) :: garea_i ! input grid: global area + real(r8) :: gglac_o ! output grid: global glac + real(r8) :: garea_o ! output grid: global area + integer :: ier, rcode ! error status + real(r8), parameter :: min_valid = 0._r8 ! minimum valid value + character(len=*), parameter :: subname = 'mkgdp' + !----------------------------------------------------------------------- + + if (root_task) then + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make GDP.....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) + end if + + ! Open input data file + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) + + ! Read in input mesh + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Determine ns_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the landmask from the file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (frac_i(ni) > 0._r4) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Read in peat_i + allocate(gdp_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'gdp', mesh_i, gdp_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + + ! Create a route handle between the input and output mesh and get frac_o + allocate(frac_o(ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + + ! Regrid gdp + call regrid_rawdata(mesh_i, mesh_o, routehandle, gdp_i, gdp_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (min_bad(gdp_o, min_valid, 'gdp')) then + call shr_sys_abort(subname//' error in reading gdp_i') + end if + + ! Close the file + call pio_closefile(pioid) + call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) + + ! Output diagnostic info + allocate(area_i(ns_i)) + allocate(area_o(ns_o)) + call get_meshareas(mesh_i, area_i, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call get_meshareas(mesh_o, area_o, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! call output_diagnostics_continuous(area_i, area_o, mask_i, frac_o, & + ! gdp_i, gdp_o, "GDP", "x1000 US$ per capita", ndiag) + + ! Clean up memory + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + if (root_task) then + write (ndiag,'(a)') 'Successfully made GDP' + write (ndiag,'(a)') + end if + + end subroutine mkgdp end module mkgdpMod diff --git a/tools/mksurfdata_esmf/src/mkpeatMod.F90 b/tools/mksurfdata_esmf/src/mkpeatMod.F90 index 70a0b5e00f..cbe68b4775 100644 --- a/tools/mksurfdata_esmf/src/mkpeatMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpeatMod.F90 @@ -3,7 +3,7 @@ module mkpeatMod !----------------------------------------------------------------------- ! make fraction peat from input peat data !----------------------------------------------------------------------- - ! + use ESMF use pio use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 @@ -35,10 +35,10 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) use mkchecksMod , only : min_bad, max_bad ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o - real(r8) , intent(inout) :: peat_o(:) ! output grid: fraction peat + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! input model mesh + real(r8) , intent(inout) :: peat_o(:) ! output grid: fraction peat integer , intent(out) :: rc ! local variables: @@ -52,18 +52,17 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) real(r8), allocatable :: frac_o(:) real(r8), allocatable :: area_i(:) real(r8), allocatable :: area_o(:) - real(r8), allocatable :: peat_i(:) ! input grid: percent glac - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: gglac_i ! input grid: global glac - real(r8) :: garea_i ! input grid: global area - real(r8) :: gglac_o ! output grid: global glac - real(r8) :: garea_o ! output grid: global area - integer :: ier, rcode ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - real(r8), allocatable :: data_i(:) ! data on input grid - real(r8), parameter :: min_valid = 0._r8 ! minimum valid value - real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value + real(r8), allocatable :: peat_i(:) ! input grid: percent peat + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: gglac_i ! input grid: global glac + real(r8) :: garea_i ! input grid: global area + real(r8) :: gglac_o ! output grid: global glac + real(r8) :: garea_o ! output grid: global area + integer :: ier, rcode ! error status + real(r8), allocatable :: data_i(:) ! 2d data on input grid for dominant search + real(r8), parameter :: min_valid = 0._r8 ! minimum valid value + real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value character(len=*), parameter :: subname = 'mkpeat' !----------------------------------------------------------------------- @@ -99,7 +98,7 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i - if (frac_i(ni) > 0._r4) then + if (frac_i(ni) > 0._r8) then mask_i(ni) = 1 else mask_i(ni) = 0 @@ -131,16 +130,15 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) ! Close the file call pio_closefile(pioid) - call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) ! Output diagnostic info - allocate(area_i(ns_i)) - allocate(area_o(ns_o)) - call get_meshareas(mesh_i, area_i, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call get_meshareas(mesh_o, area_o, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call output_diagnostics_area(area_i, area_o, mask_i, peat_i, peat_o, 'peat', .true., ndiag) + ! allocate(area_i(ns_i)) + ! allocate(area_o(ns_o)) + ! call get_meshareas(mesh_i, area_i, rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return + ! call get_meshareas(mesh_o, area_o, rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return + ! call output_diagnostics_area(area_i, area_o, mask_i, peat_i, peat_o, 'peat', .true., ndiag) ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) @@ -149,10 +147,6 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) - if (root_task) then - write (ndiag,'(a)') 'Successfully made organic matter ' - end if - if (root_task) then write (ndiag,'(a)') 'Successfully made peat' end if diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index 1704f56055..9953567612 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -94,8 +94,8 @@ subroutine mkpftInit( zero_out_l, all_veg_l ) if ( zero_out_l .and. use_input_pft )then write(6,*) subname//"trying to both zero out all PFT's as well as set them to specific values" call shr_sys_abort() - return end if + ! If zeroing out, set use_input_pft to true so the pft_override will be used if( zero_out_l )then nzero = 0 @@ -383,6 +383,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + ! pres_cover is true if zero_out_l is true if ( .not. presc_cover ) then ! get dimensions @@ -478,28 +479,24 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ns_i = 1 numpft_i = numpft+1 allocate(pctnatveg_i(ns_i), & - pctnatveg_o(ns_o), & - pctcrop_i(ns_i), & - pctcrop_o(ns_o), & - pct_cft_i(ns_i,1:num_cft), & - pct_cft_o(ns_o,1:num_cft), & - pct_nat_pft_i(ns_i,0:num_natpft), & - pct_nat_pft_o(ns_o,0:num_natpft), & - stat=ier) - if (ier/=0)then - call shr_sys_abort() - return - end if + pctnatveg_o(ns_o), & + pctcrop_i(ns_i), & + pctcrop_o(ns_o), & + pct_cft_i(ns_i,1:num_cft), & + pct_cft_o(ns_o,1:num_cft), & + pct_nat_pft_i(ns_i,0:num_natpft), & + pct_nat_pft_o(ns_o,0:num_natpft), & + stat=ier) + if (ier/=0) call shr_sys_abort() + end if + allocate(pctpft_i(ns_i,0:(numpft_i-1)), & - pctpft_o(ns_o,0:(numpft_i-1)), & - pctnatpft_i(ns_i), & - pctcft_i(ns_i), & - stat=ier) - if (ier/=0)then - call shr_sys_abort() - return - end if + pctpft_o(ns_o,0:(numpft_i-1)), & + pctnatpft_i(ns_i), & + pctcft_i(ns_i), & + stat=ier) + if (ier/=0) call shr_sys_abort() ! Determine pctpft_o on output grid ! If total vegetation cover is prescribed from input... @@ -511,8 +508,10 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft pctnatveg_o(no) = pft_override%natveg pctcrop_o(no) = pft_override%crop end do - + + ! ---------------------------------------- ! otherewise if total cover isn't prescribed read it from the datasets + ! ---------------------------------------- else ! Compute pctlnd_o, pctpft_o @@ -524,21 +523,26 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! Area-average percent cover on input grid [pctpft_i] to output grid ! [pctpft_o] and correct [pctpft_o] according to land landmask ! Note that percent cover is in terms of total grid area. - pctlnd_o(:) = frac_dst(:) * 100._r8 ! ???? + pctlnd_o(:) = frac_o(:) * 100._r8 + + ! ---------------------------------------- ! If specific PFT/CFT's are NOT prescribed set them from the input file + ! ---------------------------------------- if ( .not. use_input_pft )then - do m = 0, num_natpft - - ! multiply data_pct_nat_pft_i(m,:) by pctnatveg_i*0.01_r8*mask_i - ! then regrid that - call gridmap_areaave_scs(tgridmap, pct_nat_pft_i(:,m), & - pct_nat_pft_o(:,m), nodata=0._r8, & - src_wt = pctnatveg_i(:)*0.01_r8*mask(:), & - dst_wt = pctnatveg_o(:)*0.01_r8, frac_dst=frac_dst) + ! TODO: allocate data_pct_nat_pft_i and data_pct_nat_pft_o + do m = 0,num_natpft + do ni = 1,ns_i + data_pct_nat_pft_i(m,ni) = pct_nat_pft_i(ni,m) * pctnatveg_i(ni) * 0.01_r8 * mask_i(ni) + end do + end do + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_pct_nat_pft_i, data_pct_nat_pft_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do m = 0,num_natpft do no = 1,ns_o + pct_nat_pft_o(no,m) = data_pct_nat_pft_o(no,m) / pctnatveg_o(no) * 0.01_r8 if (pctlnd_o(no) < 1.0e-6 .or. pctnatveg_o(no) < 1.0e-6) then if (m == 0) then pct_nat_pft_o(no,m) = 100._r8 @@ -546,12 +550,15 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft pct_nat_pft_o(no,m) = 0._r8 endif end if - enddo + end do end do + do m = 1, num_cft + call gridmap_areaave_scs(tgridmap, pct_cft_i(:,m), pct_cft_o(:,m), & nodata=0._r8, src_wt=pctcrop_i*0.01_r8*tdomain%mask, & dst_wt=pctcrop_o*0.01_r8, frac_dst=frac_dst) + do no = 1,ns_o if (pctlnd_o(no) < 1.0e-6 .or. pctcrop_o(no) < 1.0e-6) then if (m == 1) then @@ -562,7 +569,11 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft end if enddo end do - ! Otherwise do some error checking to make sure specific veg types are given where nat-veg and crop is assigned + + ! ---------------------------------------- + ! Otherwise do some error checking to make sure specific veg + ! types are given where nat-veg and crop is assigned + ! ---------------------------------------- else do no = 1,ns_o if (pctlnd_o(no) > 1.0e-6 .and. pctnatveg_o(no) > 1.0e-6) then @@ -570,14 +581,13 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft write(6,*) subname//': ERROR: no natural vegetation PFTs are being prescribed but there are natural '// & 'vegetation areas: provide at least one natural veg PFT' call shr_sys_abort() - return end if end if if (pctlnd_o(no) > 1.0e-6 .and. pctcrop_o(no) > 1.0e-6) then if ( pft_override%crop <= 0.0_r8 )then - write(6,*) subname//': ERROR: no crop CFTs are being prescribed but there are crop areas: provide at least one CFT' + write(6,*) subname//': ERROR: no crop CFTs are being prescribed '& + //' but there are crop areas: provide at least one CFT' call shr_sys_abort() - return end if end if end do @@ -802,7 +812,6 @@ subroutine mkpft_parse_oride( string ) return end if read(substring,*) pft_idx(0:num_elms) - !----------------------------------------------------------------------- end subroutine mkpft_parse_oride @@ -810,11 +819,11 @@ end subroutine mkpft_parse_oride subroutine mkpft_check_oride( error_happened ) ! ! Check that the pft override values are valid - - ! !ARGUMENTS: + ! + ! input/output variables logical, intent(out) :: error_happened ! Result, true if there was a problem ! - ! !LOCAL VARIABLES: + ! local variables: integer :: i, j ! indices real(r8) :: sumpft ! Sum of pft_frc real(r8), parameter :: hndrd = 100.0_r8 ! A hundred percent @@ -832,7 +841,6 @@ subroutine mkpft_check_oride( error_happened ) write(6,*) 'With PFT index : ', pft_idx(0:nzero) error_happened = .true. call shr_sys_abort() - return else use_input_pft = .true. nzero = numpft @@ -848,19 +856,16 @@ subroutine mkpft_check_oride( error_happened ) write(6,*) subname//'PFT fraction is out of range: pft_frc=', pft_frc(i) error_happened = .true. call shr_sys_abort() - return else if ( pft_frc(i) > 0.0_r8 .and. pft_idx(i) == -1 )then write(6,*) subname//'PFT fraction > zero, but index NOT set: pft_idx=', pft_idx(i) error_happened = .true. call shr_sys_abort() - return end if ! PFT index out of range if ( pft_idx(i) < 0 .or. pft_idx(i) > numpft )then write(6,*) subname//'PFT index is out of range: ', pft_idx(i) error_happened = .true. call shr_sys_abort() - return end if ! Make sure index values NOT used twice do j = 0, i-1 @@ -868,7 +873,6 @@ subroutine mkpft_check_oride( error_happened ) write(6,*) subname//'Same PFT index is used twice: ', pft_idx(i) error_happened = .true. call shr_sys_abort() - return end if end do end do @@ -878,7 +882,6 @@ subroutine mkpft_check_oride( error_happened ) write(6,*) subname//'After PFT fraction is zeroed out, fraction is non zero, or index set' error_happened = .true. call shr_sys_abort() - return end if end do end if diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index a7eacbe87c..c3d77c4aaa 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -546,10 +546,6 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) rc = ESMF_SUCCESS - if (root_task) then - write(ndiag,'(a)') 'setting iodesc for : '//trim(varname) - end if - ! get pio variable id, type and dimension information rcode = pio_inq_varid(pioid, trim(varname), pio_varid) rcode = pio_inq_vartype(pioid, pio_varid, pio_vartype) diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index 65fad7ffb0..d89cb320ac 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -233,18 +233,16 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r ! write (ndiag,'(1x,a,i3,d16.3,d17.3)') 'class ',k, gast_i(k)*1.e-6, gast_o(k)*1.e-6 ! end do - if (root_task) then - write (ndiag,'(a)') 'Successfully made soil color classes' - write (ndiag,'(a)') - end if - ! Clean up memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_LogWrite(subname//' finished routine mksoilcol') + if (root_task) then + write (ndiag,'(a)') 'Successfully made soil color classes' + write (ndiag,'(a)') + end if end subroutine mksoilcol diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 80f045e276..a010dda6bd 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -96,16 +96,16 @@ program mksurfdata use mklaiMod , only : mklai use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride + use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft use mkharvestMod , only : mkharvest, mkharvest_init, mkharvest_fieldname use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride use mkharvestMod , only : harvestDataType - use mkgdpMod , only : mkgdp - use mkagfirepkmonthMod , only : mkagfirepkmon use mktopostatsMod , only : mktopostats use mkVICparamsMod , only : mkVICparams - use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft #endif use mkdomainMod , only : mkdomain + use mkgdpMod , only : mkgdp + use mkagfirepkmonthMod , only : mkagfirepkmon use mkpeatMod , only : mkpeat use mkvocefMod , only : mkvocef use mkglcmecMod , only : mkglcmecInit, mkglcmec, mkglacier, nglcec @@ -116,7 +116,7 @@ program mksurfdata use mksoilcolMod , only : mksoilcol use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, mkurban_topo, numurbl use mklanwatMod , only : mklakwat - use mkOrganicMod , only : mkorganic + use mkorganicMod , only : mkorganic use mkutilsMod , only : normalize_classes_by_gcell, chkerr use mkfileMod , only : mkfile_fsurdat use mkvarpar , only : nlevsoi, elev_thresh, numstdpft @@ -315,6 +315,8 @@ program mksurfdata ! ---------------------------------------------------------------------- #ifdef TODO + ! zero_out_l => If veg should be zero'ed out + ! all_veg_l => If should zero out other fractions so that all land-cover is vegetation call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) #endif allocate ( elevclass(nglcec+1) ) @@ -322,7 +324,7 @@ program mksurfdata call mkurbanInit (mksrf_furban) ! ---------------------------------------------------------------------- - ! Allocate and initialize dynamic memory for local variables + ! Read in model mesh ! ---------------------------------------------------------------------- ! Read in model mesh to determine the number of local points @@ -333,14 +335,10 @@ program mksurfdata call ESMF_MeshGet(mesh_model, numOwnedElements=lsize_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - allocate ( landfrac_pft(lsize_o)) ; landfrac_pft(:) = spval - allocate ( pctlnd_pft(lsize_o)) ; pctlnd_pft(:) = spval - allocate ( pftdata_mask(lsize_o)) ; pftdata_mask(:) = -999 - !allocate ( pctnatpft(lsize_o)) ; - !allocate ( pctnatpft_max(lsize_o)) ; - !allocate ( pctcft(lsize_o)) ; - !allocate ( pctcft_max(lsize_o)) ; - allocate ( gdp(lsize_o)) ; gdp(:) = spval + ! ---------------------------------------------------------------------- + ! Allocate and initialize dynamic memory for local variables + ! ---------------------------------------------------------------------- + allocate ( topo_stddev(lsize_o)) ; topo_stddev(:) = spval allocate ( slope(lsize_o)) ; slope(:) = spval allocate ( vic_binfl(lsize_o)) ; vic_binfl(:) = spval @@ -348,15 +346,23 @@ program mksurfdata allocate ( vic_dsmax(lsize_o)) ; vic_dsmax(:) = spval allocate ( vic_ds(lsize_o)) ; vic_ds(:) = spval - ! voc emission factors - ! ---------------------------------------------------------------------- ! Read in and interpolate surface data set fields ! ---------------------------------------------------------------------- - ! ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] + ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] + ! Determine fractional land from pft dataset + allocate ( landfrac_pft(lsize_o)) ; landfrac_pft(:) = spval + allocate ( pctlnd_pft(lsize_o)) ; pctlnd_pft(:) = spval + allocate ( pftdata_mask(lsize_o)) ; pftdata_mask(:) = -999 + ! allocate ( pctnatpft(lsize_o)) ; + ! allocate ( pctnatpft_max(lsize_o)) ; + ! allocate ( pctcft(lsize_o)) ; + ! allocate ( pctcft_max(lsize_o)) ; ! call mkpft( mapfname=map_fpft, fpft=mksrf_fvegtyp, ndiag=ndiag, & ! pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft) + ! landfrac_pft(:) = pctlnd_pft(:)/100._r8 + ! end do ! Create harvesting data at model resolution ! if (all_veg) then @@ -371,30 +377,32 @@ program mksurfdata ! call mkharvest( mapfname=map_fharvest, datfname=mksrf_fhrvtyp, ndiag=ndiag, harvdata=harvdata ) ! end if - ! -------------------------------------------------- - ! begin working - ! Make lats/lons of model allocate (lon(lsize_o)) ; lon(:) = spval allocate (lat(lsize_o)) ; lat(:) = spval call mkdomain(mesh_model, lon_o=lon, lat_o=lat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') + ! Make GDP data [gdp] from [gdp] + allocate ( gdp(lsize_o)); gdp(:) = spval + call mkgdp (mksrf_fgdp_mesh, mksrf_fgdp, mesh_model, gdp_o=gdp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') + + ! Make agricultural fire peak month data [abm] from [abm] + allocate (agfirepkmon(lsize_o)); agfirepkmon(:) = -999 + call mkagfirepkmon (mksrf_fabm_mesh, mksrf_fabm, mesh_model, agfirepkmon_o=agfirepkmon, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkagfirepkmon') + ! Make peat data [fpeat] from [peatf] allocate (fpeat(lsize_o)) ; fpeat(:) = spval - call mkpeat ( mksrf_fpeat_mesh, mksrf_fpeat, mesh_model, peat_o=fpeat, rc=rc) + call mkpeat (mksrf_fpeat_mesh, mksrf_fpeat, mesh_model, peat_o=fpeat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpeat') - ! Make agricultural fire peak month data [abm] from [abm] - allocate ( agfirepkmon(lsize_o)); agfirepkmon(:) = -999 - ! call mkagfirepkmon (mksrf_fabm_mesh, mksrf_fabm, mesh_model, agfirepkmon_o=agfirepkmon, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkagfirepkmon') - ! Make glacier fraction [pctgla] from [fglacier] dataset - allocate ( pctgla(lsize_o)) ; pctgla(:) = spval + allocate (pctgla(lsize_o)) ; pctgla(:) = spval zero_out = (all_urban .or. all_veg) if (.not. zero_out) then - call mkglacier ( mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, glac_o=pctgla, rc=rc) + call mkglacier (mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, glac_o=pctgla, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacier') else if (root_task) then @@ -487,9 +495,6 @@ program mksurfdata ! end working ! -------------------------------------------------- - ! ! Make GDP data [gdp] from [gdp] - ! call mkgdp ( mapfname=map_fgdp, datfname=mksrf_fgdp, ndiag=ndiag, gdp_o=gdp) - ! ! Compute topography statistics [topo_stddev, slope] from [ftopostats] ! call mktopostats ( mapfname=map_ftopostats, datfname=mksrf_ftopostats, & ! ndiag=ndiag, topo_stddev_o=topo_stddev, slope_o=slope, std_elev=std_elev) @@ -632,9 +637,9 @@ program mksurfdata end if ! ---------------------------------------------------------------------- - ! Determine fractional land from pft dataset ! ---------------------------------------------------------------------- + ! Determine fractional land from pft dataset ! do n = 1,lsize_o ! landfrac_pft(n) = pctlnd_pft(n)/100._r8 ! end do @@ -689,6 +694,7 @@ program mksurfdata ef_shr=ef1_shr, & ef_grs=ef1_grs, & ef_crp=ef1_crp, & + elevclass=elevclass, & pctgla=pctgla, & pctglcmec=pctglcmec, & topoglcmec=topoglcmec, & @@ -697,6 +703,8 @@ program mksurfdata pctglc_gic=pctglc_gic, & pctglc_icesheet=pctglc_icesheet, & fpeat=fpeat, & + agfirepkmon=agfirepkmon, & + gdp=gdp, & rc=rc) if (root_task) then write(ndiag,*) @@ -723,8 +731,8 @@ program mksurfdata deallocate (pctglc_gic, pctglc_icesheet) end if deallocate(fpeat) -#ifdef TODO deallocate(gdp) +#ifdef TODO deallocate(agfirepkmon) deallocate(topo_stddev deallocate(slope) diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index e566de7184..7cdf897522 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -467,15 +467,17 @@ subroutine write_namelist_input() write(ndiag,*) write(ndiag,'(a)')'Output configuration variables' if (outnc_1d) then - write(ndiag,'(a)')' output file will be 1d format' + write(ndiag,'(a)')' output file is 1d format' else - write(ndiag,'(a)')' fsurdat is 2d lat/lon grid' + write(ndiag,'(a)')' output file is 2d lat/lon format' end if if ( outnc_large_files ) then write(ndiag,'(a)')' Output file in NetCDF 64-bit large_files format' end if if ( outnc_double )then write(ndiag,'(a)')' Output ALL data in file as 64-bit' + else + write(ndiag,'(a)')' Output ALL data in file as 32-bit' end if if ( outnc_vic )then write(ndiag,'(a)')' Output VIC fields' @@ -483,17 +485,20 @@ subroutine write_namelist_input() if ( outnc_3dglc )then write(ndiag,'(a)')' Output optional 3D glacier fields (mostly used for verification of the glacier model)' end if - if ( outnc_3dglc )then - write(ndiag,'(a)')' Output optional 3D glacier fields (mostly used for verification of the glacier model)' - end if if ( all_urban )then - write(ndiag,'(a)') ' Output ALL data in file as 100% urban' + write(ndiag,'(a)') ' all_urban is true => Output ALL data in file as 100% urban' + else + write(ndiag,'(a)') ' all_urban is false ' end if if ( no_inlandwet )then - write(ndiag,'(a)') ' Set wetland to 0% over land' + write(ndiag,'(a)') ' no_inlandwet is true => Set wetland to 0% over land' + else + write(ndiag,'(a)') ' no_inlandwet is false' end if if (all_veg) then - write(ndiag,'(a)') ' Output ALL data in file as 100% vegetated' + write(ndiag,'(a)') ' all_veg is true => Output ALL data in file as 100% vegetated' + else + write(ndiag,'(a)') ' all_veg is false ' end if if (urban_skip_abort_on_invalid_data_check) then write(ndiag, '(a)') " WARNING: aborting on invalid data check in urban has been disabled!" From dd4bb03c337e7d6493dd80dcb52a3b1ee095efd1 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 6 Feb 2022 11:39:36 -0700 Subject: [PATCH 042/614] removed DEBUG statement --- .../src/mkagfirepkmonthMod.F90 | 1 - tools/mksurfdata_map/src/mkncdio.F90 | 558 ++++++++++++++++++ tools/mksurfdata_map/src/mksurfdat.F90 | 4 +- 3 files changed, 559 insertions(+), 4 deletions(-) create mode 100644 tools/mksurfdata_map/src/mkncdio.F90 diff --git a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 index c1bd84f3df..0e04a2d3e2 100644 --- a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 +++ b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 @@ -155,7 +155,6 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) do no = 1,ns_o max_index = maxloc(data_o(:,no)) - write(6,*)'DEBUG: no,max_index = ',no,max_index agfirepkmon_o(no) = max_index(1) end do diff --git a/tools/mksurfdata_map/src/mkncdio.F90 b/tools/mksurfdata_map/src/mkncdio.F90 new file mode 100644 index 0000000000..555eb6ae80 --- /dev/null +++ b/tools/mksurfdata_map/src/mkncdio.F90 @@ -0,0 +1,558 @@ +module mkncdio + +!----------------------------------------------------------------------- +!BOP +! +! !MODULE: mkncdio +! +! !DESCRIPTION: +! Generic interfaces to write fields to netcdf files, and other useful netcdf operations +! +! !USES: + use shr_kind_mod , only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_flush +! +! !PUBLIC TYPES: + implicit none + include 'netcdf.inc' + save + + private + + public :: check_ret ! checks return status of netcdf calls + public :: ncd_defvar ! define netCDF input variable + public :: ncd_def_spatial_var ! define spatial netCDF variable (convenience wrapper to ncd_defvar) + public :: ncd_put_time_slice ! write a single time slice of a variable + public :: get_dim_lengths ! get dimension lengths of a netcdf variable + + interface ncd_def_spatial_var + module procedure ncd_def_spatial_var_0lev + module procedure ncd_def_spatial_var_1lev + module procedure ncd_def_spatial_var_2lev + end interface ncd_def_spatial_var + + interface ncd_put_time_slice + module procedure ncd_put_time_slice_1d + module procedure ncd_put_time_slice_2d + end interface ncd_put_time_slice + + public :: convert_latlon ! convert a latitude or longitude variable to degrees E / N +! +! !REVISION HISTORY: +! +! +! !PRIVATE MEMBER FUNCTIONS: +! + private :: get_time_slice_beg_and_len ! determine beg and len vectors for writing a time slice + + logical :: masterproc = .true. ! always use 1 proc + real(r8) :: spval = 1.e36 ! special value + + public :: nf_open + public :: nf_close + public :: nf_write + public :: nf_sync + public :: nf_inq_attlen + public :: nf_inq_dimlen + public :: nf_inq_dimname + public :: nf_inq_varid + public :: nf_inq_varndims + public :: nf_inq_vardimid + public :: nf_get_att_double + public :: nf_get_att_text + public :: nf_get_var_double + public :: nf_get_vara_double + public :: nf_get_var_int + public :: nf_get_vara_int + public :: nf_put_var_double + public :: nf_put_vara_double + public :: nf_put_var_int + public :: nf_put_vara_int + public :: nf_inq_dimid + public :: nf_max_name + public :: nf_max_var_dims + public :: nf_noerr + public :: nf_nowrite + public :: nf_enotatt + public :: nf_strerror +!EOP +!----------------------------------------------------------------------- + +contains + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: check_ret +! +! !INTERFACE: + subroutine check_ret(ret, calling, varexists) +! +! !DESCRIPTION: +! Check return status from netcdf call +! +! !ARGUMENTS: + implicit none + integer, intent(in) :: ret + character(len=*) :: calling + logical, intent(out), optional :: varexists +! +! !REVISION HISTORY: +! +!EOP +!----------------------------------------------------------------------- + + if ( present(varexists) ) varexists = .true. + if ( present(varexists) .and. ret == NF_ENOTVAR )then + varexists = .false. + else if (ret /= NF_NOERR) then + write(6,*)'netcdf error from ',trim(calling), ' rcode = ', ret, & + ' error = ', NF_STRERROR(ret) + call abort() + end if + + end subroutine check_ret + +!----------------------------------------------------------------------- +!BOP +! +! !IROUTINE: ncd_defvar +! +! !INTERFACE: + subroutine ncd_defvar(ncid, varname, xtype, & + dim1name, dim2name, dim3name, dim4name, dim5name, & + long_name, units, cell_method, missing_value, fill_value, & + imissing_value, ifill_value) +! +! !DESCRIPTION: +! Define a netcdf variable +! +! !ARGUMENTS: + implicit none + integer , intent(in) :: ncid ! input unit + character(len=*), intent(in) :: varname ! variable name + integer , intent(in) :: xtype ! external type + character(len=*), intent(in), optional :: dim1name ! dimension name + character(len=*), intent(in), optional :: dim2name ! dimension name + character(len=*), intent(in), optional :: dim3name ! dimension name + character(len=*), intent(in), optional :: dim4name ! dimension name + character(len=*), intent(in), optional :: dim5name ! dimension name + character(len=*), intent(in), optional :: long_name ! attribute + character(len=*), intent(in), optional :: units ! attribute + character(len=*), intent(in), optional :: cell_method ! attribute + real(r8) , intent(in), optional :: missing_value ! attribute for real + real(r8) , intent(in), optional :: fill_value ! attribute for real + integer , intent(in), optional :: imissing_value ! attribute for int + integer , intent(in), optional :: ifill_value ! attribute for int +! +! !REVISION HISTORY: +! +! +! !LOCAL VARIABLES: +!EOP + integer :: n ! indices + integer :: ndims ! dimension counter + integer :: dimid(5) ! dimension ids + integer :: varid ! variable id + integer :: itmp ! temporary + character(len=256) :: str ! temporary + character(len=32) :: subname='NCD_DEFVAR_REAL' ! subroutine name +!----------------------------------------------------------------------- + + if (.not. masterproc) return + + ! Determine dimension ids for variable + + dimid(:) = 0 + + if (present(dim1name)) then + call check_ret(nf_inq_dimid(ncid, dim1name, dimid(1)), subname) + end if + if (present(dim2name)) then + call check_ret(nf_inq_dimid(ncid, dim2name, dimid(2)), subname) + end if + if (present(dim3name)) then + call check_ret(nf_inq_dimid(ncid, dim3name, dimid(3)), subname) + end if + if (present(dim4name)) then + call check_ret(nf_inq_dimid(ncid, dim4name, dimid(4)), subname) + end if + if (present(dim5name)) then + call check_ret(nf_inq_dimid(ncid, dim5name, dimid(5)), subname) + end if + + ! Define variable + + if (present(dim1name)) then + ndims = 0 + do n = 1, size(dimid) + if (dimid(n) /= 0) ndims = ndims + 1 + end do + call check_ret(nf_def_var(ncid, trim(varname), xtype, ndims, dimid(1:ndims), varid), subname) + else + call check_ret(nf_def_var(ncid, varname, xtype, 0, 0, varid), subname) + end if + if (present(long_name)) then + call check_ret(nf_put_att_text(ncid, varid, 'long_name', len_trim(long_name), trim(long_name)), subname) + end if + if (present(units)) then + call check_ret(nf_put_att_text(ncid, varid, 'units', len_trim(units), trim(units)), subname) + end if + if (present(cell_method)) then + str = 'time: ' // trim(cell_method) + call check_ret(nf_put_att_text(ncid, varid, 'cell_method', len_trim(str), trim(str)), subname) + end if + if (present(fill_value)) then + call check_ret(nf_put_att_double(ncid, varid, '_FillValue', xtype, 1, fill_value), subname) + end if + if (present(missing_value)) then + call check_ret(nf_put_att_double(ncid, varid, 'missing_value', xtype, 1, missing_value), subname) + end if + if (present(ifill_value)) then + call check_ret(nf_put_att_int(ncid, varid, '_FillValue', xtype, 1, ifill_value), subname) + end if + if (present(imissing_value)) then + call check_ret(nf_put_att_int(ncid, varid, 'missing_value', xtype, 1, imissing_value), subname) + end if + + end subroutine ncd_defvar + + ! ======================================================================== + ! ncd_def_spatial_var routines: define a spatial netCDF variable (convenience wrapper to + ! ncd_defvar) + ! ======================================================================== + + !----------------------------------------------------------------------- + subroutine ncd_def_spatial_var_0lev(ncid, varname, xtype, long_name, units) + ! + ! !DESCRIPTION: + ! Define a spatial netCDF variable (convenience wrapper to ncd_defvar) + ! + ! The variable in question has ONLY spatial dimensions (no level or time dimensions) + ! + ! !USES: + use mkvarctl, only : outnc_1d + ! + ! !ARGUMENTS: + integer , intent(in) :: ncid ! input unit + character(len=*) , intent(in) :: varname ! variable name + integer , intent(in) :: xtype ! external type + character(len=*) , intent(in) :: long_name ! attribute + character(len=*) , intent(in) :: units ! attribute + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'ncd_def_spatial_var_0lev' + !----------------------------------------------------------------------- + + if (outnc_1d) then + call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & + dim1name='gridcell', & + long_name=long_name, units=units) + else + call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & + dim1name='lsmlon', dim2name='lsmlat', & + long_name=long_name, units=units) + end if + + end subroutine ncd_def_spatial_var_0lev + + !----------------------------------------------------------------------- + subroutine ncd_def_spatial_var_1lev(ncid, varname, xtype, lev1name, long_name, units) + ! + ! !DESCRIPTION: + ! Define a spatial netCDF variable (convenience wrapper to ncd_defvar) + ! + ! The variable in question has one level (or time) dimension in addition to its + ! spatial dimensions + ! + ! !USES: + use mkvarctl, only : outnc_1d + ! + ! !ARGUMENTS: + integer , intent(in) :: ncid ! input unit + character(len=*) , intent(in) :: varname ! variable name + integer , intent(in) :: xtype ! external type + character(len=*) , intent(in) :: lev1name ! name of level (or time) dimension + character(len=*) , intent(in) :: long_name ! attribute + character(len=*) , intent(in) :: units ! attribute + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'ncd_def_spatial_var_1lev' + !----------------------------------------------------------------------- + + if (outnc_1d) then + call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & + dim1name='gridcell', dim2name=lev1name, & + long_name=long_name, units=units) + else + call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & + dim1name='lsmlon', dim2name='lsmlat',dim3name=lev1name, & + long_name=long_name, units=units) + end if + + end subroutine ncd_def_spatial_var_1lev + + !----------------------------------------------------------------------- + subroutine ncd_def_spatial_var_2lev(ncid, varname, xtype, lev1name, lev2name, long_name, units) + ! + ! !DESCRIPTION: + ! Define a spatial netCDF variable (convenience wrapper to ncd_defvar) + ! + ! The variable in question has two level (or time) dimensions in addition to its + ! spatial dimensions + ! + ! !USES: + use mkvarctl, only : outnc_1d + ! + ! !ARGUMENTS: + integer , intent(in) :: ncid ! input unit + character(len=*) , intent(in) :: varname ! variable name + integer , intent(in) :: xtype ! external type + character(len=*) , intent(in) :: lev1name ! name of first level (or time) dimension + character(len=*) , intent(in) :: lev2name ! name of second level (or time) dimension + character(len=*) , intent(in) :: long_name ! attribute + character(len=*) , intent(in) :: units ! attribute + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'ncd_def_spatial_var_2lev' + !----------------------------------------------------------------------- + + if (outnc_1d) then + call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & + dim1name='gridcell', dim2name=lev1name, dim3name=lev2name, & + long_name=long_name, units=units) + else + call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & + dim1name='lsmlon', dim2name='lsmlat', dim3name=lev1name, dim4name=lev2name, & + long_name=long_name, units=units) + end if + + end subroutine ncd_def_spatial_var_2lev + + ! ======================================================================== + ! ncd_put_time_slice routines: write a single time slice of a variable + ! ======================================================================== + + !----------------------------------------------------------------------- + subroutine ncd_put_time_slice_1d(ncid, varid, time_index, data) + ! + ! !DESCRIPTION: + ! Write a single time slice of a 1-d variable + ! + ! !USES: + ! + ! !ARGUMENTS: + integer , intent(in) :: ncid ! netCDF id + integer , intent(in) :: varid ! variable id + integer , intent(in) :: time_index ! time index in file + real(r8), intent(in) :: data(:) ! data to write (a single time slice) + ! + ! !LOCAL VARIABLES: + integer, allocatable :: beg(:) ! begin indices for each dimension + integer, allocatable :: len(:) ! length along each dimension + + character(len=*), parameter :: subname = 'ncd_put_time_slice_1d' + !----------------------------------------------------------------------- + + call get_time_slice_beg_and_len(ncid, varid, time_index, beg, len) + call check_ret(nf_put_vara_double(ncid, varid, beg, len, data), subname) + + deallocate(beg, len) + + end subroutine ncd_put_time_slice_1d + + !----------------------------------------------------------------------- + subroutine ncd_put_time_slice_2d(ncid, varid, time_index, data) + ! + ! !DESCRIPTION: + ! Write a single time slice of a 2-d variable + ! + ! !USES: + ! + ! !ARGUMENTS: + integer , intent(in) :: ncid ! netCDF id + integer , intent(in) :: varid ! variable id + integer , intent(in) :: time_index ! time index in file + real(r8), intent(in) :: data(:,:) ! data to write (a single time slice) + ! + ! !LOCAL VARIABLES: + integer, allocatable :: beg(:) ! begin indices for each dimension + integer, allocatable :: len(:) ! length along each dimension + + character(len=*), parameter :: subname = 'ncd_put_time_slice_2d' + !----------------------------------------------------------------------- + + call get_time_slice_beg_and_len(ncid, varid, time_index, beg, len) + call check_ret(nf_put_vara_double(ncid, varid, beg, len, data), subname) + + deallocate(beg, len) + + end subroutine ncd_put_time_slice_2d + + + !----------------------------------------------------------------------- + subroutine get_time_slice_beg_and_len(ncid, varid, time_index, beg, len) + ! + ! !DESCRIPTION: + ! Determine beg and len vectors for writing a time slice. + ! + ! Assumes time is the last dimension of the given variable. + ! + ! Allocates memory for beg & len. + ! + ! !USES: + ! + ! !ARGUMENTS: + integer , intent(in) :: ncid ! netcdf ID + integer , intent(in) :: varid ! variable ID + integer , intent(in) :: time_index ! time index in file + integer, allocatable, intent(out) :: beg(:) ! begin indices for each dimension + integer, allocatable, intent(out) :: len(:) ! length along each dimension + ! + ! !LOCAL VARIABLES: + integer :: n ! index + integer :: ndims ! number of dimensions + integer, allocatable :: dimids(:) ! dimension IDs + + character(len=*), parameter :: subname = 'get_time_slice_beg_and_len' + !----------------------------------------------------------------------- + + call check_ret(nf_inq_varndims(ncid, varid, ndims), subname) + allocate(beg(ndims)) + allocate(len(ndims)) + allocate(dimids(ndims)) + + call check_ret(nf_inq_vardimid(ncid, varid, dimids), subname) + beg(1:ndims-1) = 1 + do n = 1,ndims-1 + call check_ret(nf_inq_dimlen(ncid, dimids(n), len(n)), subname) + end do + len(ndims) = 1 + beg(ndims) = time_index + + deallocate(dimids) + + end subroutine get_time_slice_beg_and_len + + + + +!------------------------------------------------------------------------------ +!BOP +! +! !IROUTINE: get_dim_lengths +! +! !INTERFACE: +subroutine get_dim_lengths(ncid, varname, ndims, dim_lengths) +! +! !DESCRIPTION: +! Returns the number of dimensions and an array containing the dimension lengths of a +! variable in an open netcdf file. +! +! Entries 1:ndims in the returned dim_lengths array contain the dimension lengths; the +! remaining entries in that vector are meaningless. The dim_lengths array must be large +! enough to hold all ndims values; if not, the code aborts (this can be ensured by passing +! in an array of length nf_max_var_dims). +! +! !USES: +! +! !ARGUMENTS: + implicit none + integer , intent(in) :: ncid ! netcdf id of an open netcdf file + character(len=*), intent(in) :: varname ! name of variable of interest + integer , intent(out):: ndims ! number of dimensions of variable + integer , intent(out):: dim_lengths(:) ! lengths of dimensions of variable +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +! +! !LOCAL VARIABLES: + integer :: varid + integer :: dimids(size(dim_lengths)) + integer :: i + character(len=*), parameter :: subname = 'get_dim_lengths' +!EOP +!------------------------------------------------------------------------------ + call check_ret(nf_inq_varid(ncid, varname, varid), subname) + call check_ret(nf_inq_varndims(ncid, varid, ndims), subname) + + if (ndims > size(dim_lengths)) then + write(6,*) trim(subname), ' ERROR: dim_lengths too small' + call abort() + end if + + call check_ret(nf_inq_vardimid(ncid, varid, dimids), subname) + + dim_lengths(:) = 0 ! pre-fill with 0 so we won't have garbage in elements past ndims + do i = 1, ndims + call check_ret(nf_inq_dimlen(ncid, dimids(i), dim_lengths(i)), subname) + end do + end subroutine get_dim_lengths + +!---------------------------------------------------------------------------- +!BOP +! +! !IROUTINE: convert_latlon +! +! !INTERFACE: + subroutine convert_latlon(ncid, varname, data) +! +! !DESCRIPTION: +! Convert a latitude or longitude variable from its units in the input file to degrees E / +! degrees N. Currently, this just handles conversions from radians to degrees. +! +! Assumes that the longitude / latitude variable has already been read from file, into +! the variable given by 'data'. ncid & varname give the file ID and variable name from +! which this variable was read (needed to obtain the variable's units). +! +! !USES: + use shr_const_mod, only : SHR_CONST_PI +! +! !ARGUMENTS: + implicit none + integer , intent(in) :: ncid ! ID of open netcdf file + character(len=*), intent(in) :: varname ! name of lat or lon variable that was read into 'data' + real(r8) , intent(inout):: data(:) ! latitude or longitude data +! +! !REVISION HISTORY: +! Author: Bill Sacks +! +! +! !LOCAL VARIABLES: +!EOP + integer :: ier ! error return code + integer :: varid ! netCDF variable id + integer :: units_len ! length of units attribute on file + character(len=256) :: units ! units attribute + character(len= 32) :: subname = 'convert_latlon' +!----------------------------------------------------------------- + + call check_ret(nf_inq_varid (ncid, varname, varid), subname) + ier = nf_inq_attlen(ncid, varid, 'units', units_len) + + ! Only do the following processing if there is no error; if ier /= NF_NOERR, that + ! probably means there isn't a units attribute -- in that case, assume units are + ! degrees and need no conversion + if (ier == NF_NOERR) then + if (units_len > len(units)) then + write(6,*) trim(subname), ' ERROR: units variable not long enough to hold attributue' + call abort() + end if + + call check_ret(nf_get_att_text(ncid, varid, 'units', units), subname) + + if (units(1:7) == 'radians') then + ! convert from radians to degrees + data(:) = data(:) * 180._r8 / SHR_CONST_PI + end if + end if + + end subroutine convert_latlon +!------------------------------------------------------------------------------ + + +end module mkncdio diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index f075bd3421..aa965f097d 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -140,8 +140,6 @@ program mksurfdat integer, allocatable :: harvind1D(:) ! Indices of 1D harvest fields integer, allocatable :: harvind2D(:) ! Indices of 2D harvest fields - logical :: zero_out - ! NOTE(bja, 2015-01) added to work around a ?bug? causing 1x1_urbanc_alpha to abort. See !/glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 logical :: urban_skip_abort_on_invalid_data_check @@ -381,7 +379,7 @@ program mksurfdat ! Call module initialization routines ! call mksoilInit( ) - !call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) + call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) allocate ( elevclass(nglcec+1) ) call mkglcmecInit (elevclass) call mkurbanInit (mksrf_furban) From f7b28645aea41786ddd4b71cf47d2223f9fb65d2 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 6 Feb 2022 11:40:51 -0700 Subject: [PATCH 043/614] extended interfaces for reading in rawdata 3d variables --- tools/mksurfdata_esmf/src/mkpioMod.F90 | 59 +++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index c3d77c4aaa..fc0d53c003 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -29,6 +29,7 @@ module mkpioMod interface mkpio_get_rawdata_level module procedure mkpio_get_rawdata1d_level_real4 module procedure mkpio_get_rawdata1d_level_real8 + module procedure mkpio_get_rawdata2d_level_real8 end interface mkpio_get_rawdata_level interface mkpio_get_rawdata @@ -1050,7 +1051,7 @@ subroutine mkpio_get_rawdata1d_level_real4(pioid, pio_iodesc, unlimited_index, v real(r8) , allocatable :: data_double(:) integer :: ns_i integer :: rcode - character(len=*), parameter :: subname = 'mkpio_get_rawdata1d_real4' + character(len=*), parameter :: subname = 'mkpio_get_rawdata_level_real4' !------------------------------------------------- ! Get variable id and type @@ -1141,4 +1142,60 @@ subroutine mkpio_get_rawdata1d_level_real8(pioid, pio_iodesc, unlimited_index, v end subroutine mkpio_get_rawdata1d_level_real8 + ! ======================================================================== + subroutine mkpio_get_rawdata2d_level_real8(pioid, pio_iodesc, unlimited_index, varname, data_i) + + ! input/output variables + type(file_desc_t), intent(inout) :: pioid + type(io_desc_t) , intent(inout) :: pio_iodesc + integer , intent(in) :: unlimited_index + character(len=*) , intent(in) :: varname ! field name in rawdata file + real(r8) , intent(inout) :: data_i(:,:) ! input raw data + + ! local variables + type(var_desc_t) :: pio_varid + integer :: pio_vartype + integer(i2) , allocatable :: data_short(:,:) + integer(i4) , allocatable :: data_int(:,:) + real(r4) , allocatable :: data_real(:,:) + integer :: ns_i + integer :: nlev + integer :: rcode + character(len=*), parameter :: subname = 'mkpio_get_rawdata1d_real4' + !------------------------------------------------- + + ! Get variable id and type + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + rcode = pio_inq_vartype(pioid, pio_varid, pio_vartype) + + ! Set unlimited frame index + call pio_setframe(pioid, pio_varid, int(unlimited_index, kind=Pio_Offset_Kind)) + + ! Read the input raw data + ns_i = size(data_i, dim=1) + nlev = size(data_i, dim=2) + if (pio_vartype == PIO_SHORT) then + allocate(data_short(ns_i,nlev)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_short, rcode) + data_i(:,:) = real(data_short(:,:), kind=r8) + deallocate(data_short) + else if (pio_vartype == PIO_INT) then + allocate(data_int(ns_i,nlev)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_int, rcode) + data_i(:,:) = real(data_int(:,:), kind=r4) + deallocate(data_int) + else if (pio_vartype == PIO_REAL) then + allocate(data_real(ns_i,nlev)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real, rcode) + data_i(:,:) = real(data_real(:,:), kind=r8) + deallocate(data_real) + else if (pio_vartype == PIO_DOUBLE) then + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_i, rcode) + else + call shr_sys_abort(subName//" ERROR: vartype not supported for "//trim(varname)) + end if + call ESMF_VMLogMemInfo("After call to pio_read_darray for varname "//trim(varname)) + + end subroutine mkpio_get_rawdata2d_level_real8 + end module mkpioMod From 3dafd6e8f16e37e31d9abfde44444492729d0874 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 6 Feb 2022 21:19:29 -0700 Subject: [PATCH 044/614] changes for mklai --- .../gen_mksurfdata_namelist.xml | 2 +- tools/mksurfdata_esmf/run/mksurfdata_in | 2 +- tools/mksurfdata_esmf/src/CMakeLists.txt | 4 +- tools/mksurfdata_esmf/src/mkfileMod.F90 | 16 +- tools/mksurfdata_esmf/src/mkglcmecMod.F90 | 5 - tools/mksurfdata_esmf/src/mklaiMod.F90 | 484 ++++++++---------- tools/mksurfdata_esmf/src/mkorganicMod.F90 | 2 +- tools/mksurfdata_esmf/src/mkpioMod.F90 | 75 ++- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 98 ++-- tools/mksurfdata_esmf/src/mksurfdata.F90 | 3 +- 10 files changed, 333 insertions(+), 358 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 42bf9412d7..ce09114b19 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -10,7 +10,7 @@ - lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.c170413.nc + lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.cdf5.c170413.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc diff --git a/tools/mksurfdata_esmf/run/mksurfdata_in b/tools/mksurfdata_esmf/run/mksurfdata_in index dc4332629b..d78f5dc8fd 100644 --- a/tools/mksurfdata_esmf/run/mksurfdata_in +++ b/tools/mksurfdata_esmf/run/mksurfdata_in @@ -1,5 +1,5 @@ &mksurfdata_input - mksrf_flai = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.c170413.nc' + mksrf_flai = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.cdf5.c220206.nc' mksrf_flai_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc' mksrf_flakwat = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_LakePnDepth_3x3min_simyr2004_csplk_c151015.nc' mksrf_flakwat_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 12e906ca8f..a8fcb1d33e 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -20,14 +20,16 @@ set(SRCFILES mkvarctl.F90 mkvarpar.F90 mkpioMod.F90 mkfileMod.F90 - mkdomainMod.F90 mkagfirepkmonthMod.F90 + mkdomainMod.F90 mkgdpMod.F90 mkglacierregionMod.F90 mkglcmecMod.F90 + mklaiMod.F90 mklanwatMod.F90 mkorganicMod.F90 mkpeatMod.F90 + mkpftConstantsMod.F90 mksoilcolMod.F90 mksoilfmaxMod.F90 mksoiltexMod.F90 diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 30fce8d726..97d25677f9 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -8,6 +8,7 @@ module mkfileMod use mkvarpar , only : nlevsoi, numrad, numstdpft use mkurbanparMod, only : numurbl, nlevurb, mkurbanpar use mkglcmecMod , only : nglcec + use mklaiMod , only : mklai #ifdef TODO use mkpftMod , only : mkpftAtt use mkharvestMod , only : mkharvest_fieldname, mkharvest_numtypes, mkharvest_longname, mkharvest_units, harvestDataType @@ -198,11 +199,6 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, lon, lat, dynlanduse, & 'unitless', fpeat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out peatland fraction" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'peatf', 'peatland fraction', & - 'unitless', fpeat, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glacier" call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLACIER', 'percent glacier', 'unitless', & pctgla, rc=rc) @@ -346,11 +342,11 @@ subroutine mkfile_fsurdat(nx, ny, mesh_o, lon, lat, dynlanduse, & ! Make LAI and SAI from 1/2 degree data and write to surface dataset ! Write to netcdf file is done inside mklai routine ! ---------------------------------------------------------------------- - ! if (root_task) then - ! write(ndiag,'(a)')'calling mklai' - ! end if - ! call mklai(mksrf_lai, mksrf_lai_mesh, pioid, mesh_o, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (root_task) then + write(ndiag,'(a)')'calling mklai' + end if + call mklai(mksrf_flai_mesh, mksrf_flai, mesh_o, pioid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! ---------------------------------------------------------------------- ! TODO: Write out variables that did not work in the loop diff --git a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 index 6ecdb290a3..b398447b2a 100644 --- a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 @@ -281,7 +281,6 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & do lev = 1, nlev write(6,'(i4)',advance='no') lev - call ESMF_LogWrite("DEBUG here0") ! Read in one level of data rcode = pio_inq_varid(pioid, 'PCT_GLC_GIC', pio_varid) call pio_setframe(pioid, pio_varid, int(lev,kind=Pio_Offset_Kind)) @@ -295,18 +294,15 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & data_pctglc_i(:) = data_pctglc_gic_i(:) + data_pctglc_icesheet_i(:) ! Map level of data to output grid - call ESMF_LogWrite("DEBUG here1") call regrid_rawdata(mesh_i, mesh_o, routehandle, data_pctglc_i, data_pctglc_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call regrid_rawdata(mesh_i, mesh_o, routehandle, data_pctglc_gic_i, data_pctglc_gic_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call regrid_rawdata(mesh_i, mesh_o, routehandle, data_pctglc_icesheet_i, data_pctglc_icesheet_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite("DEBUG here2") ! Compute output variables m = get_elevclass(topoice_i(lev)) - write(6,*)'DEBUG: m= ',m do no = 1,ns_o pctglcmec_o(no,m) = pctglcmec_o(no,m) + data_pctglc_o(no) if (outnc_3dglc) then @@ -315,7 +311,6 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & end if topoglcmec_unnorm_o(no,m) = topoglcmec_unnorm_o(no,m) + data_pctglc_o(no)*topoice_i(lev) end do - call ESMF_LogWrite("DEBUG here4") end do ! Close glacier input file diff --git a/tools/mksurfdata_esmf/src/mklaiMod.F90 b/tools/mksurfdata_esmf/src/mklaiMod.F90 index 3625bf78bd..0c2720b6f2 100644 --- a/tools/mksurfdata_esmf/src/mklaiMod.F90 +++ b/tools/mksurfdata_esmf/src/mklaiMod.F90 @@ -1,108 +1,92 @@ module mklaiMod - !----------------------------------------------------------------------- ! Make LAI/SAI/height data !----------------------------------------------------------------------- use ESMF use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 - use shr_sys_mod , only : shr_sys_abort - use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths - use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas - use mkutilsMod , only : chkerr - use mkvarctl - + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkpioMod , only : mkpio_get_rawdata, mkpio_get_rawdata_level + use mkpioMod , only : mkpio_def_spatial_var, mkpio_iodesc_output, mkpio_iodesc_rawdata + use mkpioMod , only : mkpio_put_time_slice + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkutilsMod , only : chkerr + use mkpftConstantsMod , only : c3cropindex, c3irrcropindex + use mkvarctl , only : root_task, ndiag, outnc_double, numpft, mpicom implicit none private +#include + public :: mklai - private :: pft_laicheck + private :: check_global_sums + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ !================================================================================= contains !================================================================================= - subroutine mklai(ldomain, mapfname, datfname, ndiag, ncido) + subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! ! Make LAI/SAI/height data - ! Portions of this code could be moved out of the month loop - ! for improved efficiency - ! - use mkvarpar, only : re - use mkpftConstantsMod, only : c3cropindex, c3irrcropindex ! ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh - integer , intent(out) :: glacier_region_o(:) ! glacier region - integer , intent(out) :: rc + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + type(file_desc_t) , intent(inout) :: pioid_o + integer , intent(out) :: rc ! ! local variables - integer :: numpft_i ! number of plant types on input - type(ESMF_RouteHandle) :: routehandle ! nearest neighbor routehandle + type(ESMF_RouteHandle) :: routehandle ! nearest neighbor routehandle type(ESMF_Mesh) :: mesh_i - type(file_desc_t) :: pioid - integer :: ni,no,l + type(file_desc_t) :: pioid_i + type(io_desc_t) :: pio_iodesc_i + type(io_desc_t) :: pio_iotype_i + type(var_desc_t) :: pio_varid_i + integer :: pio_vartype_i + type(io_desc_t) :: pio_iodesc_o + type(var_desc_t) :: pio_varid_o + integer :: dimid + integer :: ni,no integer :: ns_i, ns_o + integer :: k,l,m,nt ! indices + integer :: numpft_i ! number of plant types on input + integer :: ntime ! number of input time samples integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) real(r8), allocatable :: data_i(:,:) real(r8), allocatable :: data_o(:,:) - real(r8), allocatable :: mlai_o(:,:) ! monthly lai - real(r8), allocatable :: msai_o(:,:) ! monthly sai - real(r8), allocatable :: mhgtt_o(:,:) ! monthly height (top) - real(r8), allocatable :: mhgtb_o(:,:) ! monthly height (bottom) - real(r8), allocatable :: mlai_max(:,:) ! monthly lai - real(r8), allocatable :: msai_max(:,:) ! monthly sai - real(r8), allocatable :: mhgtt_max(:,:) ! monthly height (top) - real(r8), allocatable :: mhgtb_max(:,:) ! monthly height (bottom) - real(r8), allocatable :: mlai_i(:,:) ! monthly lai in - real(r8), allocatable :: msai_i(:,:) ! monthly sai in - real(r8), allocatable :: mhgtt_i(:,:) ! monthly height (top) in - real(r8), allocatable :: mhgtb_i(:,:) ! monthly height (bottom) in - real(r8), allocatable :: frac_dst(:) ! output fractions: same as frac_dst - integer, allocatable :: laimask(:,:) ! lai+sai output mask for each plant function type - real(r8) :: glai_o(0:numpft) ! output grid: global area pfts - real(r8) :: gsai_o(0:numpft) ! output grid: global area pfts - real(r8) :: ghgtt_o(0:numpft) ! output grid: global area pfts - real(r8) :: ghgtb_o(0:numpft) ! output grid: global area pfts - real(r8) :: glai_i(0:numpft) ! input grid: global area pfts - real(r8) :: gsai_i(0:numpft) ! input grid: global area pfts - real(r8) :: ghgtt_i(0:numpft) ! input grid: global area pfts - real(r8) :: ghgtb_i(0:numpft) ! input grid: global area pfts - real(r8) :: garea_i ! input grid: global area - real(r8) :: garea_o ! output grid: global area - integer :: mwts ! number of weights - integer :: ni,no,ns_i,ns_o ! indices - integer :: k,l,n,m ! indices - integer :: dimids(4) ! netCDF dimension ids - integer :: bego(4),leno(4) ! netCDF bounds - integer :: begi(4),leni(4) ! netCDF bounds - integer :: ntim ! number of input time samples - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=256) :: name ! name of attribute - character(len=256) :: unit ! units of attribute - character(len= 32) :: subname = 'mklai' + real(r8), allocatable :: mlai_o(:,:) ! monthly lai + real(r8), allocatable :: msai_o(:,:) ! monthly sai + real(r8), allocatable :: mhgtt_o(:,:) ! monthly height (top) + real(r8), allocatable :: mhgtb_o(:,:) ! monthly height (bottom) + integer, allocatable :: laimask(:,:) ! lai+sai output mask for each plant function type + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + integer :: ier, rcode ! error status + integer :: xtype ! external type + character(len=*), parameter :: subname = 'mklai' !----------------------------------------------------------------------- rc = ESMF_SUCCESS if (root_task) then write(ndiag,*) - write (ndiag,'(a)') 'Attempting to make LAIs/SAIs/heights .....' + write(ndiag,'(a)') 'Attempting to make LAIs/SAIs/heights .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if - ! Open input data file call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh @@ -124,7 +108,7 @@ subroutine mklai(ldomain, mapfname, datfname, ndiag, ncido) if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i if (frac_i(ni) > 0._r8) then @@ -133,6 +117,7 @@ subroutine mklai(ldomain, mapfname, datfname, ndiag, ncido) mask_i(ni) = 0 end if end do + deallocate(frac_i) call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -142,10 +127,10 @@ subroutine mklai(ldomain, mapfname, datfname, ndiag, ncido) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - rcode = pio_inq_dimid(pioid 'pft', dimid) - rcode = pio_inq_dimlen(pioid, dimid, numpft_i) - rcode = pio_inq_dimid(pioid, 'time', dimid) - rcode = pio_inq_dimlen(pioid, dimid, ntim) + rcode = pio_inq_dimid(pioid_i, 'pft', dimid) + rcode = pio_inq_dimlen(pioid_i, dimid, numpft_i) + rcode = pio_inq_dimid(pioid_i, 'time', dimid) + rcode = pio_inq_dimlen(pioid_i, dimid, ntime) if (numpft_i /= numpft+1) then write(6,*) 'WARNING: ' // trim(subname) // '(): parameter numpft+1 = ', numpft+1, & @@ -160,20 +145,11 @@ subroutine mklai(ldomain, mapfname, datfname, ndiag, ncido) call shr_sys_abort() end if endif - if (ntim /= 12) then + if (ntime /= 12) then write(6,*)'MKLAI: must have 12 time samples on input data' call shr_sys_abort() endif - ! Dynamic allocation of variables of size 0:numpft_i - allocate(mlai_i(ns_i,0:numpft_i), & - msai_i(ns_i,0:numpft_i), & - mhgtt_i(ns_i,0:numpft_i), & - mhgtb_i(ns_i,0:numpft_i), stat=ier) - if (ier /= 0) then - write(6,*)'mklai allocation error'; call shr_sys_abort() - end if - ! Dynamic allocation of variables of size 0:numpft allocate(mlai_o(ns_o,0:numpft), & msai_o(ns_o,0:numpft), & @@ -184,255 +160,201 @@ subroutine mklai(ldomain, mapfname, datfname, ndiag, ncido) write(6,*)'mklai allocation error'; call shr_sys_abort() end if + ! Create iodescriptor for a single level of the input data + call mkpio_iodesc_rawdata(mesh_i, 'MONTHLY_LAI', pioid_i, pio_varid_i, pio_vartype_i, pio_iodesc_i, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Put output file back in define mode, define variables and then end define mode + if ( outnc_double ) then + xtype = PIO_DOUBLE + else + xtype = PIO_REAL + end if + + rcode = pio_redef(pioid_o) + call mkpio_def_spatial_var(pioid_o, 'MONTHLY_LAI', xtype, & + lev1name='lsmpft', lev2name='time', long_name='monthly leaf area index', units='unitless') + call mkpio_def_spatial_var(pioid_o, 'MONTHLY_SAI',xtype, & + lev1name='lsmpft', lev2name='time', long_name='monthly stem area index', units='unitless') + call mkpio_def_spatial_var(pioid_o, 'MONTHLY_HEIGHT_TOP', xtype, & + lev1name='lsmpft', lev2name='time',long_name='monthly height top', units='meters') + call mkpio_def_spatial_var(pioid_o, 'MONTHLY_HEIGHT_BOT', xtype, & + lev1name='lsmpft', lev2name='time', long_name='monthly height bottom', units='meters') + rcode = pio_enddef(pioid_o) + + ! Create iodescriptor for a single level of the output data + call mkpio_iodesc_output(pioid_o, mesh_o, 'MONTHLY_LAI', pio_iodesc_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for MONTHLY_LAI') + + ! Allocate memory that will be used in time loop below allocate(data_i(0:numpft_i,ns_i),stat=ier) if (ier/=0) call shr_sys_abort() + allocate(data_o(0:numpft_i,ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() - ! Determine number of dimensions in output by querying MONTHLY_LAI - + ! The following is needed for the global check + allocate(area_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(area_o(ns_o), stat=ier) + if (ier/=0) call shr_sys_abort() + call get_meshareas(mesh_i, area_i, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call get_meshareas(mesh_o, area_o, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Loop over months + ! Loop over the 12 months and write out data mlai_o(:,:) = 0. msai_o(:,:) = 0. mhgtt_o(:,:) = 0. mhgtb_o(:,:) = 0. + do nt = 1, ntime + + ! Below - copy LAI, SAI, & heights from the C3 crop (pft15) + ! to the irrigated (pft16) whether crop is on or off - do nt = 1, ntim - call mkpio_get_rawdata(pioid, 'MONTHLY_LAI', mesh_i, data_i, nt=nt, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft, rc) + ! Read in one time slice of data for mlai, regrid and write out + rcode = pio_inq_varid(pioid_i, 'MONTHLY_LAI', pio_varid_i) + call pio_setframe(pioid_i, pio_varid_i, int(nt, kind=Pio_Offset_Kind)) + call mkpio_get_rawdata_level(pioid_i, pio_iodesc_i, nt, 'MONTHLY_LAI', data_i) + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft_i, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - do l = 0,numpft_i-1 + do l = 0,numpft_i-1 ! TODO: why -1? do no = 1,ns_o mlai_o(no,l) = data_o(l,no) end do end do - - call mkpio_get_rawdata(pioid, 'MONTHLY_SAI', mesh_i, data_i, nt=nt, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft, rc) + mlai_o(:,c3irrcropindex) = mlai_o(:,c3cropindex) + rcode = pio_inq_varid(pioid_o, 'MONTHLY_LAI', pio_varid_o) + call mkpio_put_time_slice(pioid_o, pio_varid_o, pio_iodesc_o, nt, mlai_o) + call check_global_sums('LAI', ns_i, ns_o, numpft_i, nt, & + data_i, data_o, area_i, area_o, mask_i, frac_o) + + ! Read in one time slice of data for msai, regrid and write out + rcode = pio_inq_varid(pioid_i, 'MONTHLY_SAI', pio_varid_i) + call pio_setframe(pioid_i, pio_varid_i, int(nt, kind=Pio_Offset_Kind)) + call mkpio_get_rawdata_level(pioid_i, pio_iodesc_i, nt, 'MONTHLY_SAI', data_i) + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft_i, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - do l = 0,numpft_i-1 + do l = 0,numpft_i-1 ! TODO: why -1? do no = 1,ns_o - lai_o(no,l) = data_o(l,no) + msai_o(no,l) = data_o(l,no) end do end do - - call mkpio_get_rawdata(pioid, 'MONTHLY_HEIGHT_TOP', mesh_i, data_i, nt=nt, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft, rc) + msai_o(:,c3irrcropindex) = msai_o(:,c3cropindex) + rcode = pio_inq_varid(pioid_o, 'MONTHLY_SAI', pio_varid_o) + call mkpio_put_time_slice(pioid_o, pio_varid_o, pio_iodesc_o, nt, msai_o) + + ! Read in one time slice of data for msai, regrid and write out + rcode = pio_inq_varid(pioid_i, 'MONTHLY_HEIGHT_TOP', pio_varid_i) + call pio_setframe(pioid_i, pio_varid_i, int(nt, kind=Pio_Offset_Kind)) + call mkpio_get_rawdata_level(pioid_i, pio_iodesc_i, nt, 'MONTHLY_HEIGHT_TOP', data_i) + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft_i, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - do l = 0,numpft_i-1 + do l = 0,numpft_i-1 ! TODO: why -1? do no = 1,ns_o mhgtt_o(no,l) = data_o(l,no) end do end do - - call mkpio_get_rawdata(pioid, 'MONTHLY_HEIGHT_BOT', mesh_i, data_i, nt=nt, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft, rc) + mhgtt_o(:,c3irrcropindex) = mhgtt_o(:,c3cropindex) + rcode = pio_inq_varid(pioid_o, 'MONTHLY_HEIGHT_TOP', pio_varid_o) + call mkpio_put_time_slice(pioid_o, pio_varid_o, pio_iodesc_o, nt, mhgtt_o) + + ! Read in one time slice of data for msai, regrid and write out + rcode = pio_inq_varid(pioid_i, 'MONTHLY_HEIGHT_BOT', pio_varid_i) + call pio_setframe(pioid_i, pio_varid_i, int(nt, kind=Pio_Offset_Kind)) + call mkpio_get_rawdata_level(pioid_i, pio_iodesc_i, nt, 'MONTHLY_HEIGHT_BOT', data_i) + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft_i, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - do l = 0,numpft_i-1 + do l = 0,numpft_i-1 ! TODO: why -1? do no = 1,ns_o mhgtb_o(no,l) = data_o(l,no) end do end do - - ! copy LAI, SAI, & heights from the C3 crop (pft15) - ! to the irrigated (pft16) whether crop is on or off - mlai_o(:,c3irrcropindex) = mlai_o(:,c3cropindex) - msai_o(:,c3irrcropindex) = msai_o(:,c3cropindex) - mhgtt_o(:,c3irrcropindex) = mhgtt_o(:,c3cropindex) mhgtb_o(:,c3irrcropindex) = mhgtb_o(:,c3cropindex) + rcode = pio_inq_varid(pioid_o, 'MONTHLY_HEIGHT_BOT', pio_varid_o) + call mkpio_put_time_slice(pioid_o, pio_varid_o, pio_iodesc_o, nt, mhgtb_o) - ! Determine laimask - laimask(:,:) = 0 - - ! ----------------------------------------------------------------- - ! Output model resolution LAI/SAI/HEIGHT data - ! ----------------------------------------------------------------- - - if ( outnc_double ) then - xtype = PIO_DOUBLE - else - xtype = PIO_REAL + if (root_task) then + write (ndiag,*) 'Successfully made LAIs/SAIs/heights for month ', nt end if - rcode = pio_redef(pioid_o) - - call mkpio_def_spatial_var(pioid_o, varname='MONTHLY_LAI', xtype=xtype, & - lev1name='lsmpft', lev2name='time', long_name='monthly leaf area index', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='MONTHLY_SAI', xtype=xtype, & - lev1name='lsmpft', lev2name='time', long_name='monthly stem area index', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='MONTHLY_HEIGHT_TOP', xtype=xtype, & - lev1name='lsmpft', lev2name='time',long_name='monthly height top', units='meters') - - call mkpio_def_spatial_var(pioid_o, varname='MONTHLY_HEIGHT_BOT', xtype=xtype, & - lev1name='lsmpft', lev2name='time', long_name='monthly height bottom', units='meters') - - ! End define model - rcode = pio_enddef(pioid_o) - - ! Only need to define 1 PIO descriptor here - call mkpio_iodesc_output(pioid_o, mesh_o, 'MONTHLY_LAI', pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for MONTHLY_LAI') + end do ! end loop over months - rcode = pio_inq_varid(pioid_o, 'MONTHLY_LAI', pio_varid) - call pio_write_darray(pioid_o, pio_varid, pio_iodesc, mlai_o, rcode) + ! Close the input file + call pio_closefile(pioid_i) + call ESMF_VMLogMemInfo("After pio_closefile for input in "//trim(subname)) - rcode = pio_inq_varid(pioid_o, 'MONTHLY_SAI', pio_varid) - call pio_write_darray(pioid_o, pio_varid, pio_iodesc, msai_o, rcode) + ! Release memory + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) - rcode = pio_inq_varid(pioid_o, 'MONTHLY_HEIGHT_TOP', pio_varid) - call pio_write_darray(pioid_o, pio_varid, pio_iodesc, mhgtt_o, rcode) - - rcode = pio_inq_varid(pioid_o, 'MONTHLY_HEIGHT_BOT', pio_varid) - call pio_write_darray(pioid_o, pio_varid, pio_iodesc, mhgtt_o, rcode) - - ! TODO - output time - write out the wholE time array at once - !rcode = pio_inq_varid(pioid_o, 'time', pio_varid) - !rcode = pio_put_var(pioid_o, pio_varid, bego(ndimso), leno(ndimso), m) - - ! ----------------------------------------------------------------- - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - - ! Input grid global area - - garea_i = 0. - do ni = 1,ns_i - garea_i = garea_i + tgridmap%area_src(ni) - end do + end subroutine mklai - glai_i(:) = 0. - gsai_i(:) = 0. - ghgtt_i(:) = 0. - ghgtb_i(:) = 0. - do l = 0, numpft_i - 1 - do ni = 1, ns_i - glai_i(l) = glai_i(l) + mlai_i(ni,l) *tgridmap%area_src(ni)*& - tdomain%mask(ni)*re**2 - gsai_i(l) = gsai_i(l) + msai_i(ni,l) *tgridmap%area_src(ni)*& - tdomain%mask(ni)*re**2 - ghgtt_i(l) = ghgtt_i(l)+ mhgtt_i(ni,l)*tgridmap%area_src(ni)*& - tdomain%mask(ni)*re**2 - ghgtb_i(l) = ghgtb_i(l)+ mhgtb_i(ni,l)*tgridmap%area_src(ni)*& - tdomain%mask(ni)*re**2 - end do - end do + !================================================================================= + subroutine check_global_sums(name, ns_i, ns_o, numpft_i, nt, & + data_i, data_o, area_i, area_o, mask_i, frac_o) + + ! Compare global areas on input and output grids + + ! input/otuput variables + character(len=*) , intent(in) :: name + integer , intent(in) :: ns_i + integer , intent(in) :: ns_o + integer , intent(in) :: nt + integer , intent(in) :: numpft_i + real(r8) , intent(in) :: data_i(:,:) + real(r8) , intent(in) :: data_o(:,:) + real(r8) , intent(in) :: area_i(:) + real(r8) , intent(in) :: area_o(:) + integer , intent(in) :: mask_i(:) + real(r8) , intent(in) :: frac_o(:) - ! Output grid global area + ! local variables + integer :: ni, no, l, k + integer :: ier + real(r8) :: local_i(0:numpft_i) ! local global area, by surface type + real(r8) :: local_o(0:numpft_i) ! local global area, by surface type + real(r8) :: global_i(0:numpft_i) ! input grid: global area pfts + real(r8) :: global_o(0:numpft_i) ! output grid: global area pfts + !----------------------------------------------------------------------- - garea_o = 0. - do no = 1,ns_o - garea_o = garea_o + tgridmap%area_dst(no) + ! Input grid global area + local_i(:) = 0. + do l = 0, numpft_i - 1 + do ni = 1, ns_i + local_i(l) = local_i(l) + data_i(l,ni) *area_i(ni)*mask_i(ni) end do + end do + call mpi_reduce(local_i, global_i , numpft_i, MPI_REAL8, MPI_SUM, 0, mpicom, ier) - glai_o(:) = 0. - gsai_o(:) = 0. - ghgtt_o(:) = 0. - ghgtb_o(:) = 0. - do l = 0, numpft_i - 1 - do no = 1,ns_o - glai_o(l) = glai_o(l) + mlai_o(no,l)*tgridmap%area_dst(no)* & - frac_dst(no)*re**2 - gsai_o(l) = gsai_o(l) + msai_o(no,l)*tgridmap%area_dst(no)* & - frac_dst(no)*re**2 - ghgtt_o(l) = ghgtt_o(l)+ mhgtt_o(no,l)*tgridmap%area_dst(no)* & - frac_dst(no)*re**2 - ghgtb_o(l) = ghgtb_o(l)+ mhgtb_o(no,l)*tgridmap%area_dst(no)* & - frac_dst(no)*re**2 - end do + ! Output grid global area + local_o(:) = 0. + do l = 0, numpft_i - 1 + do no = 1, ns_o + local_o(l) = local_o(l) + data_o(l,no) *area_o(no)*frac_o(no) end do + end do + call mpi_reduce(local_o, global_o , numpft_i, MPI_REAL8, MPI_SUM, 0, mpicom, ier) - ! Comparison - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'LAI Output for month ',m - write (ndiag,'(1x,70a1)') ('=',k=1,70) - + ! Comparison + if (root_task) then write (ndiag,*) + write (ndiag,*) trim(name)//' Output for month ',nt write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,1001) -1001 format (1x,'PFT input grid area output grid area',/ & - 1x,3x,' 10**6 km**2',' 10**6 km**2') + write (ndiag,101) +101 format (1x,'PFT input grid area output grid area',/ & + 1x,3x,' 10**6 km**2',' 10**6 km**2') write (ndiag,'(1x,70a1)') ('.',k=1,70) write (ndiag,*) - do l = 0, numpft - write (ndiag,1002) l, glai_i(l)*1.e-06*1.e-02,glai_o(l)*1.e-06*1.e-02 -1002 format (1x,i3,f16.3,f17.3) + do l = 0, numpft_i-1 + write (ndiag,102) l, global_i(l)*1.e-06*1.e-02, global_o(l)*1.e-06*1.e-02 +102 format (1x,i3,f16.3,f17.3) end do + end if - write (6,*) 'Successfully made LAIs/SAIs/heights for month ', m - - enddo - write (6,*) - - ! Close input file - call check_ret(nf_close(ncidi), subname) - - ! consistency check that PFT and LAI+SAI make sense - !call pft_laicheck( ni_s, pft_i, laimask ) - - ! Deallocate dynamic memory - deallocate(mlai_i) - deallocate(msai_i) - deallocate(mhgtt_i) - deallocate(mhgtb_i) - deallocate(mlai_o) - deallocate(msai_o) - deallocate(mhgtt_o) - deallocate(mhgtb_o) - deallocate(laimask) - deallocate(frac_dst) - - call gridmap_clean(tgridmap) - call domain_clean(tdomain) - - end subroutine mklai - - !----------------------------------------------------------------------- - subroutine pft_laicheck( ni_s, pctpft_i, laimask ) - - ! !USES: - ! - ! !DESCRIPTION: - ! - ! consistency check that PFT and LAI+SAI make sense - ! - ! !ARGUMENTS: - integer , intent(in) :: ni_s ! input PFT grid resolution - real(r8), intent(in) :: pctpft_i(:,:) ! % plant function types - integer, intent(in) :: laimask(:,:) ! mask where LAI+SAI > 0 - - ! local variables - character(len=*), parameter :: subName="pft_laicheck" - integer :: ni,l,n,nc ! Indices - !----------------------------------------------------------------------- - - do l = 0, numpft - n = 0 - nc = 0 - do ni = 1,ni_s - if ( pctpft_i(ni,l) > 0.0_r8 ) nc = nc + 1 - if ( (pctpft_i(ni,l) > 0.0_r8) .and. (laimask(ni,l) /= 1) )then - write (6,*) subName//' :: warning: pft and LAI+SAI mask not consistent!' - write (6,*) 'ni,l = ', ni, l - write (6,*) 'pctpft_i = ',pctpft_i(ni,l) - write (6,*) 'laimask = ', laimask(ni,l) - n = n + 1 - end if - end do - if ( n > max(4,nc/4) ) then - write (6,*) subName//' :: pft/LAI+SAI inconsistency over more than 25% land-cover' - write (6,*) '# inconsistent points, total PFT pts, total LAI+SAI pts = ', & - n, nc, sum(laimask(:,l)) - call abort() - end if - end do - - end subroutine pft_laicheck + end subroutine check_global_sums end module mklaiMod diff --git a/tools/mksurfdata_esmf/src/mkorganicMod.F90 b/tools/mksurfdata_esmf/src/mkorganicMod.F90 index 3b04ada05d..a32e37173f 100644 --- a/tools/mksurfdata_esmf/src/mkorganicMod.F90 +++ b/tools/mksurfdata_esmf/src/mkorganicMod.F90 @@ -60,7 +60,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) if (root_task) then write(ndiag,*) - write (ndiag,'(a)')'Attempting to make organic mater dataset .....' + write(ndiag,'(a)')'Attempting to make organic mater dataset .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index fc0d53c003..0ac49ee953 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -319,13 +319,14 @@ subroutine mkpio_get_rawdata2d_real4(pioid, varname, mesh_i, data_i, rc) end subroutine mkpio_get_rawdata2d_real4 !=============================================================== - subroutine mkpio_get_rawdata2d_real8(pioid, varname, mesh_i, data_i, rc) + subroutine mkpio_get_rawdata2d_real8(pioid, varname, mesh_i, data_i, setframe, rc) ! input/output variables type(file_desc_t) , intent(inout) :: pioid character(len=*) , intent(in) :: varname ! field name in rawdata file type(ESMF_Mesh) , intent(in) :: mesh_i real(r8) , intent(inout) :: data_i(:,:) ! input raw data + integer, optional , intent(in) :: setframe integer , intent(out) :: rc ! local variables @@ -501,6 +502,8 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, dimlens(1),dimlens(2),dimlens(3) end if else + write(6,*)' ndims = ',ndims + write(6,*)' unlimited_dim = ',unlimited_dim call shr_sys_abort('for lon/lat support up to 3 spatial dims plus a time dim') end if else @@ -541,6 +544,7 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) type(var_desc_t) :: pio_varid integer :: pio_vartype integer :: rCode ! pio return code (only used when pio error handling is PIO_BCAST_ERROR) + integer :: unlimdim logical :: unlimited_dim character(*), parameter :: subname = '(shr_strdata_set_stream_iodesc) ' !------------------------------------------------------------------------------- @@ -557,8 +561,8 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) do n = 1, ndims rcode = pio_inq_dimlen(pioid, dimids(n), dimlens(n)) end do - rcode = pio_inq_dimname(pioid, dimids(ndims), dimname) - unlimited_dim = (dimids(ndims) == PIO_UNLIMITED) + rcode = pio_inq_unlimdim(pioid, unlimdim) + unlimited_dim = (dimids(ndims) == unlimdim) ! Get compdof from mesh call ESMF_MeshGet(mesh, elementdistGrid=distGrid, rc=rc) @@ -635,6 +639,7 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) end if else if (ndims == 4) then if (unlimited_dim) then + write(6,*)'Creating an output pio descriptor here' call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) else call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3),dimlens(4)/), compdof3d, pio_iodesc) @@ -1155,11 +1160,12 @@ subroutine mkpio_get_rawdata2d_level_real8(pioid, pio_iodesc, unlimited_index, v ! local variables type(var_desc_t) :: pio_varid integer :: pio_vartype - integer(i2) , allocatable :: data_short(:,:) - integer(i4) , allocatable :: data_int(:,:) - real(r4) , allocatable :: data_real(:,:) - integer :: ns_i - integer :: nlev + integer(i2) , allocatable :: data_short2d(:,:) + integer(i4) , allocatable :: data_int2d(:,:) + real(r4) , allocatable :: data_real2d(:,:) + real(r8) , allocatable :: data_double2d(:,:) + integer :: ns_i, nlev + integer :: n, l integer :: rcode character(len=*), parameter :: subname = 'mkpio_get_rawdata1d_real4' !------------------------------------------------- @@ -1172,25 +1178,48 @@ subroutine mkpio_get_rawdata2d_level_real8(pioid, pio_iodesc, unlimited_index, v call pio_setframe(pioid, pio_varid, int(unlimited_index, kind=Pio_Offset_Kind)) ! Read the input raw data - ns_i = size(data_i, dim=1) - nlev = size(data_i, dim=2) + ! - levels are the innermost dimension for esmf fields + ! - levels are the outermost dimension in pio reads + ! Input data is read into (ns_i,nlev) array and then transferred to data_i(nlev,ns_i) + ! which sill be used for esmf regridding + nlev = size(data_i, dim=1) + ns_i = size(data_i, dim=2) if (pio_vartype == PIO_SHORT) then - allocate(data_short(ns_i,nlev)) - call pio_read_darray(pioid, pio_varid, pio_iodesc, data_short, rcode) - data_i(:,:) = real(data_short(:,:), kind=r8) - deallocate(data_short) + allocate(data_short2d(ns_i,nlev)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_short2d, rcode) + do l = 1,nlev + do n = 1,ns_i + data_i(l,n) = real(data_short2d(n,l), kind=r8) + end do + end do + deallocate(data_short2d) else if (pio_vartype == PIO_INT) then - allocate(data_int(ns_i,nlev)) - call pio_read_darray(pioid, pio_varid, pio_iodesc, data_int, rcode) - data_i(:,:) = real(data_int(:,:), kind=r4) - deallocate(data_int) + allocate(data_int2d(ns_i,nlev)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_int2d, rcode) + do l = 1,nlev + do n = 1,ns_i + data_i(l,n) = real(data_int2d(n,l), kind=r8) + end do + end do + deallocate(data_int2d) else if (pio_vartype == PIO_REAL) then - allocate(data_real(ns_i,nlev)) - call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real, rcode) - data_i(:,:) = real(data_real(:,:), kind=r8) - deallocate(data_real) + allocate(data_real2d(ns_i,nlev)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_real2d, rcode) + do l = 1,nlev + do n = 1,ns_i + data_i(l,n) = real(data_real2d(n,l), kind=r8) + end do + end do + deallocate(data_real2d) else if (pio_vartype == PIO_DOUBLE) then - call pio_read_darray(pioid, pio_varid, pio_iodesc, data_i, rcode) + allocate(data_double2d(ns_i,nlev)) + call pio_read_darray(pioid, pio_varid, pio_iodesc, data_double2d, rcode) + do l = 1,nlev + do n = 1,ns_i + data_i(l,n) = data_double2d(n,l) + end do + end do + deallocate(data_double2d) else call shr_sys_abort(subName//" ERROR: vartype not supported for "//trim(varname)) end if diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index d89cb320ac..740b834a52 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -17,7 +17,9 @@ module mksoilcolMod #include public :: mksoilcol ! Set soil colors + private :: mkrank + private :: check_global_areas character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -54,10 +56,6 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r logical :: has_color ! whether this grid cell has non-zero color integer :: nsoilcol_local integer :: maxindex(1) - real(r4), allocatable :: loc_gast_i(:) ! local global area, by surface type - real(r4), allocatable :: loc_gast_o(:) ! local global area, by surface type - real(r4), allocatable :: gast_i(:) ! global area, by surface type - real(r4), allocatable :: gast_o(:) ! global area, by surface type integer :: rcode, ier character(len=*), parameter :: subname = 'mksoilcol' !----------------------------------------------------------------------- @@ -113,6 +111,7 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r mask_i(ni) = 0 end if end do + deallocate(frac_i) call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -197,41 +196,14 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r end do ! Compare global area of each soil color on input and output grids - allocate(area_i(ns_i)) allocate(area_o(ns_o)) call get_meshareas(mesh_i, area_i, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call get_meshareas(mesh_o, area_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - -! allocate(loc_gast_i(0:nsoilcol)) -! allocate(loc_gast_o(0:nsoilcol)) -! allocate(gast_i(0:nsoilcol)) -! allocate(gast_o(0:nsoilcol)) -! loc_gast_i(:) = 0. -! do ni = 1,ns_i -! k = soil_color_i(ni) -! loc_gast_i(k) = loc_gast_i(k) + area_i(ni) * mask_i(ni) -! end do -! call mpi_reduce(loc_gast_i, gast_i, nsoilcol+1, nsoilcol+1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) -! loc_gast_o(:) = 0. -! do no = 1,ns_o -! k = soil_color_o(no) -! loc_gast_o(k) = loc_gast_o(k) + area_o(no) * frac_o(no) -! end do -! call mpi_reduce(loc_gast_o, gast_o, nsoilcol+1, nsoilcol+1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) - -! write (ndiag,*) -! write (ndiag,'(1x,70a1)') ('.',k=1,70) -! write (ndiag,101) -! 101 format (1x,'soil color type',5x,' input grid area output grid area',/ & -! 1x,20x,' 10**6 km**2',' 10**6 km**2') -! write (ndiag,'(1x,70a1)') ('.',k=1,70) -! write (ndiag,*) -! do k = 0, nsoilcol -! write (ndiag,'(1x,a,i3,d16.3,d17.3)') 'class ',k, gast_i(k)*1.e-6, gast_o(k)*1.e-6 -! end do + call check_global_areas('soil color type', ns_i, ns_o, nsoilcol, & + soil_color_i, soil_color_o, area_i, area_o, mask_i, frac_o) ! Clean up memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) @@ -284,4 +256,64 @@ subroutine mkrank (n, a, iv) end if end subroutine mkrank + !=============================================================== + subroutine check_global_areas(name, ns_i, ns_o, nsoilcol, & + soil_color_i, soil_color_o, area_i, area_o, mask_i, frac_o) + + use mkvarctl, only : mpicom, MPI_INTEGER, MPI_MAX + + ! Compare global areas on input and output grids + + ! input/otuput variables + character(len=*) , intent(in) :: name + integer , intent(in) :: ns_i + integer , intent(in) :: ns_o + integer , intent(in) :: nsoilcol + real(r4) , intent(in) :: soil_color_i(ns_i) + integer , intent(in) :: soil_color_o(ns_o) + real(r8) , intent(in) :: area_i(ns_i) + real(r8) , intent(in) :: area_o(ns_o) + integer , intent(in) :: mask_i(ns_i) + real(r4) , intent(in) :: frac_o(ns_o) + + ! local variables + integer :: ni, no, l, k + integer :: ier + real(r4) :: local_i(0:nsoilcol) ! local global area, by surface type + real(r4) :: local_o(0:nsoilcol) ! local global area, by surface type + real(r4) :: global_i(0:nsoilcol) ! input grid: global area pfts + real(r4) :: global_o(0:nsoilcol) ! output grid: global area pfts + !----------------------------------------------------------------------- + + ! Input grid global area + local_i(:) = 0 + do ni = 1,ns_i + k = int(soil_color_i(ni)) + local_i(k) = local_i(k) + area_i(ni) * mask_i(ni) + end do + call mpi_reduce(local_i, global_i, nsoilcol+1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) + + ! Output grid global area + local_o(:) = 0. + do no = 1,ns_o + k = soil_color_o(no) + local_o(k) = local_o(k) + area_o(no) * frac_o(no) + end do + call mpi_reduce(local_o, global_o, nsoilcol+1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) + + ! Comparison + if (root_task) then + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,101) +101 format (1x,'soil color type',5x,' input grid area output grid area',/ & + 1x,20x,' 10**6 km**2',' 10**6 km**2') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + do k = 0, nsoilcol + write (ndiag,'(1x,a,i3,d16.3,d17.3)') 'class ',k, global_i(k)*1.e-6, global_o(k)*1.e-6 + end do + end if + end subroutine check_global_areas + end module mksoilcolMod diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index a010dda6bd..bfe5051ec9 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -93,7 +93,6 @@ program mksurfdata use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs use shr_sys_mod , only : shr_sys_abort #ifdef TODO - use mklaiMod , only : mklai use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft @@ -526,7 +525,7 @@ program mksurfdata pctwet(n) = float(nint(pctwet(n))) pctgla(n) = float(nint(pctgla(n))) end do - !Debug + !DEBUG call ESMF_LogWrite("After fixes", ESMF_LOGMSG_INFO) From 26903f03355a1432d128624952fc77b78ae7a20b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 6 Feb 2022 21:42:16 -0700 Subject: [PATCH 045/614] fixes for mklai output --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 97d25677f9..c274c0c580 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -9,7 +9,9 @@ module mkfileMod use mkurbanparMod, only : numurbl, nlevurb, mkurbanpar use mkglcmecMod , only : nglcec use mklaiMod , only : mklai + use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft, num_natpft #ifdef TODO + use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array use mkpftMod , only : mkpftAtt use mkharvestMod , only : mkharvest_fieldname, mkharvest_numtypes, mkharvest_longname, mkharvest_units, harvestDataType #endif @@ -394,6 +396,8 @@ subroutine mkfile_define_dims(pioid, nx, ny, dynlanduse) ! local variables integer :: dimid ! temporary integer :: rcode ! error status + integer :: pftsize + integer :: natpftsize character(len=*), parameter :: subname = 'mkfile_define_dims' !----------------------------------------------------------------------- @@ -415,6 +419,21 @@ subroutine mkfile_define_dims(pioid, nx, ny, dynlanduse) rcode = pio_def_dim(pioid, 'time' , PIO_UNLIMITED , dimid) rcode = pio_def_dim(pioid, 'nchar' , 256 , dimid) + if (.not. dynlanduse) then + pftsize = numpft + 1 + rcode = pio_def_dim(pioid, 'lsmpft' , pftsize, dimid) + end if + ! TODO: uncomment this + ! natpftsize = num_natpft + 1 + ! rcode = pio_def_dim (pioid, 'natpft', natpftsize, dimid) + + ! zero-size dimensions can cause problems, so we only include the + ! cft dimension if num_cft > 0 Note that this implies that we can + ! only include PCT_CFT on the dataset if num_cft > 0 + if (num_cft > 0) then + rcode = pio_def_dim (pioid, 'cft', num_cft, dimid) + end if + end subroutine mkfile_define_dims !================================================================================= From 22a40d2af26f096853e403ce5007703bd47e17ea Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 7 Feb 2022 08:15:28 -0700 Subject: [PATCH 046/614] more updates --- tools/mksurfdata_esmf/run/mksurfdata_in | 4 +- tools/mksurfdata_esmf/src/CMakeLists.txt | 3 + tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 | 180 ++-- tools/mksurfdata_esmf/src/mkpftMod.F90 | 895 +++++++----------- tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 | 25 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 452 ++++----- 6 files changed, 636 insertions(+), 923 deletions(-) diff --git a/tools/mksurfdata_esmf/run/mksurfdata_in b/tools/mksurfdata_esmf/run/mksurfdata_in index d78f5dc8fd..03cc248ceb 100644 --- a/tools/mksurfdata_esmf/run/mksurfdata_in +++ b/tools/mksurfdata_esmf/run/mksurfdata_in @@ -23,9 +23,9 @@ mksrf_fglacier_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' mksrf_fglacierregion = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_GlacierRegion_10x10min_nomask_cd5_c220131.nc' mksrf_fglacierregion_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_cdf5_c200129.nc' - mksrf_fvegtyp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_1850.c190119.nc' + mksrf_fvegtyp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_1850.cdf5.c190119.nc' mksrf_fvegtyp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' - mksrf_fhrvtyp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_1850.c190119.nc' + mksrf_fhrvtyp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_1850.cdf5.c190119.nc' mksrf_fhrvtyp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' mksrf_fgdp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_gdp_0.5x0.5_AVHRR_simyr2000.c130228.nc' mksrf_fgdp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index a8fcb1d33e..101e8146ea 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -30,6 +30,9 @@ set(SRCFILES mkvarctl.F90 mkorganicMod.F90 mkpeatMod.F90 mkpftConstantsMod.F90 + mkpftMod.F90 + mkpftUtilsMod.F90 + mkpctPftTypeMod.F90 mksoilcolMod.F90 mksoilfmaxMod.F90 mksoiltexMod.F90 diff --git a/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 b/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 index 8a4073e6b3..9d2faad36e 100644 --- a/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 @@ -1,27 +1,17 @@ module mkpctPftTypeMod !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mkpctPftType - ! - ! !DESCRIPTION: ! Derived type and associated methods for operating on pct_pft data - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! !----------------------------------------------------------------------- - !!USES: use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_abort implicit none private - ! !PUBLIC TYPES public :: pct_pft_type - + type :: pct_pft_type private real(r8), allocatable :: pct_p2l(:) ! pct of each pft on the landunit @@ -45,7 +35,6 @@ module mkpctPftTypeMod procedure, private :: check_vals ! perform a sanity check after setting values end type pct_pft_type - ! !PUBLIC MEMBER FUNCTIONS public :: update_max_array ! given an array of pct_pft_type variables update the max_p2l values from pct_p2l public :: get_pct_p2l_array ! given an array of pct_pft_type variables, return a 2-d array of pct_p2l public :: get_pct_l2g_array ! given an array of pct_pft_type variables, return an array of pct_l2g @@ -56,13 +45,12 @@ module mkpctPftTypeMod module procedure constructor_empty ! initialize a new pct_pft_type object for an empty landunit end interface pct_pft_type - ! !PRIVATE TYPES: real(r8), parameter :: tol = 1.e-12_r8 ! tolerance for checking equality - !EOP - +!=============================================================== contains - +!=============================================================== + ! ======================================================================== ! Constructors ! ======================================================================== @@ -70,7 +58,6 @@ module mkpctPftTypeMod !----------------------------------------------------------------------- function constructor_pong(pct_p2g, first_pft_index, default_pct_p2l) result(this) ! - ! !DESCRIPTION: ! Given the % of each pft on the grid cell, create a pct_pft_type object. ! ! Note that pct_p2g should just contain the pfts in this landunit. @@ -80,16 +67,14 @@ function constructor_pong(pct_p2g, first_pft_index, default_pct_p2l) result(this ! (1) size of default_pct_p2l must match size of pct_p2g ! (2) default_pct_p2l must sum to 100% ! - ! !ARGUMENTS: - type(pct_pft_type) :: this ! function result - + ! input/output variables + type(pct_pft_type) :: this ! function result real(r8), intent(in) :: pct_p2g(:) ! % of each pft on the grid cell integer , intent(in) :: first_pft_index ! index of the first pft (lower bound of arrays) real(r8), intent(in) :: default_pct_p2l(:) ! default % of each pft on the landunit, used if total landunit area is 0% ! - ! !LOCAL VARIABLES: + ! local variables integer :: last_pft_index - character(len=*), parameter :: subname = 'constructor_pong' !----------------------------------------------------------------------- @@ -107,22 +92,19 @@ end function constructor_pong !----------------------------------------------------------------------- function constructor(pct_p2l, pct_l2g, first_pft_index) result(this) ! - ! !DESCRIPTION: - ! Given the % of each pft on the land cell and % of land unit on grid cell, + ! Given the % of each pft on the land cell and % of land unit on grid cell, ! create a pct_pft_type object. ! ! Note that pct_p2g should just contain the pfts in this landunit. ! - ! !ARGUMENTS: + ! input/output variables type(pct_pft_type) :: this ! function result - real(r8), intent(in) :: pct_p2l(:) ! % of each pft on the landunit real(r8), intent(in) :: pct_l2g ! % of the landunit on the grid cell integer , intent(in) :: first_pft_index ! index of the first pft (lower bound of arrays) ! - ! !LOCAL VARIABLES: + ! local variables integer :: last_pft_index - character(len=*), parameter :: subname = 'constructor' !----------------------------------------------------------------------- @@ -136,26 +118,22 @@ end function constructor !----------------------------------------------------------------------- function constructor_empty() result(this) ! - ! !DESCRIPTION: ! Initialize a new pct_pft_type object for an empty landunit - that is, one that has ! no PFTs on it, and never can (e.g., the crop landunit when we're running without ! prognostic crops, so that the landunit is always empty). ! - ! !ARGUMENTS: + ! input/output variables type(pct_pft_type) :: this ! function result ! - ! !LOCAL VARIABLES: - + ! local variables: character(len=*), parameter :: subname = 'constructor_empty' !----------------------------------------------------------------------- - + this%pct_l2g = 0._r8 allocate(this%pct_p2l(0)) end function constructor_empty - - ! ======================================================================== ! Public member functions ! ======================================================================== @@ -163,18 +141,16 @@ end function constructor_empty !----------------------------------------------------------------------- function get_pct_p2l(this) result(pct_p2l) ! - ! !DESCRIPTION: ! Get an array holding % of each pft on the landunit ! - ! !ARGUMENTS: + ! input/output variables class(pct_pft_type), intent(in) :: this real(r8) :: pct_p2l(size(this%pct_p2l)) ! function result ! - ! !LOCAL VARIABLES: - + ! local variables: character(len=*), parameter :: subname = 'get_pct_p2l' !----------------------------------------------------------------------- - + pct_p2l = this%pct_p2l end function get_pct_p2l @@ -182,18 +158,16 @@ end function get_pct_p2l !----------------------------------------------------------------------- function get_pct_p2g(this) result(pct_p2g) ! - ! !DESCRIPTION: ! Get an array holding % of each pft on the gridcell ! - ! !ARGUMENTS: + ! input/output variables class(pct_pft_type), intent(in) :: this real(r8) :: pct_p2g(size(this%pct_p2l)) ! function result ! - ! !LOCAL VARIABLES: - + ! local variables: character(len=*), parameter :: subname = 'get_pct_p2g' !----------------------------------------------------------------------- - + pct_p2g(:) = this%pct_p2l(:) * this%pct_l2g / 100._r8 end function get_pct_p2g @@ -201,18 +175,16 @@ end function get_pct_p2g !----------------------------------------------------------------------- function get_pct_l2g(this) result(pct_l2g) ! - ! !DESCRIPTION: ! Get % of landunit on the grid cell ! - ! !ARGUMENTS: + ! input/output variables real(r8) :: pct_l2g ! function result class(pct_pft_type), intent(in) :: this ! - ! !LOCAL VARIABLES: - + ! local variables: character(len=*), parameter :: subname = 'get_pct_l2g' !----------------------------------------------------------------------- - + pct_l2g = this%pct_l2g end function get_pct_l2g @@ -220,18 +192,16 @@ end function get_pct_l2g !----------------------------------------------------------------------- function get_first_pft_index(this) result(first_pft_index) ! - ! !DESCRIPTION: ! Get index of the first pft (lower bound of arrays) ! - ! !ARGUMENTS: + ! input/output variables integer :: first_pft_index ! function result class(pct_pft_type), intent(in) :: this ! - ! !LOCAL VARIABLES: - + ! local variables: character(len=*), parameter :: subname = 'get_first_pft_index' !----------------------------------------------------------------------- - + first_pft_index = lbound(this%pct_p2l, 1) end function get_first_pft_index @@ -239,19 +209,17 @@ end function get_first_pft_index !----------------------------------------------------------------------- function get_one_pct_p2g(this, pft_index) result(pct_p2g) ! - ! !DESCRIPTION: ! Get % of gridcell for a single pft ! - ! !ARGUMENTS: + ! input/output variables real(r8) :: pct_p2g ! function result class(pct_pft_type), intent(in) :: this integer :: pft_index ! - ! !LOCAL VARIABLES: - + ! local variables: character(len=*), parameter :: subname = 'get_one_pct_p2g' !----------------------------------------------------------------------- - + pct_p2g = this%pct_p2l(pft_index) * this%pct_l2g / 100._r8 end function get_one_pct_p2g @@ -259,18 +227,16 @@ end function get_one_pct_p2g !----------------------------------------------------------------------- subroutine set_pct_l2g(this, pct_l2g_new) ! - ! !DESCRIPTION: ! Set percent of landunit on the grid cell. Keep pct_p2l the same as before. ! - ! !ARGUMENTS: + ! input/output variables class(pct_pft_type), intent(inout) :: this real(r8), intent(in) :: pct_l2g_new ! new percent of this landunit with respect to grid cell ! - ! !LOCAL VARIABLES: - + ! local variables: character(len=*), parameter :: subname = 'set_pct_l2g' !----------------------------------------------------------------------- - + if (pct_l2g_new < 0._r8 .or. pct_l2g_new > (100._r8 + tol)) then write(6,*) subname//' ERROR: pct_l2g_new must be between 0 and 100%' write(6,*) 'pct_l2g_new = ', pct_l2g_new @@ -284,7 +250,6 @@ end subroutine set_pct_l2g !----------------------------------------------------------------------- subroutine set_one_pct_p2g(this, pft_index, pct_p2g_new) ! - ! !DESCRIPTION: ! Set percent pft for a single pft, given its weight on the grid cell. ! ! The landunit percent is adjusted appropriately. In addition, the coverage of other @@ -295,24 +260,23 @@ subroutine set_one_pct_p2g(this, pft_index, pct_p2g_new) ! ! Note about pft_index: Note that the first element of the array has index given by ! the first_pft_index value given to the constructor. - ! - ! !ARGUMENTS: + ! + ! input/output variables class(pct_pft_type), intent(inout) :: this integer , intent(in) :: pft_index ! index of the pft to change - real(r8), intent(in) :: pct_p2g_new ! new percent of this pft, with respect to grid cell + real(r8), intent(in) :: pct_p2g_new ! new percent of this pft, with respect to grid cell ! - ! !LOCAL VARIABLES: + ! local variables: real(r8), allocatable :: pct_p2g(:) ! % of each pft on the grid cell - character(len=*), parameter :: subname = 'set_pct_p2g' !----------------------------------------------------------------------- - + if (pct_p2g_new < 0._r8 .or. pct_p2g_new > (100._r8 + tol)) then write(6,*) subname//' ERROR: pct_p2g_new must be between 0 and 100%' write(6,*) 'pct_p2g_new = ', pct_p2g_new call shr_sys_abort() end if - + allocate(pct_p2g(lbound(this%pct_p2l, 1) : ubound(this%pct_p2l, 1))) pct_p2g(:) = this%get_pct_p2g() pct_p2g(pft_index) = pct_p2g_new @@ -329,19 +293,17 @@ end subroutine set_one_pct_p2g !----------------------------------------------------------------------- subroutine merge_pfts(this, source, dest) ! - ! !DESCRIPTION: ! Merge all area from one PFT into another PFT ! - ! !ARGUMENTS: + ! input/output variables class(pct_pft_type), intent(inout) :: this integer, intent(in) :: source ! index of source PFT integer, intent(in) :: dest ! index of dest PFT ! - ! !LOCAL VARIABLES: - + ! local variables: character(len=*), parameter :: subname = 'merge_pfts' !----------------------------------------------------------------------- - + this%pct_p2l(dest) = this%pct_p2l(dest) + this%pct_p2l(source) this%pct_p2l(source) = 0._r8 @@ -352,18 +314,14 @@ end subroutine merge_pfts !----------------------------------------------------------------------- subroutine remove_small_cover(this, too_small, nsmall) ! - ! !DESCRIPTION: ! Remove any small PFTs, defined as those whose grid cell coverage is below some ! threshold. Also returns the number of small PFTs found. ! - ! !USES: - ! - ! !ARGUMENTS: + ! input/output variables class(pct_pft_type), intent(inout) :: this real(r8), intent(in) :: too_small ! threshold for considering a PFT too small (% of grid cell) integer , intent(out) :: nsmall ! number of small (but non-zero) PFTs found ! - ! !LOCAL VARIABLES: integer :: pft_lbound integer :: pft_ubound integer :: pft_index @@ -373,7 +331,7 @@ subroutine remove_small_cover(this, too_small, nsmall) character(len=*), parameter :: subname = 'remove_small_cover' !----------------------------------------------------------------------- - + pft_lbound = lbound(this%pct_p2l, 1) pft_ubound = ubound(this%pct_p2l, 1) allocate(pct_p2g (pft_lbound : pft_ubound)) @@ -383,7 +341,7 @@ subroutine remove_small_cover(this, too_small, nsmall) pct_p2g(:) = this%get_pct_p2g() is_zero(:) = (pct_p2g == 0._r8) is_small(:) = (pct_p2g < too_small .and. .not. is_zero(:)) - + nsmall = count(is_small(:)) if (nsmall > 0) then @@ -417,19 +375,17 @@ end subroutine remove_small_cover !----------------------------------------------------------------------- subroutine convert_from_p2g(this, pct_p2g, default_pct_p2l) ! - ! !DESCRIPTION: ! Given a p2g array, compute the p2l array and l2g ! - ! !ARGUMENTS: + ! input/output variables class(pct_pft_type), intent(inout) :: this real(r8), intent(in) :: pct_p2g(:) ! % of each pft on the grid cell real(r8), intent(in) :: default_pct_p2l(:) ! default % of each pft on the landunit, used if total landunit area is 0% ! - ! !LOCAL VARIABLES: - + ! local variables: character(len=*), parameter :: subname = 'convert_from_p2g' !----------------------------------------------------------------------- - + ! Check pre-conditions if (size(pct_p2g) /= size(this%pct_p2l) .or. size(default_pct_p2l) /= size(this%pct_p2l)) then @@ -474,18 +430,16 @@ end subroutine convert_from_p2g !----------------------------------------------------------------------- subroutine check_vals(this, caller) ! - ! !DESCRIPTION: ! Perform a sanity check after setting values ! - ! !ARGUMENTS: + ! input/output variables class(pct_pft_type), intent(in) :: this character(len=*), intent(in) :: caller ! name of the calling subroutine ! - ! !LOCAL VARIABLES: - + ! local variables: character(len=*), parameter :: subname = 'check_vals' !----------------------------------------------------------------------- - + if (abs(sum(this%pct_p2l) - 100._r8) > tol) then write(6,*) subname//' ERROR from ', caller, ': pct_p2l does not sum to 100' write(6,*) 'sum(this%pct_p2l) = ', sum(this%pct_p2l) @@ -505,7 +459,7 @@ subroutine check_vals(this, caller) end if end subroutine check_vals - + ! ======================================================================== ! Module-level routines (not member functions) ! ======================================================================== @@ -513,27 +467,25 @@ end subroutine check_vals !----------------------------------------------------------------------- subroutine update_max_array(pct_pft_max_arr,pct_pft_arr) ! - ! !DESCRIPTION: ! Given an array of pct_pft_type variables, update all the max_p2l variables. ! - ! Assumes that all elements of pct_pft_max_arr and pct_pft_arr have the same + ! Assumes that all elements of pct_pft_max_arr and pct_pft_arr have the same ! size and lower bound for their pct_p2l array. ! - ! !ARGUMENTS: + ! input/output variables ! workaround for gfortran bug (58043): declare this 'type' rather than 'class': type(pct_pft_type), intent(inout) :: pct_pft_max_arr(:) type(pct_pft_type), intent(in) :: pct_pft_arr(:) ! - ! !LOCAL VARIABLES: + ! local variables: integer :: pft_lbound integer :: pft_ubound integer :: arr_index integer :: pft_index - character(len=*), parameter :: subname = 'update_max_array' !----------------------------------------------------------------------- - - + + pft_lbound = lbound(pct_pft_arr(1)%pct_p2l, 1) pft_ubound = ubound(pct_pft_arr(1)%pct_p2l, 1) @@ -544,7 +496,7 @@ subroutine update_max_array(pct_pft_max_arr,pct_pft_arr) write(6,*) 'the same size and lower bound for their pct_p2l array' call shr_sys_abort() end if - + if (pct_pft_arr(arr_index)%pct_l2g > pct_pft_max_arr(arr_index)%pct_l2g) then pct_pft_max_arr(arr_index)%pct_l2g = pct_pft_arr(arr_index)%pct_l2g end if @@ -561,26 +513,24 @@ end subroutine update_max_array !----------------------------------------------------------------------- function get_pct_p2l_array(pct_pft_arr) result(pct_p2l) ! - ! !DESCRIPTION: ! Given an array of pct_pft_type variables, return a 2-d array of pct_p2l. ! ! Assumes that all elements of pct_pft_arr have the same size and lower bound for ! their pct_p2l array. ! - ! !ARGUMENTS: + ! input/output variables real(r8), allocatable :: pct_p2l(:,:) ! function result (n_elements, n_pfts) ! workaround for gfortran bug (58043): declare this 'type' rather than 'class': type(pct_pft_type), intent(in) :: pct_pft_arr(:) ! - ! !LOCAL VARIABLES: + ! local variables: integer :: pft_lbound integer :: pft_ubound integer :: arr_index integer :: pft_index - character(len=*), parameter :: subname = 'get_pct_p2l_array' !----------------------------------------------------------------------- - + pft_lbound = lbound(pct_pft_arr(1)%pct_p2l, 1) pft_ubound = ubound(pct_pft_arr(1)%pct_p2l, 1) @@ -593,7 +543,7 @@ function get_pct_p2l_array(pct_pft_arr) result(pct_p2l) write(6,*) 'the same size and lower bound for their pct_p2l array' call shr_sys_abort() end if - + do pft_index = pft_lbound, pft_ubound pct_p2l(arr_index, pft_index) = pct_pft_arr(arr_index)%pct_p2l(pft_index) end do @@ -604,19 +554,17 @@ end function get_pct_p2l_array !----------------------------------------------------------------------- function get_pct_l2g_array(pct_pft_arr) result(pct_l2g) ! - ! !DESCRIPTION: ! Given an array of pct_pft_type variables, return an array of pct_l2g. ! - ! !ARGUMENTS: + ! input/output variables real(r8), allocatable :: pct_l2g(:) ! function result class(pct_pft_type), intent(in) :: pct_pft_arr(:) ! - ! !LOCAL VARIABLES: + ! local variables: integer :: arr_index - character(len=*), parameter :: subname = 'get_pct_l2g_array' !----------------------------------------------------------------------- - + allocate(pct_l2g(size(pct_pft_arr))) pct_l2g = pct_pft_arr(:)%pct_l2g diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index 9953567612..a798c83ffc 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -9,18 +9,18 @@ module mkpftMod use mkpioMod , only : mkpio_iodesc_rawdata, mkpio_get_rawdata_level use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas use mkutilsMod , only : chkerr - use mkvarctl , only : ndiag, root_task, outnc_3dglc, numpft - use mkvarpar , only : noveg - use mkvarctl , only : numpft + use mkvarctl , only : numpft, root_task, ndiag + use mkvarpar , only : numstdpft, numstdcft, noveg use mkpftConstantsMod implicit none private ! By default make data private +#include + public :: mkpftInit ! Initialization public :: mkpft ! Set PFT public :: mkpft_parse_oride ! Parse the string with PFT fraction/index info to override - public :: mkpftAtt ! Write out attributes to output file on pft private :: mkpft_check_oride ! Check the pft_frc and pft_idx values for correctness @@ -29,13 +29,15 @@ module mkpftMod ! The sum of pft_frc must = 100%, and each pft_idx point in the array corresponds to ! the fraction in pft_frc. Only the first few points are used until pft_frc = 0.0. - integer :: m ! index - integer, public :: pft_idx(0:maxpft) = & ! PFT vegetation index to override with - (/ ( -1, m = 0, maxpft ) /) - real(r8), public :: pft_frc(0:maxpft) = & ! PFT vegetation fraction to override with - (/ ( 0.0_r8, m = 0, maxpft ) /) + integer :: m ! index + + ! PFT vegetation index to override with + integer, public :: pft_idx(0:maxpft) = (/ ( -1, m = 0, maxpft ) /) + + ! PFT vegetation fraction to override with + real(r8), public :: pft_frc(0:maxpft) = (/ ( 0.0_r8, m = 0, maxpft ) /) - ! !PRIVATE DATA MEMBERS: + ! private data members: logical, public, protected :: use_input_pft = .false. ! Flag to override PFT with input values logical, public, protected :: presc_cover = .false. ! Flag to prescribe vegetation coverage integer, private :: nzero ! index of first zero fraction @@ -55,9 +57,14 @@ module mkpftMod module procedure :: constructor ! PFT Overide object constructor end interface pft_oride + character(len=35) :: veg(0:maxpft) ! vegetation types + ! Module instance of PFT override object ! Used for both zeroing out PFT's as well as setting specified PFT's over the gridcell - type(pft_oride), private :: pft_override + type(pft_oride), private :: pft_override + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ !=============================================================== contains @@ -66,9 +73,7 @@ module mkpftMod subroutine mkpftInit( zero_out_l, all_veg_l ) ! ! Initialize of Make PFT data - ! - use mkvarpar, only : numstdpft, numstdcft - + ! ! input/output variables logical, intent(in) :: zero_out_l ! If veg should be zero'ed out logical, intent(in) :: all_veg_l ! If should zero out other fractions so that all land-cover is vegetation @@ -83,13 +88,11 @@ subroutine mkpftInit( zero_out_l, all_veg_l ) if ( maxpft < numpft ) then write(6,*) subname//'number PFT is > max allowed!' call shr_sys_abort() - return end if nzero = -1 call mkpft_check_oride( error_happened ) if ( error_happened )then write(6,*) subname//'Problem setting pft override settings' - return end if if ( zero_out_l .and. use_input_pft )then write(6,*) subname//"trying to both zero out all PFT's as well as set them to specific values" @@ -115,17 +118,16 @@ subroutine mkpftInit( zero_out_l, all_veg_l ) if ( zero_out_l .and. all_veg_l )then write(6,*) subname//'zeroing out vegetation and setting vegetation to 100% is a contradiction!' call shr_sys_abort() - return end if ! Determine number of PFTs on the natural vegetation landunit, and number of CFTs on - ! the crop landunit. + ! the crop landunit. ! ! For the sake of dynamic PFTs and dynamic landunits, it helps for the structure of the ! surface dataset to reflect the subgrid structure that will be used by CLM. Currently ! generic crops will always go on the crop landunit, regardless of whether or not we're - ! using the extra specific crops (so we always run CLM with create_crop_landunit=.true.). - ! When we create a surface dataset WITH the extra specific crops, all crops + ! using the extra specific crops (so we always run CLM with create_crop_landunit=.true.). + ! When we create a surface dataset WITH the extra specific crops, all crops ! (including the generic crops) again go on the crop landunit. num_natpft = numstdpft - numstdcft @@ -168,85 +170,6 @@ subroutine mkpftInit( zero_out_l, all_veg_l ) end if end if - end subroutine mkpftInit - - !=============================================================== - subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft_o, rc) - ! - ! Make PFT data - ! - ! This dataset consists of the %cover of the [numpft]+1 PFTs used by - ! the model. The input %cover pertains to the "vegetated" portion of the - ! grid cell and sums to 100. The real portion of each grid cell - ! covered by each PFT is the PFT cover times the fraction of the - ! grid cell that is land. This is the quantity preserved when - ! area-averaging from the input (1/2 degree) grid to the models grid. - ! - ! Upon return from this routine, the % cover of the natural veg + crop landunits is - ! generally 100% everywhere; this will be normalized later to account for special landunits. - ! - use mkpctPftTypeMod, only : pct_pft_type - use mkpftConstantsMod, only : natpft_lb, natpft_ub, num_cft, cft_lb, cft_ub - ! - ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o - real(r8) , intent(out) :: pctlnd_o(:) ! output grid:%land/gridcell - type(pct_pft_type), intent(out) :: pctnatpft_o(:) ! natural PFT cover - type(pct_pft_type), intent(out) :: pctcft_o(:) ! crop (CFT) cover - ! - ! local variables: - type(ESMF_RouteHandle) :: routehandle - type(ESMF_Mesh) :: mesh_i - type(file_desc_t) :: pioid - integer :: ni,no,k - integer :: ns_i, ns_o - integer , allocatable :: mask_i(:) - real(r8), allocatable :: frac_i(:) - real(r8), allocatable :: frac_o(:) - real(r8), allocatable :: area_i(:) - real(r8), allocatable :: area_o(:) - type(pct_pft_type), allocatable :: pctnatpft_i(:) ! input grid: natural PFT cover - type(pct_pft_type), allocatable :: pctcft_i(:) ! input grid: crop (CFT) cover - real(r8), allocatable :: pctpft_i(:,:) ! input grid: PFT percent - real(r8), allocatable :: pctpft_o(:,:) ! output grid: PFT percent (% of grid cell) - real(r8), allocatable :: pctnatveg_i(:) ! input grid: natural veg percent (% of grid cell) - real(r8), allocatable :: pctnatveg_o(:) ! output grid: natural veg percent (% of grid cell) - real(r8), allocatable :: pctcrop_i(:) ! input grid: all crop percent (% of grid cell) - real(r8), allocatable :: pctcrop_o(:) ! output grid: all crop percent (% of grid cell) - real(r8), allocatable :: pct_cft_i(:,:) ! input grid: CFT (Crop Functional Type) percent (% of landunit cell) - real(r8), allocatable :: pct_cft_o(:,:) ! output grid: CFT (Crop Functional Type) percent (% of landunit cell) - real(r8), allocatable :: pct_nat_pft_i(:,:) ! input grid: natural PFT percent (% of landunit cell) - real(r8), allocatable :: pct_nat_pft_o(:,:) ! output grid: natural PFT percent (% of landunit cell) - real(r8), allocatable :: temp_i(:,:) ! input grid: temporary 2D variable to read in - integer :: numpft_i ! num of plant types input data - integer :: natpft_i ! num of natural plant types input data - integer :: ncft_i ! num of crop types input data - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: wst_sum ! sum of %pft - real(r8), allocatable :: gpft_o(:) ! output grid: global area pfts - real(r8) :: garea_o ! output grid: global area - real(r8), allocatable :: gpft_i(:) ! input grid: global area pfts - real(r8) :: garea_i ! input grid: global area - integer :: k,n,m,ni,no,ns_i,ns_o ! indices - integer :: ndims ! number of dimensions for a variable on the file - integer :: dimlens(3) ! dimension lengths for a variable on the file - integer :: ier ! error status - real(r8) :: relerr = 0.0001_r8 ! max error: sum overlap wts ne 1 - logical :: error_happened ! If an error was triggered so should return - character(len=35) :: veg(0:maxpft) ! vegetation types - character(len=*), parameter :: subname = 'mkpf' - !----------------------------------------------------------------------- - - if (root_task) - write(ndiag,*) - write(ndiag,'(a)') 'Attempting to make PFTs .....' - write(ndiag,'(a)') ' Input file is '//trim(file_data_i) - write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) - end if - ! ----------------------------------------------------------------- ! Set the vegetation types ! ----------------------------------------------------------------- @@ -333,23 +256,102 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft 'tropical_soybean ', & 'irrigated_tropical_soybean ' /) end if - if ( numpft == numstdpft )then + if (numpft == numstdpft )then if (root_task) then write(ndiag, '(a,i8)')'Creating surface datasets with the standard # of PFTs =', numpft end if else if ( numpft > numstdpft )then if (root_task) then write(ndiag,'(a,i8)')'Creating surface datasets with extra types for crops; total pfts =', numpft + end if else write(6,*) subname//': parameter numpft is NOT set to a known value (should be 16 or more) =',numpft call shr_sys_abort() end if - ! ----------------------------------------------------------------- - ! Read input PFT file - ! ----------------------------------------------------------------- + end subroutine mkpftInit - ! Open input data file + !=============================================================== + subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft_o, rc) + ! + ! Make PFT data + ! + ! This dataset consists of the %cover of the [numpft]+1 PFTs used by + ! the model. The input %cover pertains to the "vegetated" portion of the + ! grid cell and sums to 100. The real portion of each grid cell + ! covered by each PFT is the PFT cover times the fraction of the + ! grid cell that is land. This is the quantity preserved when + ! area-averaging from the input grid to the models grid. + ! + ! Upon return from this routine, the % cover of the natural veg + crop landunits is + ! generally 100% everywhere; this will be normalized later to account for special landunits. + ! + use mkpctPftTypeMod, only : pct_pft_type + use mkpftConstantsMod, only : natpft_lb, natpft_ub, num_cft, cft_lb, cft_ub + ! + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh + real(r8) , intent(inout) :: pctlnd_o(:) ! output grid:%land/gridcell + type(pct_pft_type), intent(inout) :: pctnatpft_o(:) ! natural PFT cover + type(pct_pft_type), intent(inout) :: pctcft_o(:) ! crop (CFT) cover + integer , intent(out) :: rc + ! + ! local variables: + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + integer :: dimid + integer :: ndims ! number of dimensions for a variable on the file + integer :: dimlens(3) ! dimension lengths for a variable on the file + integer :: ns_i, ns_o ! input/output bounds + integer :: ni,no ! indices + integer :: k,n,m ! indices + type(pct_pft_type), allocatable :: pctnatpft_i(:) ! input grid: natural PFT cover + type(pct_pft_type), allocatable :: pctcft_i(:) ! input grid: crop (CFT) cover + real(r8), allocatable :: pct_cft_i(:,:) ! input grid: CFT (Crop Functional Type) percent (% of landunit cell) + real(r8), allocatable :: pct_cft_o(:,:) ! output grid: CFT (Crop Functional Type) percent (% of landunit cell) + real(r8), allocatable :: pct_nat_pft_i(:,:) ! input grid: natural PFT percent (% of landunit cell) + real(r8), allocatable :: pct_nat_pft_o(:,:) ! output grid: natural PFT percent (% of landunit cell) + real(r8), allocatable :: output_pct_nat_pft_o(:,:) + real(r8), allocatable :: output_pct_cft_o(:,:) + integer , allocatable :: mask_i(:) + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + real(r8), allocatable :: pctnatveg_i(:) ! input grid: natural veg percent (% of grid cell) + real(r8), allocatable :: pctnatveg_o(:) ! output grid: natural veg percent (% of grid cell) + real(r8), allocatable :: pctcrop_i(:) ! input grid: all crop percent (% of grid cell) + real(r8), allocatable :: pctcrop_o(:) ! output grid: all crop percent (% of grid cell) + real(r8), allocatable :: pctpft_i(:,:) ! input grid: PFT percent (for error checks) + real(r8), allocatable :: pctpft_o(:,:) ! output grid: PFT percent (% of grid cell) + real(r8), allocatable :: temp_i(:,:) ! input grid: temporary 2D variable to read in + integer :: numpft_i ! num of plant types input data + integer :: natpft_i ! num of natural plant types input data + integer :: ncft_i ! num of crop types input data + real(r8) :: sum_fldo ! global sum of dummy output fld + real(r8) :: sum_fldi ! global sum of dummy input fld + real(r8) :: wst_sum ! sum of %pft + real(r8), allocatable :: gpft_o(:) ! output grid: global area pfts + real(r8) :: garea_o ! output grid: global area + real(r8), allocatable :: gpft_i(:) ! input grid: global area pfts + real(r8) :: garea_i ! input grid: global area + integer :: ier, rcode ! error status + real(r8) :: relerr = 0.0001_r8 ! max error: sum overlap wts ne 1 + logical :: error_happened ! If an error was triggered so should return + character(len=*), parameter :: subname = 'mkpf' + !----------------------------------------------------------------------- + + if (root_task) then + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make PFTs .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) + end if + + ! Open input pft file rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) @@ -383,14 +385,12 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! pres_cover is true if zero_out_l is true + ! Create Error checks if presc_cover is false if ( .not. presc_cover ) then - - ! get dimensions rcode = pio_inq_dimid(pioid, 'natpft', dimid) rcode = pio_inq_dimlen(pioid, dimid, natpft_i) rcode = pio_inq_dimid(pioid, 'cft', dimid) - rcode = pio_inq_dimlen(pioid, dimid, ncfg_i) + rcode = pio_inq_dimlen(pioid, dimid, ncft_i) numpft_i = natpft_i + ncft_i ! Check if the number of pfts on the input matches the expected number. A mismatch @@ -408,227 +408,196 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft call shr_sys_abort() end if endif + end if - ! Create a route handle between the input and output mesh and get frac_o + ! ---------------------------------------- + ! Create a route handle between the input and output mesh and get frac_o + ! ---------------------------------------- + if (.not. presc_cover) then allocate(frac_o(ns_o),stat=ier) if (ier/=0) call shr_sys_abort() call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + end if - ! Allocate memory - allocate(pctnatveg_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(pctnatveg_o(ns_o), stat=ier) - if (ier/=0) call shr_sys_abort() - - allocate(pctcrop_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(pctcrop_o(ns_o), stat=ier) - if (ier/=0) call shr_sys_abort() - - allocate(pct_cft_i(ns_i,1:num_cft), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(pct_cft_o(ns_o,1:num_cft), stat=ier) - if (ier/=0) call shr_sys_abort() - - allocate(pct_nat_pft_i(ns_i,0:num_natpft), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(pct_nat_pft_o(ns_o,0:num_natpft), stat=ier) - if (ier/=0) call shr_sys_abort() - - ! Read in 1d data - call mkpio_get_rawdata(pioid, 'PCT_NATVEG', mesh_i, pctnatveg_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call mkpio_get_rawdata(pioid, 'PCT_CROP', mesh_i, pctcrop_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Read in 2d data - if ( .not. use_input_pft )then - allocate(data_cft_i(1:numcft, ns_i) - if (ier/=0) call shr_sys_abort() - - call mkpio_get_dimlengths(pioid, 'PCT_CFT', ndims, dimlens(:)) - if (ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) == num_cft )then - call mkpio_get_rawdata(pioid, 'PCT_CFT', mesh_i, data_cft_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else if ( ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) > num_cft )then - ! Read in the whole array: then sum the rainfed and irrigated seperately - allocate(temp_i(dimlens(3),ns_i)) - call mkpio_get_rawdata(pioid, 'PCT_CFT', mesh_i, temp_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1, num_cft - data_cft_i(n,:) = 0.0_r8 - do m = n, dimlens(3), 2 - data_cft_i(n,:) = data_cft_i(n,:) + temp_i(m,:) - end do - end do - deallocate( temp_i ) - else - call shr_sys_abort(subname//' error: dimensions for PCT_CROP are NOT what is expected') - end if - - allocate(data_nat_pft_i(0:num_natpft,ns_i) - if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'PCT_NAT_PFT', mesh_i, data_nat_pft_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - + ! ---------------------------------------- + ! Determine pctlnd_o(:) (output argument) + ! ---------------------------------------- + if ( use_input_pft .and. presc_cover ) then + pctlnd_o(:) = 100._r8 else - - ns_i = 1 - numpft_i = numpft+1 - allocate(pctnatveg_i(ns_i), & - pctnatveg_o(ns_o), & - pctcrop_i(ns_i), & - pctcrop_o(ns_o), & - pct_cft_i(ns_i,1:num_cft), & - pct_cft_o(ns_o,1:num_cft), & - pct_nat_pft_i(ns_i,0:num_natpft), & - pct_nat_pft_o(ns_o,0:num_natpft), & - stat=ier) - if (ier/=0) call shr_sys_abort() - + pctlnd_o(:) = frac_o(:) * 100._r8 end if - allocate(pctpft_i(ns_i,0:(numpft_i-1)), & - pctpft_o(ns_o,0:(numpft_i-1)), & - pctnatpft_i(ns_i), & - pctcft_i(ns_i), & - stat=ier) - if (ier/=0) call shr_sys_abort() - - ! Determine pctpft_o on output grid - ! If total vegetation cover is prescribed from input... + ! DEBUG + RETURN + !DEBUG + ! ---------------------------------------- + ! Determine pctnatveg_o(:) + ! ---------------------------------------- if ( use_input_pft .and. presc_cover ) then - do no = 1,ns_o - pctlnd_o(no) = 100._r8 pctnatveg_o(no) = pft_override%natveg - pctcrop_o(no) = pft_override%crop end do - - ! ---------------------------------------- - ! otherewise if total cover isn't prescribed read it from the datasets - ! ---------------------------------------- else - - ! Compute pctlnd_o, pctpft_o + allocate(pctnatveg_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'PCT_NATVEG', mesh_i, pctnatveg_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return call regrid_rawdata(mesh_i, mesh_o, routehandle, pctnatveg_i, pctnatveg_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + ! ---------------------------------------- + ! Determine pctcrop_o(:) + ! ---------------------------------------- + if ( use_input_pft .and. presc_cover ) then + do no = 1,ns_o + pctcrop_o(no) = pft_override%crop + end do + else + allocate(pctcrop_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'PCT_CROP', mesh_i, pctcrop_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return call regrid_rawdata(mesh_i, mesh_o, routehandle, pctcrop_i, pctcrop_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if - ! Area-average percent cover on input grid [pctpft_i] to output grid - ! [pctpft_o] and correct [pctpft_o] according to land landmask - ! Note that percent cover is in terms of total grid area. - pctlnd_o(:) = frac_o(:) * 100._r8 - - - ! ---------------------------------------- - ! If specific PFT/CFT's are NOT prescribed set them from the input file - ! ---------------------------------------- - if ( .not. use_input_pft )then + ! ---------------------------------------- + ! Determine pct_nat_pft_o(:,:) + ! ---------------------------------------- + if ( .not. use_input_pft )then + allocate(pct_nat_pft_i(0:num_natpft,ns_i)) + if (ier/=0) call shr_sys_abort() + allocate(pct_nat_pft_o(0:num_natpft,ns_o)) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'PCT_NAT_PFT', mesh_i, pct_nat_pft_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do m = 0,num_natpft + do ni = 1,ns_i + pct_nat_pft_i(m,ni) = pct_nat_pft_i(m,ni) * pctnatveg_i(ni) * 0.01_r8 * mask_i(ni) + end do + end do + call regrid_rawdata(mesh_i, mesh_o, routehandle, pct_nat_pft_i, pct_nat_pft_o, 0, num_natpft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do m = 0,num_natpft + do no = 1,ns_o + pct_nat_pft_o(m,no) = pct_nat_pft_o(m,no) / pctnatveg_o(no) * 0.01_r8 + if (pctlnd_o(no) < 1.0e-6 .or. pctnatveg_o(no) < 1.0e-6) then + if (m == 0) then + pct_nat_pft_o(m,no) = 100._r8 + else + pct_nat_pft_o(m,no) = 0._r8 + endif + end if + end do + end do + end if - ! TODO: allocate data_pct_nat_pft_i and data_pct_nat_pft_o + ! ---------------------------------------- + ! Determine pct_cft_o(:,:) + ! ---------------------------------------- + allocate(pct_cft_i(1:num_cft,ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(pct_cft_o(1:num_cft,ns_o), stat=ier) + if (ier/=0) call shr_sys_abort() - do m = 0,num_natpft - do ni = 1,ns_i - data_pct_nat_pft_i(m,ni) = pct_nat_pft_i(ni,m) * pctnatveg_i(ni) * 0.01_r8 * mask_i(ni) - end do - end do - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_pct_nat_pft_i, data_pct_nat_pft_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - do m = 0,num_natpft - do no = 1,ns_o - pct_nat_pft_o(no,m) = data_pct_nat_pft_o(no,m) / pctnatveg_o(no) * 0.01_r8 - if (pctlnd_o(no) < 1.0e-6 .or. pctnatveg_o(no) < 1.0e-6) then - if (m == 0) then - pct_nat_pft_o(no,m) = 100._r8 - else - pct_nat_pft_o(no,m) = 0._r8 - endif - end if + if ( .not. use_input_pft )then + call mkpio_get_dimlengths(pioid, 'PCT_CFT', ndims, dimlens(:)) + if (ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) == num_cft )then + call mkpio_get_rawdata(pioid, 'PCT_CFT', mesh_i, pct_cft_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else if ( ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) > num_cft )then + ! Read in the whole array: then sum the rainfed and irrigated seperately + allocate(temp_i(dimlens(3),ns_i)) + call mkpio_get_rawdata(pioid, 'PCT_CFT', mesh_i, temp_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1, num_cft + pct_cft_i(n,:) = 0.0_r8 + do m = n, dimlens(3), 2 + pct_cft_i(n,:) = pct_cft_i(n,:) + temp_i(m,:) end do end do + deallocate(temp_i) + else + call shr_sys_abort(subname//' error: dimensions for PCT_CROP are NOT what is expected') + end if - do m = 1, num_cft - - call gridmap_areaave_scs(tgridmap, pct_cft_i(:,m), pct_cft_o(:,m), & - nodata=0._r8, src_wt=pctcrop_i*0.01_r8*tdomain%mask, & - dst_wt=pctcrop_o*0.01_r8, frac_dst=frac_dst) - - do no = 1,ns_o - if (pctlnd_o(no) < 1.0e-6 .or. pctcrop_o(no) < 1.0e-6) then - if (m == 1) then - pct_cft_o(no,m) = 100._r8 - else - pct_cft_o(no,m) = 0._r8 - endif - end if - enddo + do m = 0,num_cft + do ni = 1,ns_i + pct_cft_i(m,ni) = pct_cft_i(m,ni) * pctcrop_i(ni) * 0.01_r8 * mask_i(ni) end do + end do + call regrid_rawdata(mesh_i, mesh_o, routehandle, pct_cft_i, pct_cft_o, 1, num_cft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do no = 1,ns_o + pct_cft_o(m,no) = pct_cft_o(m,no) / pctcrop_o(no) * 0.01_r8 + if (pctlnd_o(no) < 1.0e-6 .or. pctcrop_o(no) < 1.0e-6) then + if (m == 1) then + pct_cft_o(no,m) = 100._r8 + else + pct_cft_o(no,m) = 0._r8 + endif + end if + enddo + end if - ! ---------------------------------------- - ! Otherwise do some error checking to make sure specific veg - ! types are given where nat-veg and crop is assigned - ! ---------------------------------------- - else - do no = 1,ns_o - if (pctlnd_o(no) > 1.0e-6 .and. pctnatveg_o(no) > 1.0e-6) then - if ( pft_override%natveg <= 0.0_r8 )then - write(6,*) subname//': ERROR: no natural vegetation PFTs are being prescribed but there are natural '// & - 'vegetation areas: provide at least one natural veg PFT' - call shr_sys_abort() - end if + ! ---------------------------------------- + ! If specific PFT/CFT's are prescribed set them directly + ! But first do error checking to make sure specific veg + ! types are given where nat-veg and crop is assigned + ! ---------------------------------------- + if (use_input_pft) then + do no = 1,ns_o + if (pctlnd_o(no) > 1.0e-6 .and. pctnatveg_o(no) > 1.0e-6) then + if ( pft_override%natveg <= 0.0_r8 )then + write(6,*) subname//': ERROR: no natural vegetation PFTs are being prescribed '//& + ' but there are natural vegetation areas: provide at least one natural veg PFT' + call shr_sys_abort() end if - if (pctlnd_o(no) > 1.0e-6 .and. pctcrop_o(no) > 1.0e-6) then - if ( pft_override%crop <= 0.0_r8 )then - write(6,*) subname//': ERROR: no crop CFTs are being prescribed '& - //' but there are crop areas: provide at least one CFT' - call shr_sys_abort() - end if + end if + if (pctlnd_o(no) > 1.0e-6 .and. pctcrop_o(no) > 1.0e-6) then + if ( pft_override%crop <= 0.0_r8 )then + write(6,*) subname//': ERROR: no crop CFTs are being prescribed '& + //' but there are crop areas: provide at least one CFT' + call shr_sys_abort() end if - end do - end if - end if + end if + end do - ! - ! If specific PFT/CFT's are prescribed set them directly - ! - if ( use_input_pft )then do no = 1,ns_o if (pctlnd_o(no) > 1.0e-6 .and. pctnatveg_o(no) > 1.0e-6) then - pct_nat_pft_o(no,noveg:num_natpft) = pft_override%natpft(noveg:num_natpft) + pct_nat_pft_o(noveg:num_natpft,no) = pft_override%natpft(noveg:num_natpft) else - pct_nat_pft_o(no,noveg) = 100._r8 - pct_nat_pft_o(no,noveg+1:) = 0._r8 + pct_nat_pft_o(noveg,no) = 100._r8 + pct_nat_pft_o(noveg+1:,no) = 0._r8 end if if (pctlnd_o(no) > 1.0e-6 .and. pctcrop_o(no) > 1.0e-6) then - pct_cft_o(no,1:num_cft) = pft_override%cft(1:num_cft) + pct_cft_o(1:num_cft,no) = pft_override%cft(1:num_cft) else - pct_cft_o(no,1) = 100._r8 - pct_cft_o(no,2:) = 0._r8 + pct_cft_o(1,no) = 100._r8 + pct_cft_o(2:,no) = 0._r8 end if - pctpft_o(no,natpft_lb:natpft_ub) = pct_nat_pft_o(no,0:num_natpft) - pctpft_o(no,cft_lb:cft_ub) = pct_cft_o(no,1:num_cft) + pctpft_o(natpft_lb:natpft_ub,no) = pct_nat_pft_o(0:num_natpft,no) + pctpft_o(cft_lb:cft_ub,no) = pct_cft_o(1:num_cft,no) end do end if - - ! Error check: percents should sum to 100 for land grid cells, within roundoff - ! Also correct sums so that if they differ slightly from 100, they are corrected to - ! equal 100 more exactly. - + ! ---------------------------------------- + ! Correct sums so that if they differ slightly from 100, they are + ! corrected to equal 100 more exactly. + ! ---------------------------------------- do no = 1,ns_o wst_sum = 0. do m = 0, num_natpft - wst_sum = wst_sum + pct_nat_pft_o(no,m) + wst_sum = wst_sum + pct_nat_pft_o(m,no) enddo + ! Error check: percents should sum to 100 for land grid cells, within roundoff if (abs(wst_sum-100._r8) > relerr) then - write (6,*) subname//'error: nat pft = ', & - (pct_nat_pft_o(no,m), m = 0, num_natpft), & + write (6,*) subname//'error: nat pft = ', (pct_nat_pft_o(m,no), m = 0, num_natpft), & ' do not sum to 100. at no = ',no,' but to ', wst_sum call shr_sys_abort() end if @@ -636,16 +605,16 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! Correct sum so that if it differs slightly from 100, it is corrected to equal ! 100 more exactly do m = 1, num_natpft - pct_nat_pft_o(no,m) = pct_nat_pft_o(no,m) * 100._r8 / wst_sum + pct_nat_pft_o(m,no) = pct_nat_pft_o(m,no) * 100._r8 / wst_sum end do wst_sum = 0. do m = 1, num_cft - wst_sum = wst_sum + pct_cft_o(no,m) + wst_sum = wst_sum + pct_cft_o(m,no) enddo + ! Error check: percents should sum to 100 for land grid cells, within roundoff if (abs(wst_sum-100._r8) > relerr) then - write (6,*) subname//'error: crop cft = ', & - (pct_cft_o(no,m), m = 1, num_cft), & + write (6,*) subname//'error: crop cft = ',(pct_cft_o(no,m), m = 1, num_cft), & ' do not sum to 100. at no = ',no,' but to ', wst_sum call shr_sys_abort() end if @@ -653,16 +622,19 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! Correct sum so that if it differs slightly from 100, it is corrected to equal ! 100 more exactly do m = 1, num_cft - pct_cft_o(no,m) = pct_cft_o(no,m) * 100._r8 / wst_sum + pct_cft_o(m,no) = pct_cft_o(m,no) * 100._r8 / wst_sum end do - end do - ! Convert % pft as % of grid cell to % pft on the landunit and % of landunit on the - ! grid cell + ! ---------------------------------------- + ! Convert % pft as % of grid cell to % pft on the landunit and % of landunit on the grid cell + ! ---------------------------------------- do no = 1,ns_o - pctnatpft_o(no) = pct_pft_type( pct_nat_pft_o(no,:), pctnatveg_o(no), first_pft_index=natpft_lb ) - pctcft_o(no) = pct_pft_type( pct_cft_o(no,:), pctcrop_o(no), first_pft_index=cft_lb ) + output_pct_nat_pft_o(no,:) = pct_nat_pft_o(:,no) + pctnatpft_o(no) = pct_pft_type( output_pct_nat_pft_o(no,:), pctnatveg_o(no), first_pft_index=natpft_lb ) + + output_pct_cft_o(no,:) = pct_cft_o(:,no) + pctcft_o(no) = pct_pft_type( output_pct_cft_o(no,:), pctcrop_o(no), first_pft_index=cft_lb ) end do ! ----------------------------------------------------------------- @@ -674,92 +646,90 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! datasets. ! ----------------------------------------------------------------- - if ( .not. presc_cover ) then - - ! Convert to pctpft over grid if using new format - do ni = 1, ns_i - pctnatpft_i(ni) = pct_pft_type( pct_nat_pft_i(ni,:), pctnatveg_i(ni), first_pft_index=natpft_lb ) - pctcft_i(ni) = pct_pft_type( pct_cft_i(ni,:), pctcrop_i(ni), first_pft_index=cft_lb ) - end do - - do no = 1,ns_o - pctpft_o(no,natpft_lb:natpft_ub) = pctnatpft_o(no)%get_pct_p2g() - pctpft_o(no,cft_lb:cft_ub) = pctcft_o(no)%get_pct_p2g() - end do - allocate(gpft_i(0:numpft_i-1)) - allocate(gpft_o(0:numpft_i-1)) - - ! input grid - - gpft_i(:) = 0. - garea_i = 0. - do ni = 1,ns_i - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - do m = 0, numpft_i - 1 - gpft_i(m) = gpft_i(m) + pctpft_i(ni,m)*tgridmap%area_src(ni)*& - tdomain%mask(ni)*re**2 - end do - end do - if ( allocated(pctpft_i) ) deallocate (pctpft_i) - - ! output grid - - gpft_o(:) = 0. - garea_o = 0. - do no = 1,ns_o - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - do m = 0, numpft_i - 1 - gpft_o(m) = gpft_o(m) + pctpft_o(no,m)*tgridmap%area_dst(no)*& - frac_dst(no)*re**2 - end do - end do - - ! comparison - + ! if (presc_cover) then + ! ns_i = 1 + ! numpft_i = numpft+1 + ! end if + + ! if ( .not. presc_cover ) then + ! ! Derived types + ! allocate(pctnatpft_i(ns_i), stat=ier) + ! if (ier/=0) call shr_sys_abort() + ! allocate(pctcft_i(ns_i), stat=ier) + ! if (ier/=0) call shr_sys_abort() + + ! do ni = 1, ns_i + ! pctnatpft_i(ni) = pct_pft_type( pct_nat_pft_i(ni,:), pctnatveg_i(ni), first_pft_index=natpft_lb ) + ! pctcft_i(ni) = pct_pft_type( pct_cft_i(ni,:), pctcrop_i(ni), first_pft_index=cft_lb ) + ! end do + + ! do no = 1,ns_o + ! pctpft_o(no,natpft_lb:natpft_ub) = pctnatpft_o(no)%get_pct_p2g() + ! pctpft_o(no,cft_lb:cft_ub) = pctcft_o(no)%get_pct_p2g() + ! end do + + ! allocate(gpft_i(0:numpft_i-1)) + ! allocate(gpft_o(0:numpft_i-1)) + + ! ! input grid + ! allocate(pctpft_i(ns_i,0:(numpft_i-1)), stat=ier) + ! if (ier/=0) call shr_sys_abort() + ! allocate(pctpft_o(ns_o,0:(numpft_i-1)), stat=ier) + ! if (ier/=0) call shr_sys_abort() + + ! gpft_i(:) = 0. + ! garea_i = 0. + ! do ni = 1,ns_i + ! garea_i = garea_i + area_src(ni)*re**2 + ! do m = 0, numpft_i - 1 + ! gpft_i(m) = gpft_i(m) + pctpft_i(ni,m) * area_src(ni) * mask(ni)*re**2 + ! end do + ! end do + ! if ( allocated(pctpft_i) ) deallocate (pctpft_i) + + ! ! output grid + ! gpft_o(:) = 0. + ! garea_o = 0. + ! do no = 1,ns_o + ! garea_o = garea_o + area_dst(no)*re**2 + ! do m = 0, numpft_i - 1 + ! gpft_o(m) = gpft_o(m) + pctpft_o(no,m)*area_dst(no)*frac_o(no)*re**2 + ! end do + ! end do + + ! ! comparison + ! write (ndiag,*) + ! write (ndiag,'(1x,70a1)') ('=',k=1,70) + ! write (ndiag,*) 'PFTs Output' + ! write (ndiag,'(1x,70a1)') ('=',k=1,70) + + ! write (ndiag,*) + ! write (ndiag,'(1x,70a1)') ('.',k=1,70) + ! write (ndiag,1001) + ! 1001 format (1x,'plant type ',20x,' input grid area',' output grid area',/ & + ! 1x,33x,' 10**6 km**2',' 10**6 km**2') + ! write (ndiag,'(1x,70a1)') ('.',k=1,70) + ! write (ndiag,*) + ! do m = 0, numpft_i - 1 + ! write (ndiag,1002) veg(m), gpft_i(m)*1.e-06/100.,gpft_o(m)*1.e-06/100. + ! end do + ! 1002 format (1x,a35,f16.3,f17.3) + + ! deallocate(gpft_i, gpft_o, frac_dst) + + ! end if + + ! Clean up memory + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + if (root_task) then + write (ndiag,'(a)') 'Successfully made PFTs' write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'PFTs Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,1001) -1001 format (1x,'plant type ',20x,' input grid area',' output grid area',/ & - 1x,33x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - do m = 0, numpft_i - 1 - write (ndiag,1002) veg(m), gpft_i(m)*1.e-06/100.,gpft_o(m)*1.e-06/100. - end do -1002 format (1x,a35,f16.3,f17.3) - - deallocate(gpft_i, gpft_o, frac_dst) - - end if - deallocate( pctnatpft_i ) - deallocate( pctcft_i ) - deallocate(pctpft_o) - - - ! Deallocate dynamic memory - - deallocate(pctnatveg_i) - deallocate(pctnatveg_o) - deallocate(pctcrop_i) - deallocate(pctcrop_o) - deallocate(pct_cft_i) - deallocate(pct_cft_o) - deallocate(pct_nat_pft_i) - deallocate(pct_nat_pft_o) - if ( .not. presc_cover ) then - call domain_clean(tdomain) - call gridmap_clean(tgridmap) end if - write (6,*) 'Successfully made PFTs' - write (6,*) - - end subroutine mkpft !----------------------------------------------------------------------- @@ -827,7 +797,7 @@ subroutine mkpft_check_oride( error_happened ) integer :: i, j ! indices real(r8) :: sumpft ! Sum of pft_frc real(r8), parameter :: hndrd = 100.0_r8 ! A hundred percent - character(len=32) :: subname = 'mkpftMod::mkpft_check_oride() ' + character(len=*), parameter :: subname = 'mkpftMod::mkpft_check_oride() ' !----------------------------------------------------------------------- error_happened = .false. @@ -888,174 +858,14 @@ subroutine mkpft_check_oride( error_happened ) end subroutine mkpft_check_oride - !----------------------------------------------------------------------- - subroutine mkpftAtt( ncid, dynlanduse, xtype ) - - ! make PFT attributes on the output file - - use mkutilsMod , only : get_filename - use mkvarctl , only : mksrf_fvegtyp, mksrf_flai - use mkvarpar - - ! !ARGUMENTS: - integer, intent(in) :: ncid ! NetCDF file ID to write out to - logical, intent(in) :: dynlanduse ! if dynamic land-use file - integer, intent(in) :: xtype ! external type to output real data as - - ! !LOCAL VARIABLES: - integer :: pftsize ! size of lsmpft dimension - integer :: natpftsize ! size of natpft dimension - integer :: dimid ! input netCDF id's - character(len=256) :: str ! global attribute string - character(len=32) :: subname = 'mkpftAtt' - - ! Define dimensions - call check_ret(nf_def_dim (ncid, 'time' , nf_unlimited, dimid), subname) - - if (.not. dynlanduse) then - pftsize = numpft + 1 - call check_ret(nf_def_dim (ncid, 'lsmpft' , pftsize , dimid), subname) - end if - - natpftsize = num_natpft + 1 - call check_ret(nf_def_dim (ncid, 'natpft' , natpftsize , dimid), subname) - - ! zero-size dimensions can cause problems, so we only include the cft dimension if num_cft > 0 - ! Note that this implies that we can only include PCT_CFT on the dataset if num_cft > 0 - if (num_cft > 0) then - call check_ret(nf_def_dim (ncid, 'cft' , num_cft , dimid), subname) - end if - - ! Add global attributes - - if (.not. dynlanduse) then - str = get_filename(mksrf_flai) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Lai_raw_data_file_name', len_trim(str), trim(str)), subname) - end if - - if ( use_input_pft ) then - str = 'TRUE' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'pft_override', len_trim(str), trim(str)), subname) - else - str = get_filename(mksrf_fvegtyp) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Vegetation_type_raw_data_filename', len_trim(str), trim(str)), subname) - end if - - ! Define variables - - ! Coordinate variable for indices of natural PFTs - call ncd_defvar(ncid=ncid, varname='natpft', xtype=nf_int, & - dim1name='natpft', long_name='indices of natural PFTs', units='index') - - ! Coordinate variable for indices of CFTs - if (num_cft > 0) then - call ncd_defvar(ncid=ncid, varname='cft', xtype=nf_int, & - dim1name='cft', long_name='indices of CFTs', units='index') - end if - - call ncd_def_spatial_var(ncid=ncid, varname='LANDFRAC_PFT', xtype=nf_double, & - long_name='land fraction from pft dataset', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PFTDATA_MASK', xtype=nf_int, & - long_name='land mask from pft dataset, indicative of real/fake points', units='unitless') - - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='PCT_NATVEG', xtype=xtype, & - long_name='total percent natural vegetation landunit', units='unitless') - end if - - ! PCT_CROP - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CROP', xtype=xtype, & - long_name='total percent crop landunit', units='unitless') - else - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CROP', xtype=xtype, & - lev1name='time', & - long_name='total percent crop landunit', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CROP_MAX', xtype=xtype, & - long_name='maximum total percent crop landunit during time period', units='unitless') - end if - - ! PCT_NAT_PFT - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='PCT_NAT_PFT', xtype=xtype, & - lev1name='natpft', & - long_name='percent plant functional type on the natural veg landunit (% of landunit)', units='unitless') - else - call ncd_def_spatial_var(ncid=ncid, varname='PCT_NAT_PFT', xtype=xtype, & - lev1name='natpft', lev2name='time', & - long_name='percent plant functional type on the natural veg landunit (% of landunit)', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='PCT_NAT_PFT_MAX', xtype=xtype, & - lev1name='natpft', & - long_name='maximum percent plant functional type during time period (% of landunit)', units='unitless') - end if - - ! PCT_CFT - if (num_cft > 0) then - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CFT', xtype=xtype, & - lev1name='cft', & - long_name='percent crop functional type on the crop landunit (% of landunit)', units='unitless') - else - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CFT', xtype=xtype, & - lev1name='cft', lev2name='time', & - long_name='percent crop functional type on the crop landunit (% of landunit)', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CFT_MAX', xtype=xtype, & - lev1name='cft', & - long_name='maximum percent crop functional type during time period (% of landunit)', units='unitless') - end if - end if - - ! LAI,SAI,HTOP,HBOT - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_LAI', xtype=xtype, & - lev1name='lsmpft', lev2name='time', & - long_name='monthly leaf area index', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_SAI', xtype=xtype, & - lev1name='lsmpft', lev2name='time', & - long_name='monthly stem area index', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_HEIGHT_TOP', xtype=xtype, & - lev1name='lsmpft', lev2name='time', & - long_name='monthly height top', units='meters') - - call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_HEIGHT_BOT', xtype=xtype, & - lev1name='lsmpft', lev2name='time', & - long_name='monthly height bottom', units='meters') - end if - - ! OTHER - if (dynlanduse) then - call ncd_defvar(ncid=ncid, varname='YEAR', xtype=nf_int, & - dim1name='time', & - long_name='Year of PFT data', units='unitless') - call ncd_defvar(ncid=ncid, varname='time', xtype=nf_int, & - dim1name='time', & - long_name='year', units='unitless') - call ncd_defvar(ncid=ncid, varname='input_pftdata_filename', xtype=nf_char, & - dim1name='nchar', & - dim2name='time', & - long_name='Input filepath for PFT values for this year', units='unitless') - else - call ncd_defvar(ncid=ncid, varname='time', xtype=nf_int, & - dim1name='time', & - long_name='Calendar month', units='month') - end if - - end subroutine mkpftAtt - !----------------------------------------------------------------------- function constructor( ) result(this) ! ! Construct a new PFT override object ! - ! !ARGUMENTS: + ! input/output variables type(pft_oride) :: this - character(len=32) :: subname = 'mkpftMod::constructor() ' + character(len=*), parameter :: subname = 'mkpftMod::constructor() ' this%crop = -1.0_r8 this%natveg = -1.0_r8 @@ -1082,7 +892,7 @@ subroutine InitZeroOut( this ) ! ! Initialize a pft_oride object with vegetation that's zeroed out ! - ! !ARGUMENTS: + ! input/output variables class(pft_oride), intent(inout) :: this this%crop = 0.0_r8 @@ -1100,13 +910,14 @@ subroutine InitAllPFTIndex( this ) ! ! Initialize a pft_oride object with vegetation that's zeroed out ! - ! !ARGUMENTS: + ! input/otuput variables class(pft_oride), intent(inout) :: this + ! local variables integer :: m, i ! Indices real(r8) :: croptot ! Total of crop real(r8) :: natvegtot ! Total of natural vegetation - character(len=32) :: subname = 'mkpftMod::coInitAllPFTIndex() ' + character(len=*), parameter :: subname = 'mkpftMod::coInitAllPFTIndex() ' croptot = 0.0_r8 natvegtot = 0.0_r8 diff --git a/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 b/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 index 9c009a3d8e..ff7f228a86 100644 --- a/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 @@ -1,35 +1,20 @@ module mkpftUtilsMod !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mkpftUtils - ! - ! !DESCRIPTION: ! Lower-level utilities used in making PFT data. ! ! These are separated out from mkpftMod mainly as an aid to testing. - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! !----------------------------------------------------------------------- - !!USES: + use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_abort implicit none private - ! - ! !PUBLIC MEMBER FUNCTIONS: - ! public :: convert_from_p2g ! Convert a p2g array into pct_pft_type objects public :: adjust_total_veg_area ! Adjust the total vegetated area (natural veg & crop) to a new specified total - ! - ! !PRIVATE MEMBER FUNCTIONS: - ! - private :: get_default_natpft ! Get the default natural pft breakdown, for a 0-area natural veg. landunit private :: get_default_cft ! Get the default cft breakdown, for a 0-area crop landunit @@ -38,10 +23,9 @@ module mkpftUtilsMod module procedure convert_from_p2g_missing_crops end interface convert_from_p2g - !EOP - !=============================================================== +!=============================================================== contains - !=============================================================== +!=============================================================== !----------------------------------------------------------------------- subroutine convert_from_p2g_default(pct_p2g, pctnatpft, pctcft) @@ -251,7 +235,6 @@ subroutine adjust_total_veg_area(new_total_pct, pctnatpft, pctcft) end subroutine adjust_total_veg_area - end module mkpftUtilsMod diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index bfe5051ec9..61a22525cb 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -93,15 +93,14 @@ program mksurfdata use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs use shr_sys_mod , only : shr_sys_abort #ifdef TODO - use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array - use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride - use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft use mkharvestMod , only : mkharvest, mkharvest_init, mkharvest_fieldname - use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride - use mkharvestMod , only : harvestDataType + use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride, harvestDataType use mktopostatsMod , only : mktopostats use mkVICparamsMod , only : mkVICparams #endif + use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride + use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array + use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft use mkdomainMod , only : mkdomain use mkgdpMod , only : mkgdp use mkagfirepkmonthMod , only : mkagfirepkmon @@ -156,12 +155,10 @@ program mksurfdata real(r8), allocatable :: pctlnd_pft(:) ! PFT data: % of gridcell for PFTs real(r8), allocatable :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs integer , allocatable :: pftdata_mask(:) ! mask indicating real or fake land type -#ifdef TODO type(pct_pft_type), allocatable :: pctnatpft(:) ! % of grid cell that is nat veg, and breakdown into PFTs type(pct_pft_type), allocatable :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series type(pct_pft_type), allocatable :: pctcft(:) ! % of grid cell that is crop, and breakdown into CFTs type(pct_pft_type), allocatable :: pctcft_max(:) ! % of grid cell maximum CFTs of the time series -#endif real(r8) :: harvest_initval ! initial value for harvest variables real(r8), allocatable :: harvest1D(:) ! harvest 1D data: normalized harvesting real(r8), allocatable :: harvest2D(:,:) ! harvest 1D data: normalized harvesting @@ -309,19 +306,6 @@ program mksurfdata call check_namelist_input() call write_namelist_input() - ! ---------------------------------------------------------------------- - ! Call module initialization routines - ! ---------------------------------------------------------------------- - -#ifdef TODO - ! zero_out_l => If veg should be zero'ed out - ! all_veg_l => If should zero out other fractions so that all land-cover is vegetation - call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) -#endif - allocate ( elevclass(nglcec+1) ) - call mkglcmecInit (elevclass) - call mkurbanInit (mksrf_furban) - ! ---------------------------------------------------------------------- ! Read in model mesh ! ---------------------------------------------------------------------- @@ -335,33 +319,47 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() ! ---------------------------------------------------------------------- - ! Allocate and initialize dynamic memory for local variables + ! Read in and interpolate surface data set fields ! ---------------------------------------------------------------------- - allocate ( topo_stddev(lsize_o)) ; topo_stddev(:) = spval - allocate ( slope(lsize_o)) ; slope(:) = spval - allocate ( vic_binfl(lsize_o)) ; vic_binfl(:) = spval - allocate ( vic_ws(lsize_o)) ; vic_ws(:) = spval - allocate ( vic_dsmax(lsize_o)) ; vic_dsmax(:) = spval - allocate ( vic_ds(lsize_o)) ; vic_ds(:) = spval + ! Call module initialization routines + allocate ( elevclass(nglcec+1) ) + call mkglcmecInit (elevclass) + call mkurbanInit (mksrf_furban) - ! ---------------------------------------------------------------------- - ! Read in and interpolate surface data set fields - ! ---------------------------------------------------------------------- + ! Make lats/lons of model + allocate (lon(lsize_o)) ; lon(:) = spval + allocate (lat(lsize_o)) ; lat(:) = spval + call mkdomain(mesh_model, lon_o=lon, lat_o=lat, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] ! Determine fractional land from pft dataset - allocate ( landfrac_pft(lsize_o)) ; landfrac_pft(:) = spval - allocate ( pctlnd_pft(lsize_o)) ; pctlnd_pft(:) = spval - allocate ( pftdata_mask(lsize_o)) ; pftdata_mask(:) = -999 - ! allocate ( pctnatpft(lsize_o)) ; - ! allocate ( pctnatpft_max(lsize_o)) ; - ! allocate ( pctcft(lsize_o)) ; - ! allocate ( pctcft_max(lsize_o)) ; - ! call mkpft( mapfname=map_fpft, fpft=mksrf_fvegtyp, ndiag=ndiag, & - ! pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft) - ! landfrac_pft(:) = pctlnd_pft(:)/100._r8 - ! end do + allocate ( landfrac_pft(lsize_o)) ; landfrac_pft(:) = spval + allocate ( pctlnd_pft(lsize_o)) ; pctlnd_pft(:) = spval + allocate ( pftdata_mask(lsize_o)) ; pftdata_mask(:) = -999 + allocate ( pctnatpft(lsize_o)) ; + allocate ( pctnatpft_max(lsize_o)) ; + allocate ( pctcft(lsize_o)) ; + allocate ( pctcft_max(lsize_o)) ; + call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) + call mkpft( mksrf_fvegtyp_mesh, mksrf_fvegtyp, mesh_model, & + pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') + + ! Set landfrac_pft and pftdata_mask + do n = 1,lsize_o + landfrac_pft(n) = pctlnd_pft(n)/100._r8 + if (pctlnd_pft(n) < 1.e-6_r8) then + pftdata_mask(n) = 0 + else + pftdata_mask(n) = 1 + end if + if (pctlnd_pft(n) < 1.e-6_r8) then + !call pctnatpft(n)%set_pct_l2g(0._r8) + !call pctcft(n)%set_pct_l2g(0._r8) + end if + end do ! Create harvesting data at model resolution ! if (all_veg) then @@ -376,26 +374,16 @@ program mksurfdata ! call mkharvest( mapfname=map_fharvest, datfname=mksrf_fhrvtyp, ndiag=ndiag, harvdata=harvdata ) ! end if - ! Make lats/lons of model - allocate (lon(lsize_o)) ; lon(:) = spval - allocate (lat(lsize_o)) ; lat(:) = spval - call mkdomain(mesh_model, lon_o=lon, lat_o=lat, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') - - ! Make GDP data [gdp] from [gdp] - allocate ( gdp(lsize_o)); gdp(:) = spval - call mkgdp (mksrf_fgdp_mesh, mksrf_fgdp, mesh_model, gdp_o=gdp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') - - ! Make agricultural fire peak month data [abm] from [abm] - allocate (agfirepkmon(lsize_o)); agfirepkmon(:) = -999 - call mkagfirepkmon (mksrf_fabm_mesh, mksrf_fabm, mesh_model, agfirepkmon_o=agfirepkmon, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkagfirepkmon') - - ! Make peat data [fpeat] from [peatf] - allocate (fpeat(lsize_o)) ; fpeat(:) = spval - call mkpeat (mksrf_fpeat_mesh, mksrf_fpeat, mesh_model, peat_o=fpeat, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpeat') + ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] + allocate ( pctlak(lsize_o)) ; pctlak(:) = spval + allocate ( pctwet(lsize_o)) ; pctwet(:) = spval + allocate ( lakedepth(lsize_o)) ; lakedepth(:) = spval + zero_out_lake = (all_urban .or. all_veg) + zero_out_wetland = (all_urban .or. all_veg .or. no_inlandwet) + call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & + zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') + call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) ! Make glacier fraction [pctgla] from [fglacier] dataset allocate (pctgla(lsize_o)) ; pctgla(:) = spval @@ -411,24 +399,67 @@ program mksurfdata end if end if - ! Make VOC emission factors for isoprene [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] - allocate (ef1_btr(lsize_o)) ; ef1_btr(:) = 0._r8 - allocate (ef1_fet(lsize_o)) ; ef1_fet(:) = 0._r8 - allocate (ef1_fdt(lsize_o)) ; ef1_fdt(:) = 0._r8 - allocate (ef1_shr(lsize_o)) ; ef1_shr(:) = 0._r8 - allocate (ef1_grs(lsize_o)) ; ef1_grs(:) = 0._r8 - allocate (ef1_crp(lsize_o)) ; ef1_crp(:) = 0._r8 - call mkvocef ( mksrf_fvocef_mesh, mksrf_fvocef, mesh_model, & - ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & - ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkvocef') - ! Make glacier region ID [glacier_region] from [fglacierregion] dataset allocate (glacier_region(lsize_o)) ; glacier_region(:) = -999 call mkglacierregion(mksrf_fglacierregion_mesh, mksrf_fglacierregion, mesh_model, glacier_region, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacierregion') - ! ! Make urban fraction [pcturb] from [furban] dataset + ! Make soil texture [pctsand, pctclay] + ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero + ! (not a very small number such as 1e-16) where it really should be zero + allocate(mapunits(lsize_o)) ; mapunits(:) = 0 + allocate(pctsand(lsize_o,nlevsoi)) ; pctsand(:,:) = spval + allocate(pctclay(lsize_o,nlevsoi)) ; pctclay(:,:) = spval + call mksoiltex( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pctsand, pctclay, mapunits, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') + do n = 1,lsize_o + do k = 1,nlevsoi + pctsand(n,k) = float(nint(pctsand(n,k))) + pctclay(n,k) = float(nint(pctclay(n,k))) + end do + if (pctlnd_pft(n) < 1.e-6_r8) then + pctsand(n,:) = 43._r8 + pctclay(n,:) = 18._r8 + end if + end do + + ! Make soil color classes [soicol] [fsoicol] + allocate (soil_color(lsize_o)); soil_color(:) = -999 + call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, soil_color, nsoilcol, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilcol') + do n = 1,lsize_o + if (pctlnd_pft(n) < 1.e-6_r8) then + ! assume medium soil color (15) and loamy texture + soil_color(n) = 15 + end if + end do + + ! Make soil fmax [fmaxsoil] + allocate(fmaxsoil(lsize_o)); fmaxsoil(:) = spval + call mksoilfmax( mksrf_fmax_mesh, mksrf_fmax, mesh_model, fmaxsoil, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilfmax') + + ! Make GDP data [gdp] from [gdp] + allocate (gdp(lsize_o)); gdp(:) = spval + call mkgdp (mksrf_fgdp_mesh, mksrf_fgdp, mesh_model, gdp_o=gdp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') + + ! Make peat data [fpeat] from [peatf] + allocate (fpeat(lsize_o)) ; fpeat(:) = spval + call mkpeat (mksrf_fpeat_mesh, mksrf_fpeat, mesh_model, peat_o=fpeat, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpeat') + + ! Make soil depth data [soildepth] from [soildepthf] + allocate ( soildepth(lsize_o)); soildepth(:) = spval + call mksoildepth( mksrf_fsoildepth_mesh, mksrf_fsoildepth, mesh_model, soildepth, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoildepth') + + ! Make agricultural fire peak month data [abm] from [abm] + allocate (agfirepkmon(lsize_o)); agfirepkmon(:) = -999 + call mkagfirepkmon (mksrf_fabm_mesh, mksrf_fabm, mesh_model, agfirepkmon_o=agfirepkmon, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkagfirepkmon') + + ! Make urban fraction [pcturb] from [furban] dataset allocate (pcturb(lsize_o)) ; pcturb(:) = spval allocate (urban_classes(lsize_o,numurbl)) ; urban_classes(:,:) = spval allocate (urban_classes_g(lsize_o,numurbl)); urban_classes_g(:,:) = spval @@ -453,140 +484,95 @@ program mksurfdata deallocate(elev) end if - ! Make soil fmax [fmaxsoil] - allocate(fmaxsoil(lsize_o)); fmaxsoil(:) = spval - call mksoilfmax( mksrf_fmax_mesh, mksrf_fmax, mesh_model, fmaxsoil, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilfmax') - - ! Make soil texture [pctsand, pctclay] - allocate(mapunits(lsize_o)) ; mapunits(:) = 0 - allocate(pctsand(lsize_o,nlevsoi)) ; pctsand(:,:) = spval - allocate(pctclay(lsize_o,nlevsoi)) ; pctclay(:,:) = spval - call mksoiltex( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pctsand, pctclay, mapunits, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') - - ! Make soil depth data [soildepth] from [soildepthf] - allocate ( soildepth(lsize_o)); soildepth(:) = spval - call mksoildepth( mksrf_fsoildepth_mesh, mksrf_fsoildepth, mesh_model, soildepth, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoildepth') - - ! Make soil color classes [soicol] [fsoicol] - allocate (soil_color(lsize_o)); soil_color(:) = -999 - call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, soil_color, nsoilcol, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilcol') - - ! Make organic matter density [organic] [forganic] - allocate ( organic(lsize_o,nlevsoi)); organic(:,:) = spval - call mkorganic( mksrf_forganic_mesh, mksrf_forganic, mesh_model, organic, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') - - ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] - allocate ( pctlak(lsize_o)) ; pctlak(:) = spval - allocate ( pctwet(lsize_o)) ; pctwet(:) = spval - allocate ( lakedepth(lsize_o)) ; lakedepth(:) = spval - zero_out_lake = (all_urban .or. all_veg) - zero_out_wetland = (all_urban .or. all_veg .or. no_inlandwet) - call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & - zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') - call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) - - ! end working - ! -------------------------------------------------- - - ! ! Compute topography statistics [topo_stddev, slope] from [ftopostats] + ! TODO: + ! Compute topography statistics [topo_stddev, slope] from [ftopostats] + ! allocate ( topo_stddev(lsize_o)) ; topo_stddev(:) = spval + ! allocate ( slope(lsize_o)) ; slope(:) = spval ! call mktopostats ( mapfname=map_ftopostats, datfname=mksrf_ftopostats, & ! ndiag=ndiag, topo_stddev_o=topo_stddev, slope_o=slope, std_elev=std_elev) - ! ! Make VIC parameters [binfl, ws, dsmax, ds] from [fvic] + ! TODO: + ! Make VIC parameters [binfl, ws, dsmax, ds] from [fvic] ! if ( outnc_vic )then + ! allocate ( vic_binfl(lsize_o)) ; vic_binfl(:) = spval + ! allocate ( vic_ws(lsize_o)) ; vic_ws(:) = spval + ! allocate ( vic_dsmax(lsize_o)) ; vic_dsmax(:) = spval + ! allocate ( vic_ds(lsize_o)) ; vic_ds(:) = spval ! call mkVICparams ( mapfname=map_fvic, datfname=mksrf_fvic, ndiag=ndiag, & ! binfl_o=vic_binfl, ws_o=vic_ws, dsmax_o=vic_dsmax, ds_o=vic_ds) ! end if - ! ! Do landuse changes such as for the poles, etc. - ! call change_landuse( dynpft=.false. ) + ! Make organic matter density [organic] [forganic] + allocate ( organic(lsize_o,nlevsoi)); organic(:,:) = spval + call mkorganic( mksrf_forganic_mesh, mksrf_forganic, mesh_model, organic, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') + do n = 1,lsize_o + if (pctlnd_pft(n) < 1.e-6_r8) then + organic(n,:) = 0._r8 + end if + end do + + ! Make VOC emission factors for isoprene [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] + allocate (ef1_btr(lsize_o)) ; ef1_btr(:) = 0._r8 + allocate (ef1_fet(lsize_o)) ; ef1_fet(:) = 0._r8 + allocate (ef1_fdt(lsize_o)) ; ef1_fdt(:) = 0._r8 + allocate (ef1_shr(lsize_o)) ; ef1_shr(:) = 0._r8 + allocate (ef1_grs(lsize_o)) ; ef1_grs(:) = 0._r8 + allocate (ef1_crp(lsize_o)) ; ef1_crp(:) = 0._r8 + call mkvocef ( mksrf_fvocef_mesh, mksrf_fvocef, mesh_model, & + ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & + ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkvocef') + + ! TODO: + ! Do landuse changes such as for the poles, etc. + ! call change_landuse(dynpft=.false., lat_o=lat_o) ! ---------------------------------------------------------------------- - ! Modify interpolated fields based on additional constrants + ! Modify pctlak, pctwet, pctgla and pcturb where needed ! ---------------------------------------------------------------------- - ! ! Truncate all percentage fields on output grid. This is needed to - ! ! insure that wt is zero (not a very small number such as - ! ! 1e-16) where it really should be zero - - !DEBUG do n = 1,lsize_o - do k = 1,nlevsoi - pctsand(n,k) = float(nint(pctsand(n,k))) - pctclay(n,k) = float(nint(pctclay(n,k))) - end do + ! Truncate all percentage fields on output grid. This is needed to insure that + ! wt is zero (not a very small number such as 1e-16) where it should be zero pctlak(n) = float(nint(pctlak(n))) pctwet(n) = float(nint(pctwet(n))) pctgla(n) = float(nint(pctgla(n))) + + ! Assume wetland, glacier and/or lake when dataset landmask implies ocean + if (pctlnd_pft(n) < 1.e-6_r8) then + if (pctgla(n) < 1.e-6_r8) then + pctwet(n) = 100._r8 - pctlak(n) + pctgla(n) = 0._r8 + else + pctwet(n) = max(100._r8 - pctgla(n) - pctlak(n), 0.0_r8) + end if + pcturb(n) = 0._r8 + end if + + ! Make sure sum of land cover types does not exceed 100. If it does, + ! subtract excess from most dominant land cover. + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + if (suma > 250._r4) then + write (6,*) subname, ' error: sum of pctlak, pctwet,', & + 'pcturb and pctgla is greater than 250%' + write (6,*)'n,pctlak,pctwet,pcturb,pctgla= ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n) + call shr_sys_abort() + else if (suma > 100._r4) then + pctlak(n) = pctlak(n) * 100._r8/suma + pctwet(n) = pctwet(n) * 100._r8/suma + pcturb(n) = pcturb(n) * 100._r8/suma + pctgla(n) = pctgla(n) * 100._r8/suma + end if end do - !DEBUG - - call ESMF_LogWrite("After fixes", ESMF_LOGMSG_INFO) - - ! do n = 1,lsize_o - ! ! Truncate all percentage fields on output grid. This is needed to - ! ! insure that wt is zero (not a very small number such as - ! ! 1e-16) where it really should be zero - - ! do k = 1,nlevsoi - ! pctsand(n,k) = float(nint(pctsand(n,k))) - ! pctclay(n,k) = float(nint(pctclay(n,k))) - ! end do - ! pctlak(n) = float(nint(pctlak(n))) - ! pctwet(n) = float(nint(pctwet(n))) - ! pctgla(n) = float(nint(pctgla(n))) - - ! ! Assume wetland, glacier and/or lake when dataset landmask implies ocean - ! ! (assume medium soil color (15) and loamy texture). - ! ! Also set pftdata_mask here - - ! if (pctlnd_pft(n) < 1.e-6_r8) then - ! pftdata_mask(n) = 0 - ! soicol(n) = 15 - ! if (pctgla(n) < 1.e-6_r8) then - ! pctwet(n) = 100._r8 - pctlak(n) - ! pctgla(n) = 0._r8 - ! else - ! pctwet(n) = max(100._r8 - pctgla(n) - pctlak(n), 0.0_r8) - ! end if - ! pcturb(n) = 0._r8 - ! !call pctnatpft(n)%set_pct_l2g(0._r8) - ! !call pctcft(n)%set_pct_l2g(0._r8) - ! pctsand(n,:) = 43._r8 - ! pctclay(n,:) = 18._r8 - ! organic(n,:) = 0._r8 - ! else - ! pftdata_mask(n) = 1 - ! end if - - ! ! Make sure sum of land cover types does not exceed 100. If it does, - ! ! subtract excess from most dominant land cover. - - ! suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - ! if (suma > 250._r4) then - ! write (6,*) subname, ' error: sum of pctlak, pctwet,', & - ! 'pcturb and pctgla is greater than 250%' - ! write (6,*)'n,pctlak,pctwet,pcturb,pctgla= ', & - ! n,pctlak(n),pctwet(n),pcturb(n),pctgla(n) - ! call shr_sys_abort() - ! else if (suma > 100._r4) then - ! pctlak(n) = pctlak(n) * 100._r8/suma - ! pctwet(n) = pctwet(n) * 100._r8/suma - ! pcturb(n) = pcturb(n) * 100._r8/suma - ! pctgla(n) = pctgla(n) * 100._r8/suma - ! end if - ! end do + ! ---------------------------------------------------------------------- + ! TODO: ! call normalizencheck_landuse() - ! ! Write out sum of PFT's - + ! TODO: + ! Write out sum of PFT's ! do k = natpft_lb,natpft_ub ! suma = 0._r8 ! do n = 1,lsize_o @@ -594,8 +580,8 @@ program mksurfdata ! enddo ! write(6,*) 'sum over domain of pft ',k,suma ! enddo - ! write(6,*) - + ! if (root_task) write(ndiag,*) + ! ! do k = cft_lb,cft_ub ! suma = 0._r8 ! do n = 1,lsize_o @@ -603,7 +589,7 @@ program mksurfdata ! enddo ! write(6,*) 'sum over domain of cft ',k,suma ! enddo - ! write(6,*) + ! if (root_task) write(ndiag,*) ! Make final values of percent urban by class ! This call needs to occur after all corrections are made to pcturb @@ -636,19 +622,9 @@ program mksurfdata end if ! ---------------------------------------------------------------------- + ! Create netCDF surface dataset ! ---------------------------------------------------------------------- - ! Determine fractional land from pft dataset - ! do n = 1,lsize_o - ! landfrac_pft(n) = pctlnd_pft(n)/100._r8 - ! end do - - ! ---------------------------------------------------------------------- - ! Create surface dataset - ! ---------------------------------------------------------------------- - - ! Create netCDF surface dataset. - ! If fsurdat is blank, then we do not write a surface dataset - but we may still ! write a dynamic landuse file. This is useful if we are creating many datasets at ! once, and don't want duplicate surface datasets. @@ -747,19 +723,20 @@ program mksurfdata ! Create dynamic land use dataset if appropriate ! ---------------------------------------------------------------------- + if (mksrf_fdynuse /= ' '.and. fdyndat == ' ') then + call shr_sys_abort(' must specify fdyndat in namelist if mksrf_fdynuse is not blank') + end if + if (mksrf_fdynuse /= ' ') then - ! write(6,*)'creating dynamic land use dataset' + if (root_task) then + write(ndiag,'(a)')'creating dynamic land use dataset' + end if ! allocate(pctlnd_pft_dyn(lsize_o)) ! call mkharvest_init( lsize_o, spval, harvdata, mksrf_fhrvtyp ) - ! if (fdyndat == ' ') then - ! write(6,*)' must specify fdyndat in namelist if mksrf_fdynuse is not blank' - ! call shr_sys_abort() - ! end if - - ! ! Define dimensions and global attributes + ! Define dimensions and global attributes ! call mkfile( fdyndat, harvdata, dynlanduse=.true., pioid) @@ -936,8 +913,7 @@ program mksurfdata contains !----------------------------------------------------------------------- -#ifdef TODO - subroutine change_landuse( dynpft, lsize_o, mesh_o) + subroutine change_landuse(dynpft) ! Do landuse changes such as for the poles, etc. ! If have pole points on grid - set south pole to glacier @@ -946,54 +922,48 @@ subroutine change_landuse( dynpft, lsize_o, mesh_o) ! input/output variables logical, intent(in) :: dynpft ! if part of the dynpft section of code - ! !LOCAL VARIABLES: - integer :: n,lsize_o ! indices - character(len=32) :: subname = 'change_landuse' ! subroutine name + ! local variables: + integer :: n ! indices + character(len=*), parameter :: subname = 'change_landuse' ! subroutine name !----------------------------------------------------------------------- - ! - do n = 1,lsize_o - ! TODO: define latc - if (abs(latc(n) - 90._r8) < 1.e-6_r8) then - pctlak(n) = 0._r8 - pctwet(n) = 0._r8 - pcturb(n) = 0._r8 - pctgla(n) = 100._r8 + if (abs(lat(n) - 90._r8) < 1.e-6_r8) then + pctlak(n) = 0._r8 + pctwet(n) = 0._r8 + pcturb(n) = 0._r8 + pctgla(n) = 100._r8 call pctnatpft(n)%set_pct_l2g(0._r8) call pctcft(n)%set_pct_l2g(0._r8) if ( .not. dynpft )then - organic(n,:) = 0._r8 - ef1_btr(n) = 0._r8 - ef1_fet(n) = 0._r8 - ef1_fdt(n) = 0._r8 - ef1_shr(n) = 0._r8 - ef1_grs(n) = 0._r8 - ef1_crp(n) = 0._r8 + organic(n,:) = 0._r8 + ef1_btr(n) = 0._r8 + ef1_fet(n) = 0._r8 + ef1_fdt(n) = 0._r8 + ef1_shr(n) = 0._r8 + ef1_grs(n) = 0._r8 + ef1_crp(n) = 0._r8 end if end if - end do end subroutine change_landuse !----------------------------------------------------------------------- - subroutine normalizencheck_landuse(ldomain) + subroutine normalizencheck_landuse(ns_o) ! ! Normalize land use and make sure things add up to 100% as well as ! checking that things are as they should be. ! ! Precondition: pctlak + pctwet + pcturb + pctgla <= 100 (within roundoff) ! - ! !USES: use mkpftConstantsMod , only : baregroundindex use mkpftUtilsMod , only : adjust_total_veg_area - implicit none - ! !ARGUMENTS: - type(domain_type) :: ldomain - ! - ! !LOCAL VARIABLES: - integer :: m,k,n,ns_o ! indices + ! input/output variables: + integer, intent(in) :: ns_o + + ! local variables: + integer :: m,k,n ! indices integer :: nsmall ! number of small PFT values for a single check integer :: nsmall_tot ! total number of small PFT values in all grid cells real(r8) :: suma ! sum for error check @@ -1013,7 +983,6 @@ subroutine normalizencheck_landuse(ldomain) ! Normalize vegetated area so that vegetated + special area is 100% ! ------------------------------------------------------------------------ - ns_o = ldomain%ns do n = 1,ns_o ! Check preconditions @@ -1057,13 +1026,13 @@ subroutine normalizencheck_landuse(ldomain) suma = pctlak(n)+pctwet(n)+pctgla(n) new_total_veg_pct = 100._r8 - suma + ! correct for rounding error: new_total_veg_pct = max(new_total_veg_pct, 0._r8) - call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) + ! call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) ! Make sure we did the above rescaling correctly - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() if (abs(suma - 100._r8) > tol_loose) then write(6,*) subname, ' ERROR in rescaling veg based on (special excluding urban' @@ -1266,6 +1235,5 @@ subroutine normalizencheck_landuse(ldomain) end if end subroutine normalizencheck_landuse -#endif end program mksurfdata From e5bbf5ee660e1825cfbff9e572155b80e26eeae6 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 8 Feb 2022 09:36:10 -0700 Subject: [PATCH 047/614] fixes for writing out urban the new way --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 1116 +++++++++++------- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 955 +++++---------- tools/mksurfdata_esmf/src/mklaiMod.F90 | 24 +- tools/mksurfdata_esmf/src/mkpioMod.F90 | 3 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 634 +++++----- tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 140 +-- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 98 +- 7 files changed, 1396 insertions(+), 1574 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index c274c0c580..0360f3cef0 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -2,25 +2,28 @@ module mkfileMod use ESMF use pio - use shr_kind_mod , only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_getenv, shr_sys_abort - use mkutilsMod , only : get_filename, chkerr - use mkvarpar , only : nlevsoi, numrad, numstdpft - use mkurbanparMod, only : numurbl, nlevurb, mkurbanpar - use mkglcmecMod , only : nglcec - use mklaiMod , only : mklai + use shr_kind_mod , only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_getenv, shr_sys_abort + use mkutilsMod , only : get_filename, chkerr + use mkvarpar , only : nlevsoi, numrad, numstdpft + use mkurbanparMod , only : numurbl, nlevurb, mkurbanpar + use mkglcmecMod , only : nglcec + use mklaiMod , only : mklai use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft, num_natpft -#ifdef TODO use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array - use mkpftMod , only : mkpftAtt - use mkharvestMod , only : mkharvest_fieldname, mkharvest_numtypes, mkharvest_longname, mkharvest_units, harvestDataType -#endif + !use mkharvestMod , only : mkharvest_fieldname, mkharvest_numtypes, mkharvest_longname, mkharvest_units, harvestDataType use mkpioMod ! TODO: add only use mkvarctl implicit none private + public :: mkfile_fdyndat + public :: mkfile_define_dims + public :: mkfile_define_atts + public :: mkfile_define_vars + public :: mkfile_output + interface mkfile_output module procedure mkfile_output_int1d module procedure mkfile_output_int2d @@ -28,8 +31,6 @@ module mkfileMod module procedure mkfile_output_real2d end interface mkfile_output - public :: mkfile_fsurdat - character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -37,353 +38,247 @@ module mkfileMod contains !================================================================================= - subroutine mkfile_fsurdat(nx, ny, mesh_o, lon, lat, dynlanduse, & - pctlak, pctwet, lakedepth, organic, soil_color, nsoilcol, & - urban_classes_g, urban_region, pctsand, pctclay, mapunits, fmaxsoil, soildepth, & - glacier_region, ef_btr, ef_fet, ef_fdt, ef_shr, ef_grs, ef_crp, & - elevclass, pctgla, pctglcmec, topoglcmec, pctglcmec_gic, pctglcmec_icesheet, pctglc_gic, & - pctglc_icesheet, fpeat, agfirepkmon, gdp, rc) + subroutine mkfile_fdyndat(nx, ny, mesh_o, ns_o, lon, lat, rc) ! input/output variables integer , intent(in) :: nx integer , intent(in) :: ny type(ESMF_Mesh) , intent(in) :: mesh_o + integer , intent(in) :: ns_o real(r8) , intent(in) :: lon(:) real(r8) , intent(in) :: lat(:) - logical , intent(in) :: dynlanduse - real(r8) , intent(in) :: pctlak(:) ! percent of grid cell that is lake - real(r8) , intent(in) :: pctwet(:) ! percent of grid cell that is wetland - real(r8) , intent(in) :: lakedepth(:) ! lake depth (m) - real(r8) , intent(in) :: organic(:,:) ! organic - integer , intent(in) :: soil_color(:) - integer , intent(in) :: nsoilcol - real(r8) , intent(in) :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell - integer , intent(in) :: urban_region(:) ! urban region ID - real(r8) , intent(in) :: fmaxsoil(:) ! soil_fractional saturated area - real(r8) , intent(in) :: pctsand(:,:) ! soil texture: percent sand - real(r8) , intent(in) :: pctclay(:,:) ! soil texture: percent clay - integer , intent(in) :: mapunits(:) - real(r8) , intent(in) :: soildepth(:) ! soil depth (m) - integer , intent(in) :: glacier_region(:) - real(r8) , intent(in) :: ef_btr(:) - real(r8) , intent(in) :: ef_fet(:) - real(r8) , intent(in) :: ef_fdt(:) - real(r8) , intent(in) :: ef_shr(:) - real(r8) , intent(in) :: ef_grs(:) - real(r8) , intent(in) :: ef_crp(:) - real(r8) , intent(in) :: elevclass(:) - real(r8) , intent(in) :: pctgla(:) - real(r8) , intent(in) :: pctglcmec(:,:) - real(r8) , intent(in) :: topoglcmec(:,:) - real(r8) , intent(in) :: pctglcmec_gic(:,:) - real(r8) , intent(in) :: pctglcmec_icesheet(:,:) - real(r8) , intent(in) :: pctglc_gic(:) - real(r8) , intent(in) :: pctglc_icesheet(:) - real(r8) , intent(in) :: fpeat(:) - integer , intent(in) :: agfirepkmon(:) - real(r8) , intent(in) :: gdp(:) - integer , intent(out):: rc -#ifdef TODO - type(harvestDataType) , intent(in) :: harvdata -#endif + integer , intent(out) :: rc ! local variables - type(file_desc_t) :: pioid - type(var_desc_t) :: pio_varid - character(len=256) :: varname - character(len=256) :: longname - character(len=256) :: units - integer :: xtype ! external type - integer :: dimid - logical :: define_mode - character(len=256) :: lev1name - integer, allocatable :: ind1D(:) ! Indices of 1D harvest variables - integer, allocatable :: ind2D(:) ! Indices of 2D harvest variables - integer :: n, i ! Indices - integer :: rcode ! Error status - character(len=*), parameter :: subname=' (mkfile_fsurdat) ' - !----------------------------------------------------------------------- - - !--------------------------- - ! Create and open file - !--------------------------- - - ! TODO: what about setting no fill values? - call mkpio_wopen(trim(fsurdat), clobber=.true., pioid=pioid) - - ! ---------------------------------------------------------------------- - ! Define dimensions and global attributes - ! ---------------------------------------------------------------------- - - call mkfile_define_dims(pioid, nx, ny, dynlanduse) - call mkfile_define_atts(pioid, dynlanduse) - - ! ---------------------------------------------------------------------- - ! Define and outut variables - ! ---------------------------------------------------------------------- - - if (root_task) then - write(ndiag,'(a)') 'Writing out output variables' - end if - - if ( outnc_double ) then - xtype = PIO_DOUBLE - else - xtype = PIO_REAL - end if + type(file_desc_t) :: pioid_o + type(var_desc_t) :: pio_varid_o + type(file_desc_t) :: pioid_i + type(var_desc_t) :: pio_varid_i + real(r8), allocatable :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs + character(len=256) :: varname + character(len=256) :: longname + character(len=256) :: units + integer :: xtype ! external type + integer :: dimid + logical :: define_mode + character(len=256) :: lev1name + integer, allocatable :: ind1D(:) ! Indices of 1D harvest variables + integer, allocatable :: ind2D(:) ! Indices of 2D harvest variables + integer :: n, i ! Indices + integer :: rcode ! Error status + character(len=*), parameter :: subname=' (mkfile_fdyndat) ' + ! ------------------------------------------------------------ - ! call mkpftAtt( ncid, dynlanduse, xtype ) - - do n = 1,2 - - define_mode = (n == 1) - if (.not. define_mode) then - rcode = pio_enddef(pioid) - end if - - ! -------------------------------- - ! Write out model grid - ! -------------------------------- - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out model grid" - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'LONGXY', 'model longitudes', & - 'degrees', lat, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LATIXY" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'LATIXY', 'model latitudes', & - 'degrees', lon, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! -------------------------------- - ! Write out non-spatial variables - ! -------------------------------- - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out non-spatial variables" - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out mksoil_color" - if (define_mode) then - rcode = pio_def_var(pioid, 'mxsoil_color', PIO_INT, pio_varid) - rcode = pio_put_att(pioid, pio_varid, 'long_name', 'maximum numbers of soil colors') - rcode = pio_put_att(pioid, pio_varid, 'units', 'unitless') - else - rcode = pio_inq_varid(pioid, 'mxsoil_color', pio_varid) - rcode = pio_put_var(pioid, pio_varid, nsoilcol) - end if - - if (.not. dynlanduse) then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out GLC_MEC" - if (define_mode) then - rcode = pio_inq_dimid(pioid, 'nglcecp1', dimid) - rcode = pio_def_var(pioid, 'GLC_MEC', PIO_DOUBLE, (/dimid/), pio_varid) - rcode = pio_put_att(pioid, pio_varid, 'long_name', 'Glacier elevation class') - rcode = pio_put_att(pioid, pio_varid, 'm', 'unitless') - else - rcode = pio_inq_varid(pioid, 'GLC_MEC', pio_varid) - rcode = pio_put_var(pioid, pio_varid, elevclass) - end if - end if - - ! -------------------------------- - ! Write out spatial variables - ! -------------------------------- - if (.not. dynlanduse) then - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out spatial variables" - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out gdp" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'gdp', 'gdp', & - 'unitless', gdp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out peatland fraction" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'peatf', 'peatland fraction', & - 'unitless', fpeat, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glacier" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLACIER', 'percent glacier', 'unitless', & - pctgla, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLC_MEC', & - 'percent glacier for each glacier elevation class (% of landunit)', 'unitless', & - pctglcmec, lev1name='nglcec', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out topo_glc_mec" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'TOPO_GLC_MEC', & - 'mean elevation on glacier elevation classes', 'm', & - topoglcmec, lev1name='nglcec', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if ( outnc_3dglc ) then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec_gic" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLC_MEC_GIC', & - 'percent smaller glaciers and ice caps for each glacier elevation class (% of landunit)', 'unitless', & - pctglcmec_gic, lev1name='nglcec', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec_icesheet" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLC_MEC_ICESHEET', & - 'percent ice sheet for each glacier elevation class (% of landunit)', 'unitless', & - pctglcmec_icesheet, lev1name='nglcec', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_gic" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLC_GIC', & - 'percent ice caps/glaciers (% of landunit)', 'unitless', & - pctglc_gic, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_icesheet" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_GLC_ICESHEET', & - 'percent ice sheet (% of landunit)', 'unitless', & - pctglc_icesheet, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_lake" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_LAKE', 'percent_lake', & - 'unitless', pctlak, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_wetland" - call mkfile_output(pioid,define_mode, mesh_o, xtype, 'PCT_WETLAND', 'percent_wetland', & - 'unitless', pctwet, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out lakedepth" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'LAKEDEPTH', 'lake_depth', & - 'm', lakedepth, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil organic matter density" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'ORGANIC', 'organic matter density at soil levels', & - 'kg/m3 (assumed carbon content 0.58 gC per gOM)', organic, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_SAND', 'percent sand', & - 'unitless', pctsand, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_CLAY', 'percent sand', & - 'unitless', pctclay, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! TODO: uncommenting this gives garbage in the PCT_SAND and PCT_CLAY output - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil mapunits" - ! call mkfile_output(pioid, define_mode, mesh_o, 'mapunits', 'igbp mapunits', & - ! 'unitless', mapunits, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil fmax (maximum fraction saturated area)" - call mkfile_output (pioid, define_mode, mesh_o, xtype, 'FMAX', 'maximum fractional saturated area', & - 'unitless', fmaxsoil, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil depth" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'zbedrock', 'soil depth', & - 'm', soildepth, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil color" - call mkfile_output(pioid, define_mode, mesh_o, 'SOIL_COLOR', 'soil color', & - 'unitless', soil_color, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out urban region id" - call mkfile_output(pioid, define_mode, mesh_o, 'URBAN_REGION_ID', 'urban region ID', & - 'unitless', urban_region, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out percnt urban" - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_URBAN', 'percent urban for each density type', & - 'unitless', urban_classes_g, lev1name='numurbl', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'EF1_BTR', 'EF btr (isoprene)', & - 'unitless', ef_btr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'EF1_FET', 'EF fet (isoprene)', & - 'unitless', ef_fet, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'EF1_FDT', 'EF fdt (isoprene)', & - 'unitless', ef_fdt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'EF1_SHR', 'EF shr (isoprene)', & - 'unitless', ef_shr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'EF1_GRS', 'EF grs (isoprene)', & - 'unitless', ef_grs, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call mkfile_output(pioid, define_mode, mesh_o, xtype, 'EF1_CRP', 'EF crp (isoprene)', & - 'unitless', ef_crp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - end if - end do - - ! ---------------------------------------------------------------------- - ! Make Urban Parameters from raw input data and write to surface dataset - ! Write to netcdf file is done inside mkurbanpar routine - ! ---------------------------------------------------------------------- - - call mkurbanpar(mksrf_furban, pioid, mesh_o, urban_region, urban_classes_g, & - urban_skip_abort_on_invalid_data_check) - - ! ---------------------------------------------------------------------- - ! Make LAI and SAI from 1/2 degree data and write to surface dataset - ! Write to netcdf file is done inside mklai routine - ! ---------------------------------------------------------------------- - if (root_task) then - write(ndiag,'(a)')'calling mklai' - end if - call mklai(mksrf_flai_mesh, mksrf_flai, mesh_o, pioid, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! ---------------------------------------------------------------------- - ! TODO: Write out variables that did not work in the loop - ! ---------------------------------------------------------------------- - do n = 1,2 - if (n == 1) then - define_mode = .true. - rcode = pio_redef(pioid) - else - define_mode = .false. - rcode = pio_enddef(pioid) - end if - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out glacier_region" - call mkfile_output(pioid, define_mode, mesh_o, 'GLACIER_REGION', 'glacier region ID', & - 'unitless', glacier_region, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing abm (agricultural fire peak month)" - call mkfile_output(pioid, define_mode, mesh_o, 'abm', 'agricultural fire peak month', & - 'unitless', agfirepkmon, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - end do - - ! Close surface dataset - call pio_closefile(pioid) - - if (root_task) then - write (ndiag,'(72a1)') ("-",i=1,60) - write (ndiag,'(a)')' land model surface data set successfully created for ' - end if + rc = ESMF_SUCCESS - end subroutine mkfile_fsurdat + ! if (root_task) then + ! write(ndiag,'(a)')'creating dynamic land use dataset' + ! end if + + ! allocate(pctlnd_pft_dyn(ns_o)) + ! !call mkharvest_init( lsize_o, spval, harvdata, mksrf_fhrvtyp ) + + ! ! open output file + ! call mkpio_wopen(trim(fdyndat), clobber=.true., pioid=pioid_o) + + ! ! Define dimensions and global attributes + ! call mkfile_define_dims(pioid, nx, ny, dynlanduse=.true.) + ! call mkfile_define_atts(pioid, dynlanduse = .true.) + + ! if ( outnc_double ) then + ! xtype = PIO_DOUBLE + ! else + ! xtype = PIO_REAL + ! end if + + ! do n = 1,2 + + ! define_mode = (n == 1) + ! if (.not. define_mode) then + ! rcode = pio_enddef(pioid_o) + ! end if + + ! ! -------------------------------- + ! ! Write out model grid + ! ! -------------------------------- + ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out model grid" + + ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" + ! call mkfile_output(pioid_o, mesh_o, 'LONGXY', 'model longitudes', & + ! 'degrees', lat, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LATIXY" + ! call mkfile_output(pioid_o, mesh_o, 'LATIXY', 'model latitudes', & + ! 'degrees', lon, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! !rcode = pio_open(trim(fdyndat), nf_write, pioid_o)) + ! !rcode = pio_set_fill (pioid_o, nf_nofill, omode)) + + ! ! -------------------------------- + ! ! Write out non-spatial variables + ! ! -------------------------------- + ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out non-spatial variables" + + ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out natpft" + ! if (define_mode) then + ! rcode = pio_def_var(pioid_o, 'natpft', PIO_INT, pio_varid) + ! else + ! rcode = pio_inq_varid(pioid_o, 'natpft', pio_varid) + ! rcode = pio_put_var_int(pioid_o, pio_varid, (/(n,n=natpft_lb,natpft_ub)/)) + ! end if + + ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out cft" + ! if (define_mode) then + ! rcode = pio_def_var(pioid_o, 'cft', PIO_INT, pio_varid) + ! else + ! rcode = pio_inq_varid(pioid_o, 'cft', pio_varid) + ! rcode = pio_put_var_int(pioid_o, pio_varid, (/(n,n=cft_lb,cft_ub)/)) + ! end if + + ! ! -------------------------------- + ! ! Write out spatial variables + ! ! -------------------------------- + + ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing land mask from pft dataset" + ! call mkfile_output(pioid_o, mesh_o, 'PFTDATA_MASK', & + ! 'land mask from pft dataset, indicative of real/fake points', 'unitless', pftdata_mask, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil depth" + ! call mkfile_output(pioid_o, mesh_o, 'LANDFRAC_PFT', & + ! 'land fraction from pft dataset', 'unitless', landfrac_pft, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! end do + + ! ! ----------------------------------------- + ! ! Read in each dynamic pft landuse dataset + ! ! ----------------------------------------- + + ! ! Open txt file + ! open (newunit=nfdyn, file=trim(mksrf_fdynuse), form='formatted', iostat=ier) + ! if (ioe /= 0) then + ! call shr_sys_abort(subname//" failed to open file "//trim(mksrf_fdynuse)) + ! end if + + ! pctnatpft_max = pctnatpft + ! pctcft_max = pctcft + + ! ntim = 0 + ! do + + ! ! Determine file name + ! read(nfdyn, '(A195,1x,I4)', iostat=ier) string, year + ! if (ier /= 0) exit + + ! ! If pft fraction override is set, than intrepret string as PFT and harvesting override values + ! ! Otherwise intrepret string as a filename with PFT and harvesting values in it + ! if ( all_veg )then + ! fname = ' ' + ! fhrvname = ' ' + ! call mkpft_parse_oride(string) + ! call mkharvest_parse_oride(string) + ! write(6, '(a, i4, a)') 'PFT and harvesting values for year ', year, ' :' + ! write(6, '(a, a)') ' ', trim(string) + ! else + ! fname = string + ! read(nfdyn, '(A195,1x,I4)', iostat=ier) fhrvname, year2 + ! if (root_task) then + ! write(ndiat,'(a,i8,a)')' input pft dynamic dataset for year ', year,' is : '//trim(fname) + ! end if + ! if ( year2 /= year ) then + ! write(6,*) subname, ' error: year for harvest not equal to year for PFT files' + ! call shr_sys_abort() + ! end if + ! end if + ! ntim = ntim + 1 + + ! ! Create pctpft data at model resolution from file fname + ! call mkpft( mksrf_fvegtyp_mesh, fname, mesh_model, & + ! pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') + + ! ! Create harvesting data at model resolution + ! call mkharvest( mksrf_fhrvtyp, mesh_model, harvdata=harvdata, rc ) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') + + ! ! Consistency check on input land fraction + ! do n = 1,lsize_o + ! if (pctlnd_pft_dyn(n) /= pctlnd_pft(n)) then + ! write(6,*) subname,' error: pctlnd_pft for dynamics data = ',& + ! pctlnd_pft_dyn(n), ' not equal to pctlnd_pft for surface data = ',& + ! pctlnd_pft(n),' at n= ',n + ! if ( trim(fname) == ' ' )then + ! write(6,*) ' PFT string = ', string + ! else + ! write(6,*) ' PFT file = ', fname + ! end if + ! call shr_sys_abort() + ! end if + ! end do + + ! call change_landuse( dynpft=.true.) + + ! call normalizencheck_landuse(ldomain) + + ! call update_max_array(pctnatpft_max,pctnatpft) + ! call update_max_array(pctcft_max,pctcft) + + ! ! Output time-varying data for current year + + ! rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT', pio_varid) + ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_p2l_array(pctnatpft)) + + ! rcode = pio_inq_varid(pioid, 'PCT_CROP', pio_varid) + ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_l2g_array(pctcft)) + + ! if (num_cft > 0) then + ! rcode = pio_inq_varid(pioid, 'PCT_CFT', pio_varid) + ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_p2l_array(pctcft)) + ! end if + + ! call harvdata%getFieldsIdx( harvind1D, harvind2D) + ! do k = 1, harvdata%num1Dfields() + ! rcode = pio_inq_varid(pioid, trim(mkharvest_fieldname(harvind1D(k),constant=.false.)), pio_varid) + ! harvest1D => harvdata%get1DFieldPtr( harvind1D(k), output=.true. ) + ! call mkpio_put_time_slice(pioid, pio_varid, ntim, harvest1D) + ! end do + ! do k = 1, harvdata%num2Dfields() + ! rcode = pio_inq_varid(pioid, trim(mkharvest_fieldname(harvind2D(k),constant=.false.)), pio_varid) + ! harvest2D => harvdata%get2DFieldPtr( harvind2D(k), output=.true. ) + ! call mkpio_put_time_slice(pioid, pio_varid, ntim, harvest2D) + ! end do + ! deallocate( harvind1D, harvind2D ) + + ! rcode = pio_inq_varid(pioid, 'YEAR', pio_varid) + ! rcode = pio_put_vara_int(pioid, pio_varid, ntim, 1, year) + + ! rcode = pio_inq_varid(pioid, 'time', pio_varid) + ! rcode = pio_put_vara_int(pioid, pio_varid, ntim, 1, year) + + ! rcode = pio_inq_varid(pioid, 'input_pftdata_filename', pio_varid) + ! rcode = pio_put_vara_text(pioid, pio_varid, (/ 1, ntim /), (/ len_trim(string), 1 /), trim(string)) + + ! end do ! end of read loop + + ! rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT_MAX', pio_varid) + ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_p2l_array(pctnatpft_max)) + + ! rcode = pio_inq_varid(pioid, 'PCT_CROP_MAX', pio_varid) + ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_l2g_array(pctcft_max)) + + ! if (num_cft > 0) then + ! rcode = pio_inq_varid(pioid, 'PCT_CFT_MAX', pio_varid) + ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_p2l_array(pctcft_max)) + ! end if + + ! rcode = pio_closefile(pioid) + + end subroutine mkfile_fdyndat -!================================================================================= + !================================================================================= subroutine mkfile_define_dims(pioid, nx, ny, dynlanduse) ! ! Define dimensions. @@ -412,6 +307,7 @@ subroutine mkfile_define_dims(pioid, nx, ny, dynlanduse) rcode = pio_def_dim(pioid, 'nlevsoi', nlevsoi , dimid) rcode = pio_def_dim(pioid, 'nlevurb', nlevurb , dimid) rcode = pio_def_dim(pioid, 'numurbl', numurbl , dimid) + rcode = pio_def_dim(pioid, 'numrad' , numrad, dimid) if (.not. dynlanduse) then rcode = pio_def_dim(pioid, 'nglcec' , nglcec , dimid) rcode = pio_def_dim(pioid, 'nglcecp1', nglcec+1, dimid) @@ -423,9 +319,8 @@ subroutine mkfile_define_dims(pioid, nx, ny, dynlanduse) pftsize = numpft + 1 rcode = pio_def_dim(pioid, 'lsmpft' , pftsize, dimid) end if - ! TODO: uncomment this - ! natpftsize = num_natpft + 1 - ! rcode = pio_def_dim (pioid, 'natpft', natpftsize, dimid) + natpftsize = num_natpft + 1 + rcode = pio_def_dim (pioid, 'natpft', natpftsize, dimid) ! zero-size dimensions can cause problems, so we only include the ! cft dimension if num_cft > 0 Note that this implies that we can @@ -612,15 +507,428 @@ subroutine mkfile_define_atts(pioid, dynlanduse) end subroutine mkfile_define_atts !================================================================================= - subroutine mkfile_output_int1d(pioid, define_mode, mesh, varname, longname, units, data, rc) + subroutine mkfile_define_vars(pioid, dynlanduse) + + ! Define fsurdat variables + + ! input/output variables + type(file_desc_t) , intent(in) :: pioid + logical , intent(in) :: dynlanduse + + ! local variables + integer :: xtype ! external type + character(len=*), parameter :: subname = 'mkfile_define_vars' + !----------------------------------------------------------------------- + + if ( outnc_double ) then + xtype = PIO_DOUBLE + else + xtype = PIO_REAL + end if + + call mkpio_def_spatial_var(pioid=pioid, varname='LONGXY', xtype=xtype, & + long_name='longitude', units='degrees east') + + call mkpio_def_spatial_var(pioid=pioid, varname='LATIXY', xtype=xtype, & + long_name='latitude', units='degrees north') + + if (.not. dynlanduse) then + + call mkpio_defvar(pioid=pioid, varname='mxsoil_color', xtype=PIO_INT, & + long_name='maximum numbers of soil colors', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='SOIL_COLOR', xtype=PIO_INT, & + long_name='soil color', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_SAND', xtype=xtype, & + lev1name='nlevsoi', & + long_name='percent sand', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_CLAY', xtype=xtype, & + lev1name='nlevsoi', & + long_name='percent clay', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='ORGANIC', xtype=xtype, & + lev1name='nlevsoi', & + long_name='organic matter density at soil levels', & + units='kg/m3 (assumed carbon content 0.58 gC per gOM)') + + call mkpio_def_spatial_var(pioid=pioid, varname='FMAX', xtype=xtype, & + long_name='maximum fractional saturated area', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='EF1_BTR', xtype=xtype, & + long_name='EF btr (isoprene)', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='EF1_FET', xtype=xtype, & + long_name='EF fet (isoprene)', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='EF1_FDT', xtype=xtype, & + long_name='EF fdt (isoprene)', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='EF1_SHR', xtype=xtype, & + long_name='EF shr (isoprene)', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='EF1_GRS', xtype=xtype, & + long_name='EF grs (isoprene)', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='EF1_CRP', xtype=xtype, & + long_name='EF crp (isoprene)', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='CANYON_HWR', xtype=xtype, & + lev1name='numurbl', & + long_name='canyon height to width ratio', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='EM_IMPROAD', xtype=xtype, & + lev1name='numurbl', & + long_name='emissivity of impervious road', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='EM_PERROAD', xtype=xtype, & + lev1name='numurbl', & + long_name='emissivity of pervious road', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='EM_ROOF', xtype=xtype, & + lev1name='numurbl', & + long_name='emissivity of roof', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='EM_WALL', xtype=xtype, & + lev1name='numurbl', & + long_name='emissivity of wall', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='HT_ROOF', xtype=xtype, & + lev1name='numurbl', & + long_name='height of roof', units='meters') + + call mkpio_def_spatial_var(pioid=pioid, varname='THICK_ROOF', xtype=xtype, & + lev1name='numurbl', & + long_name='thickness of roof', units='meters') + + call mkpio_def_spatial_var(pioid=pioid, varname='THICK_WALL', xtype=xtype, & + lev1name='numurbl', & + long_name='thickness of wall', units='meters') + + call mkpio_def_spatial_var(pioid=pioid, varname='T_BUILDING_MIN', xtype=xtype, & + lev1name='numurbl', & + long_name='minimum interior building temperature', units='K') + + call mkpio_def_spatial_var(pioid=pioid, varname='WIND_HGT_CANYON', xtype=xtype, & + lev1name='numurbl', & + long_name='height of wind in canyon', units='meters') + + call mkpio_def_spatial_var(pioid=pioid, varname='WTLUNIT_ROOF', xtype=xtype, & + lev1name='numurbl', & + long_name='fraction of roof', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='WTROAD_PERV', xtype=xtype, & + lev1name='numurbl', & + long_name='fraction of pervious road', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='ALB_IMPROAD_DIR', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='direct albedo of impervious road', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='ALB_IMPROAD_DIF', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='diffuse albedo of impervious road', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='ALB_PERROAD_DIR', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='direct albedo of pervious road', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='ALB_PERROAD_DIF', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='diffuse albedo of pervious road', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='ALB_ROOF_DIR', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='direct albedo of roof', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='ALB_ROOF_DIF', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='diffuse albedo of roof', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='ALB_WALL_DIR', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='direct albedo of wall', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='ALB_WALL_DIF', xtype=xtype, & + lev1name='numurbl', lev2name='numrad', & + long_name='diffuse albedo of wall', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='TK_ROOF', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='thermal conductivity of roof', units='W/m*K') + + call mkpio_def_spatial_var(pioid=pioid, varname='TK_WALL', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='thermal conductivity of wall', units='W/m*K') + + call mkpio_def_spatial_var(pioid=pioid, varname='TK_IMPROAD', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='thermal conductivity of impervious road', units='W/m*K') + + call mkpio_def_spatial_var(pioid=pioid, varname='CV_ROOF', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='volumetric heat capacity of roof', units='J/m^3*K') + + call mkpio_def_spatial_var(pioid=pioid, varname='CV_WALL', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='volumetric heat capacity of wall', units='J/m^3*K') + + call mkpio_def_spatial_var(pioid=pioid, varname='CV_IMPROAD', xtype=xtype, & + lev1name='numurbl', lev2name='nlevurb', & + long_name='volumetric heat capacity of impervious road', units='J/m^3*K') + + call mkpio_def_spatial_var(pioid=pioid, varname='NLEV_IMPROAD', xtype=PIO_INT, & + lev1name='numurbl', & + long_name='number of impervious road layers', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='peatf', xtype=xtype, & + long_name='peatland fraction', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='zbedrock', xtype=xtype, & + long_name='soil depth', units='m') + + call mkpio_def_spatial_var(pioid=pioid, varname='abm', xtype=PIO_INT, & + long_name='agricultural fire peak month', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='gdp', xtype=xtype, & + long_name='gdp', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='SLOPE', xtype=xtype, & + long_name='mean topographic slope', units='degrees') + + call mkpio_def_spatial_var(pioid=pioid, varname='STD_ELEV', xtype=xtype, & + long_name='standard deviation of elevation', units='m') + + if ( outnc_vic )then + call mkpio_def_spatial_var(pioid=pioid, varname='binfl', xtype=xtype, & + long_name='VIC b parameter for the Variable Infiltration Capacity Curve', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='Ws', xtype=xtype, & + long_name='VIC Ws parameter for the ARNO curve', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='Dsmax', xtype=xtype, & + long_name='VIC Dsmax parameter for the ARNO curve', units='mm/day') + + call mkpio_def_spatial_var(pioid=pioid, varname='Ds', xtype=xtype, & + long_name='VIC Ds parameter for the ARNO curve', units='unitless') + + end if + call mkpio_def_spatial_var(pioid=pioid, varname='LAKEDEPTH', xtype=xtype, & + long_name='lake depth', units='m') + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_WETLAND', xtype=xtype, & + long_name='percent wetland', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_LAKE', xtype=xtype, & + long_name='percent lake', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_GLACIER', xtype=xtype, & + long_name='percent glacier', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='GLACIER_REGION', xtype=PIO_INT, & + long_name='glacier region ID', units='unitless') + + call mkpio_defvar(pioid=pioid, varname='GLC_MEC', xtype=xtype, & + dim1name='nglcecp1', long_name='Glacier elevation class', units='m') + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_GLC_MEC', xtype=xtype, & + lev1name='nglcec', & + long_name='percent glacier for each glacier elevation class (% of landunit)', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='TOPO_GLC_MEC', xtype=xtype, & + lev1name='nglcec', & + long_name='mean elevation on glacier elevation classes', units='m') + + if ( outnc_3dglc ) then + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_GLC_MEC_GIC', xtype=xtype, & + lev1name='nglcec', & + long_name='percent smaller glaciers and ice caps for each glacier elevation class (% of landunit)', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_GLC_MEC_ICESHEET', xtype=xtype, & + lev1name='nglcec', & + long_name='percent ice sheet for each glacier elevation class (% of landunit)', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_GLC_GIC', xtype=xtype, & + long_name='percent ice caps/glaciers (% of landunit)', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_GLC_ICESHEET', xtype=xtype, & + long_name='percent ice sheet (% of landunit)', units='unitless') + + end if + + if ( outnc_3dglc ) then + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_GLC_MEC_GIC', xtype=xtype, & + lev1name='nglcec', & + long_name='percent smaller glaciers and ice caps for each glacier elevation class (% of landunit)', & + units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_GLC_MEC_ICESHEET', xtype=xtype, & + lev1name='nglcec', & + long_name='percent ice sheet for each glacier elevation class (% of landunit)', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_GLC_GIC', xtype=xtype, & + long_name='percent ice caps/glaciers (% of landunit)', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_GLC_ICESHEET', xtype=xtype, & + long_name='percent ice sheet (% of landunit)', units='unitless') + + end if + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_URBAN', xtype=xtype, & + lev1name='numurbl', & + long_name='percent urban for each density type', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='URBAN_REGION_ID', xtype=PIO_INT, & + long_name='urban region ID', units='unitless') + end if + + if (.not. dynlanduse) then + call mkpio_def_spatial_var(pioid=pioid, varname='CONST_HARVEST_VH1', xtype=xtype, & + long_name = "harvest from primary forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='CONST_HARVEST_VH2', xtype=xtype, & + long_name = "harvest from primary non-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='CONST_HARVEST_SH1', xtype=xtype, & + long_name = "harvest from secondary mature-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='CONST_HARVEST_SH2', xtype=xtype, & + long_name = "harvest from secondary young-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='CONST_HARVEST_SH3', xtype=xtype, & + long_name = "harvest from secondary non-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='CONST_GRAZING', xtype=xtype, & + long_name = "grazing of herbacous pfts", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='CONST_FERTNITRO_CFT', xtype=xtype, & + lev1name = 'cft', & + long_name = "nitrogen fertilizer for each crop", units = "gN/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='UNREPRESENTED_PFT_LULCC', xtype=xtype,& + lev1name = 'natpft', & + long_name = "unrepresented PFT gross LULCC transitions", units = "unitless") + call mkpio_def_spatial_var(pioid=pioid, varname='UNREPRESENTED_CFT_LULCC', xtype=xtype, & + lev1name = 'cft', & + long_name = "unrepresented crop gross LULCC transitions", units = "unitless") + else + call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_VH1', xtype=xtype, & + long_name = "harvest from primary forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_VH2', xtype=xtype, & + long_name = "harvest from primary non-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_SH1', xtype=xtype, & + long_name = "harvest from secondary mature-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_SH2', xtype=xtype, & + long_name = "harvest from secondary young-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_SH3', xtype=xtype, & + long_name = "harvest from secondary non-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='GRAZING', xtype=xtype, & + long_name = "grazing of herbacous pfts", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='FERTNITRO_CFT', xtype=xtype, & + lev1name = 'cft', & + long_name = "nitrogen fertilizer for each crop", units = "gN/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='UNREPRESENTED_PFT_LULCC', xtype=xtype, & + lev1name = 'natpft', & + long_name = "unrepresented PFT gross LULCC transitions", units = "unitless") + call mkpio_def_spatial_var(pioid=pioid, varname='UNREPRESENTED_CFT_LULCC', xtype=xtype, & + lev1name = 'cft', & + long_name = "unrepresented crop gross LULCC transitions", units = "unitless") + end if ! .not. dynlanduse + + ! Coordinate variable for indices of natural PFTs + call mkpio_defvar(pioid=pioid, varname='natpft', xtype=PIO_INT, & + dim1name='natpft', long_name='indices of natural PFTs', units='index') + + ! Coordinate variable for indices of CFTs + if (num_cft > 0) then + call mkpio_defvar(pioid=pioid, varname='cft', xtype=PIO_INT, & + dim1name='cft', long_name='indices of CFTs', units='index') + end if + + call mkpio_def_spatial_var(pioid=pioid, varname='LANDFRAC_PFT', xtype=xtype, & + long_name='land fraction from pft dataset', units='unitless') + + call mkpio_def_spatial_var(pioid=pioid, varname='PFTDATA_MASK', xtype=PIO_INT, & + long_name='land mask from pft dataset, indicative of real/fake points', units='unitless') + + if (.not. dynlanduse) then + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_NATVEG', xtype=xtype, & + long_name='total percent natural vegetation landunit', units='unitless') + end if + + if (.not. dynlanduse) then + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_CROP', xtype=xtype, & + long_name='total percent crop landunit', units='unitless') + else + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_CROP', xtype=xtype, & + lev1name='time', & + long_name='total percent crop landunit', units='unitless') + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_CROP_MAX', xtype=xtype, & + long_name='maximum total percent crop landunit during time period', units='unitless') + end if + + if (.not. dynlanduse) then + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_NAT_PFT', xtype=xtype, & + lev1name='natpft', & + long_name='percent plant functional type on the natural veg landunit (% of landunit)', units='unitless') + else + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_NAT_PFT', xtype=xtype, & + lev1name='natpft', lev2name='time', & + long_name='percent plant functional type on the natural veg landunit (% of landunit)', units='unitless') + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_NAT_PFT_MAX', xtype=xtype, & + lev1name='natpft', & + long_name='maximum percent plant functional type during time period (% of landunit)', units='unitless') + end if + + if (num_cft > 0) then + if (.not. dynlanduse) then + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_CFT', xtype=xtype, & + lev1name='cft', & + long_name='percent crop functional type on the crop landunit (% of landunit)', units='unitless') + else + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_CFT', xtype=xtype, & + lev1name='cft', lev2name='time', & + long_name='percent crop functional type on the crop landunit (% of landunit)', units='unitless') + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_CFT_MAX', xtype=xtype, & + lev1name='cft', & + long_name='maximum percent crop functional type during time period (% of landunit)', units='unitless') + end if + end if + + if (.not. dynlanduse) then + call mkpio_def_spatial_var(pioid=pioid, varname='MONTHLY_LAI', xtype=xtype, & + lev1name='lsmpft', lev2name='time', & + long_name='monthly leaf area index', units='unitless') + call mkpio_def_spatial_var(pioid=pioid, varname='MONTHLY_SAI', xtype=xtype, & + lev1name='lsmpft', lev2name='time', & + long_name='monthly stem area index', units='unitless') + call mkpio_def_spatial_var(pioid=pioid, varname='MONTHLY_HEIGHT_TOP', xtype=xtype, & + lev1name='lsmpft', lev2name='time', & + long_name='monthly height top', units='meters') + call mkpio_def_spatial_var(pioid=pioid, varname='MONTHLY_HEIGHT_BOT', xtype=xtype, & + lev1name='lsmpft', lev2name='time', & + long_name='monthly height bottom', units='meters') + end if + + if (dynlanduse) then + call mkpio_defvar(pioid=pioid, varname='YEAR', xtype=PIO_INT, & + dim1name='time', & + long_name='Year of PFT data', units='unitless') + call mkpio_defvar(pioid=pioid, varname='time', xtype=PIO_INT, & + dim1name='time', & + long_name='year', units='unitless') + call mkpio_defvar(pioid=pioid, varname='input_pftdata_filename', xtype=PIO_CHAR, & + dim1name='nchar', dim2name='time', & + long_name='Input filepath for PFT values for this year', units='unitless') + else + call mkpio_defvar(pioid=pioid, varname='time', xtype=PIO_INT, & + dim1name='time', & + long_name='Calendar month', units='month') + end if + + end subroutine mkfile_define_vars + + !================================================================================= + subroutine mkfile_output_int1d(pioid, mesh, varname, data, rc) ! input/output variables type(file_desc_t) , intent(inout) :: pioid - logical , intent(in) :: define_mode type(ESMF_Mesh) , intent(in) :: mesh character(len=*) , intent(in) :: varname - character(len=*) , intent(in) :: longname - character(len=*) , intent(in) :: units integer , intent(in) :: data(:) integer , intent(out) :: rc @@ -632,27 +940,21 @@ subroutine mkfile_output_int1d(pioid, define_mode, mesh, varname, longname, unit rc = ESMF_SUCCESS - if (define_mode) then - call mkpio_def_spatial_var(pioid, trim(varname), PIO_INT, trim(longname), trim(units)) - else - call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - rcode = pio_inq_varid(pioid, trim(varname), pio_varid) - call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) - call pio_freedecomp(pioid, pio_iodesc) - end if + call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) + call pio_freedecomp(pioid, pio_iodesc) + end subroutine mkfile_output_int1d !================================================================================= - subroutine mkfile_output_int2d(pioid, define_mode, mesh, varname, longname, units, data, rc) + subroutine mkfile_output_int2d(pioid, mesh, varname, data, rc) ! input/output variables type(file_desc_t) , intent(inout) :: pioid - logical , intent(in) :: define_mode type(ESMF_Mesh) , intent(in) :: mesh character(len=*) , intent(in) :: varname - character(len=*) , intent(in) :: longname - character(len=*) , intent(in) :: units integer , intent(in) :: data(:,:) integer , intent(out) :: rc @@ -664,30 +966,23 @@ subroutine mkfile_output_int2d(pioid, define_mode, mesh, varname, longname, unit rc = ESMF_SUCCESS - if (define_mode) then - call mkpio_def_spatial_var(pioid, trim(varname), PIO_INT, trim(longname), trim(units)) - else - call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - rcode = pio_inq_varid(pioid, trim(varname), pio_varid) - call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) - call pio_freedecomp(pioid, pio_iodesc) - end if + call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) + call pio_freedecomp(pioid, pio_iodesc) + end subroutine mkfile_output_int2d !================================================================================= - subroutine mkfile_output_real1d(pioid, define_mode, mesh, xtype, varname, longname, units, data, rc) + subroutine mkfile_output_real1d(pioid, mesh, varname, data, rc) ! input/output variables - type(file_desc_t), intent(inout) :: pioid - logical , intent(in) :: define_mode - type(ESMF_Mesh) , intent(in) :: mesh - integer , intent(in) :: xtype - character(len=*), intent(in) :: varname - character(len=*), intent(in) :: longname - character(len=*), intent(in) :: units - real(r8) , intent(in) :: data(:) - integer , intent(out) :: rc + type(file_desc_t) , intent(inout) :: pioid + type(ESMF_Mesh) , intent(in) :: mesh + character(len=*) , intent(in) :: varname + real(r8) , intent(in) :: data(:) + integer , intent(out) :: rc ! local variables type(io_desc_t) :: pio_iodesc @@ -697,31 +992,24 @@ subroutine mkfile_output_real1d(pioid, define_mode, mesh, xtype, varname, longna rc = ESMF_SUCCESS - if (define_mode) then - call mkpio_def_spatial_var(pioid, trim(varname), xtype, trim(longname), trim(units)) - else - call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - rcode = pio_inq_varid(pioid, trim(varname), pio_varid) - call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) - call pio_freedecomp(pioid, pio_iodesc) - end if + call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) + call pio_freedecomp(pioid, pio_iodesc) + end subroutine mkfile_output_real1d !================================================================================= - subroutine mkfile_output_real2d(pioid, define_mode, mesh, xtype, varname, longname, units, data, lev1name, rc) + subroutine mkfile_output_real2d(pioid, mesh, varname, data, lev1name, rc) ! input/output variables - type(file_desc_t), intent(inout) :: pioid - logical , intent(in) :: define_mode - type(ESMF_Mesh) , intent(in) :: mesh - integer , intent(in) :: xtype - character(len=*), intent(in) :: varname - character(len=*), intent(in) :: longname - character(len=*), intent(in) :: units - character(len=*), intent(in) :: lev1name - real(r8) , intent(in) :: data(:,:) - integer , intent(out) :: rc + type(file_desc_t) , intent(inout) :: pioid + type(ESMF_Mesh) , intent(in) :: mesh + character(len=*) , intent(in) :: varname + character(len=*) , intent(in) :: lev1name + real(r8) , intent(in) :: data(:,:) + integer , intent(out) :: rc ! local variables type(io_desc_t) :: pio_iodesc @@ -731,15 +1019,11 @@ subroutine mkfile_output_real2d(pioid, define_mode, mesh, xtype, varname, longna rc = ESMF_SUCCESS - if (define_mode) then - call mkpio_def_spatial_var(pioid, trim(varname), xtype, trim(lev1name), trim(longname), trim(units)) - else - call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - rcode = pio_inq_varid(pioid, trim(varname), pio_varid) - call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) - call pio_freedecomp(pioid, pio_iodesc) - end if + call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) + call pio_freedecomp(pioid, pio_iodesc) end subroutine mkfile_output_real2d end module mkfileMod diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index 452c6fc68d..e95f67e76d 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -6,61 +6,27 @@ module mkharvestMod use ESMF use pio - use shr_kind_mod , only : r8 => shr_kind_r8, CL => shr_kind_CL - use mkpioMod - use mkvarpar - use mkvarctl + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4, cs => shr_kind_cs, cl => shr_kind_cl + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkpioMod , only : mkpio_get_rawdata, mkpio_get_rawdata_level, mkpio_get_dimlengths + use mkpioMod , only : mkpio_def_spatial_var, mkpio_iodesc_output, mkpio_iodesc_rawdata + use mkpioMod , only : mkpio_put_time_slice + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkutilsMod , only : chkerr + use mkvarctl , only : root_task, ndiag, mpicom implicit none private - public :: harvestDataType - integer, private, parameter :: numharv = 9 ! number of harvest and grazing fields +#include - ! public types - type :: harvestDataType - private - type(ESMF_Routehandle) :: routehandle - type(ESMF_Mesh) :: mesh_i - integer :: ns_i - integer :: ns_o - integer :: dims2nd(numharv) ! 2nd dimension size - integer :: CFTdimsize ! Size of CFT dimension - integer :: PFTdimsize ! Size of PFT dimension - integer :: indices1D(numharv) ! Field indices for CFT variables - integer :: indicesCFT(numharv) ! Field indices for CFT variables - integer :: indicesPFT(numharv) ! Field indices for PFT variables - real(r8), pointer :: data1D(:,:) ! Input 1D data - real(r8), pointer :: data2DCFT(:,:,:) ! Input 2D data with CFT's - real(r8), pointer :: data2DPFT(:,:,:) ! Input 2D data with PFT's - real(r8), pointer :: OutData1D(:,:) ! Output 1D data - real(r8), pointer :: OutData2DCFT(:,:,:) ! Output 2D data with CFT's - real(r8), pointer :: OutData2DPFT(:,:,:) ! Output 2D data with natural PFT's - contains - procedure :: init ! Initialization - procedure :: get1DFieldPtr ! Get a pointer to a 1D field - procedure :: get2DFieldPtr ! Get a pointer to a 2D field - procedure :: getFieldsIdx ! Get field indexes to 1D and 2D fields - procedure :: getFieldsDim ! Get dimension names for this field - procedure :: isField1D ! Return true if field is a 1D field - procedure :: isField2D ! Return true if field is a 2D field - procedure :: num1DFields ! Return the number of 1D fields - procedure :: num2DFields ! Return the number of 2D fields - procedure :: clean ! Clean and deallocate everything - end type harvestDataType + integer, private, parameter :: numharv = 9 ! number of harvest and grazing fields ! public member functions - public :: mkharvest_init ! Initialization public :: mkharvest ! Calculate the harvest values on output grid - public :: mkharvest_fieldname ! Field name for harvest fields on landuse.timeseries - public :: mkharvest_longname ! Long name - public :: mkharvest_units ! units - public :: mkharvest_numtypes ! Number of harvest types public :: mkharvest_parse_oride ! Parse the over-ride string - ! private member functions: (but public because unit test uses them) - public mkharvest_fieldInBounds ! Check that field index is within bounds - ! private data members: integer, parameter :: harlen = 25 ! length of strings for harvest fieldnames character(len=harlen), parameter :: harvest_fieldnames(numharv) = (/ & @@ -86,6 +52,8 @@ module mkharvestMod 'UNREPRESENTED_CFT_LULCC' & /) + logical :: is_field_1d(num_harv) + character(len=CL), parameter :: string_undef = 'UNSET' real(r8), parameter :: real_undef = -999.99 character(len=CL) :: harvest_longnames(numharv) = string_undef @@ -93,140 +61,40 @@ module mkharvestMod real(r8), pointer :: oride_harv(:) ! array that can override harvesting logical :: initialized = .false. + type(ESMF_Mesh) , private :: mesh_i + type(ESMF_RouteHandle), private :: routehandle + real(r8), allocatable , private :: frac_o(:) + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + !================================================================================= contains !================================================================================= - - subroutine init( this, dims2nd, ns_i, ns_o, init_value ) - ! - ! Initialization of the harvestData object - ! - ! input/output variables - class(harvestDataType), intent(inout) :: this ! harvestData object - integer, intent(in) :: dims2nd(:) ! 2nd Dimension sizes - integer, intent(in) :: ns_i ! Input dimension size - integer, intent(in) :: ns_o ! Output dimension size - real(r8), intent(in) :: init_value ! Initial value - ! - ! !local variables: - character(len=*), parameter :: subname = 'harvestData::init' - integer :: num2nd ! number of non 1D variables - integer :: numCFT, numPFT ! number of CFT and PFT variables respectively - integer :: num1D ! number of 1D variables - integer :: n ! index !----------------------------------------------------------------------- - if ( size(dims2nd) /= numharv )then - write(*,*) subname//':ERROR:: dims2nd given to init is not the right size' - call shr_sys_abort() - end if + rc = ESMF_SUCCESS - this%CFTdimsize = 64 - this%PFTdimsize = 15 - this%dims2nd = dims2nd - num2nd = 0 - numCFT = 0 - numPFT = 0 - num1D = 0 - this%indices1D = -1 - this%indicesPFT = -1 - this%indicesCFT = -1 - - do n = 1, numharv - if ( dims2nd(n) == 0 )then - num1D = num1D + 1 - this%indices1D(n) = num1D - else - num2nd = num2nd + 1 - if (dims2nd(n) == this%CFTdimsize) then - numCFT = numCFT + 1 - this%indicesCFT(n) = numCFT - else if ( dims2nd(n) == this%PFTdimsize )then - numPFT = numPFT + 1 - this%indicesPFT(n) = numPFT - else - write(*,*) 'ERROR:: dims2nd is not the right size (should be 0, 15, or 64) = ', dims2nd(n) - call shr_sys_abort() - end if - end if - end do - - allocate( this%data1D(ns_i,num1D) ) - allocate( this%OutData1D(ns_o,num1D) ) - - this%OutData1D(:,:) = init_value - - if ( num2nd > 0 ) then - allocate( this%data2DCFT (ns_i,this%CFTdimsize,numCFT) ) - allocate( this%OutData2DCFT(ns_o,this%CFTdimsize,numCFT) ) - - this%OutData2DCFT(:,:,:) = init_value + ! TODO: check that number of global elements in mesh is identical + ! to number of global elements in input data - allocate( this%data2DPFT (ns_i,this%PFTdimsize,numPFT) ) - allocate( this%OutData2DPFT(ns_o,this%PFTdimsize,numPFT) ) - - this%OutData2DPFT(:,:,:) = init_value + if (root_task) then + write (ndiag,'(a)') 'Attempting to initialize harvest module .... ' end if - end subroutine init - - !================================================================================= - subroutine mkharvest_init(file_mesh_i, file_data_i, mesh_o, init_val, harvdata, pioid, constant) - ! - ! Initialization of mkharvest module. - ! - ! input/output variables: - real(r8) , intent(in) :: init_val ! initial value to set to - character(len=*) , intent(in) :: fharvest ! input harvest dataset file name - type(file_desc_t) , intent(out) :: pioid - type(harvestDataType) , intent(inout) :: harvdata ! Harvest data - logical, optional , intent(in) :: constant ! Flag if variables are CONST_ version for surface dataset - - ! local variables: - character(len=CL) :: lunits ! local units read in - integer :: ifld ! indices - integer :: ret ! return code - logical :: lconstant ! local version of constant flag - logical :: varexists ! If variable exists on file - integer :: dim_lengths(3) ! Dimension lengths on file - integer :: dims2nd(numharv) ! Dimension lengths of 3rd dimension for each variable on file - integer :: ndims ! Number of dimensions on file - integer :: rcode - character(len=*), parameter :: subname = 'mkharvest_init' - !----------------------------------------------------------------------- - - ! TODO: check that number of global elements in mesh is identical to number of global elements in input data - lconstant = .false. if ( present(constant) ) lconstant = constant - initialized = .true. - - ! Open fharvest - call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(fharvest), pio_nowrite) - call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) - - ! Read in input mesh - mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine ns_i - call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Determine ns_o and allocate data_o - call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + initialized = .true. - ! Create a route handle between the input and output mesh - call create_routehandle_r8(mesh_i, mesh_o, routehandle, rc) - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + ! Open input harvest file + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) do ifld = 1, numharv call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) ! Determine if variable is on input dataset (fharvest) varname = mkharvest_fieldname(ifld, constant=lconstant) - rCode = pio_inq_varid(varname, pio_varid) + rCode = pio_inq_varid(pioid, varname, pio_varid) call pio_seterrorhandling(pioid, PIO_INTERNAL_ERROR) if (rcode == PIO_NOERR) then varexists = .true. @@ -234,15 +102,6 @@ subroutine mkharvest_init(file_mesh_i, file_data_i, mesh_o, init_val, harvdata, varexists = .false. end if if (varexists) then - ! Get variable attributes if they exist - call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) - rcode = pio_inq_attname(pioid, pio_varid, attnum, attname) - call pio_seterrorhandling(pioid, PIO_INTERNAL_ERROR) - if (rcode == 'PIO_NOERR') then - rcode = pio_get_att_text( pioid, pio_varid, 'long_name', harvest_longnames(ifld)) - rcode = pio_get_att_text( pioid, pio_varid, 'units', harvest_units(ifld)) - end if - ! get dims2nd for variable call mkpio_get_dimlengths(pioid, varname, ndims, dim_lengths) if ( ndims == 2 )then @@ -253,26 +112,25 @@ subroutine mkharvest_init(file_mesh_i, file_data_i, mesh_o, init_val, harvdata, write(*,*) 'ERROR:: bad dimensionality for variable = ', mkharvest_fieldname(ifld, constant=lconstant) call shr_sys_abort() end if + if (root_task) then + write(ndiag,'(a)') "Will Read: "//mkharvest_fieldname(ifld, constant=lconstant) + end if else if (root_task) then - write(ndiag,'(a)') "SKIPPING: "//mkharvest_fieldname(ifld, constant=lconstant) + write(ndiag,'(a)') "Will Skip: "//mkharvest_fieldname(ifld, constant=lconstant) end if - harvest_longnames(ifld) = trim(mkharvest_fieldname(ifld, constant=lconstant)) // " (zeroed out)" - harvest_units(ifld) = "not_read_in" end if end do call pio_closefile(pioid) - ! Initialize harvest datatype - call harvdata%init( dims2nd, ns_i, ns_o, init_val, routehandle, mesh_i ) - - allocate( oride_harv(numharv) ) - oride_harv(:) = real_undef + if (root_task) then + write (ndiag,'(a)') 'finished mkharvest_init' + end if end subroutine mkharvest_init !================================================================================= - subroutine mkharvest(file_data_i, mesh_o, harvdata, rc) + subroutine mkharvest(file_data_i, mesh_o, pioid_o, constant, rc) ! ! Make harvest data for the dynamic PFT dataset. ! This dataset consists of the normalized harvest or grazing fraction (0-1) of @@ -281,210 +139,217 @@ subroutine mkharvest(file_data_i, mesh_o, harvdata, rc) ! input/output variables: character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh - type(harvestDataType) , intent(inout) :: harvdata ! Harvest data + type(file_desc_t) , intent(in) :: pioid_o + logical, optional , intent(in) :: constant integer , intent(out) :: rc ! return code ! local variables: - type(file_desc_t) :: pioid - type(var_desc_t) :: pio_varid - integer :: ni,no,ns_i,ns_o ! indices - integer :: k,l,n,m ! indices - integer :: rcode, ier ! error status - integer :: ndims - integer , allocatable :: dimlengths(:) - real(r8), allocatable :: data_i(:,:) - real(r8), allocatable :: data_o(:,:) - real(r8), allocatable :: frac_i(:) - real(r8), allocatable :: frac_o(:) - real(r8) :: gharv_o(numharv) ! output grid: global area harvesting - real(r8) :: garea_o ! output grid: global area - real(r8) :: gharv_i(numharv) ! input grid: global area harvesting - real(r8) :: garea_i ! input grid: global area - integer :: ifld ! indices - logical :: varexists ! If variable exists or not - integer, allocatable :: ind1D(:) ! Index of 1D harvest fields - integer, allocatable :: ind2D(:) ! Index of 2D harvest fields - real(r8), pointer :: data1D_i(:) ! 1D input data - real(r8), pointer :: data2D_i(:,:) ! 2D output data - real(r8), pointer :: data1D_o(:) ! 1D output data - real(r8), pointer :: data2D_o(:,:) ! 2D output data - real(r8), allocatable :: read_data2d_i(:,:) ! input 2d data read in - real(r8), allocatable :: read_data2d_o(:,:) ! regridded input 2d data - character(len=CS) :: varname - integer :: nlev ! inner dimension of input 2d data read in - character(len=*), parameter :: unit = '10**6 km**2' ! Output units - real(r8), parameter :: fac = 1.e-06_r8 ! Output factor - real(r8), parameter :: rat = fac/100._r8 ! Output factor divided by 100% + type(file_desc_t) :: pioid_i + type(var_desc_t) :: pio_varid + integer :: ni,no,ns_i,ns_o ! indices + integer :: k,l,n,m ! indices + integer :: ndims + integer :: nlev ! inner dimension of input 2d data read in + integer :: ifld ! indices + character(len=cs) :: varname + logical :: varexists ! If variable exists or not + integer , allocatable :: mask_i(:) + real(r8) , allocatable :: frac_i(:) + real(r8) , allocatable :: frac_o(:) + real(r8) , allocatable :: data_i(:,:) + real(r8) , allocatable :: data_o(:,:) + real(r8) , allocatable :: read_data2d_i(:,:) ! input 2d data read in + real(r8) , allocatable :: read_data2d_o(:,:) ! regridded input 2d data + real(r8) , allocatable :: area_i(:) + real(r8) , allocatable :: area_o(:) + integer :: dims2nd(numharv) ! Dimension lengths of 3rd dimension for each variable on file + logical :: lconstant ! local version of constant flag + integer :: dim_lengths(3) ! Dimension lengths on file + integer :: ndims ! Number of dimensions on file + logical :: varexists ! If variable exists on file + integer :: ifld ! indices + integer :: rcode, ier ! error status + logical :: lconstant character(len=*), parameter :: subname = 'mkharvest' !----------------------------------------------------------------------- + rc = ESMF_SUCCESS + + ! Normally read in the harvesting file, and then regrid to output grid + if (root_task) then write (ndiag,'(a)') 'Attempting to make harvest fields .....' end if - ! ----------------------------------------------------------------- - ! Normally read in the harvesting file, and then regrid to output grid - ! ----------------------------------------------------------------- + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) - call harvdata%getFieldsIdx( ind1D, ind2D ) + ! Read in input mesh + if (.not. ESMF_MeshCreated(mesh_i)) then + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + ! Create a route handle between the input and output mesh + if (.not. RouteHandleisCreated(routehandle_r8)) then + allocate(frac_o(ns_o)) + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + end if + + ! Determine ns_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + allocate( oride_harv(numharv) ) + oride_harv(:) = real_undef if ( all(oride_harv == real_undef ) )then - ! ----------------------------------------------------------------- - ! Read input harvesting file - ! ----------------------------------------------------------------- - - ! Determine frac_o (regrid frac_i to frac_o) - allocate(frac_i(ns_i)) - allocate(frac_o(ns_o)) + ! Get the landmask from the file and reset the mesh mask based on that + allocate(frac_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, frac_i, frac_o, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regrid landmask in "//trim(subname)) - - ! Read in input 1d fields if they exists and map to output grid - do k = 1, harvdata%num1Dfields() - ifld = ind1D(k) - data1d_i => harvdata%get1DFieldPtr( ifld ) - data1d_o => harvdata%get1DFieldPtr( ifld, output=.true. ) - data1d_i(:) = 0.0_r8 - call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) - varname = mkharvest_fieldname(ifld) - rCode = pio_inq_varid(varname, pio_varid) - call pio_seterrorhandling(pioid, PIO_INTERNAL_ERROR) - if (rcode == PIO_NOERR) then - call mkpio_get_rawdata(pioid, varname, mesh_i, data1d_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, data1d_i, data1d_o, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - do n = 1,ns_o - if (frac_o(n) > 0._r8) then - data1d_o(n) = datda1d_o(n) / frac_o(n) - else - data1d_o(n) = 0._r8 - end if - end do + do ni = 1,ns_i + if (frac_i(ni) > 0._r4) then + mask_i(ni) = 1 else - write(*,*) "SKIP: "//mkharvest_fieldname(ifld) + mask_i(ni) = 0 end if end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return ! Read in input 1d fields if they exists and map to output grid - do k = 1, harvdata%num2Dfields() - ifld = ind2D(k) - data2d_i => harvdata%get2DFieldPtr( ifld ) - data2d_o => harvdata%get2DFieldPtr( ifld, output=.true. ) - data2d_i(:,:) = 0.0_r8 - call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) - varname = mkharvest_fieldname(ifld) - rCode = pio_inq_varid(varname, pio_varid) + do ifld = 1,numharv + varname_i = trim(harvest_fieldnames(ifld)) + if (lconstant) then + varname_o = trim(harvest_const_fieldnames(ifld) + else + varname_o = varname_i + end if + ! Check if the variable is on the input file + call pio_seterrorhandling(pioid_i, PIO_BCAST_ERROR) + rCode = pio_inq_varid(pioid, varname, pio_varid) call pio_seterrorhandling(pioid, PIO_INTERNAL_ERROR) if (rcode == PIO_NOERR) then - nlev = size(data2d_i, dim=2) - allocate(read_data2d_i(nlev, ns_i)) - allocate(read_data2d_o(nlev, ns_o)) - call mkpio_get_rawdata(pioid, varname, mesh_i, read_data2d_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, read_data2d_i, read_data2d_o, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - do n = 1,ns_o - if (frac_o(n) > 0._r8) then - read_data2d_o(:,n) = datda2d_o(:,n) / frac_o(n) - else - read_data2d_o(:,n) = 0._r8 - end if - end do - do l = 1,nlev - do n = 1,ns_o - data2d_o(n,l) = read_data2d_o(l,n) - end do - end do - deallocate(read_data2d_i) - deallocate(read_data2d_o) + varexists = .true. else - write(*,*) "SKIP: "//mkharvest_fieldname(ifld) + varexists = .false. + end if + if (varexists) then + call mkpio_get_dimlengths(pioid, varname, ndims, dim_lengths) + if ( ndims == 2 )then + dims2nd(ifld) = 0 + else if (ndims == 3 )then + dims2nd(ifld) = dim_lengths(3) + else + write(*,*) 'ERROR:: bad dimensionality for variable = ',trim(varname_i) + call shr_sys_abort() + end if + if (root_task) then + write(ndiag,'(a)') "Will Read: "//trim(varname_i) + end if + else + if (root_task) then + write(ndiag,'(a)') "Will Skip: "//trim(varname_i) + end if + end if + if (varexists) then + if (dim2nd(ifld) == 0) then + allocate(data1d_i(ns_i)) + allocate(data1d_o(ns_o)) + ! read in input 1d variable + call mkpio_get_rawdata(pioid, varname, mesh_i, data1d_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! regrid input variable + call regrid_rawdata(mesh_i, mesh_o, routehandle, data1d_i, data1d_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + deallocate(data1d_i) + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out "//trim(varname_o) + + ! write out mapped variable + call mkfile_output(pioid_o, mesh_o, trim(varname_o), data1d_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + deallocate(data1d_o)) + else + nlev = dims2nd(ifld) + allocate(read_data2d_i(nlev, ns_i)) + allocate(read_data2d_o(nlev, ns_o)) + ! read in input variable + call mkpio_get_rawdata(pioid, varname, mesh_i, read_data2d_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! regrid input variable + call regrid_rawdata(mesh_i, mesh_o, routehandle, read_data2d_i, read_data2d_o, 1, nlev, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + deallocate(read_data2d_i) + + ! write out variable + allocate(data2d_o(ns_o, nlev)) + do l = 1,nlev + do n = 1,ns_o + data2d_o(n,l) = read_data2d_o(l,n) + end do + end do + call mkfile_output(pioid_o, mesh_o, trim(varname_o), data2d_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + deallocate(data2d_o) + end if end if end do - call pio_closefile(pioid) - - ! ----------------------------------------------------------------- - ! Error check ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- + ! call check_global_sums('harvest type', ns_i, ns_o, mesh_i, mesh_o, mask_i, frac_o, IND1d, rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! gharv_i(:) = 0. - ! garea_i = 0. - ! do ni = 1, ns_i - ! garea_i = garea_i + area_src(ni)*re**2 - ! do k = 1, harvdata%num1Dfields() - ! m = ind1D(k) - ! data1D_i => harvdata%get1DFieldPtr( m ) - ! gharv_i(m) = gharv_i(m) + data1D_i(ni)*area_src(ni) * mask(ni)*re**2 - ! end do + else + + ! Otherwise override the harvesting with the input harvest values + ! TODO: implement this + ! if ( any(oride_harv == real_undef ) )then + ! write(6,*) subname, ' error some override harvesting fields set and others are not = ', oride_harv + ! call shr_sys_abort() + ! end if + ! do k = 1, harvdata%num1Dfields() + ! m = ind1D(k) + ! if ( oride_harv(m) < 0.0_r8 .or. oride_harv(m) > 100.0_r8 )then + ! write(6,*) subname, ' error override harvesting field out of range', & + ! oride_harv(m), ' field = ', mkharvest_fieldname(m) + ! call shr_sys_abort() + ! end if ! end do - ! gharv_o(:) = 0. - ! garea_o = 0. ! do no = 1,ns_o - ! garea_o = garea_o + area_dst(no)*re**2 ! do k = 1, harvdata%num1Dfields() ! m = ind1D(k) - ! data1D_o => harvdata%get1DFieldPtr( m, output=.true. ) - ! gharv_o(m) = gharv_o(m) + data1D_o(no)*area_dst(no)* frac_dst(no)*re**2 + ! data1D_o(no) = oride_harv(m) ! end do ! end do - ! Write out to diagnostic output file -! write (ndiag,*) -! write (ndiag,'(1x,70a1)') ('=',k=1,70) -! write (ndiag,*) 'Harvesting Output' -! write (ndiag,'(1x,70a1)') ('=',k=1,70) - -! write (ndiag,*) -! write (ndiag,'(1x,70a1)') ('.',k=1,70) -! write (ndiag,1001) unit, unit -! 1001 format (1x,'harvest type ',20x,' input grid area',' output grid area',/ & -! 1x,33x,' ',A,' ',A) -! write (ndiag,'(1x,70a1)') ('.',k=1,70) -! write (ndiag,*) -! do k = 1, harvdata%num1Dfields() -! m = ind1D(k) -! write (ndiag,1002) mkharvest_fieldname(m), gharv_i(m)*rat,gharv_o(m)*rat -! end do -! 1002 format (1x,a35,f16.3,f17.3) - - else - - ! ----------------------------------------------------------------- - ! Otherwise override the harvesting with the input harvest values - ! ----------------------------------------------------------------- - - if ( any(oride_harv == real_undef ) )then - write(6,*) subname, ' error some override harvesting fields set and others are not = ', oride_harv - call shr_sys_abort() - end if - do k = 1, harvdata%num1Dfields() - m = ind1D(k) - if ( oride_harv(m) < 0.0_r8 .or. oride_harv(m) > 100.0_r8 )then - write(6,*) subname, ' error override harvesting field out of range', & - oride_harv(m), ' field = ', mkharvest_fieldname(m) - call shr_sys_abort() - end if - end do - do no = 1,ns_o - do k = 1, harvdata%num1Dfields() - m = ind1D(k) - data1D_o => harvdata%get1DFieldPtr( m, output=.true. ) - data1D_o(no) = oride_harv(m) - end do - end do + end if + ! If constant model, clean up the mapping + lconstant = .false. + if ( present(constant) ) lconstant = constant + if (lconstant) then + deallocate(frac_o) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() end if - deallocate( ind1D, ind2D ) - write (6,*) 'Successfully made harvest and grazing' - write (6,*) + if (root_task) then + write (ndiag,'(a)') 'Successfully made harvest and grazing' + write (ndiag,*) + end if end subroutine mkharvest @@ -497,11 +362,11 @@ subroutine mkharvest_parse_oride( string ) use shr_string_mod, only: shr_string_betweenTags ! input/output variables: - character(len=256), intent(in) :: string ! String to parse with harvest and grazing data + character(len=CS), intent(in) :: string ! String to parse with harvest and grazing data ! local variables: - integer :: rc ! error return code - character(len=256) :: substring ! substring between tags + character(len=CS) :: substring ! substring between tags + integer :: rc ! error return code character(len=*), parameter :: harv_start = "" character(len=*), parameter :: harv_end = "" character(len=*), parameter :: graz_start = "" @@ -529,334 +394,84 @@ subroutine mkharvest_parse_oride( string ) end subroutine mkharvest_parse_oride !================================================================================= - function get1DFieldPtr( this, nfield, output ) result(ptr1D) - ! - ! Returns 2D pointer to field data for this index - ! - ! input/output variables - class(harvestDataType) , intent(in) :: this ! harvestData object - integer , intent(in) :: nfield ! field index - real(r8) , pointer :: ptr1D(:) ! Pointer to 1D data - logical, optional , intent(in) :: output ! Flag if this is the output pointer or not (input) - ! - ! !local variables: - logical :: loutput ! Local output flag - character(len=*), parameter :: subname = 'harvestData::get1DFieldPtr' - !----------------------------------------------------------------------- - - loutput = .false. - if (present(output)) loutput = output - - if ( mkharvest_fieldInBounds( nfield ) .and. this%isField1D(nfield) )then - if ( .not. loutput ) then - ptr1D => this%data1D(:,this%indices1D(nfield)) - else - ptr1D => this%OutData1D(:,this%indices1D(nfield)) - end if - else - call shr_sys_abort() - end if - end function get1DFieldPtr - - !================================================================================= - function get2DFieldPtr( this, nfield, output ) result(ptr2D) - ! - ! Returns 2D pointer to field data for this index - ! - ! input/output variables: - class(harvestDataType) , intent(in) :: this ! harvestData object - integer , intent(in) :: nfield ! field index - real(r8) , pointer :: ptr2D(:,:) ! Pointer to 2D data - logical, optional , intent(in) :: output ! Flag if this is the output pointer or not (input) - ! - ! local variables: - logical :: loutput ! Local output flag - character(len=*), parameter :: subname = 'harvestData::get2DFieldPtr' - !----------------------------------------------------------------------- - - loutput = .false. - if ( present(output) ) loutput = output - if ( mkharvest_fieldInBounds( nfield ) .and. this%isField2D(nfield) )then - if ( .not. loutput ) then - if ( this%dims2nd(nfield) == this%CFTdimsize )then - ptr2D => this%data2DCFT(:,:,this%indicesCFT(nfield)) - else - ptr2D => this%data2DPFT(:,:,this%indicesPFT(nfield)) - end if - else - if ( this%dims2nd(nfield) == this%CFTdimsize )then - ptr2D => this%OutData2DCFT(:,:,this%indicesCFT(nfield)) - else - ptr2D => this%OutData2DPFT(:,:,this%indicesPFT(nfield)) - end if - end if - else - call shr_sys_abort() - end if - end function get2DFieldPtr + subroutine check_global_sums(this, name, ns_i, ns_o, mesh_i, mesh_o, mask_i, frac_o, ind1D, rc) - !================================================================================= - subroutine getFieldsIdx( this, indices1D, indices2D ) - ! - ! Returns list of 1D and 2D fields indices - ! - ! input/output variables: - class(harvestDataType), intent(in) :: this ! harvestData object - integer, allocatable :: indices1D(:) ! List of 1D indices - integer, allocatable :: indices2D(:) ! List of 2D indices - ! - ! local variables: - character(len=*), parameter :: subname = 'harvestData::getFieldsIdx' - integer :: ifld, n1, n2 ! field index and field index + ! input/otuput variables + class(harvestDataType), intent(inout) :: this ! harvestData object + character(len=*) , intent(in) :: name + integer , intent(in) :: ns_i + integer , intent(in) :: ns_o + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o + integer , intent(in) :: mask_i(:) + real(r8) , intent(in) :: frac_o(:) + integer , intent(in) :: ind1D(:) + integer , intent(out) :: rc + + ! local variables + integer :: ni, no, k, m + integer :: ier + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + real(r8) :: local_i(numharv) ! input grid: global area harvesting + real(r8) :: local_o(numharv) ! output grid: global area harvesting + real(r8) :: global_i(numharv) ! input grid: global area harvesting + real(r8) :: global_o(numharv) ! output grid: global area harvesting + real(r8), pointer :: data1D_i(:) ! 1D input data + real(r8), pointer :: data1D_o(:) ! 1D output data + real(r8), parameter :: fac = 1.e-06_r8 ! Output factor + real(r8), parameter :: rat = fac/100._r8 ! Output factor divided by 100% + character(len=*) , parameter :: unit = '10**6 km**2' ! Output units !----------------------------------------------------------------------- - allocate( indices1D(max(1,this%num1DFields()) ) ) - allocate( indices2D(max(1,this%num2DFields()) ) ) - indices1D = -1 - indices2D = -1 - n1 = 0 - n2 = 0 - do ifld = 1, mkharvest_numtypes() - if ( this%isField1D(ifld) )then - n1 = n1 + 1 - indices1D(n1) = ifld - else if ( this%isField2D(ifld) )then - n2 = n2 + 1 - indices2D(n2) = ifld - end if + rc = ESMF_SUCCESS + + allocate(area_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(area_o(ns_o), stat=ier) + if (ier/=0) call shr_sys_abort() + call get_meshareas(mesh_i, area_i, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call get_meshareas(mesh_o, area_o, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Input grid global area + local_i(:) = 0. + do ni = 1, ns_i + do k = 1, this%num1Dfields() + m = ind1D(k) + data1D_i => this%get1DFieldPtr( m ) + local_i(m) = local_i(m) + data1D_i(ni) *area_i(ni) * mask_i(ni) + end do end do - end subroutine getFieldsIdx - - !================================================================================= - function getFieldsDim( this, nfield ) result(dimname) - ! - ! Returns list of 1D and 2D fields indices - ! - ! input/output variables: - class(harvestDataType), intent(in) :: this ! harvestData object - integer, intent(in) :: nfield ! field index - character(len=10) :: dimname ! Dimension names - ! - ! local variables: - character(len=*), parameter :: subname = 'harvestData::getFieldsDim' - !----------------------------------------------------------------------- - - if ( this%dims2nd(nfield) == this%CFTdimsize )then - dimname = "cft" - else if ( this%dims2nd(nfield) == this%PFTdimsize )then - dimname = "natpft" - else - dimname = "none" - end if - end function getFieldsDim - - !================================================================================= - logical function isField1D( this, nfield ) - ! - ! Returns true if this field index is a 1D field - ! - ! input/output variables: - class(harvestDataType), intent(in) :: this ! harvestData object - integer, intent(in) :: nfield ! field index - ! - ! local variables: - character(len=*), parameter :: subname = 'harvestData::isField1D' - !----------------------------------------------------------------------- - - isField1D = .false. - if ( mkharvest_fieldInBounds( nfield ) )then - if ( this%dims2nd(nfield) == 0 ) isField1D = .true. - else - call shr_sys_abort() - end if - end function isField1D - - !================================================================================= - logical function isField2D( this, nfield ) - ! - ! Returns true if this field index is a 2D field - ! - ! input/output variables: - class(harvestDataType), intent(in) :: this ! harvestData object - integer, intent(in) :: nfield ! field index - ! - ! local variables: - character(len=*), parameter :: subname = 'harvestData::isField2D' - !----------------------------------------------------------------------- - - isField2D = .false. - if ( mkharvest_fieldInBounds( nfield ) )then - if ( this%dims2nd(nfield) /= 0 ) isField2D = .true. - else - call shr_sys_abort() - end if - end function isField2D - - !================================================================================= - integer function num1DFields( this ) - ! - ! Returns the number of 1D fields - ! - ! input/output variables: - class(harvestDataType), intent(in) :: this ! harvestData object - ! - ! local variables: - character(len=*), parameter :: subname = 'harvestData::num1DFields' - !----------------------------------------------------------------------- - num1DFields = count( this%dims2nd == 0) - end function num1DFields + call mpi_reduce(local_i, global_i, numharv, MPI_REAL8, MPI_SUM, 0, mpicom, ier) - !================================================================================= - integer function num2DFields( this ) - ! - ! Returns the number of 2D fields - ! - ! input/output variables: - class(harvestDataType), intent(in) :: this ! harvestData object - ! - ! local variables: - character(len=*), parameter :: subname = 'harvestData::num2DFields' - !----------------------------------------------------------------------- - - num2DFields = count( this%dims2nd /= 0) - end function num2DFields - - - !================================================================================= - logical function mkharvest_fieldInBounds( nfield ) - ! - ! Return true if field index is in bounds and initialization done - ! - ! input/output variables: - integer, intent(in) :: nfield ! field index - ! - ! local variables: - character(len=*), parameter :: subname = 'mkharvest_fieldInBounds' - !----------------------------------------------------------------------- - - if ( nfield < 1 )then - write(6,*) subname, ' ERROR nfield < 1' - mkharvest_fieldInBounds = .false. - else if ( nfield > numharv )then - write(6,*) subname, ' ERROR nfield > max fields' - mkharvest_fieldInBounds = .false. - else if ( .not. initialized ) then - write(6,*) subname, ' ERROR mkharvest NOT initialized yet!' - mkharvest_fieldInBounds = .false. - else - mkharvest_fieldInBounds = .true. - end if - - end function mkharvest_fieldInBounds - - !================================================================================= - character(len=harlen) function mkharvest_fieldname( nfield, constant ) - ! - ! Return harvest fieldname of input field number. - ! - ! input/output variables: - integer, intent(in) :: nfield - logical, intent(in), optional :: constant - ! - ! local variables: - character(len=*), parameter :: subname = 'mkharvest_fieldname' - logical :: lconstant ! local version of constant flag - !----------------------------------------------------------------------- - lconstant = .false. - if ( present(constant) ) lconstant = constant - - if ( mkharvest_fieldInBounds( nfield ) )then - if ( .not. lconstant )then - mkharvest_fieldname = harvest_fieldnames(nfield) - else - mkharvest_fieldname = harvest_const_fieldnames(nfield) - end if - else - call shr_sys_abort() - end if - - end function mkharvest_fieldname - - !================================================================================= - character(len=CL) function mkharvest_units( nfield ) - ! - ! Return units description of harvest fields - ! - ! input/output variables: - integer, intent(in) :: nfield - - ! local variables: - character(len=*), parameter :: subname = 'mkharvest_units' - !----------------------------------------------------------------------- - - if ( mkharvest_fieldInBounds( nfield ) )then - mkharvest_units = harvest_units(nfield) - else - call shr_sys_abort() - end if - - end function mkharvest_units - - !================================================================================= - character(len=CL) function mkharvest_longname( nfield ) - ! - ! Return longname description of given input field number. - - ! input/output variables: - integer, intent(in) :: nfield - ! - ! local variables: - character(len=*), parameter :: subname = 'mkharvest_longname' - !----------------------------------------------------------------------- - - if ( mkharvest_fieldInBounds( nfield ) )then - mkharvest_longname = harvest_longnames(nfield) - else - call shr_sys_abort() - end if - - end function mkharvest_longname - - !================================================================================= - integer function mkharvest_numtypes( ) - ! - ! Return number of different harvest field types. - ! - ! input/output variables: - character(len=*), parameter :: subname = 'mkharvest_numtypes' - - ! local variables: - !----------------------------------------------------------------------- - mkharvest_numtypes = numharv - - end function mkharvest_numtypes - - !================================================================================= - subroutine clean( this ) - ! - ! Clean and deallocate the harvestData object - ! - ! input/output variables: - class(harvestDataType), intent(inout) :: this ! harvestData object - ! - ! local variables: - character(len=*), parameter :: subname = 'harvestData::clean' - !----------------------------------------------------------------------- + ! Output grid global area + local_o(:) = 0. + do no = 1,ns_o + do k = 1, this%num1Dfields() + m = ind1D(k) + data1D_o => this%get1DFieldPtr( m, output=.true. ) + local_o(m) = local_o(m) + data1D_o(no) * area_o(no) * frac_o(no) + end do + end do + call mpi_reduce(local_o, global_o, numharv, MPI_REAL8, MPI_SUM, 0, mpicom, ier) + + ! Comparison + write (ndiag,*) + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,101) unit, unit +101 format (1x,'harvest type ',20x,' input grid area',' output grid area',/ & + 1x,33x,' ',A,' ',A) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + do k = 1, this%num1Dfields() + m = ind1D(k) + write (ndiag,102) mkharvest_fieldname(m), global_i(m)*rat, global_o(m)*rat + end do +102 format (1x,a35,f16.3,f17.3) - this%CFTdimsize = -1 - this%PFTdimsize = -1 - - if ( associated(this%data1D) ) deallocate( this%data1D ) - if ( associated(this%Outdata1D) ) deallocate( this%OutData1D ) - - if ( associated(this%data2DCFT) ) deallocate( this%data2DCFT ) - if ( associated(this%OutData2DCFT)) deallocate( this%OutData2DCFT ) - if ( associated(this%data2DPFT ) ) deallocate( this%data2DPFT ) - if ( associated(this%OutData2DPFT)) deallocate( this%OutData2DPFT ) - this%data2DCFT => null() - this%OutData2DCFT => null() - this%data2DPFT => null() - this%OutData2DPFT => null() - end subroutine clean + end subroutine check_global_sums end module mkharvestMod diff --git a/tools/mksurfdata_esmf/src/mklaiMod.F90 b/tools/mksurfdata_esmf/src/mklaiMod.F90 index 0c2720b6f2..d54ecd375e 100644 --- a/tools/mksurfdata_esmf/src/mklaiMod.F90 +++ b/tools/mksurfdata_esmf/src/mklaiMod.F90 @@ -1,4 +1,5 @@ module mklaiMod + !----------------------------------------------------------------------- ! Make LAI/SAI/height data !----------------------------------------------------------------------- @@ -9,8 +10,7 @@ module mklaiMod use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem use mkpioMod , only : mkpio_get_rawdata, mkpio_get_rawdata_level - use mkpioMod , only : mkpio_def_spatial_var, mkpio_iodesc_output, mkpio_iodesc_rawdata - use mkpioMod , only : mkpio_put_time_slice + use mkpioMod , only : mkpio_iodesc_output, mkpio_iodesc_rawdata, mkpio_put_time_slice use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas use mkutilsMod , only : chkerr use mkpftConstantsMod , only : c3cropindex, c3irrcropindex @@ -85,9 +85,7 @@ subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) end if ! Open input data file - call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) - call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) @@ -164,24 +162,6 @@ subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) call mkpio_iodesc_rawdata(mesh_i, 'MONTHLY_LAI', pioid_i, pio_varid_i, pio_vartype_i, pio_iodesc_i, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Put output file back in define mode, define variables and then end define mode - if ( outnc_double ) then - xtype = PIO_DOUBLE - else - xtype = PIO_REAL - end if - - rcode = pio_redef(pioid_o) - call mkpio_def_spatial_var(pioid_o, 'MONTHLY_LAI', xtype, & - lev1name='lsmpft', lev2name='time', long_name='monthly leaf area index', units='unitless') - call mkpio_def_spatial_var(pioid_o, 'MONTHLY_SAI',xtype, & - lev1name='lsmpft', lev2name='time', long_name='monthly stem area index', units='unitless') - call mkpio_def_spatial_var(pioid_o, 'MONTHLY_HEIGHT_TOP', xtype, & - lev1name='lsmpft', lev2name='time',long_name='monthly height top', units='meters') - call mkpio_def_spatial_var(pioid_o, 'MONTHLY_HEIGHT_BOT', xtype, & - lev1name='lsmpft', lev2name='time', long_name='monthly height bottom', units='meters') - rcode = pio_enddef(pioid_o) - ! Create iodescriptor for a single level of the output data call mkpio_iodesc_output(pioid_o, mesh_o, 'MONTHLY_LAI', pio_iodesc_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for MONTHLY_LAI') diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 0ac49ee953..f6729d8f68 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -20,12 +20,11 @@ module mkpioMod public :: mkpio_iodesc_output public :: mkpio_wopen public :: mkpio_close + public :: mkpio_defvar public :: mkpio_def_spatial_var public :: mkpio_get_dimlengths public :: mkpio_put_time_slice - private :: mkpio_defvar - interface mkpio_get_rawdata_level module procedure mkpio_get_rawdata1d_level_real4 module procedure mkpio_get_rawdata1d_level_real8 diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 61a22525cb..e4ba5415e1 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -93,17 +93,18 @@ program mksurfdata use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs use shr_sys_mod , only : shr_sys_abort #ifdef TODO - use mkharvestMod , only : mkharvest, mkharvest_init, mkharvest_fieldname - use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride, harvestDataType use mktopostatsMod , only : mktopostats use mkVICparamsMod , only : mkVICparams #endif + ! use mkharvestMod , only : mkharvest, mkharvest_init, mkharvest_fieldname + ! use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride, harvestDataType use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft use mkdomainMod , only : mkdomain use mkgdpMod , only : mkgdp use mkagfirepkmonthMod , only : mkagfirepkmon + use mklaiMod , only : mklai use mkpeatMod , only : mkpeat use mkvocefMod , only : mkvocef use mkglcmecMod , only : mkglcmecInit, mkglcmec, mkglacier, nglcec @@ -116,7 +117,8 @@ program mksurfdata use mklanwatMod , only : mklakwat use mkorganicMod , only : mkorganic use mkutilsMod , only : normalize_classes_by_gcell, chkerr - use mkfileMod , only : mkfile_fsurdat + use mkfileMod , only : mkfile_define_dims, mkfile_define_atts, mkfile_define_vars + use mkfileMod , only : mkfile_fdyndat, mkfile_output use mkvarpar , only : nlevsoi, elev_thresh, numstdpft use nanMod , only : nan, bigint use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem @@ -153,7 +155,6 @@ program mksurfdata real(r8), allocatable :: lat(:) real(r8), allocatable :: landfrac_pft(:) ! PFT data: % land per gridcell real(r8), allocatable :: pctlnd_pft(:) ! PFT data: % of gridcell for PFTs - real(r8), allocatable :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs integer , allocatable :: pftdata_mask(:) ! mask indicating real or fake land type type(pct_pft_type), allocatable :: pctnatpft(:) ! % of grid cell that is nat veg, and breakdown into PFTs type(pct_pft_type), allocatable :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series @@ -197,8 +198,6 @@ program mksurfdata real(r8), allocatable :: topo_stddev(:) ! standard deviation of elevation (m) real(r8), allocatable :: slope(:) ! topographic slope (degrees) real(r8), allocatable :: vic_binfl(:) ! VIC b - - ! parameters (unitless) real(r8), allocatable :: vic_ws(:) ! VIC Ws parameter (unitless) real(r8), allocatable :: vic_dsmax(:) ! VIC Dsmax parameter (mm/day) real(r8), allocatable :: vic_ds(:) ! VIC Ds parameter (unitless) @@ -208,9 +207,7 @@ program mksurfdata logical :: zero_out_lake ! if should zero glacier out logical :: zero_out_wetland ! if should zero glacier out logical :: zero_out -#ifdef TODO - type(harvestDataType) :: harvdata -#endif + !type(harvestDataType) :: harvdata ! esmf variables integer :: rc @@ -319,35 +316,95 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() ! ---------------------------------------------------------------------- - ! Read in and interpolate surface data set fields + ! Create netCDF surface dataset ! ---------------------------------------------------------------------- - ! Call module initialization routines - allocate ( elevclass(nglcec+1) ) - call mkglcmecInit (elevclass) + ! Initialize urban dimensions (needed to initialize the dimensions in fsurdat) call mkurbanInit (mksrf_furban) + ! Initialize pft/cft dimensions (needed to initialize the dimensions in fsurdat) + call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) + + ! If fsurdat is blank, then we do not write a surface dataset - but we may still + ! write a dynamic landuse file. This is useful if we are creating many datasets at + ! once, and don't want duplicate surface datasets. + ! + ! TODO(wjs, 2016-01-26) Ideally, we would also avoid doing the processing of + ! variables that are just needed by the surface dataset (not by the dynamic landuse + ! file). However, this would require some analysis of the above code, to determine + ! which processing is needed (directly or indirectly) in order to create a dynamic + ! landuse file. + + ! Open fsurdat and write out variables + if (fsurdat == ' ') then + if (root_task) then + write (ndiag,'(a)') ' fsurdat is blank: skipping writing surface dataset' + end if + else + if (root_task)then + write(ndiag,'(a)')"Calling fsurdat "//trim(fsurdat) + end if + + ! Open file + ! TODO: what about setting no fill values? + call mkpio_wopen(trim(fsurdat), clobber=.true., pioid=pioid) + + ! Define dimensions + call mkfile_define_dims(pioid, nx=mksrf_fgrid_mesh_nx, ny=mksrf_fgrid_mesh_ny, dynlanduse=.false.) + + ! Define global attributes + call mkfile_define_atts(pioid, dynlanduse = .false.) + + ! Define variables + call mkfile_define_vars(pioid, dynlanduse = .false.) + rcode = pio_enddef(pioid) + end if + + ! ----------------------------------- ! Make lats/lons of model + ! ----------------------------------- allocate (lon(lsize_o)) ; lon(:) = spval allocate (lat(lsize_o)) ; lat(:) = spval call mkdomain(mesh_model, lon_o=lon, lat_o=lat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out model grid" + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" + call mkfile_output(pioid, mesh_model, 'LONGXY', lon, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LATIXY" + call mkfile_output(pioid, mesh_model, 'LATIXY', lat, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + end if + ! ----------------------------------- ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] + ! ----------------------------------- ! Determine fractional land from pft dataset - allocate ( landfrac_pft(lsize_o)) ; landfrac_pft(:) = spval allocate ( pctlnd_pft(lsize_o)) ; pctlnd_pft(:) = spval - allocate ( pftdata_mask(lsize_o)) ; pftdata_mask(:) = -999 allocate ( pctnatpft(lsize_o)) ; - allocate ( pctnatpft_max(lsize_o)) ; allocate ( pctcft(lsize_o)) ; - allocate ( pctcft_max(lsize_o)) ; - call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) call mkpft( mksrf_fvegtyp_mesh, mksrf_fvegtyp, mesh_model, & pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') + if (fsurdat /= ' ') then + ! rcode = pio_inq_varid(pio_ 'PCT_NATVEG', pio_varid) + ! call mkfile_output(pioid, mesh_model, pio_varid, get_pct_l2g_array(pctnatpft), rc=rc) + ! rcode = pio_inq_varid(ncid, 'PCT_CROP', pio_varid) + ! call mkfile_output(pioid, mesh_model, pio_varid, get_pct_l2g_array(pctcft), rc=rc) + ! rcode = pio_inq_varid(ncid, 'PCT_NAT_PFT', pio_varid) + ! call mkfile_output(pioid, mesh_model, pio_varid, get_pct_p2l_array(pctnatpft), rc=rc) + ! if (num_cft > 0) then + ! rcode = pio_inq_varid(ncid, 'PCT_CFT', varid) + ! call mkfile_output(pioid, mesh_model, pio_varid, get_pct_p2l_array(pctcft), rc=rc) + ! end if + end if + ! ----------------------------------- ! Set landfrac_pft and pftdata_mask + ! ----------------------------------- + allocate ( pftdata_mask(lsize_o)) ; pftdata_mask(:) = -999 + allocate ( landfrac_pft(lsize_o)) ; landfrac_pft(:) = spval do n = 1,lsize_o landfrac_pft(n) = pctlnd_pft(n)/100._r8 if (pctlnd_pft(n) < 1.e-6_r8) then @@ -360,21 +417,34 @@ program mksurfdata !call pctcft(n)%set_pct_l2g(0._r8) end if end do + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing land mask from pft dataset" + call mkfile_output(pioid, mesh_model, 'PFTDATA_MASK', pftdata_mask, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid) + end if - ! Create harvesting data at model resolution + ! ----------------------------------- + ! Create constant harvesting data at model resolution + ! ----------------------------------- ! if (all_veg) then - ! ! In this case, we don't call mkharvest, so we want the harvest variables to be - ! ! initialized reasonably. + ! ! In this case, we don't call mkharvest, but want the harvest + ! ! variables to be initialized reasonably. ! harvest_initval = 0._r8 ! else ! harvest_initval = spval ! end if - ! call mkharvest_init( lsize_o, harvest_initval, harvdata, mksrf_fhrvtyp ) - ! if ( .not. all_veg )then - ! call mkharvest( mapfname=map_fharvest, datfname=mksrf_fhrvtyp, ndiag=ndiag, harvdata=harvdata ) + ! call mkharvest_init(mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, & + ! init_val=harvest_initval, harvdata=harvdata, constant=.true., rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') + ! if (.not. all_veg )then + ! call mkharvest( mksrf_fhrvtyp, mesh_model, harvdata=harvdata, constant=.true., rc=rc ) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') ! end if + ! ----------------------------------- ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] + ! ----------------------------------- allocate ( pctlak(lsize_o)) ; pctlak(:) = spval allocate ( pctwet(lsize_o)) ; pctwet(:) = spval allocate ( lakedepth(lsize_o)) ; lakedepth(:) = spval @@ -383,14 +453,35 @@ program mksurfdata call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') - call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out lakedepth" + call mkfile_output(pioid, mesh_model, 'LAKEDEPTH', lakedepth, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') +!DEBUG + call mkfile_output(pioid, mesh_model, 'PCT_LAKE', pctlak, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_wetland" + call mkfile_output(pioid, mesh_model, 'PCT_WETLAND', pctwet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') +!DEBUG + call pio_syncfile(pioid) + end if + deallocate (lakedepth ) + ! ----------------------------------- ! Make glacier fraction [pctgla] from [fglacier] dataset + ! ----------------------------------- allocate (pctgla(lsize_o)) ; pctgla(:) = spval zero_out = (all_urban .or. all_veg) if (.not. zero_out) then call mkglacier (mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, glac_o=pctgla, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacier') +!DEBUG + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glacier" + call mkfile_output(pioid, mesh_model, 'PCT_GLACIER', pctgla, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out percnt urban" +!DEBUG else if (root_task) then write (ndiag,'(a)') 'Attempting to make %glacier .....' @@ -399,12 +490,22 @@ program mksurfdata end if end if + ! ----------------------------------- ! Make glacier region ID [glacier_region] from [fglacierregion] dataset + ! ----------------------------------- allocate (glacier_region(lsize_o)) ; glacier_region(:) = -999 call mkglacierregion(mksrf_fglacierregion_mesh, mksrf_fglacierregion, mesh_model, glacier_region, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacierregion') + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out glacier_region" + call mkfile_output(pioid, mesh_model, 'GLACIER_REGION', glacier_region, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + end if + deallocate (glacier_region ) + ! ----------------------------------- ! Make soil texture [pctsand, pctclay] + ! ----------------------------------- ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero ! (not a very small number such as 1e-16) where it really should be zero allocate(mapunits(lsize_o)) ; mapunits(:) = 0 @@ -422,8 +523,21 @@ program mksurfdata pctclay(n,:) = 18._r8 end if end do + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" + call mkfile_output(pioid, mesh_model, 'PCT_SAND', pctsand, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" + call mkfile_output(pioid, mesh_model, 'PCT_CLAY', pctclay, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid) + end if + deallocate (pctsand) + deallocate (pctclay ) + ! ----------------------------------- ! Make soil color classes [soicol] [fsoicol] + ! ----------------------------------- allocate (soil_color(lsize_o)); soil_color(:) = -999 call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, soil_color, nsoilcol, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilcol') @@ -433,40 +547,105 @@ program mksurfdata soil_color(n) = 15 end if end do + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil color" + call mkfile_output(pioid, mesh_model, 'SOIL_COLOR', soil_color, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out mksoil_color" + rcode = pio_inq_varid(pioid, 'mxsoil_color', pio_varid) + rcode = pio_put_var(pioid, pio_varid, nsoilcol) + call pio_syncfile(pioid) + end if + deallocate (soil_color ) + ! ----------------------------------- ! Make soil fmax [fmaxsoil] + ! ----------------------------------- allocate(fmaxsoil(lsize_o)); fmaxsoil(:) = spval call mksoilfmax( mksrf_fmax_mesh, mksrf_fmax, mesh_model, fmaxsoil, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilfmax') + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil fmax (maximum fraction saturated area)" + call mkfile_output (pioid, mesh_model, 'FMAX', fmaxsoil, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid) + end if + deallocate (fmaxsoil ) + ! ----------------------------------- ! Make GDP data [gdp] from [gdp] + ! ----------------------------------- allocate (gdp(lsize_o)); gdp(:) = spval call mkgdp (mksrf_fgdp_mesh, mksrf_fgdp, mesh_model, gdp_o=gdp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out gdp" + call mkfile_output(pioid, mesh_model, 'gdp', gdp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid) + end if + deallocate(gdp) + ! ----------------------------------- ! Make peat data [fpeat] from [peatf] + ! ----------------------------------- allocate (fpeat(lsize_o)) ; fpeat(:) = spval call mkpeat (mksrf_fpeat_mesh, mksrf_fpeat, mesh_model, peat_o=fpeat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpeat') + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out peatland fraction" + call mkfile_output(pioid, mesh_model, 'peatf', fpeat, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid) + end if + deallocate(fpeat) + ! ----------------------------------- ! Make soil depth data [soildepth] from [soildepthf] + ! ----------------------------------- allocate ( soildepth(lsize_o)); soildepth(:) = spval call mksoildepth( mksrf_fsoildepth_mesh, mksrf_fsoildepth, mesh_model, soildepth, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoildepth') + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil depth" + call mkfile_output(pioid, mesh_model, 'zbedrock', soildepth, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid) + end if + deallocate (soildepth ) + ! ----------------------------------- ! Make agricultural fire peak month data [abm] from [abm] + ! ----------------------------------- allocate (agfirepkmon(lsize_o)); agfirepkmon(:) = -999 call mkagfirepkmon (mksrf_fabm_mesh, mksrf_fabm, mesh_model, agfirepkmon_o=agfirepkmon, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkagfirepkmon') + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing abm (agricultural fire peak month)" + call mkfile_output(pioid, mesh_model, 'abm', agfirepkmon, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid) + end if + deallocate(agfirepkmon) - ! Make urban fraction [pcturb] from [furban] dataset + ! ----------------------------------- + ! Make urban fraction [pcturb] from [furban] dataset and + ! ----------------------------------- allocate (pcturb(lsize_o)) ; pcturb(:) = spval allocate (urban_classes(lsize_o,numurbl)) ; urban_classes(:,:) = spval - allocate (urban_classes_g(lsize_o,numurbl)); urban_classes_g(:,:) = spval allocate (urban_region(lsize_o)) ; urban_region(:) = -999 call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, all_veg, pcturb, urban_classes, urban_region, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out urban region id" + call mkfile_output(pioid, mesh_model, 'URBAN_REGION_ID', urban_region, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid) + end if + ! Note that final values of urban are not set and written out until further down + ! Adjust pcturb ! Make elevation [elev] from [ftopo, ffrac] dataset ! Used only to screen pcturb, screen pcturb by elevation threshold from elev dataset if ( .not. all_urban .and. .not. all_veg )then @@ -484,14 +663,31 @@ program mksurfdata deallocate(elev) end if + ! ----------------------------------- + ! Make LAI and SAI from 1/2 degree data and write to surface dataset + ! Write to netcdf file is done inside mklai routine + ! ----------------------------------- + if (root_task) then + write(ndiag,'(a)')'calling mklai' + end if + call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid) + + ! ----------------------------------- ! TODO: ! Compute topography statistics [topo_stddev, slope] from [ftopostats] + ! ----------------------------------- ! allocate ( topo_stddev(lsize_o)) ; topo_stddev(:) = spval ! allocate ( slope(lsize_o)) ; slope(:) = spval ! call mktopostats ( mapfname=map_ftopostats, datfname=mksrf_ftopostats, & ! ndiag=ndiag, topo_stddev_o=topo_stddev, slope_o=slope, std_elev=std_elev) + ! deallocate(topo_stddev + ! deallocate(slope) + ! ----------------------------------- ! TODO: + ! ----------------------------------- ! Make VIC parameters [binfl, ws, dsmax, ds] from [fvic] ! if ( outnc_vic )then ! allocate ( vic_binfl(lsize_o)) ; vic_binfl(:) = spval @@ -500,9 +696,16 @@ program mksurfdata ! allocate ( vic_ds(lsize_o)) ; vic_ds(:) = spval ! call mkVICparams ( mapfname=map_fvic, datfname=mksrf_fvic, ndiag=ndiag, & ! binfl_o=vic_binfl, ws_o=vic_ws, dsmax_o=vic_dsmax, ds_o=vic_ds) + ! deallocate(vic_binfl) + ! deallocate(vic_ws) + ! deallocate(vic_dsmax) + ! deallocate(vic_ds) + ! deallocate(vic_binfl, vic_ws, vic_dsmax, vic_ds ) ! end if + ! ----------------------------------- ! Make organic matter density [organic] [forganic] + ! ----------------------------------- allocate ( organic(lsize_o,nlevsoi)); organic(:,:) = spval call mkorganic( mksrf_forganic_mesh, mksrf_forganic, mesh_model, organic, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') @@ -511,18 +714,42 @@ program mksurfdata organic(n,:) = 0._r8 end if end do + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil organic matter density" + call mkfile_output(pioid, mesh_model, 'ORGANIC', organic, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + end if + deallocate (organic ) + ! ----------------------------------- ! Make VOC emission factors for isoprene [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] + ! ----------------------------------- allocate (ef1_btr(lsize_o)) ; ef1_btr(:) = 0._r8 allocate (ef1_fet(lsize_o)) ; ef1_fet(:) = 0._r8 allocate (ef1_fdt(lsize_o)) ; ef1_fdt(:) = 0._r8 allocate (ef1_shr(lsize_o)) ; ef1_shr(:) = 0._r8 allocate (ef1_grs(lsize_o)) ; ef1_grs(:) = 0._r8 allocate (ef1_crp(lsize_o)) ; ef1_crp(:) = 0._r8 - call mkvocef ( mksrf_fvocef_mesh, mksrf_fvocef, mesh_model, & - ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & - ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkvocef') + if (fsurdat /= ' ') then + call mkvocef ( mksrf_fvocef_mesh, mksrf_fvocef, mesh_model, & + ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & + ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkvocef') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out voc emission factors" + call mkfile_output(pioid, mesh_model, 'EF1_BTR', ef1_btr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call mkfile_output(pioid, mesh_model, 'EF1_FET', ef1_fet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call mkfile_output(pioid, mesh_model, 'EF1_FDT', ef1_fdt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call mkfile_output(pioid, mesh_model, 'EF1_SHR', ef1_shr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call mkfile_output(pioid, mesh_model, 'EF1_GRS', ef1_grs, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call mkfile_output(pioid, mesh_model, 'EF1_CRP', ef1_crp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + end if + deallocate (ef1_btr, ef1_fet, ef1_fdt, ef1_shr, ef1_grs, ef1_crp ) ! TODO: ! Do landuse changes such as for the poles, etc. @@ -567,12 +794,27 @@ program mksurfdata end if end do + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glacier" + call mkfile_output(pioid, mesh_model, 'PCT_GLACIER', pctgla, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_lake" + call mkfile_output(pioid, mesh_model, 'PCT_LAKE', pctlak, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_wetland" + call mkfile_output(pioid, mesh_model, 'PCT_WETLAND', pctwet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + end if + ! ---------------------------------------------------------------------- ! TODO: ! call normalizencheck_landuse() + ! ---------------------------------------------------------------------- + ! ---------------------------------------------------------------------- ! TODO: ! Write out sum of PFT's + ! ---------------------------------------------------------------------- ! do k = natpft_lb,natpft_ub ! suma = 0._r8 ! do n = 1,lsize_o @@ -591,16 +833,39 @@ program mksurfdata ! enddo ! if (root_task) write(ndiag,*) - ! Make final values of percent urban by class + + ! ----------------------------------- + ! Make final values of percent urban by class and compute urban parameters + ! ----------------------------------- + ! This call needs to occur after all corrections are made to pcturb + allocate (urban_classes_g(lsize_o,numurbl)); urban_classes_g(:,:) = spval call normalize_classes_by_gcell(urban_classes, pcturb, urban_classes_g) + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out percnt urban" + call mkfile_output(pioid, mesh_model, 'PCT_URBAN', urban_classes_g, lev1name='numurbl', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + + ! Now Make Urban Parameters from raw input data and write to surface dataset + ! Write to netcdf file is done inside mkurbanpar routine + call mkurbanpar(mksrf_furban, pioid, mesh_model, urban_region, urban_classes_g, & + urban_skip_abort_on_invalid_data_check) + + deallocate(pcturb) + deallocate(urban_classes) + deallocate(urban_region) ! ---------------------------------------------------------------------- ! Make glacier multiple elevation classes [pctglcmec,topoglcmec] from [fglacier] dataset ! ---------------------------------------------------------------------- ! This call needs to occur after pctgla has been adjusted for the final time - + allocate ( elevclass(nglcec+1) ) + call mkglcmecInit (elevclass) + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out GLC_MEC" + rcode = pio_inq_varid(pioid, 'GLC_MEC', pio_varid) + rcode = pio_put_var(pioid, pio_varid, elevclass) + end if allocate ( pctglcmec(lsize_o,nglcec)) ; pctglcmec(:,:) = spval allocate ( topoglcmec(lsize_o,nglcec)) ; topoglcmec(:,:)= spval if ( outnc_3dglc )then @@ -620,276 +885,61 @@ program mksurfdata pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglcmec') end if - - ! ---------------------------------------------------------------------- - ! Create netCDF surface dataset - ! ---------------------------------------------------------------------- - - ! If fsurdat is blank, then we do not write a surface dataset - but we may still - ! write a dynamic landuse file. This is useful if we are creating many datasets at - ! once, and don't want duplicate surface datasets. - ! - ! TODO(wjs, 2016-01-26) Ideally, we would also avoid doing the processing of - ! variables that are just needed by the surface dataset (not by the dynamic landuse - ! file). However, this would require some analysis of the above code, to determine - ! which processing is needed (directly or indirectly) in order to create a dynamic - ! landuse file. - - if (fsurdat == ' ') then - if (root_task) then - write (ndiag,'(a)') ' fsurdat is blank: skipping writing surface dataset' - end if - else - if (root_task)then - write(ndiag,'(a)')"Calling mkfile_fsurdat" + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec" + call mkfile_output(pioid, mesh_model, 'PCT_GLC_MEC', pctglcmec, lev1name='nglcec', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out topo_glc_mec" + call mkfile_output(pioid, mesh_model, 'TOPO_GLC_MEC', topoglcmec, lev1name='nglcec', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (outnc_3dglc ) then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec_gic" + call mkfile_output(pioid, mesh_model, 'PCT_GLC_MEC_GIC', pctglcmec_gic, lev1name='nglcec', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec_icesheet" + call mkfile_output(pioid, mesh_model, 'PCT_GLC_MEC_ICESHEET', pctglcmec_icesheet, lev1name='nglcec', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_gic" + call mkfile_output(pioid, mesh_model, 'PCT_GLC_GIC', pctglc_gic, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_icesheet" + call mkfile_output(pioid, mesh_model, 'PCT_GLC_ICESHEET', pctglc_icesheet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') end if - call mkfile_fsurdat( nx=mksrf_fgrid_mesh_nx, & - ny=mksrf_fgrid_mesh_ny, & - mesh_o=mesh_model, & - lon=lon, & - lat=lat, & - dynlanduse=.false., & - pctlak=pctlak, & - pctwet=pctwet, & - lakedepth=lakedepth, & - organic=organic, & - soil_color=soil_color, & - nsoilcol=nsoilcol, & - urban_classes_g=urban_classes_g, & - urban_region=urban_region, & - pctsand=pctsand, & - pctclay=pctclay, & - mapunits=mapunits, & - fmaxsoil=fmaxsoil, & - soildepth=soildepth, & - glacier_region=glacier_region, & - ef_btr=ef1_btr, & - ef_fet=ef1_fet, & - ef_fdt=ef1_fdt, & - ef_shr=ef1_shr, & - ef_grs=ef1_grs, & - ef_crp=ef1_crp, & - elevclass=elevclass, & - pctgla=pctgla, & - pctglcmec=pctglcmec, & - topoglcmec=topoglcmec, & - pctglcmec_gic=pctglcmec_gic, & - pctglcmec_icesheet=pctglcmec_icesheet, & - pctglc_gic=pctglc_gic, & - pctglc_icesheet=pctglc_icesheet, & - fpeat=fpeat, & - agfirepkmon=agfirepkmon, & - gdp=gdp, & - rc=rc) - if (root_task) then - write(ndiag,*) - write(ndiag,'(a)')'successfully created file '//trim(fsurdat) - end if - - end if ! if (fsurdat /= ' ') + end if + deallocate(pctglcmec) + deallocate(topoglcmec) + deallocate(elevclass ) + if (outnc_3dglc) then + deallocate(pctglcmec_gic) + deallocate(pctglcmec_icesheet) + deallocate (pctglc_gic) + deallocate (pctglc_icesheet) + end if ! ---------------------------------------------------------------------- - ! Deallocate arrays NOT needed for dynamic-pft section of code + ! Close surface dataset ! ---------------------------------------------------------------------- - deallocate (organic ) - deallocate (ef1_btr, ef1_fet, ef1_fdt, ef1_shr, ef1_grs, ef1_crp ) - deallocate (lakedepth ) - deallocate (soil_color ) - deallocate (soildepth ) - deallocate (pctsand, pctclay ) - deallocate (glacier_region ) - deallocate (pctglcmec, topoglcmec) - deallocate (elevclass ) - deallocate (fmaxsoil ) - if (outnc_3dglc) then - deallocate (pctglc_gic, pctglc_icesheet) + call pio_closefile(pioid) + + if (root_task) then + write(ndiag,*) + write(ndiag,'(a)')'successfully created file '//trim(fsurdat) end if - deallocate(fpeat) - deallocate(gdp) -#ifdef TODO - deallocate(agfirepkmon) - deallocate(topo_stddev - deallocate(slope) - deallocate(vic_binfl) - deallocate(vic_ws) - deallocate(vic_dsmax) - deallocate(vic_ds) - deallocate(vic_binfl, vic_ws, vic_dsmax, vic_ds ) - call harvdata%clean() -#endif ! ---------------------------------------------------------------------- ! Create dynamic land use dataset if appropriate ! ---------------------------------------------------------------------- - if (mksrf_fdynuse /= ' '.and. fdyndat == ' ') then - call shr_sys_abort(' must specify fdyndat in namelist if mksrf_fdynuse is not blank') - end if - - if (mksrf_fdynuse /= ' ') then - - if (root_task) then - write(ndiag,'(a)')'creating dynamic land use dataset' - end if - - ! allocate(pctlnd_pft_dyn(lsize_o)) - ! call mkharvest_init( lsize_o, spval, harvdata, mksrf_fhrvtyp ) - - ! Define dimensions and global attributes - - ! call mkfile( fdyndat, harvdata, dynlanduse=.true., pioid) - - ! ! Write fields other pft to dynamic land use dataset - - ! call domain_write( fdyndat) - - ! rcode = pio_open(trim(fdyndat), nf_write, pioid)) - ! rcode = pio_set_fill (pioid, nf_nofill, omode)) - - ! rcode = pio_inq_varid(pioid, 'natpft', pio_varid)) - ! rcode = pio_put_var_int(pioid, pio_varid, (/(n,n=natpft_lb,natpft_ub)/)) - - ! if (num_cft > 0) then - ! rcode = pio_inq_varid(pioid, 'cft', pio_varid)) - ! rcode = pio_put_var_int(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/) + ! allocate ( pctcft_max(lsize_o)) ; + ! allocate ( pctnatpft_max(lsize_o)) ; + ! if (mksrf_fdynuse) then + ! if (fdyndat == ' ') then + ! call shr_sys_abort(' must specify fdyndat in namelist if mksrf_fdynuse is not blank') ! end if - - ! rcode = pio_inq_varid(pioid, 'PFTDATA_MASK', pio_varid)) - ! rcode = pio_put_var_int(pioid, pio_varid, pftdata_mask)) - - ! rcode = pio_inq_varid(pioid, 'LANDFRAC_PFT', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, landfrac_pft)) - - ! ! Synchronize the disk copy of a netCDF dataset with in-memory buffers - - ! rcode = pio_sync(pioid)) - - ! ! Read in each dynamic pft landuse dataset - - ! call opnfil (newunit=nfdyn, mksrf_fdynuse, nfdyn, 'f') - - ! pctnatpft_max = pctnatpft - ! pctcft_max = pctcft - - ! ntim = 0 - ! do - ! ! Read input pft data - - ! read(nfdyn, '(A195,1x,I4)', iostat=ier) string, year - ! if (ier /= 0) exit - ! ! - ! ! If pft fraction override is set, than intrepret string as PFT and harvesting override values - ! ! - ! if ( all_veg )then - ! fname = ' ' - ! fhrvname = ' ' - ! call mkpft_parse_oride(string) - ! call mkharvest_parse_oride(string) - ! write(6, '(a, i4, a)') 'PFT and harvesting values for year ', year, ' :' - ! write(6, '(a, a)') ' ', trim(string) - ! ! - ! ! Otherwise intrepret string as a filename with PFT and harvesting values in it - ! ! - ! else - ! fname = string - ! write(6,*)'input pft dynamic dataset for year ', year, ' is : ', trim(fname) - ! read(nfdyn, '(A195,1x,I4)', iostat=ier) fhrvname, year2 - ! if ( year2 /= year ) then - ! write(6,*) subname, ' error: year for harvest not equal to year for PFT files' - ! call shr_sys_abort() - ! end if - ! end if - ! ntim = ntim + 1 - - ! ! Create pctpft data at model resolution - - ! call mkpft( mapfname=map_fpft, fpft=fname, & - ! ndiag=ndiag, pctlnd_o=pctlnd_pft_dyn, pctnatpft_o=pctnatpft, pctcft_o=pctcft ) - - ! ! Create harvesting data at model resolution - - ! call mkharvest( mapfname=map_fharvest, datfname=fhrvname, & - ! ndiag=ndiag, harvdata=harvdata ) - - ! ! Consistency check on input land fraction - - ! do n = 1,lsize_o - ! if (pctlnd_pft_dyn(n) /= pctlnd_pft(n)) then - ! write(6,*) subname,' error: pctlnd_pft for dynamics data = ',& - ! pctlnd_pft_dyn(n), ' not equal to pctlnd_pft for surface data = ',& - ! pctlnd_pft(n),' at n= ',n - ! if ( trim(fname) == ' ' )then - ! write(6,*) ' PFT string = ', string - ! else - ! write(6,*) ' PFT file = ', fname - ! end if - ! call shr_sys_abort() - ! end if - ! end do - - ! call change_landuse( dynpft=.true.) - - ! call normalizencheck_landuse(ldomain) - - ! call update_max_array(pctnatpft_max,pctnatpft) - ! call update_max_array(pctcft_max,pctcft) - - ! ! Output time-varying data for current year - - ! rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT', pio_varid)) - ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_p2l_array(pctnatpft)) - - ! rcode = pio_inq_varid(pioid, 'PCT_CROP', pio_varid)) - ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_l2g_array(pctcft)) - - ! if (num_cft > 0) then - ! rcode = pio_inq_varid(pioid, 'PCT_CFT', pio_varid)) - ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_p2l_array(pctcft)) - ! end if - - ! call harvdata%getFieldsIdx( harvind1D, harvind2D ) - ! do k = 1, harvdata%num1Dfields() - ! rcode = pio_inq_varid(pioid, trim(mkharvest_fieldname(harvind1D(k),constant=.false.)), pio_varid)) - ! harvest1D => harvdata%get1DFieldPtr( harvind1D(k), output=.true. ) - ! call mkpio_put_time_slice(pioid, pio_varid, ntim, harvest1D) - ! end do - ! do k = 1, harvdata%num2Dfields() - ! rcode = pio_inq_varid(pioid, trim(mkharvest_fieldname(harvind2D(k),constant=.false.)), pio_varid)) - ! harvest2D => harvdata%get2DFieldPtr( harvind2D(k), output=.true. ) - ! call mkpio_put_time_slice(pioid, pio_varid, ntim, harvest2D) - ! end do - ! deallocate( harvind1D, harvind2D ) - - ! rcode = pio_inq_varid(pioid, 'YEAR', pio_varid)) - ! rcode = pio_put_vara_int(pioid, pio_varid, ntim, 1, year)) - - ! rcode = pio_inq_varid(pioid, 'time', pio_varid)) - ! rcode = pio_put_vara_int(pioid, pio_varid, ntim, 1, year)) - - ! rcode = pio_inq_varid(pioid, 'input_pftdata_filename', pio_varid)) - ! rcode = pio_put_vara_text(pioid, pio_varid, (/ 1, ntim /), (/ len_trim(string), 1 /), trim(string) )) - - ! ! Synchronize the disk copy of a netCDF dataset with in-memory buffers - - ! rcode = pio_sync(pioid)) - - ! end do ! end of read loop - - ! rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT_MAX', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_p2l_array(pctnatpft_max))) - - ! rcode = pio_inq_varid(pioid, 'PCT_CROP_MAX', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_l2g_array(pctcft_max))) - - ! if (num_cft > 0) then - ! rcode = pio_inq_varid(pioid, 'PCT_CFT_MAX', pio_varid)) - ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_p2l_array(pctcft_max))) - ! end if - - ! rcode = pio_closefile(pioid)) - - end if ! end of if-create dynamic landust dataset + ! call mkfile_fdyndat() + ! end if ! end of if-create dynamic landust dataset ! ---------------------------------------------------------------------- ! Close diagnostic dataset @@ -912,7 +962,7 @@ program mksurfdata !----------------------------------------------------------------------- contains !----------------------------------------------------------------------- - + subroutine change_landuse(dynpft) ! Do landuse changes such as for the poles, etc. diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index 349260a390..690dc93b2b 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -26,8 +26,6 @@ subroutine mktopostats(ldomain, mapfname, datfname, ndiag, topo_stddev_o, slope_ use mkchecksMod, only : min_bad, max_bad ! ! !ARGUMENTS: - - implicit none type(domain_type) , intent(in) :: ldomain character(len=*) , intent(in) :: mapfname ! input mapping file name character(len=*) , intent(in) :: datfname ! input data file name @@ -36,15 +34,7 @@ subroutine mktopostats(ldomain, mapfname, datfname, ndiag, topo_stddev_o, slope_ real(r8) , intent(out):: topo_stddev_o(:) ! output grid: standard deviation of elevation (m) real(r8) , intent(out):: slope_o(:) ! output grid: slope (degrees) ! - ! !CALLED FROM: - ! subroutine mksrfdat in module mksrfdatMod - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! - ! ! !LOCAL VARIABLES: - !EOP type(gridmap_type) :: tgridmap type(domain_type) :: tdomain ! local domain real(r8), allocatable :: data_i(:) ! data on input grid @@ -83,7 +73,7 @@ subroutine mktopostats(ldomain, mapfname, datfname, ndiag, topo_stddev_o, slope_ ! dst_array(no) = dst_array(no) + wt * (src_array(ni) - weighted_means(no))**2 part, ! and then just do a plain sparse matrix multiply on a src Field of all 1.0 to do the ! weight sum part, and then do the divide and sqrt locally on each PET. - + ! One issue is how to get the weight_means() in for each ! dest. location. I think that you could pass them in via the ! dst_array and then pull them out before doing the calculation, but @@ -92,79 +82,79 @@ subroutine mktopostats(ldomain, mapfname, datfname, ndiag, topo_stddev_o, slope_ ! zeroregion=ESMF_REGION_EMPTY.This would also depend on the ! calculation happening only once for each destination location, ! which I would guess is true, but Gerhard can confirm. - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write(6,*)'Open Topography file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(data_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() - - ! ----------------------------------------------------------------- - ! Make topography standard deviation - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'ELEVATION', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areastddev(tgridmap, data_i, topo_stddev_o, nodata=0._r8) - - call output_diagnostics_continuous_outonly(topo_stddev_o, tgridmap, "Topo Std Dev", "m", ndiag) - else - write (6,*) ' Set std deviation of topography to ', std_elev - topo_stddev_o = std_elev - end if - - ! Check validity of output data - if (min_bad(topo_stddev_o, min_valid_topo_stddev, 'topo_stddev')) then - call abort() - end if - ! ----------------------------------------------------------------- - ! Regrid slope + ! Open input file, allocate memory for input data ! ----------------------------------------------------------------- - if ( .not. bypass_reading )then - call check_ret(nf_inq_varid (ncid, 'SLOPE', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - - ! Subr. gridmap_areaave_no_srcmask should NOT be used in general. We have - ! kept it to support the rare raw data files for which we have masking on - ! the mapping file and, therefore, we do not explicitly pass the src_mask - ! as an argument. In general, users are advised to use subroutine - ! gridmap_areaave_srcmask. - call gridmap_areaave_no_srcmask(tgridmap, data_i, slope_o, nodata=0._r8) - - call output_diagnostics_continuous(data_i, slope_o, tgridmap, "Slope", "degrees", ndiag, tdomain%mask, tgridmap%frac_dst) - else - write (6,*) ' Set slope of topography to ', 0.0_r8 - slope_o = 0.0_r8 - end if - ! Check validity of output data - if (min_bad(slope_o, min_valid_slope, 'slope') .or. & - max_bad(slope_o, max_valid_slope, 'slope')) then - call abort() - end if + write(6,*)'Open Topography file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + allocate(data_i(tdomain%ns), stat=ier) + if (ier/=0) call abort() ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory + ! Make topography standard deviation ! ----------------------------------------------------------------- - if ( .not. bypass_reading )then - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (data_i) - end if - - write (6,*) 'Successfully made Topography statistics' - write (6,*) - - end subroutine mktopostats + call check_ret(nf_inq_varid (ncid, 'ELEVATION', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + call gridmap_areastddev(tgridmap, data_i, topo_stddev_o, nodata=0._r8) + + call output_diagnostics_continuous_outonly(topo_stddev_o, tgridmap, "Topo Std Dev", "m", ndiag) + else + write (6,*) ' Set std deviation of topography to ', std_elev + topo_stddev_o = std_elev + end if + + ! Check validity of output data + if (min_bad(topo_stddev_o, min_valid_topo_stddev, 'topo_stddev')) then + call abort() + end if + + + ! ----------------------------------------------------------------- + ! Regrid slope + ! ----------------------------------------------------------------- + + if ( .not. bypass_reading )then + call check_ret(nf_inq_varid (ncid, 'SLOPE', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + + ! Subr. gridmap_areaave_no_srcmask should NOT be used in general. We have + ! kept it to support the rare raw data files for which we have masking on + ! the mapping file and, therefore, we do not explicitly pass the src_mask + ! as an argument. In general, users are advised to use subroutine + ! gridmap_areaave_srcmask. + call gridmap_areaave_no_srcmask(tgridmap, data_i, slope_o, nodata=0._r8) + + call output_diagnostics_continuous(data_i, slope_o, tgridmap, "Slope", "degrees", ndiag, tdomain%mask, tgridmap%frac_dst) + else + write (6,*) ' Set slope of topography to ', 0.0_r8 + slope_o = 0.0_r8 + end if + ! Check validity of output data + if (min_bad(slope_o, min_valid_slope, 'slope') .or. & + max_bad(slope_o, max_valid_slope, 'slope')) then + call abort() + end if + + + ! ----------------------------------------------------------------- + ! Close files and deallocate dynamic memory + ! ----------------------------------------------------------------- + + if ( .not. bypass_reading )then + call check_ret(nf_close(ncid), subname) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (data_i) + end if + + write (6,*) 'Successfully made Topography statistics' + write (6,*) + +end subroutine mktopostats !================================================================================================ subroutine dynMaskProc(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, rc) diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 0c6917fff7..d28ce76063 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -9,8 +9,7 @@ module mkurbanparMod use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkpioMod , only : mkpio_iodesc_output, mkpio_def_spatial_var, mkpio_wopen - use mkpioMod , only : mkpio_get_dimlengths, mkpio_get_rawdata + use mkpioMod , only : mkpio_iodesc_output, mkpio_get_dimlengths, mkpio_get_rawdata use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr @@ -595,101 +594,6 @@ subroutine mkurbanpar(datfname_i, pioid_o, mesh_o, & unity_dens_o(:,k) = k end do - if ( outnc_double ) then - xtype = PIO_DOUBLE - else - xtype = PIO_REAL - end if - - ! Put output file back in define mode and define urban parameter output variables - rcode = pio_redef(pioid_o) - - rcode = pio_def_dim(pioid_o, 'numrad' , numrad, dimid) - - call mkpio_def_spatial_var(pioid_o, varname='CANYON_HWR', xtype=xtype, & - lev1name='numurbl', long_name='canyon height to width ratio', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='EM_IMPROAD', xtype=xtype, & - lev1name='numurbl', long_name='emissivity of impervious road', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='EM_PERROAD', xtype=xtype, & - lev1name='numurbl', long_name='emissivity of pervious road', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='EM_ROOF', xtype=xtype, & - lev1name='numurbl', long_name='emissivity of roof', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='EM_WALL', xtype=xtype, & - lev1name='numurbl', long_name='emissivity of wall', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='HT_ROOF', xtype=xtype, & - lev1name='numurbl', long_name='height of roof', units='meters') - - call mkpio_def_spatial_var(pioid_o, varname='THICK_ROOF', xtype=xtype, & - lev1name='numurbl', long_name='thickness of roof', units='meters') - - call mkpio_def_spatial_var(pioid_o, varname='THICK_WALL', xtype=xtype, & - lev1name='numurbl', long_name='thickness of wall', units='meters') - - call mkpio_def_spatial_var(pioid_o, varname='T_BUILDING_MIN', xtype=xtype, & - lev1name='numurbl', long_name='minimum interior building temperature', units='K') - - call mkpio_def_spatial_var(pioid_o, varname='WIND_HGT_CANYON', xtype=xtype, & - lev1name='numurbl', long_name='height of wind in canyon', units='meters') - - call mkpio_def_spatial_var(pioid_o, varname='WTLUNIT_ROOF', xtype=xtype, & - lev1name='numurbl', long_name='fraction of roof', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='WTROAD_PERV', xtype=xtype, & - lev1name='numurbl', long_name='fraction of pervious road', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='ALB_IMPROAD_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', long_name='direct albedo of impervious road', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='ALB_IMPROAD_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', long_name='diffuse albedo of impervious road', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='ALB_PERROAD_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', long_name='direct albedo of pervious road', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='ALB_PERROAD_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', long_name='diffuse albedo of pervious road', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='ALB_ROOF_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', long_name='direct albedo of roof', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='ALB_ROOF_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', long_name='diffuse albedo of roof', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='ALB_WALL_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', long_name='direct albedo of wall', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='ALB_WALL_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', long_name='diffuse albedo of wall', units='unitless') - - call mkpio_def_spatial_var(pioid_o, varname='TK_ROOF', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', long_name='thermal conductivity of roof', units='W/m*K') - - call mkpio_def_spatial_var(pioid_o, varname='TK_WALL', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', long_name='thermal conductivity of wall', units='W/m*K') - - call mkpio_def_spatial_var(pioid_o, varname='TK_IMPROAD', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', long_name='thermal conductivity of impervious road', units='W/m*K') - - call mkpio_def_spatial_var(pioid_o, varname='CV_ROOF', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', long_name='volumetric heat capacity of roof', units='J/m^3*K') - - call mkpio_def_spatial_var(pioid_o, varname='CV_WALL', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', long_name='volumetric heat capacity of wall', units='J/m^3*K') - - call mkpio_def_spatial_var(pioid_o, varname='CV_IMPROAD', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', long_name='volumetric heat capacity of impervious road', units='J/m^3*K') - - call mkpio_def_spatial_var(pioid_o, varname='NLEV_IMPROAD', xtype=PIO_INT, & - lev1name='numurbl', long_name='number of impervious road layers', units='unitless') - - ! End define model - rcode = pio_enddef(pioid_o) - ! ------------------------------------------------ ! Handle urban parameters with no extra dimensions ! ------------------------------------------------ From fffe11c9e14cc9ad4b29907fb66d102f46149d37 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 8 Feb 2022 22:36:45 -0700 Subject: [PATCH 048/614] changes to get mkharvest working --- .../gen_mksurfdata_namelist.py | 15 +- .../gen_mksurfdata_namelist.xml | 30 +- tools/mksurfdata_esmf/src/CMakeLists.txt | 25 +- tools/mksurfdata_esmf/src/mkVICparamsMod.F90 | 312 ++++++------- tools/mksurfdata_esmf/src/mkfileMod.F90 | 266 +---------- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 434 +++++++++--------- tools/mksurfdata_esmf/src/mklaiMod.F90 | 9 +- tools/mksurfdata_esmf/src/mkorganicMod.F90 | 7 +- tools/mksurfdata_esmf/src/mkpftMod.F90 | 1 - tools/mksurfdata_esmf/src/mksurfdata.F90 | 287 +++++++++--- 10 files changed, 652 insertions(+), 734 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index d30b41b2d9..7efb090cf7 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -258,9 +258,9 @@ def main (): model_mesh = child2.text rawdata_files["mksrf_fgrid_mesh"] = os.path.join(input_path,model_mesh.strip('$DIN_LOC_ROOT/')) if child2.tag == 'nx': - rawdata_files["mksrf_fgrid_nx"] = child2.text + rawdata_files["mksrf_fgrid_mesh_nx"] = child2.text if child2.tag == 'ny': - rawdata_files["mksrf_fgrid_ny"] = child2.text + rawdata_files["mksrf_fgrid_mesh_ny"] = child2.text if len(model_mesh) == 0: print (f"ERROR: input res {res} is invalid") @@ -317,14 +317,11 @@ def main (): fsurlog = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.log" fdyndat = f"landuse.timeseries_{res}_{ssp_rcp}_{num_pft}_CMIP6_{start_year}-{end_year}_c{time_stamp}.log" - # TODO: make this an input argument - create_esmf_pet_files = True - with open(nlfname, "w",encoding='utf-8') as nlfile: nlfile.write("&mksurfdata_input \n") for key,value in rawdata_files.items(): - if key == 'mksrf_fgrid_nx' or key == 'mksrf_fgrid_ny': + if key == 'mksrf_fgrid_mesh_nx' or key == 'mksrf_fgrid_mesh_ny': nlfile.write(f" {key} = {value} \n") elif key != "mksrf_fvic" and key != "mksrf_fvic_mesh": nlfile.write(f" {key} = \'{value}\' \n") @@ -347,10 +344,10 @@ def main (): nlfile.write(f" mksrf_fdynuse = \'{landuse_fname} \' \n") mksrf_vic = rawdata_files["mksrf_fvic"] - nlfile.write(f" use_vic = .{vic_flag}. \n") nlfile.write( " outnc_vic = .true. \n") - nlfile.write(f" use_glc = .{glc_flag}. \n") - nlfile.write(f" create_esmf_pet_files = .{create_esmf_pet_files}. \n") + #nlfile.write(f" use_vic = .{vic_flag}. \n") + #nlfile.write(f" use_glc = .{glc_flag}. \n") + #nlfile.write(f" create_esmf_pet_files = .{create_esmf_pet_files}. \n") nlfile.write("/ \n") if __name__ == "__main__": diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index ce09114b19..03853a97db 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -10,7 +10,7 @@ - lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.cdf5.c170413.nc + lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.cdf5.c220206.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc @@ -30,12 +30,12 @@ - - - lnd/clm2/rawdata/mksrf_irrig_2160x4320_simyr2000.c110527.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc - - + + + + + + @@ -145,7 +145,7 @@ version of the raw dataset will probably go away. - lnd/clm2/rawdata/mksrf_GlacierRegion_10x10min_nomask_c191120.nc + lnd/clm2/rawdata/mksrf_GlacierRegion_10x10min_nomask_cd5_c220131.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_cdf5_c200129.nc @@ -224,11 +224,21 @@ version of the raw dataset will probably go away. - + + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1850.c170629.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + + lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_1850.c190119.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc - + + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2005.c170629.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + + lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_2005.c190119.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 101e8146ea..93dc3eca15 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -16,34 +16,35 @@ string(REPLACE "-I" "" ESMF_F90COMPILEPATHS ${ESMF_F90COMPILEPATHS}) string(REPLACE " " ";" ESMF_F90COMPILEPATHS ${ESMF_F90COMPILEPATHS}) message("ESMF_F90COMPILEPATHS: ${ESMF_F90COMPILEPATHS}") -set(SRCFILES mkvarctl.F90 - mkvarpar.F90 - mkpioMod.F90 - mkfileMod.F90 - mkagfirepkmonthMod.F90 +set(SRCFILES mkagfirepkmonthMod.F90 + mkchecksMod.F90 + mkdiagnosticsMod.F90 mkdomainMod.F90 + mkesmfMod.F90 + mkfileMod.F90 mkgdpMod.F90 mkglacierregionMod.F90 mkglcmecMod.F90 + mkharvestMod.F90 + mkindexmapMod.F90 mklaiMod.F90 mklanwatMod.F90 mkorganicMod.F90 mkpeatMod.F90 - mkpftConstantsMod.F90 + mkpioMod.F90 mkpftMod.F90 - mkpftUtilsMod.F90 + mkpftConstantsMod.F90 mkpctPftTypeMod.F90 + mkpftUtilsMod.F90 mksoilcolMod.F90 mksoilfmaxMod.F90 mksoiltexMod.F90 mksoildepthMod.F90 mkurbanparMod.F90 - mkvocefMod.F90 - mkesmfMod.F90 mkutilsMod.F90 - mkchecksMod.F90 - mkdiagnosticsMod.F90 - mkindexmapMod.F90 + mkvarctl.F90 + mkvarpar.F90 + mkvocefMod.F90 nanMod.F90 shr_const_mod.F90 shr_kind_mod.F90 diff --git a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 index 9b43bd9274..ab59589c4f 100644 --- a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 @@ -1,197 +1,155 @@ module mkVICparamsMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkVICparamsMod -! -! !DESCRIPTION: -! make parameters for VIC -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -!----------------------------------------------------------------------- -! -! !USES: + !----------------------------------------------------------------------- + ! make parameters for VIC + !----------------------------------------------------------------------- + ! use shr_kind_mod, only : r8 => shr_kind_r8 - use mkdomainMod , only : domain_checksame + use shr_sys_mod , only : shr_sys_abort implicit none - private -! !PUBLIC MEMBER FUNCTIONS: public mkVICparams ! make VIC parameters -! -!EOP + !=============================================================== contains !=============================================================== -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkVICparams -! -! !INTERFACE: -subroutine mkVICparams(ldomain, mapfname, datfname, ndiag, & - binfl_o, ws_o, dsmax_o, ds_o) -! -! !DESCRIPTION: -! make VIC parameters -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_continuous - use mkchecksMod, only : min_bad -! -! !ARGUMENTS: - - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: binfl_o(:) ! output grid: VIC b parameter for the Variable Infiltration Capacity Curve (unitless) - real(r8) , intent(out):: ws_o(:) ! output grid: VIC Ws parameter for the ARNO curve (unitless) - real(r8) , intent(out):: dsmax_o(:) ! output grid: VIC Dsmax parameter for the ARNO curve (mm/day) - real(r8) , intent(out):: ds_o(:) ! output grid: VIC Ds parameter for the ARNO curve (unitless) -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: data_i(:) ! data on input grid - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - - real(r8), parameter :: min_valid_binfl = 0._r8 - real(r8), parameter :: min_valid_ws = 0._r8 - real(r8), parameter :: min_valid_dsmax = 0._r8 - real(r8), parameter :: min_valid_ds = 0._r8 - - character(len=32) :: subname = 'mkVICparams' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make VIC parameters.....' - - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - call domain_read(tdomain,datfname) - - call gridmap_mapread(tgridmap, mapfname ) - - ! Obtain frac_dst - allocate(frac_dst(ldomain%ns), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write(6,*)'Open VIC parameter file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(data_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() - - ! ----------------------------------------------------------------- - ! Regrid binfl - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'binfl', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, binfl_o, nodata=0.1_r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(binfl_o, min_valid_binfl, 'binfl')) then - call abort() - end if - - call output_diagnostics_continuous(data_i, binfl_o, tgridmap, "VIC b parameter", "unitless", ndiag, tdomain%mask, frac_dst) - - ! ----------------------------------------------------------------- - ! Regrid Ws - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'Ws', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, ws_o, nodata=0.75_r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(ws_o, min_valid_ws, 'Ws')) then - call abort() - end if - - call output_diagnostics_continuous(data_i, ws_o, tgridmap, "VIC Ws parameter", "unitless", ndiag, tdomain%mask, frac_dst) - - ! ----------------------------------------------------------------- - ! Regrid Dsmax - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'Dsmax', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, dsmax_o, nodata=10._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(dsmax_o, min_valid_dsmax, 'Dsmax')) then - call abort() - end if - - call output_diagnostics_continuous(data_i, dsmax_o, tgridmap, "VIC Dsmax parameter", "mm/day", ndiag, tdomain%mask, frac_dst) - - ! ----------------------------------------------------------------- - ! Regrid Ds - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'Ds', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, ds_o, nodata=0.1_r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(ds_o, min_valid_ds, 'Ds')) then - call abort() - end if + subroutine mkVICparams(ldomain, mapfname, datfname, ndiag, binfl_o, ws_o, dsmax_o, ds_o) + ! + ! make VIC parameters + ! + use mkdiagnosticsMod, only : output_diagnostics_continuous + use mkchecksMod, only : min_bad + ! + ! !ARGUMENTS: + character(len=*) , intent(in) :: datfname ! input data file name + integer , intent(in) :: ndiag ! unit number for diag out + real(r8) , intent(out):: binfl_o(:) ! output VIC b parameter for the Variable Infiltration Capacity Curve (unitless) + real(r8) , intent(out):: ws_o(:) ! output VIC Ws parameter for the ARNO curve (unitless) + real(r8) , intent(out):: dsmax_o(:) ! output VIC Dsmax parameter for the ARNO curve (mm/day) + real(r8) , intent(out):: ds_o(:) ! output VIC Ds parameter for the ARNO curve (unitless) + ! + ! !LOCAL VARIABLES: + real(r8), allocatable :: data_i(:) ! data on input grid + real(r8), allocatable :: frac_dst(:) ! output fractions + real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask + integer :: ncid,varid ! input netCDF id's + integer :: ier ! error status + real(r8), parameter :: min_valid_binfl = 0._r8 + real(r8), parameter :: min_valid_ws = 0._r8 + real(r8), parameter :: min_valid_dsmax = 0._r8 + real(r8), parameter :: min_valid_ds = 0._r8 + character(len=*), parameter :: subname = 'mkVICparams' + !----------------------------------------------------------------------- + + write (6,*) 'Attempting to make VIC parameters.....' + + ! ----------------------------------------------------------------- + ! Read domain and mapping information, check for consistency + ! ----------------------------------------------------------------- + + call domain_read(tdomain,datfname) + + call gridmap_mapread(tgridmap, mapfname ) + + ! Obtain frac_dst + allocate(frac_dst(ldomain%ns), stat=ier) + if (ier/=0) call abort() + call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) + + allocate(mask_r8(tdomain%ns), stat=ier) + if (ier/=0) call abort() + mask_r8 = tdomain%mask + call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) + + call domain_checksame( tdomain, ldomain, tgridmap ) + + ! ----------------------------------------------------------------- + ! Open input file, allocate memory for input data + ! ----------------------------------------------------------------- + + write(6,*)'Open VIC parameter file: ', trim(datfname) + call check_ret(nf_open(datfname, 0, ncid), subname) + + allocate(data_i(tdomain%ns), stat=ier) + if (ier/=0) call abort() + + ! ----------------------------------------------------------------- + ! Regrid binfl + ! ----------------------------------------------------------------- + + call check_ret(nf_inq_varid (ncid, 'binfl', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + call gridmap_areaave_srcmask(tgridmap, data_i, binfl_o, nodata=0.1_r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check validity of output data + if (min_bad(binfl_o, min_valid_binfl, 'binfl')) then + call abort() + end if + + call output_diagnostics_continuous(data_i, binfl_o, tgridmap, "VIC b parameter", "unitless", ndiag, tdomain%mask, frac_dst) + + ! ----------------------------------------------------------------- + ! Regrid Ws + ! ----------------------------------------------------------------- + + call check_ret(nf_inq_varid (ncid, 'Ws', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + call gridmap_areaave_srcmask(tgridmap, data_i, ws_o, nodata=0.75_r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check validity of output data + if (min_bad(ws_o, min_valid_ws, 'Ws')) then + call abort() + end if + + call output_diagnostics_continuous(data_i, ws_o, tgridmap, "VIC Ws parameter", "unitless", ndiag, tdomain%mask, frac_dst) + + ! ----------------------------------------------------------------- + ! Regrid Dsmax + ! ----------------------------------------------------------------- + + call check_ret(nf_inq_varid (ncid, 'Dsmax', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + call gridmap_areaave_srcmask(tgridmap, data_i, dsmax_o, nodata=10._r8, mask_src=tdomain%mask, frac_dst=frac_dst) + + ! Check validity of output data + if (min_bad(dsmax_o, min_valid_dsmax, 'Dsmax')) then + call abort() + end if + + call output_diagnostics_continuous(data_i, dsmax_o, tgridmap, "VIC Dsmax parameter", "mm/day", ndiag, tdomain%mask, frac_dst) + + ! ----------------------------------------------------------------- + ! Regrid Ds + ! ----------------------------------------------------------------- + + call check_ret(nf_inq_varid (ncid, 'Ds', varid), subname) + call check_ret(nf_get_var_double (ncid, varid, data_i), subname) + call gridmap_areaave_srcmask(tgridmap, data_i, ds_o, nodata=0.1_r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call output_diagnostics_continuous(data_i, ds_o, tgridmap, "VIC Ds parameter", "unitless", ndiag, tdomain%mask, frac_dst) + ! Check validity of output data + if (min_bad(ds_o, min_valid_ds, 'Ds')) then + call abort() + end if - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- + call output_diagnostics_continuous(data_i, ds_o, tgridmap, "VIC Ds parameter", "unitless", ndiag, tdomain%mask, frac_dst) - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (data_i) - deallocate (frac_dst) - deallocate (mask_r8) + ! ----------------------------------------------------------------- + ! Close files and deallocate dynamic memory + ! ----------------------------------------------------------------- - write (6,*) 'Successfully made VIC parameters' - write (6,*) + call check_ret(nf_close(ncid), subname) + call domain_clean(tdomain) + call gridmap_clean(tgridmap) + deallocate (data_i) + deallocate (frac_dst) + deallocate (mask_r8) -end subroutine mkVICparams + write (6,*) 'Successfully made VIC parameters' + write (6,*) + end subroutine mkVICparams end module mkVICparamsMod diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 0360f3cef0..c6dc2765fc 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -8,17 +8,15 @@ module mkfileMod use mkvarpar , only : nlevsoi, numrad, numstdpft use mkurbanparMod , only : numurbl, nlevurb, mkurbanpar use mkglcmecMod , only : nglcec - use mklaiMod , only : mklai + use mklaiMod , only : mklai use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft, num_natpft use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array - !use mkharvestMod , only : mkharvest_fieldname, mkharvest_numtypes, mkharvest_longname, mkharvest_units, harvestDataType use mkpioMod ! TODO: add only use mkvarctl implicit none private - public :: mkfile_fdyndat public :: mkfile_define_dims public :: mkfile_define_atts public :: mkfile_define_vars @@ -38,247 +36,6 @@ module mkfileMod contains !================================================================================= - subroutine mkfile_fdyndat(nx, ny, mesh_o, ns_o, lon, lat, rc) - - ! input/output variables - integer , intent(in) :: nx - integer , intent(in) :: ny - type(ESMF_Mesh) , intent(in) :: mesh_o - integer , intent(in) :: ns_o - real(r8) , intent(in) :: lon(:) - real(r8) , intent(in) :: lat(:) - integer , intent(out) :: rc - - ! local variables - type(file_desc_t) :: pioid_o - type(var_desc_t) :: pio_varid_o - type(file_desc_t) :: pioid_i - type(var_desc_t) :: pio_varid_i - real(r8), allocatable :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs - character(len=256) :: varname - character(len=256) :: longname - character(len=256) :: units - integer :: xtype ! external type - integer :: dimid - logical :: define_mode - character(len=256) :: lev1name - integer, allocatable :: ind1D(:) ! Indices of 1D harvest variables - integer, allocatable :: ind2D(:) ! Indices of 2D harvest variables - integer :: n, i ! Indices - integer :: rcode ! Error status - character(len=*), parameter :: subname=' (mkfile_fdyndat) ' - ! ------------------------------------------------------------ - - rc = ESMF_SUCCESS - - ! if (root_task) then - ! write(ndiag,'(a)')'creating dynamic land use dataset' - ! end if - - ! allocate(pctlnd_pft_dyn(ns_o)) - ! !call mkharvest_init( lsize_o, spval, harvdata, mksrf_fhrvtyp ) - - ! ! open output file - ! call mkpio_wopen(trim(fdyndat), clobber=.true., pioid=pioid_o) - - ! ! Define dimensions and global attributes - ! call mkfile_define_dims(pioid, nx, ny, dynlanduse=.true.) - ! call mkfile_define_atts(pioid, dynlanduse = .true.) - - ! if ( outnc_double ) then - ! xtype = PIO_DOUBLE - ! else - ! xtype = PIO_REAL - ! end if - - ! do n = 1,2 - - ! define_mode = (n == 1) - ! if (.not. define_mode) then - ! rcode = pio_enddef(pioid_o) - ! end if - - ! ! -------------------------------- - ! ! Write out model grid - ! ! -------------------------------- - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out model grid" - - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" - ! call mkfile_output(pioid_o, mesh_o, 'LONGXY', 'model longitudes', & - ! 'degrees', lat, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LATIXY" - ! call mkfile_output(pioid_o, mesh_o, 'LATIXY', 'model latitudes', & - ! 'degrees', lon, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! !rcode = pio_open(trim(fdyndat), nf_write, pioid_o)) - ! !rcode = pio_set_fill (pioid_o, nf_nofill, omode)) - - ! ! -------------------------------- - ! ! Write out non-spatial variables - ! ! -------------------------------- - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out non-spatial variables" - - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out natpft" - ! if (define_mode) then - ! rcode = pio_def_var(pioid_o, 'natpft', PIO_INT, pio_varid) - ! else - ! rcode = pio_inq_varid(pioid_o, 'natpft', pio_varid) - ! rcode = pio_put_var_int(pioid_o, pio_varid, (/(n,n=natpft_lb,natpft_ub)/)) - ! end if - - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out cft" - ! if (define_mode) then - ! rcode = pio_def_var(pioid_o, 'cft', PIO_INT, pio_varid) - ! else - ! rcode = pio_inq_varid(pioid_o, 'cft', pio_varid) - ! rcode = pio_put_var_int(pioid_o, pio_varid, (/(n,n=cft_lb,cft_ub)/)) - ! end if - - ! ! -------------------------------- - ! ! Write out spatial variables - ! ! -------------------------------- - - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing land mask from pft dataset" - ! call mkfile_output(pioid_o, mesh_o, 'PFTDATA_MASK', & - ! 'land mask from pft dataset, indicative of real/fake points', 'unitless', pftdata_mask, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil depth" - ! call mkfile_output(pioid_o, mesh_o, 'LANDFRAC_PFT', & - ! 'land fraction from pft dataset', 'unitless', landfrac_pft, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! end do - - ! ! ----------------------------------------- - ! ! Read in each dynamic pft landuse dataset - ! ! ----------------------------------------- - - ! ! Open txt file - ! open (newunit=nfdyn, file=trim(mksrf_fdynuse), form='formatted', iostat=ier) - ! if (ioe /= 0) then - ! call shr_sys_abort(subname//" failed to open file "//trim(mksrf_fdynuse)) - ! end if - - ! pctnatpft_max = pctnatpft - ! pctcft_max = pctcft - - ! ntim = 0 - ! do - - ! ! Determine file name - ! read(nfdyn, '(A195,1x,I4)', iostat=ier) string, year - ! if (ier /= 0) exit - - ! ! If pft fraction override is set, than intrepret string as PFT and harvesting override values - ! ! Otherwise intrepret string as a filename with PFT and harvesting values in it - ! if ( all_veg )then - ! fname = ' ' - ! fhrvname = ' ' - ! call mkpft_parse_oride(string) - ! call mkharvest_parse_oride(string) - ! write(6, '(a, i4, a)') 'PFT and harvesting values for year ', year, ' :' - ! write(6, '(a, a)') ' ', trim(string) - ! else - ! fname = string - ! read(nfdyn, '(A195,1x,I4)', iostat=ier) fhrvname, year2 - ! if (root_task) then - ! write(ndiat,'(a,i8,a)')' input pft dynamic dataset for year ', year,' is : '//trim(fname) - ! end if - ! if ( year2 /= year ) then - ! write(6,*) subname, ' error: year for harvest not equal to year for PFT files' - ! call shr_sys_abort() - ! end if - ! end if - ! ntim = ntim + 1 - - ! ! Create pctpft data at model resolution from file fname - ! call mkpft( mksrf_fvegtyp_mesh, fname, mesh_model, & - ! pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') - - ! ! Create harvesting data at model resolution - ! call mkharvest( mksrf_fhrvtyp, mesh_model, harvdata=harvdata, rc ) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') - - ! ! Consistency check on input land fraction - ! do n = 1,lsize_o - ! if (pctlnd_pft_dyn(n) /= pctlnd_pft(n)) then - ! write(6,*) subname,' error: pctlnd_pft for dynamics data = ',& - ! pctlnd_pft_dyn(n), ' not equal to pctlnd_pft for surface data = ',& - ! pctlnd_pft(n),' at n= ',n - ! if ( trim(fname) == ' ' )then - ! write(6,*) ' PFT string = ', string - ! else - ! write(6,*) ' PFT file = ', fname - ! end if - ! call shr_sys_abort() - ! end if - ! end do - - ! call change_landuse( dynpft=.true.) - - ! call normalizencheck_landuse(ldomain) - - ! call update_max_array(pctnatpft_max,pctnatpft) - ! call update_max_array(pctcft_max,pctcft) - - ! ! Output time-varying data for current year - - ! rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT', pio_varid) - ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_p2l_array(pctnatpft)) - - ! rcode = pio_inq_varid(pioid, 'PCT_CROP', pio_varid) - ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_l2g_array(pctcft)) - - ! if (num_cft > 0) then - ! rcode = pio_inq_varid(pioid, 'PCT_CFT', pio_varid) - ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_p2l_array(pctcft)) - ! end if - - ! call harvdata%getFieldsIdx( harvind1D, harvind2D) - ! do k = 1, harvdata%num1Dfields() - ! rcode = pio_inq_varid(pioid, trim(mkharvest_fieldname(harvind1D(k),constant=.false.)), pio_varid) - ! harvest1D => harvdata%get1DFieldPtr( harvind1D(k), output=.true. ) - ! call mkpio_put_time_slice(pioid, pio_varid, ntim, harvest1D) - ! end do - ! do k = 1, harvdata%num2Dfields() - ! rcode = pio_inq_varid(pioid, trim(mkharvest_fieldname(harvind2D(k),constant=.false.)), pio_varid) - ! harvest2D => harvdata%get2DFieldPtr( harvind2D(k), output=.true. ) - ! call mkpio_put_time_slice(pioid, pio_varid, ntim, harvest2D) - ! end do - ! deallocate( harvind1D, harvind2D ) - - ! rcode = pio_inq_varid(pioid, 'YEAR', pio_varid) - ! rcode = pio_put_vara_int(pioid, pio_varid, ntim, 1, year) - - ! rcode = pio_inq_varid(pioid, 'time', pio_varid) - ! rcode = pio_put_vara_int(pioid, pio_varid, ntim, 1, year) - - ! rcode = pio_inq_varid(pioid, 'input_pftdata_filename', pio_varid) - ! rcode = pio_put_vara_text(pioid, pio_varid, (/ 1, ntim /), (/ len_trim(string), 1 /), trim(string)) - - ! end do ! end of read loop - - ! rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT_MAX', pio_varid) - ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_p2l_array(pctnatpft_max)) - - ! rcode = pio_inq_varid(pioid, 'PCT_CROP_MAX', pio_varid) - ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_l2g_array(pctcft_max)) - - ! if (num_cft > 0) then - ! rcode = pio_inq_varid(pioid, 'PCT_CFT_MAX', pio_varid) - ! rcode = pio_put_var_double(pioid, pio_varid, get_pct_p2l_array(pctcft_max)) - ! end if - - ! rcode = pio_closefile(pioid) - - end subroutine mkfile_fdyndat - - !================================================================================= subroutine mkfile_define_dims(pioid, nx, ny, dynlanduse) ! ! Define dimensions. @@ -536,7 +293,7 @@ subroutine mkfile_define_vars(pioid, dynlanduse) call mkpio_defvar(pioid=pioid, varname='mxsoil_color', xtype=PIO_INT, & long_name='maximum numbers of soil colors', units='unitless') - + call mkpio_def_spatial_var(pioid=pioid, varname='SOIL_COLOR', xtype=PIO_INT, & long_name='soil color', units='unitless') @@ -786,44 +543,60 @@ subroutine mkfile_define_vars(pioid, dynlanduse) if (.not. dynlanduse) then call mkpio_def_spatial_var(pioid=pioid, varname='CONST_HARVEST_VH1', xtype=xtype, & long_name = "harvest from primary forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='CONST_HARVEST_VH2', xtype=xtype, & long_name = "harvest from primary non-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='CONST_HARVEST_SH1', xtype=xtype, & long_name = "harvest from secondary mature-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='CONST_HARVEST_SH2', xtype=xtype, & long_name = "harvest from secondary young-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='CONST_HARVEST_SH3', xtype=xtype, & long_name = "harvest from secondary non-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='CONST_GRAZING', xtype=xtype, & long_name = "grazing of herbacous pfts", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='CONST_FERTNITRO_CFT', xtype=xtype, & lev1name = 'cft', & long_name = "nitrogen fertilizer for each crop", units = "gN/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='UNREPRESENTED_PFT_LULCC', xtype=xtype,& lev1name = 'natpft', & long_name = "unrepresented PFT gross LULCC transitions", units = "unitless") + call mkpio_def_spatial_var(pioid=pioid, varname='UNREPRESENTED_CFT_LULCC', xtype=xtype, & lev1name = 'cft', & long_name = "unrepresented crop gross LULCC transitions", units = "unitless") else call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_VH1', xtype=xtype, & long_name = "harvest from primary forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_VH2', xtype=xtype, & long_name = "harvest from primary non-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_SH1', xtype=xtype, & long_name = "harvest from secondary mature-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_SH2', xtype=xtype, & long_name = "harvest from secondary young-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_SH3', xtype=xtype, & long_name = "harvest from secondary non-forest", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='GRAZING', xtype=xtype, & long_name = "grazing of herbacous pfts", units = "gC/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='FERTNITRO_CFT', xtype=xtype, & lev1name = 'cft', & long_name = "nitrogen fertilizer for each crop", units = "gN/m2/yr") + call mkpio_def_spatial_var(pioid=pioid, varname='UNREPRESENTED_PFT_LULCC', xtype=xtype, & lev1name = 'natpft', & long_name = "unrepresented PFT gross LULCC transitions", units = "unitless") + call mkpio_def_spatial_var(pioid=pioid, varname='UNREPRESENTED_CFT_LULCC', xtype=xtype, & lev1name = 'cft', & long_name = "unrepresented crop gross LULCC transitions", units = "unitless") @@ -893,12 +666,15 @@ subroutine mkfile_define_vars(pioid, dynlanduse) call mkpio_def_spatial_var(pioid=pioid, varname='MONTHLY_LAI', xtype=xtype, & lev1name='lsmpft', lev2name='time', & long_name='monthly leaf area index', units='unitless') + call mkpio_def_spatial_var(pioid=pioid, varname='MONTHLY_SAI', xtype=xtype, & lev1name='lsmpft', lev2name='time', & long_name='monthly stem area index', units='unitless') + call mkpio_def_spatial_var(pioid=pioid, varname='MONTHLY_HEIGHT_TOP', xtype=xtype, & lev1name='lsmpft', lev2name='time', & long_name='monthly height top', units='meters') + call mkpio_def_spatial_var(pioid=pioid, varname='MONTHLY_HEIGHT_BOT', xtype=xtype, & lev1name='lsmpft', lev2name='time', & long_name='monthly height bottom', units='meters') diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index e95f67e76d..9e19627239 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -10,8 +10,9 @@ module mkharvestMod use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem use mkpioMod , only : mkpio_get_rawdata, mkpio_get_rawdata_level, mkpio_get_dimlengths - use mkpioMod , only : mkpio_def_spatial_var, mkpio_iodesc_output, mkpio_iodesc_rawdata - use mkpioMod , only : mkpio_put_time_slice + use mkpioMod , only : mkpio_def_spatial_var, mkpio_iodesc_rawdata + use mkpioMod , only : mkpio_put_time_slice, mkpio_iodesc_output + use mkfileMod , only : mkfile_output use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag, mpicom @@ -21,13 +22,12 @@ module mkharvestMod #include - integer, private, parameter :: numharv = 9 ! number of harvest and grazing fields - ! public member functions public :: mkharvest ! Calculate the harvest values on output grid public :: mkharvest_parse_oride ! Parse the over-ride string ! private data members: + integer, parameter :: numharv = 9 ! number of harvest and grazing fields integer, parameter :: harlen = 25 ! length of strings for harvest fieldnames character(len=harlen), parameter :: harvest_fieldnames(numharv) = (/ & 'HARVEST_VH1 ', & @@ -52,18 +52,14 @@ module mkharvestMod 'UNREPRESENTED_CFT_LULCC' & /) - logical :: is_field_1d(num_harv) - character(len=CL), parameter :: string_undef = 'UNSET' real(r8), parameter :: real_undef = -999.99 - character(len=CL) :: harvest_longnames(numharv) = string_undef - character(len=CL) :: harvest_units(numharv) = string_undef real(r8), pointer :: oride_harv(:) ! array that can override harvesting - logical :: initialized = .false. - type(ESMF_Mesh) , private :: mesh_i - type(ESMF_RouteHandle), private :: routehandle - real(r8), allocatable , private :: frac_o(:) + type(ESMF_Mesh) :: mesh_i + type(ESMF_RouteHandle) :: routehandle_r8 + real(r8), allocatable :: frac_o(:) + logical :: initialized = .false. character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -71,244 +67,230 @@ module mkharvestMod !================================================================================= contains !================================================================================= - !----------------------------------------------------------------------- - - rc = ESMF_SUCCESS - - ! TODO: check that number of global elements in mesh is identical - ! to number of global elements in input data - - if (root_task) then - write (ndiag,'(a)') 'Attempting to initialize harvest module .... ' - end if - - lconstant = .false. - if ( present(constant) ) lconstant = constant - - initialized = .true. - - ! Open input harvest file - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) - - do ifld = 1, numharv - call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) - ! Determine if variable is on input dataset (fharvest) - varname = mkharvest_fieldname(ifld, constant=lconstant) - rCode = pio_inq_varid(pioid, varname, pio_varid) - call pio_seterrorhandling(pioid, PIO_INTERNAL_ERROR) - if (rcode == PIO_NOERR) then - varexists = .true. - else - varexists = .false. - end if - if (varexists) then - ! get dims2nd for variable - call mkpio_get_dimlengths(pioid, varname, ndims, dim_lengths) - if ( ndims == 2 )then - dims2nd(ifld) = 0 - else if ( ndims == 3 )then - dims2nd(ifld) = dim_lengths(3) - else - write(*,*) 'ERROR:: bad dimensionality for variable = ', mkharvest_fieldname(ifld, constant=lconstant) - call shr_sys_abort() - end if - if (root_task) then - write(ndiag,'(a)') "Will Read: "//mkharvest_fieldname(ifld, constant=lconstant) - end if - else - if (root_task) then - write(ndiag,'(a)') "Will Skip: "//mkharvest_fieldname(ifld, constant=lconstant) - end if - end if - end do - call pio_closefile(pioid) - if (root_task) then - write (ndiag,'(a)') 'finished mkharvest_init' - end if - - end subroutine mkharvest_init - - !================================================================================= - subroutine mkharvest(file_data_i, mesh_o, pioid_o, constant, rc) + subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constant, ntime, rc) ! ! Make harvest data for the dynamic PFT dataset. ! This dataset consists of the normalized harvest or grazing fraction (0-1) of ! the model. ! ! input/output variables: + character(len=*) , intent(in) :: file_mesh_i character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh - type(file_desc_t) , intent(in) :: pioid_o - logical, optional , intent(in) :: constant + type(file_desc_t) , intent(inout) :: pioid_o + logical , intent(in) :: all_veg + logical , intent(in) :: constant + integer, optional , intent(in) :: ntime integer , intent(out) :: rc ! return code ! local variables: type(file_desc_t) :: pioid_i - type(var_desc_t) :: pio_varid - integer :: ni,no,ns_i,ns_o ! indices - integer :: k,l,n,m ! indices - integer :: ndims - integer :: nlev ! inner dimension of input 2d data read in - integer :: ifld ! indices - character(len=cs) :: varname - logical :: varexists ! If variable exists or not - integer , allocatable :: mask_i(:) - real(r8) , allocatable :: frac_i(:) - real(r8) , allocatable :: frac_o(:) - real(r8) , allocatable :: data_i(:,:) - real(r8) , allocatable :: data_o(:,:) - real(r8) , allocatable :: read_data2d_i(:,:) ! input 2d data read in - real(r8) , allocatable :: read_data2d_o(:,:) ! regridded input 2d data - real(r8) , allocatable :: area_i(:) - real(r8) , allocatable :: area_o(:) - integer :: dims2nd(numharv) ! Dimension lengths of 3rd dimension for each variable on file - logical :: lconstant ! local version of constant flag - integer :: dim_lengths(3) ! Dimension lengths on file - integer :: ndims ! Number of dimensions on file - logical :: varexists ! If variable exists on file + type(var_desc_t) :: pio_varid_i + type(var_desc_t) :: pio_varid_o + type(io_desc_t) :: pio_iodesc_i + type(io_desc_t) :: pio_iodesc_o + integer :: ns_i, ns_o ! input/output sizes + integer :: ni,no ! indices + integer :: k,l,m ! indices integer :: ifld ! indices + integer :: dims2nd ! variable dimension lengths of 3rd dimension + character(len=cs) :: name2nd ! name of 2nd dimension + logical :: varexists ! true if variable exists on file + character(len=cs) :: varname_i ! input variable name + character(len=cs) :: varname_o ! output variable name + real(r8) , allocatable :: rmask_i(:) ! real value of input mask (read in) + integer , allocatable :: mask_i(:) ! integer value of rmask_i + real(r8) , allocatable :: data1d_i(:) ! input 1d data + real(r8) , allocatable :: data1d_o(:) ! otuput 1d data + real(r8) , allocatable :: data2d_o(:,:) ! output 2d data + real(r8) , allocatable :: read_data2d_i(:,:) + real(r8) , allocatable :: read_data2d_o(:,:) + real(r8) , allocatable :: area_i(:) ! areas on input mesh + real(r8) , allocatable :: area_o(:) ! areas on output mesh integer :: rcode, ier ! error status - logical :: lconstant character(len=*), parameter :: subname = 'mkharvest' !----------------------------------------------------------------------- rc = ESMF_SUCCESS - ! Normally read in the harvesting file, and then regrid to output grid - if (root_task) then - write (ndiag,'(a)') 'Attempting to make harvest fields .....' + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make harvest fields .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Normally read in the harvesting file, and then regrid to output grid + if (root_task) write(ndiag,'(a)') ' opening input data file' + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) + if (root_task) write(ndiag,'(a)') ' finished opening input data file' + + ! If all veg then write out output data with values set to harvest_initval and return + if (all_veg) then + varname_i = trim(harvest_fieldnames(ifld)) + if (constant) then + varname_o = trim(harvest_const_fieldnames(ifld)) + else + varname_o = varname_i + end if + call mkharvest_check_input_var(pioid_i, trim(varname_i), varexists, dims2nd, name2nd) + if (varexists) then + if (dims2nd == 0) then + allocate(data1d_o(ns_o)) + data1d_o(:) = 0._r8 + call mkfile_output(pioid_o, mesh_o, trim(varname_o), data1d_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + deallocate(data1d_o) + else + allocate(data2d_o(ns_o,dims2nd)) + data2d_o(:,:) = 0._r8 + call mkfile_output(pioid_o, mesh_o, trim(varname_o), data2d_o, lev1name=name2nd, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + deallocate(data2d_o) + end if + end if + call pio_closefile(pioid_i) + RETURN + end if ! Read in input mesh - if (.not. ESMF_MeshCreated(mesh_i)) then + if (.not. ESMF_MeshIsCreated(mesh_i)) then + if (root_task) write(ndiag,'(a)') ' creating input mesh' mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - ! Create a route handle between the input and output mesh - if (.not. RouteHandleisCreated(routehandle_r8)) then - allocate(frac_o(ns_o)) - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + if (root_task) write(ndiag,'(a)') ' finished creating input mesh' end if ! Determine ns_i call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Determine ns_o - call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - + + ! TODO: imlement oride_harv funcitionality - this is hard-wired for now allocate( oride_harv(numharv) ) oride_harv(:) = real_undef if ( all(oride_harv == real_undef ) )then ! Get the landmask from the file and reset the mesh mask based on that - allocate(frac_i(ns_i), stat=ier) + allocate(rmask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i - if (frac_i(ni) > 0._r4) then + if (rmask_i(ni) > 0._r4) then mask_i(ni) = 1 else mask_i(ni) = 0 end if end do + deallocate(rmask_i) call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Create a route handle between the input and output mesh + ! NOTE: this must be done after mask_i is set in mesh_i + if (.not. ESMF_RouteHandleIsCreated(routehandle_r8)) then + if (root_task) write(ndiag,'(a)') ' creating route handle ' + allocate(frac_o(ns_o)) + call create_routehandle_r8(mesh_i, mesh_o, routehandle_r8, frac_o=frac_o, rc=rc) + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + if (root_task) write(ndiag,'(a)') ' finished creating route handle ' + end if + ! Read in input 1d fields if they exists and map to output grid do ifld = 1,numharv varname_i = trim(harvest_fieldnames(ifld)) - if (lconstant) then - varname_o = trim(harvest_const_fieldnames(ifld) + if (constant) then + varname_o = trim(harvest_const_fieldnames(ifld)) else varname_o = varname_i end if - ! Check if the variable is on the input file - call pio_seterrorhandling(pioid_i, PIO_BCAST_ERROR) - rCode = pio_inq_varid(pioid, varname, pio_varid) - call pio_seterrorhandling(pioid, PIO_INTERNAL_ERROR) - if (rcode == PIO_NOERR) then - varexists = .true. - else - varexists = .false. - end if - if (varexists) then - call mkpio_get_dimlengths(pioid, varname, ndims, dim_lengths) - if ( ndims == 2 )then - dims2nd(ifld) = 0 - else if (ndims == 3 )then - dims2nd(ifld) = dim_lengths(3) - else - write(*,*) 'ERROR:: bad dimensionality for variable = ',trim(varname_i) - call shr_sys_abort() - end if - if (root_task) then - write(ndiag,'(a)') "Will Read: "//trim(varname_i) - end if - else - if (root_task) then - write(ndiag,'(a)') "Will Skip: "//trim(varname_i) - end if - end if + call mkharvest_check_input_var(pioid_i, trim(varname_i), varexists, dims2nd, name2nd) if (varexists) then - if (dim2nd(ifld) == 0) then + if (dims2nd == 0) then + + ! 1d output allocate(data1d_i(ns_i)) allocate(data1d_o(ns_o)) + ! read in input 1d variable - call mkpio_get_rawdata(pioid, varname, mesh_i, data1d_i, rc=rc) + call mkpio_get_rawdata(pioid_i, varname_i, mesh_i, data1d_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! regrid input variable - call regrid_rawdata(mesh_i, mesh_o, routehandle, data1d_i, data1d_o, rc=rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle_r8, data1d_i, data1d_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - deallocate(data1d_i) - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out "//trim(varname_o) ! write out mapped variable - call mkfile_output(pioid_o, mesh_o, trim(varname_o), data1d_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - deallocate(data1d_o)) - else - nlev = dims2nd(ifld) - allocate(read_data2d_i(nlev, ns_i)) - allocate(read_data2d_o(nlev, ns_o)) - ! read in input variable - call mkpio_get_rawdata(pioid, varname, mesh_i, read_data2d_i, rc=rc) + if (present(ntime)) then + rcode = pio_inq_varid(pioid_o, trim(varname_o), pio_varid_o) + call mkpio_iodesc_output(pioid_o, mesh_o, trim(varname_o), pio_iodesc_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in making an iodesc for '//trim(varname_o)) + call mkpio_put_time_slice(pioid_o, pio_varid_o, pio_iodesc_o, ntime, data2d_o) + call pio_freedecomp(pioid_o, pio_iodesc_o) + else + if (root_task) write(ndiag, '(a)') " writing out 1d "//trim(varname_o) + call mkfile_output(pioid_o, mesh_o, trim(varname_o), data1d_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call pio_syncfile(pioid_o) + end if + + ! TODO: uncomment the following and validate + ! Compare global areas on input and output grids for 1d variables + ! call mkharvest check_global_sums('harvest type '//trim(varname_o), ns_i, ns_o, & + ! mesh_i, mesh_o, mask_i, frac_o, data1d_i, data1d_o, rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) return + + deallocate(data1d_i) + deallocate(data1d_o) + + else ! 2d output + + ! Read in input data + allocate(read_data2d_i(dims2nd, ns_i)) + allocate(read_data2d_o(dims2nd, ns_o)) + call mkpio_get_rawdata(pioid_i, trim(varname_i), mesh_i, read_data2d_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! regrid input variable - call regrid_rawdata(mesh_i, mesh_o, routehandle, read_data2d_i, read_data2d_o, 1, nlev, rc) + ! Regrid input input data + call regrid_rawdata(mesh_i, mesh_o, routehandle_r8, read_data2d_i, read_data2d_o, 1, dims2nd, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return deallocate(read_data2d_i) - ! write out variable - allocate(data2d_o(ns_o, nlev)) - do l = 1,nlev - do n = 1,ns_o - data2d_o(n,l) = read_data2d_o(l,n) + ! Fill in output 2d array + allocate(data2d_o(ns_o,dims2nd)) + do l = 1,dims2nd + do no = 1,ns_o + data2d_o(no,l) = read_data2d_o(l,no) end do end do - call mkfile_output(pioid_o, mesh_o, trim(varname_o), data2d_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + deallocate(read_data2d_o) + + ! write out variable + if (present(ntime)) then + rcode = pio_inq_varid(pioid_o, trim(varname_o), pio_varid_o) + call mkpio_iodesc_output(pioid_o, mesh_o, trim(varname_o), pio_iodesc_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in making an iodesc for '//trim(varname_o)) + call mkpio_put_time_slice(pioid_o, pio_varid_o, pio_iodesc_o, ntime, data2d_o) + call pio_freedecomp(pioid_o, pio_iodesc_o) + else + if (root_task) write(ndiag, '(a)') " writing out 2d "//trim(varname_o) + call mkfile_output(pioid_o, mesh_o, trim(varname_o), data2d_o, lev1name=trim(name2nd), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if deallocate(data2d_o) + end if end if - end do - ! Compare global areas on input and output grids - ! call check_global_sums('harvest type', ns_i, ns_o, mesh_i, mesh_o, mask_i, frac_o, IND1d, rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) return + end do else @@ -336,11 +318,9 @@ subroutine mkharvest(file_data_i, mesh_o, pioid_o, constant, rc) end if ! If constant model, clean up the mapping - lconstant = .false. - if ( present(constant) ) lconstant = constant - if (lconstant) then + if (constant) then deallocate(frac_o) - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + call ESMF_RouteHandleDestroy(routehandle_r8, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() @@ -394,19 +374,20 @@ subroutine mkharvest_parse_oride( string ) end subroutine mkharvest_parse_oride !================================================================================= - subroutine check_global_sums(this, name, ns_i, ns_o, mesh_i, mesh_o, mask_i, frac_o, ind1D, rc) + subroutine mkharvest_check_global_sums(name, ns_i, ns_o, mesh_i, mesh_o, mask_i, frac_o, & + data_i, data_o, rc) ! input/otuput variables - class(harvestDataType), intent(inout) :: this ! harvestData object - character(len=*) , intent(in) :: name - integer , intent(in) :: ns_i - integer , intent(in) :: ns_o - type(ESMF_Mesh) , intent(in) :: mesh_i - type(ESMF_Mesh) , intent(in) :: mesh_o - integer , intent(in) :: mask_i(:) - real(r8) , intent(in) :: frac_o(:) - integer , intent(in) :: ind1D(:) - integer , intent(out) :: rc + character(len=*) , intent(in) :: name + integer , intent(in) :: ns_i + integer , intent(in) :: ns_o + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o + integer , intent(in) :: mask_i(:) + real(r8) , intent(in) :: frac_o(:) + real(r8) , intent(in) :: data_i(:) ! 1D input data + real(r8) , intent(in) :: data_o(:) ! 1D output data + integer , intent(out) :: rc ! local variables integer :: ni, no, k, m @@ -417,8 +398,6 @@ subroutine check_global_sums(this, name, ns_i, ns_o, mesh_i, mesh_o, mask_i, fra real(r8) :: local_o(numharv) ! output grid: global area harvesting real(r8) :: global_i(numharv) ! input grid: global area harvesting real(r8) :: global_o(numharv) ! output grid: global area harvesting - real(r8), pointer :: data1D_i(:) ! 1D input data - real(r8), pointer :: data1D_o(:) ! 1D output data real(r8), parameter :: fac = 1.e-06_r8 ! Output factor real(r8), parameter :: rat = fac/100._r8 ! Output factor divided by 100% character(len=*) , parameter :: unit = '10**6 km**2' ! Output units @@ -438,22 +417,14 @@ subroutine check_global_sums(this, name, ns_i, ns_o, mesh_i, mesh_o, mask_i, fra ! Input grid global area local_i(:) = 0. do ni = 1, ns_i - do k = 1, this%num1Dfields() - m = ind1D(k) - data1D_i => this%get1DFieldPtr( m ) - local_i(m) = local_i(m) + data1D_i(ni) *area_i(ni) * mask_i(ni) - end do + local_i(m) = local_i(m) + data_i(ni) *area_i(ni) * mask_i(ni) end do call mpi_reduce(local_i, global_i, numharv, MPI_REAL8, MPI_SUM, 0, mpicom, ier) ! Output grid global area local_o(:) = 0. do no = 1,ns_o - do k = 1, this%num1Dfields() - m = ind1D(k) - data1D_o => this%get1DFieldPtr( m, output=.true. ) - local_o(m) = local_o(m) + data1D_o(no) * area_o(no) * frac_o(no) - end do + local_o(m) = local_o(m) + data_o(no) * area_o(no) * frac_o(no) end do call mpi_reduce(local_o, global_o, numharv, MPI_REAL8, MPI_SUM, 0, mpicom, ier) @@ -462,16 +433,69 @@ subroutine check_global_sums(this, name, ns_i, ns_o, mesh_i, mesh_o, mask_i, fra write (ndiag,*) write (ndiag,'(1x,70a1)') ('.',k=1,70) write (ndiag,101) unit, unit -101 format (1x,'harvest type ',20x,' input grid area',' output grid area',/ & +101 format (1x,'harvest type' ,20x,' input grid area',' output grid area',/ & 1x,33x,' ',A,' ',A) write (ndiag,'(1x,70a1)') ('.',k=1,70) write (ndiag,*) - do k = 1, this%num1Dfields() - m = ind1D(k) - write (ndiag,102) mkharvest_fieldname(m), global_i(m)*rat, global_o(m)*rat - end do + write (ndiag,102) trim(name), global_i*rat, global_o*rat 102 format (1x,a35,f16.3,f17.3) - end subroutine check_global_sums + end subroutine mkharvest_check_global_sums + + !================================================================================= + subroutine mkharvest_check_input_var(pioid, varname, varexists, dims2nd, name2nd) + + ! input/output variables + type(file_desc_t) , intent(inout) :: pioid + character(len=*) , intent(in) :: varname + logical , intent(out) :: varexists + integer , intent(out) :: dims2nd + character(len=*) , intent(out) :: name2nd + + ! local variable + type(var_desc_t) :: pio_varid + integer :: ndims ! number of variable dimension + integer :: dimids(3) ! variable dimension dim ids + integer :: dimlens(3) ! variable dimensions sizes + integer :: ifld ! index + integer :: rcode ! error status + character(len=*) , parameter :: subname = 'mkharvest_check_input_var' + !----------------------------------------------------------------------- + + dims2nd = -999 + name2nd = 'unset' + + call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) + rcode = pio_inq_varid(pioid, varname, pio_varid) + call pio_seterrorhandling(pioid, PIO_INTERNAL_ERROR) + if (rcode == PIO_NOERR) then + varexists = .true. + else + varexists = .false. + end if + if (varexists) then + rcode = pio_inq_varndims(pioid, pio_varid, ndims) + if ( ndims == 2 )then + dims2nd = 0 + else if (ndims == 3 )then + rcode = pio_inq_vardimid(pioid, pio_varid, dimids) + rcode = pio_inq_dimlen(pioid, dimids(3), dimlens(3)) + dims2nd = dimlens(3) + rcode = pio_inq_vardimid(pioid, pio_varid, dimids) + rcode = pio_inq_dimname(pioid, dimids(3), name2nd) + else + write(*,*) 'ERROR:: bad dimensionality for variable = ',trim(varname) + call shr_sys_abort() + end if + if (root_task) then + write(ndiag,'(a)') " reading: "//trim(varname) + end if + else + if (root_task) then + write(ndiag,'(a)') " skipping: "//trim(varname) + end if + end if + + end subroutine mkharvest_check_input_var end module mkharvestMod diff --git a/tools/mksurfdata_esmf/src/mklaiMod.F90 b/tools/mksurfdata_esmf/src/mklaiMod.F90 index d54ecd375e..e246147c10 100644 --- a/tools/mksurfdata_esmf/src/mklaiMod.F90 +++ b/tools/mksurfdata_esmf/src/mklaiMod.F90 @@ -261,6 +261,9 @@ subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) end do ! end loop over months ! Close the input file + call pio_freedecomp(pioid_i, pio_iodesc_i) + call pio_freedecomp(pioid_o, pio_iodesc_o) + call pio_closefile(pioid_i) call ESMF_VMLogMemInfo("After pio_closefile for input in "//trim(subname)) @@ -280,8 +283,8 @@ subroutine check_global_sums(name, ns_i, ns_o, numpft_i, nt, & ! Compare global areas on input and output grids ! input/otuput variables - character(len=*) , intent(in) :: name - integer , intent(in) :: ns_i + character(len=*) , intent(in) :: name + integer , intent(in) :: ns_i integer , intent(in) :: ns_o integer , intent(in) :: nt integer , intent(in) :: numpft_i @@ -290,7 +293,7 @@ subroutine check_global_sums(name, ns_i, ns_o, numpft_i, nt, & real(r8) , intent(in) :: area_i(:) real(r8) , intent(in) :: area_o(:) integer , intent(in) :: mask_i(:) - real(r8) , intent(in) :: frac_o(:) + real(r8) , intent(in) :: frac_o(:) ! local variables integer :: ni, no, l, k diff --git a/tools/mksurfdata_esmf/src/mkorganicMod.F90 b/tools/mksurfdata_esmf/src/mkorganicMod.F90 index a32e37173f..094bd9ea15 100644 --- a/tools/mksurfdata_esmf/src/mkorganicMod.F90 +++ b/tools/mksurfdata_esmf/src/mkorganicMod.F90 @@ -66,12 +66,11 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) end if ! Open input data file - call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) - ! Get dimensions of raw data. - ! - raw data is dimensions (lon,lat,lev) + ! Get dimensions of raw data. + ! - raw data is dimensions (lon,lat,lev) ! - input read from pio has dimensions(n,lev) ! - esmf field dataptr has dimensions (lev,n) allocate(dimlengths(3)) @@ -154,7 +153,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) enddo end do - ! Close the file + ! Close the file call pio_closefile(pioid) call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index a798c83ffc..1d97be4ead 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -84,7 +84,6 @@ subroutine mkpftInit( zero_out_l, all_veg_l ) character(len=*), parameter :: subname = ' (mkpftInit) ' !----------------------------------------------------------------------- - write (6, '(a, a, a)') "In ", subname, "..." if ( maxpft < numpft ) then write(6,*) subname//'number PFT is > max allowed!' call shr_sys_abort() diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index e4ba5415e1..cd854b5264 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -96,18 +96,17 @@ program mksurfdata use mktopostatsMod , only : mktopostats use mkVICparamsMod , only : mkVICparams #endif - ! use mkharvestMod , only : mkharvest, mkharvest_init, mkharvest_fieldname - ! use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride, harvestDataType use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft use mkdomainMod , only : mkdomain + use mkharvestMod , only : mkharvest, mkharvest_parse_oride use mkgdpMod , only : mkgdp use mkagfirepkmonthMod , only : mkagfirepkmon use mklaiMod , only : mklai use mkpeatMod , only : mkpeat use mkvocefMod , only : mkvocef - use mkglcmecMod , only : mkglcmecInit, mkglcmec, mkglacier, nglcec + use mkglcmecMod , only : mkglcmecInit, mkglcmec, mkglacier, nglcec use mkglacierregionMod , only : mkglacierregion use mksoiltexMod , only : mksoiltex use mksoilfmaxMod , only : mksoilfmax @@ -118,7 +117,7 @@ program mksurfdata use mkorganicMod , only : mkorganic use mkutilsMod , only : normalize_classes_by_gcell, chkerr use mkfileMod , only : mkfile_define_dims, mkfile_define_atts, mkfile_define_vars - use mkfileMod , only : mkfile_fdyndat, mkfile_output + use mkfileMod , only : mkfile_output use mkvarpar , only : nlevsoi, elev_thresh, numstdpft use nanMod , only : nan, bigint use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem @@ -155,14 +154,13 @@ program mksurfdata real(r8), allocatable :: lat(:) real(r8), allocatable :: landfrac_pft(:) ! PFT data: % land per gridcell real(r8), allocatable :: pctlnd_pft(:) ! PFT data: % of gridcell for PFTs + real(r8), allocatable :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs integer , allocatable :: pftdata_mask(:) ! mask indicating real or fake land type type(pct_pft_type), allocatable :: pctnatpft(:) ! % of grid cell that is nat veg, and breakdown into PFTs type(pct_pft_type), allocatable :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series type(pct_pft_type), allocatable :: pctcft(:) ! % of grid cell that is crop, and breakdown into CFTs type(pct_pft_type), allocatable :: pctcft_max(:) ! % of grid cell maximum CFTs of the time series real(r8) :: harvest_initval ! initial value for harvest variables - real(r8), allocatable :: harvest1D(:) ! harvest 1D data: normalized harvesting - real(r8), allocatable :: harvest2D(:,:) ! harvest 1D data: normalized harvesting real(r8), allocatable :: pctgla(:) ! percent of grid cell that is glacier real(r8), allocatable :: pctglc_gic(:) ! percent of grid cell that is gic (% of glc landunit) real(r8), allocatable :: pctglc_icesheet(:) ! percent of grid cell that is ice sheet (% of glc landunit) @@ -206,8 +204,8 @@ program mksurfdata integer , allocatable :: harvind2D(:) ! Indices of 2D harvest fields logical :: zero_out_lake ! if should zero glacier out logical :: zero_out_wetland ! if should zero glacier out - logical :: zero_out - !type(harvestDataType) :: harvdata + logical :: zero_out + character(len=cs) :: fname ! esmf variables integer :: rc @@ -315,9 +313,9 @@ program mksurfdata call ESMF_MeshGet(mesh_model, numOwnedElements=lsize_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - ! ---------------------------------------------------------------------- - ! Create netCDF surface dataset - ! ---------------------------------------------------------------------- + ! ====================================================================== + ! Create fsurdat + ! ====================================================================== ! Initialize urban dimensions (needed to initialize the dimensions in fsurdat) call mkurbanInit (mksrf_furban) @@ -357,23 +355,35 @@ program mksurfdata ! Define variables call mkfile_define_vars(pioid, dynlanduse = .false.) + + ! End define model rcode = pio_enddef(pioid) end if + ! ----------------------------------- + ! Write out coordinate variables + ! ----------------------------------- + rcode = pio_inq_varid(pioid, 'natpft', pio_varid) + rcode = pio_put_var(pioid, pio_varid, (/(n,n=natpft_lb,natpft_ub)/)) + if (num_cft > 0) then + rcode = pio_inq_varid(pioid, 'cft', pio_varid) + rcode = pio_put_var(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/)) + end if + ! ----------------------------------- ! Make lats/lons of model ! ----------------------------------- allocate (lon(lsize_o)) ; lon(:) = spval allocate (lat(lsize_o)) ; lat(:) = spval - call mkdomain(mesh_model, lon_o=lon, lat_o=lat, rc=rc) + call mkdomain(mesh_model, lon_o=lon, lat_o=lat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing out model grid" if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" - call mkfile_output(pioid, mesh_model, 'LONGXY', lon, rc=rc) + call mkfile_output(pioid, mesh_model, 'LONGXY', lon, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LATIXY" - call mkfile_output(pioid, mesh_model, 'LATIXY', lat, rc=rc) + call mkfile_output(pioid, mesh_model, 'LATIXY', lat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') end if @@ -421,26 +431,19 @@ program mksurfdata if (root_task) write(ndiag, '(a)') trim(subname)//" writing land mask from pft dataset" call mkfile_output(pioid, mesh_model, 'PFTDATA_MASK', pftdata_mask, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing land fraction from pft dataset" + call mkfile_output(pioid, mesh_model, 'LANDFRAC_PFT', landfrac_pft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') call pio_syncfile(pioid) end if ! ----------------------------------- ! Create constant harvesting data at model resolution ! ----------------------------------- - ! if (all_veg) then - ! ! In this case, we don't call mkharvest, but want the harvest - ! ! variables to be initialized reasonably. - ! harvest_initval = 0._r8 - ! else - ! harvest_initval = spval - ! end if - ! call mkharvest_init(mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, & - ! init_val=harvest_initval, harvdata=harvdata, constant=.true., rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') - ! if (.not. all_veg )then - ! call mkharvest( mksrf_fhrvtyp, mesh_model, harvdata=harvdata, constant=.true., rc=rc ) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') - ! end if + ! Note that this call must come after call to mkpftInit - since num_cft is set there + call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, & + pioid_o=pioid, all_veg=all_veg, constant=.true., rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') ! ----------------------------------- ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] @@ -457,13 +460,6 @@ program mksurfdata if (root_task) write(ndiag, '(a)') trim(subname)//" writing out lakedepth" call mkfile_output(pioid, mesh_model, 'LAKEDEPTH', lakedepth, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') -!DEBUG - call mkfile_output(pioid, mesh_model, 'PCT_LAKE', pctlak, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_wetland" - call mkfile_output(pioid, mesh_model, 'PCT_WETLAND', pctwet, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') -!DEBUG call pio_syncfile(pioid) end if deallocate (lakedepth ) @@ -476,12 +472,6 @@ program mksurfdata if (.not. zero_out) then call mkglacier (mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, glac_o=pctgla, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacier') -!DEBUG - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glacier" - call mkfile_output(pioid, mesh_model, 'PCT_GLACIER', pctgla, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out percnt urban" -!DEBUG else if (root_task) then write (ndiag,'(a)') 'Attempting to make %glacier .....' @@ -506,7 +496,7 @@ program mksurfdata ! ----------------------------------- ! Make soil texture [pctsand, pctclay] ! ----------------------------------- - ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero + ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero ! (not a very small number such as 1e-16) where it really should be zero allocate(mapunits(lsize_o)) ; mapunits(:) = 0 allocate(pctsand(lsize_o,nlevsoi)) ; pctsand(:,:) = spval @@ -581,7 +571,7 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing out gdp" - call mkfile_output(pioid, mesh_model, 'gdp', gdp, rc=rc) + call mkfile_output(pioid, mesh_model, 'gdp', gdp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') call pio_syncfile(pioid) end if @@ -595,7 +585,7 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpeat') if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing out peatland fraction" - call mkfile_output(pioid, mesh_model, 'peatf', fpeat, rc=rc) + call mkfile_output(pioid, mesh_model, 'peatf', fpeat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') call pio_syncfile(pioid) end if @@ -630,7 +620,7 @@ program mksurfdata deallocate(agfirepkmon) ! ----------------------------------- - ! Make urban fraction [pcturb] from [furban] dataset and + ! Make urban fraction [pcturb] from [furban] dataset and ! ----------------------------------- allocate (pcturb(lsize_o)) ; pcturb(:) = spval allocate (urban_classes(lsize_o,numurbl)) ; urban_classes(:,:) = spval @@ -643,7 +633,7 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') call pio_syncfile(pioid) end if - ! Note that final values of urban are not set and written out until further down + ! Note that final values of urban are not set and written out until further down ! Adjust pcturb ! Make elevation [elev] from [ftopo, ffrac] dataset @@ -755,12 +745,12 @@ program mksurfdata ! Do landuse changes such as for the poles, etc. ! call change_landuse(dynpft=.false., lat_o=lat_o) - ! ---------------------------------------------------------------------- + ! ----------------------------------- ! Modify pctlak, pctwet, pctgla and pcturb where needed - ! ---------------------------------------------------------------------- + ! ----------------------------------- do n = 1,lsize_o - ! Truncate all percentage fields on output grid. This is needed to insure that + ! Truncate all percentage fields on output grid. This is needed to insure that ! wt is zero (not a very small number such as 1e-16) where it should be zero pctlak(n) = float(nint(pctlak(n))) pctwet(n) = float(nint(pctwet(n))) @@ -797,14 +787,17 @@ program mksurfdata if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glacier" call mkfile_output(pioid, mesh_model, 'PCT_GLACIER', pctgla, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in mkfile_output for pctgla') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_lake" call mkfile_output(pioid, mesh_model, 'PCT_LAKE', pctlak, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in mkfile_output for pctlak') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_wetland" call mkfile_output(pioid, mesh_model, 'PCT_WETLAND', pctwet, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in in mkfile_output for pctwet') end if + ! NOTE: do not deallocate pctlak, pctwet, pctglacier and pcturban ! ---------------------------------------------------------------------- ! TODO: @@ -928,22 +921,180 @@ program mksurfdata write(ndiag,'(a)')'successfully created file '//trim(fsurdat) end if - ! ---------------------------------------------------------------------- - ! Create dynamic land use dataset if appropriate - ! ---------------------------------------------------------------------- + ! ====================================================================== + ! Create fdyndat if appropriate + ! ====================================================================== - ! allocate ( pctcft_max(lsize_o)) ; - ! allocate ( pctnatpft_max(lsize_o)) ; - ! if (mksrf_fdynuse) then - ! if (fdyndat == ' ') then - ! call shr_sys_abort(' must specify fdyndat in namelist if mksrf_fdynuse is not blank') - ! end if - ! call mkfile_fdyndat() - ! end if ! end of if-create dynamic landust dataset + if (mksrf_fdynuse /= ' ') then - ! ---------------------------------------------------------------------- - ! Close diagnostic dataset - ! ---------------------------------------------------------------------- + if (fdyndat == ' ') then + call shr_sys_abort(' must specify fdyndat in namelist if mksrf_fdynuse is not blank') + end if + + if (root_task) then + write(ndiag,'(a)')'creating dynamic land use dataset' + end if + + allocate(pctcft_max(lsize_o)) ; + allocate(pctnatpft_max(lsize_o)) ; + allocate(pctlnd_pft_dyn(ns_o)) + + ! open output file + call mkpio_wopen(trim(fdyndat), clobber=.true., pioid=pioid) + + ! Define dimensions + call mkfile_define_dims(pioid, nx=mksrf_fgrid_mesh_nx, ny=mksrf_fgrid_mesh_ny, dynlanduse=.true.) + + ! Define global attributes + call mkfile_define_atts(pioid, dynlanduse = .true.) + + ! End define model + rcode = pio_enddef(pioid) + + ! Write out model grid + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" + call mkfile_output(pioid, mesh_model, 'LONGXY', lon, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LATIXY" + call mkfile_output(pioid, mesh_model, 'LATIXY', lat, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + + ! Write out natpft + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out natpft" + rcode = pio_inq_varid(pioid, 'natpft', pio_varid) + rcode = pio_put_var(pioid, pio_varid, (/(n,n=natpft_lb,natpft_ub)/)) + + ! Write out cft + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out cft" + rcode = pio_inq_varid(pioid, 'cft', pio_varid) + rcode = pio_put_var(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/)) + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing land mask from pft dataset" + call mkfile_output(pioid, mesh_model, 'PFTDATA_MASK', pftdata_mask, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing land fraction from pft dataset" + call mkfile_output(pioid, mesh_model, 'LANDFRAC_PFT', landfrac_pft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + + ! ----------------------------------------- + ! Read in each dynamic pft landuse dataset + ! ----------------------------------------- + + ! Open txt file + open (newunit=nfdyn, file=trim(mksrf_fdynuse), form='formatted', iostat=ier) + if (ier /= 0) then + call shr_sys_abort(subname//" failed to open file "//trim(mksrf_fdynuse)) + end if + + pctnatpft_max = pctnatpft + pctcft_max = pctcft + + ntim = 0 + do + + ! Determine file name + read(nfdyn, '(A195,1x,I4)', iostat=ier) string, year + if (ier /= 0) EXIT + + ! If pft fraction override is set, than intrepret string as PFT and harvesting override values + ! Otherwise intrepret string as a filename with PFT and harvesting values in it + if ( all_veg )then + fname = ' ' + fhrvname = ' ' + call mkpft_parse_oride(string) + call mkharvest_parse_oride(string) + write(6, '(a, i4, a)') 'PFT and harvesting values for year ', year, ' :' + write(6, '(a, a)') ' ', trim(string) + else + fname = string + read(nfdyn, '(A195,1x,I4)', iostat=ier) fhrvname, year2 + if (root_task) then + write(ndiag,'(a,i8,a)')' input pft dynamic dataset for year ', year,' is : '//trim(fname) + end if + if ( year2 /= year ) then + write(6,*) subname, ' error: year for harvest not equal to year for PFT files' + call shr_sys_abort() + end if + end if + ntim = ntim + 1 + + ! Create pctpft data at model resolution from file fname + ! Note that pctlnd_o below is different than the above call and returns pctlnd_pft_dyn + call mkpft( mksrf_fvegtyp_mesh, fname, mesh_model, & + pctlnd_o=pctlnd_pft_dyn, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpft') + + ! Consistency check on input land fraction + do n = 1,lsize_o + if (pctlnd_pft_dyn(n) /= pctlnd_pft(n)) then + write(6,*) subname,' error: pctlnd_pft for dynamics data = ',& + pctlnd_pft_dyn(n), ' not equal to pctlnd_pft for surface data = ',& + pctlnd_pft(n),' at n= ',n + if ( trim(fname) == ' ' )then + write(6,*) ' PFT string = ', string + else + write(6,*) ' PFT file = ', fname + end if + call shr_sys_abort() + end if + end do + + ! Create harvesting data at model resolution + call mkharvest( mksrf_fhrvtyp_mesh, fhrvname, mesh_model, & + pioid_o=pioid, all_veg=.false., constant=.false., ntime=ntim, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest') + + ! Do landuse changes such as for the poles, etc. + call change_landuse( dynpft=.true.) + + ! Normalize land use and make sure things add up to 100% as well as + ! checking that things are as they should be. + call normalizencheck_landuse(ns_o) + + ! Given an array of pct_pft_type variables, update all the max_p2l variables. + call update_max_array(pctnatpft_max,pctnatpft) + call update_max_array(pctcft_max,pctcft) + + ! TODO: need to create an io descriptor here - need to actually put this in mkpft? + ! Output time-varying data for current year + ! rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT', pio_varid) + ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_p2l_array(pctnatpft)) + ! rcode = pio_inq_varid(pioid, 'PCT_CROP', pio_varid) + ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_l2g_array(pctcft)) + ! if (num_cft > 0) then + ! rcode = pio_inq_varid(pioid, 'PCT_CFT', pio_varid) + ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_p2l_array(pctcft)) + ! end if + ! TODO: make sure the following is correct + ! rcode = pio_inq_varid(pioid, 'YEAR', pio_varid) + ! rcode = pio_put_var(pioid, pio_varid, ntim, 1, year) + ! rcode = pio_inq_varid(pioid, 'time', pio_varid) + ! rcode = pio_put_var(pioid, pio_varid, ntim, 1, year) + ! rcode = pio_inq_varid(pioid, 'input_pftdata_filename', pio_varid) + ! rcode = pio_put_var(pioid, pio_varid, (/ 1, ntim /), (/ len_trim(string), 1 /), trim(string)) + + end do ! end of read loop + + rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT_MAX', pio_varid) + rcode = pio_put_var(pioid, pio_varid, get_pct_p2l_array(pctnatpft_max)) + + rcode = pio_inq_varid(pioid, 'PCT_CROP_MAX', pio_varid) + rcode = pio_put_var(pioid, pio_varid, get_pct_l2g_array(pctcft_max)) + + if (num_cft > 0) then + rcode = pio_inq_varid(pioid, 'PCT_CFT_MAX', pio_varid) + rcode = pio_put_var(pioid, pio_varid, get_pct_p2l_array(pctcft_max)) + end if + + ! Close the file + call pio_closefile(pioid) + + end if ! end of if-create dynamic landust dataset + + ! ====================================================================== + ! Wrap things up + ! ====================================================================== if (root_task) then write (ndiag,'(a)') @@ -954,15 +1105,15 @@ program mksurfdata write (ndiag,'(a)') write (ndiag,'(a)') 'Successfully created surface dataset' end if - close (ndiag) + ! TODO: fix the error condition here call ESMF_Finalize() !----------------------------------------------------------------------- contains !----------------------------------------------------------------------- - + subroutine change_landuse(dynpft) ! Do landuse changes such as for the poles, etc. From e80025f1fb24c2e412ceeedfc5a1313ebbec90ea Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 9 Feb 2022 09:28:26 -0700 Subject: [PATCH 049/614] some cleanup of write to 6 --- tools/mksurfdata_esmf/run/mksurfdata_in | 48 +-- .../src/mkagfirepkmonthMod.F90 | 1 - tools/mksurfdata_esmf/src/mkgdpMod.F90 | 4 +- tools/mksurfdata_esmf/src/mklaiMod.F90 | 20 +- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 31 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 15 +- tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 334 +++++++++++------- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 1 - 8 files changed, 249 insertions(+), 205 deletions(-) mode change 100644 => 120000 tools/mksurfdata_esmf/run/mksurfdata_in diff --git a/tools/mksurfdata_esmf/run/mksurfdata_in b/tools/mksurfdata_esmf/run/mksurfdata_in deleted file mode 100644 index 03cc248ceb..0000000000 --- a/tools/mksurfdata_esmf/run/mksurfdata_in +++ /dev/null @@ -1,47 +0,0 @@ -&mksurfdata_input - mksrf_flai = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.cdf5.c220206.nc' - mksrf_flai_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc' - mksrf_flakwat = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_LakePnDepth_3x3min_simyr2004_csplk_c151015.nc' - mksrf_flakwat_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' - mksrf_fwetlnd = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_lanwat.050425.nc' - mksrf_fwetlnd_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' - mksrf_forganic = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_organic_10level_5x5min_ISRIC-WISE-NCSCD_nlev7_c120830.nc' - mksrf_forganic_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' - mksrf_fsoicol = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_soilcolor_CMIP6_simyr2005_cd5.c220126.nc' - mksrf_fsoicol_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc' - mksrf_furban = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_urban_0.05x0.05_simyr2000.c220127.nc' - mksrf_furban_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' - mksrf_fgdp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_gdp_0.5x0.5_AVHRR_simyr2000.c130228.nc' - mksrf_fgdp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' - mksrf_fpeat = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_peatf_0.5x0.5_AVHRR_simyr2000.c130228.nc' - mksrf_fpeat_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' - mksrf_fvocef = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_vocef_0.5x0.5_simyr2000.c110531.nc' - mksrf_fvocef_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' - mksrf_furbtopo = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_topo.10min.cdf5.c220201.nc' - mksrf_furbtopo_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_c200129.nc' - mksrf_fglacier = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000.cdf5.c120926.nc' - mksrf_fglacier_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' - mksrf_fglacierregion = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_GlacierRegion_10x10min_nomask_cd5_c220131.nc' - mksrf_fglacierregion_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_cdf5_c200129.nc' - mksrf_fvegtyp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_1850.cdf5.c190119.nc' - mksrf_fvegtyp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' - mksrf_fhrvtyp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_1850.cdf5.c190119.nc' - mksrf_fhrvtyp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' - mksrf_fgdp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_gdp_0.5x0.5_AVHRR_simyr2000.c130228.nc' - mksrf_fgdp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' - mksrf_fsoildepth = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksf_soilthk_5x5min_ORNL-Soil_simyr1900-2015_c170630.nc' - mksrf_fsoildepth_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' - mksrf_fabm = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_abm_0.5x0.5_AVHRR_simyr2000.c130201.nc' - mksrf_fabm_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' - mksrf_ftopostats = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_topostats_1km-merge-10min_HYDRO1K-merge-nomask_simyr2000.c130402.nc' - mksrf_ftopostats_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UGRID_1km-merge-10min_HYDRO1K-merge-nomask_c130402.nc' - mksrf_fsoitex = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_soitex.10level.c010119.nc' - mksrf_fsoitex_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' - mksrf_fmax = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_fmax_0.125x0.125_c200220.nc' - mksrf_fmax_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.125x0.125_nomask_c200129.nc' - mksrf_fgrid_mesh_nx = 144 - mksrf_fgrid_mesh_ny = 96 - mksrf_fgrid_mesh = '/glade/p/cesm/cseg/inputdata/share/meshes/fv1.9x2.5_141008_ESMFmesh.nc' - fsurdat = 'surfdata_1.9x2.5_hist_78pfts_CMIP6_1850_c220119.nc' - fsurlog = 'surfdata_1.9x2.5_hist_78pfts_CMIP6_1850_c220119.log' -/ diff --git a/tools/mksurfdata_esmf/run/mksurfdata_in b/tools/mksurfdata_esmf/run/mksurfdata_in new file mode 120000 index 0000000000..dfb9810251 --- /dev/null +++ b/tools/mksurfdata_esmf/run/mksurfdata_in @@ -0,0 +1 @@ +surfdata_1.9x2.5_hist_78pfts_CMIP6_2000_c220208.namelist \ No newline at end of file diff --git a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 index 0e04a2d3e2..042750e217 100644 --- a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 +++ b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 @@ -224,7 +224,6 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) if (root_task) then write (ndiag,'(a)') 'Successfully made Agricultural fire peak month' end if - write(6,*)'finished mkagfirepkmon' end subroutine mkagfirepkmon diff --git a/tools/mksurfdata_esmf/src/mkgdpMod.F90 b/tools/mksurfdata_esmf/src/mkgdpMod.F90 index 7da1418035..1b4d8e8445 100644 --- a/tools/mksurfdata_esmf/src/mkgdpMod.F90 +++ b/tools/mksurfdata_esmf/src/mkgdpMod.F90 @@ -3,7 +3,7 @@ module mkgdpMod !----------------------------------------------------------------------- ! make GDP from input GDP data !----------------------------------------------------------------------- - ! + use ESMF use pio use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 @@ -64,6 +64,8 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, gdp_o, rc) character(len=*), parameter :: subname = 'mkgdp' !----------------------------------------------------------------------- + rc = ESMF_SUCCESS + if (root_task) then write(ndiag,*) write(ndiag,'(a)') 'Attempting to make GDP.....' diff --git a/tools/mksurfdata_esmf/src/mklaiMod.F90 b/tools/mksurfdata_esmf/src/mklaiMod.F90 index e246147c10..6c18e122a9 100644 --- a/tools/mksurfdata_esmf/src/mklaiMod.F90 +++ b/tools/mksurfdata_esmf/src/mklaiMod.F90 @@ -131,20 +131,26 @@ subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) rcode = pio_inq_dimlen(pioid_i, dimid, ntime) if (numpft_i /= numpft+1) then - write(6,*) 'WARNING: ' // trim(subname) // '(): parameter numpft+1 = ', numpft+1, & - 'does not equal input dataset numpft = ', numpft_i - write(6,*)'This inconsistency used to stop the program. Now we allow it ' - write(6,*)'because crop pfts 17-last are assumed to never use satellite lai data.' + if (root_task) then + write(ndiag,*) 'WARNING: ' // trim(subname) // '(): parameter numpft+1 = ', numpft+1, & + 'does not equal input dataset numpft = ', numpft_i + write(ndiag,*)'This inconsistency used to stop the program. Now we allow it ' + write(ndiag,*)'because crop pfts 17-last are assumed to never use satellite lai data.' + end if if (numpft_i > numpft + 1) then ! NOTE(bja, 2015-01) If this error check is determined to be ! invalid, all the loop bounds over output data in this ! routine will need to be double checked! - write(6, *) "ERROR:" // trim(subname) // "(): input numpft must be less than or equal to output numpft+1." + if (root_task) then + write(ndiag,*) (subname) //' error input numpft must be less than or equal to output numpft+1.' + end if call shr_sys_abort() end if endif if (ntime /= 12) then - write(6,*)'MKLAI: must have 12 time samples on input data' + if (root_task) then + write(ndiag,*) subname // 'error must have 12 time samples on input data' + end if call shr_sys_abort() endif @@ -155,7 +161,7 @@ subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) mhgtb_o(ns_o,0:numpft), & laimask(ns_i,0:numpft), stat=ier ) if (ier /= 0) then - write(6,*)'mklai allocation error'; call shr_sys_abort() + call shr_sys_abort(subname //' mklai allocation error ') end if ! Create iodescriptor for a single level of the input data diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 38d717e3f6..962613f616 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -178,21 +178,24 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & end do ! Diagnostic output - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Inland Water Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,201) -201 format (1x,'surface type input grid area output grid area'/ & + if (root_task) then + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) 'Inland Water Output' + write (ndiag,'(1x,70a1)') ('=',k=1,70) + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,201) +201 format (1x,'surface type input grid area output grid area'/ & 1x,' 10**6 km**2 10**6 km**2 ') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,202) glake_i*1.e-06, glake_o*1.e-06 - write (ndiag,204) garea_i*1.e-06, garea_o*1.e-06 -202 format (1x,'lakes ',f14.3,f17.3) -204 format (1x,'all surface ',f14.3,f17.3) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + write (ndiag,202) glake_i*1.e-06, glake_o*1.e-06 + write (ndiag,204) garea_i*1.e-06, garea_o*1.e-06 +202 format (1x,'lakes ',f14.3,f17.3) +204 format (1x,'all surface ',f14.3,f17.3) + end if + else do no = 1,ns_o lake_o(no) = 0. diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index cd854b5264..82992b4f3f 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -93,8 +93,8 @@ program mksurfdata use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs use shr_sys_mod , only : shr_sys_abort #ifdef TODO - use mktopostatsMod , only : mktopostats use mkVICparamsMod , only : mkVICparams + use mktopostatsMod , only : mktopostats #endif use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array @@ -661,18 +661,19 @@ program mksurfdata write(ndiag,'(a)')'calling mklai' end if call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') call pio_syncfile(pioid) ! ----------------------------------- ! TODO: ! Compute topography statistics [topo_stddev, slope] from [ftopostats] ! ----------------------------------- - ! allocate ( topo_stddev(lsize_o)) ; topo_stddev(:) = spval - ! allocate ( slope(lsize_o)) ; slope(:) = spval - ! call mktopostats ( mapfname=map_ftopostats, datfname=mksrf_ftopostats, & - ! ndiag=ndiag, topo_stddev_o=topo_stddev, slope_o=slope, std_elev=std_elev) - ! deallocate(topo_stddev + ! allocate ( topo_stddev(lsize_o)) ; topo_stddev(:) = spval + ! allocate ( slope(lsize_o)) ; slope(:) = spval + ! call mktopostats ( mksrf_ftopostats_mesh, mksrf_ftopostats, mesh_model, & + ! topo_stddev_o=topo_stddev, slope_o=slope, std_elev=std_elev, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mktopostats') + ! deallocate(topo_stddev) ! deallocate(slope) ! ----------------------------------- diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index 690dc93b2b..e015eadae4 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -4,8 +4,16 @@ module mktopostatsMod ! make various topography statistics !----------------------------------------------------------------------- - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkdomainMod , only : domain_checksame + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkutilsMod , only : chkerr + use mkvarctl , only : ndiag, root_task, mpicom + +#include implicit none private @@ -14,150 +22,213 @@ module mktopostatsMod type(ESMF_DynamicMask) :: dynamicMask + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + !=============================================================== contains !=============================================================== - subroutine mktopostats(ldomain, mapfname, datfname, ndiag, topo_stddev_o, slope_o, std_elev) - ! + subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, std_elev, topo_stddev_o, slope_o, rc) + ! make various topography statistics ! use mkdiagnosticsMod, only : output_diagnostics_continuous, output_diagnostics_continuous_outonly - use mkchecksMod, only : min_bad, max_bad + use mkchecksMod , only : min_bad, max_bad ! - ! !ARGUMENTS: - type(domain_type) , intent(in) :: ldomain + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! input model mesh + real(r8) , intent(out) :: topo_stddev_o(:) ! output grid: standard deviation of elevation (m) + real(r8) , intent(out) :: slope_o(:) ! output grid: slope (degrees) + real(r8) , intent(in) :: std_elev ! standard deviation of elevation (m) to use when not using input file + integer , intent(out) :: rc + character(len=*) , intent(in) :: mapfname ! input mapping file name character(len=*) , intent(in) :: datfname ! input data file name integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(in) :: std_elev ! standard deviation of elevation (m) to use when not using input file - real(r8) , intent(out):: topo_stddev_o(:) ! output grid: standard deviation of elevation (m) - real(r8) , intent(out):: slope_o(:) ! output grid: slope (degrees) ! - ! !LOCAL VARIABLES: - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: data_i(:) ! data on input grid - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - logical :: bypass_reading ! If should bypass reading dataset and just use a global value - - real(r8), parameter :: min_valid_topo_stddev = 0._r8 - - real(r8), parameter :: min_valid_slope = 0._r8 - real(r8), parameter :: max_valid_slope = 90._r8 - - character(len=32) :: subname = 'mktopostats' + ! local variables: + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + integer :: ni,no,k + integer :: ns_i, ns_o + integer , allocatable :: mask_i(:) + real(r8), allocatable :: rmask_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + real(r8), allocatable :: gdp_i(:) ! input grid: percent gdp + logical :: bypass_reading ! bypass reading dataset and just use a global value + integer :: ier, rcode ! error status + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + real(r8), pointer :: dataptr(:) + real(r8), parameter :: min_valid = 0._r8 ! minimum valid value + real(r8), parameter :: min_valid_topo_stddev = 0._r8 + real(r8), parameter :: min_valid_slope = 0._r8 + real(r8), parameter :: max_valid_slope = 90._r8 + character(len=*), parameter :: subname = 'mktopostats' !----------------------------------------------------------------------- - write (6,*) 'Attempting to make Topography statistics.....' + if (root_task) then + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make Topography statistics.....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) + end if + if ( std_elev >= 0.0_r8 )then - bypass_reading = .true. - write (6,*) ' By pass the reading and just use global values' - else - bypass_reading = .false. + if (root_task) then + write (ndiag,'(a)')' Bypass the reading and just use global values' + write (ndiag,'(a)')' Setting std deviation of topography to ', std_elev + write (ndiag,'(a)')' Setting slope of topography to zero' + end if + topo_stddev_o(:) = std_elev + slope_o = 0.0_r8 + RETURN end if - ! Create a dynamic mask object - ! The dynamic mask object further holds a pointer to the routine that will be called in order to - ! handle dynamically masked elements - in this case its DynMaskProc (see below) - call ESMF_DynamicMaskSetR8R8R8(dynamicMask, dynamicSrcMaskValue=czero, dynamicMaskRoutine=DynMaskProc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Open input data file + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) - ! Create a route handle - the normal way + ! Read in input mesh + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - ! Do the regridding the normal way to create the mean + ! Determine ns_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Force the mask to be one + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + mask_i(:) = 1 + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + deallocate(mask_i) ! Compute the standard deviation - ! Use the dynamic masking could be used to do this. + ! Use the dynamic masking could be used to do this. ! dst_array(no) = dst_array(no) + wt * (src_array(ni) - weighted_means(no))**2 part, ! and then just do a plain sparse matrix multiply on a src Field of all 1.0 to do the ! weight sum part, and then do the divide and sqrt locally on each PET. - ! One issue is how to get the weight_means() in for each - ! dest. location. I think that you could pass them in via the - ! dst_array and then pull them out before doing the calculation, but - ! to do so that you to stop it from zeroing out the - ! dst array which you can do by setting - ! zeroregion=ESMF_REGION_EMPTY.This would also depend on the - ! calculation happening only once for each destination location, - ! which I would guess is true, but Gerhard can confirm. - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write(6,*)'Open Topography file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(data_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() - - ! ----------------------------------------------------------------- - ! Make topography standard deviation - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'ELEVATION', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areastddev(tgridmap, data_i, topo_stddev_o, nodata=0._r8) - - call output_diagnostics_continuous_outonly(topo_stddev_o, tgridmap, "Topo Std Dev", "m", ndiag) - else - write (6,*) ' Set std deviation of topography to ', std_elev - topo_stddev_o = std_elev - end if - - ! Check validity of output data - if (min_bad(topo_stddev_o, min_valid_topo_stddev, 'topo_stddev')) then - call abort() - end if - - - ! ----------------------------------------------------------------- - ! Regrid slope - ! ----------------------------------------------------------------- - - if ( .not. bypass_reading )then - call check_ret(nf_inq_varid (ncid, 'SLOPE', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - - ! Subr. gridmap_areaave_no_srcmask should NOT be used in general. We have - ! kept it to support the rare raw data files for which we have masking on - ! the mapping file and, therefore, we do not explicitly pass the src_mask - ! as an argument. In general, users are advised to use subroutine - ! gridmap_areaave_srcmask. - call gridmap_areaave_no_srcmask(tgridmap, data_i, slope_o, nodata=0._r8) - - call output_diagnostics_continuous(data_i, slope_o, tgridmap, "Slope", "degrees", ndiag, tdomain%mask, tgridmap%frac_dst) - else - write (6,*) ' Set slope of topography to ', 0.0_r8 - slope_o = 0.0_r8 - end if - ! Check validity of output data - if (min_bad(slope_o, min_valid_slope, 'slope') .or. & - max_bad(slope_o, max_valid_slope, 'slope')) then - call abort() - end if - - - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- - - if ( .not. bypass_reading )then - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (data_i) - end if - - write (6,*) 'Successfully made Topography statistics' - write (6,*) - -end subroutine mktopostats + ! One issue is how to get the weight_means() in for each + ! dest. location. I think that you could pass them in via the + ! dst_array and then pull them out before doing the calculation, but + ! to do so that you to stop it from zeroing out the + ! dst array which you can do by setting + ! zeroregion=ESMF_REGION_EMPTY.This would also depend on the + ! calculation happening only once for each destination location, + ! which I would guess is true, but Gerhard can confirm. + + ! Read in data_i + allocate(data_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort(subname//' error in allocating data_i') + call mkpio_get_rawdata(pioid, 'ELEVATION', mesh_i, data_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + + ! Create a route handle between the input and output mesh and get frac_o + allocate(frac_o(ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() + + ! Create ESMF fields that will be used below + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create a route handle + call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=0, & + srcMaskValues=(/-987987/), dstMaskValues=(/-987987/), & + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) + + ! ----------------------------- + ! Obtain the standard deviation + ! ----------------------------- + + ! Create a dynamic mask object + ! The dynamic mask object further holds a pointer to the routine that will be called in order to + ! handle dynamically masked elements - in this case its DynMaskProc (see below) + call ESMF_DynamicMaskSetR8R8R8(dynamicMask, dynamicMaskRoutine=StdDevProc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Interpolate data_i to data_o + call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) + dataptr(:) = data_i(:) + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr(:) = 0._r8 + + call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, & + termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, & + zeroregion=ESMF_REGION_EMPTY, dynamicMaskRoutine=StdDevProc, rc=rc) + + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + topo_stddev_o(:) = dataptr(:) + + ! call output_diagnostics_continuous_outonly(topo_stddev_o, tgridmap, "Topo Std Dev", "m", ndiag) + ! Check validity of output data + if (min_bad(topo_stddev_o, min_valid_topo_stddev, 'topo_stddev')) then + call shr_sys_abort() + end if + + ! ----------------------------- + ! Obtain the slope + ! ----------------------------- + + call mkpio_get_rawdata(pioid, 'SLOPE', mesh_i, data_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) + dataptr(:) = data_i(:) + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr(:) = 0._r8 + + call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, & + termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, & + zeroregion=ESMF_REGION_EMPTY, rc=rc) + + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + slope_o(:) = dataptr(:) + + !call output_diagnostics_continuous(data_i, slope_o, tgridmap, + !"Slope", "degrees", ndiag, tdomain%mask, tgridmap%frac_dst) + + ! Check validity of output data + if (min_bad(slope_o, min_valid_slope, 'slope') .or. & + max_bad(slope_o, max_valid_slope, 'slope')) then + call shr_sys_abort() + end if + + ! Close files and deallocate dynamic memory + + if (root_task) then + write (ndiag,'(a)') 'Successfully made Topography statistics' + write (ndiag,'(a)') + end if + + end subroutine mktopostats !================================================================================================ - subroutine dynMaskProc(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, rc) + subroutine StdDevProc(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, rc) use ESMF, only : ESMF_RC_ARG_BAD @@ -170,34 +241,43 @@ subroutine dynMaskProc(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue ! local variables integer :: i, j real(ESMF_KIND_R8) :: renorm + real(ESMF_KIND_R8) :: mean !--------------------------------------------------------------- rc = ESMF_SUCCESS ! Below - ONLY if you do NOT have the source masked out then do ! the regridding (which is done explicitly here) + ! Below i are the destination points and j are the source points if (associated(dynamicMaskList)) then do i=1, size(dynamicMaskList) dynamicMaskList(i)%dstElement = czero ! set to zero renorm = 0.d0 ! reset - if (dynamicSrcMaskValue /= dynamicMaskList(i)%srcElement(j)) then - do j = 1, size(dynamicMaskList(i)%factor) - dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement + & - (dynamicMaskList(i)%factor(j) * dynamicMaskList(i)%srcElement(j)) - renorm = renorm + dynamicMaskList(i)%factor(j) + + ! Determine the mean + do j = 1, size(dynamicMaskList(i)%factor) + dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement + & + (dynamicMaskList(i)%factor(j) * dynamicMaskList(i)%srcElement(j)) + renorm = renorm + dynamicMaskList(i)%factor(j) enddo if (renorm > 0.d0) then dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement / renorm - else if (present(dynamicSrcMaskValue)) then - dynamicMaskList(i)%dstElement = dynamicSrcMaskValue else rc = ESMF_RC_ARG_BAD ! error detected return endif + mean = dynamicMaskList(i)%dstElement + + ! Now compute the standard deviation + dynamicMaskList(i)%dstElement = czero ! reset to zero + do j = 1, size(dynamicMaskList(i)%factor) + dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement + & + (dynamicMaskList(i)%factor(j) * (dynamicMaskList(i)%srcElement(j)) - mean)**2 + enddo enddo endif - end subroutine DynOcnMaskProc + end subroutine StdDevProc end module mktopostatsMod diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index d28ce76063..a1a0fb3a16 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -925,7 +925,6 @@ subroutine mkurban_topo(file_mesh_i, file_data_i, mesh_o, varname, elev_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Read topo elev dataset with unit mask everywhere - write (6,*) 'Open elevation file: ', trim(file_data_i) allocate(elev_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid, trim(varname), mesh_i, elev_i, rc=rc) From 133c5cefb0620bcff755da1215a98909b5873b75 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 9 Feb 2022 09:45:04 -0700 Subject: [PATCH 050/614] updates to get year 2000 working correctly --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 2 ++ tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml | 7 +++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 7efb090cf7..ab86f941aa 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -175,6 +175,8 @@ def main (): pft_years = "1850" elif start_year == 2000 and end_year == 2000: pft_years = "2005" + elif start_year == 2005 and end_year == 2005: + pft_years = "2005" elif start_year >= 850 and end_year <= 1849: pft_years = "0850-1849" elif start_year >= 1850 and end_year <= 2005: diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 03853a97db..30901bb95b 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -229,15 +229,14 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1850.c170629.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - - lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_1850.c190119.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2000.c170629.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2005.c170629.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_2005.c190119.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc From 752275a9cdf489376ffedd3e79f34b7a37d6963b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 10 Feb 2022 15:35:53 -0700 Subject: [PATCH 051/614] first set of changes to get topo standard deviation working --- tools/mksurfdata_esmf/run/run_mksurfdata | 4 +- tools/mksurfdata_esmf/src/CMakeLists.txt | 1 + tools/mksurfdata_esmf/src/mkfileMod.F90 | 75 +++++++++-- tools/mksurfdata_esmf/src/mkpioMod.F90 | 16 ++- tools/mksurfdata_esmf/src/mksurfdata.F90 | 46 ++++--- tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 132 ++++++++----------- 6 files changed, 161 insertions(+), 113 deletions(-) diff --git a/tools/mksurfdata_esmf/run/run_mksurfdata b/tools/mksurfdata_esmf/run/run_mksurfdata index b845ca7dcc..f961aad9d7 100755 --- a/tools/mksurfdata_esmf/run/run_mksurfdata +++ b/tools/mksurfdata_esmf/run/run_mksurfdata @@ -5,8 +5,8 @@ #PBS -q premium #PBS -l walltime=20:00 ##PBS -l select=1:ncpus=36:mpiprocs=36 -#PBS -l select=4:ncpus=36:mpiprocs=36 -##PBS -l select=16:ncpus=36:mpiprocs=9 +##PBS -l select=4:ncpus=36:mpiprocs=36 +#PBS -l select=16:ncpus=36:mpiprocs=9 # note for -l input above # -l select={num_nodes}:ncpus={max_tasks_per_node}:mpiprocs={tasks_per_node} diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 93dc3eca15..1461a89b5f 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -40,6 +40,7 @@ set(SRCFILES mkagfirepkmonthMod.F90 mksoilfmaxMod.F90 mksoiltexMod.F90 mksoildepthMod.F90 + mktopostatsMod.F90 mkurbanparMod.F90 mkutilsMod.F90 mkvarctl.F90 diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index c6dc2765fc..02f568e94f 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -2,7 +2,7 @@ module mkfileMod use ESMF use pio - use shr_kind_mod , only : r8 => shr_kind_r8 + use shr_kind_mod , only : r8 => shr_kind_r8, r4=> shr_kind_r4 use shr_sys_mod , only : shr_sys_getenv, shr_sys_abort use mkutilsMod , only : get_filename, chkerr use mkvarpar , only : nlevsoi, numrad, numstdpft @@ -25,8 +25,10 @@ module mkfileMod interface mkfile_output module procedure mkfile_output_int1d module procedure mkfile_output_int2d - module procedure mkfile_output_real1d - module procedure mkfile_output_real2d + module procedure mkfile_output_real1dr8 + module procedure mkfile_output_real2dr8 + module procedure mkfile_output_real1dr4 + module procedure mkfile_output_real2dr4 end interface mkfile_output character(len=*) , parameter :: u_FILE_u = & @@ -451,10 +453,10 @@ subroutine mkfile_define_vars(pioid, dynlanduse) call mkpio_def_spatial_var(pioid=pioid, varname='gdp', xtype=xtype, & long_name='gdp', units='unitless') - call mkpio_def_spatial_var(pioid=pioid, varname='SLOPE', xtype=xtype, & + call mkpio_def_spatial_var(pioid=pioid, varname='SLOPE', xtype=PIO_REAL, & long_name='mean topographic slope', units='degrees') - call mkpio_def_spatial_var(pioid=pioid, varname='STD_ELEV', xtype=xtype, & + call mkpio_def_spatial_var(pioid=pioid, varname='STD_ELEV', xtype=PIO_REAL, & long_name='standard deviation of elevation', units='m') if ( outnc_vic )then @@ -751,7 +753,7 @@ subroutine mkfile_output_int2d(pioid, mesh, varname, data, rc) end subroutine mkfile_output_int2d !================================================================================= - subroutine mkfile_output_real1d(pioid, mesh, varname, data, rc) + subroutine mkfile_output_real1dr8(pioid, mesh, varname, data, rc) ! input/output variables type(file_desc_t) , intent(inout) :: pioid @@ -774,10 +776,10 @@ subroutine mkfile_output_real1d(pioid, mesh, varname, data, rc) call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) call pio_freedecomp(pioid, pio_iodesc) - end subroutine mkfile_output_real1d + end subroutine mkfile_output_real1dr8 !================================================================================= - subroutine mkfile_output_real2d(pioid, mesh, varname, data, lev1name, rc) + subroutine mkfile_output_real2dr8(pioid, mesh, varname, data, lev1name, rc) ! input/output variables type(file_desc_t) , intent(inout) :: pioid @@ -800,6 +802,61 @@ subroutine mkfile_output_real2d(pioid, mesh, varname, data, lev1name, rc) rcode = pio_inq_varid(pioid, trim(varname), pio_varid) call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) call pio_freedecomp(pioid, pio_iodesc) - end subroutine mkfile_output_real2d + + end subroutine mkfile_output_real2dr8 + + !================================================================================= + subroutine mkfile_output_real1dr4(pioid, mesh, varname, data, rc) + + ! input/output variables + type(file_desc_t) , intent(inout) :: pioid + type(ESMF_Mesh) , intent(in) :: mesh + character(len=*) , intent(in) :: varname + real(r4) , intent(in) :: data(:) + integer , intent(out) :: rc + + ! local variables + type(io_desc_t) :: pio_iodesc + type(var_desc_t) :: pio_varid + integer :: rcode + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) + call pio_freedecomp(pioid, pio_iodesc) + + end subroutine mkfile_output_real1dr4 + + !================================================================================= + subroutine mkfile_output_real2dr4(pioid, mesh, varname, data, lev1name, rc) + + ! input/output variables + type(file_desc_t) , intent(inout) :: pioid + type(ESMF_Mesh) , intent(in) :: mesh + character(len=*) , intent(in) :: varname + character(len=*) , intent(in) :: lev1name + real(r4) , intent(in) :: data(:,:) + integer , intent(out) :: rc + + ! local variables + type(io_desc_t) :: pio_iodesc + type(var_desc_t) :: pio_varid + integer :: rcode + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + call pio_write_darray(pioid, pio_varid, pio_iodesc, data, rcode) + call pio_freedecomp(pioid, pio_iodesc) + + end subroutine mkfile_output_real2dr4 end module mkfileMod + diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index f6729d8f68..8f5d25421e 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -325,7 +325,7 @@ subroutine mkpio_get_rawdata2d_real8(pioid, varname, mesh_i, data_i, setframe, r character(len=*) , intent(in) :: varname ! field name in rawdata file type(ESMF_Mesh) , intent(in) :: mesh_i real(r8) , intent(inout) :: data_i(:,:) ! input raw data - integer, optional , intent(in) :: setframe + integer, optional , intent(in) :: setframe integer , intent(out) :: rc ! local variables @@ -473,7 +473,13 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, end if ! determine io descriptor for this variable - if (ndims == 2) then + if (ndims == 1) then + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) + if (root_task) then + write(ndiag,'(a,i20)') ' set iodesc for rawdata: '//trim(varname)//' with dim(1) = ',& + dimlens(1) + end if + else if (ndims == 2) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) if (root_task) then write(ndiag,'(a,i8,i8)') ' set iodesc for rawdata: '//trim(varname)//' with dim(1),dim(2) = ',& @@ -506,7 +512,7 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, call shr_sys_abort('for lon/lat support up to 3 spatial dims plus a time dim') end if else - call shr_sys_abort('rawdata input for variable '//trim(varname)//' must have ndims either 2, 3 or 4') + call shr_sys_abort('rawdata input for variable '//trim(varname)//' must have ndims either 1,2,3 or 4') end if ! deallocate memory @@ -1145,7 +1151,7 @@ subroutine mkpio_get_rawdata1d_level_real8(pioid, pio_iodesc, unlimited_index, v call ESMF_VMLogMemInfo("After call to pio_read_darray for varname "//trim(varname)) end subroutine mkpio_get_rawdata1d_level_real8 - + ! ======================================================================== subroutine mkpio_get_rawdata2d_level_real8(pioid, pio_iodesc, unlimited_index, varname, data_i) @@ -1164,7 +1170,7 @@ subroutine mkpio_get_rawdata2d_level_real8(pioid, pio_iodesc, unlimited_index, v real(r4) , allocatable :: data_real2d(:,:) real(r8) , allocatable :: data_double2d(:,:) integer :: ns_i, nlev - integer :: n, l + integer :: n, l integer :: rcode character(len=*), parameter :: subname = 'mkpio_get_rawdata1d_real4' !------------------------------------------------- diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 82992b4f3f..22540197f5 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -94,8 +94,8 @@ program mksurfdata use shr_sys_mod , only : shr_sys_abort #ifdef TODO use mkVICparamsMod , only : mkVICparams - use mktopostatsMod , only : mktopostats #endif + use mktopostatsMod , only : mktopostats use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft @@ -193,8 +193,8 @@ program mksurfdata real(r8), allocatable :: fpeat(:) ! peatland fraction of gridcell real(r8), allocatable :: soildepth(:) ! soil depth (m) integer , allocatable :: agfirepkmon(:) ! agricultural fire peak month - real(r8), allocatable :: topo_stddev(:) ! standard deviation of elevation (m) - real(r8), allocatable :: slope(:) ! topographic slope (degrees) + real(r4), allocatable :: topo_stddev(:) ! standard deviation of elevation (m) + real(r4), allocatable :: slope(:) ! topographic slope (degrees) real(r8), allocatable :: vic_binfl(:) ! VIC b real(r8), allocatable :: vic_ws(:) ! VIC Ws parameter (unitless) real(r8), allocatable :: vic_dsmax(:) ! VIC Dsmax parameter (mm/day) @@ -211,6 +211,8 @@ program mksurfdata integer :: rc type(ESMF_LogKind_Flag) :: logkindflag type(ESMF_VM) :: vm + integer :: petcount + integer :: stride character(len=CS) :: varname logical :: create_esmf_pet_files = .true. character(len=32) :: subname = 'mksrfdata' ! program name @@ -240,8 +242,8 @@ program mksurfdata if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_VMGetGlobal(vm, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_VMGet(vm, mpicommunicator=mpicom, localPet=iam, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMGet(vm, mpicommunicator=mpicom, localPet=iam, petcount=petcount, & + ssiLocalPetCount=stride, rc=rc) call ESMF_LogSet(flush=.true.) call ESMF_LogWrite("mksurfdata starting", ESMF_LOGMSG_INFO) @@ -250,20 +252,9 @@ program mksurfdata ! ------------------ ! the following returns pio_iosystem - ! call pio_init(iam, mpicom, 1, 0, 36, PIO_REARR_SUBSET, pio_iosystem) - ! TODO: generalize iotype - - call pio_init(iam, mpicom, 4, 0, 36, PIO_REARR_SUBSET, pio_iosystem) - - ! call pio_init(comp_rank=iam, & - ! comp_comm=mpicom, & - ! num_iotasks = 8, & - ! num_aggregator = 0, & - ! stride = 36, & - ! rearr = PIO_REARR_SUBSET, & - ! iosystem = pio_iosystem) + call pio_init(iam, mpicom, max(1,petcount/stride), 0, stride, PIO_REARR_SUBSET, pio_iosystem) - pio_iotype = PIO_IOTYPE_PNETCDF + pio_iotype = PIO_IOTYPE_NETCDF pio_ioformat = PIO_64BIT_DATA call ESMF_LogWrite("finished initializing PIO", ESMF_LOGMSG_INFO) @@ -360,6 +351,25 @@ program mksurfdata rcode = pio_enddef(pioid) end if + ! DEBUG + allocate ( topo_stddev(lsize_o)) ; topo_stddev(:) = spval + allocate ( slope(lsize_o)) ; slope(:) = spval + call mktopostats ( mksrf_ftopostats_mesh, mksrf_ftopostats, mesh_model, & + topo_stddev_o=topo_stddev, slope_o=slope, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mktopostats') + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing topo_stddev " + call mkfile_output(pioid, mesh_model, 'STD_ELEV', topo_stddev, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for STD_ELEV') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing slope" + call mkfile_output(pioid, mesh_model, 'SLOPE', slope, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for SLOPE') + call pio_syncfile(pioid) + end if + deallocate(topo_stddev) + deallocate(slope) + ! DEBUG + ! ----------------------------------- ! Write out coordinate variables ! ----------------------------------- diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index e015eadae4..3c28b2f863 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -9,15 +9,15 @@ module mktopostatsMod use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkesmfMod , only : get_meshareas use mkutilsMod , only : chkerr - use mkvarctl , only : ndiag, root_task, mpicom - -#include + use mkvarctl , only : ndiag, root_task, mpicom, std_elev implicit none private +#include + public :: mktopostats ! make topo stddev & mean slope type(ESMF_DynamicMask) :: dynamicMask @@ -29,7 +29,7 @@ module mktopostatsMod contains !=============================================================== - subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, std_elev, topo_stddev_o, slope_o, rc) + subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, rc) ! make various topography statistics ! @@ -40,36 +40,28 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, std_elev, topo_stddev_o character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! input model mesh - real(r8) , intent(out) :: topo_stddev_o(:) ! output grid: standard deviation of elevation (m) - real(r8) , intent(out) :: slope_o(:) ! output grid: slope (degrees) - real(r8) , intent(in) :: std_elev ! standard deviation of elevation (m) to use when not using input file + real(r4) , intent(out) :: topo_stddev_o(:) ! output grid: standard deviation of elevation (m) + real(r4) , intent(out) :: slope_o(:) ! output grid: slope (degrees) integer , intent(out) :: rc - - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out ! ! local variables: type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o type(file_desc_t) :: pioid integer :: ni,no,k integer :: ns_i, ns_o - integer , allocatable :: mask_i(:) - real(r8), allocatable :: rmask_i(:) - real(r8), allocatable :: frac_o(:) + real(r4), allocatable :: data_i(:) + real(r4), pointer :: dataptr(:) real(r8), allocatable :: area_i(:) real(r8), allocatable :: area_o(:) - real(r8), allocatable :: gdp_i(:) ! input grid: percent gdp - logical :: bypass_reading ! bypass reading dataset and just use a global value integer :: ier, rcode ! error status - type(ESMF_Field) :: field_i - type(ESMF_Field) :: field_o - real(r8), pointer :: dataptr(:) - real(r8), parameter :: min_valid = 0._r8 ! minimum valid value - real(r8), parameter :: min_valid_topo_stddev = 0._r8 - real(r8), parameter :: min_valid_slope = 0._r8 - real(r8), parameter :: max_valid_slope = 90._r8 + integer :: srcTermProcessing_Value = 0 + real(r4), parameter :: min_valid = 0._r4 ! minimum valid value + real(r4), parameter :: min_valid_topo_stddev = 0._r4 + real(r4), parameter :: min_valid_slope = 0._r4 + real(r4), parameter :: max_valid_slope = 90._r4 character(len=*), parameter :: subname = 'mktopostats' !----------------------------------------------------------------------- @@ -96,7 +88,7 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, std_elev, topo_stddev_o call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh - mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_UGRID, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) @@ -108,29 +100,6 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, std_elev, topo_stddev_o call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Force the mask to be one - allocate(mask_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - mask_i(:) = 1 - call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(mask_i) - - ! Compute the standard deviation - ! Use the dynamic masking could be used to do this. - ! dst_array(no) = dst_array(no) + wt * (src_array(ni) - weighted_means(no))**2 part, - ! and then just do a plain sparse matrix multiply on a src Field of all 1.0 to do the - ! weight sum part, and then do the divide and sqrt locally on each PET. - - ! One issue is how to get the weight_means() in for each - ! dest. location. I think that you could pass them in via the - ! dst_array and then pull them out before doing the calculation, but - ! to do so that you to stop it from zeroing out the - ! dst array which you can do by setting - ! zeroregion=ESMF_REGION_EMPTY.This would also depend on the - ! calculation happening only once for each destination location, - ! which I would guess is true, but Gerhard can confirm. - ! Read in data_i allocate(data_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort(subname//' error in allocating data_i') @@ -138,22 +107,23 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, std_elev, topo_stddev_o if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - ! Create a route handle between the input and output mesh and get frac_o - allocate(frac_o(ns_o),stat=ier) - if (ier/=0) call shr_sys_abort() - ! Create ESMF fields that will be used below - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle + if (root_task) then + write(ndiag,'(a)') subname//' creating a routehandle ' + end if call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=0, & - srcMaskValues=(/-987987/), dstMaskValues=(/-987987/), & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (root_task) then + write(ndiag,'(a)') subname//' finished creating a routehandle ' + end if call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) ! ----------------------------- @@ -163,19 +133,20 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, std_elev, topo_stddev_o ! Create a dynamic mask object ! The dynamic mask object further holds a pointer to the routine that will be called in order to ! handle dynamically masked elements - in this case its DynMaskProc (see below) - call ESMF_DynamicMaskSetR8R8R8(dynamicMask, dynamicMaskRoutine=StdDevProc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! call ESMF_DynamicMaskSetR4R8R4(dynamicMask, dynamicMaskRoutine=StdDevProc, rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return ! Interpolate data_i to data_o call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) dataptr(:) = data_i(:) call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr(:) = 0._r8 + dataptr(:) = 0._r4 - call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, & - termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, & - zeroregion=ESMF_REGION_EMPTY, dynamicMaskRoutine=StdDevProc, rc=rc) + ! call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, dynamicMask=dynamicMask, rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) @@ -184,9 +155,13 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, std_elev, topo_stddev_o ! call output_diagnostics_continuous_outonly(topo_stddev_o, tgridmap, "Topo Std Dev", "m", ndiag) ! Check validity of output data - if (min_bad(topo_stddev_o, min_valid_topo_stddev, 'topo_stddev')) then - call shr_sys_abort() - end if + !if (min_bad(topo_stddev_o, min_valid_topo_stddev, 'topo_stddev')) then + !call shr_sys_abort() + !end if + + ! TODO: get the output diagnostics working + ! call output_diagnostics_continuous_outonly(area_i, area_o, mask_i, frac_o, & + ! data_i, topo_stddev_o, "Topo Std Dev", "m", ndiag) ! ----------------------------- ! Obtain the slope @@ -199,11 +174,10 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, std_elev, topo_stddev_o dataptr(:) = data_i(:) call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr(:) = 0._r8 + dataptr(:) = 0._r4 call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, & - termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, & - zeroregion=ESMF_REGION_EMPTY, rc=rc) + termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_EMPTY, rc=rc) call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -213,10 +187,10 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, std_elev, topo_stddev_o !"Slope", "degrees", ndiag, tdomain%mask, tgridmap%frac_dst) ! Check validity of output data - if (min_bad(slope_o, min_valid_slope, 'slope') .or. & - max_bad(slope_o, max_valid_slope, 'slope')) then - call shr_sys_abort() - end if + !if (min_bad(slope_o, min_valid_slope, 'slope') .or. & + ! max_bad(slope_o, max_valid_slope, 'slope')) then + !call shr_sys_abort() + !end if ! Close files and deallocate dynamic memory @@ -233,15 +207,15 @@ subroutine StdDevProc(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, use ESMF, only : ESMF_RC_ARG_BAD ! input/output arguments - type(ESMF_DynamicMaskElementR8R8R8) , pointer :: dynamicMaskList(:) - real(ESMF_KIND_R8) , intent(in), optional :: dynamicSrcMaskValue - real(ESMF_KIND_R8) , intent(in), optional :: dynamicDstMaskValue + type(ESMF_DynamicMaskElementR4R8R4) , pointer :: dynamicMaskList(:) + real(ESMF_KIND_R4) , intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R4) , intent(in), optional :: dynamicDstMaskValue integer , intent(out) :: rc ! local variables integer :: i, j - real(ESMF_KIND_R8) :: renorm - real(ESMF_KIND_R8) :: mean + real(ESMF_KIND_R4) :: renorm + real(ESMF_KIND_R4) :: mean !--------------------------------------------------------------- rc = ESMF_SUCCESS @@ -252,7 +226,7 @@ subroutine StdDevProc(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, if (associated(dynamicMaskList)) then do i=1, size(dynamicMaskList) - dynamicMaskList(i)%dstElement = czero ! set to zero + dynamicMaskList(i)%dstElement = 0.d0 ! set to zero renorm = 0.d0 ! reset ! Determine the mean @@ -270,7 +244,7 @@ subroutine StdDevProc(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, mean = dynamicMaskList(i)%dstElement ! Now compute the standard deviation - dynamicMaskList(i)%dstElement = czero ! reset to zero + dynamicMaskList(i)%dstElement = 0.d0 ! reset to zero do j = 1, size(dynamicMaskList(i)%factor) dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement + & (dynamicMaskList(i)%factor(j) * (dynamicMaskList(i)%srcElement(j)) - mean)**2 From 093dbc6c53ad768df76c1e463dabee2aa5c9962f Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 10 Feb 2022 16:32:04 -0700 Subject: [PATCH 052/614] got standard deviation of topography working --- tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index 3c28b2f863..01b7173398 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -133,8 +133,8 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, ! Create a dynamic mask object ! The dynamic mask object further holds a pointer to the routine that will be called in order to ! handle dynamically masked elements - in this case its DynMaskProc (see below) - ! call ESMF_DynamicMaskSetR4R8R4(dynamicMask, dynamicMaskRoutine=StdDevProc, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_DynamicMaskSetR4R8R4(dynamicMask, dynamicMaskRoutine=StdDevProc, handleAllElements=.true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return ! Interpolate data_i to data_o call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) @@ -143,10 +143,10 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:) = 0._r4 - ! call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, dynamicMask=dynamicMask, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, rc=rc) + call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, dynamicMask=dynamicMask, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + ! call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) @@ -241,14 +241,16 @@ subroutine StdDevProc(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, rc = ESMF_RC_ARG_BAD ! error detected return endif + dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement / renorm mean = dynamicMaskList(i)%dstElement ! Now compute the standard deviation dynamicMaskList(i)%dstElement = 0.d0 ! reset to zero do j = 1, size(dynamicMaskList(i)%factor) dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement + & - (dynamicMaskList(i)%factor(j) * (dynamicMaskList(i)%srcElement(j)) - mean)**2 + (dynamicMaskList(i)%factor(j) * (dynamicMaskList(i)%srcElement(j) - mean)**2) enddo + dynamicMaskList(i)%dstElement = sqrt(dynamicMaskList(i)%dstElement/renorm) enddo endif From 6d058a81330f862877e74736690744f13f9a6c36 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 10 Feb 2022 16:37:11 -0700 Subject: [PATCH 053/614] fixed typo in previous test --- tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index 01b7173398..72f9f652ee 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -241,10 +241,9 @@ subroutine StdDevProc(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, rc = ESMF_RC_ARG_BAD ! error detected return endif - dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement / renorm - mean = dynamicMaskList(i)%dstElement ! Now compute the standard deviation + mean = dynamicMaskList(i)%dstElement dynamicMaskList(i)%dstElement = 0.d0 ! reset to zero do j = 1, size(dynamicMaskList(i)%factor) dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement + & From b45ac6d9303d18372142fb0ceedac8d026090ab9 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 10 Feb 2022 17:28:19 -0700 Subject: [PATCH 054/614] got both slope and std_elev working --- tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 25 +++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index 72f9f652ee..491a7f85d9 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -22,6 +22,8 @@ module mktopostatsMod type(ESMF_DynamicMask) :: dynamicMask + logical :: calculate_stddev = .true. + character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -176,8 +178,11 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:) = 0._r4 - call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, & - termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_EMPTY, rc=rc) + calculate_stddev = .false. + ! call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, & + ! termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_EMPTY, rc=rc) + call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, dynamicMask=dynamicMask, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -243,13 +248,15 @@ subroutine StdDevProc(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, endif ! Now compute the standard deviation - mean = dynamicMaskList(i)%dstElement - dynamicMaskList(i)%dstElement = 0.d0 ! reset to zero - do j = 1, size(dynamicMaskList(i)%factor) - dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement + & - (dynamicMaskList(i)%factor(j) * (dynamicMaskList(i)%srcElement(j) - mean)**2) - enddo - dynamicMaskList(i)%dstElement = sqrt(dynamicMaskList(i)%dstElement/renorm) + if (calculate_stddev) then + mean = dynamicMaskList(i)%dstElement + dynamicMaskList(i)%dstElement = 0.d0 ! reset to zero + do j = 1, size(dynamicMaskList(i)%factor) + dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement + & + (dynamicMaskList(i)%factor(j) * (dynamicMaskList(i)%srcElement(j) - mean)**2) + enddo + dynamicMaskList(i)%dstElement = sqrt(dynamicMaskList(i)%dstElement/renorm) + end if enddo endif From 72eb8d8ab31077904dc2e8974fcd56fb8399a3ff Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 10 Feb 2022 17:28:57 -0700 Subject: [PATCH 055/614] got both slope and std_elev working --- tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index 491a7f85d9..fb567e371e 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -178,9 +178,7 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:) = 0._r4 - calculate_stddev = .false. - ! call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, & - ! termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_EMPTY, rc=rc) + calculate_stddev = .false. ! module variable used by dynamic mask call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, dynamicMask=dynamicMask, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return From 34e6ec14c70b2c7648537ad977b1a907929f8ea3 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 10 Feb 2022 20:33:44 -0700 Subject: [PATCH 056/614] refactored mksoilcol to use dynamic masking instead of multi-level arrays --- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 256 +++++++++++++++------ 1 file changed, 189 insertions(+), 67 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index 740b834a52..0bafc9cede 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -6,7 +6,7 @@ module mksoilcolMod use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r4, get_meshareas + use mkesmfMod , only : get_meshareas use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag, mpicom, MPI_INTEGER, MPI_MAX use mkvarctl , only : soil_color_override, unsetcol @@ -21,6 +21,9 @@ module mksoilcolMod private :: mkrank private :: check_global_areas + integer :: num_soilcolors + type(ESMF_DynamicMask) :: dynamicMask + character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -41,22 +44,24 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r ! local variables: type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + type(ESMF_Field) :: field_dstfrac type(file_desc_t) :: pioid integer :: ni,no integer :: ns_i, ns_o integer :: n,l,k integer , allocatable :: mask_i(:) - real(r4), allocatable :: frac_i(:) + real(r4), allocatable :: rmask_i(:) real(r4), allocatable :: frac_o(:) real(r8), allocatable :: area_i(:) real(r8), allocatable :: area_o(:) - real(r4), allocatable :: data_i(:,:) - real(r4), allocatable :: data_o(:,:) real(r4), allocatable :: soil_color_i(:) - logical :: has_color ! whether this grid cell has non-zero color + real(r4), pointer :: dataptr(:) + real(r8), pointer :: dataptr_r8(:) integer :: nsoilcol_local - integer :: maxindex(1) integer :: rcode, ier + integer :: srcTermProcessing_Value = 0 character(len=*), parameter :: subname = 'mksoilcol' !----------------------------------------------------------------------- @@ -98,30 +103,23 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Get the landmask from the file and reset the mesh mask based on that - allocate(frac_i(ns_i), stat=ier) + allocate(rmask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, rmask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i - if (frac_i(ni) > 0._r4) then + if (rmask_i(ni) > 0._r4) then mask_i(ni) = 1 else mask_i(ni) = 0 end if end do - deallocate(frac_i) + deallocate(rmask_i) call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Create a route handle between the input and output mesh and get frac_o - allocate(frac_o(ns_o),stat=ier) - if (ier/=0) call shr_sys_abort() - call create_routehandle_r4(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - ! Read in input soil color data allocate(soil_color_i(ns_i),stat=ier) if (ier/=0) call shr_sys_abort() @@ -129,6 +127,13 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + ! Scale the input soil color by the input mask + do ni = 1,ns_i + if (mask_i(ni) == 0) then + soil_color_i(ni) = 0._r4 + end if + end do + ! Determine maximum number of soil colors across all processors ! This will be used for the ungridded dimension of data_o below nsoilcol_local = maxval(soil_color_i) @@ -136,58 +141,55 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r ! TODO: MPI_SUCCESS could not be accessed from mkvarctl !if (rcode /= MPI_SUCCESS) call shr_sys_abort('error for mpi_allredice in '//trim(subname)) - ! Now determine data_i as a real 2d array - for every possible soil color create a global - ! field with gridcells equal to 1 for that soil color and zero elsewhere - allocate(data_i(0:nsoilcol,ns_i)) - data_i(:,:) = 0._r4 - do l = 0,nsoilcol - do n = 1,ns_i - if (int(soil_color_i(n)) == l) then - data_i(l,n) = 1._r4 * mask_i(n) - end if - end do - end do + ! Set module variable (used in the get_dominant_soilcol routine) + num_soilcolors = nsoilcol + if (root_task) then + write(ndiag,*)'DEBUG: num_soilcolors = ',num_soilcolors + end if - ! Regrid data_i to data_o - allocate(data_o(0:nsoilcol, ns_o),stat=ier) - if (ier/=0) call shr_sys_abort() - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, nsoilcol, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(subname//'after regrid rawdata in '//trim(subname)) + ! Create ESMF fields that will be used below + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_dstfrac = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Determine output soil color - soil_color_o(:) = 0 - do no = 1,ns_o - ! If the output cell has any non-zero-colored inputs, then set the weight of - ! zero-colored inputs to 0, to ensure that the zero-color is NOT dominant. - if (any(data_o(1:nsoilcol,no) > 0.)) then - has_color = .true. - data_o(0,no) = 0.0 - else - has_color = .false. - end if + ! Create a route handle + call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & + dstFracField= field_dstfrac, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - ! Rank non-zero weights by color type. wsti(1) is the most extensive color type. - if (has_color) then - call mkrank (nsoilcol, data_o(0:nsoilcol,no), maxindex) - soil_color_o(no) = maxindex(1) - end if + ! Determin frac_o + call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(frac_o(ns_o)) + frac_o(:) = real(dataptr_r8(:), kind=r4) + + ! Create a dynamic mask object + ! The dynamic mask object further holds a pointer to the routine that will be called in order to + ! handle dynamically masked elements - in this case its DynMaskProc (see below) + call ESMF_DynamicMaskSetR4R8R4(dynamicMask, dynamicMaskRoutine=get_dominant_soilcol, & + dynamicSrcMaskValue=0._r4, handleAllElements=.true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! If land but no color, set color to 15 (in older dataset generic soil color 4) - if (nsoilcol == 8) then - if (soil_color_o(no)==0) then - soil_color_o(no) = 4 - end if - else if (nsoilcol == 20) then - if (soil_color_o(no)==0) then - soil_color_o(no) = 15 - end if - else - write(6,*) 'MKSOILCOL error: unhandled nsoilcol: ', nsoilcol - call shr_sys_abort() - end if + ! Determine dominant soil color in the field regrid call below + call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) + dataptr(:) = soil_color_i(:) + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr(:) = 0._r4 - ! Error checks + call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, dynamicMask=dynamicMask, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do no = 1,ns_o + soil_color_o(no) = int(dataptr(no)) if (soil_color_o(no) < 0 .or. soil_color_o(no) > nsoilcol) then write (6,*) 'MKSOILCOL error: land model soil color = ', & soil_color_o(no),' is not valid for lon,lat = ',no @@ -210,6 +212,12 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_dstfrac, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() if (root_task) then write (ndiag,'(a)') 'Successfully made soil color classes' @@ -265,8 +273,8 @@ subroutine check_global_areas(name, ns_i, ns_o, nsoilcol, & ! Compare global areas on input and output grids ! input/otuput variables - character(len=*) , intent(in) :: name - integer , intent(in) :: ns_i + character(len=*) , intent(in) :: name + integer , intent(in) :: ns_i integer , intent(in) :: ns_o integer , intent(in) :: nsoilcol real(r4) , intent(in) :: soil_color_i(ns_i) @@ -274,7 +282,7 @@ subroutine check_global_areas(name, ns_i, ns_o, nsoilcol, & real(r8) , intent(in) :: area_i(ns_i) real(r8) , intent(in) :: area_o(ns_o) integer , intent(in) :: mask_i(ns_i) - real(r4) , intent(in) :: frac_o(ns_o) + real(r4) , intent(in) :: frac_o(ns_o) ! local variables integer :: ni, no, l, k @@ -316,4 +324,118 @@ subroutine check_global_areas(name, ns_i, ns_o, nsoilcol, & end if end subroutine check_global_areas + !================================================================================================ + subroutine get_dominant_soilcol(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, rc) + + use ESMF, only : ESMF_RC_ARG_BAD + + ! input/output arguments + type(ESMF_DynamicMaskElementR4R8R4) , pointer :: dynamicMaskList(:) + real(ESMF_KIND_R4) , intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R4) , intent(in), optional :: dynamicDstMaskValue + integer , intent(out) :: rc + + ! local variables + integer :: ni, no, n + real(ESMF_KIND_R4) :: wts_o(0:num_soilcolors) + logical :: has_color + integer :: soil_color_o + integer :: maxindex(1) + !--------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Below - ONLY if you do NOT have the source masked out then do + ! the regridding (which is done explicitly here) + ! Below i are the destination points and j are the source points + + if (associated(dynamicMaskList)) then + call ESMF_LogWrite("DEBUG: determining soil colors") + + do no = 1, size(dynamicMaskList) + + wts_o(:) = 0.d0 + do ni = 1, size(dynamicMaskList(no)%factor) + if (dynamicSrcMaskValue /= dynamicMaskList(no)%srcElement(ni)) then + do n = 0,num_soilcolors + if (dynamicMaskList(no)%srcElement(ni) == n) then + wts_o(n) = wts_o(n) + dynamicMaskList(no)%factor(ni) + end if + enddo + end if + end do + + ! If the output cell has any non-zero-colored inputs, then set the weight of + ! zero-colored inputs to 0, to ensure that the zero-color is NOT dominant. + soil_color_o = 0 + if (any(wts_o(1:num_soilcolors) > 0.)) then + has_color = .true. + wts_o(0) = 0.0 + else + has_color = .false. + end if + + ! Find index of maximum weight + if (has_color) then + call ESMF_LogWrite("DEBUG: ranking soil colors") + call mkrank (num_soilcolors, wts_o(0:num_soilcolors), maxindex) + soil_color_o = maxindex(1) + end if + + ! If land but no color, set color to 15 (in older dataset generic soil color 4) + if (num_soilcolors == 8) then + if (soil_color_o == 0) then + soil_color_o = 4 + end if + else if (num_soilcolors == 20) then + if (soil_color_o == 0) then + call ESMF_LogWrite("DEBUG: setting soil color to 15") + soil_color_o = 15 + end if + end if + dynamicMaskList(no)%dstElement = real(soil_color_o, kind=r4) + + end do + end if + + contains + + subroutine mkrank (n, a, iv) + ! Return indices of largest [num] values in array [a]. + + ! input/output variables + integer , intent(in) :: n !array length + real(r4), intent(in) :: a(0:n) !array to be ranked + integer , intent(out):: iv(1) !index to [num] largest values in array [a] + + ! local variables: + real(r4) :: a_max !maximum value in array + real(r4) :: delmax !tolerance for finding if larger value + integer :: i !array index + integer :: m !do loop index + integer :: k !do loop index + integer :: miss !missing data value + !----------------------------------------------------------------------- + + ! Find index of largest non-zero number + delmax = 1.e-06 + miss = 9999 + iv(1) = miss + + a_max = -9999. + do i = 0, n + if (a(i)>0. .and. (a(i)-a_max)>delmax) then + a_max = a(i) + iv(1) = i + end if + end do + ! iv(1) = miss indicates no values > 0. this is an error + if (iv(1) == miss) then + write (6,*) 'MKRANK error: iv(1) = missing' + call shr_sys_abort() + end if + end subroutine mkrank + + end subroutine get_dominant_soilcol + end module mksoilcolMod From 37e1d99653340e368878b662813765af41238f50 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 11 Feb 2022 10:06:51 -0700 Subject: [PATCH 057/614] removed print statements from mksoilcolMod --- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index 0bafc9cede..edb0918ac3 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -350,7 +350,6 @@ subroutine get_dominant_soilcol(dynamicMaskList, dynamicSrcMaskValue, dynamicDst ! Below i are the destination points and j are the source points if (associated(dynamicMaskList)) then - call ESMF_LogWrite("DEBUG: determining soil colors") do no = 1, size(dynamicMaskList) @@ -377,7 +376,6 @@ subroutine get_dominant_soilcol(dynamicMaskList, dynamicSrcMaskValue, dynamicDst ! Find index of maximum weight if (has_color) then - call ESMF_LogWrite("DEBUG: ranking soil colors") call mkrank (num_soilcolors, wts_o(0:num_soilcolors), maxindex) soil_color_o = maxindex(1) end if @@ -389,7 +387,6 @@ subroutine get_dominant_soilcol(dynamicMaskList, dynamicSrcMaskValue, dynamicDst end if else if (num_soilcolors == 20) then if (soil_color_o == 0) then - call ESMF_LogWrite("DEBUG: setting soil color to 15") soil_color_o = 15 end if end if From 2183718751acfe2b1fb1cee92827024008f88e0b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 11 Feb 2022 15:37:14 -0700 Subject: [PATCH 058/614] updates to get soiltex use the dynamic masking capability --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 3 + tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 3 - tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 193 ++++++++++++--------- tools/mksurfdata_esmf/src/mksurfdata.F90 | 43 ++--- 4 files changed, 133 insertions(+), 109 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 02f568e94f..7fc19f9183 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -307,6 +307,9 @@ subroutine mkfile_define_vars(pioid, dynlanduse) lev1name='nlevsoi', & long_name='percent clay', units='unitless') + call mkpio_def_spatial_var(pioid=pioid, varname='mapunits', xtype=PIO_INT, & + long_name='soil texture map units', units='unitless') + call mkpio_def_spatial_var(pioid=pioid, varname='ORGANIC', xtype=xtype, & lev1name='nlevsoi', & long_name='organic matter density at soil levels', & diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index edb0918ac3..59748e8732 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -143,9 +143,6 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r ! Set module variable (used in the get_dominant_soilcol routine) num_soilcolors = nsoilcol - if (root_task) then - write(ndiag,*)'DEBUG: num_soilcolors = ',num_soilcolors - end if ! Create ESMF fields that will be used below field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 51988b581e..aa6859a5f0 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -10,7 +10,7 @@ module mksoiltexMod use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r4, get_meshareas + use mkesmfMod , only : get_meshareas use mkutilsMod , only : chkerr use mkvarctl use mkvarpar @@ -23,6 +23,11 @@ module mksoiltexMod integer, parameter :: num=2 ! set soil mapunit number integer, parameter :: nlsm=4 ! number of soil textures + integer :: num_soil_textures + type(ESMF_DynamicMask) :: dynamicMask + + integer :: mapunit_value_max + character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -47,6 +52,9 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o ! local variables type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + type(ESMF_Field) :: field_dstfrac type(file_desc_t) :: pioid type(var_desc_t) :: pio_varid integer :: pio_vartype @@ -54,38 +62,28 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o integer :: ni,no integer :: ns_i, ns_o integer :: n,l,m - integer :: gindex, lindex character(len=38) :: typ ! soil texture based on ... integer :: nlay ! number of soil layers integer :: mapunittemp ! temporary igbp soil mapunit integer :: maxovr integer , allocatable :: mask_i(:) - real(r4), allocatable :: area_i(:) - real(r4), allocatable :: area_o(:) - real(r4), allocatable :: frac_i(:) + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + real(r4), allocatable :: rmask_i(:) real(r4), allocatable :: frac_o(:) real(r4), allocatable :: sand_i(:,:) ! input grid: percent sand real(r4), allocatable :: clay_i(:,:) ! input grid: percent clay + real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits + real(r4), pointer :: dataptr(:) + real(r8), pointer :: dataptr_r8(:) character(len=38) :: soil(0:nlsm) ! name of each soil texture real(r4) :: gast_i(0:nlsm) ! global area, by texture type real(r4) :: gast_o(0:nlsm) ! global area, by texture type - real(r4) :: wt ! map overlap weight real(r4) :: sum_fldi ! global sum of dummy input fld real(r4) :: sum_fldo ! global sum of dummy output fld real(r4) :: sumtex integer :: rcode, ier ! error status - integer :: mapunit_value_max - integer :: mapunit_value_min - integer :: mapunit_value - integer :: nmax - integer :: loop, nloops - real(r4) :: max_value - integer :: max_index(1) - real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits - real(r4), allocatable :: data_i(:,:) - real(r4), allocatable :: data_o(:,:) - real(r4), allocatable :: global_max_value(:) - real(r4), allocatable :: global_max_index(:) + integer :: srcTermProcessing_Value = 0 character(len=*), parameter :: subname = 'mksoiltex' !----------------------------------------------------------------------- @@ -149,14 +147,14 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Get the landmask from the file and reset the mesh mask based on that - allocate(frac_i(ns_i), stat=ier) + allocate(rmask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, rmask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i - if (frac_i(ni) > 0._r4) then + if (rmask_i(ni) > 0._r4) then mask_i(ni) = 1 else mask_i(ni) = 0 @@ -165,14 +163,6 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Create a route handle between the input and output mesh - ! Can only use this routehandle to map fields containing r4 data - allocate(frac_o(ns_o),stat=ier) - if (ier/=0) call shr_sys_abort() - call create_routehandle_r4(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - ! Read in mapunit data allocate(mapunit_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() @@ -180,55 +170,62 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - ! Now determine data_i as a real 2d array - for every possible soil color create a global - ! field with gridcells equal to 1 for that soil color and zero elsewhere + ! Scale the input soil color by the input mask + ! do ni = 1,ns_i + ! if (mask_i(ni) == 0) then + ! mapunit_i(ni) = 0._r4 + ! end if + ! end do + + ! Determine mapunit_value_max (set it as a module variable so that it can be + ! accessible to gen_dominant_mapunit) rcode = pio_inq_dimid (pioid, 'max_value_mapunit', dimid) rcode = pio_inq_dimlen (pioid, dimid, mapunit_value_max) - mapunit_value_min = 0 - nmax = 100 - nloops = (mapunit_value_max - mapunit_value_min + nmax)/nmax - allocate(global_max_value(ns_o)) ; global_max_value(:) = -999. - if (ier/=0) call shr_sys_abort() - allocate(global_max_index(ns_o)) ; global_max_index(:) = 0 - if (ier/=0) call shr_sys_abort() - allocate(data_i(nmax,ns_i)) - if (ier/=0) call shr_sys_abort() - allocate(data_o(nmax,ns_o)) - if (ier/=0) call shr_sys_abort() + ! Create ESMF fields that will be used below + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_dstfrac = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Create a route handle + call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & + dstFracField= field_dstfrac, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - mapunit_o(:) = 0 - do loop = 1,nloops - data_i(:,:) = 0._r4 - do lindex = 0,nmax-1 - mapunit_value = lindex + (nmax*(loop-1)) - if (mapunit_value <= mapunit_value_max) then - do ni = 1,ns_i - if (int(mapunit_i(ni)) == mapunit_value) then - data_i(lindex+1,ni) = 1._r4 - end if - end do - end if - end do - - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 1, nmax, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - do no = 1,ns_o - max_index = maxloc(data_o(:,no)) - max_value = data_o(max_index(1),no) - if ( max_value > global_max_value(no)) then - global_max_value(no) = max_value - mapunit_o(no) = max_index(1) + (nmax*(loop-1)) - 1 - if (mapunit_o(no) < 0 .or. mapunit_o(no) > mapunit_value_max) then - call shr_sys_abort('mapunit_o is invalid') - end if - end if - end do + ! Determin frac_o + call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(frac_o(ns_o)) + frac_o(:) = real(dataptr_r8(:), kind=r4) + + ! Create a dynamic mask object + ! The dynamic mask object further holds a pointer to the routine that will be called in order to + ! handle dynamically masked elements - in this case its DynMaskProc (see below) + call ESMF_DynamicMaskSetR4R8R4(dynamicMask, dynamicMaskRoutine=get_dominant_mapunit, & + handleAllElements=.true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Determine dominant soil color in the field regrid call below + call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) + dataptr(:) = mapunit_i(:) + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr(:) = 0._r4 + + call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, dynamicMask=dynamicMask, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do no = 1,ns_o + mapunit_o(no) = int(dataptr(no)) end do - deallocate(data_i) - deallocate(data_o) ! Get dimensions from input file and allocate memory for sand_i and clay_i rcode = pio_inq_dimid (pioid, 'number_of_layers', dimid) @@ -252,7 +249,8 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o if (mapunit_o(no) > 0) then ! valid value is obtained if (mapunit_o(no) > mapunit_value_max) then - call shr_sys_abort("mapunit_o is out of bounds") + write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) + ! call shr_sys_abort("mapunit_o is out of bounds") end if do l = 1, nlay sand_o(no,l) = sand_i(mapunit_o(no),l) @@ -268,7 +266,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o end do ! ----------------------------------------------------------------- - ! Error check + ! TODO: ! Compare global area of each soil type on input and output grids ! ----------------------------------------------------------------- @@ -291,7 +289,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o ! else if (sand_i(mapunittemp,l) >= 50.) then ! typ = 'sands' ! else if (clay_i(mapunittemp,l)+sand_i(mapunittemp,l) < 50.) then - ! if (frac_i(ni) /= 0.) then + ! if (rmask_i(ni) /= 0.) then ! typ = 'silts' ! else !if (mask(ni) == 0.) then no data ! typ = 'no soil: ocean, glacier, lake, no data' @@ -362,10 +360,6 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o ! write (ndiag,'(1x,a38,f16.3,f17.3)') soil(l),gast_i(l)*1.e-6,gast_o(l)*1.e-6 ! end do - ! Deallocate dynamic memory - deallocate(sand_i,clay_i,mapunit_i) - deallocate(mask_i) - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) @@ -379,4 +373,45 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o end subroutine mksoiltex + !================================================================================================ + subroutine get_dominant_mapunit(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, rc) + + use ESMF, only : ESMF_RC_ARG_BAD + + ! input/output arguments + type(ESMF_DynamicMaskElementR4R8R4) , pointer :: dynamicMaskList(:) + real(ESMF_KIND_R4) , intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R4) , intent(in), optional :: dynamicDstMaskValue + integer , intent(out) :: rc + + ! local variables + integer :: ni, no, n + real(ESMF_KIND_R4) :: wts_o(0:mapunit_value_max) + integer :: maxindex(1) + !--------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (associated(dynamicMaskList)) then + do no = 1, size(dynamicMaskList) + dynamicMaskList(no)%dstElement = 0.d0 + wts_o(:) = 0.d0 + do ni = 1, size(dynamicMaskList(no)%factor) + if (dynamicMaskList(no)%srcElement(ni) > 0.d0) then + do n = 0,mapunit_value_max + if (dynamicMaskList(no)%srcElement(ni) == n) then + wts_o(n) = wts_o(n) + dynamicMaskList(no)%factor(ni) + end if + enddo + end if + end do + + ! Determine the most dominant index of wts_o + maxindex = maxloc(wts_o(:)) + dynamicMaskList(no)%dstElement = real(maxindex(1)-1, kind=r4) + end do + end if + + end subroutine get_dominant_mapunit + end module mksoiltexMod diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 22540197f5..4f95a89206 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -351,25 +351,6 @@ program mksurfdata rcode = pio_enddef(pioid) end if - ! DEBUG - allocate ( topo_stddev(lsize_o)) ; topo_stddev(:) = spval - allocate ( slope(lsize_o)) ; slope(:) = spval - call mktopostats ( mksrf_ftopostats_mesh, mksrf_ftopostats, mesh_model, & - topo_stddev_o=topo_stddev, slope_o=slope, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mktopostats') - if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing topo_stddev " - call mkfile_output(pioid, mesh_model, 'STD_ELEV', topo_stddev, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for STD_ELEV') - if (root_task) write(ndiag, '(a)') trim(subname)//" writing slope" - call mkfile_output(pioid, mesh_model, 'SLOPE', slope, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for SLOPE') - call pio_syncfile(pioid) - end if - deallocate(topo_stddev) - deallocate(slope) - ! DEBUG - ! ----------------------------------- ! Write out coordinate variables ! ----------------------------------- @@ -675,16 +656,24 @@ program mksurfdata call pio_syncfile(pioid) ! ----------------------------------- - ! TODO: ! Compute topography statistics [topo_stddev, slope] from [ftopostats] ! ----------------------------------- - ! allocate ( topo_stddev(lsize_o)) ; topo_stddev(:) = spval - ! allocate ( slope(lsize_o)) ; slope(:) = spval - ! call mktopostats ( mksrf_ftopostats_mesh, mksrf_ftopostats, mesh_model, & - ! topo_stddev_o=topo_stddev, slope_o=slope, std_elev=std_elev, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mktopostats') - ! deallocate(topo_stddev) - ! deallocate(slope) + allocate ( topo_stddev(lsize_o)) ; topo_stddev(:) = spval + allocate ( slope(lsize_o)) ; slope(:) = spval + call mktopostats ( mksrf_ftopostats_mesh, mksrf_ftopostats, mesh_model, & + topo_stddev_o=topo_stddev, slope_o=slope, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mktopostats') + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing topo_stddev " + call mkfile_output(pioid, mesh_model, 'STD_ELEV', topo_stddev, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for STD_ELEV') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing slope" + call mkfile_output(pioid, mesh_model, 'SLOPE', slope, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for SLOPE') + call pio_syncfile(pioid) + end if + deallocate(topo_stddev) + deallocate(slope) ! ----------------------------------- ! TODO: From 179d73b2093ea0b48494e402cff516f6921a0307 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 12 Feb 2022 14:52:03 -0700 Subject: [PATCH 059/614] cleanup of soiltexMod.F90 --- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 37 +++++++++++++++------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index aa6859a5f0..acb450da31 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -177,7 +177,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o ! end if ! end do - ! Determine mapunit_value_max (set it as a module variable so that it can be + ! Determine mapunit_value_max (set it as a module variable so that it can be ! accessible to gen_dominant_mapunit) rcode = pio_inq_dimid (pioid, 'max_value_mapunit', dimid) rcode = pio_inq_dimlen (pioid, dimid, mapunit_value_max) @@ -276,7 +276,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o ! allocate(area_o(ns_o)) ! call get_meshareas(mesh_o, area_o, rc) ! if (chkerr(rc,__LINE__,u_FILE_u)) return - + ! ! input grid: global areas by texture class ! gast_i(:) = 0. ! do l = 1, nlay @@ -308,7 +308,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o ! gast_i(m) = gast_i(m) + area_i(ni)*mask_i(ni)*re**2 ! end do ! end do - + ! ! output grid: global areas by texture class ! gast_o(:) = 0. ! do l = 1, nlay @@ -335,19 +335,19 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o ! gast_o(m) = gast_o(m) + area_o(no)*frac_o(no)*re**2 ! end do ! end do - + ! ! Diagnostic output - + ! write (ndiag,*) ! write (ndiag,'(1x,70a1)') ('=',l=1,70) ! write (ndiag,*) 'Soil Texture Output' ! write (ndiag,'(1x,70a1)') ('=',l=1,70) ! write (ndiag,*) - + ! write (ndiag,*) 'The following table of soil texture classes is for comparison only.' ! write (ndiag,*) 'The actual data is continuous %sand, %silt and %clay not textural classes' ! write (ndiag,*) - + ! write (ndiag,*) ! write (ndiag,'(1x,70a1)') ('.',l=1,70) ! write (ndiag,1001) @@ -355,11 +355,11 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o ! 1x,33x,' 10**6 km**2',' 10**6 km**2') ! write (ndiag,'(1x,70a1)') ('.',l=1,70) ! write (ndiag,*) - + ! do l = 0, nlsm ! write (ndiag,'(1x,a38,f16.3,f17.3)') soil(l),gast_i(l)*1.e-6,gast_o(l)*1.e-6 ! end do - + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) @@ -388,6 +388,8 @@ subroutine get_dominant_mapunit(dynamicMaskList, dynamicSrcMaskValue, dynamicDst integer :: ni, no, n real(ESMF_KIND_R4) :: wts_o(0:mapunit_value_max) integer :: maxindex(1) + real(ESMF_KIND_R4) :: maxvalue + character(len=*), parameter :: subname = 'mksoiltex' !--------------------------------------------------------------- rc = ESMF_SUCCESS @@ -405,10 +407,21 @@ subroutine get_dominant_mapunit(dynamicMaskList, dynamicSrcMaskValue, dynamicDst enddo end if end do - + ! Determine the most dominant index of wts_o - maxindex = maxloc(wts_o(:)) - dynamicMaskList(no)%dstElement = real(maxindex(1)-1, kind=r4) + maxvalue = -999._r4 + maxindex = -999 + do n = 0,mapunit_value_max + if (wts_o(n) > maxvalue) then + maxindex(1) = n + maxvalue = wts_o(n) + end if + end do + if (maxindex(1) > mapunit_value_max) then + write(6,*)'mapunit_o is out of bounds ',maxindex(1) + call shr_sys_abort(subname//" mapunit_o is out of bounds") + end if + dynamicMaskList(no)%dstElement = real(maxindex(1), kind=r4) end do end if From b3cbcb5bd1613bec088283f036de8d4b315ae238 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 12 Feb 2022 15:21:52 -0700 Subject: [PATCH 060/614] refactored mkagfirepkmonthMod.F90 --- .../src/mkagfirepkmonthMod.F90 | 267 ++++++++---------- .../mksurfdata_esmf/src/mkdiagnosticsMod.F90 | 136 +++++---- tools/mksurfdata_esmf/src/mkpeatMod.F90 | 1 - 3 files changed, 206 insertions(+), 198 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 index 042750e217..83a8fdc795 100644 --- a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 +++ b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 @@ -10,12 +10,12 @@ module mkagfirepkmonthMod use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkpioMod , only : mkpio_iodesc_rawdata, mkpio_get_rawdata_level - use mkesmfMod , only : regrid_rawdata, create_routehandle_r4, get_meshareas + use mkpioMod , only : mkpio_get_rawdata_level + use mkesmfMod , only : get_meshareas use mkutilsMod , only : chkerr use mkvarctl , only : ndiag, root_task - use mkvarpar , only : re use mkchecksMod , only : min_bad, max_bad + use mkdiagnosticsMod, only : output_diagnostics_index implicit none private ! By default make data private @@ -23,11 +23,12 @@ module mkagfirepkmonthMod #include public :: mkagfirepkmon ! Set agricultural fire peak month - private :: define_months ! define month strings - integer , parameter :: min_valid_value = 1 - integer , parameter :: max_valid_value = 12 - integer , parameter :: unsetmon = 13 ! flag to indicate agricultural fire peak month NOT set + integer , parameter :: min_valid = 1 + integer , parameter :: max_valid = 12 + integer , parameter :: unsetmon = 13 + + type(ESMF_DynamicMask) :: dynamicMask character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -50,29 +51,20 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) ! local variables: type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + type(ESMF_Field) :: field_dstfrac type(file_desc_t) :: pioid - integer :: ni,no,l + integer :: ni,no integer :: ns_i, ns_o integer , allocatable :: mask_i(:) - real(r4), allocatable :: frac_i(:) + real(r4), allocatable :: rmask_i(:) real(r4), allocatable :: frac_o(:) - real(r8), allocatable :: area_i(:) - real(r8), allocatable :: area_o(:) - real(r4), allocatable :: data_i(:,:) - real(r4), allocatable :: data_o(:,:) - integer :: max_index(1) - integer , allocatable :: agfirepkmon_i(:) ! input grid: agricultural fire peak month - integer :: nagfirepkmon ! number of peak months - character(len=35), allocatable :: month(:) ! name of each month - integer :: rcode, ier ! error status - integer, parameter :: unsetmon = 13 ! flag to indicate agricultural fire peak month NOT set - integer, parameter :: miss = unsetmon ! missing data indicator - integer, parameter :: min_valid = 1 ! minimum valid value - integer, parameter :: max_valid = 13 ! maximum valid value - real(r8), allocatable :: loc_gast_i(:) ! local global area, by surface type - real(r8), allocatable :: loc_gast_o(:) ! local global area, by surface type - real(r8), allocatable :: gast_i(:) ! global area, by surface type - real(r8), allocatable :: gast_o(:) ! global area, by surface type + integer , allocatable :: idata_i(:) ! input grid: agricultural fire peak month + real(r4), pointer :: dataptr(:) + real(r8), pointer :: dataptr_r8(:) + integer :: rcode, ier ! error status + integer :: srcTermProcessing_Value = 0 character(len=*), parameter :: subname = 'mkagfirepkmon' !----------------------------------------------------------------------- @@ -101,14 +93,14 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Get the landmask from the file and reset the mesh mask based on that - allocate(frac_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort(subname//" ERROR in allocating frac_i") + allocate(rmask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" ERROR in allocating rmask_i") allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort(subname//" ERROR in allocating mask_i") - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, rmask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i - if (frac_i(ni) > 0.) then + if (rmask_i(ni) > 0.) then mask_i(ni) = 1 else mask_i(ni) = 0 @@ -118,148 +110,139 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Read in agfirepkmon_i - allocate(agfirepkmon_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort(subname//" error in allocating agfirepkmon_i") - call mkpio_get_rawdata(pioid, 'abm', mesh_i, agfirepkmon_i, rc=rc) + allocate(idata_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort(subname//" error in allocating idata_i") + call mkpio_get_rawdata(pioid, 'abm', mesh_i, idata_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - ! Create a route handle between the input and output mesh and get frac_o - allocate(frac_o(ns_o),stat=ier) - if (ier/=0) call shr_sys_abort() - call create_routehandle_r4(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + ! Create ESMF fields that will be used below + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_dstfrac = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - - ! Now determine data_i as a real 2d array - for every possible soil color create a global - ! field with gridcells equal to 1 for that soil color and zero elsewhere - allocate(data_i(min_valid_value:max_valid,ns_i),stat=ier) - if (ier/=0) call shr_sys_abort(subname//' error in allocating data_i') - data_i(:,:) = 0._r4 - do l = min_valid,max_valid - do ni = 1,ns_i - if (int(agfirepkmon_i(ni)) == l .and. int(agfirepkmon_i(ni)) /= miss) then - data_i(l,ni) = 1._r4 * mask_i(ni) - end if - end do - end do - ! Regrid data_i to data_o - ! Note that any input point that is outside the range [min_valid_value,max_valid_value] - ! will be ignored; this ignores input points with value of unsetmon - allocate(data_o(min_valid:max_valid, ns_o),stat=ier) - if (ier/=0) call shr_sys_abort(subname//' error in allocating data_o') - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, min_valid, max_valid, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(subname//'after regrid rawdata in '//trim(subname)) + ! Create a route handle + call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & + dstFracField= field_dstfrac, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) + + ! Determin frac_o + call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(frac_o(ns_o)) + frac_o(:) = real(dataptr_r8(:), kind=r4) + + ! Create a dynamic mask object + ! The dynamic mask object further holds a pointer to the routine that will be called in order to + ! handle dynamically masked elements - in this case its DynMaskProc (see below) + call ESMF_DynamicMaskSetR4R8R4(dynamicMask, dynamicMaskRoutine=get_dominant_indices, & + handleAllElements=.true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Determine dominant fire month + ! **NOTE** the use of the dynamicMask argument to the ESMF_FieldRegrid call + call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) + dataptr(:) = real(idata_i(:), kind=r4) + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr(:) = 0._r4 + call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, dynamicMask=dynamicMask, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return do no = 1,ns_o - max_index = maxloc(data_o(:,no)) - agfirepkmon_o(no) = max_index(1) + agfirepkmon_o(no) = int(dataptr(no)) end do ! Check validity of output data if (min_bad(agfirepkmon_o, min_valid, 'agfirepkmon') .or. & - max_bad(agfirepkmon_o, max_valid, 'agfirepkmon')) then - call shr_sys_abort() - end if + max_bad(agfirepkmon_o, unsetmon , 'agfirepkmon')) then + call shr_sys_abort() + end if + + ! Close the file + call pio_closefile(pioid) ! ----------------------------------------------------------------- ! Output diagnostics comparing global area of each peak month on input and output grids - ! - ! WJS (3-4-13): I am trying to generally put these diagnostics in mkdiagnosticsMod, but - ! so far there isn't a general diagnostics routine for categorical data - ! - ! TODO(wjs, 2016-01-22) Now there is a routine for this: output_diagnostics_index. - ! However, it currently doesn't provide the capability for named months. Either add - ! that capability or decide it's not important, then delete the below code, instead - ! calling output_diagnostics_index. ! ----------------------------------------------------------------- - ! nagfirepkmon = maxval(agfirepkmon_i) - ! allocate(gast_i(1:nagfirepkmon),gast_o(1:nagfirepkmon),month(1:nagfirepkmon)) - ! call define_months(nagfirepkmon, month) - - ! gast_i(:) = 0.0_r8 - ! do ni = 1,ns_i - ! k = agfirepkmon_i(ni) - ! gast_i(k) = gast_i(k) + area_src(ni)*mask(ni)*re**2 - ! end do - ! gast_o(:) = 0.0_r8 - ! do no = 1,ns_o - ! k = agfirepkmon_o(no) - ! gast_o(k) = gast_o(k) + area_dst(no)*frac_dst(no)*re**2 - ! end do + ! TODO: fix this + ! call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, idata_i, agfirepkmon_o, & + ! 'peak fire month', ndiag) - ! area comparison - - ! write (ndiag,*) - ! write (ndiag,'(1x,70a1)') ('=',k=1,70) - ! write (ndiag,*) 'Agricultural fire peak month Output' - ! write (ndiag,'(1x,70a1)') ('=',k=1,70) - - ! write (ndiag,*) - ! write (ndiag,'(1x,70a1)') ('.',k=1,70) - ! write (ndiag,1001) - ! 1001 format (1x,'peak month',20x,' input grid area output grid area',/ & - ! 1x,33x,' 10**6 km**2',' 10**6 km**2') - ! write (ndiag,'(1x,70a1)') ('.',k=1,70) - ! write (ndiag,*) - - ! do k = 1, nagfirepkmon - ! write (ndiag,1002) month(k),gast_i(k)*1.e-6,gast_o(k)*1.e-6 - ! 1002 format (1x,a35,f16.3,f17.3) - ! end do - - ! Close the file - call pio_closefile(pioid) - + ! ----------------------------------------------------------------- ! Release memory + ! ----------------------------------------------------------------- + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - !call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_dstfrac, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) if (root_task) then write (ndiag,'(a)') 'Successfully made Agricultural fire peak month' + write (ndiag,*) end if end subroutine mkagfirepkmon - !=============================================================== - subroutine define_months(nagfirepkmon, month) - ! - ! Define month strings - ! - ! input/output variables - integer , intent(in) :: nagfirepkmon ! max input value (including the 'unset' special value) - character(len=*), intent(out):: month(:) ! name of each month value - !----------------------------------------------------------------------- - - if (nagfirepkmon == unsetmon) then - if (size(month) < 13) then - write(6,*) 'month array too small: ', size(month), ' < 13' - call shr_sys_abort() - end if - month(1) = 'January ' - month(2) = 'February ' - month(3) = 'March ' - month(4) = 'April ' - month(5) = 'May ' - month(6) = 'June ' - month(7) = 'July ' - month(8) = 'August ' - month(9) = 'September ' - month(10) = 'October ' - month(11) = 'November ' - month(12) = 'December ' - month(13) = 'no agricultural fire peak month data' - else - write(6,*)'nagfirepkmon value of ',nagfirepkmon,' not supported' - call shr_sys_abort() + !================================================================================================ + subroutine get_dominant_indices(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, rc) + + ! input/output arguments + type(ESMF_DynamicMaskElementR4R8R4) , pointer :: dynamicMaskList(:) + real(ESMF_KIND_R4) , intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R4) , intent(in), optional :: dynamicDstMaskValue + integer , intent(out) :: rc + + ! local variables + integer :: ni, no, n + real(ESMF_KIND_R4) :: wts_o(min_valid:max_valid) + integer :: maxindex(1) + logical :: hasdata + !--------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (associated(dynamicMaskList)) then + do no = 1, size(dynamicMaskList) + hasdata = .false. + wts_o(:) = 0.d0 + do ni = 1, size(dynamicMaskList(no)%factor) + if (dynamicMaskList(no)%srcElement(ni) > 0.d0) then + do n = min_valid,max_valid + if ( dynamicMaskList(no)%srcElement(ni) == n) then + wts_o(n) = wts_o(n) + dynamicMaskList(no)%factor(ni) + hasdata = .true. + end if + enddo + end if + end do + + ! Determine the most dominant index of wts_o + if (hasdata) then + maxindex = maxloc(wts_o(:)) + dynamicMaskList(no)%dstElement = real(maxindex(1), kind=r4) + else + dynamicMaskList(no)%dstElement = real(unsetmon, kind=r4) + end if + end do end if - end subroutine define_months + end subroutine get_dominant_indices end module mkagfirepkmonthMod diff --git a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 index c3806abda4..67b6e577bd 100644 --- a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 @@ -28,23 +28,24 @@ module mkdiagnosticsMod contains !=============================================================== - subroutine output_diagnostics_area(area_i, area_o, mask_i, data_i, data_o, name, percent, ndiag) + subroutine output_diagnostics_area(mesh_i, mesh_o, mask_i, data_i, data_o, name, percent, ndiag, rc) ! Output diagnostics for a field that gives either fraction or percent of grid cell area - use mkvarpar, only : re - ! input/output variables - real(r8) , intent(in) :: area_i(:) - real(r8) , intent(in) :: area_o(:) - integer , intent(in) :: mask_i(:) - real(r8) , intent(in) :: data_i(:) ! data on input grid - real(r8) , intent(in) :: data_o(:) ! data on output grid - character(len=*) , intent(in) :: name ! name of field - logical , intent(in) :: percent ! is field specified as percent? (alternative is fraction) - integer , intent(in) :: ndiag + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o + integer , intent(in) :: mask_i(:) + real(r8) , intent(in) :: data_i(:) ! data on input grid + real(r8) , intent(in) :: data_o(:) ! data on output grid + character(len=*) , intent(in) :: name ! name of field + logical , intent(in) :: percent ! is field specified as percent? (alternative is fraction) + integer , intent(in) :: ndiag + integer , intent(out) :: rc ! local variables: + integer :: ns_i, ns_o ! sizes of input & output grids + integer :: ni,no,k ! indices real(r8) :: loc_gdata_i ! local_global sum of input data real(r8) :: loc_gdata_o ! local_global sum of output data real(r8) :: gdata_i ! global sum of input data @@ -53,14 +54,27 @@ subroutine output_diagnostics_area(area_i, area_o, mask_i, data_i, data_o, name, real(r8) :: loc_garea_o ! local global sum of output area real(r8) :: garea_i ! global sum of input area real(r8) :: garea_o ! global sum of output area - integer :: ns_i, ns_o ! sizes of input & output grids - integer :: ni,no,k ! indices integer :: ier ! error code + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) character(len=*), parameter :: subname = "output_diagnostics_area" !------------------------------------------------------------------------------ - ns_i = size(data_i) - ns_o = size(data_o) + rc = ESMF_SUCCESS + + ! Determine ns_i and ns_o + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine areas + allocate(area_i(ns_i)) + allocate(area_o(ns_o)) + call get_meshareas(mesh_i, area_i, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call get_meshareas(mesh_o, area_o, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return ! Error check for array size consistencies if (size(mask_i) /= ns_i) then @@ -74,8 +88,8 @@ subroutine output_diagnostics_area(area_i, area_o, mask_i, data_i, data_o, name, loc_gdata_i = 0. loc_garea_i = 0. do ni = 1,ns_i - loc_garea_i = loc_garea_i + area_i(ni) * re**2 - loc_gdata_i = loc_gdata_i + data_i(ni) * area_i(ni) * mask_i(ni) * re**2 + loc_garea_i = loc_garea_i + area_i(ni) + loc_gdata_i = loc_gdata_i + data_i(ni) * area_i(ni) * mask_i(ni) end do call mpi_reduce(loc_gdata_i,gdata_i,1,MPI_REAL8,MPI_SUM,0,mpicom,ier) @@ -83,8 +97,8 @@ subroutine output_diagnostics_area(area_i, area_o, mask_i, data_i, data_o, name, loc_gdata_o = 0. loc_garea_o = 0. do no = 1,ns_o - loc_garea_o = loc_garea_o + area_o(no) * re**2 - loc_gdata_o = loc_gdata_o + data_o(no) * area_o(no) * re**2 + loc_garea_o = loc_garea_o + area_o(no) + loc_gdata_o = loc_gdata_o + data_o(no) * area_o(no) end do call mpi_reduce(loc_gdata_o,gdata_o,1,MPI_REAL8,MPI_SUM,0,mpicom,ier) @@ -271,40 +285,55 @@ subroutine output_diagnostics_continuous_outonly(area_o, frac_o, data_o, name, u end subroutine output_diagnostics_continuous_outonly !=============================================================== - subroutine output_diagnostics_index(area_i, area_o, mask_i, frac_o, data_i, data_o, name, minval, maxval, ndiag) + subroutine output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & + data_i, data_o, name, ndiag, rc) ! ! Output diagnostics for an index field: area of each index in input and output ! - use mkvarpar, only : re - ! input/output variables - real(r8) , intent(in) :: area_i(:) - real(r8) , intent(in) :: area_o(:) - integer , intent(in) :: mask_i(:) - real(r8) , intent(in) :: frac_o(:) - integer , intent(in) :: data_i(:) ! data on input grid - integer , intent(in) :: data_o(:) ! data on output grid - character(len=*) , intent(in) :: name ! name of field - integer , intent(in) :: minval ! minimum valid value - integer , intent(in) :: maxval ! minimum valid value - integer , intent(in) :: ndiag ! unit number for diagnostic output + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o + integer , intent(in) :: mask_i(:) + real(r8) , intent(in) :: frac_o(:) + integer , intent(in) :: data_i(:) ! data on input grid + integer , intent(in) :: data_o(:) ! data on output grid + character(len=*) , intent(in) :: name ! name of field + integer , intent(in) :: ndiag ! unit number for diagnostic output + integer , intent(out) :: rc ! local variables: integer :: ns_i, ns_o ! sizes of input & output grids integer :: ni, no, k ! indices + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) real(r8), allocatable :: loc_garea_i(:) ! input grid: global area of each index real(r8), allocatable :: loc_garea_o(:) ! output grid: global area of each index real(r8), allocatable :: garea_i(:) ! input grid: global area of each index real(r8), allocatable :: garea_o(:) ! output grid: global area of each index integer :: ier ! error status + integer :: max_valid_loc + integer :: max_valid + integer :: min_valid character(len=*), parameter :: subname = 'output_diagnostics_index' !----------------------------------------------------------------------- - ! Error check for array size consistencies + rc = ESMF_SUCCESS - ns_i = size(area_i) - ns_o = size(area_o) + ! Determine ns_i and ns_o + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine areas + allocate(area_i(ns_i)) + allocate(area_o(ns_o)) + call get_meshareas(mesh_i, area_i, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call get_meshareas(mesh_o, area_o, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Error check for array size consistencies if (size(data_i) /= ns_i .or. size(data_o) /= ns_o) then write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) write(6,*) 'size(data_i) = ', size(data_i) @@ -313,12 +342,6 @@ subroutine output_diagnostics_index(area_i, area_o, mask_i, frac_o, data_i, data write(6,*) 'ns_o = ', ns_o call shr_sys_abort() end if - if (size(frac_o) /= ns_o) then - write(6,*) subname//' ERROR: incorrect size of frac_o' - write(6,*) 'size(frac_o) = ', size(frac_o) - write(6,*) 'ns_o = ', ns_o - call shr_sys_abort() - end if if (size(mask_i) /= ns_i) then write(6,*) subname//' ERROR: incorrect size of mask_i' write(6,*) 'size(mask_i) = ', size(mask_i) @@ -326,28 +349,33 @@ subroutine output_diagnostics_index(area_i, area_o, mask_i, frac_o, data_i, data call shr_sys_abort() end if + max_valid_loc = maxval(data_i) + call mpi_reduce(max_valid_loc, (/max_valid/), 1, MPI_INT, MPI_SUM, 0, mpicom, ier) + ! Sum areas on input grid - allocate(loc_garea_i(minval:maxval), stat=ier) - allocate(garea_i(minval:maxval), stat=ier) + ! For now hard-wire min_valid to 1 + min_valid = 1 + allocate(loc_garea_i(min_valid:max_valid), stat=ier) + allocate(garea_i(min_valid:max_valid), stat=ier) if (ier/=0) call shr_sys_abort() loc_garea_i(:) = 0. do ni = 1, ns_i k = data_i(ni) - if (k >= minval .and. k <= maxval) then - loc_garea_i(k) = loc_garea_i(k) + area_i(ni) * mask_i(ni) * re**2 + if (k >= min_valid .and. k <= max_valid) then + loc_garea_i(k) = loc_garea_i(k) + area_i(ni) * mask_i(ni) end if end do call mpi_reduce(loc_garea_i, garea_i, size(garea_i), size(garea_i), MPI_REAL8, MPI_SUM, 0, mpicom, ier) ! Sum areas on output grid - allocate(loc_garea_o(minval:maxval), stat=ier) - allocate(garea_o(minval:maxval), stat=ier) + allocate(loc_garea_o(min_valid:max_valid), stat=ier) + allocate(garea_o(min_valid:max_valid), stat=ier) if (ier/=0) call shr_sys_abort() loc_garea_o(:) = 0. do no = 1, ns_o k = data_o(no) - if (k >= minval .and. k <= maxval) then - loc_garea_o(k) = garea_o(k) + area_o(no) * frac_o(no) * re**2 + if (k >= min_valid .and. k <= max_valid) then + loc_garea_o(k) = garea_o(k) + area_o(no) * frac_o(no) end if end do call mpi_reduce(loc_garea_o, garea_o, size(garea_o), size(garea_o), MPI_REAL8, MPI_SUM, 0, mpicom, ier) @@ -355,15 +383,13 @@ subroutine output_diagnostics_index(area_i, area_o, mask_i, frac_o, data_i, data ! Write results if (root_task) then write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,'(1x,60a1)') ('.',k=1,60) write (ndiag,2001) 2001 format (1x,'index input grid area output grid area',/ & 1x,' 10**6 km**2 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - do k = minval, maxval - write (ndiag,2002) k, garea_i(k)*1.e-06, garea_o(k)*1.e-06 -2002 format (1x,i9,f17.3,f18.3) + write (ndiag,'(1x,60a1)') ('.',k=1,60) + do k = min_valid, max_valid + write (ndiag,'(1x,i9,f17.3,f18.3)') k, garea_i(k)*1.e-06, garea_o(k)*1.e-06 end do end if diff --git a/tools/mksurfdata_esmf/src/mkpeatMod.F90 b/tools/mksurfdata_esmf/src/mkpeatMod.F90 index cbe68b4775..6dc4a00108 100644 --- a/tools/mksurfdata_esmf/src/mkpeatMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpeatMod.F90 @@ -60,7 +60,6 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) real(r8) :: gglac_o ! output grid: global glac real(r8) :: garea_o ! output grid: global area integer :: ier, rcode ! error status - real(r8), allocatable :: data_i(:) ! 2d data on input grid for dominant search real(r8), parameter :: min_valid = 0._r8 ! minimum valid value real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value character(len=*), parameter :: subname = 'mkpeat' From b263c9fe59620f250454e2eb8ed03fcf99bd644a Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 13 Feb 2022 11:25:09 -0700 Subject: [PATCH 061/614] more cleanup --- tools/mksurfdata_esmf/run/run_mksurfdata | 6 +- .../mksurfdata_esmf/src/mkdiagnosticsMod.F90 | 3 +- tools/mksurfdata_esmf/src/mkdomainMod.F90 | 3 + .../src/mkglacierregionMod.F90 | 4 +- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 9 +- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 176 ++++++++------- tools/mksurfdata_esmf/src/mkpftMod.F90 | 2 + tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 212 ++++++++---------- tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 | 10 +- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 21 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 75 +++++-- .../mksurfdata_map/src/mkagfirepkmonthMod.F90 | 3 +- tools/mksurfdata_map/src/mkharvestMod.F90 | 41 ++-- 13 files changed, 302 insertions(+), 263 deletions(-) diff --git a/tools/mksurfdata_esmf/run/run_mksurfdata b/tools/mksurfdata_esmf/run/run_mksurfdata index f961aad9d7..589b69f248 100755 --- a/tools/mksurfdata_esmf/run/run_mksurfdata +++ b/tools/mksurfdata_esmf/run/run_mksurfdata @@ -6,7 +6,8 @@ #PBS -l walltime=20:00 ##PBS -l select=1:ncpus=36:mpiprocs=36 ##PBS -l select=4:ncpus=36:mpiprocs=36 -#PBS -l select=16:ncpus=36:mpiprocs=9 +##PBS -l select=16:ncpus=36:mpiprocs=9 +#PBS -l select=16:ncpus=36:mpiprocs=14 # note for -l input above # -l select={num_nodes}:ncpus={max_tasks_per_node}:mpiprocs={tasks_per_node} @@ -19,4 +20,5 @@ mkdir -p $TMPDIR #make # -np {total_tasks} -mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata +#mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata +mpiexec_mpt -p "%g:" -np 224 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata diff --git a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 index 67b6e577bd..bacfc2799d 100644 --- a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 @@ -215,7 +215,7 @@ subroutine output_diagnostics_continuous(area_i, area_o, mask_i, frac_o, & 2002 format (1x,' ', a24, a24) write (ndiag,'(1x,70a1)') ('.',k=1,70) write (ndiag,*) - write (ndiag,2003) name, gdata_i, gdata_o + write (ndiag,2003) name, gdata_i, gdata_o 2003 format (1x,a12, f22.3,f17.3) end if @@ -269,7 +269,6 @@ subroutine output_diagnostics_continuous_outonly(area_o, frac_o, data_o, name, u ! Diagnostic output if (root_task) then - write (ndiag,*) write (ndiag,*) write (ndiag,'(1x,70a1)') ('.',k=1,70) write (ndiag,2001) diff --git a/tools/mksurfdata_esmf/src/mkdomainMod.F90 b/tools/mksurfdata_esmf/src/mkdomainMod.F90 index f14b85a3f1..0d25eb6646 100644 --- a/tools/mksurfdata_esmf/src/mkdomainMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdomainMod.F90 @@ -33,6 +33,7 @@ subroutine mkdomain(mesh_o, lon_o, lat_o, rc) integer :: no integer :: ns_o integer :: spatialDim + integer :: k real(r8), allocatable :: ownedElemCoords(:) character(len=*), parameter :: subname = 'mkdomain' !----------------------------------------------------------------------- @@ -40,6 +41,8 @@ subroutine mkdomain(mesh_o, lon_o, lat_o, rc) rc = ESMF_SUCCESS if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,70a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to create model lats and lons from model mesh .....' end if diff --git a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 index ccaff35ad8..0f4e2e5848 100644 --- a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 @@ -48,7 +48,7 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r type(ESMF_RouteHandle) :: routehandle ! nearest neighbor routehandle type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid - integer :: ni,no,l + integer :: ni,no,l,k integer :: ns_i, ns_o integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) @@ -66,6 +66,8 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r rc = ESMF_SUCCESS if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to make glacier region .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index 9e19627239..4037acb4f1 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -115,6 +115,8 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constan rc = ESMF_SUCCESS if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to make harvest fields .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) @@ -126,9 +128,7 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constan if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Normally read in the harvesting file, and then regrid to output grid - if (root_task) write(ndiag,'(a)') ' opening input data file' rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) - if (root_task) write(ndiag,'(a)') ' finished opening input data file' ! If all veg then write out output data with values set to harvest_initval and return if (all_veg) then @@ -160,10 +160,8 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constan ! Read in input mesh if (.not. ESMF_MeshIsCreated(mesh_i)) then - if (root_task) write(ndiag,'(a)') ' creating input mesh' mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag,'(a)') ' finished creating input mesh' end if ! Determine ns_i @@ -197,11 +195,9 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constan ! Create a route handle between the input and output mesh ! NOTE: this must be done after mask_i is set in mesh_i if (.not. ESMF_RouteHandleIsCreated(routehandle_r8)) then - if (root_task) write(ndiag,'(a)') ' creating route handle ' allocate(frac_o(ns_o)) call create_routehandle_r8(mesh_i, mesh_o, routehandle_r8, frac_o=frac_o, rc=rc) call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - if (root_task) write(ndiag,'(a)') ' finished creating route handle ' end if ! Read in input 1d fields if they exists and map to output grid @@ -328,7 +324,6 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constan if (root_task) then write (ndiag,'(a)') 'Successfully made harvest and grazing' - write (ndiag,*) end if end subroutine mkharvest diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 962613f616..537fddecc1 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -7,18 +7,23 @@ module mklanwatMod use ESMF use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 - use shr_sys_mod , only : shr_sys_abort - use mkvarpar , only : re - use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas - use mkutilsMod , only : chkerr - use mkvarctl , only : root_task, ndiag + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkvarpar , only : re + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkdiagnosticsMod , only : output_diagnostics_continuous + use mkchecksMod , only : min_bad + use mkutilsMod , only : chkerr + use mkvarctl , only : root_task, ndiag implicit none private +#include + public :: mklakwat ! make % lake, % wetland and lake parameters + private :: check_global_sums character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -30,11 +35,6 @@ module mklanwatMod subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & zero_out_lake, zero_out_wetland, lake_o, swmp_o, lakedepth_o, rc) -#ifdef TODO - use mkdiagnosticsMod , only : output_diagnostics_continuous -#endif - use mkchecksMod , only : min_bad - ! ------------------- ! make %lake, %wetland and lake parameters ! ------------------- @@ -64,14 +64,6 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & real(r8), allocatable :: lakedepth_i(:) ! iput grid: lake depth integer :: ni,no,k ! indices integer :: ns_i,ns_o ! local sizes - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: garea_i ! input grid: global area - real(r8) :: garea_o ! output grid: global area - real(r8) :: glake_i ! input grid: global lake - real(r8) :: glake_o ! output grid: global lake - real(r8) :: gswmp_i ! input grid: global swamp - real(r8) :: gswmp_o ! output grid: global swamp integer :: ier,rcode ! error status real(r8), parameter :: min_valid_lakedepth = 0._r8 character(len=*), parameter :: subname = ' mklakwat ' @@ -80,6 +72,8 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & rc = ESMF_SUCCESS if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)')'Attempting to %lake, %wetland and lakdepth data' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) @@ -134,7 +128,6 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & lake_o(:) = 0._r8 if (.not. zero_out_lake) then - if (root_task) then write (ndiag,*) 'Attempting to make %lake .....' end if @@ -153,57 +146,12 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & enddo call ESMF_VMLogMemInfo("After regrid_rawdata for PCT_LAKE in "//trim(subname)) - ! Compare global areas on input and output grids - allocate(area_i(ns_i)) - allocate(area_o(ns_o)) - call get_meshareas(mesh_i, area_i, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call get_meshareas(mesh_o, area_o, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Input grid - glake_i = 0. - garea_i = 0. - do ni = 1,ns_i - garea_i = garea_i + area_i(ni)*re**2 - glake_i = glake_i + lake_i(ni)*area_i(ni)/100.*re**2 - end do - - ! Output grid - glake_o = 0. - garea_o = 0. - do no = 1,ns_o - garea_o = garea_o + area_o(no)*re**2 - glake_o = glake_o + lake_o(no)*area_o(no)/100.*re**2 - end do - - ! Diagnostic output - if (root_task) then - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Inland Water Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,201) -201 format (1x,'surface type input grid area output grid area'/ & - 1x,' 10**6 km**2 10**6 km**2 ') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,202) glake_i*1.e-06, glake_o*1.e-06 - write (ndiag,204) garea_i*1.e-06, garea_o*1.e-06 -202 format (1x,'lakes ',f14.3,f17.3) -204 format (1x,'all surface ',f14.3,f17.3) - end if + ! Check global areas + call check_global_sums(mesh_i, mesh_o, mask_i, frac_o, lake_i, lake_o, 'pct lake', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - else - do no = 1,ns_o - lake_o(no) = 0. - enddo + deallocate (lake_i) end if - - deallocate (lake_i) - if (root_task) then write (ndiag,*) 'Successfully made %lake' write (ndiag,*) @@ -233,12 +181,16 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & do no = 1,ns_o if (swmp_o(no) < 1.) swmp_o(no) = 0. enddo - deallocate (swmp_i) - if (root_task) then - write (ndiag,*) 'Successfully made %wetland' - write (ndiag,*) - end if + ! Check global areas + call check_global_sums(mesh_i, mesh_o, mask_i, frac_o, swmp_i, swmp_o, 'pct wetland', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + deallocate (swmp_i) + end if + if (root_task) then + write (ndiag,*) 'Successfully made %wetland' + write (ndiag,*) end if ! ---------------------------------------- @@ -279,7 +231,6 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & ! Release memory call ESMF_VMLogMemInfo("Before destroy operation for lanwat ") - deallocate (lakedepth_i) call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) @@ -288,9 +239,80 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & if (root_task) then write (ndiag,*) 'Successfully made lake parameters' - write (ndiag,*) end if end subroutine mklakwat + !=============================================================== + subroutine check_global_sums(mesh_i, mesh_o, mask_i, frac_o, data_i, data_o, name, rc) + + use mkvarctl, only : mpicom, MPI_INTEGER, MPI_MAX + + ! Compare global areas on input and output grids + + ! input/otuput variables + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o + integer , intent(in) :: mask_i(:) + real(r8) , intent(in) :: frac_o(:) + real(r8) , intent(in) :: data_i(:) + real(r8) , intent(in) :: data_o(:) + character(len=*) , intent(in) :: name + integer , intent(out) :: rc + + ! local variables + integer :: ns_i + integer :: ns_o + integer :: ni, no, l, k + integer :: ier + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + real(r4) :: local_i ! local global area, by surface type + real(r4) :: local_o ! local global area, by surface type + real(r4) :: global_i ! input grid: global area pfts + real(r4) :: global_o ! output grid: global area pfts + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Determine ns_i and ns_o + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get areas from mesh + allocate(area_i(ns_i)) + allocate(area_o(ns_o)) + call get_meshareas(mesh_i, area_i, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call get_meshareas(mesh_o, area_o, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Input grid global area + local_i = 0. + do ni = 1,ns_i + local_i = local_i + (data_i(ni) * area_i(ni) * mask_i(ni)) + end do + call mpi_reduce(local_i, global_i, 1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) + + ! Output grid global area + local_o = 0. + do no = 1,ns_o + local_i = local_i + data_o(no) * area_i(no) * frac_o(no) + end do + call mpi_reduce(local_o, global_o, 1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) + + ! Comparison + if (root_task) then + write(ndiag,*) + write(ndiag,'(a)')' surface type input grid area output grid area' + write(ndiag,'(a)')' 10**6 km**2 10**6 km**2 ' + write(ndiag,'(60a1)') ('.',k=1,60) + write(ndiag,'(a,f14.3,f17.3)')' '//trim(name), global_i*1.e-06, global_o*1.e-06 + write(ndiag,*) + end if + + end subroutine check_global_sums + end module mklanwatMod diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index 1d97be4ead..063be6d912 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -344,6 +344,8 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft !----------------------------------------------------------------------- if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to make PFTs .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index 59748e8732..e40f3fe8d1 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -17,9 +17,7 @@ module mksoilcolMod #include public :: mksoilcol ! Set soil colors - - private :: mkrank - private :: check_global_areas + private :: check_global_sums integer :: num_soilcolors type(ESMF_DynamicMask) :: dynamicMask @@ -48,14 +46,11 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r type(ESMF_Field) :: field_o type(ESMF_Field) :: field_dstfrac type(file_desc_t) :: pioid - integer :: ni,no + integer :: ni,no, k integer :: ns_i, ns_o - integer :: n,l,k integer , allocatable :: mask_i(:) real(r4), allocatable :: rmask_i(:) real(r4), allocatable :: frac_o(:) - real(r8), allocatable :: area_i(:) - real(r8), allocatable :: area_o(:) real(r4), allocatable :: soil_color_i(:) real(r4), pointer :: dataptr(:) real(r8), pointer :: dataptr_r8(:) @@ -81,7 +76,12 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r end if if (root_task) then - write (ndiag,'(a)') 'Attempting to make soil color classes .....' + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make soil color classes .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if ! Open soil color data file @@ -195,14 +195,9 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r end do ! Compare global area of each soil color on input and output grids - allocate(area_i(ns_i)) - allocate(area_o(ns_o)) - call get_meshareas(mesh_i, area_i, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call get_meshareas(mesh_o, area_o, rc) + call check_global_sums(mesh_i, mesh_o, mask_i, frac_o, & + soil_color_i, soil_color_o, 'soil color type', nsoilcol, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call check_global_areas('soil color type', ns_i, ns_o, nsoilcol, & - soil_color_i, soil_color_o, area_i, area_o, mask_i, frac_o) ! Clean up memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) @@ -215,6 +210,7 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_FieldDestroy(field_dstfrac, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) if (root_task) then write (ndiag,'(a)') 'Successfully made soil color classes' @@ -223,109 +219,9 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r end subroutine mksoilcol - !=============================================================== - subroutine mkrank (n, a, iv) - ! - ! Return indices of largest [num] values in array [a]. - ! - ! input/output variables - integer , intent(in) :: n !array length - real(r4), intent(in) :: a(0:n) !array to be ranked - integer , intent(out):: iv(1) !index to [num] largest values in array [a] - - ! local variables: - real(r4) :: a_max !maximum value in array - real(r4) :: delmax !tolerance for finding if larger value - integer :: i !array index - integer :: m !do loop index - integer :: k !do loop index - integer :: miss !missing data value - !----------------------------------------------------------------------- - - ! Find index of largest non-zero number - delmax = 1.e-06 - miss = 9999 - iv(1) = miss - - a_max = -9999. - do i = 0, n - if (a(i)>0. .and. (a(i)-a_max)>delmax) then - a_max = a(i) - iv(1) = i - end if - end do - ! iv(1) = miss indicates no values > 0. this is an error - if (iv(1) == miss) then - write (6,*) 'MKRANK error: iv(1) = missing' - call shr_sys_abort() - end if - end subroutine mkrank - - !=============================================================== - subroutine check_global_areas(name, ns_i, ns_o, nsoilcol, & - soil_color_i, soil_color_o, area_i, area_o, mask_i, frac_o) - - use mkvarctl, only : mpicom, MPI_INTEGER, MPI_MAX - - ! Compare global areas on input and output grids - - ! input/otuput variables - character(len=*) , intent(in) :: name - integer , intent(in) :: ns_i - integer , intent(in) :: ns_o - integer , intent(in) :: nsoilcol - real(r4) , intent(in) :: soil_color_i(ns_i) - integer , intent(in) :: soil_color_o(ns_o) - real(r8) , intent(in) :: area_i(ns_i) - real(r8) , intent(in) :: area_o(ns_o) - integer , intent(in) :: mask_i(ns_i) - real(r4) , intent(in) :: frac_o(ns_o) - - ! local variables - integer :: ni, no, l, k - integer :: ier - real(r4) :: local_i(0:nsoilcol) ! local global area, by surface type - real(r4) :: local_o(0:nsoilcol) ! local global area, by surface type - real(r4) :: global_i(0:nsoilcol) ! input grid: global area pfts - real(r4) :: global_o(0:nsoilcol) ! output grid: global area pfts - !----------------------------------------------------------------------- - - ! Input grid global area - local_i(:) = 0 - do ni = 1,ns_i - k = int(soil_color_i(ni)) - local_i(k) = local_i(k) + area_i(ni) * mask_i(ni) - end do - call mpi_reduce(local_i, global_i, nsoilcol+1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) - - ! Output grid global area - local_o(:) = 0. - do no = 1,ns_o - k = soil_color_o(no) - local_o(k) = local_o(k) + area_o(no) * frac_o(no) - end do - call mpi_reduce(local_o, global_o, nsoilcol+1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) - - ! Comparison - if (root_task) then - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,101) -101 format (1x,'soil color type',5x,' input grid area output grid area',/ & - 1x,20x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - do k = 0, nsoilcol - write (ndiag,'(1x,a,i3,d16.3,d17.3)') 'class ',k, global_i(k)*1.e-6, global_o(k)*1.e-6 - end do - end if - end subroutine check_global_areas - !================================================================================================ subroutine get_dominant_soilcol(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, rc) - use ESMF, only : ESMF_RC_ARG_BAD - ! input/output arguments type(ESMF_DynamicMaskElementR4R8R4) , pointer :: dynamicMaskList(:) real(ESMF_KIND_R4) , intent(in), optional :: dynamicSrcMaskValue @@ -342,14 +238,8 @@ subroutine get_dominant_soilcol(dynamicMaskList, dynamicSrcMaskValue, dynamicDst rc = ESMF_SUCCESS - ! Below - ONLY if you do NOT have the source masked out then do - ! the regridding (which is done explicitly here) - ! Below i are the destination points and j are the source points - if (associated(dynamicMaskList)) then - do no = 1, size(dynamicMaskList) - wts_o(:) = 0.d0 do ni = 1, size(dynamicMaskList(no)%factor) if (dynamicSrcMaskValue /= dynamicMaskList(no)%srcElement(ni)) then @@ -432,4 +322,84 @@ end subroutine mkrank end subroutine get_dominant_soilcol + !=============================================================== + subroutine check_global_sums(mesh_i, mesh_o, mask_i, frac_o, & + soil_color_i, soil_color_o, name, nsoilcol, rc) + + use mkvarctl, only : mpicom, MPI_INTEGER, MPI_MAX + + ! Compare global sums on input and output grids + + ! input/otuput variables + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o + integer , intent(in) :: mask_i(:) + real(r4) , intent(in) :: frac_o(:) + real(r4) , intent(in) :: soil_color_i(:) + integer , intent(in) :: soil_color_o(:) + character(len=*) , intent(in) :: name + integer , intent(in) :: nsoilcol + integer , intent(out) :: rc + + ! local variables + integer :: ns_i + integer :: ns_o + integer :: ni, no, l, k + integer :: ier + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + real(r4) :: local_i(0:nsoilcol) ! local global area, by surface type + real(r4) :: local_o(0:nsoilcol) ! local global area, by surface type + real(r4) :: global_i(0:nsoilcol) ! input grid: global area pfts + real(r4) :: global_o(0:nsoilcol) ! output grid: global area pfts + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Determine ns_i and ns_o + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get areas from mesh + allocate(area_i(ns_i)) + allocate(area_o(ns_o)) + call get_meshareas(mesh_i, area_i, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call get_meshareas(mesh_o, area_o, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Input grid global area + local_i(:) = 0. + do ni = 1,ns_i + k = int(soil_color_i(ni)) + ! TODO: is this change okay? + ! local_i(k) = local_i(k) + area_i(ni) * mask_i(ni) + local_i(k) = local_i(k) + area_i(ni) + end do + call mpi_reduce(local_i, global_i, nsoilcol+1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) + + ! Output grid global area + local_o(:) = 0. + do no = 1,ns_o + k = int(soil_color_o(no)) + ! TODO: is this change okay? + ! local_o(k) = local_o(k) + area_o(no) * frac_o(no) + local_o(k) = local_o(k) + area_o(no) + end do + call mpi_reduce(local_o, global_o, nsoilcol+1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) + + ! Comparison + if (root_task) then + write(ndiag,*) + write(ndiag,'(a)')'soil color type input grid area output grid area' + write(ndiag,'(a)')' 10**6 km**2 10**6 km**2' + write(ndiag,'(1x,60a1)') ('.',k=1,60) + do k = 0, nsoilcol + write (ndiag,'(a,i3,d16.3,d17.3)') 'class ',k, global_i(k)*1.e-6, global_o(k)*1.e-6 + end do + end if + end subroutine check_global_sums + end module mksoilcolMod diff --git a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 index c929bc7350..3d196d1678 100644 --- a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 @@ -64,7 +64,12 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) rc = ESMF_SUCCESS if (root_task) then - write (ndiag,'(a)') 'Attempting to make %fmax .....' + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make %fmax .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if ! Error check soil_fmax if it is set @@ -145,8 +150,7 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) do no = 1, ns_o if ((fmax_o(no)) > 1.000001_r8) then write (6,*) 'MKFMAX error: fmax = ',fmax_o(no),' greater than 1.000001 for no = ',no - ! TODO: why are we hitting this error - ! call shr_sys_abort() + call shr_sys_abort() end if enddo diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index acb450da31..7fafd94908 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -61,7 +61,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o integer :: dimid integer :: ni,no integer :: ns_i, ns_o - integer :: n,l,m + integer :: k,l,m,n character(len=38) :: typ ! soil texture based on ... integer :: nlay ! number of soil layers integer :: mapunittemp ! temporary igbp soil mapunit @@ -88,7 +88,12 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o !----------------------------------------------------------------------- if (root_task) then - write (ndiag,'(a)') 'Attempting to make %sand and %clay .....' + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make %sand and %clay .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if if ( soil_clay_override /= unsetsoil )then @@ -170,12 +175,10 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - ! Scale the input soil color by the input mask - ! do ni = 1,ns_i - ! if (mask_i(ni) == 0) then - ! mapunit_i(ni) = 0._r4 - ! end if - ! end do + ! Set mapunit values to zero where the input mask is 0 + do ni = 1,ns_i + mapunit_i(ni) = mapunit_i(ni) * rmask_i(ni) + end do ! Determine mapunit_value_max (set it as a module variable so that it can be ! accessible to gen_dominant_mapunit) @@ -213,7 +216,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o ! Determine dominant soil color in the field regrid call below call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) - dataptr(:) = mapunit_i(:) + dataptr(:) = real(mapunit_i(:), kind=r4) call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:) = 0._r4 diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 4f95a89206..a7dc1abd1b 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -149,9 +149,11 @@ program mksurfdata type(var_desc_t) :: pio_varid type(io_desc_t) :: pio_iodesc - ! data arrays + ! model grid real(r8), allocatable :: lon(:) real(r8), allocatable :: lat(:) + + ! pct vegetation data real(r8), allocatable :: landfrac_pft(:) ! PFT data: % land per gridcell real(r8), allocatable :: pctlnd_pft(:) ! PFT data: % of gridcell for PFTs real(r8), allocatable :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs @@ -160,48 +162,78 @@ program mksurfdata type(pct_pft_type), allocatable :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series type(pct_pft_type), allocatable :: pctcft(:) ! % of grid cell that is crop, and breakdown into CFTs type(pct_pft_type), allocatable :: pctcft_max(:) ! % of grid cell maximum CFTs of the time series + + ! harvest initial value real(r8) :: harvest_initval ! initial value for harvest variables + + ! soil fracation saturated area data + real(r8), allocatable :: fmaxsoil(:) ! soil_fractional saturated area + + ! oranic matter density data + real(r8), allocatable :: organic(:,:) ! organic matter density (kg/m3) + + ! gdp data + real(r8), allocatable :: gdp(:) ! GDP (x1000 1995 US$/capita) + + ! peatland data + real(r8), allocatable :: fpeat(:) ! peatland fraction of gridcell + + ! topography statistics data + real(r4), allocatable :: topo_stddev(:) ! standard deviation of elevation (m) + real(r4), allocatable :: slope(:) ! topographic slope (degrees) + + ! agricultural peak month data + integer , allocatable :: agfirepkmon(:) ! agricultural fire peak month + + ! inland water data + real(r8), allocatable :: pctlak(:) ! percent of grid cell that is lake + real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland + real(r8), allocatable :: lakedepth(:) ! lake depth (m) + + ! glacier data + integer, allocatable :: glacier_region(:) ! glacier region ID real(r8), allocatable :: pctgla(:) ! percent of grid cell that is glacier real(r8), allocatable :: pctglc_gic(:) ! percent of grid cell that is gic (% of glc landunit) real(r8), allocatable :: pctglc_icesheet(:) ! percent of grid cell that is ice sheet (% of glc landunit) real(r8), allocatable :: pctglcmec(:,:) ! glacier_mec pct coverage in each class (% of landunit) - real(r8), allocatable :: topoglcmec(:,:) ! glacier_mec sfc elevation in each gridcell and class real(r8), allocatable :: pctglcmec_gic(:,:) ! GIC pct coverage in each class (% of landunit) real(r8), allocatable :: pctglcmec_icesheet(:,:) ! icesheet pct coverage in each class (% of landunit) real(r8), allocatable :: elevclass(:) ! glacier_mec elevation classes - integer, allocatable :: glacier_region(:) ! glacier region ID - real(r8), allocatable :: pctlak(:) ! percent of grid cell that is lake - real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland + real(r8), allocatable :: topoglcmec(:,:) ! glacier_mec sfc elevation in each gridcell and class + + ! urban data + integer , allocatable :: urban_region(:) ! urban region ID real(r8), allocatable :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) real(r8), allocatable :: urban_classes(:,:) ! percent cover of each urban class, as % of total urban area real(r8), allocatable :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell - integer , allocatable :: urban_region(:) ! urban region ID real(r8), allocatable :: elev(:) ! glc elevation (m) + + ! soil color data integer , allocatable :: soil_color(:) ! soil color - real(r8), allocatable :: fmaxsoil(:) ! soil_fractional saturated area + + ! soil texture data real(r8), allocatable :: pctsand(:,:) ! soil texture: percent sand real(r8), allocatable :: pctclay(:,:) ! soil texture: percent clay integer , allocatable :: mapunits(:) ! input grid: igbp soil mapunits + + ! soil depth data + real(r8), allocatable :: soildepth(:) ! soil depth (m) + + ! VOC data real(r8), allocatable :: ef1_btr(:) ! Isoprene emission factor for broadleaf real(r8), allocatable :: ef1_fet(:) ! Isoprene emission factor for fine/everg real(r8), allocatable :: ef1_fdt(:) ! Isoprene emission factor for fine/dec real(r8), allocatable :: ef1_shr(:) ! Isoprene emission factor for shrubs real(r8), allocatable :: ef1_grs(:) ! Isoprene emission factor for grasses real(r8), allocatable :: ef1_crp(:) ! Isoprene emission factor for crops - real(r8), allocatable :: organic(:,:) ! organic matter density (kg/m3) - real(r8), allocatable :: gdp(:) ! GDP (x1000 1995 US$/capita) - real(r8), allocatable :: fpeat(:) ! peatland fraction of gridcell - real(r8), allocatable :: soildepth(:) ! soil depth (m) - integer , allocatable :: agfirepkmon(:) ! agricultural fire peak month - real(r4), allocatable :: topo_stddev(:) ! standard deviation of elevation (m) - real(r4), allocatable :: slope(:) ! topographic slope (degrees) + + ! VIC data real(r8), allocatable :: vic_binfl(:) ! VIC b real(r8), allocatable :: vic_ws(:) ! VIC Ws parameter (unitless) real(r8), allocatable :: vic_dsmax(:) ! VIC Dsmax parameter (mm/day) real(r8), allocatable :: vic_ds(:) ! VIC Ds parameter (unitless) - real(r8), allocatable :: lakedepth(:) ! lake depth (m) - integer , allocatable :: harvind1D(:) ! Indices of 1D harvest fields - integer , allocatable :: harvind2D(:) ! Indices of 2D harvest fields + + ! logicals logical :: zero_out_lake ! if should zero glacier out logical :: zero_out_wetland ! if should zero glacier out logical :: zero_out @@ -402,7 +434,7 @@ program mksurfdata end if ! ----------------------------------- - ! Set landfrac_pft and pftdata_mask + ! Make landfrac_pft and pftdata_mask ! ----------------------------------- allocate ( pftdata_mask(lsize_o)) ; pftdata_mask(:) = -999 allocate ( landfrac_pft(lsize_o)) ; landfrac_pft(:) = spval @@ -429,7 +461,7 @@ program mksurfdata end if ! ----------------------------------- - ! Create constant harvesting data at model resolution + ! Make constant harvesting data at model resolution ! ----------------------------------- ! Note that this call must come after call to mkpftInit - since num_cft is set there call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, & @@ -505,9 +537,14 @@ program mksurfdata end if end do if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" + call mkfile_output(pioid, mesh_model, 'mapunits', mapunits, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" call mkfile_output(pioid, mesh_model, 'PCT_SAND', pctsand, lev1name='nlevsoi', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" call mkfile_output(pioid, mesh_model, 'PCT_CLAY', pctclay, lev1name='nlevsoi', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') diff --git a/tools/mksurfdata_map/src/mkagfirepkmonthMod.F90 b/tools/mksurfdata_map/src/mkagfirepkmonthMod.F90 index 7b58ddffad..35b308ce0f 100644 --- a/tools/mksurfdata_map/src/mkagfirepkmonthMod.F90 +++ b/tools/mksurfdata_map/src/mkagfirepkmonthMod.F90 @@ -30,8 +30,7 @@ module mkagfirepkmonthMod ! !PRIVATE DATA MEMBERS: ! integer , parameter :: min_valid_value = 1 - integer , parameter :: max_valid_value = 12 - integer , parameter :: unsetmon = 13 ! flag to indicate agricultural fire peak month NOT set + integer , parameter :: max_valid_value = 13 ! ! !PRIVATE DATA MEMBERS: ! diff --git a/tools/mksurfdata_map/src/mkharvestMod.F90 b/tools/mksurfdata_map/src/mkharvestMod.F90 index 0dc107729b..e726fc81c9 100644 --- a/tools/mksurfdata_map/src/mkharvestMod.F90 +++ b/tools/mksurfdata_map/src/mkharvestMod.F90 @@ -68,27 +68,28 @@ module mkharvestMod integer, parameter :: harlen = 25 ! length of strings for harvest fieldnames character(len=harlen), parameter :: harvest_fieldnames(numharv) = (/ & - 'HARVEST_VH1 ', & - 'HARVEST_VH2 ', & - 'HARVEST_SH1 ', & - 'HARVEST_SH2 ', & - 'HARVEST_SH3 ', & - 'GRAZING ', & - 'FERTNITRO_CFT ', & - 'UNREPRESENTED_PFT_LULCC', & - 'UNREPRESENTED_CFT_LULCC' & - /) + 'HARVEST_VH1 ', & + 'HARVEST_VH2 ', & + 'HARVEST_SH1 ', & + 'HARVEST_SH2 ', & + 'HARVEST_SH3 ', & + 'GRAZING ', & + 'FERTNITRO_CFT ', & + 'UNREPRESENTED_PFT_LULCC', & + 'UNREPRESENTED_CFT_LULCC' & + /) character(len=harlen), parameter :: harvest_const_fieldnames(numharv) = (/ & - 'CONST_HARVEST_VH1 ', & - 'CONST_HARVEST_VH2 ', & - 'CONST_HARVEST_SH1 ', & - 'CONST_HARVEST_SH2 ', & - 'CONST_HARVEST_SH3 ', & - 'CONST_GRAZING ', & - 'CONST_FERTNITRO_CFT ', & - 'UNREPRESENTED_PFT_LULCC', & - 'UNREPRESENTED_CFT_LULCC' & - /) + 'CONST_HARVEST_VH1 ', & + 'CONST_HARVEST_VH2 ', & + 'CONST_HARVEST_SH1 ', & + 'CONST_HARVEST_SH2 ', & + 'CONST_HARVEST_SH3 ', & + 'CONST_GRAZING ', & + 'CONST_FERTNITRO_CFT ', & + 'UNREPRESENTED_PFT_LULCC', & + 'UNREPRESENTED_CFT_LULCC' & + /) + character(len=CL), parameter :: string_undef = 'UNSET' real(r8), parameter :: real_undef = -999.99 character(len=CL), save :: harvest_longnames(numharv) = string_undef From 880d42ee8108ca6577dd8343d9a37dab147667c2 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 15 Feb 2022 10:19:21 -0700 Subject: [PATCH 062/614] updates to get pctpftMod output variables working --- tools/mksurfdata_esmf/src/mkdomainMod.F90 | 2 +- tools/mksurfdata_esmf/src/mkfileMod.F90 | 4 +- tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 | 41 +- .../mksurfdata_esmf/src/mkpftConstantsMod.F90 | 17 +- tools/mksurfdata_esmf/src/mkpftMod.F90 | 290 +++++----- tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 | 1 - tools/mksurfdata_esmf/src/mkpioMod.F90 | 10 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 499 ++++++++++-------- tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 11 +- tools/mksurfdata_esmf/src/mkvarctl.F90 | 16 +- 10 files changed, 486 insertions(+), 405 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkdomainMod.F90 b/tools/mksurfdata_esmf/src/mkdomainMod.F90 index 0d25eb6646..34e51e3d53 100644 --- a/tools/mksurfdata_esmf/src/mkdomainMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdomainMod.F90 @@ -42,7 +42,7 @@ subroutine mkdomain(mesh_o, lon_o, lat_o, rc) if (root_task) then write(ndiag,*) - write(ndiag,'(1x,70a1)') ('=',k=1,80) + write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to create model lats and lons from model mesh .....' end if diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 7fc19f9183..17e8977313 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -788,9 +788,9 @@ subroutine mkfile_output_real2dr8(pioid, mesh, varname, data, lev1name, rc) type(file_desc_t) , intent(inout) :: pioid type(ESMF_Mesh) , intent(in) :: mesh character(len=*) , intent(in) :: varname - character(len=*) , intent(in) :: lev1name real(r8) , intent(in) :: data(:,:) integer , intent(out) :: rc + character(len=*) , optional, intent(in) :: lev1name ! local variables type(io_desc_t) :: pio_iodesc @@ -841,9 +841,9 @@ subroutine mkfile_output_real2dr4(pioid, mesh, varname, data, lev1name, rc) type(file_desc_t) , intent(inout) :: pioid type(ESMF_Mesh) , intent(in) :: mesh character(len=*) , intent(in) :: varname - character(len=*) , intent(in) :: lev1name real(r4) , intent(in) :: data(:,:) integer , intent(out) :: rc + character(len=*) , optional, intent(in) :: lev1name ! local variables type(io_desc_t) :: pio_iodesc diff --git a/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 b/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 index 9d2faad36e..5b000ad1b1 100644 --- a/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 @@ -35,7 +35,7 @@ module mkpctPftTypeMod procedure, private :: check_vals ! perform a sanity check after setting values end type pct_pft_type - public :: update_max_array ! given an array of pct_pft_type variables update the max_p2l values from pct_p2l + public :: update_max_array ! given an array of pct_pft_type variables update the max_p2l values from pct_p2l public :: get_pct_p2l_array ! given an array of pct_pft_type variables, return a 2-d array of pct_p2l public :: get_pct_l2g_array ! given an array of pct_pft_type variables, return an array of pct_l2g @@ -491,7 +491,7 @@ subroutine update_max_array(pct_pft_max_arr,pct_pft_arr) do arr_index = 1, size(pct_pft_arr) if (lbound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_lbound .or. & - ubound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_ubound) then + ubound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_ubound) then write(6,*) subname//' ERROR: all elements of pct_pft_arr must have' write(6,*) 'the same size and lower bound for their pct_p2l array' call shr_sys_abort() @@ -511,7 +511,7 @@ subroutine update_max_array(pct_pft_max_arr,pct_pft_arr) end subroutine update_max_array !----------------------------------------------------------------------- - function get_pct_p2l_array(pct_pft_arr) result(pct_p2l) + subroutine get_pct_p2l_array(pct_pft_arr, ndim1, ndim2, pct_p2l) ! ! Given an array of pct_pft_type variables, return a 2-d array of pct_p2l. ! @@ -519,9 +519,11 @@ function get_pct_p2l_array(pct_pft_arr) result(pct_p2l) ! their pct_p2l array. ! ! input/output variables - real(r8), allocatable :: pct_p2l(:,:) ! function result (n_elements, n_pfts) ! workaround for gfortran bug (58043): declare this 'type' rather than 'class': - type(pct_pft_type), intent(in) :: pct_pft_arr(:) + type(pct_pft_type) , intent(in) :: pct_pft_arr(:) + integer , intent(in) :: ndim1 + integer , intent(in) :: ndim2 + real(r8) , intent(inout) :: pct_p2l(ndim1,ndim2) ! result (n_elements, n_pfts) ! ! local variables: integer :: pft_lbound @@ -534,41 +536,48 @@ function get_pct_p2l_array(pct_pft_arr) result(pct_p2l) pft_lbound = lbound(pct_pft_arr(1)%pct_p2l, 1) pft_ubound = ubound(pct_pft_arr(1)%pct_p2l, 1) - allocate(pct_p2l(size(pct_pft_arr), pft_lbound:pft_ubound)) - + ! error checks + if (ndim1 /= size(pct_pft_arr)) then + write(6,*) 'ndim1, size(pct_pft_arr) = ',ndim1,size(pct_pft_arr) + call shr_sys_abort(subname//' ndim1 and size(pct_pft_arr) must be equal') + end if + if (ndim2 /= pft_ubound-pft_lbound+1) then + write(6,*) 'ndim1,pft_ubound-pft_lbound+1 = ',ndim1,pft_ubound-pft_lbound+1 + call shr_sys_abort(subname//' ndim1 and pft_ubound-pft_lbound+1 must be equal') + end if do arr_index = 1, size(pct_pft_arr) if (lbound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_lbound .or. & - ubound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_ubound) then + ubound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_ubound) then write(6,*) subname//' ERROR: all elements of pct_pft_arr must have' write(6,*) 'the same size and lower bound for their pct_p2l array' call shr_sys_abort() end if + end do + do arr_index = 1, size(pct_pft_arr) do pft_index = pft_lbound, pft_ubound - pct_p2l(arr_index, pft_index) = pct_pft_arr(arr_index)%pct_p2l(pft_index) + pct_p2l(arr_index, pft_index - pft_lbound + 1) = pct_pft_arr(arr_index)%pct_p2l(pft_index) end do end do - end function get_pct_p2l_array + end subroutine get_pct_p2l_array !----------------------------------------------------------------------- - function get_pct_l2g_array(pct_pft_arr) result(pct_l2g) + subroutine get_pct_l2g_array(pct_pft_arr, pct_l2g) ! ! Given an array of pct_pft_type variables, return an array of pct_l2g. ! ! input/output variables - real(r8), allocatable :: pct_l2g(:) ! function result - class(pct_pft_type), intent(in) :: pct_pft_arr(:) + class(pct_pft_type) , intent(in) :: pct_pft_arr(:) + real(r8) , intent(inout) :: pct_l2g(:) ! result ! ! local variables: integer :: arr_index character(len=*), parameter :: subname = 'get_pct_l2g_array' !----------------------------------------------------------------------- - allocate(pct_l2g(size(pct_pft_arr))) pct_l2g = pct_pft_arr(:)%pct_l2g - end function get_pct_l2g_array - + end subroutine get_pct_l2g_array end module mkpctPftTypeMod diff --git a/tools/mksurfdata_esmf/src/mkpftConstantsMod.F90 b/tools/mksurfdata_esmf/src/mkpftConstantsMod.F90 index 241873c339..85152ef3c4 100644 --- a/tools/mksurfdata_esmf/src/mkpftConstantsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftConstantsMod.F90 @@ -1,26 +1,15 @@ module mkpftConstantsMod + !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mkpftConstants - ! - ! !DESCRIPTION: ! Constants used by mkpft and related code - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! !----------------------------------------------------------------------- - !!USES: + use shr_kind_mod, only : r8 => shr_kind_r8 implicit none private - ! - ! !PUBLIC DATA MEMBERS: - ! - + ! public data members: integer, parameter, public :: maxpft = 78 ! maximum # of PFT integer, public :: num_natpft = -1 ! number of PFTs on the natural vegetation diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index 063be6d912..60167969f5 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -22,14 +22,14 @@ module mkpftMod public :: mkpft ! Set PFT public :: mkpft_parse_oride ! Parse the string with PFT fraction/index info to override - private :: mkpft_check_oride ! Check the pft_frc and pft_idx values for correctness + private :: mkpft_check_oride ! Check the pft_frc and pft_idx values for correctness ! When pft_idx and pft_frc are set, they must be set together, and they will cause the ! entire area to be covered with vegetation and zero out other landunits. ! The sum of pft_frc must = 100%, and each pft_idx point in the array corresponds to ! the fraction in pft_frc. Only the first few points are used until pft_frc = 0.0. - integer :: m ! index + integer :: m ! index ! PFT vegetation index to override with integer, public :: pft_idx(0:maxpft) = (/ ( -1, m = 0, maxpft ) /) @@ -106,8 +106,10 @@ subroutine mkpftInit( zero_out_l, all_veg_l ) use_input_pft = .true. end if if ( use_input_pft ) then - write(6,*) 'Set PFT fraction to : ', pft_frc(0:nzero) - write(6,*) 'With PFT index : ', pft_idx(0:nzero) + if (root_task) then + write(ndiag,*) subname // ' Set PFT fraction to : ', pft_frc(0:nzero) + write(ndiag,*) subname // ' With PFT index : ', pft_idx(0:nzero) + end if end if if ( all_veg_l .and. .not. use_input_pft )then write(6,*) subname//'if all_veg is set to true then specified PFT indices must be provided (i.e. pft_frc and pft_idx)' @@ -128,7 +130,6 @@ subroutine mkpftInit( zero_out_l, all_veg_l ) ! using the extra specific crops (so we always run CLM with create_crop_landunit=.true.). ! When we create a surface dataset WITH the extra specific crops, all crops ! (including the generic crops) again go on the crop landunit. - num_natpft = numstdpft - numstdcft num_cft = numpft - num_natpft @@ -141,6 +142,15 @@ subroutine mkpftInit( zero_out_l, all_veg_l ) cft_lb = num_natpft+1 cft_ub = cft_lb + num_cft - 1 + if (root_task) then + write(ndiag, '(a, i8)') subname//' num_natpft = ',num_natpft + write(ndiag, '(a, i8)') subname//' natpft_lb = ',natpft_lb + write(ndiag, '(a, i8)') subname//' natpft_ub = ',natpft_ub + write(ndiag, '(a, i8)') subname//' num_cft = ',num_cft + write(ndiag, '(a, i8)') subname//' cft_lb = ',cft_lb + write(ndiag, '(a, i8)') subname//' cft_ub = ',cft_ub + end if + ! Make sure the array indices have been set up properly, to ensure the 1:1 ! correspondence mentioned above if (cft_ub /= numpft) then @@ -295,6 +305,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft real(r8) , intent(inout) :: pctlnd_o(:) ! output grid:%land/gridcell type(pct_pft_type), intent(inout) :: pctnatpft_o(:) ! natural PFT cover type(pct_pft_type), intent(inout) :: pctcft_o(:) ! crop (CFT) cover + integer , intent(out) :: rc ! ! local variables: @@ -303,16 +314,16 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft type(file_desc_t) :: pioid integer :: dimid integer :: ndims ! number of dimensions for a variable on the file - integer :: dimlens(3) ! dimension lengths for a variable on the file + integer, allocatable :: dimlens(:) ! dimension lengths for a variable on the file integer :: ns_i, ns_o ! input/output bounds integer :: ni,no ! indices integer :: k,n,m ! indices - type(pct_pft_type), allocatable :: pctnatpft_i(:) ! input grid: natural PFT cover - type(pct_pft_type), allocatable :: pctcft_i(:) ! input grid: crop (CFT) cover - real(r8), allocatable :: pct_cft_i(:,:) ! input grid: CFT (Crop Functional Type) percent (% of landunit cell) - real(r8), allocatable :: pct_cft_o(:,:) ! output grid: CFT (Crop Functional Type) percent (% of landunit cell) - real(r8), allocatable :: pct_nat_pft_i(:,:) ! input grid: natural PFT percent (% of landunit cell) - real(r8), allocatable :: pct_nat_pft_o(:,:) ! output grid: natural PFT percent (% of landunit cell) + type(pct_pft_type), allocatable :: pctnatpft_i(:) ! input natural PFT cover + type(pct_pft_type), allocatable :: pctcft_i(:) ! input crop (CFT) cover + real(r8), allocatable :: pct_cft_i(:,:) ! input CFT (Crop Functional Type) percent (% of landunit cell) + real(r8), allocatable :: pct_cft_o(:,:) ! output CFT (Crop Functional Type) percent (% of landunit cell) + real(r8), allocatable :: pct_nat_pft_i(:,:) ! input natural PFT percent (% of landunit cell) + real(r8), allocatable :: pct_nat_pft_o(:,:) ! output natural PFT percent (% of landunit cell) real(r8), allocatable :: output_pct_nat_pft_o(:,:) real(r8), allocatable :: output_pct_cft_o(:,:) integer , allocatable :: mask_i(:) @@ -320,26 +331,25 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft real(r8), allocatable :: frac_o(:) real(r8), allocatable :: area_i(:) real(r8), allocatable :: area_o(:) - real(r8), allocatable :: pctnatveg_i(:) ! input grid: natural veg percent (% of grid cell) - real(r8), allocatable :: pctnatveg_o(:) ! output grid: natural veg percent (% of grid cell) - real(r8), allocatable :: pctcrop_i(:) ! input grid: all crop percent (% of grid cell) - real(r8), allocatable :: pctcrop_o(:) ! output grid: all crop percent (% of grid cell) - real(r8), allocatable :: pctpft_i(:,:) ! input grid: PFT percent (for error checks) - real(r8), allocatable :: pctpft_o(:,:) ! output grid: PFT percent (% of grid cell) - real(r8), allocatable :: temp_i(:,:) ! input grid: temporary 2D variable to read in + real(r8), allocatable :: pctnatveg_i(:) ! input natural veg percent (% of grid cell) + real(r8), allocatable :: pctnatveg_o(:) ! output natural veg percent (% of grid cell) + real(r8), allocatable :: pctcrop_i(:) ! input all crop percent (% of grid cell) + real(r8), allocatable :: pctcrop_o(:) ! output all crop percent (% of grid cell) + real(r8), allocatable :: pctpft_i(:,:) ! input PFT percent (for error checks) + real(r8), allocatable :: pctpft_o(:,:) ! output PFT percent (% of grid cell) + real(r8), allocatable :: temp_i(:,:) ! input temporary 2D variable to read in integer :: numpft_i ! num of plant types input data integer :: natpft_i ! num of natural plant types input data integer :: ncft_i ! num of crop types input data real(r8) :: sum_fldo ! global sum of dummy output fld real(r8) :: sum_fldi ! global sum of dummy input fld real(r8) :: wst_sum ! sum of %pft - real(r8), allocatable :: gpft_o(:) ! output grid: global area pfts - real(r8) :: garea_o ! output grid: global area - real(r8), allocatable :: gpft_i(:) ! input grid: global area pfts - real(r8) :: garea_i ! input grid: global area + real(r8), allocatable :: gpft_o(:) ! output global area pfts + real(r8) :: garea_o ! output global area + real(r8), allocatable :: gpft_i(:) ! input global area pfts + real(r8) :: garea_i ! input global area integer :: ier, rcode ! error status real(r8) :: relerr = 0.0001_r8 ! max error: sum overlap wts ne 1 - logical :: error_happened ! If an error was triggered so should return character(len=*), parameter :: subname = 'mkpf' !----------------------------------------------------------------------- @@ -431,69 +441,77 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft pctlnd_o(:) = frac_o(:) * 100._r8 end if - ! DEBUG - RETURN - !DEBUG - ! ---------------------------------------- - ! Determine pctnatveg_o(:) + ! Determine pct_nat_pft_o(:,:) ! ---------------------------------------- + allocate(pctnatveg_o(ns_o), stat=ier) + if (ier/=0) call shr_sys_abort('error in allocating pctnatveg_o') + + ! First determine pctnatveg_o(:) if ( use_input_pft .and. presc_cover ) then do no = 1,ns_o pctnatveg_o(no) = pft_override%natveg end do else + ! Read in pctnatveg_i allocate(pctnatveg_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() + if (ier/=0) call shr_sys_abort('error allocating pctnatveg_i') + call mkpio_get_rawdata(pioid, 'PCT_NATVEG', mesh_i, pctnatveg_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Regrid to determine pctnatveg_o call regrid_rawdata(mesh_i, mesh_o, routehandle, pctnatveg_i, pctnatveg_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - ! ---------------------------------------- - ! Determine pctcrop_o(:) - ! ---------------------------------------- - if ( use_input_pft .and. presc_cover ) then - do no = 1,ns_o - pctcrop_o(no) = pft_override%crop - end do - else - allocate(pctcrop_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'PCT_CROP', mesh_i, pctcrop_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, pctcrop_i, pctcrop_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if + allocate(pct_nat_pft_i(0:num_natpft,ns_i)) + if (ier/=0) call shr_sys_abort() + allocate(pct_nat_pft_o(0:num_natpft,ns_o)) + if (ier/=0) call shr_sys_abort() - ! ---------------------------------------- - ! Determine pct_nat_pft_o(:,:) - ! ---------------------------------------- if ( .not. use_input_pft )then - allocate(pct_nat_pft_i(0:num_natpft,ns_i)) - if (ier/=0) call shr_sys_abort() - allocate(pct_nat_pft_o(0:num_natpft,ns_o)) - if (ier/=0) call shr_sys_abort() + ! Read in pct_nat_pft_i call mkpio_get_rawdata(pioid, 'PCT_NAT_PFT', mesh_i, pct_nat_pft_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - do m = 0,num_natpft - do ni = 1,ns_i - pct_nat_pft_i(m,ni) = pct_nat_pft_i(m,ni) * pctnatveg_i(ni) * 0.01_r8 * mask_i(ni) + do ni = 1,ns_i + do m = 0,num_natpft + pct_nat_pft_i(m,ni) = pct_nat_pft_i(m,ni) * (pctnatveg_i(ni) * 0.01_r8 * mask_i(ni)) end do end do + + ! Readgrid to determine pct_nat_pft_o call regrid_rawdata(mesh_i, mesh_o, routehandle, pct_nat_pft_i, pct_nat_pft_o, 0, num_natpft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - do m = 0,num_natpft - do no = 1,ns_o - pct_nat_pft_o(m,no) = pct_nat_pft_o(m,no) / pctnatveg_o(no) * 0.01_r8 - if (pctlnd_o(no) < 1.0e-6 .or. pctnatveg_o(no) < 1.0e-6) then - if (m == 0) then - pct_nat_pft_o(m,no) = 100._r8 - else - pct_nat_pft_o(m,no) = 0._r8 - endif - end if + + ! Rescale pct_nat_pft_o + do no = 1,ns_o + if (pctnatveg_o(no) > 0._r8) then + do m = 0,num_natpft + pct_nat_pft_o(m,no) = pct_nat_pft_o(m,no) / (pctnatveg_o(no) * 0.01_r8) + end do + else + pct_nat_pft_o(0:num_natpft,no) = 0._r8 + end if + if (pctlnd_o(no) < 1.0e-6 .or. pctnatveg_o(no) < 1.0e-6) then + pct_nat_pft_o(0,no) = 100._r8 + pct_nat_pft_o(1:num_natpft,no) = 0._r8 + end if + + ! Correct sums so that if they differ slightly from 100, they are + ! corrected to equal 100 more exactly. + ! Error check: percents should sum to 100 for land grid cells, within roundoff + wst_sum = 0. + do m = 0, num_natpft + wst_sum = wst_sum + pct_nat_pft_o(m,no) + enddo + if (abs(wst_sum - 100._r8) > relerr) then + write (6,*) subname//'error: nat pft = ', (pct_nat_pft_o(m,no), m = 0, num_natpft), & + ' do not sum to 100. at no = ',no,' but to ', wst_sum + call shr_sys_abort() + end if + do m = 1, num_natpft + pct_nat_pft_o(m,no) = pct_nat_pft_o(m,no) * 100._r8 / wst_sum end do end do end if @@ -501,17 +519,44 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! ---------------------------------------- ! Determine pct_cft_o(:,:) ! ---------------------------------------- + + ! First Determine pctcrop_o(:) + allocate(pctcrop_o(ns_o), stat=ier) + if (ier/=0) call shr_sys_abort('error allocating pctcrop_o_o') + if ( use_input_pft .and. presc_cover ) then + do no = 1,ns_o + pctcrop_o(no) = pft_override%crop + end do + else + allocate(pctcrop_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'PCT_CROP', mesh_i, pctcrop_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, pctcrop_i, pctcrop_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + allocate(pct_cft_i(1:num_cft,ns_i), stat=ier) if (ier/=0) call shr_sys_abort() allocate(pct_cft_o(1:num_cft,ns_o), stat=ier) if (ier/=0) call shr_sys_abort() if ( .not. use_input_pft )then + ! Get dimensions for PCT_CFT + allocate(dimlens(3)) call mkpio_get_dimlengths(pioid, 'PCT_CFT', ndims, dimlens(:)) - if (ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) == num_cft )then + if (root_task) then + do n = 1,ndims + write(ndiag,'(a,i8,i8)')' dimid, length= ',n,dimlens(n) + end do + write(ndiag,'(a,i8)')' num_cft = ',num_cft + end if + + ! Read in pct_cft_i + if (dimlens(ndims) == num_cft )then call mkpio_get_rawdata(pioid, 'PCT_CFT', mesh_i, pct_cft_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - else if ( ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) > num_cft )then + else if (dimlens(ndims) > num_cft )then ! Read in the whole array: then sum the rainfed and irrigated seperately allocate(temp_i(dimlens(3),ns_i)) call mkpio_get_rawdata(pioid, 'PCT_CFT', mesh_i, temp_i, rc=rc) @@ -526,24 +571,47 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft else call shr_sys_abort(subname//' error: dimensions for PCT_CROP are NOT what is expected') end if - - do m = 0,num_cft - do ni = 1,ns_i - pct_cft_i(m,ni) = pct_cft_i(m,ni) * pctcrop_i(ni) * 0.01_r8 * mask_i(ni) + do ni = 1,ns_i + do m = 1,num_cft + pct_cft_i(m,ni) = pct_cft_i(m,ni) * (pctcrop_i(ni) * 0.01_r8 * mask_i(ni)) end do end do + + ! Readgrid pct_cft_i to determine pct_cft_o call regrid_rawdata(mesh_i, mesh_o, routehandle, pct_cft_i, pct_cft_o, 1, num_cft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Rescale pct_nat_pft_o do no = 1,ns_o - pct_cft_o(m,no) = pct_cft_o(m,no) / pctcrop_o(no) * 0.01_r8 + if (pctcrop_o(no) > 0._r8) then + do m = 1,num_cft + pct_cft_o(m,no) = pct_cft_o(m,no) / (pctcrop_o(no) * 0.01_r8) + end do + else + pct_cft_o(1:num_cft,no) = 0._r8 + end if if (pctlnd_o(no) < 1.0e-6 .or. pctcrop_o(no) < 1.0e-6) then - if (m == 1) then - pct_cft_o(no,m) = 100._r8 - else - pct_cft_o(no,m) = 0._r8 - endif + pct_cft_o(1,no) = 100._r8 + pct_cft_o(2:num_cft,no) = 0._r8 + end if + + ! Correct sums so that if they differ slightly from 100, they are + ! corrected to equal 100 more exactly. + ! Error check: percents should sum to 100 for land grid cells, within roundoff + wst_sum = 0. + do m = 1, num_cft + wst_sum = wst_sum + pct_cft_o(m,no) + enddo + if (abs(wst_sum-100._r8) > relerr) then + write (6,*) subname//'error: crop cft = ',(pct_cft_o(no,m), m = 1, num_cft), & + ' do not sum to 100. at no = ',no,' but to ', wst_sum + call shr_sys_abort() end if + do m = 1, num_cft + pct_cft_o(m,no) = pct_cft_o(m,no) * 100._r8 / wst_sum + end do enddo + end if ! ---------------------------------------- @@ -551,6 +619,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! But first do error checking to make sure specific veg ! types are given where nat-veg and crop is assigned ! ---------------------------------------- + if (use_input_pft) then do no = 1,ns_o if (pctlnd_o(no) > 1.0e-6 .and. pctnatveg_o(no) > 1.0e-6) then @@ -582,69 +651,37 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft pct_cft_o(1,no) = 100._r8 pct_cft_o(2:,no) = 0._r8 end if - pctpft_o(natpft_lb:natpft_ub,no) = pct_nat_pft_o(0:num_natpft,no) - pctpft_o(cft_lb:cft_ub,no) = pct_cft_o(1:num_cft,no) + pctpft_o(natpft_lb:natpft_ub,no) = pct_nat_pft_o(0:num_natpft,no) + pctpft_o(cft_lb:cft_ub,no) = pct_cft_o(1:num_cft,no) end do end if - ! ---------------------------------------- - ! Correct sums so that if they differ slightly from 100, they are - ! corrected to equal 100 more exactly. - ! ---------------------------------------- - do no = 1,ns_o - wst_sum = 0. - do m = 0, num_natpft - wst_sum = wst_sum + pct_nat_pft_o(m,no) - enddo - ! Error check: percents should sum to 100 for land grid cells, within roundoff - if (abs(wst_sum-100._r8) > relerr) then - write (6,*) subname//'error: nat pft = ', (pct_nat_pft_o(m,no), m = 0, num_natpft), & - ' do not sum to 100. at no = ',no,' but to ', wst_sum - call shr_sys_abort() - end if - - ! Correct sum so that if it differs slightly from 100, it is corrected to equal - ! 100 more exactly - do m = 1, num_natpft - pct_nat_pft_o(m,no) = pct_nat_pft_o(m,no) * 100._r8 / wst_sum - end do - - wst_sum = 0. - do m = 1, num_cft - wst_sum = wst_sum + pct_cft_o(m,no) - enddo - ! Error check: percents should sum to 100 for land grid cells, within roundoff - if (abs(wst_sum-100._r8) > relerr) then - write (6,*) subname//'error: crop cft = ',(pct_cft_o(no,m), m = 1, num_cft), & - ' do not sum to 100. at no = ',no,' but to ', wst_sum - call shr_sys_abort() - end if - - ! Correct sum so that if it differs slightly from 100, it is corrected to equal - ! 100 more exactly - do m = 1, num_cft - pct_cft_o(m,no) = pct_cft_o(m,no) * 100._r8 / wst_sum - end do - end do - ! ---------------------------------------- ! Convert % pft as % of grid cell to % pft on the landunit and % of landunit on the grid cell + ! *** NOTE*** pctnatpft_o and pctcft_o are output arguments ! ---------------------------------------- + allocate(output_pct_nat_pft_o(ns_o, 0:num_natpft), stat=ier) + if (ier/=0) call shr_sys_abort('error in allocating output_pct_nat_pft_o') + allocate(output_pct_cft_o(ns_o, 1:num_cft), stat=ier) + if (ier/=0) call shr_sys_abort('error in allocating output_pct_cft_o') + do no = 1,ns_o output_pct_nat_pft_o(no,:) = pct_nat_pft_o(:,no) pctnatpft_o(no) = pct_pft_type( output_pct_nat_pft_o(no,:), pctnatveg_o(no), first_pft_index=natpft_lb ) output_pct_cft_o(no,:) = pct_cft_o(:,no) - pctcft_o(no) = pct_pft_type( output_pct_cft_o(no,:), pctcrop_o(no), first_pft_index=cft_lb ) + pctcft_o(no) = pct_pft_type( output_pct_cft_o(no,:), pctcrop_o(no), first_pft_index=cft_lb) end do + deallocate(output_pct_nat_pft_o) + deallocate(output_pct_cft_o) + ! ----------------------------------------------------------------- ! Error check ! Compare global areas on input and output grids ! Only when you aren't prescribing the vegetation coverage everywhere ! If use_input_pft is set this will compare the global coverage of - ! the prescribed vegetation to the coverage of PFT/CFT's on the input - ! datasets. + ! the prescribed vegetation to the coverage of PFT/CFT's on the input datasets. ! ----------------------------------------------------------------- ! if (presc_cover) then @@ -739,13 +776,12 @@ subroutine mkpft_parse_oride( string ) ! Parse the string with pft fraction and index information on it, to override ! the file with this information rather than reading from a file. ! - use shr_string_mod, only: shr_string_betweenTags, shr_string_countChar - ! !ARGUMENTS: - character(len=256), intent(IN) :: string ! String to parse with PFT fraction and index data - ! - ! !LOCAL VARIABLES: + ! input/output variables + character(len=*), intent(in) :: string ! String to parse with PFT fraction and index data + + ! local variables: integer :: rc ! error return code integer :: num_elms ! number of elements character(len=256) :: substring ! string between tags diff --git a/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 b/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 index ff7f228a86..ed985c4f07 100644 --- a/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 @@ -27,7 +27,6 @@ module mkpftUtilsMod contains !=============================================================== - !----------------------------------------------------------------------- subroutine convert_from_p2g_default(pct_p2g, pctnatpft, pctcft) ! ! !DESCRIPTION: diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 8f5d25421e..890780f73c 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -1021,10 +1021,10 @@ subroutine mkpio_get_dimlengths(pioid, varname, ndims, dimlengths) integer , intent(out) :: dimlengths(:) ! lengths of dimensions of variable ! ! local variables - type(var_desc_t) :: pio_varid - integer :: dimids(size(dimlengths)) - integer :: i - integer :: rcode + type(var_desc_t) :: pio_varid + integer, allocatable :: dimids(:) + integer :: i + integer :: rcode character(len=*), parameter :: subname = 'mkpio_get_dimlengths' !------------------------------------------------------------------------------ @@ -1035,11 +1035,13 @@ subroutine mkpio_get_dimlengths(pioid, varname, ndims, dimlengths) call shr_sys_abort(trim(subname)//' ERROR: dimlengths too small') end if + allocate(dimids(ndims)) rcode = pio_inq_vardimid(pioid, pio_varid, dimids(1:ndims)) dimlengths(:) = 0 ! pre-fill with 0 so we won't have garbage in elements past ndims do i = 1, ndims rcode = pio_inq_dimlen(pioid, dimids(i), dimlengths(i)) end do + deallocate(dimids) end subroutine mkpio_get_dimlengths diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index a7dc1abd1b..ac4b3df34d 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -98,7 +98,7 @@ program mksurfdata use mktopostatsMod , only : mktopostats use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array - use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft + use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft, num_natpft use mkdomainMod , only : mkdomain use mkharvestMod , only : mkharvest, mkharvest_parse_oride use mkgdpMod , only : mkgdp @@ -126,143 +126,151 @@ program mksurfdata implicit none - ! local variables - type(ESMF_Mesh) :: mesh_model - type(ESMF_Field) :: field_model - integer :: nsoilcol ! number of model color classes - integer :: k,m,n ! indices - integer :: ni,nj,ns_o ! indices - integer :: lsize_o - integer :: ier ! error status - integer :: nfdyn ! unit numbers - integer :: omode ! netCDF output mode - integer :: ret ! netCDF return status - integer :: ntim ! time sample for dynamic land use - integer :: year ! year for dynamic land use - integer :: year2 ! year for dynamic land use for harvest file - real(r8) :: suma ! sum for error check - character(len=256) :: string ! string read in - integer :: rcode - - ! pio variables - type(file_desc_t) :: pioid - type(var_desc_t) :: pio_varid - type(io_desc_t) :: pio_iodesc + ! indices + integer :: k,n ! indices + integer :: lsize_o + + ! error status + integer :: ier,rcode ! error status + + ! dynamic land use + integer :: nfdyn ! unit numbers + integer :: ntim ! time sample for dynamic land use + integer :: year ! year for dynamic land use + integer :: year2 ! year for dynamic land use for harvest file + real(r8) :: suma ! sum for error check ! model grid - real(r8), allocatable :: lon(:) - real(r8), allocatable :: lat(:) + real(r8), allocatable :: lon(:) + real(r8), allocatable :: lat(:) ! pct vegetation data - real(r8), allocatable :: landfrac_pft(:) ! PFT data: % land per gridcell - real(r8), allocatable :: pctlnd_pft(:) ! PFT data: % of gridcell for PFTs - real(r8), allocatable :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs - integer , allocatable :: pftdata_mask(:) ! mask indicating real or fake land type - type(pct_pft_type), allocatable :: pctnatpft(:) ! % of grid cell that is nat veg, and breakdown into PFTs - type(pct_pft_type), allocatable :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series - type(pct_pft_type), allocatable :: pctcft(:) ! % of grid cell that is crop, and breakdown into CFTs - type(pct_pft_type), allocatable :: pctcft_max(:) ! % of grid cell maximum CFTs of the time series + real(r8), allocatable :: landfrac_pft(:) ! PFT data: % land per gridcell + real(r8), allocatable :: pctlnd_pft(:) ! PFT data: % of gridcell for PFTs + real(r8), allocatable :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs + integer , allocatable :: pftdata_mask(:) ! mask indicating real or fake land type + type(pct_pft_type), allocatable :: pctnatpft(:) ! % of grid cell that is nat veg, and breakdown into PFTs + type(pct_pft_type), allocatable :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series + type(pct_pft_type), allocatable :: pctcft(:) ! % of grid cell that is crop, and breakdown into CFTs + type(pct_pft_type), allocatable :: pctcft_max(:) ! % of grid cell maximum CFTs of the time series ! harvest initial value - real(r8) :: harvest_initval ! initial value for harvest variables + real(r8) :: harvest_initval ! initial value for harvest variables ! soil fracation saturated area data - real(r8), allocatable :: fmaxsoil(:) ! soil_fractional saturated area + real(r8), allocatable :: fmaxsoil(:) ! soil_fractional saturated area ! oranic matter density data - real(r8), allocatable :: organic(:,:) ! organic matter density (kg/m3) + real(r8), allocatable :: organic(:,:) ! organic matter density (kg/m3) ! gdp data - real(r8), allocatable :: gdp(:) ! GDP (x1000 1995 US$/capita) + real(r8), allocatable :: gdp(:) ! GDP (x1000 1995 US$/capita) ! peatland data - real(r8), allocatable :: fpeat(:) ! peatland fraction of gridcell + real(r8), allocatable :: fpeat(:) ! peatland fraction of gridcell ! topography statistics data - real(r4), allocatable :: topo_stddev(:) ! standard deviation of elevation (m) - real(r4), allocatable :: slope(:) ! topographic slope (degrees) + real(r4), allocatable :: topo_stddev(:) ! standard deviation of elevation (m) + real(r4), allocatable :: slope(:) ! topographic slope (degrees) ! agricultural peak month data - integer , allocatable :: agfirepkmon(:) ! agricultural fire peak month + integer , allocatable :: agfirepkmon(:) ! agricultural fire peak month ! inland water data - real(r8), allocatable :: pctlak(:) ! percent of grid cell that is lake - real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland - real(r8), allocatable :: lakedepth(:) ! lake depth (m) + real(r8), allocatable :: pctlak(:) ! percent of grid cell that is lake + real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland + real(r8), allocatable :: lakedepth(:) ! lake depth (m) ! glacier data - integer, allocatable :: glacier_region(:) ! glacier region ID - real(r8), allocatable :: pctgla(:) ! percent of grid cell that is glacier - real(r8), allocatable :: pctglc_gic(:) ! percent of grid cell that is gic (% of glc landunit) - real(r8), allocatable :: pctglc_icesheet(:) ! percent of grid cell that is ice sheet (% of glc landunit) - real(r8), allocatable :: pctglcmec(:,:) ! glacier_mec pct coverage in each class (% of landunit) - real(r8), allocatable :: pctglcmec_gic(:,:) ! GIC pct coverage in each class (% of landunit) - real(r8), allocatable :: pctglcmec_icesheet(:,:) ! icesheet pct coverage in each class (% of landunit) - real(r8), allocatable :: elevclass(:) ! glacier_mec elevation classes - real(r8), allocatable :: topoglcmec(:,:) ! glacier_mec sfc elevation in each gridcell and class + integer, allocatable :: glacier_region(:) ! glacier region ID + real(r8), allocatable :: pctgla(:) ! percent of grid cell that is glacier + real(r8), allocatable :: pctglc_gic(:) ! percent of grid cell that is gic (% of glc landunit) + real(r8), allocatable :: pctglc_icesheet(:) ! percent of grid cell that is ice sheet (% of glc landunit) + real(r8), allocatable :: pctglcmec(:,:) ! glacier_mec pct coverage in each class (% of landunit) + real(r8), allocatable :: pctglcmec_gic(:,:) ! GIC pct coverage in each class (% of landunit) + real(r8), allocatable :: pctglcmec_icesheet(:,:) ! icesheet pct coverage in each class (% of landunit) + real(r8), allocatable :: elevclass(:) ! glacier_mec elevation classes + real(r8), allocatable :: topoglcmec(:,:) ! glacier_mec sfc elevation in each gridcell and class ! urban data - integer , allocatable :: urban_region(:) ! urban region ID - real(r8), allocatable :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) - real(r8), allocatable :: urban_classes(:,:) ! percent cover of each urban class, as % of total urban area - real(r8), allocatable :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell - real(r8), allocatable :: elev(:) ! glc elevation (m) + integer , allocatable :: urban_region(:) ! urban region ID + real(r8), allocatable :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) + real(r8), allocatable :: urban_classes(:,:) ! percent cover of each urban class, as % of total urban area + real(r8), allocatable :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell + real(r8), allocatable :: elev(:) ! glc elevation (m) ! soil color data - integer , allocatable :: soil_color(:) ! soil color + integer :: nsoilcol ! number of model color classes + integer , allocatable :: soil_color(:) ! soil color ! soil texture data - real(r8), allocatable :: pctsand(:,:) ! soil texture: percent sand - real(r8), allocatable :: pctclay(:,:) ! soil texture: percent clay - integer , allocatable :: mapunits(:) ! input grid: igbp soil mapunits + real(r8), allocatable :: pctsand(:,:) ! soil texture: percent sand + real(r8), allocatable :: pctclay(:,:) ! soil texture: percent clay + integer , allocatable :: mapunits(:) ! input grid: igbp soil mapunits ! soil depth data - real(r8), allocatable :: soildepth(:) ! soil depth (m) + real(r8), allocatable :: soildepth(:) ! soil depth (m) ! VOC data - real(r8), allocatable :: ef1_btr(:) ! Isoprene emission factor for broadleaf - real(r8), allocatable :: ef1_fet(:) ! Isoprene emission factor for fine/everg - real(r8), allocatable :: ef1_fdt(:) ! Isoprene emission factor for fine/dec - real(r8), allocatable :: ef1_shr(:) ! Isoprene emission factor for shrubs - real(r8), allocatable :: ef1_grs(:) ! Isoprene emission factor for grasses - real(r8), allocatable :: ef1_crp(:) ! Isoprene emission factor for crops + real(r8), allocatable :: ef1_btr(:) ! Isoprene emission factor for broadleaf + real(r8), allocatable :: ef1_fet(:) ! Isoprene emission factor for fine/everg + real(r8), allocatable :: ef1_fdt(:) ! Isoprene emission factor for fine/dec + real(r8), allocatable :: ef1_shr(:) ! Isoprene emission factor for shrubs + real(r8), allocatable :: ef1_grs(:) ! Isoprene emission factor for grasses + real(r8), allocatable :: ef1_crp(:) ! Isoprene emission factor for crops ! VIC data - real(r8), allocatable :: vic_binfl(:) ! VIC b - real(r8), allocatable :: vic_ws(:) ! VIC Ws parameter (unitless) - real(r8), allocatable :: vic_dsmax(:) ! VIC Dsmax parameter (mm/day) - real(r8), allocatable :: vic_ds(:) ! VIC Ds parameter (unitless) + real(r8), allocatable :: vic_binfl(:) ! VIC b + real(r8), allocatable :: vic_ws(:) ! VIC Ws parameter (unitless) + real(r8), allocatable :: vic_dsmax(:) ! VIC Dsmax parameter (mm/day) + real(r8), allocatable :: vic_ds(:) ! VIC Ds parameter (unitless) ! logicals - logical :: zero_out_lake ! if should zero glacier out - logical :: zero_out_wetland ! if should zero glacier out - logical :: zero_out - character(len=cs) :: fname + logical :: zero_out_lake ! if should zero glacier out + logical :: zero_out_wetland ! if should zero glacier out + logical :: zero_out + + ! pio/esmf variables + type(file_desc_t) :: pioid + type(var_desc_t) :: pio_varid + type(io_desc_t) :: pio_iodesc + integer :: petcount + integer :: stride ! esmf variables - integer :: rc - type(ESMF_LogKind_Flag) :: logkindflag - type(ESMF_VM) :: vm - integer :: petcount - integer :: stride - character(len=CS) :: varname - logical :: create_esmf_pet_files = .true. - character(len=32) :: subname = 'mksrfdata' ! program name + type(ESMF_Mesh) :: mesh_model + type(ESMF_Field) :: field_model + type(ESMF_LogKind_Flag) :: logkindflag + type(ESMF_VM) :: vm + integer :: rc + logical :: create_esmf_pet_files = .true. + + ! character variables + character(len=CS) :: string ! string read in + character(len=CS) :: fname + character(len=CS) :: varname + character(len=32) :: subname = 'mksrfdata' ! program name + + real(r8), allocatable :: pctnatveg(:) + real(r8), allocatable :: pctcrop(:) + real(r8), allocatable :: pct_nat_pft(:,:) + real(r8), allocatable :: pct_cft(:,:) + integer :: bounds(2) character(len=*) , parameter :: u_FILE_u = & __FILE__ ! ------------------------------------------------------------ - ! ------------------ + ! ====================================================================== ! Initialize MPI - ! ------------------ + ! ====================================================================== call MPI_init(rc) mpicom = mpi_comm_world - ! ------------------ + ! ====================================================================== ! Initialize ESMF and get mpicom from ESMF - ! ------------------ + ! ====================================================================== if (create_esmf_pet_files) then logkindflag = ESMF_LOGKIND_MULTI @@ -279,9 +287,12 @@ program mksurfdata call ESMF_LogSet(flush=.true.) call ESMF_LogWrite("mksurfdata starting", ESMF_LOGMSG_INFO) - ! ------------------ - ! Initialize PIO - first phase - ! ------------------ + ! Determine root task + root_task = (iam == 0) + + ! ====================================================================== + ! Initialize PIO + ! ====================================================================== ! the following returns pio_iosystem call pio_init(iam, mpicom, max(1,petcount/stride), 0, stride, PIO_REARR_SUBSET, pio_iosystem) @@ -291,18 +302,16 @@ program mksurfdata call ESMF_LogWrite("finished initializing PIO", ESMF_LOGMSG_INFO) - ! ------------------ - ! Read input namelist on root_task and broadcast to all pes - ! ------------------ + ! ====================================================================== + ! Read in namelist + ! ====================================================================== + ! Read input namelist on root_task and broadcast to all pes ! root_task is a module variable in mkvarctl - root_task = (iam == 0) - call read_namelist_input() + ! Assumne that input namelist file is 'mksurfdata_in' + call read_namelist_input(filename='mksurfdata_in') - ! ------------------ ! open output ndiag file - ! ------------------ - if (fsurlog == ' ') then call shr_sys_abort(' ERROR: must specify fsurlog in namelist') end if @@ -317,16 +326,13 @@ program mksurfdata ndiag = 6 end if - ! ------------------ ! Write out namelist input to ndiag - ! ------------------ - call check_namelist_input() call write_namelist_input() - ! ---------------------------------------------------------------------- - ! Read in model mesh - ! ---------------------------------------------------------------------- + ! ====================================================================== + ! Create fsurdat + ! ====================================================================== ! Read in model mesh to determine the number of local points mesh_model = ESMF_MeshCreate(filename=trim(mksrf_fgrid_mesh), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) @@ -336,10 +342,6 @@ program mksurfdata call ESMF_MeshGet(mesh_model, numOwnedElements=lsize_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - ! ====================================================================== - ! Create fsurdat - ! ====================================================================== - ! Initialize urban dimensions (needed to initialize the dimensions in fsurdat) call mkurbanInit (mksrf_furban) @@ -383,6 +385,8 @@ program mksurfdata rcode = pio_enddef(pioid) end if + ! NOTE: do not deallocate pctlak, pctwet, pctglacier and pcturban + ! ----------------------------------- ! Write out coordinate variables ! ----------------------------------- @@ -414,24 +418,21 @@ program mksurfdata ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] ! ----------------------------------- ! Determine fractional land from pft dataset - allocate ( pctlnd_pft(lsize_o)) ; pctlnd_pft(:) = spval - allocate ( pctnatpft(lsize_o)) ; - allocate ( pctcft(lsize_o)) ; + allocate(pctlnd_pft(lsize_o)); pctlnd_pft(:) = spval + allocate(pctnatpft(lsize_o)) ; + allocate(pctcft(lsize_o)) ; call mkpft( mksrf_fvegtyp_mesh, mksrf_fvegtyp, mesh_model, & pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') - if (fsurdat /= ' ') then - ! rcode = pio_inq_varid(pio_ 'PCT_NATVEG', pio_varid) - ! call mkfile_output(pioid, mesh_model, pio_varid, get_pct_l2g_array(pctnatpft), rc=rc) - ! rcode = pio_inq_varid(ncid, 'PCT_CROP', pio_varid) - ! call mkfile_output(pioid, mesh_model, pio_varid, get_pct_l2g_array(pctcft), rc=rc) - ! rcode = pio_inq_varid(ncid, 'PCT_NAT_PFT', pio_varid) - ! call mkfile_output(pioid, mesh_model, pio_varid, get_pct_p2l_array(pctnatpft), rc=rc) - ! if (num_cft > 0) then - ! rcode = pio_inq_varid(ncid, 'PCT_CFT', varid) - ! call mkfile_output(pioid, mesh_model, pio_varid, get_pct_p2l_array(pctcft), rc=rc) - ! end if - end if + + ! If have pole points on grid - set south pole to glacier + ! north pole is assumed as non-land + do n = 1,lsize_o + if (abs((lat(n) - 90._r8)) < 1.e-6_r8) then + call pctnatpft(n)%set_pct_l2g(0._r8) + call pctcft(n)%set_pct_l2g(0._r8) + end if + end do ! ----------------------------------- ! Make landfrac_pft and pftdata_mask @@ -446,8 +447,8 @@ program mksurfdata pftdata_mask(n) = 1 end if if (pctlnd_pft(n) < 1.e-6_r8) then - !call pctnatpft(n)%set_pct_l2g(0._r8) - !call pctcft(n)%set_pct_l2g(0._r8) + call pctnatpft(n)%set_pct_l2g(0._r8) + call pctcft(n)%set_pct_l2g(0._r8) end if end do if (fsurdat /= ' ') then @@ -631,7 +632,7 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') call pio_syncfile(pioid) end if - deallocate (soildepth ) + deallocate (soildepth) ! ----------------------------------- ! Make agricultural fire peak month data [abm] from [abm] @@ -740,6 +741,10 @@ program mksurfdata if (pctlnd_pft(n) < 1.e-6_r8) then organic(n,:) = 0._r8 end if + ! If have pole points on grid - set south pole to glacier and north pole is not land + if (abs((lat(n) - 90._r8)) < 1.e-6_r8) then + organic(n,:) = 0._r8 + end if end do if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil organic matter density" @@ -762,6 +767,19 @@ program mksurfdata ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkvocef') + + ! If have pole points on grid - set south pole to glacier + ! north pole is assumed as non-land + do n = 1,lsize_o + if (abs((lat(n) - 90._r8)) < 1.e-6_r8) then + ef1_btr(n) = 0._r8 + ef1_fet(n) = 0._r8 + ef1_fdt(n) = 0._r8 + ef1_shr(n) = 0._r8 + ef1_grs(n) = 0._r8 + ef1_crp(n) = 0._r8 + end if + end do if (root_task) write(ndiag, '(a)') trim(subname)//" writing out voc emission factors" call mkfile_output(pioid, mesh_model, 'EF1_BTR', ef1_btr, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') @@ -778,15 +796,22 @@ program mksurfdata end if deallocate (ef1_btr, ef1_fet, ef1_fdt, ef1_shr, ef1_grs, ef1_crp ) - ! TODO: - ! Do landuse changes such as for the poles, etc. - ! call change_landuse(dynpft=.false., lat_o=lat_o) - ! ----------------------------------- - ! Modify pctlak, pctwet, pctgla and pcturb where needed + ! ! ----------------------------------- do n = 1,lsize_o + + ! Do landuse changes such as for the poles, etc. + ! If have pole points on grid - set south pole to glacier + ! north pole is assumed as non-land + if (abs((lat(n) - 90._r8)) < 1.e-6_r8) then + pctlak(n) = 0._r8 + pctwet(n) = 0._r8 + pcturb(n) = 0._r8 + pctgla(n) = 100._r8 + end if + ! Truncate all percentage fields on output grid. This is needed to insure that ! wt is zero (not a very small number such as 1e-16) where it should be zero pctlak(n) = float(nint(pctlak(n))) @@ -821,69 +846,88 @@ program mksurfdata end if end do - if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glacier" - call mkfile_output(pioid, mesh_model, 'PCT_GLACIER', pctgla, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in mkfile_output for pctgla') - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_lake" - call mkfile_output(pioid, mesh_model, 'PCT_LAKE', pctlak, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in mkfile_output for pctlak') - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_wetland" - call mkfile_output(pioid, mesh_model, 'PCT_WETLAND', pctwet, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in in mkfile_output for pctwet') - end if - ! NOTE: do not deallocate pctlak, pctwet, pctglacier and pcturban - - ! ---------------------------------------------------------------------- - ! TODO: - ! call normalizencheck_landuse() - ! ---------------------------------------------------------------------- + ! Normalize land use and make sure things add up to 100% as well as + ! checking that things are as they should be. + call normalize_and_check_landuse(lsize_o) - ! ---------------------------------------------------------------------- - ! TODO: ! Write out sum of PFT's - ! ---------------------------------------------------------------------- - ! do k = natpft_lb,natpft_ub - ! suma = 0._r8 - ! do n = 1,lsize_o - ! suma = suma + pctnatpft(n)%get_one_pct_p2g(k) - ! enddo - ! write(6,*) 'sum over domain of pft ',k,suma - ! enddo - ! if (root_task) write(ndiag,*) - ! - ! do k = cft_lb,cft_ub - ! suma = 0._r8 - ! do n = 1,lsize_o - ! suma = suma + pctcft(n)%get_one_pct_p2g(k) - ! enddo - ! write(6,*) 'sum over domain of cft ',k,suma - ! enddo - ! if (root_task) write(ndiag,*) + do k = natpft_lb,natpft_ub + suma = 0._r8 + do n = 1,lsize_o + suma = suma + pctnatpft(n)%get_one_pct_p2g(k) + enddo + write(6,*) 'sum over domain of pft ',k,suma + enddo + if (root_task) write(ndiag,*) + do k = cft_lb,cft_ub + suma = 0._r8 + do n = 1,lsize_o + suma = suma + pctcft(n)%get_one_pct_p2g(k) + enddo + write(6,*) 'sum over domain of cft ',k,suma + enddo + if (root_task) write(ndiag,*) - - ! ----------------------------------- ! Make final values of percent urban by class and compute urban parameters - ! ----------------------------------- - ! This call needs to occur after all corrections are made to pcturb allocate (urban_classes_g(lsize_o,numurbl)); urban_classes_g(:,:) = spval call normalize_classes_by_gcell(urban_classes, pcturb, urban_classes_g) if (root_task) write(ndiag, '(a)') trim(subname)//" writing out percnt urban" - call mkfile_output(pioid, mesh_model, 'PCT_URBAN', urban_classes_g, lev1name='numurbl', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - ! Now Make Urban Parameters from raw input data and write to surface dataset + ! Make Urban Parameters from raw input data and write to surface dataset ! Write to netcdf file is done inside mkurbanpar routine call mkurbanpar(mksrf_furban, pioid, mesh_model, urban_region, urban_classes_g, & urban_skip_abort_on_invalid_data_check) - - deallocate(pcturb) deallocate(urban_classes) deallocate(urban_region) + ! Write out PCT_URBAN, PCT_GLACIER, PCT_LAKE and PCT_WETLAND and + ! PCT_NATVEG, PCT_NAT_PFT, PCT_CROP and PCT_CFT + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out PCT_URBAN" + call mkfile_output(pioid, mesh_model, 'PCT_URBAN', urban_classes_g, lev1name='numurbl', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out PCT_GLACIER" + call mkfile_output(pioid, mesh_model, 'PCT_GLACIER', pctgla, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in mkfile_output for pctgla') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out PCT_LAKE" + call mkfile_output(pioid, mesh_model, 'PCT_LAKE', pctlak, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in mkfile_output for pctlak') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out PCT_WETLAND" + call mkfile_output(pioid, mesh_model, 'PCT_WETLAND', pctwet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in in mkfile_output for pctwet') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_NATVEG" + if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_NATVEG" + allocate(pctnatveg(lsize_o)) + call get_pct_l2g_array(pctnatpft, pctnatveg) + call mkfile_output(pioid, mesh_model, 'PCT_NATVEG', pctnatveg, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NATVEG') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_CROP" + allocate(pctcrop(lsize_o)) + call get_pct_l2g_array(pctcft, pctcrop) + call mkfile_output(pioid, mesh_model, 'PCT_CROP', pctcrop, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_NAT_PFT" + allocate(pct_nat_pft(lsize_o, 0:num_natpft)) + call get_pct_p2l_array(pctnatpft, ndim1=lsize_o, ndim2=num_natpft+1, pct_p2l=pct_nat_pft) + call mkfile_output(pioid, mesh_model, 'PCT_NAT_PFT', pct_nat_pft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NAT_PFT') + + if (num_cft > 0) then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_CFT" + allocate(pct_cft(lsize_o, num_cft)) + call get_pct_p2l_array(pctcft, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) + call mkfile_output(pioid, mesh_model, 'PCT_CFT', pct_cft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CFT') + end if + end if + ! ---------------------------------------------------------------------- ! Make glacier multiple elevation classes [pctglcmec,topoglcmec] from [fglacier] dataset ! ---------------------------------------------------------------------- @@ -974,7 +1018,7 @@ program mksurfdata allocate(pctcft_max(lsize_o)) ; allocate(pctnatpft_max(lsize_o)) ; - allocate(pctlnd_pft_dyn(ns_o)) + allocate(pctlnd_pft_dyn(lsize_o)) ! open output file call mkpio_wopen(trim(fdyndat), clobber=.true., pioid=pioid) @@ -988,6 +1032,16 @@ program mksurfdata ! End define model rcode = pio_enddef(pioid) + ! Write out natpft + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out natpft" + rcode = pio_inq_varid(pioid, 'natpft', pio_varid) + rcode = pio_put_var(pioid, pio_varid, (/(n,n=natpft_lb,natpft_ub)/)) + + ! Write out cft + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out cft" + rcode = pio_inq_varid(pioid, 'cft', pio_varid) + rcode = pio_put_var(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/)) + ! Write out model grid if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" call mkfile_output(pioid, mesh_model, 'LONGXY', lon, rc=rc) @@ -1006,10 +1060,12 @@ program mksurfdata rcode = pio_inq_varid(pioid, 'cft', pio_varid) rcode = pio_put_var(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/)) + ! Write out PFTDATA_MASK if (root_task) write(ndiag, '(a)') trim(subname)//" writing land mask from pft dataset" call mkfile_output(pioid, mesh_model, 'PFTDATA_MASK', pftdata_mask, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + ! Write out LANDFRAC_PFT if (root_task) write(ndiag, '(a)') trim(subname)//" writing land fraction from pft dataset" call mkfile_output(pioid, mesh_model, 'LANDFRAC_PFT', landfrac_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') @@ -1083,11 +1139,22 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest') ! Do landuse changes such as for the poles, etc. - call change_landuse( dynpft=.true.) + ! If have pole points on grid - set south pole to glacier + ! north pole is assumed as non-land + do n = 1,lsize_o + if (abs(lat(n) - 90._r8) < 1.e-6_r8) then + pctlak(n) = 0._r8 + pctwet(n) = 0._r8 + pcturb(n) = 0._r8 + pctgla(n) = 100._r8 + call pctnatpft(n)%set_pct_l2g(0._r8) + call pctcft(n)%set_pct_l2g(0._r8) + end if + end do ! Normalize land use and make sure things add up to 100% as well as ! checking that things are as they should be. - call normalizencheck_landuse(ns_o) + call normalize_and_check_landuse(lsize_o) ! Given an array of pct_pft_type variables, update all the max_p2l variables. call update_max_array(pctnatpft_max,pctnatpft) @@ -1113,26 +1180,26 @@ program mksurfdata end do ! end of read loop - rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT_MAX', pio_varid) - rcode = pio_put_var(pioid, pio_varid, get_pct_p2l_array(pctnatpft_max)) + ! TODO: need to use pio here with io descriptors + ! rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT_MAX', pio_varid) + ! rcode = pio_put_var(pioid, pio_varid, get_pct_p2l_array(pctnatpft_max)) - rcode = pio_inq_varid(pioid, 'PCT_CROP_MAX', pio_varid) - rcode = pio_put_var(pioid, pio_varid, get_pct_l2g_array(pctcft_max)) + ! rcode = pio_inq_varid(pioid, 'PCT_CROP_MAX', pio_varid) + ! rcode = pio_put_var(pioid, pio_varid, get_pct_l2g_array(pctcft_max)) - if (num_cft > 0) then - rcode = pio_inq_varid(pioid, 'PCT_CFT_MAX', pio_varid) - rcode = pio_put_var(pioid, pio_varid, get_pct_p2l_array(pctcft_max)) - end if + ! if (num_cft > 0) then + ! rcode = pio_inq_varid(pioid, 'PCT_CFT_MAX', pio_varid) + ! rcode = pio_put_var(pioid, pio_varid, get_pct_p2l_array(pctcft_max)) + ! end if ! Close the file call pio_closefile(pioid) end if ! end of if-create dynamic landust dataset - ! ====================================================================== + ! ----------------------------------- ! Wrap things up - ! ====================================================================== - + ! ----------------------------------- if (root_task) then write (ndiag,'(a)') write (ndiag,'(a)') 'Surface data output file = '//trim(fsurdat) @@ -1151,43 +1218,7 @@ program mksurfdata contains !----------------------------------------------------------------------- - subroutine change_landuse(dynpft) - - ! Do landuse changes such as for the poles, etc. - ! If have pole points on grid - set south pole to glacier - ! north pole is assumed as non-land - - ! input/output variables - logical, intent(in) :: dynpft ! if part of the dynpft section of code - - ! local variables: - integer :: n ! indices - character(len=*), parameter :: subname = 'change_landuse' ! subroutine name - !----------------------------------------------------------------------- - - do n = 1,lsize_o - if (abs(lat(n) - 90._r8) < 1.e-6_r8) then - pctlak(n) = 0._r8 - pctwet(n) = 0._r8 - pcturb(n) = 0._r8 - pctgla(n) = 100._r8 - call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) - if ( .not. dynpft )then - organic(n,:) = 0._r8 - ef1_btr(n) = 0._r8 - ef1_fet(n) = 0._r8 - ef1_fdt(n) = 0._r8 - ef1_shr(n) = 0._r8 - ef1_grs(n) = 0._r8 - ef1_crp(n) = 0._r8 - end if - end if - end do - end subroutine change_landuse - - !----------------------------------------------------------------------- - subroutine normalizencheck_landuse(ns_o) + subroutine normalize_and_check_landuse(ns_o) ! ! Normalize land use and make sure things add up to 100% as well as ! checking that things are as they should be. @@ -1201,7 +1232,7 @@ subroutine normalizencheck_landuse(ns_o) integer, intent(in) :: ns_o ! local variables: - integer :: m,k,n ! indices + integer :: k,n ! indices integer :: nsmall ! number of small PFT values for a single check integer :: nsmall_tot ! total number of small PFT values in all grid cells real(r8) :: suma ! sum for error check @@ -1472,6 +1503,6 @@ subroutine normalizencheck_landuse(ns_o) write (6,*)'number of small pft = ', nsmall_tot end if - end subroutine normalizencheck_landuse + end subroutine normalize_and_check_landuse end program mksurfdata diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index fb567e371e..baa45f8f3d 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -186,7 +186,7 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, if (chkerr(rc,__LINE__,u_FILE_u)) return slope_o(:) = dataptr(:) - !call output_diagnostics_continuous(data_i, slope_o, tgridmap, + ! call output_diagnostics_continuous(data_i, slope_o, tgridmap, !"Slope", "degrees", ndiag, tdomain%mask, tgridmap%frac_dst) ! Check validity of output data @@ -196,6 +196,15 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, !end if ! Close files and deallocate dynamic memory + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) if (root_task) then write (ndiag,'(a)') 'Successfully made Topography statistics' diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index 7cdf897522..f511a653b8 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -155,12 +155,18 @@ module mkvarctl contains !=============================================================== - subroutine read_namelist_input() + subroutine read_namelist_input(filename) + + ! Read in input namelist + + ! input/output variables + character(len=*), intent(in) :: filename ! local variables integer :: ier integer :: fileunit logical :: lexist + character(len=*), parameter :: subname = 'read_namelist_input' ! ------------------------------------------------------------ namelist /mksurfdata_input/ & @@ -254,14 +260,14 @@ subroutine read_namelist_input() end if if (root_task) then - inquire (file='mksurfdata_in', exist=lexist) + inquire (file=trim(filename), exist=lexist) if (.not. lexist) then - call shr_sys_abort('mksurfdata_in does not exist') + call shr_sys_abort(subname//trim(filename)//' does not exist') end if - open(newunit=fileunit, status="old", file="mksurfdata_in") + open(newunit=fileunit, status="old", file=trim(filename)) read(fileunit, nml=mksurfdata_input, iostat=ier) if (ier > 0) then - call shr_sys_abort('error reading in mksurfdata_input namelist from mksurfdata_in') + call shr_sys_abort(subname//' error reading in mksurfdata_input namelist from '//trim(filename)) end if close(fileunit) end if From 340a29276dfab45ad3cd2c684822d64eca611f85 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 15 Feb 2022 11:21:19 -0700 Subject: [PATCH 063/614] updates to log output --- tools/mksurfdata_esmf/src/mkgdpMod.F90 | 3 ++- tools/mksurfdata_esmf/src/mkglcmecMod.F90 | 10 +++++---- tools/mksurfdata_esmf/src/mklaiMod.F90 | 2 +- tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 | 5 +++-- tools/mksurfdata_esmf/src/mksurfdata.F90 | 22 ++++++++++---------- tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 2 ++ 6 files changed, 25 insertions(+), 19 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkgdpMod.F90 b/tools/mksurfdata_esmf/src/mkgdpMod.F90 index 1b4d8e8445..940fa609e0 100644 --- a/tools/mksurfdata_esmf/src/mkgdpMod.F90 +++ b/tools/mksurfdata_esmf/src/mkgdpMod.F90 @@ -67,6 +67,8 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, gdp_o, rc) rc = ESMF_SUCCESS if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to make GDP.....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) @@ -150,7 +152,6 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, gdp_o, rc) if (root_task) then write (ndiag,'(a)') 'Successfully made GDP' - write (ndiag,'(a)') end if end subroutine mkgdp diff --git a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 index b398447b2a..751b97aaac 100644 --- a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 @@ -140,7 +140,7 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & integer :: pio_vartype integer :: ni,no,lev integer :: ns_i, ns_o - integer :: n,m ! indices + integer :: n,m,k ! indices integer :: dimid ! dimension ids integer :: ndims ! number of dimensions in input variables integer :: nlev ! number of levels in input file @@ -173,7 +173,9 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & if (root_task) then write(ndiag,*) - write (ndiag,'(a)') 'Attempting to make percent elevation class ',& + write(ndiag,'(1x,80a1)') ('=',k=1,80) + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make percent elevation class ',& 'and mean elevation for glaciers .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) @@ -437,7 +439,6 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & if (root_task) then write (ndiag,'(a)') 'Successfully made percent elevation class and mean elevation for glaciers' - write (ndiag,'(a)') end if end subroutine mkglcmec @@ -489,6 +490,8 @@ subroutine mkglacier(file_mesh_i, file_data_i, mesh_o, glac_o, rc) !----------------------------------------------------------------------- if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to make %glacier .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) @@ -601,7 +604,6 @@ subroutine mkglacier(file_mesh_i, file_data_i, mesh_o, glac_o, rc) if (root_task) then write (ndiag,'(a)') 'Successfully made %glacier' - write (ndiag,*) end if end subroutine mkglacier diff --git a/tools/mksurfdata_esmf/src/mklaiMod.F90 b/tools/mksurfdata_esmf/src/mklaiMod.F90 index 6c18e122a9..2d9923d9f5 100644 --- a/tools/mksurfdata_esmf/src/mklaiMod.F90 +++ b/tools/mksurfdata_esmf/src/mklaiMod.F90 @@ -267,10 +267,10 @@ subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) end do ! end loop over months ! Close the input file - call pio_freedecomp(pioid_i, pio_iodesc_i) call pio_freedecomp(pioid_o, pio_iodesc_o) call pio_closefile(pioid_i) + call pio_freedecomp(pio_iosystem, pio_iodesc_i) call ESMF_VMLogMemInfo("After pio_closefile for input in "//trim(subname)) ! Release memory diff --git a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 index 3d196d1678..2fde396999 100644 --- a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 @@ -78,7 +78,9 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) write(6,*)'soil_fmax is out of range = ', soil_fmax_override call shr_sys_abort() end if - write(6,*) 'Replace soil fmax for all points with: ', soil_fmax_override + if (root_task) then + write(ndiag,'(a,d13.5)') 'Replacing soil fmax for all points with: ', soil_fmax_override + end if end if ! Open input data file @@ -219,7 +221,6 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) if (root_task) then write (ndiag,'(a)') 'Successfully made %fmax' - write (ndiag,*) end if end subroutine mksoilfmax diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index ac4b3df34d..3ade517ad7 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -461,6 +461,17 @@ program mksurfdata call pio_syncfile(pioid) end if + ! ----------------------------------- + ! Make LAI and SAI from 1/2 degree data and write to surface dataset + ! Write to netcdf file is done inside mklai routine + ! ----------------------------------- + if (root_task) then + write(ndiag,'(a)')'calling mklai' + end if + call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') + call pio_syncfile(pioid) + ! ----------------------------------- ! Make constant harvesting data at model resolution ! ----------------------------------- @@ -682,17 +693,6 @@ program mksurfdata deallocate(elev) end if - ! ----------------------------------- - ! Make LAI and SAI from 1/2 degree data and write to surface dataset - ! Write to netcdf file is done inside mklai routine - ! ----------------------------------- - if (root_task) then - write(ndiag,'(a)')'calling mklai' - end if - call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') - call pio_syncfile(pioid) - ! ----------------------------------- ! Compute topography statistics [topo_stddev, slope] from [ftopostats] ! ----------------------------------- diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index baa45f8f3d..5be35ce637 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -68,6 +68,8 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, !----------------------------------------------------------------------- if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to make Topography statistics.....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) From 0795c548c6d65af185ebf1c2e608f2481f9f3743 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 15 Feb 2022 18:08:53 -0700 Subject: [PATCH 064/614] updates for getting mklai and topostd to work at the same time --- tools/mksurfdata_esmf/run/run_mksurfdata | 4 +- tools/mksurfdata_esmf/src/CMakeLists.txt | 3 +- .../src/mkagfirepkmonthMod.F90 | 3 ++ tools/mksurfdata_esmf/src/mklaiMod.F90 | 5 +- tools/mksurfdata_esmf/src/mkorganicMod.F90 | 4 +- tools/mksurfdata_esmf/src/mkpeatMod.F90 | 2 + tools/mksurfdata_esmf/src/mkpioMod.F90 | 1 - tools/mksurfdata_esmf/src/mksurfdata.F90 | 52 +++++++++++-------- tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 7 ++- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 7 +++ tools/mksurfdata_esmf/src/mkvocefMod.F90 | 2 + 11 files changed, 59 insertions(+), 31 deletions(-) diff --git a/tools/mksurfdata_esmf/run/run_mksurfdata b/tools/mksurfdata_esmf/run/run_mksurfdata index 589b69f248..5869d7c697 100755 --- a/tools/mksurfdata_esmf/run/run_mksurfdata +++ b/tools/mksurfdata_esmf/run/run_mksurfdata @@ -7,7 +7,7 @@ ##PBS -l select=1:ncpus=36:mpiprocs=36 ##PBS -l select=4:ncpus=36:mpiprocs=36 ##PBS -l select=16:ncpus=36:mpiprocs=9 -#PBS -l select=16:ncpus=36:mpiprocs=14 +#PBS -l select=24:ncpus=36:mpiprocs=12 # note for -l input above # -l select={num_nodes}:ncpus={max_tasks_per_node}:mpiprocs={tasks_per_node} @@ -21,4 +21,4 @@ mkdir -p $TMPDIR # -np {total_tasks} #mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata -mpiexec_mpt -p "%g:" -np 224 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata +mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 1461a89b5f..e5a35a2e5f 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -63,7 +63,8 @@ target_include_directories (mksurfdata PRIVATE ${ESMF_F90COMPILEPATHS}) target_include_directories (mksurfdata PRIVATE /glade/work/jedwards/tools/pio/2.5.5/intel/19.1.1/mpt/2.22/include) #target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/include) # non debug version target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/pnetcdf/1.12.2/mpt/2.22/intel/19.1.1//include) -target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/netcdf-mpi/4.8.0/mpt/2.22/intel/19.1.1//include) +#target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/netcdf-mpi/4.8.0/mpt/2.22/intel/19.1.1//include) +target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/netcdf-mpi/4.8.1/mpt/2.22/intel/19.1.1//include) #link_directories(/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/lib) #target_link_libraries(mksurfdata piof) diff --git a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 index 83a8fdc795..110408b0e0 100644 --- a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 +++ b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 @@ -55,6 +55,7 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) type(ESMF_Field) :: field_o type(ESMF_Field) :: field_dstfrac type(file_desc_t) :: pioid + integer :: k integer :: ni,no integer :: ns_i, ns_o integer , allocatable :: mask_i(:) @@ -69,6 +70,8 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) !----------------------------------------------------------------------- if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to make agricultural fire peak month data .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) diff --git a/tools/mksurfdata_esmf/src/mklaiMod.F90 b/tools/mksurfdata_esmf/src/mklaiMod.F90 index 2d9923d9f5..26850d065d 100644 --- a/tools/mksurfdata_esmf/src/mklaiMod.F90 +++ b/tools/mksurfdata_esmf/src/mklaiMod.F90 @@ -266,11 +266,10 @@ subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) end do ! end loop over months - ! Close the input file + ! Free the decomps and close the file call pio_freedecomp(pioid_o, pio_iodesc_o) - + call pio_freedecomp(pioid_i, pio_iodesc_i) call pio_closefile(pioid_i) - call pio_freedecomp(pio_iosystem, pio_iodesc_i) call ESMF_VMLogMemInfo("After pio_closefile for input in "//trim(subname)) ! Release memory diff --git a/tools/mksurfdata_esmf/src/mkorganicMod.F90 b/tools/mksurfdata_esmf/src/mkorganicMod.F90 index 094bd9ea15..24ced6de23 100644 --- a/tools/mksurfdata_esmf/src/mkorganicMod.F90 +++ b/tools/mksurfdata_esmf/src/mkorganicMod.F90 @@ -42,7 +42,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) integer :: ni,no integer :: ns_i, ns_o integer :: nlay - integer :: n, l ! indices + integer :: n,l,k ! indices integer :: rcode, ier ! error status integer :: ndims integer , allocatable :: dimlengths(:) @@ -59,6 +59,8 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) rc = ESMF_SUCCESS if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)')'Attempting to make organic mater dataset .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) diff --git a/tools/mksurfdata_esmf/src/mkpeatMod.F90 b/tools/mksurfdata_esmf/src/mkpeatMod.F90 index 6dc4a00108..2109fed9f0 100644 --- a/tools/mksurfdata_esmf/src/mkpeatMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpeatMod.F90 @@ -66,6 +66,8 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) !----------------------------------------------------------------------- if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to make peat .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 890780f73c..cb08e4a6cc 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -644,7 +644,6 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) end if else if (ndims == 4) then if (unlimited_dim) then - write(6,*)'Creating an output pio descriptor here' call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) else call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3),dimlens(4)/), compdof3d, pio_iodesc) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 3ade517ad7..1743a03210 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -297,7 +297,7 @@ program mksurfdata ! the following returns pio_iosystem call pio_init(iam, mpicom, max(1,petcount/stride), 0, stride, PIO_REARR_SUBSET, pio_iosystem) - pio_iotype = PIO_IOTYPE_NETCDF + pio_iotype = PIO_IOTYPE_PNETCDF pio_ioformat = PIO_64BIT_DATA call ESMF_LogWrite("finished initializing PIO", ESMF_LOGMSG_INFO) @@ -414,6 +414,17 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') end if + ! ----------------------------------- + ! Make LAI and SAI from 1/2 degree data and write to surface dataset + ! Write to netcdf file is done inside mklai routine + ! ----------------------------------- + if (root_task) then + write(ndiag,'(a)')'calling mklai' + end if + call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') + call pio_syncfile(pioid) + ! ----------------------------------- ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] ! ----------------------------------- @@ -424,6 +435,7 @@ program mksurfdata call mkpft( mksrf_fvegtyp_mesh, mksrf_fvegtyp, mesh_model, & pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') + call pio_syncfile(pioid) ! If have pole points on grid - set south pole to glacier ! north pole is assumed as non-land @@ -461,17 +473,6 @@ program mksurfdata call pio_syncfile(pioid) end if - ! ----------------------------------- - ! Make LAI and SAI from 1/2 degree data and write to surface dataset - ! Write to netcdf file is done inside mklai routine - ! ----------------------------------- - if (root_task) then - write(ndiag,'(a)')'calling mklai' - end if - call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') - call pio_syncfile(pioid) - ! ----------------------------------- ! Make constant harvesting data at model resolution ! ----------------------------------- @@ -479,6 +480,7 @@ program mksurfdata call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, & pioid_o=pioid, all_veg=all_veg, constant=.true., rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') + call pio_syncfile(pioid) ! ----------------------------------- ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] @@ -514,6 +516,7 @@ program mksurfdata pctgla(:) = 0. end if end if + call pio_syncfile(pioid) ! ----------------------------------- ! Make glacier region ID [glacier_region] from [fglacierregion] dataset @@ -527,6 +530,7 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') end if deallocate (glacier_region ) + call pio_syncfile(pioid) ! ----------------------------------- ! Make soil texture [pctsand, pctclay] @@ -616,6 +620,7 @@ program mksurfdata call pio_syncfile(pioid) end if deallocate(gdp) + call pio_syncfile(pioid) ! ----------------------------------- ! Make peat data [fpeat] from [peatf] @@ -630,6 +635,7 @@ program mksurfdata call pio_syncfile(pioid) end if deallocate(fpeat) + call pio_syncfile(pioid) ! ----------------------------------- ! Make soil depth data [soildepth] from [soildepthf] @@ -691,6 +697,7 @@ program mksurfdata pcturb = 0._r8 end where deallocate(elev) + call pio_syncfile(pioid) end if ! ----------------------------------- @@ -793,13 +800,10 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') call mkfile_output(pioid, mesh_model, 'EF1_CRP', ef1_crp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid) end if deallocate (ef1_btr, ef1_fet, ef1_fdt, ef1_shr, ef1_grs, ef1_crp ) - ! ----------------------------------- - ! - ! ----------------------------------- - do n = 1,lsize_o ! Do landuse changes such as for the poles, etc. @@ -856,7 +860,10 @@ program mksurfdata do n = 1,lsize_o suma = suma + pctnatpft(n)%get_one_pct_p2g(k) enddo - write(6,*) 'sum over domain of pft ',k,suma + ! TODO: calculate global sum here + if (root_task) then + write(ndiag,*) 'sum over domain of pft ',k,suma + end if enddo if (root_task) write(ndiag,*) do k = cft_lb,cft_ub @@ -864,7 +871,10 @@ program mksurfdata do n = 1,lsize_o suma = suma + pctcft(n)%get_one_pct_p2g(k) enddo - write(6,*) 'sum over domain of cft ',k,suma + ! TODO: calculate global sum here + if (root_task) then + write(6,*) 'sum over domain of cft ',k,suma + end if enddo if (root_task) write(ndiag,*) @@ -886,7 +896,7 @@ program mksurfdata if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing out PCT_URBAN" call mkfile_output(pioid, mesh_model, 'PCT_URBAN', urban_classes_g, lev1name='numurbl', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_URBAN') if (root_task) write(ndiag, '(a)') trim(subname)//" writing out PCT_GLACIER" call mkfile_output(pioid, mesh_model, 'PCT_GLACIER', pctgla, rc=rc) @@ -1299,12 +1309,12 @@ subroutine normalize_and_check_landuse(ns_o) ! correct for rounding error: new_total_veg_pct = max(new_total_veg_pct, 0._r8) - ! call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) + call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) ! Make sure we did the above rescaling correctly suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() if (abs(suma - 100._r8) > tol_loose) then - write(6,*) subname, ' ERROR in rescaling veg based on (special excluding urban' + write(6,*) subname, ' ERROR in rescaling veg based on (special excluding urban)' write(6,*) 'suma = ', suma call shr_sys_abort() end if diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index 5be35ce637..17cb43e284 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -88,7 +88,9 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, end if ! Open input data file - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + ! Read in data with PIO_IOTYPE_NETCDF rather than PIO_IOTYPE_PNETCDF since there are problems + ! with the pnetcdf read of this high resolution data + rcode = pio_openfile(pio_iosystem, pioid, PIO_IOTYPE_NETCDF, trim(file_data_i), pio_nowrite) call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh @@ -104,7 +106,7 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Read in data_i + ! Read in input data data_i allocate(data_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort(subname//' error in allocating data_i') call mkpio_get_rawdata(pioid, 'ELEVATION', mesh_i, data_i, rc=rc) @@ -198,6 +200,7 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, !end if ! Close files and deallocate dynamic memory + call pio_closefile(pioid) call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index a1a0fb3a16..a21c33d002 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -143,6 +143,8 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & rc = ESMF_SUCCESS if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to make %urban .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) @@ -271,6 +273,8 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & ! ------------------------------------------------------ if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to make urban region .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) @@ -901,6 +905,9 @@ subroutine mkurban_topo(file_mesh_i, file_data_i, mesh_o, varname, elev_o, rc) rc = ESMF_SUCCESS if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) + write(ndiag,*) write(ndiag,'(a)') 'Attempting to make urban topo elevation .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) end if diff --git a/tools/mksurfdata_esmf/src/mkvocefMod.F90 b/tools/mksurfdata_esmf/src/mkvocefMod.F90 index 19d42458ee..5510995fe1 100644 --- a/tools/mksurfdata_esmf/src/mkvocefMod.F90 +++ b/tools/mksurfdata_esmf/src/mkvocefMod.F90 @@ -74,6 +74,8 @@ subroutine mkvocef(file_mesh_i, file_data_i, mesh_o, & call ESMF_VMLogMemInfo("At start of "//trim(subname)) if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to make VOC emission factors .....' write(ndiag,'(a)') ' Input data file is '//trim(file_data_i) From 901d6642e5166ebc2af7b7269fe1e8497bb77fa1 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 16 Feb 2022 14:05:57 -0700 Subject: [PATCH 065/614] first changes to get dynamic landunits working --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 19 +-- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 6 +- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 2 - tools/mksurfdata_esmf/src/mkpioMod.F90 | 4 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 140 +++++++++++++-------- tools/mksurfdata_esmf/src/mkvarctl.F90 | 1 + 6 files changed, 95 insertions(+), 77 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 17e8977313..4beb00dceb 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -519,30 +519,13 @@ subroutine mkfile_define_vars(pioid, dynlanduse) end if - if ( outnc_3dglc ) then - call mkpio_def_spatial_var(pioid=pioid, varname='PCT_GLC_MEC_GIC', xtype=xtype, & - lev1name='nglcec', & - long_name='percent smaller glaciers and ice caps for each glacier elevation class (% of landunit)', & - units='unitless') - - call mkpio_def_spatial_var(pioid=pioid, varname='PCT_GLC_MEC_ICESHEET', xtype=xtype, & - lev1name='nglcec', & - long_name='percent ice sheet for each glacier elevation class (% of landunit)', units='unitless') - - call mkpio_def_spatial_var(pioid=pioid, varname='PCT_GLC_GIC', xtype=xtype, & - long_name='percent ice caps/glaciers (% of landunit)', units='unitless') - - call mkpio_def_spatial_var(pioid=pioid, varname='PCT_GLC_ICESHEET', xtype=xtype, & - long_name='percent ice sheet (% of landunit)', units='unitless') - - end if - call mkpio_def_spatial_var(pioid=pioid, varname='PCT_URBAN', xtype=xtype, & lev1name='numurbl', & long_name='percent urban for each density type', units='unitless') call mkpio_def_spatial_var(pioid=pioid, varname='URBAN_REGION_ID', xtype=PIO_INT, & long_name='urban region ID', units='unitless') + end if if (.not. dynlanduse) then diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index 4037acb4f1..192e2cf0ac 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -229,7 +229,8 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constan rcode = pio_inq_varid(pioid_o, trim(varname_o), pio_varid_o) call mkpio_iodesc_output(pioid_o, mesh_o, trim(varname_o), pio_iodesc_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in making an iodesc for '//trim(varname_o)) - call mkpio_put_time_slice(pioid_o, pio_varid_o, pio_iodesc_o, ntime, data2d_o) + call pio_setframe(pioid_o, pio_varid_o, int(ntime, kind=Pio_Offset_Kind)) + call pio_write_darray(pioid_o, pio_varid_o, pio_iodesc_o, data1d_o, rcode) call pio_freedecomp(pioid_o, pio_iodesc_o) else if (root_task) write(ndiag, '(a)') " writing out 1d "//trim(varname_o) @@ -274,7 +275,8 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constan rcode = pio_inq_varid(pioid_o, trim(varname_o), pio_varid_o) call mkpio_iodesc_output(pioid_o, mesh_o, trim(varname_o), pio_iodesc_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in making an iodesc for '//trim(varname_o)) - call mkpio_put_time_slice(pioid_o, pio_varid_o, pio_iodesc_o, ntime, data2d_o) + call pio_setframe(pioid_o, pio_varid_o, int(ntime, kind=Pio_Offset_Kind)) + call pio_write_darray(pioid_o, pio_varid_o, pio_iodesc_o, data2d_o, rcode) call pio_freedecomp(pioid_o, pio_iodesc_o) else if (root_task) write(ndiag, '(a)') " writing out 2d "//trim(varname_o) diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 537fddecc1..9f4a1a994e 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -82,9 +82,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & ! Open raw data file ! ASSUME for now that have only 1 input data file - call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) - call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index cb08e4a6cc..45c772d743 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -707,7 +707,9 @@ subroutine mkpio_wopen(filename, clobber, pioid) !------------------------------------------------------------------------------- ! filename not open - call ESMF_LogWrite("opening output file "//trim(filename), ESMF_LOGMSG_INFO) + if (root_task) then + write(ndiag,'(a)') "opening output file "//trim(filename) + end if if (mkpio_file_exists(filename)) then if (clobber) then diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 1743a03210..8691ed29b8 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -90,7 +90,7 @@ program mksurfdata ! !USES: use ESMF use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs, cl => shr_kind_cl use shr_sys_mod , only : shr_sys_abort #ifdef TODO use mkVICparamsMod , only : mkVICparams @@ -147,11 +147,13 @@ program mksurfdata ! pct vegetation data real(r8), allocatable :: landfrac_pft(:) ! PFT data: % land per gridcell real(r8), allocatable :: pctlnd_pft(:) ! PFT data: % of gridcell for PFTs - real(r8), allocatable :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs integer , allocatable :: pftdata_mask(:) ! mask indicating real or fake land type type(pct_pft_type), allocatable :: pctnatpft(:) ! % of grid cell that is nat veg, and breakdown into PFTs - type(pct_pft_type), allocatable :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series type(pct_pft_type), allocatable :: pctcft(:) ! % of grid cell that is crop, and breakdown into CFTs + + ! dynamic land use + real(r8), allocatable :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs + type(pct_pft_type), allocatable :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series type(pct_pft_type), allocatable :: pctcft_max(:) ! % of grid cell maximum CFTs of the time series ! harvest initial value @@ -246,18 +248,17 @@ program mksurfdata logical :: create_esmf_pet_files = .true. ! character variables - character(len=CS) :: string ! string read in - character(len=CS) :: fname - character(len=CS) :: varname - character(len=32) :: subname = 'mksrfdata' ! program name + character(len=CL) :: string ! string read in + character(len=CL) :: fname + character(len=CL) :: varname + character(len=*), parameter :: subname = 'mksrfdata' ! program name real(r8), allocatable :: pctnatveg(:) real(r8), allocatable :: pctcrop(:) real(r8), allocatable :: pct_nat_pft(:,:) real(r8), allocatable :: pct_cft(:,:) - integer :: bounds(2) - character(len=*) , parameter :: u_FILE_u = & + character(len=*), parameter :: u_FILE_u = & __FILE__ ! ------------------------------------------------------------ @@ -435,7 +436,6 @@ program mksurfdata call mkpft( mksrf_fvegtyp_mesh, mksrf_fvegtyp, mesh_model, & pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') - call pio_syncfile(pioid) ! If have pole points on grid - set south pole to glacier ! north pole is assumed as non-land @@ -1009,13 +1009,17 @@ program mksurfdata if (root_task) then write(ndiag,*) - write(ndiag,'(a)')'successfully created file '//trim(fsurdat) + write(ndiag,'(a)') 'Successfully created surface data output file = '//trim(fsurdat) + write(ndiag,'(a)') ' This file contains the land model surface data' + write(ndiag,*) end if ! ====================================================================== ! Create fdyndat if appropriate ! ====================================================================== +1000 continue + if (mksrf_fdynuse /= ' ') then if (fdyndat == ' ') then @@ -1023,7 +1027,12 @@ program mksurfdata end if if (root_task) then - write(ndiag,'(a)')'creating dynamic land use dataset' + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) + write(ndiag,'(1x,80a1)') ('*',k=1,80) + write(ndiag,'(1x,80a1)') ('=',k=1,80) + write(ndiag,*) + write(ndiag,'(a)')'Creating dynamic land use dataset '//trim(fdyndat) end if allocate(pctcft_max(lsize_o)) ; @@ -1039,6 +1048,9 @@ program mksurfdata ! Define global attributes call mkfile_define_atts(pioid, dynlanduse = .true.) + ! Define variables + call mkfile_define_vars(pioid, dynlanduse = .true.) + ! End define model rcode = pio_enddef(pioid) @@ -1085,9 +1097,12 @@ program mksurfdata ! ----------------------------------------- ! Open txt file - open (newunit=nfdyn, file=trim(mksrf_fdynuse), form='formatted', iostat=ier) - if (ier /= 0) then - call shr_sys_abort(subname//" failed to open file "//trim(mksrf_fdynuse)) + if (root_task) then + write(ndiag,'(a)')' Opening '//trim(mksrf_fdynuse)//' to read dynamic data forcing ' + open (newunit=nfdyn, file=trim(mksrf_fdynuse), form='formatted', iostat=ier) + if (ier /= 0) then + call shr_sys_abort(subname//" failed to open file "//trim(mksrf_fdynuse)) + end if end if pctnatpft_max = pctnatpft @@ -1097,7 +1112,12 @@ program mksurfdata do ! Determine file name - read(nfdyn, '(A195,1x,I4)', iostat=ier) string, year + if (root_task) then + read(nfdyn, '(A195,1x,I4)', iostat=ier) string, year + end if + call mpi_bcast (string, len(string), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (year, 1, MPI_INTEGER, 0, mpicom, ier) + if (ier /= 0) EXIT ! If pft fraction override is set, than intrepret string as PFT and harvesting override values @@ -1110,13 +1130,18 @@ program mksurfdata write(6, '(a, i4, a)') 'PFT and harvesting values for year ', year, ' :' write(6, '(a, a)') ' ', trim(string) else + write(ndiag,'(a,i8)')' fname = '//trim(fname)//' year = ',year fname = string - read(nfdyn, '(A195,1x,I4)', iostat=ier) fhrvname, year2 if (root_task) then + read(nfdyn, '(A195,1x,I4)', iostat=ier) fhrvname, year2 write(ndiag,'(a,i8,a)')' input pft dynamic dataset for year ', year,' is : '//trim(fname) end if + call mpi_bcast (fhrvname, len(fhrvname), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (year2, 1, MPI_INTEGER, 0, mpicom, ier) if ( year2 /= year ) then - write(6,*) subname, ' error: year for harvest not equal to year for PFT files' + if (root_task) then + write(ndiag,*) subname, ' error: year for harvest not equal to year for PFT files' + end if call shr_sys_abort() end if end if @@ -1170,37 +1195,53 @@ program mksurfdata call update_max_array(pctnatpft_max,pctnatpft) call update_max_array(pctcft_max,pctcft) - ! TODO: need to create an io descriptor here - need to actually put this in mkpft? - ! Output time-varying data for current year - ! rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT', pio_varid) - ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_p2l_array(pctnatpft)) - ! rcode = pio_inq_varid(pioid, 'PCT_CROP', pio_varid) - ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_l2g_array(pctcft)) - ! if (num_cft > 0) then - ! rcode = pio_inq_varid(pioid, 'PCT_CFT', pio_varid) - ! call mkpio_put_time_slice(pioid, pio_varid, ntim, get_pct_p2l_array(pctcft)) - ! end if - ! TODO: make sure the following is correct - ! rcode = pio_inq_varid(pioid, 'YEAR', pio_varid) - ! rcode = pio_put_var(pioid, pio_varid, ntim, 1, year) - ! rcode = pio_inq_varid(pioid, 'time', pio_varid) - ! rcode = pio_put_var(pioid, pio_varid, ntim, 1, year) - ! rcode = pio_inq_varid(pioid, 'input_pftdata_filename', pio_varid) - ! rcode = pio_put_var(pioid, pio_varid, (/ 1, ntim /), (/ len_trim(string), 1 /), trim(string)) + if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_NAT_PFT for year ",year + call get_pct_p2l_array(pctnatpft, ndim1=lsize_o, ndim2=num_natpft+1, pct_p2l=pct_nat_pft) + call mkfile_output(pioid, mesh_model, 'PCT_NAT_PFT', pct_nat_pft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NAT_PFT') + + if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CROP for year ",year + call get_pct_l2g_array(pctcft, pctcrop) + call mkfile_output(pioid, mesh_model, 'PCT_CROP', pctcrop, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP') + + if (num_cft > 0) then + if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CFT for year ",year + call get_pct_p2l_array(pctcft, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) + call mkfile_output(pioid, mesh_model, 'PCT_CFT', pct_cft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CFT') + end if + + rcode = pio_inq_varid(pioid, 'YEAR', pio_varid) + call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) + rcode = pio_put_var(pioid, pio_varid, year) + + rcode = pio_inq_varid(pioid, 'time', pio_varid) + call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) + rcode = pio_put_var(pioid, pio_varid, year) + + rcode = pio_inq_varid(pioid, 'input_pftdata_filename', pio_varid) + call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) + rcode = pio_put_var(pioid, pio_varid, trim(string)) end do ! end of read loop - ! TODO: need to use pio here with io descriptors - ! rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT_MAX', pio_varid) - ! rcode = pio_put_var(pioid, pio_varid, get_pct_p2l_array(pctnatpft_max)) + if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_NAT_PFT_MAX " + call get_pct_p2l_array(pctnatpft_max, ndim1=lsize_o, ndim2=num_natpft+1, pct_p2l=pct_nat_pft) + call mkfile_output(pioid, mesh_model, 'PCT_NAT_PFT', pct_nat_pft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NAT_PFT') - ! rcode = pio_inq_varid(pioid, 'PCT_CROP_MAX', pio_varid) - ! rcode = pio_put_var(pioid, pio_varid, get_pct_l2g_array(pctcft_max)) + if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CROP_MAX" + call get_pct_l2g_array(pctcft_max, pctcrop) + call mkfile_output(pioid, mesh_model, 'PCT_CROP', pctcrop, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP') - ! if (num_cft > 0) then - ! rcode = pio_inq_varid(pioid, 'PCT_CFT_MAX', pio_varid) - ! rcode = pio_put_var(pioid, pio_varid, get_pct_p2l_array(pctcft_max)) - ! end if + if (num_cft > 0) then + if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CFT_MAX" + call get_pct_p2l_array(pctcft_max, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) + call mkfile_output(pioid, mesh_model, 'PCT_CFT', pct_cft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CFT') + end if ! Close the file call pio_closefile(pioid) @@ -1210,15 +1251,6 @@ program mksurfdata ! ----------------------------------- ! Wrap things up ! ----------------------------------- - if (root_task) then - write (ndiag,'(a)') - write (ndiag,'(a)') 'Surface data output file = '//trim(fsurdat) - write (ndiag,'(a)') ' This file contains the land model surface data' - write (ndiag,'(a)') 'Diagnostic log file = '//trim(fsurlog) - write (ndiag,'(a)') ' See this file for a summary of the dataset' - write (ndiag,'(a)') - write (ndiag,'(a)') 'Successfully created surface dataset' - end if close (ndiag) ! TODO: fix the error condition here @@ -1308,7 +1340,6 @@ subroutine normalize_and_check_landuse(ns_o) ! correct for rounding error: new_total_veg_pct = max(new_total_veg_pct, 0._r8) - call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) ! Make sure we did the above rescaling correctly @@ -1350,6 +1381,7 @@ subroutine normalize_and_check_landuse(ns_o) end if call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) + end if end if ! pcturb(n) > 0 diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index f511a653b8..9c9db98251 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -340,6 +340,7 @@ subroutine read_namelist_input(filename) call mpi_bcast (mksrf_fdynuse_mesh, len(mksrf_fdynuse_mesh), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (fsurdat, len(fsurdat), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (fdyndat, len(fdyndat), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (outnc_dims, 1, MPI_INTEGER, 0, mpicom, ier) call mpi_bcast (outnc_large_files, 1, MPI_LOGICAL, 0, mpicom, ier) From 08716d9ee843f4d00eb86843adfc200416d7b0ef Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 17 Feb 2022 12:41:41 -0700 Subject: [PATCH 066/614] updates for dynamic land use --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 14 +++- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 9 ++- tools/mksurfdata_esmf/src/mkpioMod.F90 | 36 ++++++++++ tools/mksurfdata_esmf/src/mksurfdata.F90 | 77 +++++++++++++--------- 4 files changed, 99 insertions(+), 37 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 4beb00dceb..0ee059caaa 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -558,35 +558,43 @@ subroutine mkfile_define_vars(pioid, dynlanduse) call mkpio_def_spatial_var(pioid=pioid, varname='UNREPRESENTED_CFT_LULCC', xtype=xtype, & lev1name = 'cft', & long_name = "unrepresented crop gross LULCC transitions", units = "unitless") + else + call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_VH1', xtype=xtype, & + lev1name='time', & long_name = "harvest from primary forest", units = "gC/m2/yr") call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_VH2', xtype=xtype, & + lev1name='time', & long_name = "harvest from primary non-forest", units = "gC/m2/yr") call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_SH1', xtype=xtype, & + lev1name='time', & long_name = "harvest from secondary mature-forest", units = "gC/m2/yr") call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_SH2', xtype=xtype, & + lev1name='time', & long_name = "harvest from secondary young-forest", units = "gC/m2/yr") call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_SH3', xtype=xtype, & + lev1name='time', & long_name = "harvest from secondary non-forest", units = "gC/m2/yr") call mkpio_def_spatial_var(pioid=pioid, varname='GRAZING', xtype=xtype, & + lev1name='time', & long_name = "grazing of herbacous pfts", units = "gC/m2/yr") call mkpio_def_spatial_var(pioid=pioid, varname='FERTNITRO_CFT', xtype=xtype, & - lev1name = 'cft', & + lev1name = 'cft', lev2name='time', & long_name = "nitrogen fertilizer for each crop", units = "gN/m2/yr") call mkpio_def_spatial_var(pioid=pioid, varname='UNREPRESENTED_PFT_LULCC', xtype=xtype, & - lev1name = 'natpft', & + lev1name = 'natpft', lev2name='time', & long_name = "unrepresented PFT gross LULCC transitions", units = "unitless") call mkpio_def_spatial_var(pioid=pioid, varname='UNREPRESENTED_CFT_LULCC', xtype=xtype, & - lev1name = 'cft', & + lev1name = 'cft', lev2name='time', & long_name = "unrepresented crop gross LULCC transitions", units = "unitless") end if ! .not. dynlanduse diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index 192e2cf0ac..5772b28fe6 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -226,6 +226,7 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constan ! write out mapped variable if (present(ntime)) then + if (root_task) write(ndiag, '(a,i8)') subname//" writing out 1d "//trim(varname_o)//' at time ',ntime rcode = pio_inq_varid(pioid_o, trim(varname_o), pio_varid_o) call mkpio_iodesc_output(pioid_o, mesh_o, trim(varname_o), pio_iodesc_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in making an iodesc for '//trim(varname_o)) @@ -233,11 +234,11 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constan call pio_write_darray(pioid_o, pio_varid_o, pio_iodesc_o, data1d_o, rcode) call pio_freedecomp(pioid_o, pio_iodesc_o) else - if (root_task) write(ndiag, '(a)') " writing out 1d "//trim(varname_o) + if (root_task) write(ndiag, '(a)') subname//" writing out 1d "//trim(varname_o) call mkfile_output(pioid_o, mesh_o, trim(varname_o), data1d_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call pio_syncfile(pioid_o) end if + call pio_syncfile(pioid_o) ! TODO: uncomment the following and validate ! Compare global areas on input and output grids for 1d variables @@ -272,6 +273,7 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constan ! write out variable if (present(ntime)) then + if (root_task) write(ndiag, '(a,i8)') subname//" writing out 2d "//trim(varname_o)//' at time ',ntime rcode = pio_inq_varid(pioid_o, trim(varname_o), pio_varid_o) call mkpio_iodesc_output(pioid_o, mesh_o, trim(varname_o), pio_iodesc_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in making an iodesc for '//trim(varname_o)) @@ -279,10 +281,11 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constan call pio_write_darray(pioid_o, pio_varid_o, pio_iodesc_o, data2d_o, rcode) call pio_freedecomp(pioid_o, pio_iodesc_o) else - if (root_task) write(ndiag, '(a)') " writing out 2d "//trim(varname_o) + if (root_task) write(ndiag, '(a)') subname//" writing out 2d "//trim(varname_o) call mkfile_output(pioid_o, mesh_o, trim(varname_o), data2d_o, lev1name=trim(name2nd), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if + call pio_syncfile(pioid_o) deallocate(data2d_o) end if diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 45c772d743..45d8ddcaf7 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -619,11 +619,23 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) ! Where lev would correspond to an undistributed dimension in esmf if (ndims == 1) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) + if (root_task) then + write(ndiag,'(a,i20)') ' set iodesc for output data: '//trim(varname)//' with dim(1) = ',& + dimlens(1) + end if else if (ndims == 2) then if (unlimited_dim) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) + if (root_task) then + write(ndiag,'(a,i8)') ' set iodesc for output data with time dim: '//trim(varname)//& + ' with dim(1) = ',dimlens(1) + end if else call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + if (root_task) then + write(ndiag,'(a,i8,i8)') ' set iodesc for output data: '//trim(varname)//& + ' with dim(1),dim(2) = ',dimlens(1),dimlens(2) + end if end if else if (ndims == 3) then if (unlimited_dim) then @@ -631,22 +643,46 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) else call shr_sys_abort('support on 2 dimensions in addition to a time dimension when outnc_1d is true') end if + if (root_task) then + write(ndiag,'(a,i8,i8)') ' set iodesc for output data with time dim: '//trim(varname)//& + ' with dim(1),dim(2) = ',dimlens(1),dimlens(2) + end if end if else ! Assume that can have (lon,lat), (lon,lat,lev1), (lon,lat,lev1,lev2), (lon,lat,time) or (lon,lat,lev1,time) if (ndims == 2) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + if (root_task) then + write(ndiag,'(a,i8,i8)') ' set iodesc for output data: '//trim(varname)//& + ' with dim(1),dim(2)= ',dimlens(1),dimlens(2) + end if else if (ndims == 3) then if (unlimited_dim) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + if (root_task) then + write(ndiag,'(a,i8,i8)') ' set iodesc for output data with time dim : '//trim(varname)//& + ' with dim(1),dim(2)= ', dimlens(1),dimlens(2) + end if else call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) + if (root_task) then + write(ndiag,'(a,i8,i8,i8)') ' set iodesc for output data: '//trim(varname)//& + ' with dim(1),dim(2),dim3(3)= ',dimlens(1),dimlens(2),dimlens(3) + end if end if else if (ndims == 4) then if (unlimited_dim) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) + if (root_task) then + write(ndiag,'(a,i8,i8,i8)') ' set iodesc for output data with time dim : '//trim(varname)//& + ' with dim(1),dim(2),dimlens(3)= ', dimlens(1),dimlens(2),dimlens(3) + end if else call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3),dimlens(4)/), compdof3d, pio_iodesc) + if (root_task) then + write(ndiag,'(a,i8,i8,i8,i8)') ' set iodesc for output data: '//trim(varname)//& + ' with dim(1),dim(2),dimlens(3),dimlens(4)= ', dimlens(1),dimlens(2),dimlens(3),dimlens(4) + end if end if end if end if diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 8691ed29b8..aff8e829e3 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -257,6 +257,7 @@ program mksurfdata real(r8), allocatable :: pctcrop(:) real(r8), allocatable :: pct_nat_pft(:,:) real(r8), allocatable :: pct_cft(:,:) + integer :: int_varid character(len=*), parameter :: u_FILE_u = & __FILE__ @@ -888,7 +889,6 @@ program mksurfdata ! Write to netcdf file is done inside mkurbanpar routine call mkurbanpar(mksrf_furban, pioid, mesh_model, urban_region, urban_classes_g, & urban_skip_abort_on_invalid_data_check) - deallocate(urban_classes) deallocate(urban_region) ! Write out PCT_URBAN, PCT_GLACIER, PCT_LAKE and PCT_WETLAND and @@ -1111,15 +1111,14 @@ program mksurfdata ntim = 0 do - ! Determine file name + ! Determine file name - if there are no more files than exit before broadcasting if (root_task) then read(nfdyn, '(A195,1x,I4)', iostat=ier) string, year + if (ier /= 0) EXIT end if call mpi_bcast (string, len(string), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (year, 1, MPI_INTEGER, 0, mpicom, ier) - if (ier /= 0) EXIT - ! If pft fraction override is set, than intrepret string as PFT and harvesting override values ! Otherwise intrepret string as a filename with PFT and harvesting values in it if ( all_veg )then @@ -1130,7 +1129,6 @@ program mksurfdata write(6, '(a, i4, a)') 'PFT and harvesting values for year ', year, ' :' write(6, '(a, a)') ' ', trim(string) else - write(ndiag,'(a,i8)')' fname = '//trim(fname)//' year = ',year fname = string if (root_task) then read(nfdyn, '(A195,1x,I4)', iostat=ier) fhrvname, year2 @@ -1146,12 +1144,26 @@ program mksurfdata end if end if ntim = ntim + 1 + if (root_task) then + write(ndiag,'(a,i8)')subname//' ntime = ',ntim + end if + + ! TODO: the following is dying with an error that the index is out of bounds + ! rcode = pio_inq_varid(pioid, 'YEAR', pio_varid) + ! int_varid = pio_varid%varid + ! rcode = pio_put_var(pioid, int_varid, (/ntim/), (/1/), (/year/)) + ! rcode = pio_inq_varid(pioid, 'time', pio_varid) + ! int_varid = pio_varid%varid + ! rcode = pio_put_var(pioid, int_varid, (/ntim/), (/1/), (/year/)) + ! rcode = pio_inq_varid(pioid, 'input_pftdata_filename', pio_varid) + ! rcode = pio_put_var(pioid, pio_varid, (/ntim/), (trim(string))) ! Create pctpft data at model resolution from file fname ! Note that pctlnd_o below is different than the above call and returns pctlnd_pft_dyn call mkpft( mksrf_fvegtyp_mesh, fname, mesh_model, & pctlnd_o=pctlnd_pft_dyn, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpft') + call pio_syncfile(pioid) ! Consistency check on input land fraction do n = 1,lsize_o @@ -1172,6 +1184,7 @@ program mksurfdata call mkharvest( mksrf_fhrvtyp_mesh, fhrvname, mesh_model, & pioid_o=pioid, all_veg=.false., constant=.false., ntime=ntim, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest') + call pio_syncfile(pioid) ! Do landuse changes such as for the poles, etc. ! If have pole points on grid - set south pole to glacier @@ -1189,6 +1202,11 @@ program mksurfdata ! Normalize land use and make sure things add up to 100% as well as ! checking that things are as they should be. + if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) + write(ndiag,'(a)')' calling normalize_and_check_landuse' + end if call normalize_and_check_landuse(lsize_o) ! Given an array of pct_pft_type variables, update all the max_p2l variables. @@ -1199,49 +1217,46 @@ program mksurfdata call get_pct_p2l_array(pctnatpft, ndim1=lsize_o, ndim2=num_natpft+1, pct_p2l=pct_nat_pft) call mkfile_output(pioid, mesh_model, 'PCT_NAT_PFT', pct_nat_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NAT_PFT') + call pio_syncfile(pioid) if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CROP for year ",year call get_pct_l2g_array(pctcft, pctcrop) call mkfile_output(pioid, mesh_model, 'PCT_CROP', pctcrop, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP') + call pio_syncfile(pioid) if (num_cft > 0) then if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CFT for year ",year call get_pct_p2l_array(pctcft, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) call mkfile_output(pioid, mesh_model, 'PCT_CFT', pct_cft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CFT') + call pio_syncfile(pioid) end if - rcode = pio_inq_varid(pioid, 'YEAR', pio_varid) - call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) - rcode = pio_put_var(pioid, pio_varid, year) - - rcode = pio_inq_varid(pioid, 'time', pio_varid) - call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) - rcode = pio_put_var(pioid, pio_varid, year) - - rcode = pio_inq_varid(pioid, 'input_pftdata_filename', pio_varid) - call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) - rcode = pio_put_var(pioid, pio_varid, trim(string)) + if (root_task) then + write(ndiag,'(1x,80a1)') ('=',k=1,80) + write(ndiag,*) + end if end do ! end of read loop - if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_NAT_PFT_MAX " - call get_pct_p2l_array(pctnatpft_max, ndim1=lsize_o, ndim2=num_natpft+1, pct_p2l=pct_nat_pft) - call mkfile_output(pioid, mesh_model, 'PCT_NAT_PFT', pct_nat_pft, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NAT_PFT') + ! TODO: the following is hanging in writing out PCT_NAT_PFT_MAX + ! if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_NAT_PFT_MAX " + ! call get_pct_p2l_array(pctnatpft_max, ndim1=lsize_o, ndim2=num_natpft+1, pct_p2l=pct_nat_pft) + ! call mkfile_output(pioid, mesh_model, 'PCT_NAT_PFT_MAX', pct_nat_pft, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NAT_PFT') - if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CROP_MAX" - call get_pct_l2g_array(pctcft_max, pctcrop) - call mkfile_output(pioid, mesh_model, 'PCT_CROP', pctcrop, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP') + ! if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CROP_MAX" + ! call get_pct_l2g_array(pctcft_max, pctcrop) + ! call mkfile_output(pioid, mesh_model, 'PCT_CROP_MAX', pctcrop, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP') - if (num_cft > 0) then - if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CFT_MAX" - call get_pct_p2l_array(pctcft_max, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) - call mkfile_output(pioid, mesh_model, 'PCT_CFT', pct_cft, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CFT') - end if + ! if (num_cft > 0) then + ! if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CFT_MAX" + ! call get_pct_p2l_array(pctcft_max, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) + ! call mkfile_output(pioid, mesh_model, 'PCT_CFT_MAX', pct_cft, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CFT') + ! end if ! Close the file call pio_closefile(pioid) @@ -1468,6 +1483,7 @@ subroutine normalize_and_check_landuse(ns_o) pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() call shr_sys_abort() end if + suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() if ( abs(suma-100._r8) > 1.e-10_r8) then write (6,*) subname, ' error: sum of pctlak, pctwet,', & @@ -1481,7 +1497,6 @@ subroutine normalize_and_check_landuse(ns_o) end do ! Check that when pctnatveg+pctcrop identically zero, sum of special landunits is identically 100% - if ( .not. outnc_double )then do n = 1,ns_o sum8 = real(pctlak(n),r4) From 875c114b0fd75a7186de4b9d1e9815a455140a59 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 18 Feb 2022 15:45:07 -0700 Subject: [PATCH 067/614] udpates to get dynamic land use working --- tools/mksurfdata_esmf/src/mkVICparamsMod.F90 | 41 +++++--- tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 | 2 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 95 +++++++++++-------- 3 files changed, 85 insertions(+), 53 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 index ab59589c4f..ac708c42f8 100644 --- a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 @@ -4,32 +4,45 @@ module mkVICparamsMod ! make parameters for VIC !----------------------------------------------------------------------- ! - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_abort + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata + use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_ioformat, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkutilsMod , only : chkerr + use mkvarctl , only : root_task, ndiag, mpicom, MPI_INTEGER, MPI_MAX + use mkvarctl , only : soil_color_override, unsetcol + use mkvarpar , only : re + use mkchecksMod , only : min_bad + use mkdiagnosticsMod , only : output_diagnostics_continuous implicit none private - public mkVICparams ! make VIC parameters + public :: mkVICparams ! make VIC parameters + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ !=============================================================== contains !=============================================================== - subroutine mkVICparams(ldomain, mapfname, datfname, ndiag, binfl_o, ws_o, dsmax_o, ds_o) + subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, binfl_o, ws_o, dsmax_o, ds_o, rc) ! ! make VIC parameters ! - use mkdiagnosticsMod, only : output_diagnostics_continuous - use mkchecksMod, only : min_bad - ! - ! !ARGUMENTS: - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: binfl_o(:) ! output VIC b parameter for the Variable Infiltration Capacity Curve (unitless) - real(r8) , intent(out):: ws_o(:) ! output VIC Ws parameter for the ARNO curve (unitless) - real(r8) , intent(out):: dsmax_o(:) ! output VIC Dsmax parameter for the ARNO curve (mm/day) - real(r8) , intent(out):: ds_o(:) ! output VIC Ds parameter for the ARNO curve (unitless) + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesho + real(r8) , intent(out) :: binfl_o(:) ! output VIC b parameter for the Variable Infiltration Capacity Curve (unitless) + real(r8) , intent(out) :: ws_o(:) ! output VIC Ws parameter for the ARNO curve (unitless) + real(r8) , intent(out) :: dsmax_o(:) ! output VIC Dsmax parameter for the ARNO curve (mm/day) + real(r8) , intent(out) :: ds_o(:) ! output VIC Ds parameter for the ARNO curve (unitless) + integer , intent(out) :: rc ! ! !LOCAL VARIABLES: real(r8), allocatable :: data_i(:) ! data on input grid diff --git a/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 b/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 index 5b000ad1b1..230d9ca6a0 100644 --- a/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 @@ -465,7 +465,7 @@ end subroutine check_vals ! ======================================================================== !----------------------------------------------------------------------- - subroutine update_max_array(pct_pft_max_arr,pct_pft_arr) + subroutine update_max_array(pct_pft_max_arr, pct_pft_arr) ! ! Given an array of pct_pft_type variables, update all the max_p2l variables. ! diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index aff8e829e3..4e5f0ab4e8 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -257,7 +257,7 @@ program mksurfdata real(r8), allocatable :: pctcrop(:) real(r8), allocatable :: pct_nat_pft(:,:) real(r8), allocatable :: pct_cft(:,:) - integer :: int_varid + logical :: end_of_fdynloop character(len=*), parameter :: u_FILE_u = & __FILE__ @@ -478,6 +478,7 @@ program mksurfdata ! Make constant harvesting data at model resolution ! ----------------------------------- ! Note that this call must come after call to mkpftInit - since num_cft is set there + ! Output data is written in mkharvest call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, & pioid_o=pioid, all_veg=all_veg, constant=.true., rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') @@ -1083,12 +1084,14 @@ program mksurfdata rcode = pio_put_var(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/)) ! Write out PFTDATA_MASK - if (root_task) write(ndiag, '(a)') trim(subname)//" writing land mask from pft dataset" + ! pftdata_mask was calculated ABOVE + if (root_task) write(ndiag, '(a)') trim(subname)//" writing land mask (calculated in furdata calc)" call mkfile_output(pioid, mesh_model, 'PFTDATA_MASK', pftdata_mask, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') ! Write out LANDFRAC_PFT - if (root_task) write(ndiag, '(a)') trim(subname)//" writing land fraction from pft dataset" + ! landfrac_pft was calculated ABOVE + if (root_task) write(ndiag, '(a)') trim(subname)//" writing land fraction calculated in fsurdata calc)" call mkfile_output(pioid, mesh_model, 'LANDFRAC_PFT', landfrac_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') @@ -1108,16 +1111,22 @@ program mksurfdata pctnatpft_max = pctnatpft pctcft_max = pctcft + end_of_fdynloop = .false. ntim = 0 do ! Determine file name - if there are no more files than exit before broadcasting if (root_task) then read(nfdyn, '(A195,1x,I4)', iostat=ier) string, year - if (ier /= 0) EXIT + if (ier /= 0) end_of_fdynloop = .true. + end if + call mpi_bcast(end_of_fdynloop, 1, MPI_LOGICAL, 0, mpicom, ier) + if (end_of_fdynloop) then + EXIT end if call mpi_bcast (string, len(string), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (year, 1, MPI_INTEGER, 0, mpicom, ier) + ! If pft fraction override is set, than intrepret string as PFT and harvesting override values ! Otherwise intrepret string as a filename with PFT and harvesting values in it @@ -1148,39 +1157,42 @@ program mksurfdata write(ndiag,'(a,i8)')subname//' ntime = ',ntim end if - ! TODO: the following is dying with an error that the index is out of bounds - ! rcode = pio_inq_varid(pioid, 'YEAR', pio_varid) - ! int_varid = pio_varid%varid - ! rcode = pio_put_var(pioid, int_varid, (/ntim/), (/1/), (/year/)) - ! rcode = pio_inq_varid(pioid, 'time', pio_varid) - ! int_varid = pio_varid%varid - ! rcode = pio_put_var(pioid, int_varid, (/ntim/), (/1/), (/year/)) + rcode = pio_inq_varid(pioid, 'YEAR', pio_varid) + rcode = pio_put_var(pioid, pio_varid, (/ntim/), year) + rcode = pio_inq_varid(pioid, 'time', pio_varid) + rcode = pio_put_var(pioid, pio_varid, (/ntim/), year) ! rcode = pio_inq_varid(pioid, 'input_pftdata_filename', pio_varid) - ! rcode = pio_put_var(pioid, pio_varid, (/ntim/), (trim(string))) + ! rcode = pio_put_var(pioid, pio_varid, (/1,ntim/), (/len_trim(string),1/), trim(string)) + call pio_syncfile(pioid) ! Create pctpft data at model resolution from file fname ! Note that pctlnd_o below is different than the above call and returns pctlnd_pft_dyn + call mkpft( mksrf_fvegtyp_mesh, fname, mesh_model, & pctlnd_o=pctlnd_pft_dyn, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpft') call pio_syncfile(pioid) ! Consistency check on input land fraction + ! pctlnd_pft was calculated ABOVE do n = 1,lsize_o if (pctlnd_pft_dyn(n) /= pctlnd_pft(n)) then - write(6,*) subname,' error: pctlnd_pft for dynamics data = ',& - pctlnd_pft_dyn(n), ' not equal to pctlnd_pft for surface data = ',& - pctlnd_pft(n),' at n= ',n - if ( trim(fname) == ' ' )then - write(6,*) ' PFT string = ', string - else - write(6,*) ' PFT file = ', fname + if (root_task) then + write(ndiag,*) subname,' error: pctlnd_pft for dynamics data = ',& + pctlnd_pft_dyn(n), ' not equal to pctlnd_pft for surface data = ',& + pctlnd_pft(n),' at n= ',n + if ( trim(fname) == ' ' )then + write(ndiag,*) ' PFT string = ',trim(string) + else + write(ndiag,*) ' PFT file = ', fname + end if end if call shr_sys_abort() end if end do ! Create harvesting data at model resolution + ! Output data is written in mkharvest call mkharvest( mksrf_fhrvtyp_mesh, fhrvname, mesh_model, & pioid_o=pioid, all_veg=.false., constant=.false., ntime=ntim, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest') @@ -1189,6 +1201,8 @@ program mksurfdata ! Do landuse changes such as for the poles, etc. ! If have pole points on grid - set south pole to glacier ! north pole is assumed as non-land + ! pctlak, pctwet, pcturb and pctgla were calculated ABOVE + ! pctnatpft and pctcft were calculated ABOVE do n = 1,lsize_o if (abs(lat(n) - 90._r8) < 1.e-6_r8) then pctlak(n) = 0._r8 @@ -1210,16 +1224,20 @@ program mksurfdata call normalize_and_check_landuse(lsize_o) ! Given an array of pct_pft_type variables, update all the max_p2l variables. - call update_max_array(pctnatpft_max,pctnatpft) - call update_max_array(pctcft_max,pctcft) + call update_max_array(pctnatpft_max, pctnatpft) + call update_max_array(pctcft_max, pctcft) if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_NAT_PFT for year ",year + rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT', pio_varid) + call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) call get_pct_p2l_array(pctnatpft, ndim1=lsize_o, ndim2=num_natpft+1, pct_p2l=pct_nat_pft) call mkfile_output(pioid, mesh_model, 'PCT_NAT_PFT', pct_nat_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NAT_PFT') call pio_syncfile(pioid) if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CROP for year ",year + rcode = pio_inq_varid(pioid, 'PCT_CROP', pio_varid) + call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) call get_pct_l2g_array(pctcft, pctcrop) call mkfile_output(pioid, mesh_model, 'PCT_CROP', pctcrop, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP') @@ -1227,6 +1245,8 @@ program mksurfdata if (num_cft > 0) then if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CFT for year ",year + rcode = pio_inq_varid(pioid, 'PCT_CFT', pio_varid) + call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) call get_pct_p2l_array(pctcft, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) call mkfile_output(pioid, mesh_model, 'PCT_CFT', pct_cft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CFT') @@ -1240,23 +1260,22 @@ program mksurfdata end do ! end of read loop - ! TODO: the following is hanging in writing out PCT_NAT_PFT_MAX - ! if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_NAT_PFT_MAX " - ! call get_pct_p2l_array(pctnatpft_max, ndim1=lsize_o, ndim2=num_natpft+1, pct_p2l=pct_nat_pft) - ! call mkfile_output(pioid, mesh_model, 'PCT_NAT_PFT_MAX', pct_nat_pft, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NAT_PFT') + if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_NAT_PFT_MAX " + call get_pct_p2l_array(pctnatpft_max, ndim1=lsize_o, ndim2=num_natpft+1, pct_p2l=pct_nat_pft) + call mkfile_output(pioid, mesh_model, 'PCT_NAT_PFT_MAX', pct_nat_pft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NAT_PFT') - ! if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CROP_MAX" - ! call get_pct_l2g_array(pctcft_max, pctcrop) - ! call mkfile_output(pioid, mesh_model, 'PCT_CROP_MAX', pctcrop, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP') + if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CROP_MAX" + call get_pct_l2g_array(pctcft_max, pctcrop) + call mkfile_output(pioid, mesh_model, 'PCT_CROP_MAX', pctcrop, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP') - ! if (num_cft > 0) then - ! if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CFT_MAX" - ! call get_pct_p2l_array(pctcft_max, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) - ! call mkfile_output(pioid, mesh_model, 'PCT_CFT_MAX', pct_cft, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CFT') - ! end if + if (num_cft > 0) then + if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CFT_MAX" + call get_pct_p2l_array(pctcft_max, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) + call mkfile_output(pioid, mesh_model, 'PCT_CFT_MAX', pct_cft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CFT') + end if ! Close the file call pio_closefile(pioid) @@ -1524,8 +1543,8 @@ subroutine normalize_and_check_landuse(ns_o) sum8a = sum8a + pctcft(n)%get_pct_l2g() if ( sum8a==0._r8 .and. sum8 < (100._r8-4._r8*epsilon(sum8)) )then write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 - write (6,*) 'Total error, error/epsilon = ',100._r8-sum8, ((100._r8-sum8)/epsilon(sum8)) + 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 + write (6,*) 'Total error, error/epsilon = ',100._r8-sum8, ((100._r8-sum8)/epsilon(sum8)) write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,epsilon= ', & n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), epsilon(sum8) From ebd7a1dd0a045f11139356275af3519b8956e857 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 19 Feb 2022 20:12:56 -0700 Subject: [PATCH 068/614] more refactor of diagnostic output and getting VIC working --- tools/mksurfdata_esmf/run/mksurfdata_in | 53 +- tools/mksurfdata_esmf/run/run_mksurfdata | 7 +- tools/mksurfdata_esmf/src/CMakeLists.txt | 2 + tools/mksurfdata_esmf/src/mkVICparamsMod.F90 | 258 +++++---- .../src/mkagfirepkmonthMod.F90 | 39 +- .../mksurfdata_esmf/src/mkdiagnosticsMod.F90 | 120 +++-- tools/mksurfdata_esmf/src/mkfileMod.F90 | 21 +- tools/mksurfdata_esmf/src/mkgdpMod.F90 | 46 +- .../src/mkglacierregionMod.F90 | 53 +- tools/mksurfdata_esmf/src/mkglcmecMod.F90 | 12 +- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 121 +---- tools/mksurfdata_esmf/src/mkpeatMod.F90 | 55 +- tools/mksurfdata_esmf/src/mkpftMod.F90 | 32 +- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 109 +--- tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 | 76 +-- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 222 ++++---- tools/mksurfdata_esmf/src/mksurfdata.F90 | 12 +- tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 1 - tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 37 +- tools/mksurfdata_esmf/src/mkvarctl.F90 | 501 +----------------- tools/mksurfdata_esmf/src/mkvocefMod.F90 | 8 +- tools/mksurfdata_esmf/src/shr_sys_mod.F90 | 58 +- 22 files changed, 601 insertions(+), 1242 deletions(-) mode change 120000 => 100644 tools/mksurfdata_esmf/run/mksurfdata_in diff --git a/tools/mksurfdata_esmf/run/mksurfdata_in b/tools/mksurfdata_esmf/run/mksurfdata_in deleted file mode 120000 index dfb9810251..0000000000 --- a/tools/mksurfdata_esmf/run/mksurfdata_in +++ /dev/null @@ -1 +0,0 @@ -surfdata_1.9x2.5_hist_78pfts_CMIP6_2000_c220208.namelist \ No newline at end of file diff --git a/tools/mksurfdata_esmf/run/mksurfdata_in b/tools/mksurfdata_esmf/run/mksurfdata_in new file mode 100644 index 0000000000..5992c754ec --- /dev/null +++ b/tools/mksurfdata_esmf/run/mksurfdata_in @@ -0,0 +1,52 @@ +&mksurfdata_input + mksrf_flai = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.cdf5.c220206.nc' + mksrf_flai_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc' + mksrf_forganic = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_organic_10level_5x5min_ISRIC-WISE-NCSCD_nlev7_c120830.nc' + mksrf_forganic_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' + mksrf_fsoicol = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_soilcolor_CMIP6_simyr2005_cd5.c220126.nc' + mksrf_fsoicol_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc' + mksrf_fsoitex = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_soitex.10level.c010119.nc' + mksrf_fsoitex_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' + mksrf_fmax = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_fmax_0.125x0.125_c200220.nc' + mksrf_fmax_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.125x0.125_nomask_c200129.nc' + mksrf_flakwat = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_LakePnDepth_3x3min_simyr2004_csplk_c151015.nc' + mksrf_flakwat_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' + mksrf_fwetlnd = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_lanwat.050425.nc' + mksrf_fwetlnd_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' + mksrf_fvocef = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_vocef_0.5x0.5_simyr2000.c110531.nc' + mksrf_fvocef_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' + mksrf_furban = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_urban_0.05x0.05_simyr2000.c220127.nc' + mksrf_furban_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' + mksrf_furbtopo = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_topo.10min.cdf5.c220201.nc' + mksrf_furbtopo_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_c200129.nc' + mksrf_fglacier = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000.cdf5.c120926.nc' + mksrf_fglacier_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' + mksrf_fglacierregion = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_GlacierRegion_10x10min_nomask_cd5_c220131.nc' + mksrf_fglacierregion_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_cdf5_c200129.nc' + mksrf_fgdp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_gdp_0.5x0.5_AVHRR_simyr2000.c130228.nc' + mksrf_fgdp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' + mksrf_fpeat = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_peatf_0.5x0.5_AVHRR_simyr2000.c130228.nc' + mksrf_fpeat_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' + mksrf_fsoildepth = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksf_soilthk_5x5min_ORNL-Soil_simyr1900-2015_c170630.nc' + mksrf_fsoildepth_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' + mksrf_fabm = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_abm_0.5x0.5_AVHRR_simyr2000.c130201.nc' + mksrf_fabm_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' + mksrf_ftopostats = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_topostats_1km-merge-10min_HYDRO1K-merge-nomask_simyr2000.c130402.nc' + mksrf_ftopostats_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UGRID_1km-merge-10min_HYDRO1K-merge-nomask_c130402.nc' + mksrf_fvegtyp = '/glade/work/mvertens/ctsm.toolchain/tools/mksurfdata_esmf/run/mksrf_landuse_histclm50_LUH2_2000.cdf5.c170629.nc' + mksrf_fvegtyp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc' + mksrf_fhrvtyp = '/glade/work/mvertens/ctsm.toolchain/tools/mksurfdata_esmf/run/mksrf_landuse_histclm50_LUH2_2000.cdf5.c170629.nc' + mksrf_fhrvtyp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc' + mksrf_fgrid_mesh = '/glade/p/cesm/cseg/inputdata/share/meshes/ne120np4_ESMFmesh_cdf5_c20211018.nc' + mksrf_fgrid_mesh_nx = 777602 + mksrf_fgrid_mesh_ny = 1 + fsurdat = 'surfdata_ne120np4_hist_78pfts_CMIP6_2000_c220219.nc' + fsurlog = 'surfdata_ne120np4_hist_78pfts_CMIP6_2000_c220219.log' + outnc_double = .true. + all_urban = .false. + no_inlandwet = .true. + numpft = 78 + mksrf_fdynuse = ' ' + fdyndat = ' ' + outnc_vic = .true. +/ diff --git a/tools/mksurfdata_esmf/run/run_mksurfdata b/tools/mksurfdata_esmf/run/run_mksurfdata index 5869d7c697..048dd62a1f 100755 --- a/tools/mksurfdata_esmf/run/run_mksurfdata +++ b/tools/mksurfdata_esmf/run/run_mksurfdata @@ -7,7 +7,9 @@ ##PBS -l select=1:ncpus=36:mpiprocs=36 ##PBS -l select=4:ncpus=36:mpiprocs=36 ##PBS -l select=16:ncpus=36:mpiprocs=9 -#PBS -l select=24:ncpus=36:mpiprocs=12 +##PBS -l select=24:ncpus=36:mpiprocs=12 +#PBS -l select=32:ncpus=36:mpiprocs=12 + # note for -l input above # -l select={num_nodes}:ncpus={max_tasks_per_node}:mpiprocs={tasks_per_node} @@ -21,4 +23,5 @@ mkdir -p $TMPDIR # -np {total_tasks} #mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata -mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata +#mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata +mpiexec_mpt -p "%g:" -np 384 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index e5a35a2e5f..804088be9b 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -27,6 +27,7 @@ set(SRCFILES mkagfirepkmonthMod.F90 mkglcmecMod.F90 mkharvestMod.F90 mkindexmapMod.F90 + mkinputMod.F90 mklaiMod.F90 mklanwatMod.F90 mkorganicMod.F90 @@ -46,6 +47,7 @@ set(SRCFILES mkagfirepkmonthMod.F90 mkvarctl.F90 mkvarpar.F90 mkvocefMod.F90 + mkVICparamsMod.F90 nanMod.F90 shr_const_mod.F90 shr_kind_mod.F90 diff --git a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 index ac708c42f8..461ecf5cd8 100644 --- a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 @@ -3,18 +3,15 @@ module mkVICparamsMod !----------------------------------------------------------------------- ! make parameters for VIC !----------------------------------------------------------------------- - ! + use ESMF use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 use shr_sys_mod , only : shr_sys_abort - use mkpioMod , only : mkpio_get_rawdata - use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr - use mkvarctl , only : root_task, ndiag, mpicom, MPI_INTEGER, MPI_MAX - use mkvarctl , only : soil_color_override, unsetcol - use mkvarpar , only : re + use mkvarctl , only : root_task, ndiag use mkchecksMod , only : min_bad use mkdiagnosticsMod , only : output_diagnostics_continuous @@ -43,125 +40,208 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, binfl_o, ws_o, dsmax_o, real(r8) , intent(out) :: dsmax_o(:) ! output VIC Dsmax parameter for the ARNO curve (mm/day) real(r8) , intent(out) :: ds_o(:) ! output VIC Ds parameter for the ARNO curve (unitless) integer , intent(out) :: rc - ! - ! !LOCAL VARIABLES: - real(r8), allocatable :: data_i(:) ! data on input grid - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - real(r8), parameter :: min_valid_binfl = 0._r8 - real(r8), parameter :: min_valid_ws = 0._r8 - real(r8), parameter :: min_valid_dsmax = 0._r8 - real(r8), parameter :: min_valid_ds = 0._r8 + + ! local variables: + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid + integer :: ni,no + integer :: ns_i, ns_o + integer :: n,l,k + integer , allocatable :: mask_i(:) + real(r8), allocatable :: rmask_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: data_i(:) ! data on input grid + real(r8), parameter :: min_valid_binfl = 0._r8 + real(r8), parameter :: min_valid_ws = 0._r8 + real(r8), parameter :: min_valid_dsmax = 0._r8 + real(r8), parameter :: min_valid_ds = 0._r8 + integer :: ier,rcode ! error status character(len=*), parameter :: subname = 'mkVICparams' !----------------------------------------------------------------------- - write (6,*) 'Attempting to make VIC parameters.....' - - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - call domain_read(tdomain,datfname) - - call gridmap_mapread(tgridmap, mapfname ) - - ! Obtain frac_dst - allocate(frac_dst(ldomain%ns), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) + rc = ESMF_SUCCESS - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write(6,*)'Open VIC parameter file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(data_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() + if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) + write(ndiag,*) + write(ndiag,'(a)')'Attempting to make VIC parameters.....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) + end if + call ESMF_VMLogMemInfo("At start of "//trim(subname)) + + ! Open input data file + rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + + ! Read in input mesh + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Determine ns_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the landmask from the file and reset the mesh mask based on that + allocate(rmask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, rmask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (rmask_i(ni) > 0._r8) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create a route handle between the input and output mesh + allocate(frac_o(ns_o)) + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + do n = 1, ns_o + if ((frac_o(n) < 0.0) .or. (frac_o(n) > 1.0001)) then + write(6,*) "ERROR:: frac_o out of range: ", frac_o(n),n + end if + end do ! ----------------------------------------------------------------- - ! Regrid binfl + ! Determine binfl ! ----------------------------------------------------------------- - call check_ret(nf_inq_varid (ncid, 'binfl', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, binfl_o, nodata=0.1_r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data + ! Read in input data_i for a variety of inputs + allocate(data_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort('allocation error for binfl_i') + + ! Read in binfl_i into data_i + call mkpio_get_rawdata(pioid, 'binfl', mesh_i, data_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + + ! Regrid binfl_i to binfl_o and check validity of output data + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, binfl_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do no = 1,ns_o + if (frac_o(ns_o) == 0._r8) then + ws_o(n) = 0.1_r8 + end if + end do if (min_bad(binfl_o, min_valid_binfl, 'binfl')) then - call abort() + call shr_sys_abort() end if - call output_diagnostics_continuous(data_i, binfl_o, tgridmap, "VIC b parameter", "unitless", ndiag, tdomain%mask, frac_dst) + ! Calculate global diagnostics for binfl + call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + data_i, binfl_o, "VIC b parameter", "unitless", ndiag, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! ----------------------------------------------------------------- - ! Regrid Ws + ! Determine Ws ! ----------------------------------------------------------------- - call check_ret(nf_inq_varid (ncid, 'Ws', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, ws_o, nodata=0.75_r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data + ! Read in Ws into data_i + call mkpio_get_rawdata(pioid, 'Ws', mesh_i, data_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + + ! Regrid Ws_i to Ws_o and check validity of output data + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, ws_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do no = 1,ns_o + if (frac_o(ns_o) == 0._r8) then + ws_o(n) = 0.75_r8 + end if + end do if (min_bad(ws_o, min_valid_ws, 'Ws')) then - call abort() + call shr_sys_abort() end if - call output_diagnostics_continuous(data_i, ws_o, tgridmap, "VIC Ws parameter", "unitless", ndiag, tdomain%mask, frac_dst) + ! Calculate global diagnostics for Ws + call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + data_i, ws_o, "VIC Ws parameter", "unitless", ndiag, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! ----------------------------------------------------------------- - ! Regrid Dsmax + ! Determine DsMax ! ----------------------------------------------------------------- - call check_ret(nf_inq_varid (ncid, 'Dsmax', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, dsmax_o, nodata=10._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data + ! Read in Dsmax into data_i + call mkpio_get_rawdata(pioid, 'Dsmax', mesh_i, data_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + + ! Regrid Dsmax_i to Dsmax_o and check validity of output data + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, dsmax_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do no = 1,ns_o + if (frac_o(ns_o) == 0._r8) then + ws_o(n) = 10._r8 + end if + end do if (min_bad(dsmax_o, min_valid_dsmax, 'Dsmax')) then - call abort() + call shr_sys_abort() end if - call output_diagnostics_continuous(data_i, dsmax_o, tgridmap, "VIC Dsmax parameter", "mm/day", ndiag, tdomain%mask, frac_dst) + ! Calculate global diagnostics for Dsmax + call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + data_i, ws_o, "VIC Dsmax parameter", "mm/day", ndiag, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! ----------------------------------------------------------------- ! Regrid Ds ! ----------------------------------------------------------------- - call check_ret(nf_inq_varid (ncid, 'Ds', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, ds_o, nodata=0.1_r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data + ! Read in Ds into data_i + call mkpio_get_rawdata(pioid, 'Dsmax', mesh_i, data_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + + ! Regrid Ds_i to Ds_o and check validity of output data + call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, ds_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do no = 1,ns_o + if (frac_o(ns_o) == 0._r8) then + ws_o(n) = 0.1_r8 + end if + end do if (min_bad(ds_o, min_valid_ds, 'Ds')) then - call abort() + call shr_sys_abort() end if - call output_diagnostics_continuous(data_i, ds_o, tgridmap, "VIC Ds parameter", "unitless", ndiag, tdomain%mask, frac_dst) + ! Calculate global diagnostics for Ws + call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + data_i, ws_o, "VIC Ds parameter", "unitless", ndiag, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory + ! Wrap up ! ----------------------------------------------------------------- - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (data_i) - deallocate (frac_dst) - deallocate (mask_r8) + ! Close the file + call pio_closefile(pioid) + call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) - write (6,*) 'Successfully made VIC parameters' - write (6,*) + ! Release memory + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) + + if (root_task) then + write (ndiag,'(a)') 'Successfully made VIC parameters' + end if end subroutine mkVICparams diff --git a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 index 110408b0e0..e6d255d501 100644 --- a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 +++ b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 @@ -5,23 +5,18 @@ module mkagfirepkmonthMod !----------------------------------------------------------------------- use ESMF - use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 - use shr_sys_mod , only : shr_sys_abort - use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths - use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkpioMod , only : mkpio_get_rawdata_level - use mkesmfMod , only : get_meshareas - use mkutilsMod , only : chkerr - use mkvarctl , only : ndiag, root_task - use mkchecksMod , only : min_bad, max_bad - use mkdiagnosticsMod, only : output_diagnostics_index + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem + use mkvarctl , only : ndiag, root_task + use mkchecksMod , only : min_bad, max_bad + use mkdiagnosticsMod , only : output_diagnostics_index + use mkutilsMod , only : chkerr implicit none private ! By default make data private -#include - public :: mkagfirepkmon ! Set agricultural fire peak month integer , parameter :: min_valid = 1 @@ -60,7 +55,7 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) integer :: ns_i, ns_o integer , allocatable :: mask_i(:) real(r4), allocatable :: rmask_i(:) - real(r4), allocatable :: frac_o(:) + real(r8), allocatable :: frac_o(:) integer , allocatable :: idata_i(:) ! input grid: agricultural fire peak month real(r4), pointer :: dataptr(:) real(r8), pointer :: dataptr_r8(:) @@ -135,11 +130,11 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - ! Determin frac_o + ! Determine frac_o call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return allocate(frac_o(ns_o)) - frac_o(:) = real(dataptr_r8(:), kind=r4) + frac_o(:) = dataptr_r8(:) ! Create a dynamic mask object ! The dynamic mask object further holds a pointer to the routine that will be called in order to @@ -172,18 +167,12 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) ! Close the file call pio_closefile(pioid) - ! ----------------------------------------------------------------- ! Output diagnostics comparing global area of each peak month on input and output grids - ! ----------------------------------------------------------------- - - ! TODO: fix this - ! call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, idata_i, agfirepkmon_o, & - ! 'peak fire month', ndiag) + call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & + 1, 13, idata_i, agfirepkmon_o, 'peak fire month', ndiag, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - ! ----------------------------------------------------------------- ! Release memory - ! ----------------------------------------------------------------- - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 index bacfc2799d..fbd0b3da5d 100644 --- a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 @@ -8,6 +8,7 @@ module mkdiagnosticsMod use shr_kind_mod , only : r8 => shr_kind_r8 use shr_sys_mod , only : shr_sys_abort use mkutilsMod , only : chkerr + use mkesmfMod , only : get_meshareas use mkvarctl , only : mpicom, root_task implicit none @@ -127,17 +128,15 @@ subroutine output_diagnostics_area(mesh_i, mesh_o, mask_i, data_i, data_o, name, end subroutine output_diagnostics_area !=============================================================== - subroutine output_diagnostics_continuous(area_i, area_o, mask_i, frac_o, & - data_i, data_o, name, units, ndiag) + subroutine output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + data_i, data_o, name, units, ndiag, rc, nomask) ! Output diagnostics for a continuous field (but not area, for ! which there is a different routine) - use mkvarpar, only : re - - ! !ARGUMENTS: - real(r8) , intent(in) :: area_i(:) - real(r8) , intent(in) :: area_o(:) + ! input/output variables + type(ESMF_Mesh) , intent(in) :: mesh_i + type(ESMF_Mesh) , intent(in) :: mesh_o integer , intent(in) :: mask_i(:) real(r8) , intent(in) :: frac_o(:) real(r8) , intent(in) :: data_i(:) ! data on input grid @@ -145,22 +144,46 @@ subroutine output_diagnostics_continuous(area_i, area_o, mask_i, frac_o, & character(len=*) , intent(in) :: name ! name of field character(len=*) , intent(in) :: units ! units of field integer , intent(in) :: ndiag + logical, optional, intent(in) :: nomask + integer , intent(out) :: rc - ! !LOCAL VARIABLES: - real(r8) :: loc_gdata_i ! local sum of input data - real(r8) :: loc_gdata_o ! local sum of output data - real(r8) :: gdata_i ! global sum of input data - real(r8) :: gdata_o ! global sum of output data - real(r8) :: loc_gwt_i ! local global sum of input weights (area * frac) - real(r8) :: loc_gwt_o ! local global sum of output weights (area * frac) - real(r8) :: gwt_i ! global sum of input weights (area * frac) - real(r8) :: gwt_o ! global sum of output weights (area * frac) - integer :: ns_i, ns_o ! sizes of input & output grids - integer :: ni,no,k ! indices - integer :: ier ! error code + ! local variables + real(r8), allocatable :: area_i(:) + real(r8), allocatable :: area_o(:) + real(r8) :: loc_gdata_i ! local sum of input data + real(r8) :: loc_gdata_o ! local sum of output data + real(r8) :: gdata_i ! global sum of input data + real(r8) :: gdata_o ! global sum of output data + real(r8) :: loc_gwt_i ! local global sum of input weights (area * frac) + real(r8) :: loc_gwt_o ! local global sum of output weights (area * frac) + real(r8) :: gwt_i ! global sum of input weights (area * frac) + real(r8) :: gwt_o ! global sum of output weights (area * frac) + integer :: ns_i, ns_o ! sizes of input & output grids + integer :: ni,no,k ! indices + integer :: ier ! error code + logical :: lnomask character(len=*), parameter :: subname = "output_diagnostics_continuous" !------------------------------------------------------------------------------ + rc = ESMF_SUCCESS + + lnomask = .false. + if (present(nomask)) lnomask = nomask + + ! Determine ns_i and ns_o + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine areas + allocate(area_i(ns_i)) + allocate(area_o(ns_o)) + call get_meshareas(mesh_i, area_i, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call get_meshareas(mesh_o, area_o, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Error check for array size consistencies if (size(data_i) /= ns_i .or. size(data_o) /= ns_o) then write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) @@ -187,19 +210,31 @@ subroutine output_diagnostics_continuous(area_i, area_o, mask_i, frac_o, & loc_gdata_i = 0. loc_gwt_i = 0. do ni = 1,ns_i - loc_gdata_i = loc_gdata_i + data_i(ni) * area_i(ni) * mask_i(ni) - loc_gwt_i = loc_gwt_i + area_i(ni) * mask_i(ni) + if (lnomask) then + loc_gdata_i = loc_gdata_i + data_i(ni) * area_i(ni) + loc_gwt_i = loc_gwt_i + area_i(ni) + else + loc_gdata_i = loc_gdata_i + data_i(ni) * area_i(ni) * mask_i(ni) + loc_gwt_i = loc_gwt_i + area_i(ni) * mask_i(ni) + end if end do - call mpi_reduce(loc_gdata_i,gdata_i,1,MPI_REAL8,MPI_SUM,0,mpicom,ier) + call mpi_reduce(loc_gdata_i, gdata_i, 1, MPI_REAL8, MPI_SUM, 0, mpicom, ier) + call mpi_reduce(loc_gwt_i , gwt_i , 1, MPI_REAL8, MPI_SUM, 0, mpicom, ier) ! Sums on output grid loc_gdata_o = 0. loc_gwt_o = 0. do no = 1,ns_o - loc_gdata_o = loc_gdata_o + data_o(no) * area_o(no) * frac_o(no) - loc_gwt_o = loc_gwt_o + area_o(no) * frac_o(no) + if (lnomask) then + loc_gdata_o = loc_gdata_o + data_o(no) * area_o(no) + loc_gwt_o = loc_gwt_o + area_o(no) + else + loc_gdata_o = loc_gdata_o + data_o(no) * area_o(no) * frac_o(no) + loc_gwt_o = loc_gwt_o + area_o(no) * frac_o(no) + end if end do - call mpi_reduce(loc_gdata_o,gdata_o,1,MPI_REAL8,MPI_SUM,0,mpicom,ier) + call mpi_reduce(loc_gdata_o, gdata_o, 1, MPI_REAL8, MPI_SUM, 0, mpicom, ier) + call mpi_reduce(loc_gwt_o , gwt_o , 1, MPI_REAL8, MPI_SUM, 0, mpicom, ier) ! Correct units gdata_i = gdata_i / gwt_i @@ -209,14 +244,10 @@ subroutine output_diagnostics_continuous(area_i, area_o, mask_i, frac_o, & if (root_task) then write (ndiag,*) write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) - write (ndiag,2002) units, units -2001 format (1x,' parameter input grid output grid') -2002 format (1x,' ', a24, a24) + write (ndiag,'(1x,a)')'output diagnostics for '//trim(name)//' with units = '//trim(units) + write (ndiag,'(1x,a,f17.3,a,f17.3)')' global input sum= ',gdata_i,' global output sum',gdata_o write (ndiag,'(1x,70a1)') ('.',k=1,70) write (ndiag,*) - write (ndiag,2003) name, gdata_i, gdata_o -2003 format (1x,a12, f22.3,f17.3) end if end subroutine output_diagnostics_continuous @@ -228,10 +259,8 @@ subroutine output_diagnostics_continuous_outonly(area_o, frac_o, data_o, name, u ! This is used when the average of the field on the input grid is not of interest (e.g., ! when the output quantity is the standard deviation of the input field) ! - use mkvarpar, only : re - ! input/output variables - real(r8) , intent(in) :: area_o(:) + real(r8) , intent(in) :: area_o(:) real(r8) , intent(in) :: frac_o(:) real(r8) , intent(in) :: data_o(:) ! data on output grid character(len=*) , intent(in) :: name ! name of field @@ -280,12 +309,12 @@ subroutine output_diagnostics_continuous_outonly(area_o, frac_o, data_o, name, u write (ndiag,2003) name, gdata_o 2003 format (1x,a12, f22.3) end if - + end subroutine output_diagnostics_continuous_outonly !=============================================================== subroutine output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & - data_i, data_o, name, ndiag, rc) + min_valid, max_valid, data_i, data_o, name, ndiag, rc) ! ! Output diagnostics for an index field: area of each index in input and output ! @@ -294,6 +323,8 @@ subroutine output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & type(ESMF_Mesh) , intent(in) :: mesh_o integer , intent(in) :: mask_i(:) real(r8) , intent(in) :: frac_o(:) + integer , intent(in) :: min_valid + integer , intent(in) :: max_valid integer , intent(in) :: data_i(:) ! data on input grid integer , intent(in) :: data_o(:) ! data on output grid character(len=*) , intent(in) :: name ! name of field @@ -310,9 +341,6 @@ subroutine output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & real(r8), allocatable :: garea_i(:) ! input grid: global area of each index real(r8), allocatable :: garea_o(:) ! output grid: global area of each index integer :: ier ! error status - integer :: max_valid_loc - integer :: max_valid - integer :: min_valid character(len=*), parameter :: subname = 'output_diagnostics_index' !----------------------------------------------------------------------- @@ -339,6 +367,7 @@ subroutine output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & write(6,*) 'ns_i = ', ns_i write(6,*) 'size(data_o) = ', size(data_o) write(6,*) 'ns_o = ', ns_o + !call shr_sys_abort(subname,file=__FILE__,line=__LINE__) call shr_sys_abort() end if if (size(mask_i) /= ns_i) then @@ -348,13 +377,9 @@ subroutine output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & call shr_sys_abort() end if - max_valid_loc = maxval(data_i) - call mpi_reduce(max_valid_loc, (/max_valid/), 1, MPI_INT, MPI_SUM, 0, mpicom, ier) - ! Sum areas on input grid - ! For now hard-wire min_valid to 1 - min_valid = 1 allocate(loc_garea_i(min_valid:max_valid), stat=ier) + if (ier/=0) call shr_sys_abort() allocate(garea_i(min_valid:max_valid), stat=ier) if (ier/=0) call shr_sys_abort() loc_garea_i(:) = 0. @@ -364,20 +389,21 @@ subroutine output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & loc_garea_i(k) = loc_garea_i(k) + area_i(ni) * mask_i(ni) end if end do - call mpi_reduce(loc_garea_i, garea_i, size(garea_i), size(garea_i), MPI_REAL8, MPI_SUM, 0, mpicom, ier) + call mpi_reduce(loc_garea_i, garea_i, size(garea_i), MPI_REAL8, MPI_SUM, 0, mpicom, ier) ! Sum areas on output grid allocate(loc_garea_o(min_valid:max_valid), stat=ier) + if (ier/=0) call shr_sys_abort() allocate(garea_o(min_valid:max_valid), stat=ier) if (ier/=0) call shr_sys_abort() loc_garea_o(:) = 0. do no = 1, ns_o k = data_o(no) if (k >= min_valid .and. k <= max_valid) then - loc_garea_o(k) = garea_o(k) + area_o(no) * frac_o(no) + loc_garea_o(k) = loc_garea_o(k) + area_o(no) * frac_o(no) end if end do - call mpi_reduce(loc_garea_o, garea_o, size(garea_o), size(garea_o), MPI_REAL8, MPI_SUM, 0, mpicom, ier) + call mpi_reduce(loc_garea_o, garea_o, size(garea_o), MPI_REAL8, MPI_SUM, 0, mpicom, ier) ! Write results if (root_task) then diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 0ee059caaa..711ce0909a 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -12,6 +12,7 @@ module mkfileMod use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft, num_natpft use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array use mkpioMod ! TODO: add only + use mkinputMod use mkvarctl implicit none @@ -125,23 +126,15 @@ subroutine mkfile_define_atts(pioid, dynlanduse) str = 'created on: ' // datetime rcode = pio_put_att (pioid, pio_global, 'History_Log', trim(str)) -#ifdef TODO - call shr_sys_getenv ('LOGNAME', str, ier) - rcode = pio_put_att (pioid, pio_global, 'Logname', trim(str)) - - call shr_sys_getenv ('HOST', str, ier) - rcode = pio_put_att (pioid, pio_global, 'Host', trim(str)) -#endif + ! TODO: this is not working + ! call shr_sys_getenv ('LOGNAME', str, ier) + ! rcode = pio_put_att (pioid, pio_global, 'Logname', trim(str)) + ! call shr_sys_getenv ('HOST', str, ier) + ! rcode = pio_put_att (pioid, pio_global, 'Host', trim(str)) str = 'Community Land Model: CLM5' rcode = pio_put_att (pioid, pio_global, 'Source', trim(str)) - !rcode = pio_put_att (pioid, pio_global, 'Version', trim(gitdescribe), trim(gitdescribe)) -#ifdef OPT - str = 'TRUE' -#else - str = 'FALSE' -#endif - rcode = pio_put_att (pioid, pio_global, 'Compiler_Optimized', trim(str)) + !rcode = pio_put_att (pioid, pio_global, 'Version', trim(gitdescribe), trim(gitdescribe)) if ( all_urban )then str = 'TRUE' diff --git a/tools/mksurfdata_esmf/src/mkgdpMod.F90 b/tools/mksurfdata_esmf/src/mkgdpMod.F90 index 940fa609e0..7fd124d1f6 100644 --- a/tools/mksurfdata_esmf/src/mkgdpMod.F90 +++ b/tools/mksurfdata_esmf/src/mkgdpMod.F90 @@ -5,19 +5,19 @@ module mkgdpMod !----------------------------------------------------------------------- use ESMF - use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 - use shr_sys_mod , only : shr_sys_abort - use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas - use mkutilsMod , only : chkerr - use mkvarctl , only : ndiag, root_task, mpicom + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 + use mkvarctl , only : ndiag, root_task, mpicom + use mkdiagnosticsMod , only : output_diagnostics_continuous + use mkchecksMod , only : min_bad + use mkutilsMod , only : chkerr implicit none private -#include - public :: mkgdp ! regrid gdp data character(len=*) , parameter :: u_FILE_u = & @@ -31,9 +31,6 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, gdp_o, rc) ! ! make GDP from input GDP data ! - use mkdiagnosticsMod, only : output_diagnostics_continuous - use mkchecksMod, only : min_bad - ! ! input/output variables character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name @@ -50,17 +47,9 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, gdp_o, rc) integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) - real(r8), allocatable :: area_i(:) - real(r8), allocatable :: area_o(:) real(r8), allocatable :: gdp_i(:) ! input grid: percent gdp - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: gglac_i ! input grid: global glac - real(r8) :: garea_i ! input grid: global area - real(r8) :: gglac_o ! output grid: global glac - real(r8) :: garea_o ! output grid: global area - integer :: ier, rcode ! error status real(r8), parameter :: min_valid = 0._r8 ! minimum valid value + integer :: ier, rcode ! error status character(len=*), parameter :: subname = 'mkgdp' !----------------------------------------------------------------------- @@ -74,10 +63,10 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, gdp_o, rc) write(ndiag,'(a)') ' Input file is '//trim(file_data_i) write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if + call ESMF_VMLogMemInfo("At start of"//trim(subname)) ! Open input data file rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) - call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) @@ -132,17 +121,11 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, gdp_o, rc) ! Close the file call pio_closefile(pioid) - call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) ! Output diagnostic info - allocate(area_i(ns_i)) - allocate(area_o(ns_o)) - call get_meshareas(mesh_i, area_i, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call get_meshareas(mesh_o, area_o, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - ! call output_diagnostics_continuous(area_i, area_o, mask_i, frac_o, & - ! gdp_i, gdp_o, "GDP", "x1000 US$ per capita", ndiag) + call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + gdp_i, gdp_o, "GDP", "x1000 US$ per capita", ndiag, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() ! Clean up memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) @@ -153,6 +136,7 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, gdp_o, rc) if (root_task) then write (ndiag,'(a)') 'Successfully made GDP' end if + call ESMF_VMLogMemInfo("At end of "//trim(subname)) end subroutine mkgdp diff --git a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 index 0f4e2e5848..990feac4f6 100644 --- a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 @@ -6,18 +6,15 @@ module mkglacierregionMod !----------------------------------------------------------------------- use ESMF - use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 - use shr_sys_mod , only : shr_sys_abort - use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths - use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas - use mkutilsMod , only : chkerr - use mkchecksMod , only : min_bad - use mkvarctl , only : ndiag, root_task -#ifdef TODO - ! use mkdiagnosticsMod, only : output_diagnostics_index -#endif + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 + use mkchecksMod , only : min_bad + use mkvarctl , only : ndiag, root_task + use mkdiagnosticsMod , only : output_diagnostics_index + use mkutilsMod , only : chkerr implicit none private @@ -53,8 +50,6 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) - real(r8), allocatable :: area_i(:) - real(r8), allocatable :: area_o(:) real(r8), allocatable :: data_i(:,:) real(r8), allocatable :: data_o(:,:) integer , allocatable :: glacier_region_i(:) ! glacier region on input grid @@ -73,14 +68,12 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r write(ndiag,'(a)') ' Input file is '//trim(file_data_i) write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if + call ESMF_VMLogMemInfo("At start of "//trim(subname)) ! Open input data file - call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) - call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh - call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) @@ -150,40 +143,24 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r glacier_region_o(no) = max_index(1) - 1 end do - ! Determine mesh areas - allocate(area_i(ns_i)) - allocate(area_o(ns_o)) - call get_meshareas(mesh_i, area_i, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call get_meshareas(mesh_o, area_o, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - -#ifdef TODO - ! call output_diagnostic_index(area_i, area_o, mask_i, frac_o, & - ! glacier_region_i, glacier_region_o, 'Glacier Region ID', 0, max_region, ndiag) -#endif + ! Determine global diagnostics + call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & + 0, 3, glacier_region_i, glacier_region_o, 'Glacier Region ID', ndiag, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() ! Close the input file call pio_closefile(pioid) - call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) ! Release memory - deallocate(mask_i) - deallocate(frac_i) - deallocate(frac_o) - deallocate(area_i) - deallocate(area_o) - deallocate(glacier_region_i) call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) if (root_task) then write (ndiag,'(a)') 'Successfully made glacier region' - write (ndiag,*) end if + call ESMF_VMLogMemInfo("At end of "//trim(subname)) end subroutine mkglacierregion diff --git a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 index 751b97aaac..dc8f1acb36 100644 --- a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 @@ -5,16 +5,16 @@ module mkglcmecMod !----------------------------------------------------------------------- use ESMF - use pio use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 use shr_sys_mod , only : shr_sys_abort - use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths - use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite + use pio , only : var_desc_t, io_desc_t, Pio_Offset_Kind, pio_setframe + use pio , only : pio_inq_dimid, pio_inq_dimlen, pio_inq_varid, pio_get_var + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem use mkpioMod , only : mkpio_iodesc_rawdata, mkpio_get_rawdata_level - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas - use mkutilsMod , only : chkerr + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkvarctl , only : ndiag, root_task, outnc_3dglc - use mkvarpar + use mkutilsMod , only : chkerr implicit none private ! By default make data private diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 9f4a1a994e..c0490cc39a 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -6,12 +6,11 @@ module mklanwatMod !----------------------------------------------------------------------- use ESMF - use pio use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 use shr_sys_mod , only : shr_sys_abort - use mkvarpar , only : re - use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkdiagnosticsMod , only : output_diagnostics_continuous use mkchecksMod , only : min_bad use mkutilsMod , only : chkerr @@ -20,10 +19,7 @@ module mklanwatMod implicit none private -#include - public :: mklakwat ! make % lake, % wetland and lake parameters - private :: check_global_sums character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -55,10 +51,8 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid integer , allocatable :: mask_i(:) - real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: rmask_i(:) real(r8), allocatable :: frac_o(:) - real(r8), allocatable :: area_i(:) - real(r8), allocatable :: area_o(:) real(r8), allocatable :: lake_i(:) ! input grid: percent lake real(r8), allocatable :: swmp_i(:) ! input grid: percent wetland real(r8), allocatable :: lakedepth_i(:) ! iput grid: lake depth @@ -98,14 +92,14 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Get the landmask from the input data file and reset the mesh mask based on that - allocate(frac_i(ns_i), stat=ier) + allocate(rmask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, rmask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i - if (frac_i(ni) > 0._r8) then + if (rmask_i(ni) > 0._r8) then mask_i(ni) = 1 else mask_i(ni) = 0 @@ -142,18 +136,14 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & do no = 1,ns_o if (lake_o(no) < 1.) lake_o(no) = 0. enddo - call ESMF_VMLogMemInfo("After regrid_rawdata for PCT_LAKE in "//trim(subname)) ! Check global areas - call check_global_sums(mesh_i, mesh_o, mask_i, frac_o, lake_i, lake_o, 'pct lake', rc) + call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + lake_i, lake_o, "pct lake", "unitless", ndiag, nomask=.true., rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return deallocate (lake_i) end if - if (root_task) then - write (ndiag,*) 'Successfully made %lake' - write (ndiag,*) - end if ! ---------------------------------------- ! Create %wetland @@ -181,15 +171,12 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & enddo ! Check global areas - call check_global_sums(mesh_i, mesh_o, mask_i, frac_o, swmp_i, swmp_o, 'pct wetland', rc) + call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + swmp_i, swmp_o, "pct wetland", "unitless", ndiag, nomask=.true., rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return deallocate (swmp_i) end if - if (root_task) then - write (ndiag,*) 'Successfully made %wetland' - write (ndiag,*) - end if ! ---------------------------------------- ! Create lake parameter (lakedepth) @@ -214,103 +201,31 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & lakedepth_o(no) = 10._r8 end if enddo - - ! Check validity of output data if (min_bad(lakedepth_o, min_valid_lakedepth, 'lakedepth')) then call shr_sys_abort() end if - ! Write out diagnostics - ! call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - ! data_i, lakedepth_o, "Lake Depth", "m", ndiag) + ! Check global areas + call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + lakedepth_i, lakedepth_o, "lake depth", "m", ndiag, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Close the single input data file call pio_closefile(pioid) ! Release memory - call ESMF_VMLogMemInfo("Before destroy operation for lanwat ") call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_VMLogMemInfo("After destroy operation for lanwat ") if (root_task) then + write (ndiag,*) 'Successfully made %lake' + write (ndiag,*) 'Successfully made %wetland' write (ndiag,*) 'Successfully made lake parameters' end if + call ESMF_VMLogMemInfo("At end of "//trim(subname)) end subroutine mklakwat - !=============================================================== - subroutine check_global_sums(mesh_i, mesh_o, mask_i, frac_o, data_i, data_o, name, rc) - - use mkvarctl, only : mpicom, MPI_INTEGER, MPI_MAX - - ! Compare global areas on input and output grids - - ! input/otuput variables - type(ESMF_Mesh) , intent(in) :: mesh_i - type(ESMF_Mesh) , intent(in) :: mesh_o - integer , intent(in) :: mask_i(:) - real(r8) , intent(in) :: frac_o(:) - real(r8) , intent(in) :: data_i(:) - real(r8) , intent(in) :: data_o(:) - character(len=*) , intent(in) :: name - integer , intent(out) :: rc - - ! local variables - integer :: ns_i - integer :: ns_o - integer :: ni, no, l, k - integer :: ier - real(r8), allocatable :: area_i(:) - real(r8), allocatable :: area_o(:) - real(r4) :: local_i ! local global area, by surface type - real(r4) :: local_o ! local global area, by surface type - real(r4) :: global_i ! input grid: global area pfts - real(r4) :: global_o ! output grid: global area pfts - !----------------------------------------------------------------------- - - rc = ESMF_SUCCESS - - ! Determine ns_i and ns_o - call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Get areas from mesh - allocate(area_i(ns_i)) - allocate(area_o(ns_o)) - call get_meshareas(mesh_i, area_i, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call get_meshareas(mesh_o, area_o, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Input grid global area - local_i = 0. - do ni = 1,ns_i - local_i = local_i + (data_i(ni) * area_i(ni) * mask_i(ni)) - end do - call mpi_reduce(local_i, global_i, 1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) - - ! Output grid global area - local_o = 0. - do no = 1,ns_o - local_i = local_i + data_o(no) * area_i(no) * frac_o(no) - end do - call mpi_reduce(local_o, global_o, 1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) - - ! Comparison - if (root_task) then - write(ndiag,*) - write(ndiag,'(a)')' surface type input grid area output grid area' - write(ndiag,'(a)')' 10**6 km**2 10**6 km**2 ' - write(ndiag,'(60a1)') ('.',k=1,60) - write(ndiag,'(a,f14.3,f17.3)')' '//trim(name), global_i*1.e-06, global_o*1.e-06 - write(ndiag,*) - end if - - end subroutine check_global_sums - end module mklanwatMod diff --git a/tools/mksurfdata_esmf/src/mkpeatMod.F90 b/tools/mksurfdata_esmf/src/mkpeatMod.F90 index 2109fed9f0..3d5aca76ba 100644 --- a/tools/mksurfdata_esmf/src/mkpeatMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpeatMod.F90 @@ -5,22 +5,20 @@ module mkpeatMod !----------------------------------------------------------------------- use ESMF - use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 - use shr_sys_mod , only : shr_sys_abort - use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths - use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkpioMod , only : mkpio_iodesc_rawdata, mkpio_get_rawdata_level - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas - use mkutilsMod , only : chkerr - use mkvarctl , only : ndiag, root_task, mpicom + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 + use mkvarctl , only : ndiag, root_task, mpicom + use mkchecksMod , only : min_bad, max_bad + use mkdiagnosticsMod , only : output_diagnostics_continuous + use mkutilsMod , only : chkerr implicit none private -#include - - public :: mkpeat ! regrid peat data + public :: mkpeat character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -31,9 +29,6 @@ module mkpeatMod subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) - use mkdiagnosticsMod, only : output_diagnostics_area - use mkchecksMod , only : min_bad, max_bad - ! input/output variables character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name @@ -50,18 +45,10 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) - real(r8), allocatable :: area_i(:) - real(r8), allocatable :: area_o(:) real(r8), allocatable :: peat_i(:) ! input grid: percent peat - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: gglac_i ! input grid: global glac - real(r8) :: garea_i ! input grid: global area - real(r8) :: gglac_o ! output grid: global glac - real(r8) :: garea_o ! output grid: global area integer :: ier, rcode ! error status - real(r8), parameter :: min_valid = 0._r8 ! minimum valid value - real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value + real(r8), parameter :: min_valid = 0._r8 ! minimum valid value + real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value character(len=*), parameter :: subname = 'mkpeat' !----------------------------------------------------------------------- @@ -73,10 +60,10 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) write(ndiag,'(a)') ' Input file is '//trim(file_data_i) write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if + call ESMF_VMLogMemInfo("At start of "//trim(subname)) ! Open input data file rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) - call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) @@ -129,28 +116,24 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) call shr_sys_abort(subname//" peat_o does not fall in range of min_valid/max_valid") end if + ! Output diagnostic info + call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + peat_i, peat_o, "Peat", "unitless", ndiag, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + ! Close the file call pio_closefile(pioid) - ! Output diagnostic info - ! allocate(area_i(ns_i)) - ! allocate(area_o(ns_o)) - ! call get_meshareas(mesh_i, area_i, rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return - ! call get_meshareas(mesh_o, area_o, rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return - ! call output_diagnostics_area(area_i, area_o, mask_i, peat_i, peat_o, 'peat', .true., ndiag) - ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) if (root_task) then write (ndiag,'(a)') 'Successfully made peat' end if + call ESMF_VMLogMemInfo("At end of "//trim(subname)) end subroutine mkpeat diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index 60167969f5..82e3827c49 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -7,7 +7,7 @@ module mkpftMod use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem use mkpioMod , only : mkpio_iodesc_rawdata, mkpio_get_rawdata_level - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr use mkvarctl , only : numpft, root_task, ndiag use mkvarpar , only : numstdpft, numstdcft, noveg @@ -305,7 +305,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft real(r8) , intent(inout) :: pctlnd_o(:) ! output grid:%land/gridcell type(pct_pft_type), intent(inout) :: pctnatpft_o(:) ! natural PFT cover type(pct_pft_type), intent(inout) :: pctcft_o(:) ! crop (CFT) cover - + integer , intent(out) :: rc ! ! local variables: @@ -483,7 +483,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! Readgrid to determine pct_nat_pft_o call regrid_rawdata(mesh_i, mesh_o, routehandle, pct_nat_pft_i, pct_nat_pft_o, 0, num_natpft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - + ! Rescale pct_nat_pft_o do no = 1,ns_o if (pctnatveg_o(no) > 0._r8) then @@ -549,7 +549,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft do n = 1,ndims write(ndiag,'(a,i8,i8)')' dimid, length= ',n,dimlens(n) end do - write(ndiag,'(a,i8)')' num_cft = ',num_cft + write(ndiag,'(a,i8)')' num_cft = ',num_cft end if ! Read in pct_cft_i @@ -688,33 +688,33 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! ns_i = 1 ! numpft_i = numpft+1 ! end if - + ! if ( .not. presc_cover ) then ! ! Derived types ! allocate(pctnatpft_i(ns_i), stat=ier) ! if (ier/=0) call shr_sys_abort() ! allocate(pctcft_i(ns_i), stat=ier) ! if (ier/=0) call shr_sys_abort() - + ! do ni = 1, ns_i ! pctnatpft_i(ni) = pct_pft_type( pct_nat_pft_i(ni,:), pctnatveg_i(ni), first_pft_index=natpft_lb ) ! pctcft_i(ni) = pct_pft_type( pct_cft_i(ni,:), pctcrop_i(ni), first_pft_index=cft_lb ) ! end do - + ! do no = 1,ns_o ! pctpft_o(no,natpft_lb:natpft_ub) = pctnatpft_o(no)%get_pct_p2g() ! pctpft_o(no,cft_lb:cft_ub) = pctcft_o(no)%get_pct_p2g() ! end do - + ! allocate(gpft_i(0:numpft_i-1)) ! allocate(gpft_o(0:numpft_i-1)) - + ! ! input grid ! allocate(pctpft_i(ns_i,0:(numpft_i-1)), stat=ier) ! if (ier/=0) call shr_sys_abort() ! allocate(pctpft_o(ns_o,0:(numpft_i-1)), stat=ier) ! if (ier/=0) call shr_sys_abort() - + ! gpft_i(:) = 0. ! garea_i = 0. ! do ni = 1,ns_i @@ -724,7 +724,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! end do ! end do ! if ( allocated(pctpft_i) ) deallocate (pctpft_i) - + ! ! output grid ! gpft_o(:) = 0. ! garea_o = 0. @@ -734,13 +734,13 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! gpft_o(m) = gpft_o(m) + pctpft_o(no,m)*area_dst(no)*frac_o(no)*re**2 ! end do ! end do - + ! ! comparison ! write (ndiag,*) ! write (ndiag,'(1x,70a1)') ('=',k=1,70) ! write (ndiag,*) 'PFTs Output' ! write (ndiag,'(1x,70a1)') ('=',k=1,70) - + ! write (ndiag,*) ! write (ndiag,'(1x,70a1)') ('.',k=1,70) ! write (ndiag,1001) @@ -752,11 +752,11 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! write (ndiag,1002) veg(m), gpft_i(m)*1.e-06/100.,gpft_o(m)*1.e-06/100. ! end do ! 1002 format (1x,a35,f16.3,f17.3) - + ! deallocate(gpft_i, gpft_o, frac_dst) - + ! end if - + ! Clean up memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index e40f3fe8d1..aeee44ec20 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -1,15 +1,13 @@ module mksoilcolMod use ESMF - use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 - use shr_sys_mod , only : shr_sys_abort - use mkpioMod , only : mkpio_get_rawdata - use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : get_meshareas - use mkutilsMod , only : chkerr - use mkvarctl , only : root_task, ndiag, mpicom, MPI_INTEGER, MPI_MAX - use mkvarctl , only : soil_color_override, unsetcol + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem + use mkvarctl , only : root_task, ndiag, mpicom, unsetcol, soil_color_override + use mkdiagnosticsMod , only : output_diagnostics_index + use mkutilsMod , only : chkerr implicit none private @@ -17,9 +15,9 @@ module mksoilcolMod #include public :: mksoilcol ! Set soil colors - private :: check_global_sums + private :: get_dominant_soilcol - integer :: num_soilcolors + integer :: num_soilcolors type(ESMF_DynamicMask) :: dynamicMask character(len=*) , parameter :: u_FILE_u = & @@ -50,7 +48,7 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r integer :: ns_i, ns_o integer , allocatable :: mask_i(:) real(r4), allocatable :: rmask_i(:) - real(r4), allocatable :: frac_o(:) + real(r8), allocatable :: frac_o(:) real(r4), allocatable :: soil_color_i(:) real(r4), pointer :: dataptr(:) real(r8), pointer :: dataptr_r8(:) @@ -135,11 +133,8 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r end do ! Determine maximum number of soil colors across all processors - ! This will be used for the ungridded dimension of data_o below nsoilcol_local = maxval(soil_color_i) call mpi_allreduce(nsoilcol_local, nsoilcol, 1, MPI_INTEGER, MPI_MAX, mpicom, rcode) - ! TODO: MPI_SUCCESS could not be accessed from mkvarctl - !if (rcode /= MPI_SUCCESS) call shr_sys_abort('error for mpi_allredice in '//trim(subname)) ! Set module variable (used in the get_dominant_soilcol routine) num_soilcolors = nsoilcol @@ -195,8 +190,8 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r end do ! Compare global area of each soil color on input and output grids - call check_global_sums(mesh_i, mesh_o, mask_i, frac_o, & - soil_color_i, soil_color_o, 'soil color type', nsoilcol, rc) + call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & + 0, nsoilcol, int(soil_color_i), soil_color_o, 'soil color type', ndiag, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Clean up memory @@ -322,84 +317,4 @@ end subroutine mkrank end subroutine get_dominant_soilcol - !=============================================================== - subroutine check_global_sums(mesh_i, mesh_o, mask_i, frac_o, & - soil_color_i, soil_color_o, name, nsoilcol, rc) - - use mkvarctl, only : mpicom, MPI_INTEGER, MPI_MAX - - ! Compare global sums on input and output grids - - ! input/otuput variables - type(ESMF_Mesh) , intent(in) :: mesh_i - type(ESMF_Mesh) , intent(in) :: mesh_o - integer , intent(in) :: mask_i(:) - real(r4) , intent(in) :: frac_o(:) - real(r4) , intent(in) :: soil_color_i(:) - integer , intent(in) :: soil_color_o(:) - character(len=*) , intent(in) :: name - integer , intent(in) :: nsoilcol - integer , intent(out) :: rc - - ! local variables - integer :: ns_i - integer :: ns_o - integer :: ni, no, l, k - integer :: ier - real(r8), allocatable :: area_i(:) - real(r8), allocatable :: area_o(:) - real(r4) :: local_i(0:nsoilcol) ! local global area, by surface type - real(r4) :: local_o(0:nsoilcol) ! local global area, by surface type - real(r4) :: global_i(0:nsoilcol) ! input grid: global area pfts - real(r4) :: global_o(0:nsoilcol) ! output grid: global area pfts - !----------------------------------------------------------------------- - - rc = ESMF_SUCCESS - - ! Determine ns_i and ns_o - call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Get areas from mesh - allocate(area_i(ns_i)) - allocate(area_o(ns_o)) - call get_meshareas(mesh_i, area_i, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call get_meshareas(mesh_o, area_o, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Input grid global area - local_i(:) = 0. - do ni = 1,ns_i - k = int(soil_color_i(ni)) - ! TODO: is this change okay? - ! local_i(k) = local_i(k) + area_i(ni) * mask_i(ni) - local_i(k) = local_i(k) + area_i(ni) - end do - call mpi_reduce(local_i, global_i, nsoilcol+1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) - - ! Output grid global area - local_o(:) = 0. - do no = 1,ns_o - k = int(soil_color_o(no)) - ! TODO: is this change okay? - ! local_o(k) = local_o(k) + area_o(no) * frac_o(no) - local_o(k) = local_o(k) + area_o(no) - end do - call mpi_reduce(local_o, global_o, nsoilcol+1, MPI_REAL4, MPI_SUM, 0, mpicom, ier) - - ! Comparison - if (root_task) then - write(ndiag,*) - write(ndiag,'(a)')'soil color type input grid area output grid area' - write(ndiag,'(a)')' 10**6 km**2 10**6 km**2' - write(ndiag,'(1x,60a1)') ('.',k=1,60) - do k = 0, nsoilcol - write (ndiag,'(a,i3,d16.3,d17.3)') 'class ',k, global_i(k)*1.e-6, global_o(k)*1.e-6 - end do - end if - end subroutine check_global_sums - end module mksoilcolMod diff --git a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 index 2fde396999..a01c9363c6 100644 --- a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 @@ -5,15 +5,14 @@ module mksoilfmaxMod !----------------------------------------------------------------------- use ESMF - use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 - use shr_sys_mod , only : shr_sys_abort - use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths - use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas - use mkutilsMod , only : chkerr - use mkvarpar - use mkvarctl + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 + use mkdiagnosticsMod , only : output_diagnostics_continuous + use mkvarctl , only : ndiag, root_task, soil_fmax_override, unsetsoil + use mkutilsMod , only : chkerr implicit none private ! By default make data private @@ -71,6 +70,7 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) write(ndiag,'(a)') ' Input file is '//trim(file_data_i) write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if + call ESMF_VMLogMemInfo("At start of "//trim(subname)) ! Error check soil_fmax if it is set if ( soil_fmax_override /= unsetsoil )then @@ -84,11 +84,9 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) end if ! Open input data file - call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) ! Read in input mesh - call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) @@ -156,72 +154,24 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) end if enddo - ! ----------------------------------------------------------------- - ! Error check2 ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - -! allocate(areas_i(ns_i)) -! call get_meshareas(mesh_i, areas_i, rc) -! if (ChkErr(rc,__LINE__,u_FILE_u)) return - -! allocate(areas_o(ns_o)) -! call get_meshareas(mesh_o, areas_o, rc) -! if (ChkErr(rc,__LINE__,u_FILE_u)) return - -! gfmax_i = 0. -! garea_i = 0. -! do ni = 1,ns_i -! garea_i = garea_i + areas_i(ni)*re**2 -! gfmax_i = gfmax_i + fmax_i(ni)*(areas_i(ni)/100.) * frac_i(ni)*re**2 -! end do - -! gfmax_o = 0. -! garea_o = 0. -! do no = 1,ns_o -! garea_o = garea_o + areas_o(no)*re**2 -! gfmax_o = gfmax_o + fmax_o(no)*(areas_o(no)/100.) * frac_o(no)*re**2 -! end do -! deallocate(areas_i) -! deallocate(areas_o) - -! ! Diagnostic output -! if (root_task) then -! write (ndiag,*) -! write (ndiag,'(1x,70a1)') ('=',k=1,70) -! write (ndiag,*) 'Maximum Fractional Saturated Area Output' -! write (ndiag,'(1x,70a1)') ('=',k=1,70) - -! write (ndiag,*) -! write (ndiag,'(1x,70a1)') ('.',k=1,70) -! write (ndiag,2001) -! write (ndiag,'(1x,70a1)') ('.',k=1,70) -! write (ndiag,*) -! write (ndiag,2002) gfmax_i*1.e-06,gfmax_o*1.e-06 -! write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 -! 2001 format (1x,'surface type input grid area output grid area'/& -! 1x,' 10**6 km**2 10**6 km**2 ') -! 2002 format (1x,'fmax ',f14.3,f17.3) -! 2004 format (1x,'all surface ',f14.3,f17.3) -! end if + call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + fmax_i, fmax_o, "Maximum Fractional Sataturated output", "unitless", ndiag, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Close the input file call pio_closefile(pioid) - call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) ! Release memory - deallocate (fmax_i) - deallocate (frac_i) - deallocate (frac_o) call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) if (root_task) then write (ndiag,'(a)') 'Successfully made %fmax' end if + call ESMF_VMLogMemInfo("At end of "//trim(subname)) end subroutine mksoilfmax diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 7fafd94908..4bbaf7ba31 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -6,28 +6,24 @@ module mksoiltexMod use ESMF use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 - use shr_sys_mod , only : shr_sys_abort - use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths - use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : get_meshareas - use mkutilsMod , only : chkerr - use mkvarctl - use mkvarpar + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkutilsMod , only : chkerr + use mkdiagnosticsMod , only : output_diagnostics_index + use mkvarctl , only : root_task, ndiag + use mkvarctl , only : unsetsoil, soil_clay_override, soil_sand_override implicit none private ! By default make data private public :: mksoiltex ! Set soil texture - integer, parameter :: num=2 ! set soil mapunit number - integer, parameter :: nlsm=4 ! number of soil textures - - integer :: num_soil_textures + integer :: mapunit_value_max + integer :: num_soil_textures type(ESMF_DynamicMask) :: dynamicMask - integer :: mapunit_value_max - character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -62,28 +58,24 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o integer :: ni,no integer :: ns_i, ns_o integer :: k,l,m,n - character(len=38) :: typ ! soil texture based on ... integer :: nlay ! number of soil layers - integer :: mapunittemp ! temporary igbp soil mapunit - integer :: maxovr integer , allocatable :: mask_i(:) - real(r8), allocatable :: area_i(:) - real(r8), allocatable :: area_o(:) real(r4), allocatable :: rmask_i(:) - real(r4), allocatable :: frac_o(:) + real(r8), allocatable :: frac_o(:) real(r4), allocatable :: sand_i(:,:) ! input grid: percent sand real(r4), allocatable :: clay_i(:,:) ! input grid: percent clay real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits real(r4), pointer :: dataptr(:) real(r8), pointer :: dataptr_r8(:) - character(len=38) :: soil(0:nlsm) ! name of each soil texture - real(r4) :: gast_i(0:nlsm) ! global area, by texture type - real(r4) :: gast_o(0:nlsm) ! global area, by texture type - real(r4) :: sum_fldi ! global sum of dummy input fld - real(r4) :: sum_fldo ! global sum of dummy output fld real(r4) :: sumtex + integer :: mapunit ! temporary igbp soil mapunit + integer, allocatable :: soil_i(:) + integer, allocatable :: soil_o(:) integer :: rcode, ier ! error status integer :: srcTermProcessing_Value = 0 + integer, parameter :: nlsm=4 ! number of soil textures + character(len=38) :: soil(0:nlsm) ! name of each soil texture + character(len=38) :: typ ! soil texture based on ... character(len=*), parameter :: subname = 'mksoiltex' !----------------------------------------------------------------------- @@ -119,20 +111,14 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o if (soil_sand_override /= unsetsoil .and. soil_clay_override /= unsetsoil) then if (root_task) then - write(ndiag,'(a,i8)') ' Overriding soil color for all points with: ', soil_color_override + write(ndiag,'(a,i8)') ' Overriding soil sand for all points with: ', soil_sand_override + write(ndiag,'(a,i8)') ' Overriding soil clay for all points with: ', soil_clay_override end if sand_o(:,:) = soil_sand_override clay_o(:,:) = soil_clay_override RETURN end if - ! Define the model surface types: 0:4 - soil(0) = 'no soil: ocean, glacier, lake, no data' - soil(1) = 'clays ' - soil(2) = 'sands ' - soil(3) = 'loams ' - soil(4) = 'silts ' - ! Open input data file call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) @@ -205,7 +191,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return allocate(frac_o(ns_o)) - frac_o(:) = real(dataptr_r8(:), kind=r4) + frac_o(:) = dataptr_r8(:) ! Create a dynamic mask object ! The dynamic mask object further holds a pointer to the routine that will be called in order to @@ -268,101 +254,80 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o end if end do - ! ----------------------------------------------------------------- - ! TODO: - ! Compare global area of each soil type on input and output grids - ! ----------------------------------------------------------------- - - ! allocate(area_i(ns_i)) - ! call get_meshareas(mesh_i, area_i, rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return - ! allocate(area_o(ns_o)) - ! call get_meshareas(mesh_o, area_o, rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! ! input grid: global areas by texture class - ! gast_i(:) = 0. - ! do l = 1, nlay - ! do ni = 1,ns_i - ! mapunittemp = nint(mapunit_i(ni)) - ! if (mapunittemp==0) then - ! typ = 'no soil: ocean, glacier, lake, no data' - ! else if (clay_i(mapunittemp,l) >= 40.) then - ! typ = 'clays' - ! else if (sand_i(mapunittemp,l) >= 50.) then - ! typ = 'sands' - ! else if (clay_i(mapunittemp,l)+sand_i(mapunittemp,l) < 50.) then - ! if (rmask_i(ni) /= 0.) then - ! typ = 'silts' - ! else !if (mask(ni) == 0.) then no data - ! typ = 'no soil: ocean, glacier, lake, no data' - ! end if - ! else - ! typ = 'loams' - ! end if - ! do m = 0, nlsm - ! if (typ == soil(m)) go to 101 - ! end do - ! write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunittemp,l), & - ! ' clay = ',clay_i(mapunittemp,l), & - ! ' not assigned to soil type for input grid lon,lat,layer = ',ni,l - ! call shr_sys_abort() - ! 101 continue - ! gast_i(m) = gast_i(m) + area_i(ni)*mask_i(ni)*re**2 - ! end do - ! end do - - ! ! output grid: global areas by texture class - ! gast_o(:) = 0. - ! do l = 1, nlay - ! do no = 1,ns_o - ! if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then - ! typ = 'no soil: ocean, glacier, lake, no data' - ! else if (clay_o(no,l) >= 40.) then - ! typ = 'clays' - ! else if (sand_o(no,l) >= 50.) then - ! typ = 'sands' - ! else if (clay_o(no,l)+sand_o(no,l) < 50.) then - ! typ = 'silts' - ! else - ! typ = 'loams' - ! end if - ! do m = 0, nlsm - ! if (typ == soil(m)) go to 102 - ! end do - ! write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & - ! ' clay = ',clay_o(no,l), & - ! ' not assigned to soil type for output grid lon,lat,layer = ',no,l - ! call shr_sys_abort() - ! 102 continue - ! gast_o(m) = gast_o(m) + area_o(no)*frac_o(no)*re**2 - ! end do - ! end do - - ! ! Diagnostic output - - ! write (ndiag,*) - ! write (ndiag,'(1x,70a1)') ('=',l=1,70) - ! write (ndiag,*) 'Soil Texture Output' - ! write (ndiag,'(1x,70a1)') ('=',l=1,70) - ! write (ndiag,*) - - ! write (ndiag,*) 'The following table of soil texture classes is for comparison only.' - ! write (ndiag,*) 'The actual data is continuous %sand, %silt and %clay not textural classes' - ! write (ndiag,*) - - ! write (ndiag,*) - ! write (ndiag,'(1x,70a1)') ('.',l=1,70) - ! write (ndiag,1001) - ! 1001 format (1x,'soil texture class',17x,' input grid area output grid area',/ & - ! 1x,33x,' 10**6 km**2',' 10**6 km**2') - ! write (ndiag,'(1x,70a1)') ('.',l=1,70) - ! write (ndiag,*) - - ! do l = 0, nlsm - ! write (ndiag,'(1x,a38,f16.3,f17.3)') soil(l),gast_i(l)*1.e-6,gast_o(l)*1.e-6 - ! end do + ! Define the model surface types: 0:4 + soil(0) = 'no soil: ocean, glacier, lake, no data' + soil(1) = 'clays ' + soil(2) = 'sands ' + soil(3) = 'loams ' + soil(4) = 'silts ' + + ! input grid: determine soil_i for global area comparison + allocate(soil_i(ns_i)) + do l = 1, nlay + do ni = 1,ns_i + mapunit = nint(mapunit_i(ni)) + if (mapunit==0) then + typ = 'no soil: ocean, glacier, lake, no data' + else if (clay_i(mapunit,l) >= 40.) then + typ = 'clays' + else if (sand_i(mapunit,l) >= 50.) then + typ = 'sands' + else if (clay_i(mapunit,l)+sand_i(mapunit,l) < 50.) then + if (rmask_i(ni) /= 0.) then + typ = 'silts' + else + typ = 'no soil: ocean, glacier, lake, no data' + end if + else + typ = 'loams' + end if + do m = 0, nlsm + if (typ == soil(m)) go to 101 + end do + write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunit,l), & + ' clay = ',clay_i(mapunit,l),' not assigned to soil type for input grid lon,lat,layer = ',ni,l + call shr_sys_abort() +101 continue + soil_i(ni) = m ! allocate memory for this + end do + end do + + ! output grid: determine soil_o for global area comparison + allocate(soil_o(ns_o)) + do l = 1, nlay + do no = 1,ns_o + if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then + typ = 'no soil: ocean, glacier, lake, no data' + else if (clay_o(no,l) >= 40.) then + typ = 'clays' + else if (sand_o(no,l) >= 50.) then + typ = 'sands' + else if (clay_o(no,l)+sand_o(no,l) < 50.) then + typ = 'silts' + else + typ = 'loams' + end if + do m = 0, nlsm + if (typ == soil(m)) go to 102 + end do + write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & + ' clay = ',clay_o(no,l), ' not assigned to soil type for output grid lon,lat,layer = ',no,l + call shr_sys_abort() +102 continue + soil_o(no) = m + end do + end do + + ! Compare global areas + if (root_task) then + write (ndiag,'(a)') 'The following table of soil texture classes is for comparison only.' + write (ndiag,'(a)') 'The actual data is continuous %sand, %silt and %clay not textural classes' + end if + call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & + 0, nlsm, soil_i, soil_o, 'soil texture class', ndiag, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) @@ -371,7 +336,6 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o if (root_task) then write (ndiag,'(a)') 'Successfully made %sand and %clay' - write (ndiag,*) end if end subroutine mksoiltex diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 4e5f0ab4e8..4348c63e40 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -87,14 +87,11 @@ program mksurfdata ! urban_skip_abort_on_invalid_data_check ! ====================================================================== - ! !USES: use ESMF use pio use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs, cl => shr_kind_cl use shr_sys_mod , only : shr_sys_abort -#ifdef TODO use mkVICparamsMod , only : mkVICparams -#endif use mktopostatsMod , only : mktopostats use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array @@ -122,10 +119,13 @@ program mksurfdata use nanMod , only : nan, bigint use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem use mkpioMod , only : mkpio_put_time_slice, mkpio_iodesc_output, mkpio_wopen + use mkinputMod use mkvarctl implicit none +#include + ! indices integer :: k,n ! indices integer :: lsize_o @@ -1575,8 +1575,10 @@ subroutine normalize_and_check_landuse(ns_o) end if end do - if ( nsmall_tot > 0 )then - write (6,*)'number of small pft = ', nsmall_tot + if (root_task) then + if ( nsmall_tot > 0 )then + write(ndiag,*)'number of small pft = ', nsmall_tot + end if end if end subroutine normalize_and_check_landuse diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index 17cb43e284..2ed57d6f2d 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -9,7 +9,6 @@ module mktopostatsMod use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : get_meshareas use mkutilsMod , only : chkerr use mkvarctl , only : ndiag, root_task, mpicom, std_elev diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index a21c33d002..4af0896f80 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -6,16 +6,17 @@ module mkurbanparMod use ESMF use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs - use shr_sys_mod , only : shr_sys_abort - use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkpioMod , only : mkpio_iodesc_output, mkpio_get_dimlengths, mkpio_get_rawdata - use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 - use mkutilsMod , only : chkerr - use mkvarctl , only : root_task, ndiag, ispval, fsurdat, outnc_double - use mkvarctl , only : mpicom, MPI_INTEGER, MPI_MAX - use mkvarpar + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cs => shr_kind_cs + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem + use mkpioMod , only : mkpio_iodesc_output, mkpio_get_rawdata + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 + use mkutilsMod , only : chkerr + use mkvarctl , only : root_task, ndiag, ispval, outnc_double, all_urban + use mkutilsMod , only : normalize_classes_by_gcell + use mkdiagnosticsMod , only : output_diagnostics_index + use mkindexmapMod , only : dim_slice_type, lookup_2d_netcdf + use mkvarpar , only : numrad, numsolar, re implicit none private @@ -103,13 +104,6 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & ! this would also replace the use of normalize_classes_by_gcell, and maybe some other ! urban-specific code. ! - use mkutilsMod , only : normalize_classes_by_gcell - use mkvarctl , only : all_urban - use mkvarpar -#ifdef TODO - !use mkdiagnosticsMod , only : output_diagnostics_index -#endif - ! input/output variables character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name @@ -448,9 +442,6 @@ subroutine mkurbanpar(datfname_i, pioid_o, mesh_o, & ! each parameter) wherever (1) we have a nodata value for region_o, or (2) the parameter ! has nodata for the given region/density combination in the input lookup table. ! - use mkindexmapMod, only : dim_slice_type, lookup_2d_netcdf - use mkvarpar - ! input/output variables character(len=*) , intent(in) :: datfname_i ! input data file name type(file_desc_t) , intent(inout) :: pioid_o ! output file pio id @@ -737,9 +728,7 @@ subroutine lookup_and_check_err(pioid, varname, fill_val, check_invalid, & ! classes. This is why we loop over density class in this routine. ! ! Note: inherits a number of variables from the parent routine - - use mkindexmapMod, only : lookup_2d_netcdf - + ! ! input/output variables type(file_desc_t) , intent(inout) :: pioid character(len=*) , intent(in) :: varname ! name of lookup table @@ -812,8 +801,6 @@ subroutine mkurban_pct_diagnostics(area_i, area_o, mask_i, frac_o, urbn_i, urbn_ ! setting urbn_o to 0 wherever it is less than a certain threshold; the rules for doing ! this can't always be applied inline in mkurban_pct). ! - use mkvarpar - ! input/output variables real(r8) , intent(in) :: area_i(:) real(r8) , intent(in) :: area_o(:) diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index 9c9db98251..3bc4345ed9 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -6,62 +6,16 @@ module mkvarctl use ESMF use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_abort implicit none private -#include - - ! --------------------- - ! routines - ! --------------------- - - public :: read_namelist_input - public :: check_namelist_input - public :: write_namelist_input - - ! --------------------- - ! variables - ! --------------------- - integer, public :: ndiag ! output log unit logical, public :: root_task ! proc 0 logical for printing msgs integer, public :: iam ! processor number integer, public :: npes ! number of processors integer, public :: mpicom ! communicator group - ! Values from mpif.h that will be used - public :: MPI_INTEGER - public :: MPI_REAL8 - public :: MPI_LOGICAL - public :: MPI_CHARACTER - public :: MPI_COMM_WORLD - public :: MPI_MAX - public :: MPI_SUCCESS - - real(r8), public, parameter :: spval = 1.e36 ! special value - integer, public, parameter :: ispval = -9999 ! special value - integer , public, parameter :: unsetcol = -999 ! flag to indicate soil color NOT set - real(r8), public, parameter :: unsetsoil = -999.99_r8 ! Flag to signify soil texture override not set - - integer , public :: soil_color_override - real(r8), public :: soil_sand_override - real(r8), public :: soil_clay_override - real(r8), public :: soil_fmax_override - - character(len=256) , public :: fgrddat ! grid data file - character(len=256) , public :: fsurdat ! output surface data file name (if blank, do not output a surface dataset) - character(len=256) , public :: fsurlog ! output surface log file name - character(len=256) , public :: fdyndat ! dynamic landuse data file name - character(len=256) , public :: fhrvname ! generic harvest filename - logical , public :: all_veg ! if gridcell will be 100% vegetated land-cover - real(r8) , public :: std_elev = -999.99_r8 ! Standard deviation of elevation (m) to use for ent - - ! NOTE(bja, 2015-01) added to work around a ?bug? causing 1x1_urbanc_alpha to abort. See - !/glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 - logical, public :: urban_skip_abort_on_invalid_data_check - logical, public :: outnc_large_files ! output files in 64-bit format for large files logical, public :: outnc_double ! output ALL data in files as 64-bit integer, public :: outnc_dims = 2 ! only applicable to lat/lon grids @@ -69,450 +23,23 @@ module mkvarctl logical, public :: outnc_vic ! true => output VIC fields logical, public :: outnc_3dglc ! true => output 3D glacier fields - character(len= 32), public :: mksrf_gridnm = ' ' ! name of grid to use on output file - character(len=512), public :: mksrf_gridtype = ' ' ! land gridtype, global or reg - character(len=512), public :: mksrf_fgrid_mesh = ' ' ! land grid file name to use - integer , public :: mksrf_fgrid_mesh_nx - integer , public :: mksrf_fgrid_mesh_ny - - character(len=512), public :: mksrf_fvegtyp = ' ' ! vegetation data file name - character(len=512), public :: mksrf_fvegtyp_mesh = ' ' ! vegetation mesh file name - - character(len=512), public :: mksrf_fhrvtyp = ' ' ! harvest data file name - character(len=512), public :: mksrf_fhrvtyp_mesh = ' ' ! harvest mesh file name - - character(len=512), public :: mksrf_forganic = ' ' ! organic matter data file name - character(len=512), public :: mksrf_forganic_mesh = ' ' ! organic matter mesh file name - - character(len=512), public :: mksrf_fsoicol = ' ' ! soil color data file name - character(len=512), public :: mksrf_fsoicol_mesh = ' ' ! soil color mesh file name - - character(len=512), public :: mksrf_fsoitex = ' ' ! soil texture data file name - character(len=512), public :: mksrf_fsoitex_mesh = ' ' ! soil texture mesh file name - - character(len=512), public :: mksrf_fmax = ' ' ! fmax data file name - character(len=512), public :: mksrf_fmax_mesh = ' ' ! fmax mesh file name - - character(len=512), public :: mksrf_fsoildepth = ' ' ! soil depth file name - character(len=512), public :: mksrf_fsoildepth_mesh = ' ' ! soil depth file name - - character(len=512), public :: mksrf_fabm = ' ' ! ag fire peak month and - character(len=512), public :: mksrf_fabm_mesh = ' ' ! ag fire peak month and - - character(len=512), public :: mksrf_fpeat = ' ' ! peatlands and - character(len=512), public :: mksrf_fpeat_mesh = ' ' ! peatlands and - - character(len=512), public :: mksrf_fgdp = ' ' ! gdp data file names - character(len=512), public :: mksrf_fgdp_mesh = ' ' ! gdp mesh file names - - character(len=512), public :: mksrf_flakwat = ' ' ! inland lake data file name - character(len=512), public :: mksrf_flakwat_mesh = ' ' ! inland lake mesh file name - - character(len=512), public :: mksrf_fwetlnd = ' ' ! inland wetlands data file name - character(len=512), public :: mksrf_fwetlnd_mesh = ' ' ! inland wetlands mesh file name - - character(len=512), public :: mksrf_furban = ' ' ! urban data file name - character(len=512), public :: mksrf_furban_mesh = ' ' ! urban mesh file name - - character(len=512), public :: mksrf_fglacier = ' ' ! glacier data file name - character(len=512), public :: mksrf_fglacier_mesh = ' ' ! glacier mesh file name - - character(len=512), public :: mksrf_fglacierregion = ' ' ! glacier region data file name - character(len=512), public :: mksrf_fglacierregion_mesh = ' ' ! glacier region mesh file name - - character(len=512), public :: mksrf_furbtopo = ' ' ! urban topography data file name - character(len=512), public :: mksrf_furbtopo_mesh = ' ' ! urban topography mesh file name - - character(len=512), public :: mksrf_flai = ' ' ! lai data filename - character(len=512), public :: mksrf_flai_mesh = ' ' ! lai mesh filename - - character(len=512), public :: mksrf_fdynuse = ' ' ! ascii file containing names of dynamic land use files - character(len=512), public :: mksrf_fdynuse_mesh = ' ' ! ascii file containing names of dynamic land use files - - character(len=512), public :: mksrf_fvocef = ' ' ! VOC Emission Factor data file name - character(len=512), public :: mksrf_fvocef_mesh = ' ' ! VOC Emission Factor mesh file name - - character(len=512), public :: mksrf_ftopostats = ' ' ! topography statistics data file name - character(len=512), public :: mksrf_ftopostats_mesh = ' ' ! topography statistics mesh file name - - character(len=512), public :: mksrf_fvic = ' ' ! VIC parameters data file name - character(len=512), public :: mksrf_fvic_mesh = ' ' ! VIC parameters mesh file name - - character(len=512), public :: mksrf_irrig = ' ' ! TODO: should this namelist be here? - character(len=512), public :: mksrf_irrig_mesh = ' ' ! TODO: should this namelist be here? + integer , public :: soil_color_override + real(r8), public :: soil_sand_override + real(r8), public :: soil_clay_override + real(r8), public :: soil_fmax_override - integer , public :: numpft = 16 ! number of plant types + integer, public :: numpft = 16 ! number of plant types ! Variables to override data read in with ! (all_urban is mostly for single-point mode, but could be used for sensitivity studies) - logical, public :: all_urban ! output ALL data as 100% covered in urban - logical, public :: no_inlandwet ! set wetland to 0% over land; wetland will only be used for ocean points - - character(len=*) , parameter :: u_FILE_u = & - __FILE__ - -!=============================================================== -contains -!=============================================================== - - subroutine read_namelist_input(filename) - - ! Read in input namelist - - ! input/output variables - character(len=*), intent(in) :: filename - - ! local variables - integer :: ier - integer :: fileunit - logical :: lexist - character(len=*), parameter :: subname = 'read_namelist_input' - ! ------------------------------------------------------------ - - namelist /mksurfdata_input/ & - mksrf_fvegtyp, & - mksrf_fvegtyp_mesh, & - mksrf_fhrvtyp, & - mksrf_fhrvtyp_mesh, & - mksrf_fsoitex, & - mksrf_fsoitex_mesh, & - mksrf_forganic, & - mksrf_forganic_mesh, & - mksrf_fsoicol, & - mksrf_fsoicol_mesh, & - mksrf_fvocef, & - mksrf_fvocef_mesh, & - mksrf_flakwat, & - mksrf_flakwat_mesh, & - mksrf_fwetlnd, & - mksrf_fwetlnd_mesh, & - mksrf_fglacier, & - mksrf_fglacier_mesh, & - mksrf_fglacierregion, & - mksrf_fglacierregion_mesh, & - mksrf_furbtopo, & - mksrf_furbtopo_mesh, & - mksrf_fmax, & - mksrf_fmax_mesh, & - mksrf_furban, & - mksrf_furban_mesh, & - mksrf_flai, & - mksrf_flai_mesh, & - mksrf_fdynuse, & - mksrf_fdynuse_mesh, & - mksrf_fgdp, & - mksrf_fgdp_mesh, & - mksrf_fpeat, & - mksrf_fpeat_mesh, & - mksrf_fsoildepth, & - mksrf_fsoildepth_mesh, & - mksrf_fabm, & - mksrf_fabm_mesh, & - mksrf_ftopostats, & - mksrf_ftopostats_mesh, & - mksrf_fvic, & - mksrf_fvic_mesh, & - mksrf_fgrid_mesh, & - mksrf_fgrid_mesh_nx, & - mksrf_fgrid_mesh_ny, & - numpft, & - all_veg, & - all_urban, & - no_inlandwet, & - soil_color_override, & - soil_sand_override, & - soil_clay_override, & - soil_fmax_override, & -#ifdef TODO - nglcec, & - pft_idx, & - pft_frc, & - gitdescribe, & -#endif - outnc_large_files, & - outnc_double, & - outnc_dims, & - outnc_vic, & - outnc_3dglc, & - fsurdat, & - fdyndat, & - fsurlog, & - std_elev, & - urban_skip_abort_on_invalid_data_check - - ! Set default namelist values - make these the defaults in gen_mksurfdata_namelist.py - mksrf_gridtype = 'global' - outnc_large_files = .false. - outnc_double = .true. - outnc_vic = .false. - outnc_3dglc = .false. - all_urban = .false. - all_veg = .false. - no_inlandwet = .true. - soil_color_override = unsetcol - soil_sand_override = unsetsoil - soil_clay_override = unsetsoil - soil_fmax_override = unsetsoil - urban_skip_abort_on_invalid_data_check = .false. ! default value for bug work around - - if (root_task) then - write(6,*) 'Attempting to initialize control settings .....' - end if - - if (root_task) then - inquire (file=trim(filename), exist=lexist) - if (.not. lexist) then - call shr_sys_abort(subname//trim(filename)//' does not exist') - end if - open(newunit=fileunit, status="old", file=trim(filename)) - read(fileunit, nml=mksurfdata_input, iostat=ier) - if (ier > 0) then - call shr_sys_abort(subname//' error reading in mksurfdata_input namelist from '//trim(filename)) - end if - close(fileunit) - end if - - call mpi_bcast (mksrf_fgrid_mesh, len(mksrf_fgrid_mesh), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fgrid_mesh_nx, 1, MPI_INTEGER, 0, mpicom, ier) - call mpi_bcast (mksrf_fgrid_mesh_ny, 1, MPI_INTEGER, 0, mpicom, ier) - - call mpi_bcast (mksrf_fvegtyp, len(mksrf_fvegtyp), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fvegtyp_mesh, len(mksrf_fvegtyp_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_fhrvtyp, len(mksrf_fhrvtyp), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fhrvtyp_mesh, len(mksrf_fhrvtyp_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_fsoitex, len(mksrf_fsoitex), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fsoitex_mesh, len(mksrf_fsoitex_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_fmax, len(mksrf_fmax), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fmax_mesh, len(mksrf_fmax_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_forganic, len(mksrf_forganic), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_forganic_mesh, len(mksrf_forganic_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_fsoicol, len(mksrf_fsoicol), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fsoicol_mesh, len(mksrf_fsoicol_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_fsoildepth, len(mksrf_fsoildepth), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fsoildepth_mesh, len(mksrf_fsoildepth_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_fabm, len(mksrf_fabm), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fabm_mesh, len(mksrf_fabm_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_fpeat, len(mksrf_fpeat), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fpeat_mesh, len(mksrf_fpeat_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_fgdp, len(mksrf_fgdp), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fgdp_mesh, len(mksrf_fgdp_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_flakwat, len(mksrf_flakwat), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_flakwat_mesh, len(mksrf_flakwat_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_fwetlnd, len(mksrf_fwetlnd), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fwetlnd_mesh, len(mksrf_fwetlnd_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_furban, len(mksrf_furban), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_furban_mesh, len(mksrf_furban_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_furbtopo, len(mksrf_furbtopo), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_furbtopo_mesh, len(mksrf_furbtopo_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_fglacier, len(mksrf_fglacier), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fglacier_mesh, len(mksrf_fglacier_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_fglacierregion, len(mksrf_fglacierregion), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fglacierregion_mesh, len(mksrf_fglacierregion_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_flai, len(mksrf_flai), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_flai_mesh, len(mksrf_flai_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_fvocef, len(mksrf_fvocef), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fvocef_mesh, len(mksrf_fvocef_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_ftopostats, len(mksrf_ftopostats), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_ftopostats_mesh, len(mksrf_ftopostats_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_fvic, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fvic_mesh, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (mksrf_fdynuse, len(mksrf_fdynuse), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fdynuse_mesh, len(mksrf_fdynuse_mesh), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (fsurdat, len(fsurdat), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (fdyndat, len(fdyndat), MPI_CHARACTER, 0, mpicom, ier) - - call mpi_bcast (outnc_dims, 1, MPI_INTEGER, 0, mpicom, ier) - call mpi_bcast (outnc_large_files, 1, MPI_LOGICAL, 0, mpicom, ier) - call mpi_bcast (outnc_double, 1, MPI_LOGICAL, 0, mpicom, ier) - call mpi_bcast (outnc_1d, 1, MPI_LOGICAL, 0, mpicom, ier) - call mpi_bcast (outnc_vic, 1, MPI_LOGICAL, 0, mpicom, ier) - call mpi_bcast (outnc_3dglc, 1, MPI_LOGICAL, 0, mpicom, ier) - - call mpi_bcast (all_urban, 1, MPI_LOGICAL, 0, mpicom, ier) - call mpi_bcast (all_veg, 1, MPI_LOGICAL, 0, mpicom, ier) - call mpi_bcast (no_inlandwet, 1, MPI_LOGICAL, 0, mpicom, ier) - call mpi_bcast (soil_color_override, 1, MPI_INTEGER, 0, mpicom, ier) - call mpi_bcast (soil_sand_override, 1, MPI_REAL, 0, mpicom, ier) - call mpi_bcast (soil_clay_override, 1, MPI_REAL, 0, mpicom, ier) - call mpi_bcast (soil_fmax_override, 1, MPI_REAL, 0, mpicom, ier) - - call mpi_bcast (urban_skip_abort_on_invalid_data_check, 1, MPI_LOGICAL, 0, mpicom, ier) - - call mpi_bcast (numpft, 1, MPI_INTEGER, 0, mpicom, ier) - call mpi_bcast (std_elev, 1, MPI_REAL, 0, mpicom, ier) - - end subroutine read_namelist_input - - !=============================================================== - subroutine check_namelist_input() - - ! error check on namelist input - if (mksrf_fgrid_mesh /= ' ')then - fgrddat = mksrf_fgrid_mesh - else - call shr_sys_abort(" must specify mksrf_fgrid_mesh") - endif - - if (trim(mksrf_gridtype) /= 'global' .and. trim(mksrf_gridtype) /= 'regional') then - call shr_sys_abort(" mksrf_gridtype "//trim(mksrf_gridtype)//" is not supported") - endif - -#ifdef TODO - if (nglcec <= 0) then - call shr_sys_abort('nglcec must be at least 1') - end if -#endif - - if (mksrf_fgrid_mesh_ny == 1) then - outnc_1d = .true. - outnc_dims = 1 - else - outnc_1d = .false. - outnc_dims = 2 - end if - - end subroutine check_namelist_input - - !=============================================================== - subroutine write_namelist_input() - - ! Note - need to call this after ndiag has been set - - if (root_task) then - write(ndiag,'(a)')'Input rawdata files and corresponding meshes' - write(ndiag,'(a)')' PFTs from: '//trim(mksrf_fvegtyp) - write(ndiag,'(a)')' mesh for pft '//trim(mksrf_fvegtyp_mesh) - write(ndiag,*) - write(ndiag,'(a)')' inland lake from: '//trim(mksrf_flakwat) - write(ndiag,'(a)')' mesh for lake water '//trim(mksrf_flakwat_mesh) - write(ndiag,*) - write(ndiag,'(a)')' inland wetland from: '//trim(mksrf_fwetlnd) - write(ndiag,'(a)')' mesh for wetland '//trim(mksrf_fwetlnd_mesh) - write(ndiag,*) - write(ndiag,'(a)')' soil texture from: '//trim(mksrf_fsoitex) - write(ndiag,'(a)')' mesh for soil texture '//trim(mksrf_fsoitex_mesh) - write(ndiag,*) - write(ndiag,'(a)')' soil organic from: '//trim(mksrf_forganic) - write(ndiag,'(a)')' mesh for soil organic '//trim(mksrf_forganic_mesh) - write(ndiag,*) - write(ndiag,'(a)')' soil color from: '//trim(mksrf_fsoicol) - write(ndiag,'(a)')' mesh for soil color '//trim(mksrf_fsoicol_mesh) - write(ndiag,*) - write(ndiag,'(a)')' fmax from: '//trim(mksrf_fmax) - write(ndiag,'(a)')' mesh for fmax '//trim(mksrf_fmax_mesh) - write(ndiag,*) - write(ndiag,'(a)')' soil depth from: '//trim(mksrf_fsoildepth) - write(ndiag,'(a)')' mesh for soil depth '//trim(mksrf_fsoildepth_mesh) - write(ndiag,*) - write(ndiag,'(a)')' VOC emission factors from: '//trim(mksrf_fvocef) - write(ndiag,'(a)')' mesh for VOC pct emis '//trim(mksrf_fvocef_mesh) - write(ndiag,*) - write(ndiag,'(a)')' gdp from: '//trim(mksrf_fgdp) - write(ndiag,'(a)')' mesh for gdp '//trim(mksrf_fgdp_mesh) - write(ndiag,*) - write(ndiag,'(a)')' peat from: '//trim(mksrf_fpeat) - write(ndiag,'(a)')' mesh for peatlands '//trim(mksrf_fpeat_mesh) - write(ndiag,*) - write(ndiag,'(a)')' harvest from: '//trim(mksrf_fhrvtyp) - write(ndiag,'(a)')' mesh for harvest '//trim(mksrf_fhrvtyp_mesh) - write(ndiag,*) - write(ndiag,'(a)')' topography statistics from: '//trim(mksrf_ftopostats) - write(ndiag,'(a)')' mesh for topography stats '//trim(mksrf_ftopostats_mesh) - write(ndiag,*) - write(ndiag,'(a)')' glaciers from: '//trim(mksrf_fglacier) -#ifdef TODO - write(ndiag,'(a)')' with: '// nglcec, ' glacier elevation classes' -#endif - write(ndiag,'(a)')' mesh for glacier '//trim(mksrf_fglacier_mesh) - write(ndiag,'(a)')' glacier region ID from: '//trim(mksrf_fglacierregion) - write(ndiag,'(a)')' mesh for glacier region '//trim(mksrf_fglacierregion_mesh) - write(ndiag,*) - write(ndiag,'(a)')' urban from: '//trim(mksrf_furban) - write(ndiag,'(a)')' mesh for urban '//trim(mksrf_furban_mesh) - write(ndiag,*) - write(ndiag,'(a)')' urban topography from: '//trim(mksrf_furbtopo) - write(ndiag,'(a)')' mesh for urban topography '//trim(mksrf_furbtopo_mesh) - write(ndiag,*) - write(ndiag,'(a)')' mesh for lai/sai '//trim(mksrf_flai_mesh) - write(ndiag,'(a)')' mesh for ag fire pk month '//trim(mksrf_fabm_mesh) - write(ndiag,*) - write(ndiag,'(a)')' abm from: '//trim(mksrf_fabm) - write(ndiag,*) - write(ndiag,'(a)')' VIC parameters from: '//trim(mksrf_fvic) - write(ndiag,'(a)')' mesh for VIC parameters '//trim(mksrf_fvic_mesh) - write(ndiag,*) - if (mksrf_fdynuse /= ' ') then - write(ndiag,'(a)')' mksrf_fdynuse = '//trim(mksrf_fdynuse) - end if - write(ndiag,*) - write(ndiag,'(a)')'Model grid configuration variables' - write(ndiag,'(a)')' mksrf_fgrid_mesh = '//trim(mksrf_fgrid_mesh) - write(ndiag,'(a,i8)')' nlon= ',mksrf_fgrid_mesh_nx - write(ndiag,'(a,i8)')' nlat= ',mksrf_fgrid_mesh_ny - write(ndiag,'(a)')' mksrf_gridtype = '//trim(mksrf_gridtype) - write(ndiag,*) - write(ndiag,'(a)')'Output configuration variables' - if (outnc_1d) then - write(ndiag,'(a)')' output file is 1d format' - else - write(ndiag,'(a)')' output file is 2d lat/lon format' - end if - if ( outnc_large_files ) then - write(ndiag,'(a)')' Output file in NetCDF 64-bit large_files format' - end if - if ( outnc_double )then - write(ndiag,'(a)')' Output ALL data in file as 64-bit' - else - write(ndiag,'(a)')' Output ALL data in file as 32-bit' - end if - if ( outnc_vic )then - write(ndiag,'(a)')' Output VIC fields' - end if - if ( outnc_3dglc )then - write(ndiag,'(a)')' Output optional 3D glacier fields (mostly used for verification of the glacier model)' - end if - if ( all_urban )then - write(ndiag,'(a)') ' all_urban is true => Output ALL data in file as 100% urban' - else - write(ndiag,'(a)') ' all_urban is false ' - end if - if ( no_inlandwet )then - write(ndiag,'(a)') ' no_inlandwet is true => Set wetland to 0% over land' - else - write(ndiag,'(a)') ' no_inlandwet is false' - end if - if (all_veg) then - write(ndiag,'(a)') ' all_veg is true => Output ALL data in file as 100% vegetated' - else - write(ndiag,'(a)') ' all_veg is false ' - end if - if (urban_skip_abort_on_invalid_data_check) then - write(ndiag, '(a)') " WARNING: aborting on invalid data check in urban has been disabled!" - write(ndiag, '(a)') " WARNING: urban data may be invalid!" - end if - end if - - end subroutine write_namelist_input + logical , public :: all_urban ! output ALL data as 100% covered in urban + logical , public :: all_veg ! if gridcell will be 100% vegetated land-cover + logical , public :: no_inlandwet ! set wetland to 0% over land; wetland will only be used for ocean points + real(r8) , public :: std_elev = -999.99_r8 ! Standard deviation of elevation (m) to use for ent + + real(r8), public, parameter :: spval = 1.e36 ! special value + integer, public, parameter :: ispval = -9999 ! special value + integer , public, parameter :: unsetcol = -999 ! flag to indicate soil color NOT set + real(r8), public, parameter :: unsetsoil = -999.99_r8 ! Flag to signify soil texture override not set end module mkvarctl diff --git a/tools/mksurfdata_esmf/src/mkvocefMod.F90 b/tools/mksurfdata_esmf/src/mkvocefMod.F90 index 5510995fe1..6848102106 100644 --- a/tools/mksurfdata_esmf/src/mkvocefMod.F90 +++ b/tools/mksurfdata_esmf/src/mkvocefMod.F90 @@ -9,12 +9,10 @@ module mkvocefMod use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata - use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas + use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_iosystem + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr - use mkvarctl , only : root_task, ndiag, mpicom, MPI_INTEGER, MPI_MAX - use mkvarctl , only : soil_color_override, unsetcol - use mkvarpar , only : re + use mkvarctl , only : root_task, ndiag, mpicom, soil_color_override, unsetcol implicit none private diff --git a/tools/mksurfdata_esmf/src/shr_sys_mod.F90 b/tools/mksurfdata_esmf/src/shr_sys_mod.F90 index 9ce6b48d4d..56421a37e3 100644 --- a/tools/mksurfdata_esmf/src/shr_sys_mod.F90 +++ b/tools/mksurfdata_esmf/src/shr_sys_mod.F90 @@ -5,33 +5,47 @@ module shr_sys_mod implicit none private +#include + public :: shr_sys_getenv ! get an environment variable public :: shr_sys_abort ! abort a program - integer :: s_loglev = 0 - integer :: s_logunit = 6 - !=============================================================================== CONTAINS !=============================================================================== - subroutine shr_sys_abort(string,rc) + subroutine shr_sys_abort(message, file, line) - !------------------------------------------------------------------------------- - ! PURPOSE: consistent stopping mechanism - !------------------------------------------------------------------------------- + ! Parallel emergency stop - character(len=*) , optional :: string ! error message string - integer , optional :: rc ! error code - - ! local variables - character(*),parameter :: subName = '(shr_sys_abort) ' - character(*),parameter :: F00 = "('(shr_sys_abort) ',4a)" - - if (len_trim(string) > 0) write(s_logunit,F00) 'ERROR: '//trim(string) - write(s_logunit,F00) 'WARNING: stopping' - call abort() - stop + ! input/output variables + character(len=*), optional, intent(in) :: message + character(len=*), optional, intent(in) :: file + integer, optional, intent(in) :: line + + ! Local variables + integer :: rc + integer :: ier + character(len=SHR_KIND_CL):: abort_msg + + if (.not. present(message)) then + rc = 1001 + call mpi_abort(MPI_COMM_WORLD, rc, ier) + else + if (present(file) .and. present(line)) then + write(abort_msg, '(4a,i0)') trim(message),' at ',trim(file),':',line + else if (present(file)) then + write(abort_msg, '(3a)') trim(message),' at ',trim(file) + else if (present(line)) then + write(abort_msg, '(2a,i0)') trim(message),' on line ',line + else + write(abort_msg, '(a)') trim(message) + end if + + write(6,*) trim(message) + rc = 1001 + call mpi_abort(MPI_COMM_WORLD, rc, ier) + end if end subroutine shr_sys_abort @@ -43,9 +57,9 @@ subroutine shr_sys_getenv(name, val, rcode) !------------------------------------------------------------------------------- ! input/output variables - character(len=*) ,intent(in) :: name ! env var name - character(len=*) ,intent(inout) :: val ! env var value - integer ,intent(out) :: rcode ! return code + character(len=*) ,intent(in) :: name ! env var name + character(len=*) ,intent(inout) :: val ! env var value + integer ,intent(inout) :: rcode ! return code !----- local ----- integer :: lenname ! length of env var name @@ -70,7 +84,7 @@ subroutine shr_sys_getenv(name, val, rcode) #else - write(s_logunit,F00) 'ERROR: no implementation of getenv for this architecture' + write(6,F00) 'ERROR: no implementation of getenv for this architecture' call shr_sys_abort(subname//'no implementation of getenv for this machine') #endif From 3a9997538cd1ccc4012d9d9b74a0106519f559cb Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 20 Feb 2022 11:22:05 -0700 Subject: [PATCH 069/614] fixed problem with urban output at ne30 and ne120 --- tools/mksurfdata_esmf/run/mksurfdata_in | 8 +++---- tools/mksurfdata_esmf/run/run_mksurfdata | 8 +++---- tools/mksurfdata_esmf/src/mkindexmapMod.F90 | 2 +- tools/mksurfdata_esmf/src/mkpioMod.F90 | 24 ++++++++++++--------- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 21 ++++++++++++------ 5 files changed, 38 insertions(+), 25 deletions(-) diff --git a/tools/mksurfdata_esmf/run/mksurfdata_in b/tools/mksurfdata_esmf/run/mksurfdata_in index 5992c754ec..e44459426d 100644 --- a/tools/mksurfdata_esmf/run/mksurfdata_in +++ b/tools/mksurfdata_esmf/run/mksurfdata_in @@ -37,11 +37,11 @@ mksrf_fvegtyp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc' mksrf_fhrvtyp = '/glade/work/mvertens/ctsm.toolchain/tools/mksurfdata_esmf/run/mksrf_landuse_histclm50_LUH2_2000.cdf5.c170629.nc' mksrf_fhrvtyp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc' - mksrf_fgrid_mesh = '/glade/p/cesm/cseg/inputdata/share/meshes/ne120np4_ESMFmesh_cdf5_c20211018.nc' - mksrf_fgrid_mesh_nx = 777602 + mksrf_fgrid_mesh = '/glade/p/cesm/cseg/inputdata/share/meshes/ne30np4_ESMFmesh_cdf5_c20211018.nc' + mksrf_fgrid_mesh_nx = 48602 mksrf_fgrid_mesh_ny = 1 - fsurdat = 'surfdata_ne120np4_hist_78pfts_CMIP6_2000_c220219.nc' - fsurlog = 'surfdata_ne120np4_hist_78pfts_CMIP6_2000_c220219.log' + fsurdat = 'surfdata_ne30np4_hist_78pfts_CMIP6_2000_c220219.nc' + fsurlog = 'surfdata_ne30np4_hist_78pfts_CMIP6_2000_c220219.log' outnc_double = .true. all_urban = .false. no_inlandwet = .true. diff --git a/tools/mksurfdata_esmf/run/run_mksurfdata b/tools/mksurfdata_esmf/run/run_mksurfdata index 048dd62a1f..b1a688d613 100755 --- a/tools/mksurfdata_esmf/run/run_mksurfdata +++ b/tools/mksurfdata_esmf/run/run_mksurfdata @@ -7,8 +7,8 @@ ##PBS -l select=1:ncpus=36:mpiprocs=36 ##PBS -l select=4:ncpus=36:mpiprocs=36 ##PBS -l select=16:ncpus=36:mpiprocs=9 -##PBS -l select=24:ncpus=36:mpiprocs=12 -#PBS -l select=32:ncpus=36:mpiprocs=12 +#PBS -l select=24:ncpus=36:mpiprocs=12 +##PBS -l select=32:ncpus=36:mpiprocs=12 # note for -l input above @@ -23,5 +23,5 @@ mkdir -p $TMPDIR # -np {total_tasks} #mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata -#mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata -mpiexec_mpt -p "%g:" -np 384 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata +mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata +#mpiexec_mpt -p "%g:" -np 384 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata diff --git a/tools/mksurfdata_esmf/src/mkindexmapMod.F90 b/tools/mksurfdata_esmf/src/mkindexmapMod.F90 index c6de73f9a1..e653a752e0 100644 --- a/tools/mksurfdata_esmf/src/mkindexmapMod.F90 +++ b/tools/mksurfdata_esmf/src/mkindexmapMod.F90 @@ -158,7 +158,7 @@ subroutine lookup_2d(index1, index2, lookup_table, fill_val, data, ierr, & ! index out of range if (i1 <= 0 .or. i1 > table_n1 .or. & - i2 <= 0 .or. i2 > table_n2) then + i2 <= 0 .or. i2 > table_n2) then data(n) = fill_val if (ierr == 0) ierr = 2 cycle diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 45d8ddcaf7..fa5d80c8f5 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -1,7 +1,7 @@ module mkpioMod - use ESMF ! TODO: put in only statements - use pio ! TODO: put in only statements + use ESMF + use pio use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 use shr_kind_mod , only : i2 => shr_kind_i2, i4 => shr_kind_i4 use shr_kind_mod , only : cl => shr_kind_cl, cs => shr_kind_cs @@ -509,7 +509,7 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, else write(6,*)' ndims = ',ndims write(6,*)' unlimited_dim = ',unlimited_dim - call shr_sys_abort('for lon/lat support up to 3 spatial dims plus a time dim') + call shr_sys_abort('for lon/lat support up to 3 input spatial dims plus a time dim') end if else call shr_sys_abort('rawdata input for variable '//trim(varname)//' must have ndims either 1,2,3 or 4') @@ -631,7 +631,7 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) ' with dim(1) = ',dimlens(1) end if else - call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof3d, pio_iodesc) if (root_task) then write(ndiag,'(a,i8,i8)') ' set iodesc for output data: '//trim(varname)//& ' with dim(1),dim(2) = ',dimlens(1),dimlens(2) @@ -639,13 +639,17 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) end if else if (ndims == 3) then if (unlimited_dim) then - call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof3d, pio_iodesc) + if (root_task) then + write(ndiag,'(a,i8,i8)') ' set iodesc for output data with time dim: '//trim(varname)//& + ' with dim(1),dim(2) = ',dimlens(1),dimlens(2) + end if else - call shr_sys_abort('support on 2 dimensions in addition to a time dimension when outnc_1d is true') - end if - if (root_task) then - write(ndiag,'(a,i8,i8)') ' set iodesc for output data with time dim: '//trim(varname)//& - ' with dim(1),dim(2) = ',dimlens(1),dimlens(2) + call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) + if (root_task) then + write(ndiag,'(a,i8,i8,i8)') ' set iodesc for output data: '//trim(varname)//& + ' with dim(1),dim(2),dim(3) = ',dimlens(1),dimlens(2),dimlens(3) + end if end if end if else diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 4af0896f80..da62d28133 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -754,12 +754,20 @@ subroutine lookup_and_check_err(pioid, varname, fill_val, check_invalid, & ! some of which may have invalid entries. Because doing so disables some error ! checking, we do our own error checking after the call. - call lookup_2d_netcdf(pioid, varname, .true., & - 'density_class', 'region', n_extra_dims, & - unity_dens_o(:,k), region_o, fill_val, data(:,k), ierr, & - extra_dims=extra_dims, nodata=index_nodata, & - invalid_okay=.true.) - + call lookup_2d_netcdf(pioid = pioid, & + tablename = varname, & + lookup_has_invalid = .true., & + dimname1 = 'density_class', & + dimname2 = 'region', & + n_extra_dims = n_extra_dims, & + index1 = unity_dens_o(:,k), & + index2 = region_o, & + fill_val = fill_val, & + data = data(:,k), & + ierr = ierr, & + extra_dims= extra_dims, & + nodata = index_nodata, & + invalid_okay = .true.) if (ierr /= 0) then write(6,*) modname//':'//subname//' ERROR in lookup_2d_netcdf for ', & trim(varname), ' class', k, ': err=', ierr @@ -791,6 +799,7 @@ end subroutine lookup_and_check_err end subroutine mkurbanpar + !=============================================================== subroutine mkurban_pct_diagnostics(area_i, area_o, mask_i, frac_o, urbn_i, urbn_o, dens_class) ! ! print diagnostics related to pct urban From 4c9f5791399bae9effd5155ea80a3caeae4c2d6e Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 20 Feb 2022 23:13:29 -0700 Subject: [PATCH 070/614] updated python script and xml file --- .../gen_mksurfdata_namelist.py | 53 +++++++++++++------ .../gen_mksurfdata_namelist.xml | 1 + tools/mksurfdata_esmf/src/mksurfdata.F90 | 3 +- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index ab86f941aa..876ded4648 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -152,6 +152,18 @@ def get_parser(): required=False, default="4x5", ) + parser.add_argument( + "--merge_gis", + help=""" + If you want to use the glacier dataset that merges in + the Greenland Ice Sheet data that CISM uses (typically + used only if consistency with CISM is important) + """, + action="store", + dest="merge_gis", + choices=["on","off"], + default="off", + ) return parser def main (): @@ -169,6 +181,7 @@ def main (): end_year = args.end_year potveg = args.potveg_flag glc_nec = args.glc_nec + merge_gis = args.merge_gis # determine pft_years - needed to parse xml file if start_year == 1850 and end_year == 1850: @@ -201,9 +214,7 @@ def main (): attribute_list = {'hires_pft':hires_pft, 'pft_years':pft_years, 'ssp_rcp':ssp_rcp, - 'mergeGIS':'of'} - - # TODO: add an argument for mergeGIS + 'mergeGIS':merge_gis} # create dictionary for raw data files names rawdata_files = {} @@ -295,8 +306,7 @@ def main (): landuse_input_fname = file1.replace("%y",str(start_year)) if not os.path.isfile(landuse_input_fname): logger.warning(f"landunit_input_fname: {landuse_input_fname}") - # TODO: make the space/tab exactly the same as pl code: - landuse_line = landuse_input_fname + "\t\t\t" + str(year) + "\n" + landuse_line = f"{landuse_input_fname:<196}{str(year)}\n" # -- Each line is written twice in the original pl code: landuse_file.write(landuse_line) landuse_file.write(landuse_line) @@ -319,8 +329,13 @@ def main (): fsurlog = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.log" fdyndat = f"landuse.timeseries_{res}_{ssp_rcp}_{num_pft}_CMIP6_{start_year}-{end_year}_c{time_stamp}.log" + gitdescribe = subprocess.check_output('git describe', shell=True).strip() + gitdescribe = gitdescribe.decode('utf-8') + with open(nlfname, "w",encoding='utf-8') as nlfile: + nlfile.write(" mksrf_gridtype = \'global\' \n") + nlfile.write("&mksurfdata_input \n") for key,value in rawdata_files.items(): if key == 'mksrf_fgrid_mesh_nx' or key == 'mksrf_fgrid_mesh_ny': @@ -330,26 +345,34 @@ def main (): mksrf_hrvtyp = rawdata_files["mksrf_fvegtyp"] nlfile.write( f" mksrf_fhrvtyp = \'{mksrf_hrvtyp}\' \n") + mksrf_hrvtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] nlfile.write( f" mksrf_fhrvtyp_mesh = \'{mksrf_hrvtyp_mesh}\' \n") - nlfile.write( " outnc_double = .true. \n") nlfile.write( " all_urban = .false. \n") nlfile.write( " no_inlandwet = .true. \n") nlfile.write(f" numpft = {num_pft} \n") nlfile.write( " fdyndat = \' \' \n") nlfile.write(f" fsurdat = \'{fsurdat}\' \n") nlfile.write(f" fsurlog = \'{fsurlog}\' \n") - - #nlfile.write(f" start_year = {start_year}\n") - #nlfile.write(f" end_year = {end_year}\n") nlfile.write(f" mksrf_fdynuse = \'{landuse_fname} \' \n") - - mksrf_vic = rawdata_files["mksrf_fvic"] - nlfile.write( " outnc_vic = .true. \n") - #nlfile.write(f" use_vic = .{vic_flag}. \n") - #nlfile.write(f" use_glc = .{glc_flag}. \n") - #nlfile.write(f" create_esmf_pet_files = .{create_esmf_pet_files}. \n") + nlfile.write(f" gitdescribe = \'{gitdescribe}\' \n") + nlfile.write( " all_urban = .false. \n") + nlfile.write( " all_veg = .false. \n") + nlfile.write( " no_inlandwet = .true. \n") + nlfile.write( " outnc_large_files = .false. \n") + nlfile.write( " outnc_double = .true. \n") + if glc_flag: + nlfile.write( " out3d_glc = .true. \n") + else: + nlfile.write( " out3d_glc = .false. \n") + if vic_flag: + nlfile.write( " outnc_vic = .true. \n") + mksrf_fvic = rawdata_files["mksrf_fvic"] + nlfile.write(f" mksrf_fvic = {mksrf_fvic} \n") + else: + nlfile.write(" outnc_vic = .false. \n") + #nlfile.write(f" create_esmf_pet_files = .{create_esmf_pet_files}. \n") nlfile.write("/ \n") if __name__ == "__main__": diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 30901bb95b..82cf54cb09 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -237,6 +237,7 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2005.c170629.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_2005.c190119.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 4348c63e40..4ebf86e5af 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -367,7 +367,8 @@ program mksurfdata end if else if (root_task)then - write(ndiag,'(a)')"Calling fsurdat "//trim(fsurdat) + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) end if ! Open file From fd625e06d37b42db0c9d75f47fbec53e5ae66e63 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 20 Feb 2022 23:23:58 -0700 Subject: [PATCH 071/614] added mkinputMod.F90 --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 1 + tools/mksurfdata_esmf/src/mkinputMod.F90 | 484 +++++++++++++++++++++++ 2 files changed, 485 insertions(+) create mode 100644 tools/mksurfdata_esmf/src/mkinputMod.F90 diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 711ce0909a..e1916b909b 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -469,6 +469,7 @@ subroutine mkfile_define_vars(pioid, dynlanduse) long_name='VIC Ds parameter for the ARNO curve', units='unitless') end if + call mkpio_def_spatial_var(pioid=pioid, varname='LAKEDEPTH', xtype=xtype, & long_name='lake depth', units='m') diff --git a/tools/mksurfdata_esmf/src/mkinputMod.F90 b/tools/mksurfdata_esmf/src/mkinputMod.F90 new file mode 100644 index 0000000000..aca2cfc7c0 --- /dev/null +++ b/tools/mksurfdata_esmf/src/mkinputMod.F90 @@ -0,0 +1,484 @@ +module mkinputMod + + !----------------------------------------------------------------------- + ! Module containing input namelist settings + !----------------------------------------------------------------------- + + use ESMF + use shr_kind_mod , only : r8 => shr_kind_r8 + use shr_kind_mod , only : CS => shr_kind_CS, CL => shr_kind_CL, CX => shr_kind_CX + use shr_sys_mod , only : shr_sys_abort + use mkglcmecMod , only : nglcec + use mkpftMod , only : pft_idx, pft_frc + use mkvarctl + + implicit none + private + +#include + + ! --------------------- + ! routines + ! --------------------- + + public :: read_namelist_input + public :: check_namelist_input + public :: write_namelist_input + + ! --------------------- + ! variables + ! --------------------- + + character(CL) , public :: fgrddat ! grid data file + character(CL) , public :: fsurdat ! output surface data file name (if blank, do not output a surface dataset) + character(CL) , public :: fsurlog ! output surface log file name + character(CL) , public :: fdyndat ! dynamic landuse data file name + character(CL) , public :: fhrvname ! generic harvest filename + + character(CS) , public :: mksrf_gridnm = ' ' ! name of grid to use on output file + character(CX) , public :: mksrf_gridtype = ' ' ! land gridtype, global or reg + character(CX) , public :: mksrf_fgrid_mesh = ' ' ! land grid file name to use + integer , public :: mksrf_fgrid_mesh_nx + integer , public :: mksrf_fgrid_mesh_ny + + character(CX) , public :: mksrf_fvegtyp = ' ' ! vegetation data file name + character(CX) , public :: mksrf_fvegtyp_mesh = ' ' ! vegetation mesh file name + + character(CX) , public :: mksrf_fhrvtyp = ' ' ! harvest data file name + character(CX) , public :: mksrf_fhrvtyp_mesh = ' ' ! harvest mesh file name + + character(CX) , public :: mksrf_forganic = ' ' ! organic matter data file name + character(CX) , public :: mksrf_forganic_mesh = ' ' ! organic matter mesh file name + + character(CX) , public :: mksrf_fsoicol = ' ' ! soil color data file name + character(CX) , public :: mksrf_fsoicol_mesh = ' ' ! soil color mesh file name + + character(CX) , public :: mksrf_fsoitex = ' ' ! soil texture data file name + character(CX) , public :: mksrf_fsoitex_mesh = ' ' ! soil texture mesh file name + + character(CX) , public :: mksrf_fmax = ' ' ! fmax data file name + character(CX) , public :: mksrf_fmax_mesh = ' ' ! fmax mesh file name + + character(CX) , public :: mksrf_fsoildepth = ' ' ! soil depth file name + character(CX) , public :: mksrf_fsoildepth_mesh = ' ' ! soil depth file name + + character(CX) , public :: mksrf_fabm = ' ' ! ag fire peak month and + character(CX) , public :: mksrf_fabm_mesh = ' ' ! ag fire peak month and + + character(CX) , public :: mksrf_fpeat = ' ' ! peatlands and + character(CX) , public :: mksrf_fpeat_mesh = ' ' ! peatlands and + + character(CX) , public :: mksrf_fgdp = ' ' ! gdp data file names + character(CX) , public :: mksrf_fgdp_mesh = ' ' ! gdp mesh file names + + character(CX) , public :: mksrf_flakwat = ' ' ! inland lake data file name + character(CX) , public :: mksrf_flakwat_mesh = ' ' ! inland lake mesh file name + + character(CX) , public :: mksrf_fwetlnd = ' ' ! inland wetlands data file name + character(CX) , public :: mksrf_fwetlnd_mesh = ' ' ! inland wetlands mesh file name + + character(CX) , public :: mksrf_furban = ' ' ! urban data file name + character(CX) , public :: mksrf_furban_mesh = ' ' ! urban mesh file name + + character(CX) , public :: mksrf_fglacier = ' ' ! glacier data file name + character(CX) , public :: mksrf_fglacier_mesh = ' ' ! glacier mesh file name + + character(CX) , public :: mksrf_fglacierregion = ' ' ! glacier region data file name + character(CX) , public :: mksrf_fglacierregion_mesh = ' ' ! glacier region mesh file name + + character(CX) , public :: mksrf_furbtopo = ' ' ! urban topography data file name + character(CX) , public :: mksrf_furbtopo_mesh = ' ' ! urban topography mesh file name + + character(CX) , public :: mksrf_flai = ' ' ! lai data filename + character(CX) , public :: mksrf_flai_mesh = ' ' ! lai mesh filename + + character(CX) , public :: mksrf_fdynuse = ' ' ! ascii file containing names of dynamic land use files + character(CX) , public :: mksrf_fdynuse_mesh = ' ' ! ascii file containing names of dynamic land use files + + character(CX) , public :: mksrf_fvocef = ' ' ! VOC Emission Factor data file name + character(CX) , public :: mksrf_fvocef_mesh = ' ' ! VOC Emission Factor mesh file name + + character(CX) , public :: mksrf_ftopostats = ' ' ! topography statistics data file name + character(CX) , public :: mksrf_ftopostats_mesh = ' ' ! topography statistics mesh file name + + character(CX) , public :: mksrf_fvic = ' ' ! VIC parameters data file name + character(CX) , public :: mksrf_fvic_mesh = ' ' ! VIC parameters mesh file name + + character(CX) , public :: mksrf_irrig = ' ' ! TODO: should this namelist be here? + character(CX) , public :: mksrf_irrig_mesh = ' ' ! TODO: should this namelist be here? + + character(CS) , public :: gitdescribe = ' ' ! Description of model version from git + + logical , public :: urban_skip_abort_on_invalid_data_check + + character(len=*), parameter :: u_FILE_u = & + __FILE__ + +!=============================================================== +contains +!=============================================================== + + subroutine read_namelist_input(filename) + + ! Read in input namelist + + ! input/output variables + character(len=*), intent(in) :: filename + + ! local variables + integer :: ier + integer :: k + integer :: fileunit + logical :: lexist + character(len=*), parameter :: subname = 'read_namelist_input' + ! ------------------------------------------------------------ + + namelist /mksurfdata_input/ & + mksrf_fvegtyp, & + mksrf_fvegtyp_mesh, & + mksrf_fhrvtyp, & + mksrf_fhrvtyp_mesh, & + mksrf_fsoitex, & + mksrf_fsoitex_mesh, & + mksrf_forganic, & + mksrf_forganic_mesh, & + mksrf_fsoicol, & + mksrf_fsoicol_mesh, & + mksrf_fvocef, & + mksrf_fvocef_mesh, & + mksrf_flakwat, & + mksrf_flakwat_mesh, & + mksrf_fwetlnd, & + mksrf_fwetlnd_mesh, & + mksrf_fglacier, & + mksrf_fglacier_mesh, & + mksrf_fglacierregion, & + mksrf_fglacierregion_mesh, & + mksrf_furbtopo, & + mksrf_furbtopo_mesh, & + mksrf_fmax, & + mksrf_fmax_mesh, & + mksrf_furban, & + mksrf_furban_mesh, & + mksrf_flai, & + mksrf_flai_mesh, & + mksrf_fdynuse, & + mksrf_fdynuse_mesh, & + mksrf_fgdp, & + mksrf_fgdp_mesh, & + mksrf_fpeat, & + mksrf_fpeat_mesh, & + mksrf_fsoildepth, & + mksrf_fsoildepth_mesh, & + mksrf_fabm, & + mksrf_fabm_mesh, & + mksrf_ftopostats, & + mksrf_ftopostats_mesh, & + mksrf_fvic, & + mksrf_fvic_mesh, & + mksrf_fgrid_mesh, & + mksrf_fgrid_mesh_nx, & + mksrf_fgrid_mesh_ny, & + numpft, & + all_veg, & + all_urban, & + no_inlandwet, & + soil_color_override, & + soil_sand_override, & + soil_clay_override, & + soil_fmax_override, & + nglcec, & + pft_idx, & + pft_frc, & + gitdescribe, & + outnc_large_files, & + outnc_double, & + outnc_dims, & + outnc_vic, & + outnc_3dglc, & + fsurdat, & + fdyndat, & + fsurlog, & + std_elev, & + urban_skip_abort_on_invalid_data_check + + ! Set default namelist values - make these the defaults in gen_mksurfdata_namelist.py + mksrf_gridtype = 'global' + outnc_large_files = .false. + outnc_double = .true. + outnc_vic = .false. + outnc_3dglc = .false. + all_urban = .false. + all_veg = .false. + no_inlandwet = .true. + soil_color_override = unsetcol + soil_sand_override = unsetsoil + soil_clay_override = unsetsoil + soil_fmax_override = unsetsoil + urban_skip_abort_on_invalid_data_check = .false. ! default value for bug work around + + if (root_task) then + write(6,*) 'Attempting to initialize control settings .....' + end if + + if (root_task) then + inquire (file=trim(filename), exist=lexist) + if (.not. lexist) then + call shr_sys_abort(subname//trim(filename)//' does not exist') + end if + open(newunit=fileunit, status="old", file=trim(filename)) + read(fileunit, nml=mksurfdata_input, iostat=ier) + if (ier > 0) then + call shr_sys_abort(subname//' error reading in mksurfdata_input namelist from '//trim(filename)) + end if + close(fileunit) + end if + + call mpi_bcast (mksrf_fgrid_mesh, len(mksrf_fgrid_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fgrid_mesh_nx, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (mksrf_fgrid_mesh_ny, 1, MPI_INTEGER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fvegtyp, len(mksrf_fvegtyp), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fvegtyp_mesh, len(mksrf_fvegtyp_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fhrvtyp, len(mksrf_fhrvtyp), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fhrvtyp_mesh, len(mksrf_fhrvtyp_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fsoitex, len(mksrf_fsoitex), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fsoitex_mesh, len(mksrf_fsoitex_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fmax, len(mksrf_fmax), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fmax_mesh, len(mksrf_fmax_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_forganic, len(mksrf_forganic), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_forganic_mesh, len(mksrf_forganic_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fsoicol, len(mksrf_fsoicol), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fsoicol_mesh, len(mksrf_fsoicol_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fsoildepth, len(mksrf_fsoildepth), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fsoildepth_mesh, len(mksrf_fsoildepth_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fabm, len(mksrf_fabm), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fabm_mesh, len(mksrf_fabm_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fpeat, len(mksrf_fpeat), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fpeat_mesh, len(mksrf_fpeat_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fgdp, len(mksrf_fgdp), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fgdp_mesh, len(mksrf_fgdp_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_flakwat, len(mksrf_flakwat), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_flakwat_mesh, len(mksrf_flakwat_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fwetlnd, len(mksrf_fwetlnd), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fwetlnd_mesh, len(mksrf_fwetlnd_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_furban, len(mksrf_furban), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_furban_mesh, len(mksrf_furban_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_furbtopo, len(mksrf_furbtopo), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_furbtopo_mesh, len(mksrf_furbtopo_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fglacier, len(mksrf_fglacier), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fglacier_mesh, len(mksrf_fglacier_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fglacierregion, len(mksrf_fglacierregion), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fglacierregion_mesh, len(mksrf_fglacierregion_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_flai, len(mksrf_flai), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_flai_mesh, len(mksrf_flai_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fvocef, len(mksrf_fvocef), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fvocef_mesh, len(mksrf_fvocef_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_ftopostats, len(mksrf_ftopostats), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_ftopostats_mesh, len(mksrf_ftopostats_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fvic, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fvic_mesh, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (mksrf_fdynuse, len(mksrf_fdynuse), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fdynuse_mesh, len(mksrf_fdynuse_mesh), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (fsurdat, len(fsurdat), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (fdyndat, len(fdyndat), MPI_CHARACTER, 0, mpicom, ier) + + call mpi_bcast (outnc_dims, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (outnc_large_files, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (outnc_double, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (outnc_1d, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (outnc_vic, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (outnc_3dglc, 1, MPI_LOGICAL, 0, mpicom, ier) + + call mpi_bcast (all_urban, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (all_veg, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (no_inlandwet, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (soil_color_override, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (soil_sand_override, 1, MPI_REAL, 0, mpicom, ier) + call mpi_bcast (soil_clay_override, 1, MPI_REAL, 0, mpicom, ier) + call mpi_bcast (soil_fmax_override, 1, MPI_REAL, 0, mpicom, ier) + + call mpi_bcast (urban_skip_abort_on_invalid_data_check, 1, MPI_LOGICAL, 0, mpicom, ier) + + call mpi_bcast (numpft, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (std_elev, 1, MPI_REAL, 0, mpicom, ier) + + end subroutine read_namelist_input + + !=============================================================== + subroutine check_namelist_input() + + ! error check on namelist input + if (mksrf_fgrid_mesh /= ' ')then + fgrddat = mksrf_fgrid_mesh + else + call shr_sys_abort(" must specify mksrf_fgrid_mesh") + endif + + if (trim(mksrf_gridtype) /= 'global' .and. trim(mksrf_gridtype) /= 'regional') then + call shr_sys_abort(" mksrf_gridtype "//trim(mksrf_gridtype)//" is not supported") + endif + + if (nglcec <= 0) then + call shr_sys_abort('nglcec must be at least 1') + end if + + if (mksrf_fgrid_mesh_ny == 1) then + outnc_1d = .true. + outnc_dims = 1 + else + outnc_1d = .false. + outnc_dims = 2 + end if + + end subroutine check_namelist_input + + !=============================================================== + subroutine write_namelist_input() + + ! Write out namelist input to log file + ! Note - need to call this after ndiag has been set + + ! local variables + integer :: k + ! ------------------------------------------------------------ + + if (root_task) then + write(ndiag,'(a)')'Input rawdata files and corresponding meshes' + write(ndiag,'(a)')' PFTs from: '//trim(mksrf_fvegtyp) + write(ndiag,'(a)')' mesh for pft '//trim(mksrf_fvegtyp_mesh) + write(ndiag,*) + write(ndiag,'(a)')' inland lake from: '//trim(mksrf_flakwat) + write(ndiag,'(a)')' mesh for lake water '//trim(mksrf_flakwat_mesh) + write(ndiag,*) + write(ndiag,'(a)')' inland wetland from: '//trim(mksrf_fwetlnd) + write(ndiag,'(a)')' mesh for wetland '//trim(mksrf_fwetlnd_mesh) + write(ndiag,*) + write(ndiag,'(a)')' soil texture from: '//trim(mksrf_fsoitex) + write(ndiag,'(a)')' mesh for soil texture '//trim(mksrf_fsoitex_mesh) + write(ndiag,*) + write(ndiag,'(a)')' soil organic from: '//trim(mksrf_forganic) + write(ndiag,'(a)')' mesh for soil organic '//trim(mksrf_forganic_mesh) + write(ndiag,*) + write(ndiag,'(a)')' soil color from: '//trim(mksrf_fsoicol) + write(ndiag,'(a)')' mesh for soil color '//trim(mksrf_fsoicol_mesh) + write(ndiag,*) + write(ndiag,'(a)')' fmax from: '//trim(mksrf_fmax) + write(ndiag,'(a)')' mesh for fmax '//trim(mksrf_fmax_mesh) + write(ndiag,*) + write(ndiag,'(a)')' soil depth from: '//trim(mksrf_fsoildepth) + write(ndiag,'(a)')' mesh for soil depth '//trim(mksrf_fsoildepth_mesh) + write(ndiag,*) + write(ndiag,'(a)')' VOC emission factors from: '//trim(mksrf_fvocef) + write(ndiag,'(a)')' mesh for VOC pct emis '//trim(mksrf_fvocef_mesh) + write(ndiag,*) + write(ndiag,'(a)')' gdp from: '//trim(mksrf_fgdp) + write(ndiag,'(a)')' mesh for gdp '//trim(mksrf_fgdp_mesh) + write(ndiag,*) + write(ndiag,'(a)')' peat from: '//trim(mksrf_fpeat) + write(ndiag,'(a)')' mesh for peatlands '//trim(mksrf_fpeat_mesh) + write(ndiag,*) + write(ndiag,'(a)')' harvest from: '//trim(mksrf_fhrvtyp) + write(ndiag,'(a)')' mesh for harvest '//trim(mksrf_fhrvtyp_mesh) + write(ndiag,*) + write(ndiag,'(a)')' topography statistics from: '//trim(mksrf_ftopostats) + write(ndiag,'(a)')' mesh for topography stats '//trim(mksrf_ftopostats_mesh) + write(ndiag,*) + write(ndiag,'(a)')' glaciers from: '//trim(mksrf_fglacier) + write(ndiag,'(a,i4,a)')' with: ',nglcec,' glacier elevation classes' + write(ndiag,'(a)')' mesh for glacier '//trim(mksrf_fglacier_mesh) + write(ndiag,'(a)')' glacier region ID from: '//trim(mksrf_fglacierregion) + write(ndiag,'(a)')' mesh for glacier region '//trim(mksrf_fglacierregion_mesh) + write(ndiag,*) + write(ndiag,'(a)')' urban from: '//trim(mksrf_furban) + write(ndiag,'(a)')' mesh for urban '//trim(mksrf_furban_mesh) + write(ndiag,*) + write(ndiag,'(a)')' urban topography from: '//trim(mksrf_furbtopo) + write(ndiag,'(a)')' mesh for urban topography '//trim(mksrf_furbtopo_mesh) + write(ndiag,*) + write(ndiag,'(a)')' mesh for lai/sai '//trim(mksrf_flai_mesh) + write(ndiag,'(a)')' mesh for ag fire pk month '//trim(mksrf_fabm_mesh) + write(ndiag,*) + write(ndiag,'(a)')' abm from: '//trim(mksrf_fabm) + write(ndiag,*) + write(ndiag,'(a)')' VIC parameters from: '//trim(mksrf_fvic) + write(ndiag,'(a)')' mesh for VIC parameters '//trim(mksrf_fvic_mesh) + write(ndiag,*) + if (mksrf_fdynuse /= ' ') then + write(ndiag,'(a)')' mksrf_fdynuse = '//trim(mksrf_fdynuse) + end if + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) + write(ndiag,'(a)')'Model grid configuration variables' + write(ndiag,'(a)')' mksrf_fgrid_mesh = '//trim(mksrf_fgrid_mesh) + write(ndiag,'(a,i8)')' nlon= ',mksrf_fgrid_mesh_nx + write(ndiag,'(a,i8)')' nlat= ',mksrf_fgrid_mesh_ny + write(ndiag,'(a)')' mksrf_gridtype = '//trim(mksrf_gridtype) + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) + write(ndiag,*) + write(ndiag,'(a)')'Output configuration variables' + if (outnc_1d) then + write(ndiag,'(a)')' output file is 1d format' + else + write(ndiag,'(a)')' output file is 2d lat/lon format' + end if + if ( outnc_large_files ) then + write(ndiag,'(a)')' Output file in NetCDF 64-bit large_files format' + end if + if ( outnc_double )then + write(ndiag,'(a)')' Output ALL data in file as 64-bit' + else + write(ndiag,'(a)')' Output ALL data in file as 32-bit' + end if + if ( outnc_vic )then + write(ndiag,'(a)')' Output VIC fields' + end if + if ( outnc_3dglc )then + write(ndiag,'(a)')' Output optional 3D glacier fields (mostly used for verification of the glacier model)' + end if + if ( all_urban )then + write(ndiag,'(a)') ' all_urban is true => Output ALL data in file as 100% urban' + else + write(ndiag,'(a)') ' all_urban is false ' + end if + if ( no_inlandwet )then + write(ndiag,'(a)') ' no_inlandwet is true => Set wetland to 0% over land' + else + write(ndiag,'(a)') ' no_inlandwet is false' + end if + if (all_veg) then + write(ndiag,'(a)') ' all_veg is true => Output ALL data in file as 100% vegetated' + else + write(ndiag,'(a)') ' all_veg is false ' + end if + if (urban_skip_abort_on_invalid_data_check) then + write(ndiag, '(a)') " WARNING: aborting on invalid data check in urban has been disabled!" + write(ndiag, '(a)') " WARNING: urban data may be invalid!" + end if + end if + + end subroutine write_namelist_input + +end module mkinputMod From f324d6a64d63ab7ae2fbc2069c6957e921592805 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 22 Feb 2022 10:36:49 -0700 Subject: [PATCH 072/614] more refactor --- tools/mksurfdata_esmf/README | 8 +- .../{run/run_mksurfdata => gen_mksurfdata} | 18 ++- .../gen_mksurfdata_namelist.py | 79 ++++++----- .../gen_mksurfdata_namelist.xml | 8 +- tools/mksurfdata_esmf/src/mkVICparamsMod.F90 | 105 ++++++++------ tools/mksurfdata_esmf/src/mkfileMod.F90 | 7 +- tools/mksurfdata_esmf/src/mkinputMod.F90 | 23 ++- tools/mksurfdata_esmf/src/mkpioMod.F90 | 32 +++-- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 2 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 107 +++++--------- tools/mksurfdata_esmf/src/mkvarctl.F90 | 34 ++--- tools/mksurfdata_esmf/src/mkvocefMod.F90 | 131 ++++++++++++------ 12 files changed, 299 insertions(+), 255 deletions(-) rename tools/mksurfdata_esmf/{run/run_mksurfdata => gen_mksurfdata} (69%) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 2a6176d325..133c152795 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -6,10 +6,6 @@ building the executable (this will be built in src/ for now) > module load cmake > CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src/ > make -(note - if you change src/CMakeList.txt the issue the following in bld -> rm -rf * -> CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src/ -> make > cd ../ > make clean > make @@ -17,6 +13,6 @@ building the executable (this will be built in src/ for now) ============================ running the code (you could add mksurfdata_in) ============================ -> cd ../run -> ln -s ../src/mksurfdata . +> cd ../ +./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc | cut -d' ' -f5 > qsub run_mksurfdata diff --git a/tools/mksurfdata_esmf/run/run_mksurfdata b/tools/mksurfdata_esmf/gen_mksurfdata similarity index 69% rename from tools/mksurfdata_esmf/run/run_mksurfdata rename to tools/mksurfdata_esmf/gen_mksurfdata index b1a688d613..b846a444fc 100755 --- a/tools/mksurfdata_esmf/run/run_mksurfdata +++ b/tools/mksurfdata_esmf/gen_mksurfdata @@ -10,18 +10,24 @@ #PBS -l select=24:ncpus=36:mpiprocs=12 ##PBS -l select=32:ncpus=36:mpiprocs=12 - # note for -l input above # -l select={num_nodes}:ncpus={max_tasks_per_node}:mpiprocs={tasks_per_node} - -export TMPDIR=/glade/scratch/$USER/temp -mkdir -p $TMPDIR +# note for mpiexec below +# -np {total_tasks} #module rm netcdf #module load netcdf-mpi pnetcdf pio/2.5.5 #make -# -np {total_tasks} +export TMPDIR=/glade/scratch/$USER/temp +mkdir -p $TMPDIR + +# Determine mksurfdata_in +# fname=`./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc | cut -d' ' -f5` +# rm -f mksurfdata_in +# ln -s $fname mksurfdata_in + +# Run the model #mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata -mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata + mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata #mpiexec_mpt -p "%g:" -np 384 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 876ded4648..a6d4d60735 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -3,7 +3,7 @@ import sys, os, shutil import xml.etree.ElementTree as ET import logging -import argparse +import argparse, textwrap import subprocess from datetime import datetime @@ -23,28 +23,41 @@ def get_parser(): parser.print_usage = parser.print_help parser.add_argument( - "--sy", "--start-year", - help="Simulation start year. [default: %(default)s] ", + help = textwrap.dedent('''\ + Simulation start year. + [Required]'''), action="store", dest="start_year", required=True, type=int, ) parser.add_argument( - "--ey", "--end-year", - help="Simulation end year. [default: start_year] ", + help = textwrap.dedent('''\ + Simulation end year. + [Required]'''), action="store", dest="end_year", required=True, type=int, ) + parser.add_argument( + "--res", + help=""" + model resolution [default: %(default)s] + To see available supported resolutions, simply invoke this command + with a --res unknown opion + """, + action="store", + dest="res", + required=False, + default="4x5", + ) parser.add_argument( "--glc-nec", help=""" - Number of glacier elevation classes to use. - [default: %(default)s] + Number of glacier elevation classes to use. [default: %(default)s] """, action="store", dest="glc_nec", @@ -88,7 +101,8 @@ def get_parser(): parser.add_argument( "--vic", help=""" - Flag for adding the fields required for the VIC model. + Flag for adding the fields required for the VIC model. + [default: %(default)s] """, action="store_true", dest="vic_flag", @@ -98,6 +112,7 @@ def get_parser(): "--glc", help=""" Flag for adding the optional 3D glacier fields for verification of the glacier model. + [default: %(default)s] """, action="store_true", dest="glc_flag", @@ -110,6 +125,7 @@ def get_parser(): than the default lower resolution dataset. (Low resolution is at quarter-degree, high resolution at 3-minute) [Note: hires only available for 1850 and 2005.] + [default: %(default)s] """, action="store_true", dest="hres_flag", @@ -119,6 +135,7 @@ def get_parser(): "--nocrop", help=""" Create datasets with the extensive list of prognostic crop types. + [default: %(default)s] """, action="store_false", dest="crop_flag", @@ -136,28 +153,19 @@ def get_parser(): "--potveg_flag", help=""" Use Potential Vegetation for pft_years + [default: %(default)s] """, action="store_false", dest="potveg_flag", default=False, ) - parser.add_argument( - "-r", - "--res", - help=""" - model resolution - """, - action="store", - dest="res", - required=False, - default="4x5", - ) parser.add_argument( "--merge_gis", help=""" If you want to use the glacier dataset that merges in the Greenland Ice Sheet data that CISM uses (typically used only if consistency with CISM is important) + [default: %(default)s] """, action="store", dest="merge_gis", @@ -170,15 +178,15 @@ def main (): args = get_parser().parse_args() + start_year = args.start_year + end_year = args.end_year + res = args.res hires_pft = args.hres_flag ssp_rcp = args.ssp_rcp - res = args.res input_path = args.input_path crop_flag = args.crop_flag vic_flag = args.vic_flag glc_flag = args.glc_flag - start_year = args.start_year - end_year = args.end_year potveg = args.potveg_flag glc_nec = args.glc_nec merge_gis = args.merge_gis @@ -187,7 +195,7 @@ def main (): if start_year == 1850 and end_year == 1850: pft_years = "1850" elif start_year == 2000 and end_year == 2000: - pft_years = "2005" + pft_years = "2000" elif start_year == 2005 and end_year == 2005: pft_years = "2005" elif start_year >= 850 and end_year <= 1849: @@ -252,13 +260,15 @@ def main (): # ERROR: keep %y here and do the replacement later rawdata_files[child1.tag] = rawdata_files[child1.tag].replace("%y",str(start_year)) if not os.path.isfile(rawdata_files[child1.tag]): - raise Exception (f"file {rawdata_files[child1.tag]} does not exist") + print(f"intput rawdata file {rawdata_files[child1.tag]} does not exist") + os.exit(1) if item.tag == 'mesh_filename': new_key = f"{child1.tag}_mesh" rawdata_files[new_key] = os.path.join(input_path, item.text) if not os.path.isfile(rawdata_files[new_key]): - raise Exception (f"file {rawdata_files[new_key]} does not exist") + print(f"mesh file {rawdata_files[new_key]} does not exist") + os.exit(1) tree2 = ET.parse('../../ccs_config/component_grids_nuopc.xml') root = tree2.getroot() @@ -282,7 +292,7 @@ def main (): for name, value in child1.attrib.items(): valid_grids.append(value) print (f"Valid values are {valid_grids}") - raise Exception ("Exiting") + os._exit(1) # Determine num_pft if crop_flag: @@ -332,11 +342,10 @@ def main (): gitdescribe = subprocess.check_output('git describe', shell=True).strip() gitdescribe = gitdescribe.decode('utf-8') + print (f"Creating input namelist file {nlfname}") with open(nlfname, "w",encoding='utf-8') as nlfile: - - nlfile.write(" mksrf_gridtype = \'global\' \n") - nlfile.write("&mksurfdata_input \n") + for key,value in rawdata_files.items(): if key == 'mksrf_fgrid_mesh_nx' or key == 'mksrf_fgrid_mesh_ny': nlfile.write(f" {key} = {value} \n") @@ -362,17 +371,21 @@ def main (): nlfile.write( " no_inlandwet = .true. \n") nlfile.write( " outnc_large_files = .false. \n") nlfile.write( " outnc_double = .true. \n") + if glc_flag: - nlfile.write( " out3d_glc = .true. \n") + nlfile.write( " outnc_3dglc = .true. \n") else: - nlfile.write( " out3d_glc = .false. \n") + nlfile.write( " outnc_3dglc = .false. \n") + if vic_flag: nlfile.write( " outnc_vic = .true. \n") mksrf_fvic = rawdata_files["mksrf_fvic"] - nlfile.write(f" mksrf_fvic = {mksrf_fvic} \n") + nlfile.write(f" mksrf_fvic = \'{mksrf_fvic}\' \n") + mksrf_fvic_mesh = rawdata_files["mksrf_fvic_mesh"] + nlfile.write(f" mksrf_fvic_mesh = \'{mksrf_fvic_mesh}\' \n") else: nlfile.write(" outnc_vic = .false. \n") - #nlfile.write(f" create_esmf_pet_files = .{create_esmf_pet_files}. \n") + nlfile.write("/ \n") if __name__ == "__main__": diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 82cf54cb09..241a77318d 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -226,16 +226,16 @@ version of the raw dataset will probably go away. - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1850.c170629.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.cdf5.c170629/mksrf_landuse_histclm50_LUH2_1850.cdf5.c170629.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2000.c170629.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.cdf5.c170629/mksrf_landuse_histclm50_LUH2_2000.cdf5.c170629.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2005.c170629.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.cdf5.c170629/mksrf_landuse_histclm50_LUH2_2005.cdf5.c170629.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc @@ -251,7 +251,7 @@ version of the raw dataset will probably go away. - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_%y.c170629.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.cdf5.c170629/mksrf_landuse_histclm50_LUH2_%y.cdf5.c170629.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc diff --git a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 index 461ecf5cd8..5798b80197 100644 --- a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 @@ -6,13 +6,14 @@ module mkVICparamsMod use ESMF use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 + use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4, cl => shr_kind_cl use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr - use mkvarctl , only : root_task, ndiag + use mkvarctl , only : root_task, ndiag, spval use mkchecksMod , only : min_bad + use mkfileMod , only : mkfile_output use mkdiagnosticsMod , only : output_diagnostics_continuous implicit none @@ -27,36 +28,38 @@ module mkVICparamsMod contains !=============================================================== - subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, binfl_o, ws_o, dsmax_o, ds_o, rc) + subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! ! make VIC parameters ! ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesho - real(r8) , intent(out) :: binfl_o(:) ! output VIC b parameter for the Variable Infiltration Capacity Curve (unitless) - real(r8) , intent(out) :: ws_o(:) ! output VIC Ws parameter for the ARNO curve (unitless) - real(r8) , intent(out) :: dsmax_o(:) ! output VIC Dsmax parameter for the ARNO curve (mm/day) - real(r8) , intent(out) :: ds_o(:) ! output VIC Ds parameter for the ARNO curve (unitless) - integer , intent(out) :: rc + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesho + type(file_desc_t), intent(inout) :: pioid_o ! output file descripter + integer , intent(out) :: rc ! local variables: - type(ESMF_RouteHandle) :: routehandle - type(ESMF_Mesh) :: mesh_i - type(file_desc_t) :: pioid - integer :: ni,no - integer :: ns_i, ns_o - integer :: n,l,k - integer , allocatable :: mask_i(:) - real(r8), allocatable :: rmask_i(:) - real(r8), allocatable :: frac_o(:) - real(r8), allocatable :: data_i(:) ! data on input grid - real(r8), parameter :: min_valid_binfl = 0._r8 - real(r8), parameter :: min_valid_ws = 0._r8 - real(r8), parameter :: min_valid_dsmax = 0._r8 - real(r8), parameter :: min_valid_ds = 0._r8 - integer :: ier,rcode ! error status + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid_i + integer :: ni,no + integer :: ns_i, ns_o + integer :: n,l,k + real(r8), allocatable :: binfl_o(:) ! output VIC b parameter for the Variable Infiltration Capacity Curve (unitless) + real(r8), allocatable :: ws_o(:) ! output VIC Ws parameter for the ARNO curve (unitless) + real(r8), allocatable :: dsmax_o(:) ! output VIC Dsmax parameter for the ARNO curve (mm/day) + real(r8), allocatable :: ds_o(:) ! output VIC Ds parameter for the ARNO curve (unitless) + integer , allocatable :: mask_i(:) + real(r8), allocatable :: rmask_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: data_i(:) ! data on input grid + real(r8), parameter :: min_valid_binfl = 0._r8 + real(r8), parameter :: min_valid_ws = 0._r8 + real(r8), parameter :: min_valid_dsmax = 0._r8 + real(r8), parameter :: min_valid_ds = 0._r8 + integer :: ier,rcode ! error status + character(len=cl) :: errmsg character(len=*), parameter :: subname = 'mkVICparams' !----------------------------------------------------------------------- @@ -73,7 +76,7 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, binfl_o, ws_o, dsmax_o, call ESMF_VMLogMemInfo("At start of "//trim(subname)) ! Open input data file - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) ! Read in input mesh mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) @@ -88,12 +91,18 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, binfl_o, ws_o, dsmax_o, call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Allocate output variables + allocate (binfl_o(ns_o)) ; binfl_o(:) = spval + allocate (ws_o(ns_o)) ; ws_o(:) = spval + allocate (dsmax_o(ns_o)) ; dsmax_o(:) = spval + allocate (ds_o(ns_o)) ; ds_o(:) = spval + ! Get the landmask from the file and reset the mesh mask based on that allocate(rmask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, rmask_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'mask', mesh_i, rmask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i if (rmask_i(ni) > 0._r8) then @@ -112,7 +121,8 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, binfl_o, ws_o, dsmax_o, call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) do n = 1, ns_o if ((frac_o(n) < 0.0) .or. (frac_o(n) > 1.0001)) then - write(6,*) "ERROR:: frac_o out of range: ", frac_o(n),n + write(errmsg,'(a,f13.5,2x,i4)') "ERROR:: frac_o out of range: ", frac_o(n),n + call shr_sys_abort(trim(errmsg),u_FILE_u,__LINE__) end if end do @@ -122,10 +132,10 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, binfl_o, ws_o, dsmax_o, ! Read in input data_i for a variety of inputs allocate(data_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort('allocation error for binfl_i') + if (ier/=0) call shr_sys_abort('allocation error for binfl_i',u_FILE_u,__LINE__) ! Read in binfl_i into data_i - call mkpio_get_rawdata(pioid, 'binfl', mesh_i, data_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'binfl', mesh_i, data_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -138,7 +148,7 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, binfl_o, ws_o, dsmax_o, end if end do if (min_bad(binfl_o, min_valid_binfl, 'binfl')) then - call shr_sys_abort() + call shr_sys_abort('error for min_bad',u_FILE_u,__LINE__) end if ! Calculate global diagnostics for binfl @@ -151,7 +161,7 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, binfl_o, ws_o, dsmax_o, ! ----------------------------------------------------------------- ! Read in Ws into data_i - call mkpio_get_rawdata(pioid, 'Ws', mesh_i, data_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'Ws', mesh_i, data_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -177,7 +187,7 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, binfl_o, ws_o, dsmax_o, ! ----------------------------------------------------------------- ! Read in Dsmax into data_i - call mkpio_get_rawdata(pioid, 'Dsmax', mesh_i, data_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'Dsmax', mesh_i, data_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -186,7 +196,7 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, binfl_o, ws_o, dsmax_o, if (ChkErr(rc,__LINE__,u_FILE_u)) return do no = 1,ns_o if (frac_o(ns_o) == 0._r8) then - ws_o(n) = 10._r8 + dsmax_o(n) = 10._r8 end if end do if (min_bad(dsmax_o, min_valid_dsmax, 'Dsmax')) then @@ -195,7 +205,7 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, binfl_o, ws_o, dsmax_o, ! Calculate global diagnostics for Dsmax call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - data_i, ws_o, "VIC Dsmax parameter", "mm/day", ndiag, rc) + data_i, dsmax_o, "VIC Dsmax parameter", "mm/day", ndiag, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! ----------------------------------------------------------------- @@ -203,7 +213,7 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, binfl_o, ws_o, dsmax_o, ! ----------------------------------------------------------------- ! Read in Ds into data_i - call mkpio_get_rawdata(pioid, 'Dsmax', mesh_i, data_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'Dsmax', mesh_i, data_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -221,15 +231,30 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, binfl_o, ws_o, dsmax_o, ! Calculate global diagnostics for Ws call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - data_i, ws_o, "VIC Ds parameter", "unitless", ndiag, rc) + data_i, ds_o, "VIC Ds parameter", "unitless", ndiag, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! ----------------------------------------------------------------- + ! Write output + ! ----------------------------------------------------------------- + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out VIC parameters" + call mkfile_output(pioid_o, mesh_o, 'binfl', binfl_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for binfl') + call mkfile_output(pioid_o, mesh_o, 'Ws', ws_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for Ws') + call mkfile_output(pioid_o, mesh_o, 'Dsmax', dsmax_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for Dsmax') + call mkfile_output(pioid_o, mesh_o, 'Ds', ds_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for Ds') + call pio_syncfile(pioid_o) + ! ----------------------------------------------------------------- ! Wrap up ! ----------------------------------------------------------------- - ! Close the file - call pio_closefile(pioid) + ! Close the input file + call pio_closefile(pioid_i) call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) ! Release memory diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index e1916b909b..bb59c520b6 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -11,7 +11,7 @@ module mkfileMod use mklaiMod , only : mklai use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft, num_natpft use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array - use mkpioMod ! TODO: add only + use mkpioMod use mkinputMod use mkvarctl @@ -134,7 +134,7 @@ subroutine mkfile_define_atts(pioid, dynlanduse) str = 'Community Land Model: CLM5' rcode = pio_put_att (pioid, pio_global, 'Source', trim(str)) - !rcode = pio_put_att (pioid, pio_global, 'Version', trim(gitdescribe), trim(gitdescribe)) + rcode = pio_put_att (pioid, pio_global, 'Version', trim(gitdescribe)) if ( all_urban )then str = 'TRUE' @@ -149,9 +149,6 @@ subroutine mkfile_define_atts(pioid, dynlanduse) ! Raw data file names str = get_filename(mksrf_fgrid_mesh) rcode = pio_put_att(pioid, pio_global, 'Input_grid_dataset', trim(str)) - str = trim(mksrf_gridtype) - rcode = pio_put_att(pioid, pio_global, 'Input_gridtype', trim(str)) - if (.not. dynlanduse) then str = get_filename(mksrf_fvocef) rcode = pio_put_att(pioid, pio_global, 'VOC_EF_raw_data_file_name', trim(str)) diff --git a/tools/mksurfdata_esmf/src/mkinputMod.F90 b/tools/mksurfdata_esmf/src/mkinputMod.F90 index aca2cfc7c0..87ce4508ea 100644 --- a/tools/mksurfdata_esmf/src/mkinputMod.F90 +++ b/tools/mksurfdata_esmf/src/mkinputMod.F90 @@ -4,7 +4,6 @@ module mkinputMod ! Module containing input namelist settings !----------------------------------------------------------------------- - use ESMF use shr_kind_mod , only : r8 => shr_kind_r8 use shr_kind_mod , only : CS => shr_kind_CS, CL => shr_kind_CL, CX => shr_kind_CX use shr_sys_mod , only : shr_sys_abort @@ -35,11 +34,9 @@ module mkinputMod character(CL) , public :: fdyndat ! dynamic landuse data file name character(CL) , public :: fhrvname ! generic harvest filename - character(CS) , public :: mksrf_gridnm = ' ' ! name of grid to use on output file - character(CX) , public :: mksrf_gridtype = ' ' ! land gridtype, global or reg character(CX) , public :: mksrf_fgrid_mesh = ' ' ! land grid file name to use - integer , public :: mksrf_fgrid_mesh_nx - integer , public :: mksrf_fgrid_mesh_ny + integer , public :: mksrf_fgrid_mesh_nx = -999 + integer , public :: mksrf_fgrid_mesh_ny = -999 character(CX) , public :: mksrf_fvegtyp = ' ' ! vegetation data file name character(CX) , public :: mksrf_fvegtyp_mesh = ' ' ! vegetation mesh file name @@ -126,8 +123,8 @@ subroutine read_namelist_input(filename) character(len=*), intent(in) :: filename ! local variables - integer :: ier - integer :: k + integer :: ier + integer :: k integer :: fileunit logical :: lexist character(len=*), parameter :: subname = 'read_namelist_input' @@ -203,7 +200,6 @@ subroutine read_namelist_input(filename) urban_skip_abort_on_invalid_data_check ! Set default namelist values - make these the defaults in gen_mksurfdata_namelist.py - mksrf_gridtype = 'global' outnc_large_files = .false. outnc_double = .true. outnc_vic = .false. @@ -296,7 +292,7 @@ subroutine read_namelist_input(filename) call mpi_bcast (mksrf_ftopostats_mesh, len(mksrf_ftopostats_mesh), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fvic, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fvic_mesh, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fvic_mesh, len(mksrf_fvic_mesh), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fdynuse, len(mksrf_fdynuse), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fdynuse_mesh, len(mksrf_fdynuse_mesh), MPI_CHARACTER, 0, mpicom, ier) @@ -324,6 +320,8 @@ subroutine read_namelist_input(filename) call mpi_bcast (numpft, 1, MPI_INTEGER, 0, mpicom, ier) call mpi_bcast (std_elev, 1, MPI_REAL, 0, mpicom, ier) + call mpi_bcast (gitdescribe, len(gitdescribe), MPI_CHARACTER, 0, mpicom, ier) + end subroutine read_namelist_input !=============================================================== @@ -336,10 +334,6 @@ subroutine check_namelist_input() call shr_sys_abort(" must specify mksrf_fgrid_mesh") endif - if (trim(mksrf_gridtype) /= 'global' .and. trim(mksrf_gridtype) /= 'regional') then - call shr_sys_abort(" mksrf_gridtype "//trim(mksrf_gridtype)//" is not supported") - endif - if (nglcec <= 0) then call shr_sys_abort('nglcec must be at least 1') end if @@ -361,7 +355,7 @@ subroutine write_namelist_input() ! Note - need to call this after ndiag has been set ! local variables - integer :: k + integer :: k ! ------------------------------------------------------------ if (root_task) then @@ -434,7 +428,6 @@ subroutine write_namelist_input() write(ndiag,'(a)')' mksrf_fgrid_mesh = '//trim(mksrf_fgrid_mesh) write(ndiag,'(a,i8)')' nlon= ',mksrf_fgrid_mesh_nx write(ndiag,'(a,i8)')' nlat= ',mksrf_fgrid_mesh_ny - write(ndiag,'(a)')' mksrf_gridtype = '//trim(mksrf_gridtype) write(ndiag,*) write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index fa5d80c8f5..589fb0b464 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -54,6 +54,8 @@ module mkpioMod integer , public :: pio_ioformat type(iosystem_desc_t) , public :: pio_iosystem + logical :: debug = .false. + character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -475,26 +477,26 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, ! determine io descriptor for this variable if (ndims == 1) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) - if (root_task) then + if (root_task .and. debug) then write(ndiag,'(a,i20)') ' set iodesc for rawdata: '//trim(varname)//' with dim(1) = ',& dimlens(1) end if else if (ndims == 2) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) - if (root_task) then + if (root_task .and. debug) then write(ndiag,'(a,i8,i8)') ' set iodesc for rawdata: '//trim(varname)//' with dim(1),dim(2) = ',& dimlens(1),dimlens(2) end if else if (ndims == 3) then if (unlimited_dim) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) - if (root_task) then + if (root_task .and. debug) then write(ndiag,'(a,i8,i8)') ' set iodesc for rawdata: '//trim(varname)//' with dim(1),dim(2) = ',& dimlens(1),dimlens(2) end if else call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) - if (root_task) then + if (root_task .and. debug) then write(ndiag,'(a,i8,i8,i8)') ' set iodesc for rawdata: '//trim(varname)//' with dim(1),dim(2),dim(3) = ',& dimlens(1),dimlens(2),dimlens(3) end if @@ -502,7 +504,7 @@ subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, else if (ndims == 4) then if (unlimited_dim) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) - if (root_task) then + if (root_task .and. debug) then write(ndiag,'(a,i8,i8,i8)') ' set iodesc for rawdata: '//trim(varname)//' with dim(1),dim(2),dim(3) = ',& dimlens(1),dimlens(2),dimlens(3) end if @@ -619,20 +621,20 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) ! Where lev would correspond to an undistributed dimension in esmf if (ndims == 1) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) - if (root_task) then + if (root_task .and. debug) then write(ndiag,'(a,i20)') ' set iodesc for output data: '//trim(varname)//' with dim(1) = ',& dimlens(1) end if else if (ndims == 2) then if (unlimited_dim) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1)/), compdof, pio_iodesc) - if (root_task) then + if (root_task .and. debug) then write(ndiag,'(a,i8)') ' set iodesc for output data with time dim: '//trim(varname)//& ' with dim(1) = ',dimlens(1) end if else call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof3d, pio_iodesc) - if (root_task) then + if (root_task .and. debug) then write(ndiag,'(a,i8,i8)') ' set iodesc for output data: '//trim(varname)//& ' with dim(1),dim(2) = ',dimlens(1),dimlens(2) end if @@ -640,13 +642,13 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) else if (ndims == 3) then if (unlimited_dim) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof3d, pio_iodesc) - if (root_task) then + if (root_task .and. debug) then write(ndiag,'(a,i8,i8)') ' set iodesc for output data with time dim: '//trim(varname)//& ' with dim(1),dim(2) = ',dimlens(1),dimlens(2) end if else call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) - if (root_task) then + if (root_task .and. debug) then write(ndiag,'(a,i8,i8,i8)') ' set iodesc for output data: '//trim(varname)//& ' with dim(1),dim(2),dim(3) = ',dimlens(1),dimlens(2),dimlens(3) end if @@ -656,20 +658,20 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) ! Assume that can have (lon,lat), (lon,lat,lev1), (lon,lat,lev1,lev2), (lon,lat,time) or (lon,lat,lev1,time) if (ndims == 2) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) - if (root_task) then + if (root_task .and. debug) then write(ndiag,'(a,i8,i8)') ' set iodesc for output data: '//trim(varname)//& ' with dim(1),dim(2)= ',dimlens(1),dimlens(2) end if else if (ndims == 3) then if (unlimited_dim) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2)/), compdof, pio_iodesc) - if (root_task) then + if (root_task .and. debug) then write(ndiag,'(a,i8,i8)') ' set iodesc for output data with time dim : '//trim(varname)//& ' with dim(1),dim(2)= ', dimlens(1),dimlens(2) end if else call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) - if (root_task) then + if (root_task .and. debug) then write(ndiag,'(a,i8,i8,i8)') ' set iodesc for output data: '//trim(varname)//& ' with dim(1),dim(2),dim3(3)= ',dimlens(1),dimlens(2),dimlens(3) end if @@ -677,13 +679,13 @@ subroutine mkpio_iodesc_output(pioid, mesh, varname, pio_iodesc, rc) else if (ndims == 4) then if (unlimited_dim) then call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3)/), compdof3d, pio_iodesc) - if (root_task) then + if (root_task .and. debug) then write(ndiag,'(a,i8,i8,i8)') ' set iodesc for output data with time dim : '//trim(varname)//& ' with dim(1),dim(2),dimlens(3)= ', dimlens(1),dimlens(2),dimlens(3) end if else call pio_initdecomp(pio_iosystem, pio_vartype, (/dimlens(1),dimlens(2),dimlens(3),dimlens(4)/), compdof3d, pio_iodesc) - if (root_task) then + if (root_task .and. debug) then write(ndiag,'(a,i8,i8,i8,i8)') ' set iodesc for output data: '//trim(varname)//& ' with dim(1),dim(2),dimlens(3),dimlens(4)= ', dimlens(1),dimlens(2),dimlens(3),dimlens(4) end if diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index aeee44ec20..da2bfb1f25 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -159,7 +159,7 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return allocate(frac_o(ns_o)) - frac_o(:) = real(dataptr_r8(:), kind=r4) + frac_o(:) = dataptr_r8(:) ! Create a dynamic mask object ! The dynamic mask object further holds a pointer to the routine that will be called in order to diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 4ebf86e5af..610307f0ce 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -213,20 +213,6 @@ program mksurfdata ! soil depth data real(r8), allocatable :: soildepth(:) ! soil depth (m) - ! VOC data - real(r8), allocatable :: ef1_btr(:) ! Isoprene emission factor for broadleaf - real(r8), allocatable :: ef1_fet(:) ! Isoprene emission factor for fine/everg - real(r8), allocatable :: ef1_fdt(:) ! Isoprene emission factor for fine/dec - real(r8), allocatable :: ef1_shr(:) ! Isoprene emission factor for shrubs - real(r8), allocatable :: ef1_grs(:) ! Isoprene emission factor for grasses - real(r8), allocatable :: ef1_crp(:) ! Isoprene emission factor for crops - - ! VIC data - real(r8), allocatable :: vic_binfl(:) ! VIC b - real(r8), allocatable :: vic_ws(:) ! VIC Ws parameter (unitless) - real(r8), allocatable :: vic_dsmax(:) ! VIC Dsmax parameter (mm/day) - real(r8), allocatable :: vic_ds(:) ! VIC Ds parameter (unitless) - ! logicals logical :: zero_out_lake ! if should zero glacier out logical :: zero_out_wetland ! if should zero glacier out @@ -417,6 +403,17 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') end if + !DEBUG + if (fsurdat /= ' ' .and. outnc_vic) then + call mkVICparams ( mksrf_fvic_mesh, mksrf_fvic, mesh_model, pioid, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') + end if + if (fsurdat /= ' ' ) then + call mkvocef ( mksrf_fvocef_mesh, mksrf_fvocef, mesh_model, pioid, lat, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkvocef') + end if + !DEBUG + ! ----------------------------------- ! Make LAI and SAI from 1/2 degree data and write to surface dataset ! Write to netcdf file is done inside mklai routine @@ -706,8 +703,8 @@ program mksurfdata ! ----------------------------------- ! Compute topography statistics [topo_stddev, slope] from [ftopostats] ! ----------------------------------- - allocate ( topo_stddev(lsize_o)) ; topo_stddev(:) = spval - allocate ( slope(lsize_o)) ; slope(:) = spval + allocate (topo_stddev(lsize_o)) ; topo_stddev(:) = spval + allocate (slope(lsize_o)) ; slope(:) = spval call mktopostats ( mksrf_ftopostats_mesh, mksrf_ftopostats, mesh_model, & topo_stddev_o=topo_stddev, slope_o=slope, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mktopostats') @@ -720,26 +717,17 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for SLOPE') call pio_syncfile(pioid) end if - deallocate(topo_stddev) - deallocate(slope) + deallocate(topo_stddev, slope) ! ----------------------------------- - ! TODO: + ! Compute VIC parameters ! ----------------------------------- - ! Make VIC parameters [binfl, ws, dsmax, ds] from [fvic] - ! if ( outnc_vic )then - ! allocate ( vic_binfl(lsize_o)) ; vic_binfl(:) = spval - ! allocate ( vic_ws(lsize_o)) ; vic_ws(:) = spval - ! allocate ( vic_dsmax(lsize_o)) ; vic_dsmax(:) = spval - ! allocate ( vic_ds(lsize_o)) ; vic_ds(:) = spval - ! call mkVICparams ( mapfname=map_fvic, datfname=mksrf_fvic, ndiag=ndiag, & - ! binfl_o=vic_binfl, ws_o=vic_ws, dsmax_o=vic_dsmax, ds_o=vic_ds) - ! deallocate(vic_binfl) - ! deallocate(vic_ws) - ! deallocate(vic_dsmax) - ! deallocate(vic_ds) - ! deallocate(vic_binfl, vic_ws, vic_dsmax, vic_ds ) - ! end if + if (fsurdat /= ' ') then + if (outnc_vic) then + call mkVICparams ( mksrf_fvic_mesh, mksrf_fvic, mesh_model, pioid, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') + end if + end if ! ----------------------------------- ! Make organic matter density [organic] [forganic] @@ -766,50 +754,16 @@ program mksurfdata ! ----------------------------------- ! Make VOC emission factors for isoprene [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] ! ----------------------------------- - allocate (ef1_btr(lsize_o)) ; ef1_btr(:) = 0._r8 - allocate (ef1_fet(lsize_o)) ; ef1_fet(:) = 0._r8 - allocate (ef1_fdt(lsize_o)) ; ef1_fdt(:) = 0._r8 - allocate (ef1_shr(lsize_o)) ; ef1_shr(:) = 0._r8 - allocate (ef1_grs(lsize_o)) ; ef1_grs(:) = 0._r8 - allocate (ef1_crp(lsize_o)) ; ef1_crp(:) = 0._r8 - if (fsurdat /= ' ') then - call mkvocef ( mksrf_fvocef_mesh, mksrf_fvocef, mesh_model, & - ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & - ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp, rc=rc) + if (fsurdat /= ' ') then + call mkvocef ( mksrf_fvocef_mesh, mksrf_fvocef, mesh_model, pioid, lat, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkvocef') - - ! If have pole points on grid - set south pole to glacier - ! north pole is assumed as non-land - do n = 1,lsize_o - if (abs((lat(n) - 90._r8)) < 1.e-6_r8) then - ef1_btr(n) = 0._r8 - ef1_fet(n) = 0._r8 - ef1_fdt(n) = 0._r8 - ef1_shr(n) = 0._r8 - ef1_grs(n) = 0._r8 - ef1_crp(n) = 0._r8 - end if - end do - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out voc emission factors" - call mkfile_output(pioid, mesh_model, 'EF1_BTR', ef1_btr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call mkfile_output(pioid, mesh_model, 'EF1_FET', ef1_fet, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call mkfile_output(pioid, mesh_model, 'EF1_FDT', ef1_fdt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call mkfile_output(pioid, mesh_model, 'EF1_SHR', ef1_shr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call mkfile_output(pioid, mesh_model, 'EF1_GRS', ef1_grs, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call mkfile_output(pioid, mesh_model, 'EF1_CRP', ef1_crp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call pio_syncfile(pioid) end if - deallocate (ef1_btr, ef1_fet, ef1_fdt, ef1_shr, ef1_grs, ef1_crp ) + ! ----------------------------------- + ! Adjust pctlak, pctwet, pcturb and pctgla + ! ----------------------------------- do n = 1,lsize_o - ! Do landuse changes such as for the poles, etc. ! If have pole points on grid - set south pole to glacier ! north pole is assumed as non-land if (abs((lat(n) - 90._r8)) < 1.e-6_r8) then @@ -853,6 +807,10 @@ program mksurfdata end if end do + ! ----------------------------------- + ! Perform other normalizations + ! ----------------------------------- + ! Normalize land use and make sure things add up to 100% as well as ! checking that things are as they should be. call normalize_and_check_landuse(lsize_o) @@ -893,8 +851,11 @@ program mksurfdata urban_skip_abort_on_invalid_data_check) deallocate(urban_region) + ! ----------------------------------- ! Write out PCT_URBAN, PCT_GLACIER, PCT_LAKE and PCT_WETLAND and ! PCT_NATVEG, PCT_NAT_PFT, PCT_CROP and PCT_CFT + ! ----------------------------------- + if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing out PCT_URBAN" call mkfile_output(pioid, mesh_model, 'PCT_URBAN', urban_classes_g, lev1name='numurbl', rc=rc) @@ -959,8 +920,6 @@ program mksurfdata allocate(pctglcmec_icesheet(lsize_o,nglcec)) allocate(pctglc_gic(lsize_o)) allocate(pctglc_icesheet(lsize_o)) - end if - if ( outnc_3dglc )then call mkglcmec(mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, & pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, & pctglcmec_gic_o=pctglcmec_gic, pctglcmec_icesheet_o=pctglcmec_icesheet, & diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index 3bc4345ed9..db08c8ebf2 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -4,38 +4,38 @@ module mkvarctl ! Module containing control variables !----------------------------------------------------------------------- - use ESMF use shr_kind_mod, only : r8 => shr_kind_r8 implicit none private - integer, public :: ndiag ! output log unit - logical, public :: root_task ! proc 0 logical for printing msgs - integer, public :: iam ! processor number - integer, public :: npes ! number of processors - integer, public :: mpicom ! communicator group + integer, public :: ndiag ! output log unit + logical, public :: root_task ! proc 0 logical for printing msgs + integer, public :: iam ! processor number + integer, public :: npes ! number of processors + integer, public :: mpicom ! communicator group - logical, public :: outnc_large_files ! output files in 64-bit format for large files - logical, public :: outnc_double ! output ALL data in files as 64-bit - integer, public :: outnc_dims = 2 ! only applicable to lat/lon grids - logical, public :: outnc_1d ! true => output file is 1d - logical, public :: outnc_vic ! true => output VIC fields - logical, public :: outnc_3dglc ! true => output 3D glacier fields + logical, public :: outnc_large_files ! output files in 64-bit format for large files + logical, public :: outnc_double ! output ALL data in files as 64-bit + integer, public :: outnc_dims = 2 ! only applicable to lat/lon grids + logical, public :: outnc_1d ! true => output file is 1d + logical, public :: outnc_vic ! true => output VIC fields + logical, public :: outnc_3dglc ! true => output 3D glacier fields integer , public :: soil_color_override real(r8), public :: soil_sand_override real(r8), public :: soil_clay_override real(r8), public :: soil_fmax_override - integer, public :: numpft = 16 ! number of plant types + integer, public :: numpft = 16 ! number of plant types ! Variables to override data read in with ! (all_urban is mostly for single-point mode, but could be used for sensitivity studies) - logical , public :: all_urban ! output ALL data as 100% covered in urban - logical , public :: all_veg ! if gridcell will be 100% vegetated land-cover - logical , public :: no_inlandwet ! set wetland to 0% over land; wetland will only be used for ocean points - real(r8) , public :: std_elev = -999.99_r8 ! Standard deviation of elevation (m) to use for ent + + logical , public :: all_urban ! output ALL data as 100% covered in urban + logical , public :: all_veg ! if gridcell will be 100% vegetated land-cover + logical , public :: no_inlandwet ! set wetland to 0% over land; wetland will only be used for ocean points + real(r8) , public :: std_elev = -999.99_r8 ! Standard deviation of elevation (m) to use for ent real(r8), public, parameter :: spval = 1.e36 ! special value integer, public, parameter :: ispval = -9999 ! special value diff --git a/tools/mksurfdata_esmf/src/mkvocefMod.F90 b/tools/mksurfdata_esmf/src/mkvocefMod.F90 index 6848102106..671a5e7ee2 100644 --- a/tools/mksurfdata_esmf/src/mkvocefMod.F90 +++ b/tools/mksurfdata_esmf/src/mkvocefMod.F90 @@ -13,6 +13,7 @@ module mkvocefMod use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag, mpicom, soil_color_override, unsetcol + use mkfileMod , only : mkfile_output implicit none private @@ -26,44 +27,41 @@ module mkvocefMod contains !================================================================================= - subroutine mkvocef(file_mesh_i, file_data_i, mesh_o, & - ef_btr_o, ef_fet_o, ef_fdt_o, ef_shr_o, ef_grs_o, ef_crp_o, rc) - + subroutine mkvocef(file_mesh_i, file_data_i, mesh_o, pioid_o, lat_o, rc) + ! ! make volatile organic coumpunds (VOC) emission factors. - + ! ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesho - real(r8) , intent(out) :: ef_btr_o(:) ! output grid: EFs for broadleaf trees - real(r8) , intent(out) :: ef_fet_o(:) ! output grid: EFs for fineleaf evergreen - real(r8) , intent(out) :: ef_fdt_o(:) ! output grid: EFs for fineleaf deciduous - real(r8) , intent(out) :: ef_shr_o(:) ! output grid: EFs for shrubs - real(r8) , intent(out) :: ef_grs_o(:) ! output grid: EFs for grasses - real(r8) , intent(out) :: ef_crp_o(:) ! output grid: EFs for crops - integer , intent(out) :: rc + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesho + type(file_desc_t) , intent(inout) :: pioid_o ! output file descripter + real(r8) , intent(in) :: lat_o(:) ! output latitudes + integer , intent(out) :: rc ! local variables: type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i - type(file_desc_t) :: pioid + type(file_desc_t) :: pioid_i integer :: ni,no integer :: ns_i, ns_o integer :: n,l,k integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) - real(r8), allocatable :: area_i(:) - real(r8), allocatable :: area_o(:) - real(r8), allocatable :: ef_btr_i(:) ! input grid: EFs for broadleaf trees - real(r8), allocatable :: ef_fet_i(:) ! input grid: EFs for fineleaf evergreen - real(r8), allocatable :: ef_fdt_i(:) ! input grid: EFs for fineleaf deciduous - real(r8), allocatable :: ef_shr_i(:) ! input grid: EFs for shrubs - real(r8), allocatable :: ef_grs_i(:) ! input grid: EFs for grasses - real(r8), allocatable :: ef_crp_i(:) ! input grid: EFs for crops - real(r8) :: sum_fldo ! global sum of dummy input fld - real(r8) :: sum_fldi ! global sum of dummy input fld - integer :: ier, rcode ! error status + real(r8), allocatable :: ef_btr_i(:) ! input grid: EFs for broadleaf trees + real(r8), allocatable :: ef_fet_i(:) ! input grid: EFs for fineleaf evergreen + real(r8), allocatable :: ef_fdt_i(:) ! input grid: EFs for fineleaf deciduous + real(r8), allocatable :: ef_shr_i(:) ! input grid: EFs for shrubs + real(r8), allocatable :: ef_grs_i(:) ! input grid: EFs for grasses + real(r8), allocatable :: ef_crp_i(:) ! input grid: EFs for crops + real(r8), allocatable :: ef_btr_o(:) ! output grid: EFs for broadleaf trees + real(r8), allocatable :: ef_fet_o(:) ! output grid: EFs for fineleaf evergreen + real(r8), allocatable :: ef_fdt_o(:) ! output grid: EFs for fineleaf deciduous + real(r8), allocatable :: ef_shr_o(:) ! output grid: EFs for shrubs + real(r8), allocatable :: ef_grs_o(:) ! output grid: EFs for grasses + real(r8), allocatable :: ef_crp_o(:) ! output grid: EFs for crops + integer :: ier, rcode ! error status real(r8) :: relerr = 0.00001_r8 ! max error: sum overlap wts ne 1 character(len=*), parameter :: subname = 'mkvocef' !----------------------------------------------------------------------- @@ -81,7 +79,7 @@ subroutine mkvocef(file_mesh_i, file_data_i, mesh_o, & end if ! Open input data file - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh @@ -97,12 +95,20 @@ subroutine mkvocef(file_mesh_i, file_data_i, mesh_o, & call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Allocate output variables + allocate (ef_btr_o(ns_o)) ; ef_btr_o(:) = 0._r8 + allocate (ef_fet_o(ns_o)) ; ef_fet_o(:) = 0._r8 + allocate (ef_fdt_o(ns_o)) ; ef_fdt_o(:) = 0._r8 + allocate (ef_shr_o(ns_o)) ; ef_shr_o(:) = 0._r8 + allocate (ef_grs_o(ns_o)) ; ef_grs_o(:) = 0._r8 + allocate (ef_crp_o(ns_o)) ; ef_crp_o(:) = 0._r8 + ! Get the landmask from the input data file and reset the mesh mask based on that allocate(frac_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i if (frac_i(ni) > 0._r8) then @@ -121,21 +127,30 @@ subroutine mkvocef(file_mesh_i, file_data_i, mesh_o, & call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) ! Read input Emission Factors - allocate(ef_btr_i(ns_i), ef_fet_i(ns_i), ef_fdt_i(ns_i), & - ef_shr_i(ns_i), ef_grs_i(ns_i), ef_crp_i(ns_i), stat=ier) + allocate (ef_btr_i(ns_i)) + if (ier/=0) call shr_sys_abort() + allocate (ef_fet_i(ns_i)) + if (ier/=0) call shr_sys_abort() + allocate (ef_fdt_i(ns_i)) + if (ier/=0) call shr_sys_abort() + allocate (ef_shr_i(ns_i)) + if (ier/=0) call shr_sys_abort() + allocate (ef_grs_i(ns_i)) + if (ier/=0) call shr_sys_abort() + allocate (ef_crp_i(ns_i)) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'ef_btr', mesh_i, ef_btr_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'ef_btr', mesh_i, ef_btr_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call mkpio_get_rawdata(pioid, 'ef_fet', mesh_i, ef_fet_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'ef_fet', mesh_i, ef_fet_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call mkpio_get_rawdata(pioid, 'ef_fdt', mesh_i, ef_fdt_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'ef_fdt', mesh_i, ef_fdt_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call mkpio_get_rawdata(pioid, 'ef_shr', mesh_i, ef_shr_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'ef_shr', mesh_i, ef_shr_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call mkpio_get_rawdata(pioid, 'ef_grs', mesh_i, ef_grs_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'ef_grs', mesh_i, ef_grs_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call mkpio_get_rawdata(pioid, 'ef_crp', mesh_i, ef_crp_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'ef_crp', mesh_i, ef_crp_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Regrid input data to model resolution @@ -180,14 +195,52 @@ subroutine mkvocef(file_mesh_i, file_data_i, mesh_o, & end if enddo - ! Deallocate memory - deallocate ( ef_btr_i, ef_fet_i, ef_fdt_i, ef_shr_i, ef_grs_i, ef_crp_i, frac_o) + + ! If have pole points on grid - set south pole to glacier + ! north pole is assumed as non-land + do no = 1,ns_o + if (abs((lat_o(no) - 90._r8)) < 1.e-6_r8) then + ef_btr_o(no) = 0._r8 + ef_fet_o(no) = 0._r8 + ef_fdt_o(no) = 0._r8 + ef_shr_o(no) = 0._r8 + ef_grs_o(no) = 0._r8 + ef_crp_o(no) = 0._r8 + end if + end do + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out voc emission factors" + call mkfile_output(pioid_o, mesh_o, 'EF1_BTR', ef_btr_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call mkfile_output(pioid_o, mesh_o, 'EF1_FET', ef_fet_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call mkfile_output(pioid_o, mesh_o, 'EF1_FDT', ef_fdt_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call mkfile_output(pioid_o, mesh_o, 'EF1_SHR', ef_shr_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call mkfile_output(pioid_o, mesh_o, 'EF1_GRS', ef_grs_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call mkfile_output(pioid_o, mesh_o, 'EF1_CRP', ef_crp_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) + + ! ----------------------------------------------------------------- + ! Wrap up + ! ----------------------------------------------------------------- + + ! Close the input file + call pio_closefile(pioid_i) + call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) + + ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) if (root_task) then write (ndiag,'(a)') 'Successfully made VOC Emission Factors' - write (ndiag,*) end if end subroutine mkvocef From 362881c5431d931530456df1f1e37170b417a498 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 22 Feb 2022 20:22:58 -0700 Subject: [PATCH 073/614] refactor of mksurfdata --- tools/mksurfdata_esmf/gen_mksurfdata | 6 +- tools/mksurfdata_esmf/src/mkdomainMod.F90 | 23 ++++- .../src/mkglacierregionMod.F90 | 30 +++--- tools/mksurfdata_esmf/src/mklaiMod.F90 | 1 + tools/mksurfdata_esmf/src/mklanwatMod.F90 | 54 +++++++---- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 95 +++++++++++++------ tools/mksurfdata_esmf/src/mksurfdata.F90 | 92 +++--------------- 7 files changed, 150 insertions(+), 151 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata b/tools/mksurfdata_esmf/gen_mksurfdata index b846a444fc..22cb1b8683 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata +++ b/tools/mksurfdata_esmf/gen_mksurfdata @@ -28,6 +28,6 @@ mkdir -p $TMPDIR # ln -s $fname mksurfdata_in # Run the model -#mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata - mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata -#mpiexec_mpt -p "%g:" -np 384 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/run/mksurfdata +#mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata + mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata +#mpiexec_mpt -p "%g:" -np 384 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata diff --git a/tools/mksurfdata_esmf/src/mkdomainMod.F90 b/tools/mksurfdata_esmf/src/mkdomainMod.F90 index 34e51e3d53..a2ebda4a59 100644 --- a/tools/mksurfdata_esmf/src/mkdomainMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdomainMod.F90 @@ -5,9 +5,12 @@ module mkdomainMod !------------------------------- use ESMF + use pio use shr_kind_mod, only : r8 => shr_kind_r8 + use shr_sys_mod , only : shr_sys_abort use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag + use mkfileMod , only : mkfile_output implicit none private @@ -21,13 +24,14 @@ module mkdomainMod contains !================================================================================= - subroutine mkdomain(mesh_o, lon_o, lat_o, rc) + subroutine mkdomain(mesh_o, lon_o, lat_o, pioid_o, rc) ! input output variables - type(ESMF_Mesh) , intent(in) :: mesh_o - real(r8) , intent(out) :: lon_o(:) - real(r8) , intent(out) :: lat_o(:) - integer , intent(out) :: rc + type(ESMF_Mesh) , intent(in) :: mesh_o + real(r8) , intent(out) :: lon_o(:) + real(r8) , intent(out) :: lat_o(:) + type(file_desc_t) , intent(inout) :: pioid_o + integer , intent(out) :: rc ! local variables: integer :: no @@ -57,6 +61,15 @@ subroutine mkdomain(mesh_o, lon_o, lat_o, rc) lat_o(no) = ownedElemCoords(2*no) end do + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out model grid" + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" + call mkfile_output(pioid_o, mesh_o, 'LONGXY', lon_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LATIXY" + call mkfile_output(pioid_o, mesh_o, 'LATIXY', lat_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) + if (root_task) then write (ndiag,'(a)') 'Successfully made model lats and lons' end if diff --git a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 index 990feac4f6..176271a48c 100644 --- a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 @@ -15,6 +15,7 @@ module mkglacierregionMod use mkvarctl , only : ndiag, root_task use mkdiagnosticsMod , only : output_diagnostics_index use mkutilsMod , only : chkerr + use mkfileMod , only : mkfile_output implicit none private @@ -30,21 +31,21 @@ module mkglacierregionMod contains !================================================================================= - subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, rc) + subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! ! Make glacier region ID ! ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh - integer , intent(out) :: glacier_region_o(:) ! glacier region - integer , intent(out) :: rc + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + type(file_desc_t) , intent(inout) :: pioid_o + integer , intent(out) :: rc ! local variables: type(ESMF_RouteHandle) :: routehandle ! nearest neighbor routehandle type(ESMF_Mesh) :: mesh_i - type(file_desc_t) :: pioid + type(file_desc_t) :: pioid_i integer :: ni,no,l,k integer :: ns_i, ns_o integer , allocatable :: mask_i(:) @@ -53,6 +54,7 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r real(r8), allocatable :: data_i(:,:) real(r8), allocatable :: data_o(:,:) integer , allocatable :: glacier_region_i(:) ! glacier region on input grid + integer , allocatable :: glacier_region_o(:) ! glacier region on output grid integer :: ier, rcode ! error status integer :: max_index(1) character(len=*), parameter :: subname = 'mkglacierregion' @@ -71,7 +73,7 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r call ESMF_VMLogMemInfo("At start of "//trim(subname)) ! Open input data file - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) ! Read in input mesh mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) @@ -82,14 +84,15 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine ns_o + ! Determine ns_o and allocate output data call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate (glacier_region_o(ns_o)) ; glacier_region_o(:) = -999 ! Read in input data (Confirm that no value of glacier_region is less than min_allowed) allocate(glacier_region_i(ns_i), stat=ier) if (ier/=0) call abort() - call mkpio_get_rawdata(pioid, 'GLACIER_REGION', mesh_i, glacier_region_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'GLACIER_REGION', mesh_i, glacier_region_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (min_bad(glacier_region_i, 0, 'GLACIER_REGION')) then call shr_sys_abort() @@ -142,6 +145,11 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r max_index = maxloc(data_o(:,no)) glacier_region_o(no) = max_index(1) - 1 end do + + ! Write output data + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out glacier_region" + call mkfile_output(pioid_o, mesh_o, 'GLACIER_REGION', glacier_region_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') ! Determine global diagnostics call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & @@ -149,7 +157,7 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, glacier_region_o, r if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() ! Close the input file - call pio_closefile(pioid) + call pio_closefile(pioid_i) ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mklaiMod.F90 b/tools/mksurfdata_esmf/src/mklaiMod.F90 index 26850d065d..78fc406e3d 100644 --- a/tools/mksurfdata_esmf/src/mklaiMod.F90 +++ b/tools/mksurfdata_esmf/src/mklaiMod.F90 @@ -265,6 +265,7 @@ subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) end if end do ! end loop over months + call pio_syncfile(pioid_o) ! Free the decomps and close the file call pio_freedecomp(pioid_o, pio_iodesc_o) diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index c0490cc39a..19d96bf368 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -6,15 +6,16 @@ module mklanwatMod !----------------------------------------------------------------------- use ESMF + use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite, pio_syncfile use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 use shr_sys_mod , only : shr_sys_abort - use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkdiagnosticsMod , only : output_diagnostics_continuous use mkchecksMod , only : min_bad use mkutilsMod , only : chkerr - use mkvarctl , only : root_task, ndiag + use mkvarctl , only : root_task, ndiag, spval + use mkfileMod , only : mkfile_output implicit none private @@ -28,34 +29,37 @@ module mklanwatMod contains !=============================================================== - subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & - zero_out_lake, zero_out_wetland, lake_o, swmp_o, lakedepth_o, rc) + subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & + zero_out_lake, zero_out_wetland, lake_o, swmp_o, & + pioid_o, fsurdat, rc) ! ------------------- ! make %lake, %wetland and lake parameters ! ------------------- ! input/output variables - type(ESMF_Mesh) , intent(in) :: mesh_o - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - logical , intent(in) :: zero_out_lake ! if should zero glacier out - logical , intent(in) :: zero_out_wetland ! if should zero glacier out - real(r8) , intent(out) :: lake_o(:) ! output grid: %lake - real(r8) , intent(out) :: swmp_o(:) ! output grid: %lake - real(r8) , intent(out) :: lakedepth_o(:) ! output grid: lake depth (m) - integer , intent(out) :: rc + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o + logical , intent(in) :: zero_out_lake ! if should zero glacier out + logical , intent(in) :: zero_out_wetland ! if should zero glacier out + type(file_desc_t) , intent(inout) :: pioid_o + real(r8) , intent(out) :: lake_o(:) ! output grid: %lake + real(r8) , intent(out) :: swmp_o(:) ! output grid: %lake + character(len=*) , intent(in) :: fsurdat + integer , intent(out) :: rc ! local variables type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i - type(file_desc_t) :: pioid + type(file_desc_t) :: pioid_i integer , allocatable :: mask_i(:) real(r8), allocatable :: rmask_i(:) real(r8), allocatable :: frac_o(:) real(r8), allocatable :: lake_i(:) ! input grid: percent lake real(r8), allocatable :: swmp_i(:) ! input grid: percent wetland - real(r8), allocatable :: lakedepth_i(:) ! iput grid: lake depth + real(r8), allocatable :: lakedepth_i(:) ! iput grid: lake depth (m) + real(r8), allocatable :: lakedepth_o(:) ! output grid: lake depth (m) integer :: ni,no,k ! indices integer :: ns_i,ns_o ! local sizes integer :: ier,rcode ! error status @@ -76,7 +80,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & ! Open raw data file ! ASSUME for now that have only 1 input data file - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) ! Read in input mesh mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) @@ -96,7 +100,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, rmask_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i if (rmask_i(ni) > 0._r8) then @@ -127,7 +131,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & ! Read in lake_i allocate(lake_i(ns_i), stat=rcode) if (rcode/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'PCT_LAKE', mesh_i, lake_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'PCT_LAKE', mesh_i, lake_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Regrid lake_i to lake_o @@ -158,7 +162,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & ! read in swmp_i allocate(swmp_i(ns_i), stat=rcode) if (rcode/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'PCT_WETLAND', mesh_i, lake_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'PCT_WETLAND', mesh_i, lake_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! regrid swmp_i to swmp_o - this also returns swmp_i to be used in the global sums below @@ -189,10 +193,11 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & ! lakedepth allocate(lakedepth_i(ns_i), stat=rcode) if (rcode/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LAKEDEPTH', mesh_i, lakedepth_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'LAKEDEPTH', mesh_i, lakedepth_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! regrid lakedepth_i to lakedepth_o - this also returns lakedepth_i to be used in the global sums below + allocate (lakedepth_o(ns_o)); lakedepth_o(:) = spval call regrid_rawdata(mesh_i, mesh_o, routehandle, lakedepth_i, lakedepth_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regrid_rawdata for lakedepth in "//trim(subname)) @@ -205,13 +210,20 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & call shr_sys_abort() end if + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out lakedepth" + call mkfile_output(pioid_o, mesh_o, 'LAKEDEPTH', lakedepth_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) + end if + ! Check global areas call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & lakedepth_i, lakedepth_o, "lake depth", "m", ndiag, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Close the single input data file - call pio_closefile(pioid) + call pio_closefile(pioid_i) ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 4bbaf7ba31..8e52857938 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -12,8 +12,10 @@ module mksoiltexMod use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem use mkutilsMod , only : chkerr use mkdiagnosticsMod , only : output_diagnostics_index - use mkvarctl , only : root_task, ndiag + use mkfileMod , only : mkfile_output + use mkvarctl , only : root_task, ndiag, spval use mkvarctl , only : unsetsoil, soil_clay_override, soil_sand_override + use mkvarpar , only : nlevsoi implicit none private ! By default make data private @@ -31,7 +33,7 @@ module mksoiltexMod contains !================================================================================= - subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o, rc) + subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc) ! ! make %sand and %clay from IGBP soil data, which includes ! igbp soil 'mapunits' and their corresponding textures @@ -40,9 +42,8 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh - real(r8) , intent(inout) :: sand_o(:,:) ! % sand (output grid) - real(r8) , intent(inout) :: clay_o(:,:) ! % clay (output grid) - integer , intent(inout) :: mapunit_o(:) + type(file_desc_t) , intent(inout) :: pioid_o + real(r8) , intent(in) :: pctlnd_pft_o(:) ! PFT data: % of gridcell for PFTs integer , intent(out) :: rc ! local variables @@ -51,31 +52,34 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o type(ESMF_Field) :: field_i type(ESMF_Field) :: field_o type(ESMF_Field) :: field_dstfrac - type(file_desc_t) :: pioid + type(file_desc_t) :: pioid_i type(var_desc_t) :: pio_varid integer :: pio_vartype integer :: dimid integer :: ni,no integer :: ns_i, ns_o integer :: k,l,m,n - integer :: nlay ! number of soil layers + integer :: nlay ! number of soil layers integer , allocatable :: mask_i(:) real(r4), allocatable :: rmask_i(:) real(r8), allocatable :: frac_o(:) - real(r4), allocatable :: sand_i(:,:) ! input grid: percent sand - real(r4), allocatable :: clay_i(:,:) ! input grid: percent clay - real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits + real(r4), allocatable :: sand_i(:,:) ! input grid: percent sand + real(r4), allocatable :: clay_i(:,:) ! input grid: percent clay + real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits + real(r8), allocatable :: sand_o(:,:) ! % sand (output grid) + real(r8), allocatable :: clay_o(:,:) ! % clay (output grid) + integer , allocatable :: mapunit_o(:) real(r4), pointer :: dataptr(:) real(r8), pointer :: dataptr_r8(:) real(r4) :: sumtex - integer :: mapunit ! temporary igbp soil mapunit + integer :: mapunit ! temporary igbp soil mapunit integer, allocatable :: soil_i(:) integer, allocatable :: soil_o(:) - integer :: rcode, ier ! error status + integer :: rcode, ier ! error status integer :: srcTermProcessing_Value = 0 - integer, parameter :: nlsm=4 ! number of soil textures - character(len=38) :: soil(0:nlsm) ! name of each soil texture - character(len=38) :: typ ! soil texture based on ... + integer, parameter :: nlsm=4 ! number of soil textures + character(len=38) :: soil(0:nlsm) ! name of each soil texture + character(len=38) :: typ ! soil texture based on ... character(len=*), parameter :: subname = 'mksoiltex' !----------------------------------------------------------------------- @@ -109,6 +113,13 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o end if end if + ! Determine ns_o and allocate output data + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(mapunit_o(ns_o)) ; mapunit_o(:) = 0 + allocate(sand_o(ns_o,nlevsoi)) ; sand_o(:,:) = spval + allocate(clay_o(ns_o,nlevsoi)) ; clay_o(:,:) = spval + if (soil_sand_override /= unsetsoil .and. soil_clay_override /= unsetsoil) then if (root_task) then write(ndiag,'(a,i8)') ' Overriding soil sand for all points with: ', soil_sand_override @@ -121,7 +132,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o ! Open input data file call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) ! Read in input mesh call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) @@ -133,16 +144,12 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine ns_o and allocate data_o - call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Get the landmask from the file and reset the mesh mask based on that allocate(rmask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, rmask_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i if (rmask_i(ni) > 0._r4) then @@ -157,7 +164,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o ! Read in mapunit data allocate(mapunit_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'MAPUNITS', mesh_i, mapunit_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'MAPUNITS', mesh_i, mapunit_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -168,8 +175,8 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o ! Determine mapunit_value_max (set it as a module variable so that it can be ! accessible to gen_dominant_mapunit) - rcode = pio_inq_dimid (pioid, 'max_value_mapunit', dimid) - rcode = pio_inq_dimlen (pioid, dimid, mapunit_value_max) + rcode = pio_inq_dimid (pioid_i, 'max_value_mapunit', dimid) + rcode = pio_inq_dimlen (pioid_i, dimid, mapunit_value_max) ! Create ESMF fields that will be used below field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) @@ -217,18 +224,18 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o end do ! Get dimensions from input file and allocate memory for sand_i and clay_i - rcode = pio_inq_dimid (pioid, 'number_of_layers', dimid) - rcode = pio_inq_dimlen (pioid, dimid, nlay) + rcode = pio_inq_dimid (pioid_i, 'number_of_layers', dimid) + rcode = pio_inq_dimlen (pioid_i, dimid, nlay) allocate(sand_i(mapunit_value_max,nlay), stat=ier) if (ier/=0) call shr_sys_abort() allocate(clay_i(mapunit_value_max,nlay), stat=ier) if (ier/=0) call shr_sys_abort() ! read in sand_i and clay_i (they will read in total on all processors) - rcode = pio_inq_varid(pioid, 'PCT_SAND', pio_varid) - rcode = pio_get_var(pioid, pio_varid, sand_i) - rcode = pio_inq_varid(pioid, 'PCT_CLAY', pio_varid) - rcode = pio_get_var(pioid, pio_varid, clay_i) + rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid) + rcode = pio_get_var(pioid_i, pio_varid, sand_i) + rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid) + rcode = pio_get_var(pioid_i, pio_varid, clay_i) ! Set soil texture as follows: ! a. Use dominant igbp soil mapunit based on area of overlap unless 'no data' is dominant @@ -327,6 +334,34 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, sand_o, clay_o, mapunit_o 0, nlsm, soil_i, soil_o, 'soil texture class', ndiag, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Adjust pct sand and pct clay to be nearest integers and to be loam if pctlnd_pft is < 1.e-6 + ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero + ! (not a very small number such as 1e-16) where it really should be zero + do no = 1,ns_o + do k = 1,nlevsoi + sand_o(no,k) = float(nint(sand_o(no,k))) + clay_o(no,k) = float(nint(clay_o(no,k))) + end do + if (pctlnd_pft_o(no) < 1.e-6_r8) then + sand_o(no,:) = 43._r8 + clay_o(no,:) = 18._r8 + end if + end do + + ! Write out fields + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" + call mkfile_output(pioid_o, mesh_o, 'mapunits', mapunit_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" + call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" + call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) + ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 610307f0ce..c6fd1f2caa 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -156,9 +156,6 @@ program mksurfdata type(pct_pft_type), allocatable :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series type(pct_pft_type), allocatable :: pctcft_max(:) ! % of grid cell maximum CFTs of the time series - ! harvest initial value - real(r8) :: harvest_initval ! initial value for harvest variables - ! soil fracation saturated area data real(r8), allocatable :: fmaxsoil(:) ! soil_fractional saturated area @@ -205,11 +202,6 @@ program mksurfdata integer :: nsoilcol ! number of model color classes integer , allocatable :: soil_color(:) ! soil color - ! soil texture data - real(r8), allocatable :: pctsand(:,:) ! soil texture: percent sand - real(r8), allocatable :: pctclay(:,:) ! soil texture: percent clay - integer , allocatable :: mapunits(:) ! input grid: igbp soil mapunits - ! soil depth data real(r8), allocatable :: soildepth(:) ! soil depth (m) @@ -391,28 +383,10 @@ program mksurfdata ! ----------------------------------- allocate (lon(lsize_o)) ; lon(:) = spval allocate (lat(lsize_o)) ; lat(:) = spval - call mkdomain(mesh_model, lon_o=lon, lat_o=lat, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out model grid" - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" - call mkfile_output(pioid, mesh_model, 'LONGXY', lon, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LATIXY" - call mkfile_output(pioid, mesh_model, 'LATIXY', lat, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - end if - - !DEBUG - if (fsurdat /= ' ' .and. outnc_vic) then - call mkVICparams ( mksrf_fvic_mesh, mksrf_fvic, mesh_model, pioid, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') - end if - if (fsurdat /= ' ' ) then - call mkvocef ( mksrf_fvocef_mesh, mksrf_fvocef, mesh_model, pioid, lat, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkvocef') + call mkdomain(mesh_model, lon_o=lon, lat_o=lat, pioid_o=pioid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') end if - !DEBUG ! ----------------------------------- ! Make LAI and SAI from 1/2 degree data and write to surface dataset @@ -423,7 +397,6 @@ program mksurfdata end if call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') - call pio_syncfile(pioid) ! ----------------------------------- ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] @@ -480,26 +453,18 @@ program mksurfdata call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, & pioid_o=pioid, all_veg=all_veg, constant=.true., rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') - call pio_syncfile(pioid) ! ----------------------------------- ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] ! ----------------------------------- - allocate ( pctlak(lsize_o)) ; pctlak(:) = spval - allocate ( pctwet(lsize_o)) ; pctwet(:) = spval - allocate ( lakedepth(lsize_o)) ; lakedepth(:) = spval + ! LAKEDEPTH is written out in mklakwat + allocate ( pctlak(lsize_o)) ; pctlak(:) = spval + allocate ( pctwet(lsize_o)) ; pctwet(:) = spval zero_out_lake = (all_urban .or. all_veg) zero_out_wetland = (all_urban .or. all_veg .or. no_inlandwet) call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & - zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc=rc) + zero_out_lake, zero_out_wetland, pctlak, pctwet, pioid, fsurdat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') - if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out lakedepth" - call mkfile_output(pioid, mesh_model, 'LAKEDEPTH', lakedepth, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call pio_syncfile(pioid) - end if - deallocate (lakedepth ) ! ----------------------------------- ! Make glacier fraction [pctgla] from [fglacier] dataset @@ -516,58 +481,23 @@ program mksurfdata pctgla(:) = 0. end if end if - call pio_syncfile(pioid) ! ----------------------------------- ! Make glacier region ID [glacier_region] from [fglacierregion] dataset ! ----------------------------------- - allocate (glacier_region(lsize_o)) ; glacier_region(:) = -999 - call mkglacierregion(mksrf_fglacierregion_mesh, mksrf_fglacierregion, mesh_model, glacier_region, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacierregion') if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out glacier_region" - call mkfile_output(pioid, mesh_model, 'GLACIER_REGION', glacier_region, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + ! Note that GLACIER_REGION is written out in the subroutine + call mkglacierregion(mksrf_fglacierregion_mesh, mksrf_fglacierregion, mesh_model, pioid, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacierregion') end if - deallocate (glacier_region ) - call pio_syncfile(pioid) ! ----------------------------------- ! Make soil texture [pctsand, pctclay] ! ----------------------------------- - ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero - ! (not a very small number such as 1e-16) where it really should be zero - allocate(mapunits(lsize_o)) ; mapunits(:) = 0 - allocate(pctsand(lsize_o,nlevsoi)) ; pctsand(:,:) = spval - allocate(pctclay(lsize_o,nlevsoi)) ; pctclay(:,:) = spval - call mksoiltex( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pctsand, pctclay, mapunits, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') - do n = 1,lsize_o - do k = 1,nlevsoi - pctsand(n,k) = float(nint(pctsand(n,k))) - pctclay(n,k) = float(nint(pctclay(n,k))) - end do - if (pctlnd_pft(n) < 1.e-6_r8) then - pctsand(n,:) = 43._r8 - pctclay(n,:) = 18._r8 - end if - end do if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" - call mkfile_output(pioid, mesh_model, 'mapunits', mapunits, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" - call mkfile_output(pioid, mesh_model, 'PCT_SAND', pctsand, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" - call mkfile_output(pioid, mesh_model, 'PCT_CLAY', pctclay, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call pio_syncfile(pioid) + call mksoiltex( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pioid, pctlnd_pft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') end if - deallocate (pctsand) - deallocate (pctclay ) ! ----------------------------------- ! Make soil color classes [soicol] [fsoicol] From 37363c4d3628618467f57907ddb0c93142a8d992 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 22 Feb 2022 22:12:35 -0700 Subject: [PATCH 074/614] more cleanup of mksurfdata.F90 --- .../src/mkagfirepkmonthMod.F90 | 35 +++++--- tools/mksurfdata_esmf/src/mkpeatMod.F90 | 29 ++++--- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 45 +++++++--- tools/mksurfdata_esmf/src/mksoildepthMod.F90 | 38 +++++---- tools/mksurfdata_esmf/src/mksurfdata.F90 | 82 +++---------------- tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 46 +++++++---- 6 files changed, 136 insertions(+), 139 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 index e6d255d501..6115e813f9 100644 --- a/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 +++ b/tools/mksurfdata_esmf/src/mkagfirepkmonthMod.F90 @@ -5,14 +5,15 @@ module mkagfirepkmonthMod !----------------------------------------------------------------------- use ESMF + use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite, pio_syncfile use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 use shr_sys_mod , only : shr_sys_abort - use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem use mkvarctl , only : ndiag, root_task use mkchecksMod , only : min_bad, max_bad use mkdiagnosticsMod , only : output_diagnostics_index use mkutilsMod , only : chkerr + use mkfileMod , only : mkfile_output implicit none private ! By default make data private @@ -32,16 +33,16 @@ module mkagfirepkmonthMod contains !=============================================================== - subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) + subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! ! Make agricultural fire peak month data from higher resolution data ! ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh - integer , intent(inout) :: agfirepkmon_o(:) ! agricultural fire peak month - integer , intent(out) :: rc + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + type(file_desc_t) , intent(inout) :: pioid_o + integer , intent(out) :: rc ! ! local variables: type(ESMF_RouteHandle) :: routehandle @@ -49,7 +50,7 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) type(ESMF_Field) :: field_i type(ESMF_Field) :: field_o type(ESMF_Field) :: field_dstfrac - type(file_desc_t) :: pioid + type(file_desc_t) :: pioid_i integer :: k integer :: ni,no integer :: ns_i, ns_o @@ -57,6 +58,7 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) real(r4), allocatable :: rmask_i(:) real(r8), allocatable :: frac_o(:) integer , allocatable :: idata_i(:) ! input grid: agricultural fire peak month + integer , allocatable :: agfirepkmon_o(:) ! agricultural fire peak month real(r4), pointer :: dataptr(:) real(r8), pointer :: dataptr_r8(:) integer :: rcode, ier ! error status @@ -74,7 +76,7 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) end if ! Open input data file - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh @@ -86,16 +88,17 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine ns_o + ! Determine ns_o and allocate output data call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate (agfirepkmon_o(ns_o)); agfirepkmon_o(:) = -999 ! Get the landmask from the file and reset the mesh mask based on that allocate(rmask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort(subname//" ERROR in allocating rmask_i") allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort(subname//" ERROR in allocating mask_i") - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, rmask_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i if (rmask_i(ni) > 0.) then @@ -110,7 +113,7 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) ! Read in agfirepkmon_i allocate(idata_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort(subname//" error in allocating idata_i") - call mkpio_get_rawdata(pioid, 'abm', mesh_i, idata_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'abm', mesh_i, idata_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -165,7 +168,13 @@ subroutine mkagfirepkmon(file_mesh_i, file_data_i, mesh_o, agfirepkmon_o, rc) end if ! Close the file - call pio_closefile(pioid) + call pio_closefile(pioid_i) + + ! Write out data + if (root_task) write(ndiag, '(a)') trim(subname)//" writing abm (agricultural fire peak month)" + call mkfile_output(pioid_o, mesh_o, 'abm', agfirepkmon_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) ! Output diagnostics comparing global area of each peak month on input and output grids call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & diff --git a/tools/mksurfdata_esmf/src/mkpeatMod.F90 b/tools/mksurfdata_esmf/src/mkpeatMod.F90 index 3d5aca76ba..87ce2dd6c8 100644 --- a/tools/mksurfdata_esmf/src/mkpeatMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpeatMod.F90 @@ -7,13 +7,14 @@ module mkpeatMod use ESMF use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 use shr_sys_mod , only : shr_sys_abort - use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite + use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite, pio_syncfile use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 - use mkvarctl , only : ndiag, root_task, mpicom + use mkvarctl , only : ndiag, root_task, mpicom, spval use mkchecksMod , only : min_bad, max_bad use mkdiagnosticsMod , only : output_diagnostics_continuous use mkutilsMod , only : chkerr + use mkfileMod , only : mkfile_output implicit none private @@ -27,25 +28,26 @@ module mkpeatMod contains !=============================================================== - subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) + subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! input/output variables character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! input model mesh - real(r8) , intent(inout) :: peat_o(:) ! output grid: fraction peat + type(file_desc_t) , intent(inout) :: pioid_o integer , intent(out) :: rc ! local variables: type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i - type(file_desc_t) :: pioid + type(file_desc_t) :: pioid_i integer :: ni,no,k integer :: ns_i, ns_o integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) real(r8), allocatable :: peat_i(:) ! input grid: percent peat + real(r8), allocatable :: peat_o(:) ! output grid: fraction peat integer :: ier, rcode ! error status real(r8), parameter :: min_valid = 0._r8 ! minimum valid value real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value @@ -63,7 +65,7 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) call ESMF_VMLogMemInfo("At start of "//trim(subname)) ! Open input data file - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) ! Read in input mesh mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) @@ -74,16 +76,17 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine ns_o + ! Determine ns_o and allocate output data call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate (peat_o(ns_o)) ; peat_o(:) = spval ! Get the landmask from the file and reset the mesh mask based on that allocate(frac_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i if (frac_i(ni) > 0._r8) then @@ -98,7 +101,7 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) ! Read in peat_i allocate(peat_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'peatf', mesh_i, peat_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'peatf', mesh_i, peat_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -116,13 +119,19 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, peat_o, rc) call shr_sys_abort(subname//" peat_o does not fall in range of min_valid/max_valid") end if + ! Write out data to output file + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out peatland fraction" + call mkfile_output(pioid_o, mesh_o, 'peatf', peat_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) + ! Output diagnostic info call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & peat_i, peat_o, "Peat", "unitless", ndiag, rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() ! Close the file - call pio_closefile(pioid) + call pio_closefile(pioid_i) ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index da2bfb1f25..04e18fe661 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -1,13 +1,15 @@ module mksoilcolMod use ESMF + use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite + use pio , only : pio_syncfile, pio_inq_varid, pio_put_var, var_desc_t use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 use shr_sys_mod , only : shr_sys_abort - use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem use mkvarctl , only : root_task, ndiag, mpicom, unsetcol, soil_color_override use mkdiagnosticsMod , only : output_diagnostics_index use mkutilsMod , only : chkerr + use mkfileMod , only : mkfile_output implicit none private @@ -27,14 +29,14 @@ module mksoilcolMod contains !================================================================================= - subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, rc) + subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, pctlnd_pft_o, pioid_o, rc) ! input/output variables character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesho - integer , intent(inout) :: soil_color_o(:) ! soil color classes - integer , intent(out) :: nsoilcol ! number of soil colors + real(r8) , intent(in) :: pctlnd_pft_o(:) + type(file_desc_t) , intent(inout) :: pioid_o integer , intent(out) :: rc ! local variables: @@ -43,13 +45,16 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r type(ESMF_Field) :: field_i type(ESMF_Field) :: field_o type(ESMF_Field) :: field_dstfrac - type(file_desc_t) :: pioid + type(file_desc_t) :: pioid_i + type(var_desc_t) :: pio_varid integer :: ni,no, k integer :: ns_i, ns_o integer , allocatable :: mask_i(:) real(r4), allocatable :: rmask_i(:) real(r8), allocatable :: frac_o(:) real(r4), allocatable :: soil_color_i(:) + integer , allocatable :: soil_color_o(:) ! soil color classes + integer :: nsoilcol ! number of soil colors real(r4), pointer :: dataptr(:) real(r8), pointer :: dataptr_r8(:) integer :: nsoilcol_local @@ -84,7 +89,7 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r ! Open soil color data file call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) ! Read in input mesh call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) @@ -96,16 +101,17 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine ns_o + ! Determine ns_o and allocate output data call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate (soil_color_o(ns_o)); soil_color_o(:) = -999 ! Get the landmask from the file and reset the mesh mask based on that allocate(rmask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, rmask_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i if (rmask_i(ni) > 0._r4) then @@ -121,7 +127,7 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r ! Read in input soil color data allocate(soil_color_i(ns_i),stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'SOIL_COLOR', mesh_i, soil_color_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'SOIL_COLOR', mesh_i, soil_color_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -155,7 +161,7 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - ! Determin frac_o + ! Determine frac_o call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return allocate(frac_o(ns_o)) @@ -189,11 +195,30 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, soil_color_o, nsoilcol, r end if end do + ! assume medium soil color (15) and loamy texture if pct_lndpft is small + do no = 1,ns_o + if (pctlnd_pft_o(no) < 1.e-6_r8) then + soil_color_o(no) = 15 + end if + end do + + ! Write output data + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil color" + call mkfile_output(pioid_o, mesh_o, 'SOIL_COLOR', soil_color_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out mksoil_color" + rcode = pio_inq_varid(pioid_o, 'mxsoil_color', pio_varid) + rcode = pio_put_var(pioid_o, pio_varid, nsoilcol) + call pio_syncfile(pioid_o) + ! Compare global area of each soil color on input and output grids call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & 0, nsoilcol, int(soil_color_i), soil_color_o, 'soil color type', ndiag, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Close the input file + call pio_closefile(pioid_i) + ! Clean up memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() diff --git a/tools/mksurfdata_esmf/src/mksoildepthMod.F90 b/tools/mksurfdata_esmf/src/mksoildepthMod.F90 index e2db0e1a01..7d60c34fe7 100644 --- a/tools/mksurfdata_esmf/src/mksoildepthMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoildepthMod.F90 @@ -5,7 +5,7 @@ module mksoildepthMod !----------------------------------------------------------------------- ! use ESMF - use pio + use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite, pio_syncfile use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4, cs => shr_kind_cs use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata @@ -13,6 +13,7 @@ module mksoildepthMod use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr use mkchecksMod , only : min_bad, max_bad + use mkfileMod , only : mkfile_output use mkvarctl implicit none @@ -27,27 +28,28 @@ module mksoildepthMod contains !=============================================================== - subroutine mksoildepth(file_mesh_i, file_data_i, mesh_o, soildepth_o, rc) + subroutine mksoildepth(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! ! make soildepth ! ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh - real(r8) , intent(out) :: soildepth_o(:) ! output grid: fraction soildepth - integer , intent(out) :: rc + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + type(file_desc_t) , intent(inout) :: pioid_o + integer , intent(out) :: rc ! local variables: type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i - type(file_desc_t) :: pioid + type(file_desc_t) :: pioid_i integer :: ns_i, ns_o integer :: ni, no integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) real(r8), allocatable :: soildepth_i(:) + real(r8), allocatable :: soildepth_o(:) ! output grid: fraction soildepth character(len=CS) :: varname integer :: varnum real(r8), parameter :: min_valid = 0._r8 ! minimum valid value @@ -64,7 +66,7 @@ subroutine mksoildepth(file_mesh_i, file_data_i, mesh_o, soildepth_o, rc) ! Open input data file call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) ! Read in input mesh call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) @@ -76,9 +78,10 @@ subroutine mksoildepth(file_mesh_i, file_data_i, mesh_o, soildepth_o, rc) call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine ns_o + ! Determine ns_o and allocate output data call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate ( soildepth_o(ns_o)); soildepth_o(:) = spval ! Get the landmask from the file and reset the mesh mask based on that allocate(frac_o(ns_o),stat=ier) @@ -89,7 +92,7 @@ subroutine mksoildepth(file_mesh_i, file_data_i, mesh_o, soildepth_o, rc) if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i if (frac_i(ni) > 0._r4) then @@ -136,7 +139,7 @@ subroutine mksoildepth(file_mesh_i, file_data_i, mesh_o, soildepth_o, rc) ! Read in input soil depth data allocate(soildepth_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, trim(varname), mesh_i, soildepth_i, rc=rc) + call mkpio_get_rawdata(pioid_i, trim(varname), mesh_i, soildepth_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -151,14 +154,17 @@ subroutine mksoildepth(file_mesh_i, file_data_i, mesh_o, soildepth_o, rc) call shr_sys_abort() end if + ! Write output data + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil depth" + call mkfile_output(pioid_o, mesh_o, 'zbedrock', soildepth_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) + ! Close the input file - call pio_closefile(pioid) + call pio_closefile(pioid_i) call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) ! Release memory - deallocate(soildepth_i) - deallocate(frac_i) - deallocate(frac_o) call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index c6fd1f2caa..0b96cf5d6b 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -165,23 +165,15 @@ program mksurfdata ! gdp data real(r8), allocatable :: gdp(:) ! GDP (x1000 1995 US$/capita) - ! peatland data - real(r8), allocatable :: fpeat(:) ! peatland fraction of gridcell - ! topography statistics data real(r4), allocatable :: topo_stddev(:) ! standard deviation of elevation (m) real(r4), allocatable :: slope(:) ! topographic slope (degrees) - ! agricultural peak month data - integer , allocatable :: agfirepkmon(:) ! agricultural fire peak month - ! inland water data real(r8), allocatable :: pctlak(:) ! percent of grid cell that is lake real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland - real(r8), allocatable :: lakedepth(:) ! lake depth (m) ! glacier data - integer, allocatable :: glacier_region(:) ! glacier region ID real(r8), allocatable :: pctgla(:) ! percent of grid cell that is glacier real(r8), allocatable :: pctglc_gic(:) ! percent of grid cell that is gic (% of glc landunit) real(r8), allocatable :: pctglc_icesheet(:) ! percent of grid cell that is ice sheet (% of glc landunit) @@ -198,13 +190,6 @@ program mksurfdata real(r8), allocatable :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell real(r8), allocatable :: elev(:) ! glc elevation (m) - ! soil color data - integer :: nsoilcol ! number of model color classes - integer , allocatable :: soil_color(:) ! soil color - - ! soil depth data - real(r8), allocatable :: soildepth(:) ! soil depth (m) - ! logicals logical :: zero_out_lake ! if should zero glacier out logical :: zero_out_wetland ! if should zero glacier out @@ -502,26 +487,10 @@ program mksurfdata ! ----------------------------------- ! Make soil color classes [soicol] [fsoicol] ! ----------------------------------- - allocate (soil_color(lsize_o)); soil_color(:) = -999 - call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, soil_color, nsoilcol, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilcol') - do n = 1,lsize_o - if (pctlnd_pft(n) < 1.e-6_r8) then - ! assume medium soil color (15) and loamy texture - soil_color(n) = 15 - end if - end do if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil color" - call mkfile_output(pioid, mesh_model, 'SOIL_COLOR', soil_color, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out mksoil_color" - rcode = pio_inq_varid(pioid, 'mxsoil_color', pio_varid) - rcode = pio_put_var(pioid, pio_varid, nsoilcol) - call pio_syncfile(pioid) + call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, pctlnd_pft, pioid, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilcol') end if - deallocate (soil_color ) ! ----------------------------------- ! Make soil fmax [fmaxsoil] @@ -555,45 +524,26 @@ program mksurfdata ! ----------------------------------- ! Make peat data [fpeat] from [peatf] ! ----------------------------------- - allocate (fpeat(lsize_o)) ; fpeat(:) = spval - call mkpeat (mksrf_fpeat_mesh, mksrf_fpeat, mesh_model, peat_o=fpeat, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpeat') if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out peatland fraction" - call mkfile_output(pioid, mesh_model, 'peatf', fpeat, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call pio_syncfile(pioid) + call mkpeat (mksrf_fpeat_mesh, mksrf_fpeat, mesh_model, pioid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpeat') end if - deallocate(fpeat) - call pio_syncfile(pioid) ! ----------------------------------- ! Make soil depth data [soildepth] from [soildepthf] ! ----------------------------------- - allocate ( soildepth(lsize_o)); soildepth(:) = spval - call mksoildepth( mksrf_fsoildepth_mesh, mksrf_fsoildepth, mesh_model, soildepth, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoildepth') if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil depth" - call mkfile_output(pioid, mesh_model, 'zbedrock', soildepth, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call pio_syncfile(pioid) + call mksoildepth( mksrf_fsoildepth_mesh, mksrf_fsoildepth, mesh_model, pioid, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoildepth') end if - deallocate (soildepth) ! ----------------------------------- ! Make agricultural fire peak month data [abm] from [abm] ! ----------------------------------- - allocate (agfirepkmon(lsize_o)); agfirepkmon(:) = -999 - call mkagfirepkmon (mksrf_fabm_mesh, mksrf_fabm, mesh_model, agfirepkmon_o=agfirepkmon, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkagfirepkmon') if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing abm (agricultural fire peak month)" - call mkfile_output(pioid, mesh_model, 'abm', agfirepkmon, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call pio_syncfile(pioid) + call mkagfirepkmon (mksrf_fabm_mesh, mksrf_fabm, mesh_model, pioid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkagfirepkmon') end if - deallocate(agfirepkmon) ! ----------------------------------- ! Make urban fraction [pcturb] from [furban] dataset and @@ -627,27 +577,15 @@ program mksurfdata pcturb = 0._r8 end where deallocate(elev) - call pio_syncfile(pioid) end if ! ----------------------------------- ! Compute topography statistics [topo_stddev, slope] from [ftopostats] ! ----------------------------------- - allocate (topo_stddev(lsize_o)) ; topo_stddev(:) = spval - allocate (slope(lsize_o)) ; slope(:) = spval - call mktopostats ( mksrf_ftopostats_mesh, mksrf_ftopostats, mesh_model, & - topo_stddev_o=topo_stddev, slope_o=slope, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mktopostats') if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing topo_stddev " - call mkfile_output(pioid, mesh_model, 'STD_ELEV', topo_stddev, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for STD_ELEV') - if (root_task) write(ndiag, '(a)') trim(subname)//" writing slope" - call mkfile_output(pioid, mesh_model, 'SLOPE', slope, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for SLOPE') - call pio_syncfile(pioid) + call mktopostats ( mksrf_ftopostats_mesh, mksrf_ftopostats, mesh_model, pioid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mktopostats') end if - deallocate(topo_stddev, slope) ! ----------------------------------- ! Compute VIC parameters diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index 2ed57d6f2d..63e37ce94d 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -10,13 +10,12 @@ module mktopostatsMod use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem use mkutilsMod , only : chkerr - use mkvarctl , only : ndiag, root_task, mpicom, std_elev + use mkvarctl , only : ndiag, root_task, mpicom, std_elev, spval + use mkfileMod , only : mkfile_output implicit none private -#include - public :: mktopostats ! make topo stddev & mean slope type(ESMF_DynamicMask) :: dynamicMask @@ -30,7 +29,7 @@ module mktopostatsMod contains !=============================================================== - subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, rc) + subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! make various topography statistics ! @@ -38,23 +37,24 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, use mkchecksMod , only : min_bad, max_bad ! ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! input model mesh - real(r4) , intent(out) :: topo_stddev_o(:) ! output grid: standard deviation of elevation (m) - real(r4) , intent(out) :: slope_o(:) ! output grid: slope (degrees) - integer , intent(out) :: rc + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! input model mesh + type(file_desc_t) , intent(inout) :: pioid_o + integer , intent(out) :: rc ! ! local variables: type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i type(ESMF_Field) :: field_i type(ESMF_Field) :: field_o - type(file_desc_t) :: pioid + type(file_desc_t) :: pioid_i integer :: ni,no,k integer :: ns_i, ns_o real(r4), allocatable :: data_i(:) real(r4), pointer :: dataptr(:) + real(r4), allocatable :: topo_stddev_o(:) ! output grid: standard deviation of elevation (m) + real(r4), allocatable :: slope_o(:) ! output grid: slope (degrees) real(r8), allocatable :: area_i(:) real(r8), allocatable :: area_o(:) integer :: ier, rcode ! error status @@ -89,7 +89,7 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, ! Open input data file ! Read in data with PIO_IOTYPE_NETCDF rather than PIO_IOTYPE_PNETCDF since there are problems ! with the pnetcdf read of this high resolution data - rcode = pio_openfile(pio_iosystem, pioid, PIO_IOTYPE_NETCDF, trim(file_data_i), pio_nowrite) + rcode = pio_openfile(pio_iosystem, pioid_i, PIO_IOTYPE_NETCDF, trim(file_data_i), pio_nowrite) call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh @@ -101,14 +101,16 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine ns_o + ! Determine ns_o and allocate output data call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate (topo_stddev_o(ns_o)) ; topo_stddev_o(:) = spval + allocate (slope_o(ns_o)) ; slope_o(:) = spval ! Read in input data data_i allocate(data_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort(subname//' error in allocating data_i') - call mkpio_get_rawdata(pioid, 'ELEVATION', mesh_i, data_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'ELEVATION', mesh_i, data_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -150,8 +152,6 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, dynamicMask=dynamicMask, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) @@ -172,7 +172,7 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, ! Obtain the slope ! ----------------------------- - call mkpio_get_rawdata(pioid, 'SLOPE', mesh_i, data_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'SLOPE', mesh_i, data_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) @@ -198,8 +198,18 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, topo_stddev_o, slope_o, !call shr_sys_abort() !end if + ! Write out output data + if (root_task) write(ndiag, '(a)') trim(subname)//" writing topo_stddev " + call mkfile_output(pioid_o, mesh_o, 'STD_ELEV', topo_stddev_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for STD_ELEV') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing slope" + call mkfile_output(pioid_o, mesh_o, 'SLOPE', slope_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for SLOPE') + call pio_syncfile(pioid_o) + ! Close files and deallocate dynamic memory - call pio_closefile(pioid) + call pio_closefile(pioid_i) call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) From 60fad6a62c777371b421654f1de89a521118bfe0 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 22 Feb 2022 22:48:28 -0700 Subject: [PATCH 075/614] cleanup of Makefile and CMakeLists.txt --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 19 +++++++++++++++++++ tools/mksurfdata_esmf/src/CMakeLists.txt | 10 ---------- tools/mksurfdata_esmf/src/Makefile | 9 ++++----- 3 files changed, 23 insertions(+), 15 deletions(-) create mode 100755 tools/mksurfdata_esmf/gen_mksurfdata_build.sh diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh new file mode 100755 index 0000000000..645645a47f --- /dev/null +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -0,0 +1,19 @@ +#! /bin/bash -f + +module load cmake + +export MACH="cheyenne" +export COMPILER="intel" +export OS="LINUX" +export ESMFMKFILE="/glade/work/oehmke/ESMF/scalable_mesh_from_file/lib/libg/Linux.intel.64.mpt.default/esmf.mk" + +cwd=`pwd` +rm -rf bld +mkdir bld +cd bld +../../../cime/tools/configure --macros-format CMake --machine cheyenne --compiler intel --mpilib mpt +ls -l +source ./.env_mach_specific.sh +CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src +make VERBOSE=1 + diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 804088be9b..3f86d90d97 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -1,7 +1,6 @@ cmake_minimum_required(VERSION 3.10) project(mksurfdata Fortran) -#include(${CASEROOT}/Macros.cmake) set (ESMFMKFILE /glade/work/oehmke/ESMF/scalable_mesh_from_file/lib/libg/Linux.intel.64.mpt.default/esmf.mk) file(STRINGS ${ESMFMKFILE} esmf_mk_text) foreach(line ${esmf_mk_text}) @@ -63,16 +62,7 @@ message("PROJECT_BINARY_DIR is ${PROJECT_BINARY_DIR}") target_include_directories (mksurfdata PRIVATE ${ESMF_F90COMPILEPATHS}) target_include_directories (mksurfdata PRIVATE /glade/work/jedwards/tools/pio/2.5.5/intel/19.1.1/mpt/2.22/include) -#target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/include) # non debug version target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/pnetcdf/1.12.2/mpt/2.22/intel/19.1.1//include) -#target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/netcdf-mpi/4.8.0/mpt/2.22/intel/19.1.1//include) target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/netcdf-mpi/4.8.1/mpt/2.22/intel/19.1.1//include) -#link_directories(/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/lib) -#target_link_libraries(mksurfdata piof) -#target_link_libraries(mksurfdata /glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/lib/libpiof.a) -#link_directories(/glade/p/cesmdata/cseg/PROGS/esmf/8.2.0b23/mpt/2.22/intel/19.1.1/lib/libg/Linux.intel.64.mpt.default) -#target_link_libraries(mksurfdata esmf) -#target_link_libraries(mksurfdata /glade/p/cesmdata/cseg/PROGS/esmf/8.2.0b23/mpt/2.22/intel/19.1.1/lib/libg/Linux.intel.64.mpt.default/libesmf.a) - install(TARGETS mksurfdata) diff --git a/tools/mksurfdata_esmf/src/Makefile b/tools/mksurfdata_esmf/src/Makefile index f2853e3e43..f89482a85c 100644 --- a/tools/mksurfdata_esmf/src/Makefile +++ b/tools/mksurfdata_esmf/src/Makefile @@ -19,10 +19,9 @@ ################################################################################ -COMPILEPATH = -I/glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/bld -I/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/include -#LINKPATH = -L/glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/bld -L/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/lib/ -LINKPATH = -L/glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/bld -PIO_LINKPATH = -L/glade/work/jedwards/tools/pio/2.5.5/intel/19.1.1/mpt/2.22/lib -L/glade/u/apps/ch/opt/pnetcdf/1.12.2/mpt/2.22/intel/19.1.1//lib -L/glade/u/apps/ch/opt/netcdf/4.7.3/intel/19.0.5/lib +COMPILEPATH = -I$(MKSURFDATA_BLD) -I/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/include +LINKPATH = -L$(MKSURFDATA_BLD) +PIO_LINKPATH = -L/glade/work/jedwards/tools/pio/2.5.5/intel/19.1.1/mpt/2.22/lib -L/glade/u/apps/ch/opt/pnetcdf/1.12.2/mpt/2.22/intel/19.1.1//lib -L/glade/u/apps/ch/opt/netcdf/4.7.3/intel/19.0.5/lib ESMFMKFILE=/glade/work/oehmke/ESMF/scalable_mesh_from_file/lib/libg/Linux.intel.64.mpt.default/esmf.mk include $(ESMFMKFILE) @@ -37,7 +36,7 @@ include $(ESMFMKFILE) %.o : %.F90 $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) $(ESMF_F90COMPILEFREECPP) $(ESMF_F90COMPILECPPFLAGS) $(COMPILEPATH) $< - + %.o : %.c $(ESMF_CXXCOMPILER) -c $(ESMF_CXXCOMPILEOPTS) $(ESMF_CXXCOMPILEPATHSLOCAL) $(ESMF_CXXCOMPILEPATHS) $(ESMF_CXXCOMPILECPPFLAGS) $< From e698a38f5de722a937baa5b3eafde07a14fcb305 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 23 Feb 2022 13:39:58 -0700 Subject: [PATCH 076/614] more updates and cleanup --- tools/mksurfdata_esmf/README | 16 +- tools/mksurfdata_esmf/gen_mksurfdata | 17 +- tools/mksurfdata_esmf/src/CMakeLists.txt | 1 + tools/mksurfdata_esmf/src/mkfileMod.F90 | 1 - tools/mksurfdata_esmf/src/mkgdpMod.F90 | 27 ++- tools/mksurfdata_esmf/src/mkglcmecMod.F90 | 163 +++++++++++------- tools/mksurfdata_esmf/src/mkinputMod.F90 | 1 - tools/mksurfdata_esmf/src/mkorganicMod.F90 | 40 +++-- tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 | 43 ++--- tools/mksurfdata_esmf/src/mksurfdata.F90 | 178 ++++---------------- tools/mksurfdata_esmf/src/mkvarctl.F90 | 38 ++--- 11 files changed, 239 insertions(+), 286 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 133c152795..2620a589da 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -1,18 +1,22 @@ ============================ -building the executable (this will be built in src/ for now) +building the executable ============================ +> rm -rf bld > mkdir ./bld > cd bld > module load cmake > CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src/ -> make -> cd ../ +> make VERBOSE=1 + +> cd ../src > make clean -> make +> MKSURDATA_BLD=../bld make VERBOSE=1 ============================ running the code (you could add mksurfdata_in) ============================ > cd ../ -./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc | cut -d' ' -f5 -> qsub run_mksurfdata +> rm mksurfdata_in +> temp=`./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc | cut -d' ' -f5` +> ln -s $temp mksurfdata_in +> qsub gen_mksurfdata diff --git a/tools/mksurfdata_esmf/gen_mksurfdata b/tools/mksurfdata_esmf/gen_mksurfdata index 22cb1b8683..a1607c1542 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata +++ b/tools/mksurfdata_esmf/gen_mksurfdata @@ -4,29 +4,18 @@ #PBS -j oe #PBS -q premium #PBS -l walltime=20:00 -##PBS -l select=1:ncpus=36:mpiprocs=36 -##PBS -l select=4:ncpus=36:mpiprocs=36 ##PBS -l select=16:ncpus=36:mpiprocs=9 #PBS -l select=24:ncpus=36:mpiprocs=12 ##PBS -l select=32:ncpus=36:mpiprocs=12 +export TMPDIR=/glade/scratch/$USER/temp +mkdir -p $TMPDIR + # note for -l input above # -l select={num_nodes}:ncpus={max_tasks_per_node}:mpiprocs={tasks_per_node} # note for mpiexec below # -np {total_tasks} -#module rm netcdf -#module load netcdf-mpi pnetcdf pio/2.5.5 -#make - -export TMPDIR=/glade/scratch/$USER/temp -mkdir -p $TMPDIR - -# Determine mksurfdata_in -# fname=`./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc | cut -d' ' -f5` -# rm -f mksurfdata_in -# ln -s $fname mksurfdata_in - # Run the model #mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 3f86d90d97..597dadaf9e 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.10) project(mksurfdata Fortran) set (ESMFMKFILE /glade/work/oehmke/ESMF/scalable_mesh_from_file/lib/libg/Linux.intel.64.mpt.default/esmf.mk) + file(STRINGS ${ESMFMKFILE} esmf_mk_text) foreach(line ${esmf_mk_text}) string(REGEX REPLACE "^[ ]+" "" line ${line}) # strip leading spaces diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index bb59c520b6..76a9401142 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -7,7 +7,6 @@ module mkfileMod use mkutilsMod , only : get_filename, chkerr use mkvarpar , only : nlevsoi, numrad, numstdpft use mkurbanparMod , only : numurbl, nlevurb, mkurbanpar - use mkglcmecMod , only : nglcec use mklaiMod , only : mklai use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft, num_natpft use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array diff --git a/tools/mksurfdata_esmf/src/mkgdpMod.F90 b/tools/mksurfdata_esmf/src/mkgdpMod.F90 index 7fd124d1f6..2fbfe86c21 100644 --- a/tools/mksurfdata_esmf/src/mkgdpMod.F90 +++ b/tools/mksurfdata_esmf/src/mkgdpMod.F90 @@ -5,15 +5,16 @@ module mkgdpMod !----------------------------------------------------------------------- use ESMF + use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite, pio_syncfile use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 use shr_sys_mod , only : shr_sys_abort - use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 - use mkvarctl , only : ndiag, root_task, mpicom + use mkvarctl , only : ndiag, root_task, mpicom, spval use mkdiagnosticsMod , only : output_diagnostics_continuous use mkchecksMod , only : min_bad use mkutilsMod , only : chkerr + use mkfileMod , only : mkfile_output implicit none private @@ -27,7 +28,7 @@ module mkgdpMod contains !=============================================================== - subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, gdp_o, rc) + subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! ! make GDP from input GDP data ! @@ -35,7 +36,7 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, gdp_o, rc) character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! input model mesh - real(r8) , intent(inout) :: gdp_o(:) ! output grid: GDP (x1000 1995 US$ per capita) + type(file_desc_t) , intent(inout) :: pioid_o integer , intent(out) :: rc ! local variables: @@ -47,9 +48,10 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, gdp_o, rc) integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) - real(r8), allocatable :: gdp_i(:) ! input grid: percent gdp - real(r8), parameter :: min_valid = 0._r8 ! minimum valid value - integer :: ier, rcode ! error status + real(r8), allocatable :: gdp_i(:) ! input grid: percent gdp + real(r8), allocatable :: gdp_o(:) ! output grid: GDP (x1000 1995 US$ per capita) + real(r8), parameter :: min_valid = 0._r8 ! minimum valid value + integer :: ier, rcode ! error status character(len=*), parameter :: subname = 'mkgdp' !----------------------------------------------------------------------- @@ -77,9 +79,10 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, gdp_o, rc) call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine ns_o + ! Determine ns_o and allocate output data call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate (gdp_o(ns_o)); gdp_o(:) = spval ! Get the landmask from the file and reset the mesh mask based on that allocate(frac_i(ns_i), stat=ier) @@ -98,7 +101,7 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, gdp_o, rc) call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Read in peat_i + ! Read in gdp_i allocate(gdp_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid, 'gdp', mesh_i, gdp_i, rc=rc) @@ -122,6 +125,12 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, gdp_o, rc) ! Close the file call pio_closefile(pioid) + ! Write output data + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out gdp" + call mkfile_output(pioid, mesh_o, 'gdp', gdp_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) + ! Output diagnostic info call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & gdp_i, gdp_o, "GDP", "x1000 US$ per capita", ndiag, rc) diff --git a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 index dc8f1acb36..198c4f6451 100644 --- a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 @@ -9,12 +9,15 @@ module mkglcmecMod use shr_sys_mod , only : shr_sys_abort use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite use pio , only : var_desc_t, io_desc_t, Pio_Offset_Kind, pio_setframe - use pio , only : pio_inq_dimid, pio_inq_dimlen, pio_inq_varid, pio_get_var + use pio , only : pio_inq_dimid, pio_inq_dimlen, pio_inq_varid + use pio , only : pio_put_var, pio_get_var use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem use mkpioMod , only : mkpio_iodesc_rawdata, mkpio_get_rawdata_level use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 - use mkvarctl , only : ndiag, root_task, outnc_3dglc + use mkvarctl , only : ndiag, root_task, outnc_3dglc, spval, nglcec use mkutilsMod , only : chkerr + use mkutilsMod , only : slightly_below, slightly_above + use mkfileMod , only : mkfile_output implicit none private ! By default make data private @@ -26,7 +29,6 @@ module mkglcmecMod private :: get_elevclass ! get elevation class index private :: mean_elevation_vc ! get the elevation of a virtual column - integer, public :: nglcec = 10 ! number of elevation classes for glaciers real(r8), allocatable :: elevclass(:) ! elevation classes character(len=*) , parameter :: u_FILE_u = & @@ -36,14 +38,18 @@ module mkglcmecMod contains !================================================================================= - subroutine mkglcmecInit( elevclass_o ) + subroutine mkglcmecInit( pioid_o ) ! ! Initialize of Make glacier multi-elevation class data ! ! input/output variables - real(r8), intent(out) :: elevclass_o(:) ! elevation classes + type(file_desc_t) , intent(inout) :: pioid_o ! local variables: + type(var_desc_t) :: pio_varid + type(io_desc_t) :: pio_iodesc + real(r8), allocatable :: elevclass_o(:) ! elevation classes + integer :: rcode character(len=*), parameter :: subname = 'mkglcmecInit' !----------------------------------------------------------------------- @@ -95,12 +101,14 @@ subroutine mkglcmecInit( elevclass_o ) elevclass_o(:) = elevclass(:) + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out GLC_MEC" + rcode = pio_inq_varid(pioid_o, 'GLC_MEC', pio_varid) + rcode = pio_put_var(pioid_o, pio_varid, elevclass) + end subroutine mkglcmecInit !================================================================================= - subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & - pctglcmec_o, topoglcmec_o, pctglcmec_gic_o, pctglcmec_icesheet_o, & - pctglc_gic_o, pctglc_icesheet_o, rc) + subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! ! make percent glacier on multiple elevation classes, mean elevation for each ! elevation class, and associated fields @@ -117,33 +125,26 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & ! If the input glacier area is 0 for a given grid cell, this requires setting these % ! variables in an arbitrary way. ! - use mkutilsMod, only : slightly_below, slightly_above - ! ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh - real(r8) , intent(out) :: pctglcmec_o (:,:) ! % for each elevation class on output glacier grid (% of landunit) - real(r8) , intent(out) :: topoglcmec_o(:,:) ! mean elevation for each elevation classs on output glacier grid - real(r8), optional , intent(out) :: pctglcmec_gic_o(:,:) ! % glc gic on output grid, by elevation class (% of landunit) - real(r8), optional , intent(out) :: pctglcmec_icesheet_o(:,:) ! % glc ice sheet on output grid, by elevation class (% of landunit) - real(r8), optional , intent(out) :: pctglc_gic_o(:) ! % glc gic on output grid, summed across elevation classes (% of landunit) - real(r8), optional , intent(out) :: pctglc_icesheet_o(:) ! % glc ice sheet on output grid, summed across elevation classes (% of landunit) - integer , intent(out) :: rc + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + type(file_desc_t) , intent(inout) :: pioid_o + integer , intent(out) :: rc ! local variables: - type(ESMF_RouteHandle) :: routehandle ! nearest neighbor routehandle + type(ESMF_RouteHandle) :: routehandle ! nearest neighbor routehandle type(ESMF_Mesh) :: mesh_i - type(file_desc_t) :: pioid + type(file_desc_t) :: pioid_i type(var_desc_t) :: pio_varid type(io_desc_t) :: pio_iodesc integer :: pio_vartype integer :: ni,no,lev integer :: ns_i, ns_o - integer :: n,m,k ! indices - integer :: dimid ! dimension ids - integer :: ndims ! number of dimensions in input variables - integer :: nlev ! number of levels in input file + integer :: n,m,k ! indices + integer :: dimid ! dimension ids + integer :: ndims ! number of dimensions in input variables + integer :: nlev ! number of levels in input file integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) @@ -155,14 +156,19 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & real(r8), allocatable :: data_pctglc_icesheet_o(:) ! input icesheet percentage real(r8), allocatable :: data_pctglc_gic_i(:) real(r8), allocatable :: data_pctglc_gic_o(:) - real(r8), allocatable :: topoglcmec_unnorm_o(:,:) ! same as topoglcmec_o, but unnormalized - real(r8), allocatable :: pctglc_tot_o(:) ! total glacier cover for the grid cell - real(r4), allocatable :: topoice_i(:) ! topographic height of this level - integer :: unlimited_index ! z level - real(r8) :: glc_sum ! temporary - integer :: ier, rcode ! error status - logical :: errors ! error status - + real(r8), allocatable :: topoglcmec_unnorm_o(:,:) ! same as topoglcmec_o, but unnormalized + real(r8), allocatable :: pctglc_tot_o(:) ! total glacier cover for the grid cell + real(r4), allocatable :: topoice_i(:) ! topographic height of this level + real(r8), allocatable :: pctglcmec_o (:,:) ! % for each elevation class on output glacier grid (% of landunit) + real(r8), allocatable :: topoglcmec_o(:,:) ! mean elevation for each elevation classs on output glacier grid + real(r8), allocatable :: pctglcmec_gic_o(:,:) ! % glc gic on output grid, by elevation class (% of landunit) + real(r8), allocatable :: pctglcmec_icesheet_o(:,:) ! % glc ice sheet on output grid, by elevation class (% of landunit) + real(r8), allocatable :: pctglc_gic_o(:) ! % glc gic on output grid, summed across elevation classes (% of landunit) + real(r8), allocatable :: pctglc_icesheet_o(:) ! % glc ice sheet on output grid, summed across elevation classes (% of landunit) + integer :: unlimited_index ! z level + real(r8) :: glc_sum ! temporary + integer :: ier, rcode ! error status + logical :: errors ! error status real(r8), parameter :: eps = 2.e-5_r8 ! epsilon for error checks (note that we use a large-ish value ! because data are stored as single-precision floats in the raw dataset) real(r8), parameter :: eps_small = 1.e-12_r8 ! epsilon for error checks that expect close match @@ -181,23 +187,9 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if - ! Initialize all output fields to zero - pctglcmec_o(:,:) = 0. - topoglcmec_o(:,:) = 0. - if ( outnc_3dglc )then - if ( (.not. present(pctglcmec_gic_o)) .or. (.not. present(pctglcmec_icesheet_o)) .or. & - (.not. present(pctglc_gic_o) ) .or. (.not. present(pctglc_icesheet_o) ) )then - call shr_sys_abort( subname//' error: 3D glacier fields were NOT sent in and they are required' ) - end if - pctglcmec_gic_o(:,:) = 0. - pctglcmec_icesheet_o(:,:) = 0. - pctglc_gic_o(:) = 0. - pctglc_icesheet_o(:) = 0. - end if - ! Open input data file call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Read in input mesh @@ -210,16 +202,34 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine ns_o + ! Determine ns_o and allocate output data call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(pctglcmec_o(ns_o,nglcec)) + pctglcmec_o(:,:) = 0. + + allocate(topoglcmec_o(ns_o,nglcec)) + topoglcmec_o(:,:) = 0. + if ( outnc_3dglc )then + allocate(pctglcmec_gic_o(ns_o,nglcec)) + pctglcmec_gic_o(:,:) = 0. + + allocate(pctglcmec_icesheet_o(ns_o,nglcec)) + pctglcmec_icesheet_o(:,:) = 0. + + allocate(pctglc_gic_o(ns_o)) + pctglc_gic_o(:) = 0. + + allocate(pctglc_icesheet_o(ns_o)) + pctglc_icesheet_o(:) = 0. + end if ! Get the landmask from the file and reset the mesh mask based on that allocate(frac_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort(subname//" error in allocating frac_i") allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort(subname//" error in allocating mask_i") - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i if (frac_i(ni) > 0._r8) then @@ -232,13 +242,13 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & if (chkerr(rc,__LINE__,u_FILE_u)) return ! Read in BIN_CENTERS on all tasks and check validity - rcode = pio_inq_dimid (pioid, 'z', dimid) - rcode = pio_inq_dimlen(pioid, dimid, nlev) + rcode = pio_inq_dimid (pioid_i, 'z', dimid) + rcode = pio_inq_dimlen(pioid_i, dimid, nlev) ! TODO: hard-wiring topoice to be r4 - this needs to be generalized to query the variable type ! on the netcdf file allocate(topoice_i(nlev)) - rcode = pio_inq_varid (pioid, 'BIN_CENTERS', pio_varid) - rcode = pio_get_var(pioid, pio_varid, topoice_i) + rcode = pio_inq_varid (pioid_i, 'BIN_CENTERS', pio_varid) + rcode = pio_get_var(pioid_i, pio_varid, topoice_i) do lev = 1,nlev m = get_elevclass(topoice_i(lev)) if (m < 1 .or. m > nglcec) then @@ -267,7 +277,7 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & topoglcmec_unnorm_o(:,:) = 0. ! Create iodescriptor for a single level of the input data - call mkpio_iodesc_rawdata(mesh_i, 'PCT_GLC_GIC', pioid, pio_varid, pio_vartype, pio_iodesc, rc) + call mkpio_iodesc_rawdata(mesh_i, 'PCT_GLC_GIC', pioid_i, pio_varid, pio_vartype, pio_iodesc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle between the input and output mesh and get frac_o @@ -284,13 +294,13 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & write(6,'(i4)',advance='no') lev ! Read in one level of data - rcode = pio_inq_varid(pioid, 'PCT_GLC_GIC', pio_varid) - call pio_setframe(pioid, pio_varid, int(lev,kind=Pio_Offset_Kind)) - call mkpio_get_rawdata_level(pioid, pio_iodesc, lev, 'PCT_GLC_GIC', data_pctglc_gic_i) + rcode = pio_inq_varid(pioid_i, 'PCT_GLC_GIC', pio_varid) + call pio_setframe(pioid_i, pio_varid, int(lev,kind=Pio_Offset_Kind)) + call mkpio_get_rawdata_level(pioid_i, pio_iodesc, lev, 'PCT_GLC_GIC', data_pctglc_gic_i) - rcode = pio_inq_varid(pioid, 'PCT_GLC_ICESHEET', pio_varid) - call pio_setframe(pioid, pio_varid, int(lev,kind=Pio_Offset_Kind)) - call mkpio_get_rawdata_level(pioid, pio_iodesc, lev, 'PCT_GLC_ICESHEET', data_pctglc_icesheet_i) + rcode = pio_inq_varid(pioid_i, 'PCT_GLC_ICESHEET', pio_varid) + call pio_setframe(pioid_i, pio_varid, int(lev,kind=Pio_Offset_Kind)) + call mkpio_get_rawdata_level(pioid_i, pio_iodesc, lev, 'PCT_GLC_ICESHEET', data_pctglc_icesheet_i) ! Compute derived input data data_pctglc_i(:) = data_pctglc_gic_i(:) + data_pctglc_icesheet_i(:) @@ -316,7 +326,7 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & end do ! Close glacier input file - call pio_closefile(pioid) + call pio_closefile(pioid_i) call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) ! At this point, the various percentages are given as % of grid cell. @@ -430,6 +440,33 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, & call shr_sys_abort(subname//" error in error checks") end if + ! Output data tp fo;e + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec" + call mkfile_output(pioid_o, mesh_o, 'PCT_GLC_MEC', pctglcmec_o, lev1name='nglcec', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out topo_glc_mec" + call mkfile_output(pioid_o, mesh_o, 'TOPO_GLC_MEC', topoglcmec_o, lev1name='nglcec', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + + if (outnc_3dglc ) then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec_gic" + call mkfile_output(pioid_o, mesh_o, 'PCT_GLC_MEC_GIC', pctglcmec_gic_o, lev1name='nglcec', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec_icesheet" + call mkfile_output(pioid_o, mesh_o, 'PCT_GLC_MEC_ICESHEET', pctglcmec_icesheet_o, lev1name='nglcec', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_gic" + call mkfile_output(pioid_o, mesh_o, 'PCT_GLC_GIC', pctglc_gic_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_icesheet" + call mkfile_output(pioid_o, mesh_o, 'PCT_GLC_ICESHEET', pctglc_icesheet_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + end if + ! Deallocate dynamic memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() diff --git a/tools/mksurfdata_esmf/src/mkinputMod.F90 b/tools/mksurfdata_esmf/src/mkinputMod.F90 index 87ce4508ea..9e33d14e79 100644 --- a/tools/mksurfdata_esmf/src/mkinputMod.F90 +++ b/tools/mksurfdata_esmf/src/mkinputMod.F90 @@ -7,7 +7,6 @@ module mkinputMod use shr_kind_mod , only : r8 => shr_kind_r8 use shr_kind_mod , only : CS => shr_kind_CS, CL => shr_kind_CL, CX => shr_kind_CX use shr_sys_mod , only : shr_sys_abort - use mkglcmecMod , only : nglcec use mkpftMod , only : pft_idx, pft_frc use mkvarctl diff --git a/tools/mksurfdata_esmf/src/mkorganicMod.F90 b/tools/mksurfdata_esmf/src/mkorganicMod.F90 index 24ced6de23..fce5dc0e92 100644 --- a/tools/mksurfdata_esmf/src/mkorganicMod.F90 +++ b/tools/mksurfdata_esmf/src/mkorganicMod.F90 @@ -10,8 +10,9 @@ module mkorganicMod use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr - use mkvarctl , only : root_task, ndiag + use mkvarctl , only : root_task, ndiag, spval use mkvarpar , only : nlevsoi + use mkfileMod , only : mkfile_output implicit none private @@ -25,19 +26,21 @@ module mkorganicMod contains !================================================================================= - subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) + subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, pctlnd_pft_o, lat_o, pioid_o, rc) ! input/output variables character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o - real(r8) , intent(out) :: organic_o(:,:) ! output grid: %lake + real(r8) , intent(in) :: pctlnd_pft_o(:) + real(r8) , intent(in) :: lat_o(:) + type(file_desc_t) , intent(inout) :: pioid_o integer , intent(out) :: rc ! local variables type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i - type(file_desc_t) :: pioid + type(file_desc_t) :: pioid_i type(var_desc_t) :: pio_varid integer :: ni,no integer :: ns_i, ns_o @@ -53,6 +56,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) real(r8), allocatable :: area_o(:) real(r8), allocatable :: data_i(:,:) real(r8), allocatable :: data_o(:,:) + real(r8), allocatable :: organic_o(:,:) ! output grid: %lake character(len=*), parameter :: subname = 'mkorganic' !----------------------------------------------------------------------- @@ -68,7 +72,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) end if ! Open input data file - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Get dimensions of raw data. @@ -76,7 +80,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) ! - input read from pio has dimensions(n,lev) ! - esmf field dataptr has dimensions (lev,n) allocate(dimlengths(3)) - call mkpio_get_dimlengths(pioid, 'ORGANIC', ndims, dimlengths) + call mkpio_get_dimlengths(pioid_i, 'ORGANIC', ndims, dimlengths) nlay = dimlengths(3) if (nlay /= nlevsoi) then write(6,*)'nlay, nlevsoi= ',nlay,nlevsoi,' do not match' @@ -94,16 +98,17 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine ns_o + ! Determine ns_o and allocate output data call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate ( organic_o(ns_o,nlevsoi)); organic_o(:,:) = spval ! Get the landmask from the file and reset the mesh mask based on that allocate(frac_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i if (frac_i(ni) > 0._r8) then @@ -128,7 +133,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) ! Input data is read into (ns_i,nlay) array and then transferred to data_i(nlay,ns_i) allocate(data_i(nlay,ns_i),stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'ORGANIC', mesh_i, data_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'ORGANIC', mesh_i, data_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -154,9 +159,24 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) end if enddo end do + do no = 1,ns_o + ! If have very small values of pctlnd - set organic_o to zero + if (pctlnd_pft_o(no) < 1.e-6_r8) then + organic_o(no,:) = 0._r8 + end if + ! If have pole points on grid - set south pole to glacier and north pole is not land + if (abs((lat_o(no) - 90._r8)) < 1.e-6_r8) then + organic_o(no,:) = 0._r8 + end if + end do + + ! Write out the output data + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil organic matter density" + call mkfile_output(pioid_o, mesh_o, 'ORGANIC', organic_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') ! Close the file - call pio_closefile(pioid) + call pio_closefile(pioid_i) call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) ! Release memory diff --git a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 index a01c9363c6..bf4468beb0 100644 --- a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 @@ -7,12 +7,13 @@ module mksoilfmaxMod use ESMF use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 use shr_sys_mod , only : shr_sys_abort - use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite + use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite, pio_syncfile use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkdiagnosticsMod , only : output_diagnostics_continuous - use mkvarctl , only : ndiag, root_task, soil_fmax_override, unsetsoil + use mkvarctl , only : ndiag, root_task, soil_fmax_override, unsetsoil, spval use mkutilsMod , only : chkerr + use mkfileMod , only : mkfile_output implicit none private ! By default make data private @@ -26,7 +27,7 @@ module mksoilfmaxMod contains !================================================================================= - subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) + subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! ! make percent fmax ! @@ -34,29 +35,22 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh - real(r8) , intent(inout) :: fmax_o(:) ! output grid: %fmax + type(file_desc_t) , intent(inout) :: pioid_o integer , intent(out) :: rc ! local variables: type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i - type(file_desc_t) :: pioid + type(file_desc_t) :: pioid_i integer :: ni,no integer :: ns_i, ns_o integer :: n,l,k - integer , allocatable :: mask_i(:) + integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) - real(r8), allocatable :: fmax_i(:) ! input grid: percent fmax - real(r8), allocatable :: areas_i(:) ! input mesh areas - real(r8), allocatable :: areas_o(:) ! output mesh areas - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: gfmax_i ! input grid: global fmax - real(r8) :: garea_i ! input grid: global area - real(r8) :: gfmax_o ! output grid: global fmax - real(r8) :: garea_o ! output grid: global area - integer :: ier, rcode ! error status + real(r8), allocatable :: fmax_i(:) ! input grid: percent fmax + real(r8), allocatable :: fmax_o(:) ! output grid: %fmax + integer :: ier, rcode ! error status character(len=32) :: subname = 'mksoilfmax' !----------------------------------------------------------------------- @@ -84,7 +78,7 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) end if ! Open input data file - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) ! Read in input mesh mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) @@ -95,16 +89,17 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine ns_o + ! Determine ns_o and allocate output data call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(fmax_o(ns_o)); fmax_o(:) = spval ! Get the landmask from the file and reset the mesh mask based on that allocate(frac_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i if (frac_i(ni) > 0._r8) then @@ -130,7 +125,7 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) ! Read in input data allocate(fmax_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'FMAX', mesh_i, fmax_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'FMAX', mesh_i, fmax_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -159,8 +154,14 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, fmax_o, rc) fmax_i, fmax_o, "Maximum Fractional Sataturated output", "unitless", ndiag, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Write output data + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil fmax (maximum fraction saturated area)" + call mkfile_output (pioid_o, mesh_o, 'FMAX', fmax_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) + ! Close the input file - call pio_closefile(pioid) + call pio_closefile(pioid_i) ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 0b96cf5d6b..b13d007fab 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -103,7 +103,7 @@ program mksurfdata use mklaiMod , only : mklai use mkpeatMod , only : mkpeat use mkvocefMod , only : mkvocef - use mkglcmecMod , only : mkglcmecInit, mkglcmec, mkglacier, nglcec + use mkglcmecMod , only : mkglcmecInit, mkglcmec, mkglacier use mkglacierregionMod , only : mkglacierregion use mksoiltexMod , only : mksoiltex use mksoilfmaxMod , only : mksoilfmax @@ -152,38 +152,19 @@ program mksurfdata type(pct_pft_type), allocatable :: pctcft(:) ! % of grid cell that is crop, and breakdown into CFTs ! dynamic land use - real(r8), allocatable :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs - type(pct_pft_type), allocatable :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series - type(pct_pft_type), allocatable :: pctcft_max(:) ! % of grid cell maximum CFTs of the time series - - ! soil fracation saturated area data - real(r8), allocatable :: fmaxsoil(:) ! soil_fractional saturated area - - ! oranic matter density data - real(r8), allocatable :: organic(:,:) ! organic matter density (kg/m3) - - ! gdp data - real(r8), allocatable :: gdp(:) ! GDP (x1000 1995 US$/capita) - - ! topography statistics data - real(r4), allocatable :: topo_stddev(:) ! standard deviation of elevation (m) - real(r4), allocatable :: slope(:) ! topographic slope (degrees) - - ! inland water data + real(r8) , allocatable :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs + type(pct_pft_type) , allocatable :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series + type(pct_pft_type) , allocatable :: pctcft_max(:) ! % of grid cell maximum CFTs of the time series + real(r8) , allocatable :: pctnatveg(:) + real(r8) , allocatable :: pctcrop(:) + real(r8) , allocatable :: pct_nat_pft(:,:) + real(r8) , allocatable :: pct_cft(:,:) + logical :: end_of_fdynloop + + ! inland water data, glacier data and urban data real(r8), allocatable :: pctlak(:) ! percent of grid cell that is lake real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland - - ! glacier data real(r8), allocatable :: pctgla(:) ! percent of grid cell that is glacier - real(r8), allocatable :: pctglc_gic(:) ! percent of grid cell that is gic (% of glc landunit) - real(r8), allocatable :: pctglc_icesheet(:) ! percent of grid cell that is ice sheet (% of glc landunit) - real(r8), allocatable :: pctglcmec(:,:) ! glacier_mec pct coverage in each class (% of landunit) - real(r8), allocatable :: pctglcmec_gic(:,:) ! GIC pct coverage in each class (% of landunit) - real(r8), allocatable :: pctglcmec_icesheet(:,:) ! icesheet pct coverage in each class (% of landunit) - real(r8), allocatable :: elevclass(:) ! glacier_mec elevation classes - real(r8), allocatable :: topoglcmec(:,:) ! glacier_mec sfc elevation in each gridcell and class - - ! urban data integer , allocatable :: urban_region(:) ! urban region ID real(r8), allocatable :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) real(r8), allocatable :: urban_classes(:,:) ! percent cover of each urban class, as % of total urban area @@ -201,8 +182,6 @@ program mksurfdata type(io_desc_t) :: pio_iodesc integer :: petcount integer :: stride - - ! esmf variables type(ESMF_Mesh) :: mesh_model type(ESMF_Field) :: field_model type(ESMF_LogKind_Flag) :: logkindflag @@ -213,15 +192,8 @@ program mksurfdata ! character variables character(len=CL) :: string ! string read in character(len=CL) :: fname - character(len=CL) :: varname character(len=*), parameter :: subname = 'mksrfdata' ! program name - real(r8), allocatable :: pctnatveg(:) - real(r8), allocatable :: pctcrop(:) - real(r8), allocatable :: pct_nat_pft(:,:) - real(r8), allocatable :: pct_cft(:,:) - logical :: end_of_fdynloop - character(len=*), parameter :: u_FILE_u = & __FILE__ ! ------------------------------------------------------------ @@ -385,11 +357,14 @@ program mksurfdata ! ----------------------------------- ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] + ! Make landfrac_pft and pftdata_mask ! ----------------------------------- ! Determine fractional land from pft dataset allocate(pctlnd_pft(lsize_o)); pctlnd_pft(:) = spval allocate(pctnatpft(lsize_o)) ; allocate(pctcft(lsize_o)) ; + allocate(pftdata_mask(lsize_o)) ; pftdata_mask(:) = -999 + allocate(landfrac_pft(lsize_o)) ; landfrac_pft(:) = spval call mkpft( mksrf_fvegtyp_mesh, mksrf_fvegtyp, mesh_model, & pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') @@ -401,24 +376,16 @@ program mksurfdata call pctnatpft(n)%set_pct_l2g(0._r8) call pctcft(n)%set_pct_l2g(0._r8) end if - end do - - ! ----------------------------------- - ! Make landfrac_pft and pftdata_mask - ! ----------------------------------- - allocate ( pftdata_mask(lsize_o)) ; pftdata_mask(:) = -999 - allocate ( landfrac_pft(lsize_o)) ; landfrac_pft(:) = spval - do n = 1,lsize_o + if (pctlnd_pft(n) < 1.e-6_r8) then + call pctnatpft(n)%set_pct_l2g(0._r8) + call pctcft(n)%set_pct_l2g(0._r8) + end if landfrac_pft(n) = pctlnd_pft(n)/100._r8 if (pctlnd_pft(n) < 1.e-6_r8) then pftdata_mask(n) = 0 else pftdata_mask(n) = 1 end if - if (pctlnd_pft(n) < 1.e-6_r8) then - call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) - end if end do if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing land mask from pft dataset" @@ -442,10 +409,11 @@ program mksurfdata ! ----------------------------------- ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] ! ----------------------------------- - ! LAKEDEPTH is written out in mklakwat - allocate ( pctlak(lsize_o)) ; pctlak(:) = spval - allocate ( pctwet(lsize_o)) ; pctwet(:) = spval - zero_out_lake = (all_urban .or. all_veg) + ! LAKEDEPTH is written out in the subroutine + ! Need to keep pctlak and pctwet external for use below + allocate ( pctlak(lsize_o)) ; pctlak(:) = spval + allocate ( pctwet(lsize_o)) ; pctwet(:) = spval + zero_out_lake = (all_urban .or. all_veg) zero_out_wetland = (all_urban .or. all_veg .or. no_inlandwet) call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & zero_out_lake, zero_out_wetland, pctlak, pctwet, pioid, fsurdat, rc=rc) @@ -471,7 +439,7 @@ program mksurfdata ! Make glacier region ID [glacier_region] from [fglacierregion] dataset ! ----------------------------------- if (fsurdat /= ' ') then - ! Note that GLACIER_REGION is written out in the subroutine + ! GLACIER_REGION is written out in the subroutine call mkglacierregion(mksrf_fglacierregion_mesh, mksrf_fglacierregion, mesh_model, pioid, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacierregion') end if @@ -480,6 +448,7 @@ program mksurfdata ! Make soil texture [pctsand, pctclay] ! ----------------------------------- if (fsurdat /= ' ') then + ! mapunits, PCT_SAND and PCT_CLAY are written out in the subroutine call mksoiltex( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pioid, pctlnd_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') end if @@ -488,6 +457,7 @@ program mksurfdata ! Make soil color classes [soicol] [fsoicol] ! ----------------------------------- if (fsurdat /= ' ') then + ! SOIL_COLOR and mxsoil_color is written out in the subroutine call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, pctlnd_pft, pioid, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilcol') end if @@ -495,31 +465,20 @@ program mksurfdata ! ----------------------------------- ! Make soil fmax [fmaxsoil] ! ----------------------------------- - allocate(fmaxsoil(lsize_o)); fmaxsoil(:) = spval - call mksoilfmax( mksrf_fmax_mesh, mksrf_fmax, mesh_model, fmaxsoil, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilfmax') if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil fmax (maximum fraction saturated area)" - call mkfile_output (pioid, mesh_model, 'FMAX', fmaxsoil, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call pio_syncfile(pioid) + ! FMAX is written out in the subroutine + call mksoilfmax( mksrf_fmax_mesh, mksrf_fmax, mesh_model, pioid, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilfmax') end if - deallocate (fmaxsoil ) ! ----------------------------------- ! Make GDP data [gdp] from [gdp] ! ----------------------------------- - allocate (gdp(lsize_o)); gdp(:) = spval - call mkgdp (mksrf_fgdp_mesh, mksrf_fgdp, mesh_model, gdp_o=gdp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out gdp" - call mkfile_output(pioid, mesh_model, 'gdp', gdp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call pio_syncfile(pioid) + ! gdp is written out in the subroutine + call mkgdp (mksrf_fgdp_mesh, mksrf_fgdp, mesh_model, pioid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') end if - deallocate(gdp) - call pio_syncfile(pioid) ! ----------------------------------- ! Make peat data [fpeat] from [peatf] @@ -600,24 +559,10 @@ program mksurfdata ! ----------------------------------- ! Make organic matter density [organic] [forganic] ! ----------------------------------- - allocate ( organic(lsize_o,nlevsoi)); organic(:,:) = spval - call mkorganic( mksrf_forganic_mesh, mksrf_forganic, mesh_model, organic, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') - do n = 1,lsize_o - if (pctlnd_pft(n) < 1.e-6_r8) then - organic(n,:) = 0._r8 - end if - ! If have pole points on grid - set south pole to glacier and north pole is not land - if (abs((lat(n) - 90._r8)) < 1.e-6_r8) then - organic(n,:) = 0._r8 - end if - end do if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil organic matter density" - call mkfile_output(pioid, mesh_model, 'ORGANIC', organic, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call mkorganic( mksrf_forganic_mesh, mksrf_forganic, mesh_model, pctlnd_pft, lat, pioid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') end if - deallocate (organic ) ! ----------------------------------- ! Make VOC emission factors for isoprene [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] @@ -772,63 +717,12 @@ program mksurfdata ! ---------------------------------------------------------------------- ! Make glacier multiple elevation classes [pctglcmec,topoglcmec] from [fglacier] dataset ! ---------------------------------------------------------------------- - ! This call needs to occur after pctgla has been adjusted for the final time - allocate ( elevclass(nglcec+1) ) - call mkglcmecInit (elevclass) if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out GLC_MEC" - rcode = pio_inq_varid(pioid, 'GLC_MEC', pio_varid) - rcode = pio_put_var(pioid, pio_varid, elevclass) - end if - allocate ( pctglcmec(lsize_o,nglcec)) ; pctglcmec(:,:) = spval - allocate ( topoglcmec(lsize_o,nglcec)) ; topoglcmec(:,:)= spval - if ( outnc_3dglc )then - allocate(pctglcmec_gic(lsize_o,nglcec)) - allocate(pctglcmec_icesheet(lsize_o,nglcec)) - allocate(pctglc_gic(lsize_o)) - allocate(pctglc_icesheet(lsize_o)) - call mkglcmec(mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, & - pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, & - pctglcmec_gic_o=pctglcmec_gic, pctglcmec_icesheet_o=pctglcmec_icesheet, & - pctglc_gic_o=pctglc_gic, pctglc_icesheet_o=pctglc_icesheet, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglcmec') - else - call mkglcmec(mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, & - pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, rc=rc ) + call mkglcmecInit (pioid) + call mkglcmec(mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, pioid, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglcmec') end if - if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec" - call mkfile_output(pioid, mesh_model, 'PCT_GLC_MEC', pctglcmec, lev1name='nglcec', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out topo_glc_mec" - call mkfile_output(pioid, mesh_model, 'TOPO_GLC_MEC', topoglcmec, lev1name='nglcec', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - if (outnc_3dglc ) then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec_gic" - call mkfile_output(pioid, mesh_model, 'PCT_GLC_MEC_GIC', pctglcmec_gic, lev1name='nglcec', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_mec_icesheet" - call mkfile_output(pioid, mesh_model, 'PCT_GLC_MEC_ICESHEET', pctglcmec_icesheet, lev1name='nglcec', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_glc_gic" - call mkfile_output(pioid, mesh_model, 'PCT_GLC_GIC', pctglc_gic, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out pct_icesheet" - call mkfile_output(pioid, mesh_model, 'PCT_GLC_ICESHEET', pctglc_icesheet, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - end if - end if - deallocate(pctglcmec) - deallocate(topoglcmec) - deallocate(elevclass ) - if (outnc_3dglc) then - deallocate(pctglcmec_gic) - deallocate(pctglcmec_icesheet) - deallocate (pctglc_gic) - deallocate (pctglc_icesheet) - end if ! ---------------------------------------------------------------------- ! Close surface dataset diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index db08c8ebf2..acab179110 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -9,33 +9,33 @@ module mkvarctl implicit none private - integer, public :: ndiag ! output log unit - logical, public :: root_task ! proc 0 logical for printing msgs - integer, public :: iam ! processor number - integer, public :: npes ! number of processors - integer, public :: mpicom ! communicator group - - logical, public :: outnc_large_files ! output files in 64-bit format for large files - logical, public :: outnc_double ! output ALL data in files as 64-bit - integer, public :: outnc_dims = 2 ! only applicable to lat/lon grids - logical, public :: outnc_1d ! true => output file is 1d - logical, public :: outnc_vic ! true => output VIC fields - logical, public :: outnc_3dglc ! true => output 3D glacier fields + integer, public :: ndiag ! output log unit + logical, public :: root_task ! proc 0 logical for printing msgs + integer, public :: iam ! processor number + integer, public :: npes ! number of processors + integer, public :: mpicom ! communicator group + + logical, public :: outnc_large_files ! output files in 64-bit format for large files + logical, public :: outnc_double ! output ALL data in files as 64-bit + integer, public :: outnc_dims = 2 ! only applicable to lat/lon grids + logical, public :: outnc_1d ! true => output file is 1d + logical, public :: outnc_vic ! true => output VIC fields + logical, public :: outnc_3dglc ! true => output 3D glacier fields + + integer, public :: numpft = 16 ! number of plant types + integer, public :: nglcec = 10 ! number of elevation classes for glaciers integer , public :: soil_color_override real(r8), public :: soil_sand_override real(r8), public :: soil_clay_override real(r8), public :: soil_fmax_override - integer, public :: numpft = 16 ! number of plant types - ! Variables to override data read in with ! (all_urban is mostly for single-point mode, but could be used for sensitivity studies) - - logical , public :: all_urban ! output ALL data as 100% covered in urban - logical , public :: all_veg ! if gridcell will be 100% vegetated land-cover - logical , public :: no_inlandwet ! set wetland to 0% over land; wetland will only be used for ocean points - real(r8) , public :: std_elev = -999.99_r8 ! Standard deviation of elevation (m) to use for ent + logical , public :: all_urban ! output ALL data as 100% covered in urban + logical , public :: all_veg ! if gridcell will be 100% vegetated land-cover + logical , public :: no_inlandwet ! set wetland to 0% over land; wetland will only be used for ocean points + real(r8) , public :: std_elev = -999.99_r8 ! Standard deviation of elevation (m) to use for ent real(r8), public, parameter :: spval = 1.e36 ! special value integer, public, parameter :: ispval = -9999 ! special value From 976ff5335c361dc1edab6018af71403e1f50bc41 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 23 Feb 2022 14:29:11 -0700 Subject: [PATCH 077/614] fixed bug --- tools/mksurfdata_esmf/src/mkgdpMod.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkgdpMod.F90 b/tools/mksurfdata_esmf/src/mkgdpMod.F90 index 2fbfe86c21..4d60c63daf 100644 --- a/tools/mksurfdata_esmf/src/mkgdpMod.F90 +++ b/tools/mksurfdata_esmf/src/mkgdpMod.F90 @@ -42,7 +42,7 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! local variables: type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i - type(file_desc_t) :: pioid + type(file_desc_t) :: pioid_i integer :: ni,no,k integer :: ns_i, ns_o integer , allocatable :: mask_i(:) @@ -68,7 +68,7 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) call ESMF_VMLogMemInfo("At start of"//trim(subname)) ! Open input data file - rcode = pio_openfile(pio_iosystem, pioid, pio_iotype, trim(file_data_i), pio_nowrite) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) ! Read in input mesh mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) @@ -89,7 +89,7 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) if (ier/=0) call shr_sys_abort() allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, frac_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i if (frac_i(ni) > 0._r4) then @@ -104,7 +104,7 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! Read in gdp_i allocate(gdp_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'gdp', mesh_i, gdp_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'gdp', mesh_i, gdp_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -123,11 +123,11 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) end if ! Close the file - call pio_closefile(pioid) + call pio_closefile(pioid_i) ! Write output data if (root_task) write(ndiag, '(a)') trim(subname)//" writing out gdp" - call mkfile_output(pioid, mesh_o, 'gdp', gdp_o, rc=rc) + call mkfile_output(pioid_o, mesh_o, 'gdp', gdp_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') call pio_syncfile(pioid_o) From 089bed55d1b14b2a2a81cfa740124f43b7d2b2e1 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 28 Feb 2022 15:23:23 -0700 Subject: [PATCH 078/614] fixed bugs --- tools/mksurfdata_esmf/src/mkVICparamsMod.F90 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 index 5798b80197..c7ceb38964 100644 --- a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 @@ -143,8 +143,8 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, binfl_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do no = 1,ns_o - if (frac_o(ns_o) == 0._r8) then - ws_o(n) = 0.1_r8 + if (frac_o(no) == 0._r8) then + ws_o(no) = 0.1_r8 end if end do if (min_bad(binfl_o, min_valid_binfl, 'binfl')) then @@ -169,8 +169,8 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, ws_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do no = 1,ns_o - if (frac_o(ns_o) == 0._r8) then - ws_o(n) = 0.75_r8 + if (frac_o(no) == 0._r8) then + ws_o(no) = 0.75_r8 end if end do if (min_bad(ws_o, min_valid_ws, 'Ws')) then @@ -195,8 +195,8 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, dsmax_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do no = 1,ns_o - if (frac_o(ns_o) == 0._r8) then - dsmax_o(n) = 10._r8 + if (frac_o(no) == 0._r8) then + dsmax_o(no) = 10._r8 end if end do if (min_bad(dsmax_o, min_valid_dsmax, 'Dsmax')) then @@ -213,7 +213,7 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! ----------------------------------------------------------------- ! Read in Ds into data_i - call mkpio_get_rawdata(pioid_i, 'Dsmax', mesh_i, data_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'Ds', mesh_i, data_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -221,8 +221,8 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, ds_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do no = 1,ns_o - if (frac_o(ns_o) == 0._r8) then - ws_o(n) = 0.1_r8 + if (frac_o(no) == 0._r8) then + ws_o(no) = 0.1_r8 end if end do if (min_bad(ds_o, min_valid_ds, 'Ds')) then From 6ffde4255f3219026c329cf2ffc3216d850f546e Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 28 Feb 2022 16:14:38 -0700 Subject: [PATCH 079/614] updated Externals.cfg --- Externals.cfg | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Externals.cfg b/Externals.cfg index db522a635e..f596a4bd4f 100644 --- a/Externals.cfg +++ b/Externals.cfg @@ -1,10 +1,3 @@ -[ccs_config] -branch = main -protocol = git -repo_url = https://github.com/ESMCI/ccs_config_cesm -local_path = ccs_config -required = True - [clm] local_path = . protocol = externals_only From e047e8ddf2aecdfe222138aa0e6ae6d3261c1d76 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 28 Feb 2022 19:29:38 -0700 Subject: [PATCH 080/614] Fix bugs affecting VIC params --- tools/mksurfdata_esmf/src/mkVICparamsMod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 index c7ceb38964..62f7b68d64 100644 --- a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 @@ -144,7 +144,7 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do no = 1,ns_o if (frac_o(no) == 0._r8) then - ws_o(no) = 0.1_r8 + binfl_o(no) = 0.1_r8 end if end do if (min_bad(binfl_o, min_valid_binfl, 'binfl')) then @@ -222,7 +222,7 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do no = 1,ns_o if (frac_o(no) == 0._r8) then - ws_o(no) = 0.1_r8 + ds_o(no) = 0.1_r8 end if end do if (min_bad(ds_o, min_valid_ds, 'Ds')) then From 10d052e99c246fd5814933962b8d070d1edd4b0e Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 28 Feb 2022 19:31:00 -0700 Subject: [PATCH 081/614] Updated README with complete instructions and with additional notes --- tools/mksurfdata_esmf/README | 91 ++++++++++++++++++++++++++++++++---- 1 file changed, 83 insertions(+), 8 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 2620a589da..020a54edf0 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -1,22 +1,97 @@ -============================ +Updated on, by: +2/28/2022 slevis +2/23/2022 mvertens + +================ +Getting the code +================ +> cd +> git clone https://github.com/ESCOMP/CTSM.git +> cd +> git checkout feature/new_toolchain + +# Save time by checking out ccs_config only +> ./manage_externals/checkout_externals ccs_config + +> cd tools/mksurfdata_esmf + +======================= building the executable -============================ -> rm -rf bld -> mkdir ./bld +======================= +> rm -rf bld # (or the contents of /bld) before rerunning CC=... +> mkdir ./bld # IF YOU MODIFY .F90 files, start over from "rm -rf bld" > cd bld +> module load intel # in case need latest version of intel +> module load python # in case need latest version of python > module load cmake +> bash > CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src/ > make VERBOSE=1 +> export MKSURFDATA_BLD=`pwd` # needed once; execute in /bld > cd ../src > make clean -> MKSURDATA_BLD=../bld make VERBOSE=1 +> make VERBOSE=1 -============================ -running the code (you could add mksurfdata_in) -============================ > cd ../ + +======= +running +======= > rm mksurfdata_in +> bash # need if not going through "building the executable" > temp=`./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc | cut -d' ' -f5` > ln -s $temp mksurfdata_in > qsub gen_mksurfdata + +----- +NOTES +------------------------------------------------------------ +slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED +------------------------------------------------------------ +1) > temp=`./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc | cut -d' ' -f5` + +.nc file issues: +- URBAN vars have bigger diffs likely bc using newer raw datasets +- abm, std elev, organic have some bigger diffs +- glacier region MV confirmed w BillS that Greenland diff is ok + +.log file issues: +- Successfully made PFTs, harvest and grazing, glacier, urban, +topo stats, and organic don't show input/output for comparison +- soil texture category 3 and soil color category 15 inputs/outputs +problematic or just that we set ocean to loam? +- agricultural fire peak month: output areas increase for all categories +- voc emission factors all zero + +2) repeat for 0.9x + +3) > temp=`./gen_mksurfdata_namelist.py --start-year 1850 --end-year 1850 --res 4x5 --vic --glc | cut -d' ' -f5` + +No issues specific to this resolution. + +------------------------------------------------------ +DYNAMIC LU: NOT ALL FILES HAVE BEEN TRANSLATED to cdf5 +------------------------------------------------------ +Coordinate with Peter Lawrence. Use this command to translate: +> nccopy -k cdf5 oldfile newfile + +-------------------------------------------------------- +Python script for generating namelists has NOT ADDRESSED: +-------------------------------------------------------- +* Regional/1x1: handled by subset.py +* High res +* Potveg: needs file(s) converted to cdf5 first? +* Merge_gis +* Nocrop: does this work now? +* Ssp_rcp: needs files converted to cdf5 first? +* Override options: +-- all_veg = .true. handled by fsurdat_modifier zero_nonveg = .true. +-- all_urban = .true. handle w fsurdat_modifier new option (see subset.py) +-- no_inlandwet = .false. same +-- fsurdat_modify should focus on modifying and subset on subsetting + +Sam to run +> make all +to see that new code works for all the grids. How to automate and how +few nodes could be used? From 39ad587f51b572632b9ebd7471928d6593bf0921 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 1 Mar 2022 12:33:17 -0700 Subject: [PATCH 082/614] Update .gitignore to ignore PET* and other files generated by mksurfdata --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 9faff58438..6fe958c32e 100644 --- a/.gitignore +++ b/.gitignore @@ -85,6 +85,11 @@ landuse_timeseries_*.txt ctsm.input_data_list ctsm.input_data_list.previous *.stdout.txt.o* +/tools/mksurfdata_esmf/PET* +/tools/mksurfdata_esmf/job_name.o* +/tools/mksurfdata_esmf/mksurfdata_in +/tools/mksurfdata_esmf/bld +/tools/mksurfdata_esmf/src # mksurfdata unit tests unit_test_build From d8d8930c855d606b07ed3228865a389cf76dc3f6 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 28 Feb 2022 19:50:54 -0700 Subject: [PATCH 083/614] updates to remove override functionality --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 32 +- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 315 +++------ tools/mksurfdata_esmf/src/mkinputMod.F90 | 41 -- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 102 ++- tools/mksurfdata_esmf/src/mkpftMod.F90 | 709 ++++---------------- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 16 +- tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 | 14 +- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 33 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 118 ++-- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 25 +- tools/mksurfdata_esmf/src/mkvarctl.F90 | 11 +- tools/mksurfdata_esmf/src/mkvocefMod.F90 | 2 +- 12 files changed, 364 insertions(+), 1054 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 76a9401142..77de0c6bab 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -135,14 +135,6 @@ subroutine mkfile_define_atts(pioid, dynlanduse) rcode = pio_put_att (pioid, pio_global, 'Source', trim(str)) rcode = pio_put_att (pioid, pio_global, 'Version', trim(gitdescribe)) - if ( all_urban )then - str = 'TRUE' - rcode = pio_put_att(pioid, pio_global, 'all_urban', trim(str)) - end if - if ( no_inlandwet )then - str = 'TRUE' - rcode = pio_put_att(pioid, pio_global, 'no_inlandwet', trim(str)) - end if !rcode = pio_put_att_int(pioid, pio_global, 'nglcec', nglcec) ! Raw data file names @@ -230,24 +222,12 @@ subroutine mkfile_define_atts(pioid, dynlanduse) end if if (.not. dynlanduse) then - if ( soil_color_override /= unsetcol )then - rcode = pio_put_att(pioid, pio_global, 'soil_color_override', 'TRUE') - else - str = get_filename(mksrf_fsoicol) - rcode = pio_put_att(pioid, pio_global, 'soil_color_raw_data_file_name', trim(str)) - end if - if ( soil_clay_override /= unsetsoil .and. soil_sand_override /= unsetsoil) then - rcode = pio_put_att(pioid, pio_global, 'soil_clay_override', 'TRUE') - else - str = get_filename(mksrf_fsoitex) - rcode = pio_put_att(pioid, pio_global, 'soil_texture_raw_data_file_name', trim(str)) - end if - if ( soil_fmax_override /= unsetsoil )then - rcode = pio_put_att(pioid, pio_global, 'soil_fmax_override', 'TRUE') - else - str = get_filename(mksrf_fmax) - rcode = pio_put_att(pioid, pio_global, 'fmax_raw_data_file_name', trim(str)) - end if + str = get_filename(mksrf_fsoicol) + rcode = pio_put_att(pioid, pio_global, 'soil_color_raw_data_file_name', trim(str)) + str = get_filename(mksrf_fsoitex) + rcode = pio_put_att(pioid, pio_global, 'soil_texture_raw_data_file_name', trim(str)) + str = get_filename(mksrf_fmax) + rcode = pio_put_att(pioid, pio_global, 'fmax_raw_data_file_name', trim(str)) str = get_filename(mksrf_forganic) rcode = pio_put_att(pioid, pio_global, 'organic_matter_raw_data_file_name', trim(str)) end if diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index 5772b28fe6..02275a0288 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -24,7 +24,6 @@ module mkharvestMod ! public member functions public :: mkharvest ! Calculate the harvest values on output grid - public :: mkharvest_parse_oride ! Parse the over-ride string ! private data members: integer, parameter :: numharv = 9 ! number of harvest and grazing fields @@ -54,7 +53,6 @@ module mkharvestMod character(len=CL), parameter :: string_undef = 'UNSET' real(r8), parameter :: real_undef = -999.99 - real(r8), pointer :: oride_harv(:) ! array that can override harvesting type(ESMF_Mesh) :: mesh_i type(ESMF_RouteHandle) :: routehandle_r8 @@ -68,7 +66,7 @@ module mkharvestMod contains !================================================================================= - subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constant, ntime, rc) + subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, constant, ntime, rc) ! ! Make harvest data for the dynamic PFT dataset. ! This dataset consists of the normalized harvest or grazing fraction (0-1) of @@ -79,7 +77,6 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constan character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh type(file_desc_t) , intent(inout) :: pioid_o - logical , intent(in) :: all_veg logical , intent(in) :: constant integer, optional , intent(in) :: ntime integer , intent(out) :: rc ! return code @@ -130,34 +127,6 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constan ! Normally read in the harvesting file, and then regrid to output grid rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) - ! If all veg then write out output data with values set to harvest_initval and return - if (all_veg) then - varname_i = trim(harvest_fieldnames(ifld)) - if (constant) then - varname_o = trim(harvest_const_fieldnames(ifld)) - else - varname_o = varname_i - end if - call mkharvest_check_input_var(pioid_i, trim(varname_i), varexists, dims2nd, name2nd) - if (varexists) then - if (dims2nd == 0) then - allocate(data1d_o(ns_o)) - data1d_o(:) = 0._r8 - call mkfile_output(pioid_o, mesh_o, trim(varname_o), data1d_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - deallocate(data1d_o) - else - allocate(data2d_o(ns_o,dims2nd)) - data2d_o(:,:) = 0._r8 - call mkfile_output(pioid_o, mesh_o, trim(varname_o), data2d_o, lev1name=name2nd, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - deallocate(data2d_o) - end if - end if - call pio_closefile(pioid_i) - RETURN - end if - ! Read in input mesh if (.not. ESMF_MeshIsCreated(mesh_i)) then mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) @@ -168,155 +137,123 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constan call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! TODO: imlement oride_harv funcitionality - this is hard-wired for now - allocate( oride_harv(numharv) ) - oride_harv(:) = real_undef - - if ( all(oride_harv == real_undef ) )then - - ! Get the landmask from the file and reset the mesh mask based on that - allocate(rmask_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(mask_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do ni = 1,ns_i - if (rmask_i(ni) > 0._r4) then - mask_i(ni) = 1 - else - mask_i(ni) = 0 - end if - end do - deallocate(rmask_i) - call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Create a route handle between the input and output mesh - ! NOTE: this must be done after mask_i is set in mesh_i - if (.not. ESMF_RouteHandleIsCreated(routehandle_r8)) then - allocate(frac_o(ns_o)) - call create_routehandle_r8(mesh_i, mesh_o, routehandle_r8, frac_o=frac_o, rc=rc) - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + ! Get the landmask from the file and reset the mesh mask based on that + allocate(rmask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (rmask_i(ni) > 0._r4) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 end if + end do + deallocate(rmask_i) + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Read in input 1d fields if they exists and map to output grid - do ifld = 1,numharv - varname_i = trim(harvest_fieldnames(ifld)) - if (constant) then - varname_o = trim(harvest_const_fieldnames(ifld)) - else - varname_o = varname_i - end if - call mkharvest_check_input_var(pioid_i, trim(varname_i), varexists, dims2nd, name2nd) - if (varexists) then - if (dims2nd == 0) then + ! Create a route handle between the input and output mesh + ! NOTE: this must be done after mask_i is set in mesh_i + if (.not. ESMF_RouteHandleIsCreated(routehandle_r8)) then + allocate(frac_o(ns_o)) + call create_routehandle_r8(mesh_i, mesh_o, routehandle_r8, frac_o=frac_o, rc=rc) + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + end if - ! 1d output - allocate(data1d_i(ns_i)) - allocate(data1d_o(ns_o)) + ! Read in input 1d fields if they exists and map to output grid + do ifld = 1,numharv + varname_i = trim(harvest_fieldnames(ifld)) + if (constant) then + varname_o = trim(harvest_const_fieldnames(ifld)) + else + varname_o = varname_i + end if + call mkharvest_check_input_var(pioid_i, trim(varname_i), varexists, dims2nd, name2nd) + if (varexists) then + if (dims2nd == 0) then - ! read in input 1d variable - call mkpio_get_rawdata(pioid_i, varname_i, mesh_i, data1d_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! 1d output + allocate(data1d_i(ns_i)) + allocate(data1d_o(ns_o)) - ! regrid input variable - call regrid_rawdata(mesh_i, mesh_o, routehandle_r8, data1d_i, data1d_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! read in input 1d variable + call mkpio_get_rawdata(pioid_i, varname_i, mesh_i, data1d_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! write out mapped variable - if (present(ntime)) then - if (root_task) write(ndiag, '(a,i8)') subname//" writing out 1d "//trim(varname_o)//' at time ',ntime - rcode = pio_inq_varid(pioid_o, trim(varname_o), pio_varid_o) - call mkpio_iodesc_output(pioid_o, mesh_o, trim(varname_o), pio_iodesc_o, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in making an iodesc for '//trim(varname_o)) - call pio_setframe(pioid_o, pio_varid_o, int(ntime, kind=Pio_Offset_Kind)) - call pio_write_darray(pioid_o, pio_varid_o, pio_iodesc_o, data1d_o, rcode) - call pio_freedecomp(pioid_o, pio_iodesc_o) - else - if (root_task) write(ndiag, '(a)') subname//" writing out 1d "//trim(varname_o) - call mkfile_output(pioid_o, mesh_o, trim(varname_o), data1d_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - call pio_syncfile(pioid_o) - - ! TODO: uncomment the following and validate - ! Compare global areas on input and output grids for 1d variables - ! call mkharvest check_global_sums('harvest type '//trim(varname_o), ns_i, ns_o, & - ! mesh_i, mesh_o, mask_i, frac_o, data1d_i, data1d_o, rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) return - - deallocate(data1d_i) - deallocate(data1d_o) - - else ! 2d output - - ! Read in input data - allocate(read_data2d_i(dims2nd, ns_i)) - allocate(read_data2d_o(dims2nd, ns_o)) - call mkpio_get_rawdata(pioid_i, trim(varname_i), mesh_i, read_data2d_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Regrid input input data - call regrid_rawdata(mesh_i, mesh_o, routehandle_r8, read_data2d_i, read_data2d_o, 1, dims2nd, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - deallocate(read_data2d_i) - - ! Fill in output 2d array - allocate(data2d_o(ns_o,dims2nd)) - do l = 1,dims2nd - do no = 1,ns_o - data2d_o(no,l) = read_data2d_o(l,no) - end do - end do - deallocate(read_data2d_o) - - ! write out variable - if (present(ntime)) then - if (root_task) write(ndiag, '(a,i8)') subname//" writing out 2d "//trim(varname_o)//' at time ',ntime - rcode = pio_inq_varid(pioid_o, trim(varname_o), pio_varid_o) - call mkpio_iodesc_output(pioid_o, mesh_o, trim(varname_o), pio_iodesc_o, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in making an iodesc for '//trim(varname_o)) - call pio_setframe(pioid_o, pio_varid_o, int(ntime, kind=Pio_Offset_Kind)) - call pio_write_darray(pioid_o, pio_varid_o, pio_iodesc_o, data2d_o, rcode) - call pio_freedecomp(pioid_o, pio_iodesc_o) - else - if (root_task) write(ndiag, '(a)') subname//" writing out 2d "//trim(varname_o) - call mkfile_output(pioid_o, mesh_o, trim(varname_o), data2d_o, lev1name=trim(name2nd), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - call pio_syncfile(pioid_o) - deallocate(data2d_o) + ! regrid input variable + call regrid_rawdata(mesh_i, mesh_o, routehandle_r8, data1d_i, data1d_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! write out mapped variable + if (present(ntime)) then + if (root_task) write(ndiag, '(a,i8)') subname//" writing out 1d "//trim(varname_o)//' at time ',ntime + rcode = pio_inq_varid(pioid_o, trim(varname_o), pio_varid_o) + call mkpio_iodesc_output(pioid_o, mesh_o, trim(varname_o), pio_iodesc_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in making an iodesc for '//trim(varname_o)) + call pio_setframe(pioid_o, pio_varid_o, int(ntime, kind=Pio_Offset_Kind)) + call pio_write_darray(pioid_o, pio_varid_o, pio_iodesc_o, data1d_o, rcode) + call pio_freedecomp(pioid_o, pio_iodesc_o) + else + if (root_task) write(ndiag, '(a)') subname//" writing out 1d "//trim(varname_o) + call mkfile_output(pioid_o, mesh_o, trim(varname_o), data1d_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - end if + call pio_syncfile(pioid_o) - end do + ! TODO: uncomment the following and validate + ! Compare global areas on input and output grids for 1d variables + ! call mkharvest check_global_sums('harvest type '//trim(varname_o), ns_i, ns_o, & + ! mesh_i, mesh_o, mask_i, frac_o, data1d_i, data1d_o, rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) return - else + deallocate(data1d_i) + deallocate(data1d_o) - ! Otherwise override the harvesting with the input harvest values - ! TODO: implement this - ! if ( any(oride_harv == real_undef ) )then - ! write(6,*) subname, ' error some override harvesting fields set and others are not = ', oride_harv - ! call shr_sys_abort() - ! end if - ! do k = 1, harvdata%num1Dfields() - ! m = ind1D(k) - ! if ( oride_harv(m) < 0.0_r8 .or. oride_harv(m) > 100.0_r8 )then - ! write(6,*) subname, ' error override harvesting field out of range', & - ! oride_harv(m), ' field = ', mkharvest_fieldname(m) - ! call shr_sys_abort() - ! end if - ! end do - ! do no = 1,ns_o - ! do k = 1, harvdata%num1Dfields() - ! m = ind1D(k) - ! data1D_o(no) = oride_harv(m) - ! end do - ! end do + else ! 2d output - end if + ! Read in input data + allocate(read_data2d_i(dims2nd, ns_i)) + allocate(read_data2d_o(dims2nd, ns_o)) + call mkpio_get_rawdata(pioid_i, trim(varname_i), mesh_i, read_data2d_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Regrid input input data + call regrid_rawdata(mesh_i, mesh_o, routehandle_r8, read_data2d_i, read_data2d_o, 1, dims2nd, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + deallocate(read_data2d_i) + + ! Fill in output 2d array + allocate(data2d_o(ns_o,dims2nd)) + do l = 1,dims2nd + do no = 1,ns_o + data2d_o(no,l) = read_data2d_o(l,no) + end do + end do + deallocate(read_data2d_o) + + ! write out variable + if (present(ntime)) then + if (root_task) write(ndiag, '(a,i8)') subname//" writing out 2d "//trim(varname_o)//' at time ',ntime + rcode = pio_inq_varid(pioid_o, trim(varname_o), pio_varid_o) + call mkpio_iodesc_output(pioid_o, mesh_o, trim(varname_o), pio_iodesc_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in making an iodesc for '//trim(varname_o)) + call pio_setframe(pioid_o, pio_varid_o, int(ntime, kind=Pio_Offset_Kind)) + call pio_write_darray(pioid_o, pio_varid_o, pio_iodesc_o, data2d_o, rcode) + call pio_freedecomp(pioid_o, pio_iodesc_o) + else + if (root_task) write(ndiag, '(a)') subname//" writing out 2d "//trim(varname_o) + call mkfile_output(pioid_o, mesh_o, trim(varname_o), data2d_o, lev1name=trim(name2nd), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + call pio_syncfile(pioid_o) + deallocate(data2d_o) + + end if + end if + end do ! If constant model, clean up the mapping if (constant) then @@ -333,46 +270,6 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, all_veg, constan end subroutine mkharvest - !================================================================================= - subroutine mkharvest_parse_oride( string ) - ! - ! Parse the string with harvest and grazing information on it, to override - ! the file with this information rather than reading from a file. - ! - use shr_string_mod, only: shr_string_betweenTags - - ! input/output variables: - character(len=CS), intent(in) :: string ! String to parse with harvest and grazing data - - ! local variables: - character(len=CS) :: substring ! substring between tags - integer :: rc ! error return code - character(len=*), parameter :: harv_start = "" - character(len=*), parameter :: harv_end = "" - character(len=*), parameter :: graz_start = "" - character(len=*), parameter :: graz_end = "" - character(len=*), parameter :: subname = 'mkharvest_parse_oride' - !----------------------------------------------------------------------- - - call shr_string_betweenTags( string, harv_start, harv_end, substring, rc ) - if ( rc /= 0 )then - write(6,*) subname//'Trouble finding harvest start end tags' - call shr_sys_abort() - end if - read(substring,*) oride_harv(1:numharv-1) - call shr_string_betweenTags( string, graz_start, graz_end, substring, rc ) - if ( rc /= 0 )then - write(6,*) subname//'Trouble finding grazing start end tags' - call shr_sys_abort() - end if - read(substring,*) oride_harv(numharv) - if ( harvest_fieldnames(numharv) /= 'GRAZING' )then - write(6,*) subname, ' grazing is NOT last field as was expected' - call shr_sys_abort() - end if - - end subroutine mkharvest_parse_oride - !================================================================================= subroutine mkharvest_check_global_sums(name, ns_i, ns_o, mesh_i, mesh_o, mask_i, frac_o, & data_i, data_o, rc) diff --git a/tools/mksurfdata_esmf/src/mkinputMod.F90 b/tools/mksurfdata_esmf/src/mkinputMod.F90 index 9e33d14e79..8777271eb1 100644 --- a/tools/mksurfdata_esmf/src/mkinputMod.F90 +++ b/tools/mksurfdata_esmf/src/mkinputMod.F90 @@ -7,7 +7,6 @@ module mkinputMod use shr_kind_mod , only : r8 => shr_kind_r8 use shr_kind_mod , only : CS => shr_kind_CS, CL => shr_kind_CL, CX => shr_kind_CX use shr_sys_mod , only : shr_sys_abort - use mkpftMod , only : pft_idx, pft_frc use mkvarctl implicit none @@ -176,16 +175,7 @@ subroutine read_namelist_input(filename) mksrf_fgrid_mesh_nx, & mksrf_fgrid_mesh_ny, & numpft, & - all_veg, & - all_urban, & - no_inlandwet, & - soil_color_override, & - soil_sand_override, & - soil_clay_override, & - soil_fmax_override, & nglcec, & - pft_idx, & - pft_frc, & gitdescribe, & outnc_large_files, & outnc_double, & @@ -203,13 +193,6 @@ subroutine read_namelist_input(filename) outnc_double = .true. outnc_vic = .false. outnc_3dglc = .false. - all_urban = .false. - all_veg = .false. - no_inlandwet = .true. - soil_color_override = unsetcol - soil_sand_override = unsetsoil - soil_clay_override = unsetsoil - soil_fmax_override = unsetsoil urban_skip_abort_on_invalid_data_check = .false. ! default value for bug work around if (root_task) then @@ -306,16 +289,7 @@ subroutine read_namelist_input(filename) call mpi_bcast (outnc_vic, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (outnc_3dglc, 1, MPI_LOGICAL, 0, mpicom, ier) - call mpi_bcast (all_urban, 1, MPI_LOGICAL, 0, mpicom, ier) - call mpi_bcast (all_veg, 1, MPI_LOGICAL, 0, mpicom, ier) - call mpi_bcast (no_inlandwet, 1, MPI_LOGICAL, 0, mpicom, ier) - call mpi_bcast (soil_color_override, 1, MPI_INTEGER, 0, mpicom, ier) - call mpi_bcast (soil_sand_override, 1, MPI_REAL, 0, mpicom, ier) - call mpi_bcast (soil_clay_override, 1, MPI_REAL, 0, mpicom, ier) - call mpi_bcast (soil_fmax_override, 1, MPI_REAL, 0, mpicom, ier) - call mpi_bcast (urban_skip_abort_on_invalid_data_check, 1, MPI_LOGICAL, 0, mpicom, ier) - call mpi_bcast (numpft, 1, MPI_INTEGER, 0, mpicom, ier) call mpi_bcast (std_elev, 1, MPI_REAL, 0, mpicom, ier) @@ -450,21 +424,6 @@ subroutine write_namelist_input() if ( outnc_3dglc )then write(ndiag,'(a)')' Output optional 3D glacier fields (mostly used for verification of the glacier model)' end if - if ( all_urban )then - write(ndiag,'(a)') ' all_urban is true => Output ALL data in file as 100% urban' - else - write(ndiag,'(a)') ' all_urban is false ' - end if - if ( no_inlandwet )then - write(ndiag,'(a)') ' no_inlandwet is true => Set wetland to 0% over land' - else - write(ndiag,'(a)') ' no_inlandwet is false' - end if - if (all_veg) then - write(ndiag,'(a)') ' all_veg is true => Output ALL data in file as 100% vegetated' - else - write(ndiag,'(a)') ' all_veg is false ' - end if if (urban_skip_abort_on_invalid_data_check) then write(ndiag, '(a)') " WARNING: aborting on invalid data check in urban has been disabled!" write(ndiag, '(a)') " WARNING: urban data may be invalid!" diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 19d96bf368..2ccfea8166 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -29,9 +29,7 @@ module mklanwatMod contains !=============================================================== - subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & - zero_out_lake, zero_out_wetland, lake_o, swmp_o, & - pioid_o, fsurdat, rc) + subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, swmp_o, pioid_o, fsurdat, rc) ! ------------------- ! make %lake, %wetland and lake parameters @@ -41,8 +39,6 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o - logical , intent(in) :: zero_out_lake ! if should zero glacier out - logical , intent(in) :: zero_out_wetland ! if should zero glacier out type(file_desc_t) , intent(inout) :: pioid_o real(r8) , intent(out) :: lake_o(:) ! output grid: %lake real(r8) , intent(out) :: swmp_o(:) ! output grid: %lake @@ -123,65 +119,61 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & ! ---------------------------------------- lake_o(:) = 0._r8 - if (.not. zero_out_lake) then - if (root_task) then - write (ndiag,*) 'Attempting to make %lake .....' - end if - - ! Read in lake_i - allocate(lake_i(ns_i), stat=rcode) - if (rcode/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid_i, 'PCT_LAKE', mesh_i, lake_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Regrid lake_i to lake_o - call regrid_rawdata(mesh_i, mesh_o, routehandle, lake_i, lake_o, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - do no = 1,ns_o - if (lake_o(no) < 1.) lake_o(no) = 0. - enddo - - ! Check global areas - call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - lake_i, lake_o, "pct lake", "unitless", ndiag, nomask=.true., rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - deallocate (lake_i) + if (root_task) then + write (ndiag,*) 'Attempting to make %lake .....' end if + ! Read in lake_i + allocate(lake_i(ns_i), stat=rcode) + if (rcode/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid_i, 'PCT_LAKE', mesh_i, lake_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Regrid lake_i to lake_o + call regrid_rawdata(mesh_i, mesh_o, routehandle, lake_i, lake_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do no = 1,ns_o + if (lake_o(no) < 1.) lake_o(no) = 0. + enddo + + ! Check global areas + call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + lake_i, lake_o, "pct lake", "unitless", ndiag, nomask=.true., rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + deallocate (lake_i) + ! ---------------------------------------- ! Create %wetland ! ---------------------------------------- swmp_o(:) = 0._r8 - if (.not. zero_out_wetland) then - if (root_task) then - write (ndiag,*) 'Attempting to make %wetland .....' - end if - - ! read in swmp_i - allocate(swmp_i(ns_i), stat=rcode) - if (rcode/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid_i, 'PCT_WETLAND', mesh_i, lake_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! regrid swmp_i to swmp_o - this also returns swmp_i to be used in the global sums below - call regrid_rawdata(mesh_i, mesh_o, routehandle, swmp_i, swmp_o, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regrid_data for wetland") - if (ChkErr(rc,__LINE__,u_FILE_u)) return - do no = 1,ns_o - if (swmp_o(no) < 1.) swmp_o(no) = 0. - enddo - - ! Check global areas - call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - swmp_i, swmp_o, "pct wetland", "unitless", ndiag, nomask=.true., rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - deallocate (swmp_i) + if (root_task) then + write (ndiag,*) 'Attempting to make %wetland .....' end if + ! read in swmp_i + allocate(swmp_i(ns_i), stat=rcode) + if (rcode/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid_i, 'PCT_WETLAND', mesh_i, lake_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! regrid swmp_i to swmp_o - this also returns swmp_i to be used in the global sums below + call regrid_rawdata(mesh_i, mesh_o, routehandle, swmp_i, swmp_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regrid_data for wetland") + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do no = 1,ns_o + if (swmp_o(no) < 1.) swmp_o(no) = 0. + enddo + + ! Check global areas + call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + swmp_i, swmp_o, "pct wetland", "unitless", ndiag, nomask=.true., rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + deallocate (swmp_i) + ! ---------------------------------------- ! Create lake parameter (lakedepth) ! ---------------------------------------- diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index 82e3827c49..6079d55436 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -18,51 +18,13 @@ module mkpftMod #include - public :: mkpftInit ! Initialization - public :: mkpft ! Set PFT - public :: mkpft_parse_oride ! Parse the string with PFT fraction/index info to override + public :: mkpftInit ! Initialization + public :: mkpft ! Set PFT - private :: mkpft_check_oride ! Check the pft_frc and pft_idx values for correctness - - ! When pft_idx and pft_frc are set, they must be set together, and they will cause the - ! entire area to be covered with vegetation and zero out other landunits. - ! The sum of pft_frc must = 100%, and each pft_idx point in the array corresponds to - ! the fraction in pft_frc. Only the first few points are used until pft_frc = 0.0. - - integer :: m ! index - - ! PFT vegetation index to override with - integer, public :: pft_idx(0:maxpft) = (/ ( -1, m = 0, maxpft ) /) - - ! PFT vegetation fraction to override with - real(r8), public :: pft_frc(0:maxpft) = (/ ( 0.0_r8, m = 0, maxpft ) /) - - ! private data members: - logical, public, protected :: use_input_pft = .false. ! Flag to override PFT with input values - logical, public, protected :: presc_cover = .false. ! Flag to prescribe vegetation coverage - integer, private :: nzero ! index of first zero fraction - - type, public :: pft_oride ! Public only for unit testing - real(r8) :: crop ! Percent covered by crops - real(r8) :: natveg ! Percent covered by natural vegetation - real(r8), allocatable :: natpft(:) ! Percent of each natural PFT within the natural veg landunit - real(r8), allocatable :: cft(:) ! Percent of each crop CFT within the crop landunit - contains - procedure, public :: InitZeroOut ! Initialize the PFT override object to zero out all vegetation - procedure, public :: InitAllPFTIndex ! Initialize the PFT override object with PFT indeces for all veg and crop types - procedure, public :: Clean ! Clean up a PFT Override object - end type pft_oride - - interface pft_oride - module procedure :: constructor ! PFT Overide object constructor - end interface pft_oride + integer :: m ! index character(len=35) :: veg(0:maxpft) ! vegetation types - ! Module instance of PFT override object - ! Used for both zeroing out PFT's as well as setting specified PFT's over the gridcell - type(pft_oride), private :: pft_override - character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -70,17 +32,11 @@ module mkpftMod contains !=============================================================== - subroutine mkpftInit( zero_out_l, all_veg_l ) + subroutine mkpftInit( ) ! - ! Initialize of Make PFT data + ! Initialize of PFT data ! - ! input/output variables - logical, intent(in) :: zero_out_l ! If veg should be zero'ed out - logical, intent(in) :: all_veg_l ! If should zero out other fractions so that all land-cover is vegetation - ! local variables: - logical :: error_happened ! If an error was triggered so should return - real(r8), parameter :: hndrd = 100.0_r8 ! A hundred percent character(len=*), parameter :: subname = ' (mkpftInit) ' !----------------------------------------------------------------------- @@ -88,38 +44,6 @@ subroutine mkpftInit( zero_out_l, all_veg_l ) write(6,*) subname//'number PFT is > max allowed!' call shr_sys_abort() end if - nzero = -1 - call mkpft_check_oride( error_happened ) - if ( error_happened )then - write(6,*) subname//'Problem setting pft override settings' - end if - if ( zero_out_l .and. use_input_pft )then - write(6,*) subname//"trying to both zero out all PFT's as well as set them to specific values" - call shr_sys_abort() - end if - - ! If zeroing out, set use_input_pft to true so the pft_override will be used - if( zero_out_l )then - nzero = 0 - pft_frc(0) = 0.0_r8 - pft_idx(0) = noveg - use_input_pft = .true. - end if - if ( use_input_pft ) then - if (root_task) then - write(ndiag,*) subname // ' Set PFT fraction to : ', pft_frc(0:nzero) - write(ndiag,*) subname // ' With PFT index : ', pft_idx(0:nzero) - end if - end if - if ( all_veg_l .and. .not. use_input_pft )then - write(6,*) subname//'if all_veg is set to true then specified PFT indices must be provided (i.e. pft_frc and pft_idx)' - call shr_sys_abort() - end if - - if ( zero_out_l .and. all_veg_l )then - write(6,*) subname//'zeroing out vegetation and setting vegetation to 100% is a contradiction!' - call shr_sys_abort() - end if ! Determine number of PFTs on the natural vegetation landunit, and number of CFTs on ! the crop landunit. @@ -158,27 +82,6 @@ subroutine mkpftInit( zero_out_l, all_veg_l ) call shr_sys_abort() end if - ! Set the PFT override values if applicable - pft_override = pft_oride() - presc_cover = .false. - if( zero_out_l )then - call pft_override%InitZeroOut() - presc_cover = .true. - else if ( use_input_pft ) then - call pft_override%InitAllPFTIndex() - if ( .not. all_veg_l )then - if ( pft_override%crop <= 0.0 )then - write(6,*) "Warning: PFT/CFT's are being overridden, but no crop type is being asked for" - end if - if ( pft_override%natveg <= 0.0 )then - write(6,*) "Warning: PFT/CFT's are being overridden, but no natural vegetation type is being asked for" - end if - presc_cover = .false. - else - presc_cover = .true. - end if - end if - ! ----------------------------------------------------------------- ! Set the vegetation types ! ----------------------------------------------------------------- @@ -396,50 +299,37 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Create Error checks if presc_cover is false - if ( .not. presc_cover ) then - rcode = pio_inq_dimid(pioid, 'natpft', dimid) - rcode = pio_inq_dimlen(pioid, dimid, natpft_i) - rcode = pio_inq_dimid(pioid, 'cft', dimid) - rcode = pio_inq_dimlen(pioid, dimid, ncft_i) - numpft_i = natpft_i + ncft_i - - ! Check if the number of pfts on the input matches the expected number. A mismatch - ! is okay if the input raw dataset has prognostic crops and the output does not. - if (numpft_i /= numpft+1) then - if (numpft_i == numstdpft+1) then - write(6,*) subname//' ERROR: trying to use non-crop input file' - write(6,*) 'for a surface dataset with crops.' - call shr_sys_abort() - else if (numpft_i > numstdpft+1 .and. numpft_i == maxpft+1) then - write(6,*) subname//' WARNING: using a crop input raw dataset for a non-crop output surface dataset' - else - write(6,*) subname//': parameter numpft+1= ',numpft+1, & - 'does not equal input dataset numpft= ',numpft_i - call shr_sys_abort() - end if - endif - end if + ! Create error checks + rcode = pio_inq_dimid(pioid, 'natpft', dimid) + rcode = pio_inq_dimlen(pioid, dimid, natpft_i) + rcode = pio_inq_dimid(pioid, 'cft', dimid) + rcode = pio_inq_dimlen(pioid, dimid, ncft_i) + numpft_i = natpft_i + ncft_i + + ! Check if the number of pfts on the input matches the expected number. A mismatch + ! is okay if the input raw dataset has prognostic crops and the output does not. + if (numpft_i /= numpft+1) then + if (numpft_i == numstdpft+1) then + write(6,*) subname//' ERROR: trying to use non-crop input file' + write(6,*) 'for a surface dataset with crops.' + call shr_sys_abort() + else if (numpft_i > numstdpft+1 .and. numpft_i == maxpft+1) then + write(6,*) subname//' WARNING: using a crop input raw dataset for a non-crop output surface dataset' + else + write(6,*) subname//': parameter numpft+1= ',numpft+1, & + 'does not equal input dataset numpft= ',numpft_i + call shr_sys_abort() + end if + endif ! ---------------------------------------- ! Create a route handle between the input and output mesh and get frac_o ! ---------------------------------------- - if (.not. presc_cover) then - allocate(frac_o(ns_o),stat=ier) - if (ier/=0) call shr_sys_abort() - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - end if - - ! ---------------------------------------- - ! Determine pctlnd_o(:) (output argument) - ! ---------------------------------------- - if ( use_input_pft .and. presc_cover ) then - pctlnd_o(:) = 100._r8 - else - pctlnd_o(:) = frac_o(:) * 100._r8 - end if + allocate(frac_o(ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) ! ---------------------------------------- ! Determine pct_nat_pft_o(:,:) @@ -448,73 +338,65 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft if (ier/=0) call shr_sys_abort('error in allocating pctnatveg_o') ! First determine pctnatveg_o(:) - if ( use_input_pft .and. presc_cover ) then - do no = 1,ns_o - pctnatveg_o(no) = pft_override%natveg - end do - else - ! Read in pctnatveg_i - allocate(pctnatveg_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort('error allocating pctnatveg_i') + ! Read in pctnatveg_i + allocate(pctnatveg_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort('error allocating pctnatveg_i') - call mkpio_get_rawdata(pioid, 'PCT_NATVEG', mesh_i, pctnatveg_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + call mkpio_get_rawdata(pioid, 'PCT_NATVEG', mesh_i, pctnatveg_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Regrid to determine pctnatveg_o - call regrid_rawdata(mesh_i, mesh_o, routehandle, pctnatveg_i, pctnatveg_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if + ! Regrid to determine pctnatveg_o + call regrid_rawdata(mesh_i, mesh_o, routehandle, pctnatveg_i, pctnatveg_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return allocate(pct_nat_pft_i(0:num_natpft,ns_i)) if (ier/=0) call shr_sys_abort() allocate(pct_nat_pft_o(0:num_natpft,ns_o)) if (ier/=0) call shr_sys_abort() - if ( .not. use_input_pft )then - ! Read in pct_nat_pft_i - call mkpio_get_rawdata(pioid, 'PCT_NAT_PFT', mesh_i, pct_nat_pft_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do ni = 1,ns_i - do m = 0,num_natpft - pct_nat_pft_i(m,ni) = pct_nat_pft_i(m,ni) * (pctnatveg_i(ni) * 0.01_r8 * mask_i(ni)) - end do + ! Read in pct_nat_pft_i + call mkpio_get_rawdata(pioid, 'PCT_NAT_PFT', mesh_i, pct_nat_pft_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + do m = 0,num_natpft + pct_nat_pft_i(m,ni) = pct_nat_pft_i(m,ni) * (pctnatveg_i(ni) * 0.01_r8 * mask_i(ni)) end do + end do - ! Readgrid to determine pct_nat_pft_o - call regrid_rawdata(mesh_i, mesh_o, routehandle, pct_nat_pft_i, pct_nat_pft_o, 0, num_natpft, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Rescale pct_nat_pft_o - do no = 1,ns_o - if (pctnatveg_o(no) > 0._r8) then - do m = 0,num_natpft - pct_nat_pft_o(m,no) = pct_nat_pft_o(m,no) / (pctnatveg_o(no) * 0.01_r8) - end do - else - pct_nat_pft_o(0:num_natpft,no) = 0._r8 - end if - if (pctlnd_o(no) < 1.0e-6 .or. pctnatveg_o(no) < 1.0e-6) then - pct_nat_pft_o(0,no) = 100._r8 - pct_nat_pft_o(1:num_natpft,no) = 0._r8 - end if - - ! Correct sums so that if they differ slightly from 100, they are - ! corrected to equal 100 more exactly. - ! Error check: percents should sum to 100 for land grid cells, within roundoff - wst_sum = 0. - do m = 0, num_natpft - wst_sum = wst_sum + pct_nat_pft_o(m,no) - enddo - if (abs(wst_sum - 100._r8) > relerr) then - write (6,*) subname//'error: nat pft = ', (pct_nat_pft_o(m,no), m = 0, num_natpft), & - ' do not sum to 100. at no = ',no,' but to ', wst_sum - call shr_sys_abort() - end if - do m = 1, num_natpft - pct_nat_pft_o(m,no) = pct_nat_pft_o(m,no) * 100._r8 / wst_sum + ! Readgrid to determine pct_nat_pft_o + call regrid_rawdata(mesh_i, mesh_o, routehandle, pct_nat_pft_i, pct_nat_pft_o, 0, num_natpft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Rescale pct_nat_pft_o + do no = 1,ns_o + if (pctnatveg_o(no) > 0._r8) then + do m = 0,num_natpft + pct_nat_pft_o(m,no) = pct_nat_pft_o(m,no) / (pctnatveg_o(no) * 0.01_r8) end do + else + pct_nat_pft_o(0:num_natpft,no) = 0._r8 + end if + if (pctlnd_o(no) < 1.0e-6 .or. pctnatveg_o(no) < 1.0e-6) then + pct_nat_pft_o(0,no) = 100._r8 + pct_nat_pft_o(1:num_natpft,no) = 0._r8 + end if + + ! Correct sums so that if they differ slightly from 100, they are + ! corrected to equal 100 more exactly. + ! Error check: percents should sum to 100 for land grid cells, within roundoff + wst_sum = 0. + do m = 0, num_natpft + wst_sum = wst_sum + pct_nat_pft_o(m,no) + enddo + if (abs(wst_sum - 100._r8) > relerr) then + write (6,*) subname//'error: nat pft = ', (pct_nat_pft_o(m,no), m = 0, num_natpft), & + ' do not sum to 100. at no = ',no,' but to ', wst_sum + call shr_sys_abort() + end if + do m = 1, num_natpft + pct_nat_pft_o(m,no) = pct_nat_pft_o(m,no) * 100._r8 / wst_sum end do - end if + end do ! ---------------------------------------- ! Determine pct_cft_o(:,:) @@ -523,139 +405,87 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! First Determine pctcrop_o(:) allocate(pctcrop_o(ns_o), stat=ier) if (ier/=0) call shr_sys_abort('error allocating pctcrop_o_o') - if ( use_input_pft .and. presc_cover ) then - do no = 1,ns_o - pctcrop_o(no) = pft_override%crop - end do - else - allocate(pctcrop_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'PCT_CROP', mesh_i, pctcrop_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, pctcrop_i, pctcrop_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if + allocate(pctcrop_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid, 'PCT_CROP', mesh_i, pctcrop_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(mesh_i, mesh_o, routehandle, pctcrop_i, pctcrop_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return allocate(pct_cft_i(1:num_cft,ns_i), stat=ier) if (ier/=0) call shr_sys_abort() allocate(pct_cft_o(1:num_cft,ns_o), stat=ier) if (ier/=0) call shr_sys_abort() - if ( .not. use_input_pft )then - ! Get dimensions for PCT_CFT - allocate(dimlens(3)) - call mkpio_get_dimlengths(pioid, 'PCT_CFT', ndims, dimlens(:)) - if (root_task) then - do n = 1,ndims - write(ndiag,'(a,i8,i8)')' dimid, length= ',n,dimlens(n) - end do - write(ndiag,'(a,i8)')' num_cft = ',num_cft - end if - - ! Read in pct_cft_i - if (dimlens(ndims) == num_cft )then - call mkpio_get_rawdata(pioid, 'PCT_CFT', mesh_i, pct_cft_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else if (dimlens(ndims) > num_cft )then - ! Read in the whole array: then sum the rainfed and irrigated seperately - allocate(temp_i(dimlens(3),ns_i)) - call mkpio_get_rawdata(pioid, 'PCT_CFT', mesh_i, temp_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1, num_cft - pct_cft_i(n,:) = 0.0_r8 - do m = n, dimlens(3), 2 - pct_cft_i(n,:) = pct_cft_i(n,:) + temp_i(m,:) - end do - end do - deallocate(temp_i) - else - call shr_sys_abort(subname//' error: dimensions for PCT_CROP are NOT what is expected') - end if - do ni = 1,ns_i - do m = 1,num_cft - pct_cft_i(m,ni) = pct_cft_i(m,ni) * (pctcrop_i(ni) * 0.01_r8 * mask_i(ni)) - end do + ! Get dimensions for PCT_CFT + allocate(dimlens(3)) + call mkpio_get_dimlengths(pioid, 'PCT_CFT', ndims, dimlens(:)) + if (root_task) then + do n = 1,ndims + write(ndiag,'(a,i8,i8)')' dimid, length= ',n,dimlens(n) end do + write(ndiag,'(a,i8)')' num_cft = ',num_cft + end if - ! Readgrid pct_cft_i to determine pct_cft_o - call regrid_rawdata(mesh_i, mesh_o, routehandle, pct_cft_i, pct_cft_o, 1, num_cft, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Rescale pct_nat_pft_o - do no = 1,ns_o - if (pctcrop_o(no) > 0._r8) then - do m = 1,num_cft - pct_cft_o(m,no) = pct_cft_o(m,no) / (pctcrop_o(no) * 0.01_r8) - end do - else - pct_cft_o(1:num_cft,no) = 0._r8 - end if - if (pctlnd_o(no) < 1.0e-6 .or. pctcrop_o(no) < 1.0e-6) then - pct_cft_o(1,no) = 100._r8 - pct_cft_o(2:num_cft,no) = 0._r8 - end if - - ! Correct sums so that if they differ slightly from 100, they are - ! corrected to equal 100 more exactly. - ! Error check: percents should sum to 100 for land grid cells, within roundoff - wst_sum = 0. - do m = 1, num_cft - wst_sum = wst_sum + pct_cft_o(m,no) - enddo - if (abs(wst_sum-100._r8) > relerr) then - write (6,*) subname//'error: crop cft = ',(pct_cft_o(no,m), m = 1, num_cft), & - ' do not sum to 100. at no = ',no,' but to ', wst_sum - call shr_sys_abort() - end if - do m = 1, num_cft - pct_cft_o(m,no) = pct_cft_o(m,no) * 100._r8 / wst_sum + ! Read in pct_cft_i + if (dimlens(ndims) == num_cft )then + call mkpio_get_rawdata(pioid, 'PCT_CFT', mesh_i, pct_cft_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else if (dimlens(ndims) > num_cft )then + ! Read in the whole array: then sum the rainfed and irrigated seperately + allocate(temp_i(dimlens(3),ns_i)) + call mkpio_get_rawdata(pioid, 'PCT_CFT', mesh_i, temp_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1, num_cft + pct_cft_i(n,:) = 0.0_r8 + do m = n, dimlens(3), 2 + pct_cft_i(n,:) = pct_cft_i(n,:) + temp_i(m,:) end do - enddo - + end do + deallocate(temp_i) + else + call shr_sys_abort(subname//' error: dimensions for PCT_CROP are NOT what is expected') end if + do ni = 1,ns_i + do m = 1,num_cft + pct_cft_i(m,ni) = pct_cft_i(m,ni) * (pctcrop_i(ni) * 0.01_r8 * mask_i(ni)) + end do + end do - ! ---------------------------------------- - ! If specific PFT/CFT's are prescribed set them directly - ! But first do error checking to make sure specific veg - ! types are given where nat-veg and crop is assigned - ! ---------------------------------------- + ! Readgrid pct_cft_i to determine pct_cft_o + call regrid_rawdata(mesh_i, mesh_o, routehandle, pct_cft_i, pct_cft_o, 1, num_cft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (use_input_pft) then - do no = 1,ns_o - if (pctlnd_o(no) > 1.0e-6 .and. pctnatveg_o(no) > 1.0e-6) then - if ( pft_override%natveg <= 0.0_r8 )then - write(6,*) subname//': ERROR: no natural vegetation PFTs are being prescribed '//& - ' but there are natural vegetation areas: provide at least one natural veg PFT' - call shr_sys_abort() - end if - end if - if (pctlnd_o(no) > 1.0e-6 .and. pctcrop_o(no) > 1.0e-6) then - if ( pft_override%crop <= 0.0_r8 )then - write(6,*) subname//': ERROR: no crop CFTs are being prescribed '& - //' but there are crop areas: provide at least one CFT' - call shr_sys_abort() - end if - end if - end do + ! Rescale pct_nat_pft_o + do no = 1,ns_o + if (pctcrop_o(no) > 0._r8) then + do m = 1,num_cft + pct_cft_o(m,no) = pct_cft_o(m,no) / (pctcrop_o(no) * 0.01_r8) + end do + else + pct_cft_o(1:num_cft,no) = 0._r8 + end if + if (pctlnd_o(no) < 1.0e-6 .or. pctcrop_o(no) < 1.0e-6) then + pct_cft_o(1,no) = 100._r8 + pct_cft_o(2:num_cft,no) = 0._r8 + end if - do no = 1,ns_o - if (pctlnd_o(no) > 1.0e-6 .and. pctnatveg_o(no) > 1.0e-6) then - pct_nat_pft_o(noveg:num_natpft,no) = pft_override%natpft(noveg:num_natpft) - else - pct_nat_pft_o(noveg,no) = 100._r8 - pct_nat_pft_o(noveg+1:,no) = 0._r8 - end if - if (pctlnd_o(no) > 1.0e-6 .and. pctcrop_o(no) > 1.0e-6) then - pct_cft_o(1:num_cft,no) = pft_override%cft(1:num_cft) - else - pct_cft_o(1,no) = 100._r8 - pct_cft_o(2:,no) = 0._r8 - end if - pctpft_o(natpft_lb:natpft_ub,no) = pct_nat_pft_o(0:num_natpft,no) - pctpft_o(cft_lb:cft_ub,no) = pct_cft_o(1:num_cft,no) + ! Correct sums so that if they differ slightly from 100, they are + ! corrected to equal 100 more exactly. + ! Error check: percents should sum to 100 for land grid cells, within roundoff + wst_sum = 0. + do m = 1, num_cft + wst_sum = wst_sum + pct_cft_o(m,no) + enddo + if (abs(wst_sum-100._r8) > relerr) then + write (6,*) subname//'error: crop cft = ',(pct_cft_o(no,m), m = 1, num_cft), & + ' do not sum to 100. at no = ',no,' but to ', wst_sum + call shr_sys_abort() + end if + do m = 1, num_cft + pct_cft_o(m,no) = pct_cft_o(m,no) * 100._r8 / wst_sum end do - end if - + enddo ! ---------------------------------------- ! Convert % pft as % of grid cell to % pft on the landunit and % of landunit on the grid cell ! *** NOTE*** pctnatpft_o and pctcft_o are output arguments @@ -679,17 +509,8 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! ----------------------------------------------------------------- ! Error check ! Compare global areas on input and output grids - ! Only when you aren't prescribing the vegetation coverage everywhere - ! If use_input_pft is set this will compare the global coverage of - ! the prescribed vegetation to the coverage of PFT/CFT's on the input datasets. ! ----------------------------------------------------------------- - ! if (presc_cover) then - ! ns_i = 1 - ! numpft_i = numpft+1 - ! end if - - ! if ( .not. presc_cover ) then ! ! Derived types ! allocate(pctnatpft_i(ns_i), stat=ier) ! if (ier/=0) call shr_sys_abort() @@ -752,11 +573,8 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! write (ndiag,1002) veg(m), gpft_i(m)*1.e-06/100.,gpft_o(m)*1.e-06/100. ! end do ! 1002 format (1x,a35,f16.3,f17.3) - ! deallocate(gpft_i, gpft_o, frac_dst) - ! end if - ! Clean up memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() @@ -770,239 +588,4 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft end subroutine mkpft - !----------------------------------------------------------------------- - subroutine mkpft_parse_oride( string ) - ! - ! Parse the string with pft fraction and index information on it, to override - ! the file with this information rather than reading from a file. - ! - use shr_string_mod, only: shr_string_betweenTags, shr_string_countChar - - ! input/output variables - character(len=*), intent(in) :: string ! String to parse with PFT fraction and index data - - ! local variables: - integer :: rc ! error return code - integer :: num_elms ! number of elements - character(len=256) :: substring ! string between tags - character(len=*), parameter :: frc_start = "" - character(len=*), parameter :: frc_end = "" - character(len=*), parameter :: idx_start = "" - character(len=*), parameter :: idx_end = "" - character(len=*), parameter :: subname = 'mkpft_parse_oride' - !----------------------------------------------------------------------- - - ! NOTE(bja, 2015-02) pft_frc and pft_index can be reset multiple - ! times by calls to this function. If the number of elements being - ! set is different each time, then we are working with out of date - ! information, and the sums may not sum to 100%. - pft_frc = 0.0_r8 - pft_idx = -1 - - call shr_string_betweenTags( string, frc_start, frc_end, substring, rc ) - if ( rc /= 0 )then - write(6,*) subname//'Trouble finding pft_frac start end tags' - call shr_sys_abort() - return - end if - num_elms = shr_string_countChar( substring, ",", rc ) - read(substring,*) pft_frc(0:num_elms) - call shr_string_betweenTags( string, idx_start, idx_end, substring, rc ) - if ( rc /= 0 )then - write(6,*) subname//'Trouble finding pft_index start end tags' - call shr_sys_abort() - return - end if - if ( num_elms /= shr_string_countChar( substring, ",", rc ) )then - write(6,*) subname//'number of elements different between frc and idx fields' - call shr_sys_abort() - return - end if - read(substring,*) pft_idx(0:num_elms) - - end subroutine mkpft_parse_oride - - !----------------------------------------------------------------------- - subroutine mkpft_check_oride( error_happened ) - ! - ! Check that the pft override values are valid - ! - ! input/output variables - logical, intent(out) :: error_happened ! Result, true if there was a problem - ! - ! local variables: - integer :: i, j ! indices - real(r8) :: sumpft ! Sum of pft_frc - real(r8), parameter :: hndrd = 100.0_r8 ! A hundred percent - character(len=*), parameter :: subname = 'mkpftMod::mkpft_check_oride() ' - !----------------------------------------------------------------------- - - error_happened = .false. - sumpft = sum(pft_frc) - if ( sumpft == 0.0 )then - ! PFT fraction is NOT used - use_input_pft = .false. - else if ( abs(sumpft - hndrd) > 1.e-6 )then - write(6, '(a, a, f15.12)') subname, 'Sum of PFT fraction is NOT equal to 100% =', sumpft - write(6,*) 'Set PFT fraction to : ', pft_frc(0:nzero) - write(6,*) 'With PFT index : ', pft_idx(0:nzero) - error_happened = .true. - call shr_sys_abort() - else - use_input_pft = .true. - nzero = numpft - do i = 0, numpft - if ( pft_frc(i) == 0.0_r8 )then - nzero = i-1 - exit - end if - end do - ! PFT fraction IS used, and sum is OK, now check details - do i = 0, nzero - if ( pft_frc(i) < 0.0_r8 .or. pft_frc(i) > hndrd )then - write(6,*) subname//'PFT fraction is out of range: pft_frc=', pft_frc(i) - error_happened = .true. - call shr_sys_abort() - else if ( pft_frc(i) > 0.0_r8 .and. pft_idx(i) == -1 )then - write(6,*) subname//'PFT fraction > zero, but index NOT set: pft_idx=', pft_idx(i) - error_happened = .true. - call shr_sys_abort() - end if - ! PFT index out of range - if ( pft_idx(i) < 0 .or. pft_idx(i) > numpft )then - write(6,*) subname//'PFT index is out of range: ', pft_idx(i) - error_happened = .true. - call shr_sys_abort() - end if - ! Make sure index values NOT used twice - do j = 0, i-1 - if ( pft_idx(i) == pft_idx(j) )then - write(6,*) subname//'Same PFT index is used twice: ', pft_idx(i) - error_happened = .true. - call shr_sys_abort() - end if - end do - end do - ! Make sure the rest of the fraction is zero and index are not set as well - do i = nzero+1, numpft - if ( pft_frc(i) /= 0.0_r8 .or. pft_idx(i) /= -1 )then - write(6,*) subname//'After PFT fraction is zeroed out, fraction is non zero, or index set' - error_happened = .true. - call shr_sys_abort() - end if - end do - end if - - end subroutine mkpft_check_oride - - !----------------------------------------------------------------------- - function constructor( ) result(this) - ! - ! Construct a new PFT override object - ! - ! input/output variables - type(pft_oride) :: this - character(len=*), parameter :: subname = 'mkpftMod::constructor() ' - - this%crop = -1.0_r8 - this%natveg = -1.0_r8 - if ( num_natpft < 0 )then - write(6,*) subname//'num_natpft is NOT set = ', num_natpft - call shr_sys_abort() - return - end if - if ( num_cft < 0 )then - write(6,*) subname//'num_cft is NOT set = ', num_cft - call shr_sys_abort() - return - end if - allocate( this%natpft(noveg:num_natpft) ) - allocate( this%cft(1:num_cft) ) - this%natpft(:) = -1.0_r8 - this%cft(:) = -1.0_r8 - call this%InitZeroOut() - - end function constructor - - !----------------------------------------------------------------------- - subroutine InitZeroOut( this ) - ! - ! Initialize a pft_oride object with vegetation that's zeroed out - ! - ! input/output variables - class(pft_oride), intent(inout) :: this - - this%crop = 0.0_r8 - this%natveg = 0.0_r8 - - this%natpft = 0.0_r8 - this%natpft(noveg) = 100.0_r8 - this%cft = 0.0_r8 - this%cft(1) = 100.0_r8 - - end subroutine InitZeroOut - - !----------------------------------------------------------------------- - subroutine InitAllPFTIndex( this ) - ! - ! Initialize a pft_oride object with vegetation that's zeroed out - ! - ! input/otuput variables - class(pft_oride), intent(inout) :: this - - ! local variables - integer :: m, i ! Indices - real(r8) :: croptot ! Total of crop - real(r8) :: natvegtot ! Total of natural vegetation - character(len=*), parameter :: subname = 'mkpftMod::coInitAllPFTIndex() ' - - croptot = 0.0_r8 - natvegtot = 0.0_r8 - this%natpft = 0.0_r8 - this%cft = 0.0_r8 - do m = noveg, nzero - i = pft_idx(m) - if ( (i < noveg) .or. (i > numpft) )then - write(6,*) subname//'PFT index is out of valid range' - call shr_sys_abort() - return - else if ( i <= num_natpft )then - this%natpft(i) = pft_frc(m) - natvegtot = natvegtot + pft_frc(m) - else - this%cft(i-num_natpft) = pft_frc(m) - croptot = croptot + pft_frc(m) - end if - end do - this%crop = croptot - this%natveg = natvegtot - ! Renormalize - if ( natvegtot > 0.0_r8 )then - this%natpft = 100.0_r8 * this%natpft / natvegtot - else - this%natpft(noveg) = 100.0_r8 - end if - if (croptot > 0.0_r8 )then - this%cft = 100.0_r8 * this%cft / croptot - else - this%cft(1) = 100.0_r8 - end if - - end subroutine InitAllPFTIndex - - !----------------------------------------------------------------------- - subroutine Clean( this ) - ! - ! Clean up a PFT Oride object - ! - ! !ARGUMENTS: - class(pft_oride), intent(inout) :: this - - this%crop = -1.0_r8 - this%natveg = -1.0_r8 - deallocate( this%natpft ) - deallocate( this%cft ) - - end subroutine Clean - end module mkpftMod diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index 04e18fe661..25ba6956b0 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -6,7 +6,7 @@ module mksoilcolMod use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem - use mkvarctl , only : root_task, ndiag, mpicom, unsetcol, soil_color_override + use mkvarctl , only : root_task, ndiag, mpicom, unsetcol use mkdiagnosticsMod , only : output_diagnostics_index use mkutilsMod , only : chkerr use mkfileMod , only : mkfile_output @@ -65,18 +65,8 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, pctlnd_pft_o, pioid_o, rc rc = ESMF_SUCCESS - ! Error check soil_color if it is set - if ( soil_color_override /= unsetcol )then - if ( soil_color_override < 0 .or. soil_color_override > 20 )then - write(6,*)'soil_color is out of range = ', soil_color_override - call shr_sys_abort() - end if - write(6,*) 'Replace soil color for all points with: ', soil_color_override - do no = 1,size(soil_color_o) - soil_color_o(no) = soil_color_override - end do - RETURN - end if + ! Note soil_color_override has been removed - instead should now use tools + ! subset_data and modify_fsurdat if (root_task) then write(ndiag,*) diff --git a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 index bf4468beb0..d1a7fe7f13 100644 --- a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 @@ -11,7 +11,7 @@ module mksoilfmaxMod use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkdiagnosticsMod , only : output_diagnostics_continuous - use mkvarctl , only : ndiag, root_task, soil_fmax_override, unsetsoil, spval + use mkvarctl , only : ndiag, root_task, spval use mkutilsMod , only : chkerr use mkfileMod , only : mkfile_output @@ -66,16 +66,8 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) end if call ESMF_VMLogMemInfo("At start of "//trim(subname)) - ! Error check soil_fmax if it is set - if ( soil_fmax_override /= unsetsoil )then - if ( soil_fmax_override < 0.0 .or. soil_fmax_override > 1.0 )then - write(6,*)'soil_fmax is out of range = ', soil_fmax_override - call shr_sys_abort() - end if - if (root_task) then - write(ndiag,'(a,d13.5)') 'Replacing soil fmax for all points with: ', soil_fmax_override - end if - end if + ! Note soil_fmax_override has been removed - instead should now use tools + ! subset_data and modify_fsurdat ! Open input data file rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 8e52857938..6ca1aecfec 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -14,7 +14,7 @@ module mksoiltexMod use mkdiagnosticsMod , only : output_diagnostics_index use mkfileMod , only : mkfile_output use mkvarctl , only : root_task, ndiag, spval - use mkvarctl , only : unsetsoil, soil_clay_override, soil_sand_override + use mkvarctl , only : unsetsoil use mkvarpar , only : nlevsoi implicit none @@ -92,27 +92,6 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if - if ( soil_clay_override /= unsetsoil )then - write(6,*) 'Replace soil clay % for all points with: ', soil_clay_override - if ( soil_sand_override == unsetsoil )then - write (6,*) subname//':error: soil_clay set, but NOT soil_sand' - call shr_sys_abort() - end if - end if - if ( soil_sand_override /= unsetsoil )then - write(6,*) 'Replace soil sand % for all points with: ', soil_sand_override - if ( soil_clay_override == unsetsoil )then - write (6,*) subname//':error: soil_sand set, but NOT soil_clay' - call shr_sys_abort() - end if - sumtex = soil_sand_override + soil_clay_override - if ( sumtex < 0.0_r4 .or. sumtex > 100.0_r4 )then - write (6,*) subname//':error: soil_sand and soil_clay out of bounds: sand, clay = ', & - soil_sand_override, soil_clay_override - call shr_sys_abort() - end if - end if - ! Determine ns_o and allocate output data call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -120,16 +99,6 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc allocate(sand_o(ns_o,nlevsoi)) ; sand_o(:,:) = spval allocate(clay_o(ns_o,nlevsoi)) ; clay_o(:,:) = spval - if (soil_sand_override /= unsetsoil .and. soil_clay_override /= unsetsoil) then - if (root_task) then - write(ndiag,'(a,i8)') ' Overriding soil sand for all points with: ', soil_sand_override - write(ndiag,'(a,i8)') ' Overriding soil clay for all points with: ', soil_clay_override - end if - sand_o(:,:) = soil_sand_override - clay_o(:,:) = soil_clay_override - RETURN - end if - ! Open input data file call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index b13d007fab..5deac1a942 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -67,24 +67,20 @@ program mksurfdata ! outnc_3dglc ------- Output 3D glacier fields (normally only needed for comparasion) ! nglcec ------------ If you want to change the number of Glacier elevation classes ! gitdescribe ------- Description of this version from git + ! numpft ------------ Iif different than default of 16 + ! urban_skip_abort_on_invalid_data_check--- work around urban bug ! ====================================== - ! Optional settings to change values for entire area + ! Note: the folloiwng Optional settings have been REMOVED - + ! instead should now use tools subset_data and modify_fsurdat ! ====================================== - ! all_urban --------- If entire area is urban ! all_veg ----------- If entire area is to be vegetated (pft_idx and pft_frc then required) + ! all_urban --------- If entire area is urban ! no_inlandwet ------ If wetland should be set to 0% over land - ! soil_color_override -------- If you want to change the soil_color to this value everywhere ! soil_clay --------- If you want to change the soil_clay % to this value everywhere ! soil_fmax --------- If you want to change the soil_fmax to this value everywhere ! soil_sand --------- If you want to change the soil_sand % to this value everywhere ! pft_idx ----------- If you want to change to 100% veg covered with given PFT indices ! pft_frc ----------- Fractions that correspond to the pft_idx above - ! ================== - ! numpft (if different than default of 16) - ! ====================================== - ! Optional settings to work around urban bug? - ! ====================================== - ! urban_skip_abort_on_invalid_data_check ! ====================================================================== use ESMF @@ -93,11 +89,11 @@ program mksurfdata use shr_sys_mod , only : shr_sys_abort use mkVICparamsMod , only : mkVICparams use mktopostatsMod , only : mktopostats - use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride + use mkpftMod , only : mkpft, mkpftInit use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft, num_natpft use mkdomainMod , only : mkdomain - use mkharvestMod , only : mkharvest, mkharvest_parse_oride + use mkharvestMod , only : mkharvest use mkgdpMod , only : mkgdp use mkagfirepkmonthMod , only : mkagfirepkmon use mklaiMod , only : mklai @@ -171,11 +167,6 @@ program mksurfdata real(r8), allocatable :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell real(r8), allocatable :: elev(:) ! glc elevation (m) - ! logicals - logical :: zero_out_lake ! if should zero glacier out - logical :: zero_out_wetland ! if should zero glacier out - logical :: zero_out - ! pio/esmf variables type(file_desc_t) :: pioid type(var_desc_t) :: pio_varid @@ -280,10 +271,10 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() ! Initialize urban dimensions (needed to initialize the dimensions in fsurdat) - call mkurbanInit (mksrf_furban) + call mkurbanInit(mksrf_furban) ! Initialize pft/cft dimensions (needed to initialize the dimensions in fsurdat) - call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) + call mkpftInit( ) ! If fsurdat is blank, then we do not write a surface dataset - but we may still ! write a dynamic landuse file. This is useful if we are creating many datasets at @@ -402,8 +393,7 @@ program mksurfdata ! ----------------------------------- ! Note that this call must come after call to mkpftInit - since num_cft is set there ! Output data is written in mkharvest - call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, & - pioid_o=pioid, all_veg=all_veg, constant=.true., rc=rc ) + call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, pioid_o=pioid, constant=.true., rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') ! ----------------------------------- @@ -413,27 +403,15 @@ program mksurfdata ! Need to keep pctlak and pctwet external for use below allocate ( pctlak(lsize_o)) ; pctlak(:) = spval allocate ( pctwet(lsize_o)) ; pctwet(:) = spval - zero_out_lake = (all_urban .or. all_veg) - zero_out_wetland = (all_urban .or. all_veg .or. no_inlandwet) - call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & - zero_out_lake, zero_out_wetland, pctlak, pctwet, pioid, fsurdat, rc=rc) + call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, pctlak, pctwet, pioid, fsurdat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') ! ----------------------------------- ! Make glacier fraction [pctgla] from [fglacier] dataset ! ----------------------------------- allocate (pctgla(lsize_o)) ; pctgla(:) = spval - zero_out = (all_urban .or. all_veg) - if (.not. zero_out) then - call mkglacier (mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, glac_o=pctgla, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacier') - else - if (root_task) then - write (ndiag,'(a)') 'Attempting to make %glacier .....' - write(ndiag, '(a)') ' zeroing out all pct glacier data' - pctgla(:) = 0. - end if - end if + call mkglacier (mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, glac_o=pctgla, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacier') ! ----------------------------------- ! Make glacier region ID [glacier_region] from [fglacierregion] dataset @@ -510,7 +488,7 @@ program mksurfdata allocate (pcturb(lsize_o)) ; pcturb(:) = spval allocate (urban_classes(lsize_o,numurbl)) ; urban_classes(:,:) = spval allocate (urban_region(lsize_o)) ; urban_region(:) = -999 - call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, all_veg, pcturb, urban_classes, urban_region, rc=rc) + call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, pcturb, urban_classes, urban_region, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing out urban region id" @@ -523,20 +501,18 @@ program mksurfdata ! Adjust pcturb ! Make elevation [elev] from [ftopo, ffrac] dataset ! Used only to screen pcturb, screen pcturb by elevation threshold from elev dataset - if ( .not. all_urban .and. .not. all_veg )then - allocate(elev(lsize_o)) - elev(:) = spval - ! NOTE(wjs, 2016-01-15) This uses the 'TOPO_ICE' variable for historical reasons - ! (this same dataset used to be used for glacier-related purposes as well). - ! TODO(wjs, 2016-01-15) A better solution for this urban screening would probably - ! be to modify the raw urban data; in that case, I believe we could remove furbtopo. - call mkurban_topo ( mksrf_furbtopo_mesh, mksrf_furbtopo, mesh_model, varname='TOPO_ICE', elev_o=elev, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban_topo') - where (elev > elev_thresh) - pcturb = 0._r8 - end where - deallocate(elev) - end if + allocate(elev(lsize_o)) + elev(:) = spval + ! NOTE(wjs, 2016-01-15) This uses the 'TOPO_ICE' variable for historical reasons + ! (this same dataset used to be used for glacier-related purposes as well). + ! TODO(wjs, 2016-01-15) A better solution for this urban screening would probably + ! be to modify the raw urban data; in that case, I believe we could remove furbtopo. + call mkurban_topo ( mksrf_furbtopo_mesh, mksrf_furbtopo, mesh_model, varname='TOPO_ICE', elev_o=elev, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban_topo') + where (elev > elev_thresh) + pcturb = 0._r8 + end where + deallocate(elev) ! ----------------------------------- ! Compute topography statistics [topo_stddev, slope] from [ftopostats] @@ -848,31 +824,21 @@ program mksurfdata end if call mpi_bcast (string, len(string), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (year, 1, MPI_INTEGER, 0, mpicom, ier) - - - ! If pft fraction override is set, than intrepret string as PFT and harvesting override values - ! Otherwise intrepret string as a filename with PFT and harvesting values in it - if ( all_veg )then - fname = ' ' - fhrvname = ' ' - call mkpft_parse_oride(string) - call mkharvest_parse_oride(string) - write(6, '(a, i4, a)') 'PFT and harvesting values for year ', year, ' :' - write(6, '(a, a)') ' ', trim(string) - else - fname = string + + ! Intrepret string as a filename with PFT and harvesting values in it + + fname = string + if (root_task) then + read(nfdyn, '(A195,1x,I4)', iostat=ier) fhrvname, year2 + write(ndiag,'(a,i8,a)')' input pft dynamic dataset for year ', year,' is : '//trim(fname) + end if + call mpi_bcast (fhrvname, len(fhrvname), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (year2, 1, MPI_INTEGER, 0, mpicom, ier) + if ( year2 /= year ) then if (root_task) then - read(nfdyn, '(A195,1x,I4)', iostat=ier) fhrvname, year2 - write(ndiag,'(a,i8,a)')' input pft dynamic dataset for year ', year,' is : '//trim(fname) - end if - call mpi_bcast (fhrvname, len(fhrvname), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (year2, 1, MPI_INTEGER, 0, mpicom, ier) - if ( year2 /= year ) then - if (root_task) then - write(ndiag,*) subname, ' error: year for harvest not equal to year for PFT files' - end if - call shr_sys_abort() + write(ndiag,*) subname, ' error: year for harvest not equal to year for PFT files' end if + call shr_sys_abort() end if ntim = ntim + 1 if (root_task) then @@ -889,7 +855,7 @@ program mksurfdata ! Create pctpft data at model resolution from file fname ! Note that pctlnd_o below is different than the above call and returns pctlnd_pft_dyn - + call mkpft( mksrf_fvegtyp_mesh, fname, mesh_model, & pctlnd_o=pctlnd_pft_dyn, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpft') @@ -916,7 +882,7 @@ program mksurfdata ! Create harvesting data at model resolution ! Output data is written in mkharvest call mkharvest( mksrf_fhrvtyp_mesh, fhrvname, mesh_model, & - pioid_o=pioid, all_veg=.false., constant=.false., ntime=ntim, rc=rc ) + pioid_o=pioid, constant=.false., ntime=ntim, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest') call pio_syncfile(pioid) @@ -1265,7 +1231,7 @@ subroutine normalize_and_check_landuse(ns_o) sum8a = sum8a + pctcft(n)%get_pct_l2g() if ( sum8a==0._r8 .and. sum8 < (100._r8-4._r8*epsilon(sum8)) )then write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 + 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 write (6,*) 'Total error, error/epsilon = ',100._r8-sum8, ((100._r8-sum8)/epsilon(sum8)) write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,epsilon= ', & n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index da62d28133..959a75dd7b 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -12,7 +12,7 @@ module mkurbanparMod use mkpioMod , only : mkpio_iodesc_output, mkpio_get_rawdata use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr - use mkvarctl , only : root_task, ndiag, ispval, outnc_double, all_urban + use mkvarctl , only : root_task, ndiag, ispval, outnc_double use mkutilsMod , only : normalize_classes_by_gcell use mkdiagnosticsMod , only : output_diagnostics_index use mkindexmapMod , only : dim_slice_type, lookup_2d_netcdf @@ -80,8 +80,7 @@ subroutine mkurbanInit(datafname) end subroutine mkurbanInit !=============================================================== - subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & - zero_out, pcturb_o, urban_classes_o, region_o, rc) + subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, urban_classes_o, region_o, rc) ! ! make total percent urban, breakdown into urban classes, and region ID on the output grid ! @@ -108,7 +107,6 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh - logical , intent(in) :: zero_out ! if should zero urban out real(r8) , intent(inout) :: pcturb_o(:) ! output grid: total % urban real(r8) , intent(inout) :: urban_classes_o(:,:) ! output grid: breakdown of total urban into each class integer , intent(inout) :: region_o(:) ! output grid: region ID @@ -226,7 +224,6 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & ! Determine urban_classes_o ! Make percent urban on output grid, given percent urban on input grid - ! This assumes that we're neither using all_urban or zero_out ! Determine pcturb_o on ouput grid: call normalize_urbn_by_tot(urban_classes_gcell_o, pcturb_o, urban_classes_o) call ESMF_LogWrite("After normalize_urbn", ESMF_LOGMSG_INFO) @@ -235,18 +232,12 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, & ! Note that, for all these adjustments of total urban %, we do not change the breakdown ! into the different urban classes. In particular: when pcturb_o is set to 0 for a point, ! the breakdown into the different urban classes is maintained as it was before. - if (all_urban) then - pcturb_o(:) = 100._r8 - else if (zero_out) then - pcturb_o(:) = 0._r8 - else - ! Set points to 0% if they fall below a given threshold - do no = 1, ns_o - if (pcturb_o(no) < MIN_DENS) then - pcturb_o(no) = 0._r8 - end if - end do - end if + ! Set points to 0% if they fall below a given threshold + do no = 1, ns_o + if (pcturb_o(no) < MIN_DENS) then + pcturb_o(no) = 0._r8 + end if + end do ! Print diagnostics ! TODO: call to mkurban_pct_diagnostics has to be rewritten diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index acab179110..68061e1a9c 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -25,17 +25,8 @@ module mkvarctl integer, public :: numpft = 16 ! number of plant types integer, public :: nglcec = 10 ! number of elevation classes for glaciers - integer , public :: soil_color_override - real(r8), public :: soil_sand_override - real(r8), public :: soil_clay_override - real(r8), public :: soil_fmax_override - ! Variables to override data read in with - ! (all_urban is mostly for single-point mode, but could be used for sensitivity studies) - logical , public :: all_urban ! output ALL data as 100% covered in urban - logical , public :: all_veg ! if gridcell will be 100% vegetated land-cover - logical , public :: no_inlandwet ! set wetland to 0% over land; wetland will only be used for ocean points - real(r8) , public :: std_elev = -999.99_r8 ! Standard deviation of elevation (m) to use for ent + real(r8), public :: std_elev = -999.99_r8 ! Standard deviation of elevation (m) to use for entire region real(r8), public, parameter :: spval = 1.e36 ! special value integer, public, parameter :: ispval = -9999 ! special value diff --git a/tools/mksurfdata_esmf/src/mkvocefMod.F90 b/tools/mksurfdata_esmf/src/mkvocefMod.F90 index 671a5e7ee2..ae95bb5a14 100644 --- a/tools/mksurfdata_esmf/src/mkvocefMod.F90 +++ b/tools/mksurfdata_esmf/src/mkvocefMod.F90 @@ -12,7 +12,7 @@ module mkvocefMod use mkpioMod , only : mkpio_iodesc_rawdata, pio_iotype, pio_iosystem use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkutilsMod , only : chkerr - use mkvarctl , only : root_task, ndiag, mpicom, soil_color_override, unsetcol + use mkvarctl , only : root_task, ndiag, mpicom use mkfileMod , only : mkfile_output implicit none From 8262a1f215856c4d417ef823b0d9fc3524dac184 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 1 Mar 2022 13:18:34 -0700 Subject: [PATCH 084/614] updates go scripts and minor bug fixes --- tools/mksurfdata_esmf/gen_mksurfdata | 8 +-- .../gen_mksurfdata_namelist.py | 35 +++++++------ .../gen_mksurfdata_namelist.xml | 8 +-- tools/mksurfdata_esmf/run/mksurfdata_in | 52 ------------------- 4 files changed, 28 insertions(+), 75 deletions(-) delete mode 100644 tools/mksurfdata_esmf/run/mksurfdata_in diff --git a/tools/mksurfdata_esmf/gen_mksurfdata b/tools/mksurfdata_esmf/gen_mksurfdata index a1607c1542..125aaa9bbe 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata +++ b/tools/mksurfdata_esmf/gen_mksurfdata @@ -3,10 +3,11 @@ #PBS -N job_name #PBS -j oe #PBS -q premium -#PBS -l walltime=20:00 +#PBS -l walltime=30:00 ##PBS -l select=16:ncpus=36:mpiprocs=9 -#PBS -l select=24:ncpus=36:mpiprocs=12 +##PBS -l select=24:ncpus=36:mpiprocs=12 ##PBS -l select=32:ncpus=36:mpiprocs=12 +#PBS -l select=200:ncpus=36:mpiprocs=12 export TMPDIR=/glade/scratch/$USER/temp mkdir -p $TMPDIR @@ -18,5 +19,6 @@ mkdir -p $TMPDIR # Run the model #mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata - mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata +#mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata #mpiexec_mpt -p "%g:" -np 384 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata +mpiexec_mpt -p "%g:" -np 2400 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index a6d4d60735..b0861ba2b8 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -181,7 +181,6 @@ def main (): start_year = args.start_year end_year = args.end_year res = args.res - hires_pft = args.hres_flag ssp_rcp = args.ssp_rcp input_path = args.input_path crop_flag = args.crop_flag @@ -190,26 +189,30 @@ def main (): potveg = args.potveg_flag glc_nec = args.glc_nec merge_gis = args.merge_gis + if args.hres_flag: + hires_pft = 'on' + else: + hires_pft = 'off' # determine pft_years - needed to parse xml file - if start_year == 1850 and end_year == 1850: + if int(start_year) == 1850 and int(end_year) == 1850: pft_years = "1850" - elif start_year == 2000 and end_year == 2000: + elif int(start_year) == 2000 and int(end_year) == 2000: pft_years = "2000" - elif start_year == 2005 and end_year == 2005: + elif int(start_year) == 2005 and int(end_year) == 2005: pft_years = "2005" - elif start_year >= 850 and end_year <= 1849: + elif int(start_year) >= 850 and int(end_year) <= 1849: pft_years = "0850-1849" - elif start_year >= 1850 and end_year <= 2005: + elif int(start_year) >= 1850 and int(start_year) <= 2100 and int(end_year) <= 2005: pft_years = "1850-2015" - elif start_year >= 2016 and end_year <=2100: + elif int(start_year) >= 2016 and int(start_year) <= 2100 and int(end_year) <=2100: pft_years = "2016-2100" elif potveg: pft_years = "PtVg" else: - raise argparse.ArgumentTypeError( - "ERROR: Simulation start and end years should be between 850 and 2105 or potential vegetation flag needs to be true " - ) + print (f"start_year is {start_year} and end_year is {end_year}") + print (f"ERROR: start and end years should be between 850 and 2105 or pot_veg flag needs to be set") + sys.exit() # error check on glc_nec if (glc_nec <= 0) or (glc_nec >= 100): @@ -260,15 +263,15 @@ def main (): # ERROR: keep %y here and do the replacement later rawdata_files[child1.tag] = rawdata_files[child1.tag].replace("%y",str(start_year)) if not os.path.isfile(rawdata_files[child1.tag]): - print(f"intput rawdata file {rawdata_files[child1.tag]} does not exist") - os.exit(1) + print(f"ERROR: intput rawdata file {rawdata_files[child1.tag]} does not exist") + sys.exit() if item.tag == 'mesh_filename': new_key = f"{child1.tag}_mesh" rawdata_files[new_key] = os.path.join(input_path, item.text) if not os.path.isfile(rawdata_files[new_key]): - print(f"mesh file {rawdata_files[new_key]} does not exist") - os.exit(1) + print(f"ERROR: mesh file {rawdata_files[new_key]} does not exist") + sys.exit() tree2 = ET.parse('../../ccs_config/component_grids_nuopc.xml') root = tree2.getroot() @@ -291,8 +294,8 @@ def main (): for child1 in root: # this is domain tag for name, value in child1.attrib.items(): valid_grids.append(value) - print (f"Valid values are {valid_grids}") - os._exit(1) + print (f"valid grid values are {valid_grids}") + sys.exit() # Determine num_pft if crop_flag: diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 241a77318d..beb8296874 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -13,8 +13,8 @@ lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.cdf5.c220206.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - - lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_lai_histclm52deg005_earthstatmirca_2005.c190119.nc + + lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_lai_histclm52deg005_earthstatmirca_2005.cdf5.c220228.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc @@ -42,8 +42,8 @@ lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_soilcolor_CMIP6_simyr2005_cd5.c220126.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - - lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_soilcolor_histclm52deg005_earthstatmirca_2005.c190116.nc + + lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_soilcolor_histclm52deg005_earthstatmirca_2005.cdf5.c220228.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc diff --git a/tools/mksurfdata_esmf/run/mksurfdata_in b/tools/mksurfdata_esmf/run/mksurfdata_in deleted file mode 100644 index e44459426d..0000000000 --- a/tools/mksurfdata_esmf/run/mksurfdata_in +++ /dev/null @@ -1,52 +0,0 @@ -&mksurfdata_input - mksrf_flai = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.cdf5.c220206.nc' - mksrf_flai_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc' - mksrf_forganic = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_organic_10level_5x5min_ISRIC-WISE-NCSCD_nlev7_c120830.nc' - mksrf_forganic_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' - mksrf_fsoicol = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_soilcolor_CMIP6_simyr2005_cd5.c220126.nc' - mksrf_fsoicol_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc' - mksrf_fsoitex = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_soitex.10level.c010119.nc' - mksrf_fsoitex_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' - mksrf_fmax = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_fmax_0.125x0.125_c200220.nc' - mksrf_fmax_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.125x0.125_nomask_c200129.nc' - mksrf_flakwat = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_LakePnDepth_3x3min_simyr2004_csplk_c151015.nc' - mksrf_flakwat_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' - mksrf_fwetlnd = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_lanwat.050425.nc' - mksrf_fwetlnd_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' - mksrf_fvocef = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_vocef_0.5x0.5_simyr2000.c110531.nc' - mksrf_fvocef_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' - mksrf_furban = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_urban_0.05x0.05_simyr2000.c220127.nc' - mksrf_furban_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' - mksrf_furbtopo = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_topo.10min.cdf5.c220201.nc' - mksrf_furbtopo_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_c200129.nc' - mksrf_fglacier = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000.cdf5.c120926.nc' - mksrf_fglacier_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc' - mksrf_fglacierregion = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_GlacierRegion_10x10min_nomask_cd5_c220131.nc' - mksrf_fglacierregion_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_cdf5_c200129.nc' - mksrf_fgdp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_gdp_0.5x0.5_AVHRR_simyr2000.c130228.nc' - mksrf_fgdp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' - mksrf_fpeat = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_peatf_0.5x0.5_AVHRR_simyr2000.c130228.nc' - mksrf_fpeat_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' - mksrf_fsoildepth = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksf_soilthk_5x5min_ORNL-Soil_simyr1900-2015_c170630.nc' - mksrf_fsoildepth_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' - mksrf_fabm = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_abm_0.5x0.5_AVHRR_simyr2000.c130201.nc' - mksrf_fabm_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc' - mksrf_ftopostats = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_topostats_1km-merge-10min_HYDRO1K-merge-nomask_simyr2000.c130402.nc' - mksrf_ftopostats_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UGRID_1km-merge-10min_HYDRO1K-merge-nomask_c130402.nc' - mksrf_fvegtyp = '/glade/work/mvertens/ctsm.toolchain/tools/mksurfdata_esmf/run/mksrf_landuse_histclm50_LUH2_2000.cdf5.c170629.nc' - mksrf_fvegtyp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc' - mksrf_fhrvtyp = '/glade/work/mvertens/ctsm.toolchain/tools/mksurfdata_esmf/run/mksrf_landuse_histclm50_LUH2_2000.cdf5.c170629.nc' - mksrf_fhrvtyp_mesh = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc' - mksrf_fgrid_mesh = '/glade/p/cesm/cseg/inputdata/share/meshes/ne30np4_ESMFmesh_cdf5_c20211018.nc' - mksrf_fgrid_mesh_nx = 48602 - mksrf_fgrid_mesh_ny = 1 - fsurdat = 'surfdata_ne30np4_hist_78pfts_CMIP6_2000_c220219.nc' - fsurlog = 'surfdata_ne30np4_hist_78pfts_CMIP6_2000_c220219.log' - outnc_double = .true. - all_urban = .false. - no_inlandwet = .true. - numpft = 78 - mksrf_fdynuse = ' ' - fdyndat = ' ' - outnc_vic = .true. -/ From c540c6ee7bdc7ba503cb9d7efc24be7e247d7d45 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 2 Mar 2022 13:00:18 -0700 Subject: [PATCH 085/614] fixed bugs introduced in d8d8930c8 and verified that answers do not change relative to previous 1.9x2.5 surface dataset created --- tools/mksurfdata_esmf/gen_mksurfdata | 14 +- .../gen_mksurfdata_namelist.py | 6 +- .../gen_mksurfdata_namelist.xml | 2 +- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 83 +------- tools/mksurfdata_esmf/src/mkinputMod.F90 | 3 + tools/mksurfdata_esmf/src/mklanwatMod.F90 | 180 ++++++++++++++---- tools/mksurfdata_esmf/src/mkpftMod.F90 | 121 +++++------- tools/mksurfdata_esmf/src/mksurfdata.F90 | 10 +- tools/mksurfdata_esmf/src/mkvarctl.F90 | 2 + 9 files changed, 213 insertions(+), 208 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata b/tools/mksurfdata_esmf/gen_mksurfdata index 125aaa9bbe..115bd2c0cd 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata +++ b/tools/mksurfdata_esmf/gen_mksurfdata @@ -6,8 +6,8 @@ #PBS -l walltime=30:00 ##PBS -l select=16:ncpus=36:mpiprocs=9 ##PBS -l select=24:ncpus=36:mpiprocs=12 -##PBS -l select=32:ncpus=36:mpiprocs=12 -#PBS -l select=200:ncpus=36:mpiprocs=12 +#PBS -l select=32:ncpus=36:mpiprocs=12 +##PBS -l select=200:ncpus=36:mpiprocs=12 export TMPDIR=/glade/scratch/$USER/temp mkdir -p $TMPDIR @@ -17,8 +17,10 @@ mkdir -p $TMPDIR # note for mpiexec below # -np {total_tasks} + # Run the model -#mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata -#mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata -#mpiexec_mpt -p "%g:" -np 384 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata -mpiexec_mpt -p "%g:" -np 2400 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/mksurfdata +#mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata +#mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata + mpiexec_mpt -p "%g:" -np 384 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata +#mpiexec_mpt -p "%g:" -np 2400 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata + diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index b0861ba2b8..f1627fb49b 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -361,17 +361,13 @@ def main (): mksrf_hrvtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] nlfile.write( f" mksrf_fhrvtyp_mesh = \'{mksrf_hrvtyp_mesh}\' \n") - nlfile.write( " all_urban = .false. \n") - nlfile.write( " no_inlandwet = .true. \n") nlfile.write(f" numpft = {num_pft} \n") + nlfile.write( " no_inlandwet = .true. \n") nlfile.write( " fdyndat = \' \' \n") nlfile.write(f" fsurdat = \'{fsurdat}\' \n") nlfile.write(f" fsurlog = \'{fsurlog}\' \n") nlfile.write(f" mksrf_fdynuse = \'{landuse_fname} \' \n") nlfile.write(f" gitdescribe = \'{gitdescribe}\' \n") - nlfile.write( " all_urban = .false. \n") - nlfile.write( " all_veg = .false. \n") - nlfile.write( " no_inlandwet = .true. \n") nlfile.write( " outnc_large_files = .false. \n") nlfile.write( " outnc_double = .true. \n") diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index beb8296874..1f308b32ce 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -239,7 +239,7 @@ version of the raw dataset will probably go away. lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_2005.c190119.nc + lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_2005.cdf5.c190119.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index 02275a0288..109edd9ff7 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -16,12 +16,11 @@ module mkharvestMod use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag, mpicom + use mkdiagnosticsMod , only : output_diagnostics_continuous implicit none private -#include - ! public member functions public :: mkharvest ! Calculate the harvest values on output grid @@ -187,6 +186,8 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, constant, ntime, call regrid_rawdata(mesh_i, mesh_o, routehandle_r8, data1d_i, data1d_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag,*)'DEBUG: i am here in mkharvest' + ! write out mapped variable if (present(ntime)) then if (root_task) write(ndiag, '(a,i8)') subname//" writing out 1d "//trim(varname_o)//' at time ',ntime @@ -203,12 +204,11 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, constant, ntime, end if call pio_syncfile(pioid_o) - ! TODO: uncomment the following and validate ! Compare global areas on input and output grids for 1d variables - ! call mkharvest check_global_sums('harvest type '//trim(varname_o), ns_i, ns_o, & - ! mesh_i, mesh_o, mask_i, frac_o, data1d_i, data1d_o, rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) return - + call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + data1d_i, data1d_o, trim(varname_o), "gC/m2/yr", ndiag, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + deallocate(data1d_i) deallocate(data1d_o) @@ -270,75 +270,6 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, constant, ntime, end subroutine mkharvest - !================================================================================= - subroutine mkharvest_check_global_sums(name, ns_i, ns_o, mesh_i, mesh_o, mask_i, frac_o, & - data_i, data_o, rc) - - ! input/otuput variables - character(len=*) , intent(in) :: name - integer , intent(in) :: ns_i - integer , intent(in) :: ns_o - type(ESMF_Mesh) , intent(in) :: mesh_i - type(ESMF_Mesh) , intent(in) :: mesh_o - integer , intent(in) :: mask_i(:) - real(r8) , intent(in) :: frac_o(:) - real(r8) , intent(in) :: data_i(:) ! 1D input data - real(r8) , intent(in) :: data_o(:) ! 1D output data - integer , intent(out) :: rc - - ! local variables - integer :: ni, no, k, m - integer :: ier - real(r8), allocatable :: area_i(:) - real(r8), allocatable :: area_o(:) - real(r8) :: local_i(numharv) ! input grid: global area harvesting - real(r8) :: local_o(numharv) ! output grid: global area harvesting - real(r8) :: global_i(numharv) ! input grid: global area harvesting - real(r8) :: global_o(numharv) ! output grid: global area harvesting - real(r8), parameter :: fac = 1.e-06_r8 ! Output factor - real(r8), parameter :: rat = fac/100._r8 ! Output factor divided by 100% - character(len=*) , parameter :: unit = '10**6 km**2' ! Output units - !----------------------------------------------------------------------- - - rc = ESMF_SUCCESS - - allocate(area_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(area_o(ns_o), stat=ier) - if (ier/=0) call shr_sys_abort() - call get_meshareas(mesh_i, area_i, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call get_meshareas(mesh_o, area_o, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Input grid global area - local_i(:) = 0. - do ni = 1, ns_i - local_i(m) = local_i(m) + data_i(ni) *area_i(ni) * mask_i(ni) - end do - call mpi_reduce(local_i, global_i, numharv, MPI_REAL8, MPI_SUM, 0, mpicom, ier) - - ! Output grid global area - local_o(:) = 0. - do no = 1,ns_o - local_o(m) = local_o(m) + data_o(no) * area_o(no) * frac_o(no) - end do - call mpi_reduce(local_o, global_o, numharv, MPI_REAL8, MPI_SUM, 0, mpicom, ier) - - ! Comparison - write (ndiag,*) - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,101) unit, unit -101 format (1x,'harvest type' ,20x,' input grid area',' output grid area',/ & - 1x,33x,' ',A,' ',A) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,102) trim(name), global_i*rat, global_o*rat -102 format (1x,a35,f16.3,f17.3) - - end subroutine mkharvest_check_global_sums - !================================================================================= subroutine mkharvest_check_input_var(pioid, varname, varexists, dims2nd, name2nd) diff --git a/tools/mksurfdata_esmf/src/mkinputMod.F90 b/tools/mksurfdata_esmf/src/mkinputMod.F90 index 8777271eb1..8b00115ad8 100644 --- a/tools/mksurfdata_esmf/src/mkinputMod.F90 +++ b/tools/mksurfdata_esmf/src/mkinputMod.F90 @@ -175,6 +175,7 @@ subroutine read_namelist_input(filename) mksrf_fgrid_mesh_nx, & mksrf_fgrid_mesh_ny, & numpft, & + no_inlandwet, & nglcec, & gitdescribe, & outnc_large_files, & @@ -193,6 +194,7 @@ subroutine read_namelist_input(filename) outnc_double = .true. outnc_vic = .false. outnc_3dglc = .false. + no_inlandwet = .true. urban_skip_abort_on_invalid_data_check = .false. ! default value for bug work around if (root_task) then @@ -291,6 +293,7 @@ subroutine read_namelist_input(filename) call mpi_bcast (urban_skip_abort_on_invalid_data_check, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (numpft, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (no_inlandwet, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (std_elev, 1, MPI_REAL, 0, mpicom, ier) call mpi_bcast (gitdescribe, len(gitdescribe), MPI_CHARACTER, 0, mpicom, ier) diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 2ccfea8166..f380a0109b 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -14,13 +14,14 @@ module mklanwatMod use mkdiagnosticsMod , only : output_diagnostics_continuous use mkchecksMod , only : min_bad use mkutilsMod , only : chkerr - use mkvarctl , only : root_task, ndiag, spval + use mkvarctl , only : root_task, ndiag, spval, no_inlandwet use mkfileMod , only : mkfile_output implicit none private - public :: mklakwat ! make % lake, % wetland and lake parameters + public :: mklakwat ! make %lake and lake dpeth + public :: mkwetlnd ! make %wetland character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -29,10 +30,12 @@ module mklanwatMod contains !=============================================================== - subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, swmp_o, pioid_o, fsurdat, rc) + subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, fsurdat, rc) ! ------------------- - ! make %lake, %wetland and lake parameters + ! make %lake and lake depth + ! PCT_LAKE is written out to fsurdat in mksurfdata after adjustments are made + ! LAKE_DETH is written out to fsurdat here ! ------------------- ! input/output variables @@ -41,7 +44,6 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, swmp_o, pioid_o, f type(ESMF_Mesh) , intent(in) :: mesh_o type(file_desc_t) , intent(inout) :: pioid_o real(r8) , intent(out) :: lake_o(:) ! output grid: %lake - real(r8) , intent(out) :: swmp_o(:) ! output grid: %lake character(len=*) , intent(in) :: fsurdat integer , intent(out) :: rc @@ -53,7 +55,6 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, swmp_o, pioid_o, f real(r8), allocatable :: rmask_i(:) real(r8), allocatable :: frac_o(:) real(r8), allocatable :: lake_i(:) ! input grid: percent lake - real(r8), allocatable :: swmp_i(:) ! input grid: percent wetland real(r8), allocatable :: lakedepth_i(:) ! iput grid: lake depth (m) real(r8), allocatable :: lakedepth_o(:) ! output grid: lake depth (m) integer :: ni,no,k ! indices @@ -74,8 +75,13 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, swmp_o, pioid_o, f write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if + ! ---------------------------------------- + ! Read i input data and input mesh and create route handle + ! ** ASSUME ** for now that have only 1 input data file and 1 input mesh + ! for both %lake and lakedepth + ! ---------------------------------------- + ! Open raw data file - ! ASSUME for now that have only 1 input data file rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) ! Read in input mesh @@ -143,43 +149,12 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, swmp_o, pioid_o, f deallocate (lake_i) - ! ---------------------------------------- - ! Create %wetland - ! ---------------------------------------- - - swmp_o(:) = 0._r8 - if (root_task) then - write (ndiag,*) 'Attempting to make %wetland .....' - end if - - ! read in swmp_i - allocate(swmp_i(ns_i), stat=rcode) - if (rcode/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid_i, 'PCT_WETLAND', mesh_i, lake_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! regrid swmp_i to swmp_o - this also returns swmp_i to be used in the global sums below - call regrid_rawdata(mesh_i, mesh_o, routehandle, swmp_i, swmp_o, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regrid_data for wetland") - if (ChkErr(rc,__LINE__,u_FILE_u)) return - do no = 1,ns_o - if (swmp_o(no) < 1.) swmp_o(no) = 0. - enddo - - ! Check global areas - call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - swmp_i, swmp_o, "pct wetland", "unitless", ndiag, nomask=.true., rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - deallocate (swmp_i) - ! ---------------------------------------- ! Create lake parameter (lakedepth) ! ---------------------------------------- if (root_task) then - write (ndiag,*) 'Attempting to make lake parameters.....' + write (ndiag,*) 'Attempting to make lake depth .....' end if ! lakedepth @@ -209,11 +184,15 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, swmp_o, pioid_o, f call pio_syncfile(pioid_o) end if - ! Check global areas + ! Check global areas for lake depth call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & lakedepth_i, lakedepth_o, "lake depth", "m", ndiag, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! ---------------------------------------- + ! Wrap things up + ! ---------------------------------------- + ! Close the single input data file call pio_closefile(pioid_i) @@ -225,11 +204,128 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, swmp_o, pioid_o, f if (root_task) then write (ndiag,*) 'Successfully made %lake' - write (ndiag,*) 'Successfully made %wetland' - write (ndiag,*) 'Successfully made lake parameters' + write (ndiag,*) 'Successfully made lake depth' end if call ESMF_VMLogMemInfo("At end of "//trim(subname)) end subroutine mklakwat +!=============================================================== + subroutine mkwetlnd(file_mesh_i, file_data_i, mesh_o, swmp_o, rc) + + ! ---------------------------------------- + ! Create %wetland + ! Note PCT_WETLAND is written out of mksurfdata after adjustments are made + ! ---------------------------------------- + + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o + real(r8) , intent(out) :: swmp_o(:) ! output grid: %lake + integer , intent(out) :: rc + + ! local variables + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid_i + integer , allocatable :: mask_i(:) + real(r8), allocatable :: rmask_i(:) + real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: swmp_i(:) ! input grid: percent wetland + integer :: ni,no,k ! indices + integer :: ns_i,ns_o ! local sizes + integer :: ier,rcode ! error status + character(len=*), parameter :: subname = ' mklakwat ' + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if ( no_inlandwet) then + if (root_task) then + write (ndiag,*) 'Attempting to make %wetland .....' + if (root_task) write(ndiag, '(a)') trim(subname)//" setting PCT_WETLAND to zero" + end if + swmp_o(:) = 0._r8 + RETURN + end if + + if (root_task) then + write(ndiag,*) 'Attempting to make %wetland .....' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) + end if + + ! Read in input mesh + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Determine ns_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the landmask from the input data file and reset the mesh mask based on that + allocate(rmask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (rmask_i(ni) > 0._r8) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create a route handle between the input and output mesh + allocate(frac_o(ns_o)) + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + + ! read in swmp_i + allocate(swmp_i(ns_i), stat=rcode) + if (rcode/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid_i, 'PCT_WETLAND', mesh_i, swmp_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! regrid swmp_i to swmp_o - this also returns swmp_i to be used in the global sums below + call regrid_rawdata(mesh_i, mesh_o, routehandle, swmp_i, swmp_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regrid_data for wetland") + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do no = 1,ns_o + if (swmp_o(no) < 1.) swmp_o(no) = 0. + enddo + + ! Check global areas + call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + swmp_i, swmp_o, "pct wetland", "unitless", ndiag, nomask=.true., rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Close the single input data file + call pio_closefile(pioid_i) + + ! Release memory + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + if (root_task) then + write (ndiag,*) 'Successfully made %wetland' + end if + call ESMF_VMLogMemInfo("At end of "//trim(subname)) + + end subroutine mkwetlnd + end module mklanwatMod diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index 6079d55436..3666d30e28 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -7,9 +7,9 @@ module mkpftMod use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem use mkpioMod , only : mkpio_iodesc_rawdata, mkpio_get_rawdata_level - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 + use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas use mkutilsMod , only : chkerr - use mkvarctl , only : numpft, root_task, ndiag + use mkvarctl , only : numpft, root_task, ndiag, mpicom use mkvarpar , only : numstdpft, numstdcft, noveg use mkpftConstantsMod @@ -232,8 +232,6 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) real(r8), allocatable :: frac_o(:) - real(r8), allocatable :: area_i(:) - real(r8), allocatable :: area_o(:) real(r8), allocatable :: pctnatveg_i(:) ! input natural veg percent (% of grid cell) real(r8), allocatable :: pctnatveg_o(:) ! output natural veg percent (% of grid cell) real(r8), allocatable :: pctcrop_i(:) ! input all crop percent (% of grid cell) @@ -244,13 +242,10 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft integer :: numpft_i ! num of plant types input data integer :: natpft_i ! num of natural plant types input data integer :: ncft_i ! num of crop types input data - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: sum_fldi ! global sum of dummy input fld real(r8) :: wst_sum ! sum of %pft - real(r8), allocatable :: gpft_o(:) ! output global area pfts - real(r8) :: garea_o ! output global area - real(r8), allocatable :: gpft_i(:) ! input global area pfts - real(r8) :: garea_i ! input global area + real(r8), allocatable :: area_o(:) + real(r8), allocatable :: loc_gpft_o(:) ! output global area pfts + real(r8), allocatable :: glob_gpft_o(:) ! output global area pfts integer :: ier, rcode ! error status real(r8) :: relerr = 0.0001_r8 ! max error: sum overlap wts ne 1 character(len=*), parameter :: subname = 'mkpf' @@ -331,6 +326,11 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + ! ---------------------------------------- + ! Determine pctlnd_o(:) (output argument) + ! ---------------------------------------- + pctlnd_o(:) = frac_o(:) * 100._r8 + ! ---------------------------------------- ! Determine pct_nat_pft_o(:,:) ! ---------------------------------------- @@ -508,72 +508,45 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! ----------------------------------------------------------------- ! Error check - ! Compare global areas on input and output grids + ! Output global sums on output grid ! ----------------------------------------------------------------- - ! ! Derived types - ! allocate(pctnatpft_i(ns_i), stat=ier) - ! if (ier/=0) call shr_sys_abort() - ! allocate(pctcft_i(ns_i), stat=ier) - ! if (ier/=0) call shr_sys_abort() - - ! do ni = 1, ns_i - ! pctnatpft_i(ni) = pct_pft_type( pct_nat_pft_i(ni,:), pctnatveg_i(ni), first_pft_index=natpft_lb ) - ! pctcft_i(ni) = pct_pft_type( pct_cft_i(ni,:), pctcrop_i(ni), first_pft_index=cft_lb ) - ! end do - - ! do no = 1,ns_o - ! pctpft_o(no,natpft_lb:natpft_ub) = pctnatpft_o(no)%get_pct_p2g() - ! pctpft_o(no,cft_lb:cft_ub) = pctcft_o(no)%get_pct_p2g() - ! end do - - ! allocate(gpft_i(0:numpft_i-1)) - ! allocate(gpft_o(0:numpft_i-1)) - - ! ! input grid - ! allocate(pctpft_i(ns_i,0:(numpft_i-1)), stat=ier) - ! if (ier/=0) call shr_sys_abort() - ! allocate(pctpft_o(ns_o,0:(numpft_i-1)), stat=ier) - ! if (ier/=0) call shr_sys_abort() - - ! gpft_i(:) = 0. - ! garea_i = 0. - ! do ni = 1,ns_i - ! garea_i = garea_i + area_src(ni)*re**2 - ! do m = 0, numpft_i - 1 - ! gpft_i(m) = gpft_i(m) + pctpft_i(ni,m) * area_src(ni) * mask(ni)*re**2 - ! end do - ! end do - ! if ( allocated(pctpft_i) ) deallocate (pctpft_i) - - ! ! output grid - ! gpft_o(:) = 0. - ! garea_o = 0. - ! do no = 1,ns_o - ! garea_o = garea_o + area_dst(no)*re**2 - ! do m = 0, numpft_i - 1 - ! gpft_o(m) = gpft_o(m) + pctpft_o(no,m)*area_dst(no)*frac_o(no)*re**2 - ! end do - ! end do - - ! ! comparison - ! write (ndiag,*) - ! write (ndiag,'(1x,70a1)') ('=',k=1,70) - ! write (ndiag,*) 'PFTs Output' - ! write (ndiag,'(1x,70a1)') ('=',k=1,70) - - ! write (ndiag,*) - ! write (ndiag,'(1x,70a1)') ('.',k=1,70) - ! write (ndiag,1001) - ! 1001 format (1x,'plant type ',20x,' input grid area',' output grid area',/ & - ! 1x,33x,' 10**6 km**2',' 10**6 km**2') - ! write (ndiag,'(1x,70a1)') ('.',k=1,70) - ! write (ndiag,*) - ! do m = 0, numpft_i - 1 - ! write (ndiag,1002) veg(m), gpft_i(m)*1.e-06/100.,gpft_o(m)*1.e-06/100. - ! end do - ! 1002 format (1x,a35,f16.3,f17.3) - ! deallocate(gpft_i, gpft_o, frac_dst) + allocate(area_o(ns_o)) + call get_meshareas(mesh_o, area_o, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + allocate(pctpft_o(ns_o,0:(numpft_i-1)), stat=ier) + if (ier/=0) call shr_sys_abort() + do no = 1,ns_o + pctpft_o(no,natpft_lb:natpft_ub) = pctnatpft_o(no)%get_pct_p2g() + pctpft_o(no,cft_lb:cft_ub) = pctcft_o(no)%get_pct_p2g() + end do + + allocate(loc_gpft_o(0:numpft_i-1)) + allocate(glob_gpft_o(0:numpft_i-1)) + loc_gpft_o(:) = 0. + do no = 1,ns_o + do m = 0, numpft_i-1 + loc_gpft_o(m) = loc_gpft_o(m) + pctpft_o(no,m) * area_o(no) * frac_o(no) + write(6,*)'DEBUG: m,pctpft_o(no,m) = ',m,pctpft_o(no,m) + end do + end do + call mpi_reduce(loc_gpft_o, glob_gpft_o, 1, MPI_REAL8, MPI_SUM, 0, mpicom, ier) + + if (root_task) then + write (ndiag,*) + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) 'PFTs Output' + write (ndiag,101) +101 format (1x,'plant type ',20x,' output grid area',/ & + 1x,33x,' 10**6 km**2') + write (ndiag,'(1x,70a1)') ('.',k=1,70) + write (ndiag,*) + do m = 0, numpft_i - 1 + write (ndiag,102) veg(m), glob_gpft_o(m)*1.e-06/100. + end do +102 format (1x,a35,f17.3) + end if ! Clean up memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 5deac1a942..2d9d7bcc7e 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -106,7 +106,7 @@ program mksurfdata use mksoildepthMod , only : mksoildepth use mksoilcolMod , only : mksoilcol use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, mkurban_topo, numurbl - use mklanwatMod , only : mklakwat + use mklanwatMod , only : mklakwat, mkwetlnd use mkorganicMod , only : mkorganic use mkutilsMod , only : normalize_classes_by_gcell, chkerr use mkfileMod , only : mkfile_define_dims, mkfile_define_atts, mkfile_define_vars @@ -402,10 +402,13 @@ program mksurfdata ! LAKEDEPTH is written out in the subroutine ! Need to keep pctlak and pctwet external for use below allocate ( pctlak(lsize_o)) ; pctlak(:) = spval - allocate ( pctwet(lsize_o)) ; pctwet(:) = spval - call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, pctlak, pctwet, pioid, fsurdat, rc=rc) + call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, pctlak, pioid, fsurdat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') + allocate ( pctwet(lsize_o)) ; pctwet(:) = spval + call mkwetlnd(mksrf_fwetlnd_mesh, mksrf_fwetlnd, mesh_model, pctwet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkwetlnd') + ! ----------------------------------- ! Make glacier fraction [pctgla] from [fglacier] dataset ! ----------------------------------- @@ -662,7 +665,6 @@ program mksurfdata call mkfile_output(pioid, mesh_model, 'PCT_WETLAND', pctwet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in in mkfile_output for pctwet') - if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_NATVEG" if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_NATVEG" allocate(pctnatveg(lsize_o)) call get_pct_l2g_array(pctnatpft, pctnatveg) diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index 68061e1a9c..af127553ee 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -22,6 +22,8 @@ module mkvarctl logical, public :: outnc_vic ! true => output VIC fields logical, public :: outnc_3dglc ! true => output 3D glacier fields + logical, public :: no_inlandwet ! set wetland to 0% over land; wetland will only be used for ocean points + integer, public :: numpft = 16 ! number of plant types integer, public :: nglcec = 10 ! number of elevation classes for glaciers From 8b60c8363d263fb073cb439c78a4e59b720d7e90 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 2 Mar 2022 13:49:33 -0700 Subject: [PATCH 086/614] updates to get pft global integrals working --- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 2 -- tools/mksurfdata_esmf/src/mkpftMod.F90 | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index 109edd9ff7..87b6d65f2a 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -186,8 +186,6 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, constant, ntime, call regrid_rawdata(mesh_i, mesh_o, routehandle_r8, data1d_i, data1d_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag,*)'DEBUG: i am here in mkharvest' - ! write out mapped variable if (present(ntime)) then if (root_task) write(ndiag, '(a,i8)') subname//" writing out 1d "//trim(varname_o)//' at time ',ntime diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index 3666d30e28..cdf04aefe9 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -528,10 +528,11 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft do no = 1,ns_o do m = 0, numpft_i-1 loc_gpft_o(m) = loc_gpft_o(m) + pctpft_o(no,m) * area_o(no) * frac_o(no) - write(6,*)'DEBUG: m,pctpft_o(no,m) = ',m,pctpft_o(no,m) end do end do - call mpi_reduce(loc_gpft_o, glob_gpft_o, 1, MPI_REAL8, MPI_SUM, 0, mpicom, ier) + do m = 0,numpft_i-1 + call mpi_reduce(loc_gpft_o(m), glob_gpft_o(m), 1, MPI_REAL8, MPI_SUM, 0, mpicom, ier) + end do if (root_task) then write (ndiag,*) From 076dc34590e2c23e08eccab8523c4db07e499fbe Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 2 Mar 2022 14:17:26 -0700 Subject: [PATCH 087/614] added logname and hostname to namelist variables and removed routine shr_sys_getenv --- .../gen_mksurfdata_namelist.py | 8 ++++ tools/mksurfdata_esmf/src/mkfileMod.F90 | 15 +++---- tools/mksurfdata_esmf/src/mkinputMod.F90 | 6 +++ tools/mksurfdata_esmf/src/mksurfdata.F90 | 20 ++++----- tools/mksurfdata_esmf/src/shr_sys_mod.F90 | 43 ------------------- 5 files changed, 30 insertions(+), 62 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index f1627fb49b..edebbb8f3e 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -194,6 +194,11 @@ def main (): else: hires_pft = 'off' + hostname = subprocess.check_output('hostname').strip().decode(encoding='UTF-8') + print (f"hostname is {hostname}") + logname = subprocess.check_output('logname').strip().decode(encoding='UTF-8') + print (f"logname is {logname}") + # determine pft_years - needed to parse xml file if int(start_year) == 1850 and int(end_year) == 1850: pft_years = "1850" @@ -385,6 +390,9 @@ def main (): else: nlfile.write(" outnc_vic = .false. \n") + nlfile.write(f" logname = \'{logname}\' \n") + nlfile.write(f" hostname = \'{hostname}\' \n") + nlfile.write("/ \n") if __name__ == "__main__": diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 77de0c6bab..3408bf9d85 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -3,7 +3,7 @@ module mkfileMod use ESMF use pio use shr_kind_mod , only : r8 => shr_kind_r8, r4=> shr_kind_r4 - use shr_sys_mod , only : shr_sys_getenv, shr_sys_abort + use shr_sys_mod , only : shr_sys_abort use mkutilsMod , only : get_filename, chkerr use mkvarpar , only : nlevsoi, numrad, numstdpft use mkurbanparMod , only : numurbl, nlevurb, mkurbanpar @@ -116,7 +116,7 @@ subroutine mkfile_define_atts(pioid, dynlanduse) call ESMF_LogWrite(subname//'setting global attributes', ESMF_LOGMSG_INFO) - str = 'NCAR-CSM' + str = 'NCAR-CESM' rcode = pio_put_att(pioid, pio_global, "Conventions", trim(str)) call date_and_time (date, time, zone, values) @@ -124,17 +124,14 @@ subroutine mkfile_define_atts(pioid, dynlanduse) datetime(9:) = ' ' // time(1:2) // ':' // time(3:4) // ':' // time(5:6) // ' ' str = 'created on: ' // datetime rcode = pio_put_att (pioid, pio_global, 'History_Log', trim(str)) - - ! TODO: this is not working - ! call shr_sys_getenv ('LOGNAME', str, ier) - ! rcode = pio_put_att (pioid, pio_global, 'Logname', trim(str)) - ! call shr_sys_getenv ('HOST', str, ier) - ! rcode = pio_put_att (pioid, pio_global, 'Host', trim(str)) - + str = 'Community Land Model: CLM5' rcode = pio_put_att (pioid, pio_global, 'Source', trim(str)) rcode = pio_put_att (pioid, pio_global, 'Version', trim(gitdescribe)) + rcode = pio_put_att (pioid, pio_global, 'Logname', trim(logname)) + rcode = pio_put_att (pioid, pio_global, 'Host', trim(hostname)) + ! TODO: check that this works !rcode = pio_put_att_int(pioid, pio_global, 'nglcec', nglcec) ! Raw data file names diff --git a/tools/mksurfdata_esmf/src/mkinputMod.F90 b/tools/mksurfdata_esmf/src/mkinputMod.F90 index 8b00115ad8..e04198f64c 100644 --- a/tools/mksurfdata_esmf/src/mkinputMod.F90 +++ b/tools/mksurfdata_esmf/src/mkinputMod.F90 @@ -103,6 +103,8 @@ module mkinputMod character(CX) , public :: mksrf_irrig_mesh = ' ' ! TODO: should this namelist be here? character(CS) , public :: gitdescribe = ' ' ! Description of model version from git + character(CS) , public :: logname = ' ' ! user name + character(CS) , public :: hostname = ' ' ! machine name logical , public :: urban_skip_abort_on_invalid_data_check @@ -178,6 +180,8 @@ subroutine read_namelist_input(filename) no_inlandwet, & nglcec, & gitdescribe, & + logname, & + hostname, & outnc_large_files, & outnc_double, & outnc_dims, & @@ -297,6 +301,8 @@ subroutine read_namelist_input(filename) call mpi_bcast (std_elev, 1, MPI_REAL, 0, mpicom, ier) call mpi_bcast (gitdescribe, len(gitdescribe), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (logname, len(logname), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (hostname, len(hostname), MPI_CHARACTER, 0, mpicom, ier) end subroutine read_namelist_input diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 2d9d7bcc7e..f02c1c920a 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -134,7 +134,8 @@ program mksurfdata integer :: ntim ! time sample for dynamic land use integer :: year ! year for dynamic land use integer :: year2 ! year for dynamic land use for harvest file - real(r8) :: suma ! sum for error check + real(r8) :: suma ! local sum for error check + real(r8) :: loc_suma, glob_suma ! local and global sum for error check with mpi_allreduce ! model grid real(r8), allocatable :: lon(:) @@ -187,7 +188,6 @@ program mksurfdata character(len=*), parameter :: u_FILE_u = & __FILE__ - ! ------------------------------------------------------------ ! ====================================================================== ! Initialize MPI @@ -609,24 +609,24 @@ program mksurfdata ! Write out sum of PFT's do k = natpft_lb,natpft_ub - suma = 0._r8 + loc_suma = 0._r8 do n = 1,lsize_o - suma = suma + pctnatpft(n)%get_one_pct_p2g(k) + loc_suma = loc_suma + pctnatpft(n)%get_one_pct_p2g(k) enddo - ! TODO: calculate global sum here + call mpi_reduce(loc_suma, glob_suma, 1, MPI_REAL8, MPI_SUM, 0, mpicom, ier) if (root_task) then - write(ndiag,*) 'sum over domain of pft ',k,suma + write(ndiag,*) 'sum over domain of pft ',k,glob_suma end if enddo if (root_task) write(ndiag,*) do k = cft_lb,cft_ub - suma = 0._r8 + loc_suma = 0._r8 do n = 1,lsize_o - suma = suma + pctcft(n)%get_one_pct_p2g(k) + loc_suma = loc_suma + pctcft(n)%get_one_pct_p2g(k) enddo - ! TODO: calculate global sum here + call mpi_reduce(loc_suma, glob_suma, 1, MPI_REAL8, MPI_SUM, 0, mpicom, ier) if (root_task) then - write(6,*) 'sum over domain of cft ',k,suma + write(6,*) 'sum over domain of cft ',k,glob_suma end if enddo if (root_task) write(ndiag,*) diff --git a/tools/mksurfdata_esmf/src/shr_sys_mod.F90 b/tools/mksurfdata_esmf/src/shr_sys_mod.F90 index 56421a37e3..ef5ca5f566 100644 --- a/tools/mksurfdata_esmf/src/shr_sys_mod.F90 +++ b/tools/mksurfdata_esmf/src/shr_sys_mod.F90 @@ -7,7 +7,6 @@ module shr_sys_mod #include - public :: shr_sys_getenv ! get an environment variable public :: shr_sys_abort ! abort a program !=============================================================================== @@ -49,46 +48,4 @@ subroutine shr_sys_abort(message, file, line) end subroutine shr_sys_abort - !=============================================================================== - subroutine shr_sys_getenv(name, val, rcode) - - !------------------------------------------------------------------------------- - ! PURPOSE: an architecture independant system call - !------------------------------------------------------------------------------- - - ! input/output variables - character(len=*) ,intent(in) :: name ! env var name - character(len=*) ,intent(inout) :: val ! env var value - integer ,intent(inout) :: rcode ! return code - - !----- local ----- - integer :: lenname ! length of env var name - integer :: lenval ! length of env var value - character(SHR_KIND_CL) :: tmpval ! temporary env var value - character(*),parameter :: subName = '(shr_sys_getenv) ' - character(*),parameter :: F00 = "('(shr_sys_getenv) ',4a)" - - lenname=len_trim(name) - -#if (defined IRIX64 || defined CRAY || defined UNICOSMP) - - call pxfgetenv(name, lenname, val, lenval, rcode) - -#elif (defined AIX || defined OSF1 || defined SUNOS || defined LINUX || defined NEC_SX) - - call getenv(trim(name),tmpval) - val=trim(tmpval) - rcode = 0 - if (len_trim(val) == 0 ) rcode = 1 - if (len_trim(val) > SHR_KIND_CL) rcode = 2 - -#else - - write(6,F00) 'ERROR: no implementation of getenv for this architecture' - call shr_sys_abort(subname//'no implementation of getenv for this machine') - -#endif - - end subroutine shr_sys_getenv - end module shr_sys_mod From ab1f984ee472090d00607214af586da6214a1477 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 2 Mar 2022 20:25:43 -0700 Subject: [PATCH 088/614] Updates needed for running gen_mksurfdata_all - Replaced hardwired generic namelist (mksurfdata_in) with run-time determined namelist that gets passed to the executable: ./src/mksurfdata < $input (see gen_mksurfdata) - Created gen_mksurfdata_all starting from gen_mksurfdata and including all the still valid cases found in ../mksurfdata_map/Makefile.data (the old method's system of generating all the fsurdat files). For now, still valid means global (not regional or 1x1). --- tools/mksurfdata_esmf/README | 53 ++++----- tools/mksurfdata_esmf/gen_mksurfdata | 22 ++-- tools/mksurfdata_esmf/gen_mksurfdata_all | 104 ++++++++++++++++++ .../gen_mksurfdata_namelist.py | 10 +- tools/mksurfdata_esmf/src/mkinputMod.F90 | 10 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 2 +- 6 files changed, 146 insertions(+), 55 deletions(-) create mode 100755 tools/mksurfdata_esmf/gen_mksurfdata_all diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 020a54edf0..edd3e976fa 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -1,5 +1,5 @@ Updated on, by: -2/28/2022 slevis +3/2/2022 slevis 2/23/2022 mvertens ================ @@ -13,15 +13,14 @@ Getting the code # Save time by checking out ccs_config only > ./manage_externals/checkout_externals ccs_config -> cd tools/mksurfdata_esmf - ======================= building the executable ======================= +> cd tools/mksurfdata_esmf > rm -rf bld # (or the contents of /bld) before rerunning CC=... -> mkdir ./bld # IF YOU MODIFY .F90 files, start over from "rm -rf bld" +> mkdir ./bld > cd bld -> module load intel # in case need latest version of intel +> module load intel # I found I need the latest version of intel > module load python # in case need latest version of python > module load cmake > bash @@ -29,27 +28,25 @@ building the executable > make VERBOSE=1 > export MKSURFDATA_BLD=`pwd` # needed once; execute in /bld +# IF YOU MODIFY .F90 files, start here first, though more than once +# I have found it necessary to go back to the "rm -rf bld" step > cd ../src -> make clean +> make clean # REMEMBER to be in bash > make VERBOSE=1 -> cd ../ - ======= running ======= -> rm mksurfdata_in -> bash # need if not going through "building the executable" -> temp=`./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc | cut -d' ' -f5` -> ln -s $temp mksurfdata_in -> qsub gen_mksurfdata +> cd ../ +# Edit gen_mksurfdata to generate a single surface dataset that you want +> qsub gen_mksurfdata # OR qsub gen_mksurfdata_all ...to generate all the surface datasets ----- NOTES ------------------------------------------------------------ slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED ------------------------------------------------------------ -1) > temp=`./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc | cut -d' ' -f5` +1) ./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc .nc file issues: - URBAN vars have bigger diffs likely bc using newer raw datasets @@ -64,12 +61,6 @@ problematic or just that we set ocean to loam? - agricultural fire peak month: output areas increase for all categories - voc emission factors all zero -2) repeat for 0.9x - -3) > temp=`./gen_mksurfdata_namelist.py --start-year 1850 --end-year 1850 --res 4x5 --vic --glc | cut -d' ' -f5` - -No issues specific to this resolution. - ------------------------------------------------------ DYNAMIC LU: NOT ALL FILES HAVE BEEN TRANSLATED to cdf5 ------------------------------------------------------ @@ -80,18 +71,16 @@ Coordinate with Peter Lawrence. Use this command to translate: Python script for generating namelists has NOT ADDRESSED: -------------------------------------------------------- * Regional/1x1: handled by subset.py -* High res -* Potveg: needs file(s) converted to cdf5 first? -* Merge_gis -* Nocrop: does this work now? -* Ssp_rcp: needs files converted to cdf5 first? -* Override options: +* nocrop: should work +* hires_pft: should work +* ssp_rcp: should work; needs files converted to cdf5 first? +* potveg: needs file(s) converted to cdf5 first? +* merge_gis +* no_surfdat +* Override options removed: -- all_veg = .true. handled by fsurdat_modifier zero_nonveg = .true. --- all_urban = .true. handle w fsurdat_modifier new option (see subset.py) +-- all_urban = .true. handle w fsurdat_modifier new option -- no_inlandwet = .false. same --- fsurdat_modify should focus on modifying and subset on subsetting +-- soil_... +-- pft_... -Sam to run -> make all -to see that new code works for all the grids. How to automate and how -few nodes could be used? diff --git a/tools/mksurfdata_esmf/gen_mksurfdata b/tools/mksurfdata_esmf/gen_mksurfdata index 115bd2c0cd..d323649008 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata +++ b/tools/mksurfdata_esmf/gen_mksurfdata @@ -1,12 +1,12 @@ #!/bin/bash -#PBS -A P93300606 -#PBS -N job_name +#PBS -A P93300641 +#PBS -N mksurfdata #PBS -j oe -#PBS -q premium +#PBS -q regular #PBS -l walltime=30:00 -##PBS -l select=16:ncpus=36:mpiprocs=9 +#PBS -l select=16:ncpus=36:mpiprocs=9 ##PBS -l select=24:ncpus=36:mpiprocs=12 -#PBS -l select=32:ncpus=36:mpiprocs=12 +##PBS -l select=32:ncpus=36:mpiprocs=12 ##PBS -l select=200:ncpus=36:mpiprocs=12 export TMPDIR=/glade/scratch/$USER/temp @@ -17,10 +17,12 @@ mkdir -p $TMPDIR # note for mpiexec below # -np {total_tasks} +rundir=/glade/work/$USER/git_mvertens/ctsm_1663/tools/mksurfdata_esmf +cd $rundir # Run the model -#mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata -#mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata - mpiexec_mpt -p "%g:" -np 384 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata -#mpiexec_mpt -p "%g:" -np 2400 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata - +input=`./gen_mksurfdata_namelist.py --nocrop --start-year 2000 --end-year 2000 --res 1.9x2.5 | cut -d' ' -f5` +mpiexec_mpt -p "%g:" -np 144 ./src/mksurfdata < $input +#mpiexec_mpt -p "%g:" -np 288 ./src/mksurfdata < $input +#mpiexec_mpt -p "%g:" -np 384 ./src/mksurfdata < $input +#mpiexec_mpt -p "%g:" -np 2400 ./src/mksurfdata < $input diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_all b/tools/mksurfdata_esmf/gen_mksurfdata_all new file mode 100755 index 0000000000..c3267ac8b7 --- /dev/null +++ b/tools/mksurfdata_esmf/gen_mksurfdata_all @@ -0,0 +1,104 @@ +#!/bin/bash +#PBS -A P93300641 +#PBS -N mksurfdata +#PBS -j oe +#PBS -q regular +#PBS -l walltime=12:00:00 +#PBS -l select=64:ncpus=36:mpiprocs=12 + +export TMPDIR=/glade/scratch/$USER/temp +mkdir -p $TMPDIR + +# note for -l input above +# -l select={num_nodes}:ncpus={max_tasks_per_node}:mpiprocs={tasks_per_node} +# note for mpiexec below +# -np {total_tasks} = {num_nodes} x {tasks_per_node} + +rundir=/glade/work/$USER/git_mvertens/ctsm_1663/tools/mksurfdata_esmf +cd $rundir + +# Run the model + +# ------------- +# Notes +# ------------- +# T42 is needed for SCAM +# ne120np4 for high resolution SE dycore +# ne16 for testing SE dycore +# f05 for running full chemistry model +# nldas for NWP working with WRF +# ------------- + +standard_res_no_crop=( '0.9x1.25' '1.9x2.5' '4x5' ) +for res in "${standard_res_no_crop[@]}"; do + input=`./gen_mksurfdata_namelist.py --nocrop --vic --start-year 2000 --end-year 2000 --res $res | cut -d' ' -f5` + mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input +done + +# ------------- + +input=`./gen_mksurfdata_namelist.py --nocrop --start-year 2000 --end-year 2000 --res 64x128 | cut -d' ' -f5` +mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input + +# ------------- + +input=`./gen_mksurfdata_namelist.py --nocrop --hires_pft --start-year 2005 --end-year 2005 --res 0.125nldas2 | cut -d' ' -f5` +mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input + +# ------------- + +standard_res=( '0.9x1.25' '1.9x2.5' '10x15' '4x5' 'ne30np4' 'C96' 'ne30pg2' 'ne30pg3' 'ne30pg4' 'ne120np4pg3' 'ne0np4ARCTICGRISne30x8' 'ne0np4ARCTICne30x4' 'ne0np4CONUSne30x8' ) +for res in "${standard_res[@]}"; do + input=`./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res $res | cut -d' ' -f5` + mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input + + input=`./gen_mksurfdata_namelist.py --start-year 1850 --end-year 1850 --ssp_rcp SSP5-8.5 --res $res | cut -d' ' -f5` + mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input +done + +# ------------- + +input=`./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res ne16np4 | cut -d' ' -f5` +mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input + +# ------------- + +input=`./gen_mksurfdata_namelist.py --hires_pft --start-year 2000 --end-year 2000 --res 0.125x0.125 | cut -d' ' -f5` +mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input + +# ------------- + +resolutions=( '0.47x0.63' 'ne120np4' ) +years=( 1850 2000 ) +for y in "${years[@]}"; do + for res in "${resolutions[@]}"; do + input=`./gen_mksurfdata_namelist.py --start-year $y --end-year $y --res $res | cut -d' ' -f5` + mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input + done +done + +# ------------- + +# TODO --no_surfdata option not available, yet +# slevis adding to trans_res: ne120np4, 0.47x0.63 +trans_res=( '0.9x1.25' '1.9x2.5' '10x15' 'ne30np4' 'ne0np4ARCTICGRISne30x8' 'ne0np4ARCTICne30x4' 'ne0np4CONUSne30x8' 'ne120np4' '0.47x0.63' ) +for res in "${trans_res[@]}"; do + input=`./gen_mksurfdata_namelist.py --no_surfdata --start-year 1850 --end-year 2000 --res $res | cut -d' ' -f5` + mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input +done + +# ------------- + +# Crop with future scenarios +# TODO --no_surfdata option not available, yet +future_res=( '0.9x1.25' '1.9x2.5' '10x15' ) +ssp_list=( 'SSP1-2.6' 'SSP3-7.0' 'SSP5-3.4' 'SSP2-4.5' 'SSP1-1.9' 'SSP4-3.4' 'SSP4-6.0' 'SSP5-8.5' ) +for res in "${future_res[@]}"; do + for ssp in "${ssp_list[@]}"; do + input=`./gen_mksurfdata_namelist.py --no_surfdata --start-year 1850 --end-year 2100 --ssp-rcp $ssp --res $res | cut -d' ' -f5` + mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input + done +done + +# ------------- + diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index edebbb8f3e..6bec04cff5 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -194,10 +194,12 @@ def main (): else: hires_pft = 'off' - hostname = subprocess.check_output('hostname').strip().decode(encoding='UTF-8') - print (f"hostname is {hostname}") - logname = subprocess.check_output('logname').strip().decode(encoding='UTF-8') - print (f"logname is {logname}") +# hostname = subprocess.check_output('hostname').strip().decode(encoding='UTF-8') +# print (f"hostname is {hostname}") +# logname = subprocess.check_output('logname').strip().decode(encoding='UTF-8') +# print (f"logname is {logname}") + hostname = 'foo' + logname = 'foo' # determine pft_years - needed to parse xml file if int(start_year) == 1850 and int(end_year) == 1850: diff --git a/tools/mksurfdata_esmf/src/mkinputMod.F90 b/tools/mksurfdata_esmf/src/mkinputMod.F90 index e04198f64c..b8c5631be0 100644 --- a/tools/mksurfdata_esmf/src/mkinputMod.F90 +++ b/tools/mksurfdata_esmf/src/mkinputMod.F90 @@ -120,7 +120,7 @@ subroutine read_namelist_input(filename) ! Read in input namelist ! input/output variables - character(len=*), intent(in) :: filename + character(len=*), intent(in) :: filename ! now unused ! local variables integer :: ier @@ -206,16 +206,10 @@ subroutine read_namelist_input(filename) end if if (root_task) then - inquire (file=trim(filename), exist=lexist) - if (.not. lexist) then - call shr_sys_abort(subname//trim(filename)//' does not exist') - end if - open(newunit=fileunit, status="old", file=trim(filename)) - read(fileunit, nml=mksurfdata_input, iostat=ier) + read(5, nml=mksurfdata_input, iostat=ier) if (ier > 0) then call shr_sys_abort(subname//' error reading in mksurfdata_input namelist from '//trim(filename)) end if - close(fileunit) end if call mpi_bcast (mksrf_fgrid_mesh, len(mksrf_fgrid_mesh), MPI_CHARACTER, 0, mpicom, ier) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index f02c1c920a..1820a54cf4 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -179,7 +179,7 @@ program mksurfdata type(ESMF_LogKind_Flag) :: logkindflag type(ESMF_VM) :: vm integer :: rc - logical :: create_esmf_pet_files = .true. + logical :: create_esmf_pet_files = .false. ! character variables character(len=CL) :: string ! string read in From 1878b5c6d4d0f8e2e5f6958c8fd243f0312776df Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 3 Mar 2022 23:30:43 -0700 Subject: [PATCH 089/614] added --nosurfdata as an input and fixed the 10x15 time to generate the surface dataset --- tools/mksurfdata_esmf/gen_mksurfdata | 13 +-- .../gen_mksurfdata_namelist.py | 105 ++++++++++++------ tools/mksurfdata_esmf/src/mkdomainMod.F90 | 12 +- tools/mksurfdata_esmf/src/mkinputMod.F90 | 3 + tools/mksurfdata_esmf/src/mksurfdata.F90 | 87 +++++++++------ tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 39 +++++-- 6 files changed, 162 insertions(+), 97 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata b/tools/mksurfdata_esmf/gen_mksurfdata index d323649008..f7d1bb69a5 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata +++ b/tools/mksurfdata_esmf/gen_mksurfdata @@ -17,12 +17,9 @@ mkdir -p $TMPDIR # note for mpiexec below # -np {total_tasks} -rundir=/glade/work/$USER/git_mvertens/ctsm_1663/tools/mksurfdata_esmf -cd $rundir - # Run the model -input=`./gen_mksurfdata_namelist.py --nocrop --start-year 2000 --end-year 2000 --res 1.9x2.5 | cut -d' ' -f5` -mpiexec_mpt -p "%g:" -np 144 ./src/mksurfdata < $input -#mpiexec_mpt -p "%g:" -np 288 ./src/mksurfdata < $input -#mpiexec_mpt -p "%g:" -np 384 ./src/mksurfdata < $input -#mpiexec_mpt -p "%g:" -np 2400 ./src/mksurfdata < $input +#mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata +#mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata + mpiexec_mpt -p "%g:" -np 384 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata +#mpiexec_mpt -p "%g:" -np 2400 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata + diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 6bec04cff5..62c49070a6 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -131,15 +131,26 @@ def get_parser(): dest="hres_flag", default=False, ) + parser.add_argument( + "--nosurfdata", + help=""" + Do not output a surface datase + This is useful if you only want a landuse_timeseries file + [default: %(default)s] + """, + action="store_true", + dest="surfdata_flag", + default=False, + ) parser.add_argument( "--nocrop", help=""" - Create datasets with the extensive list of prognostic crop types. + Do not create datasets with the extensive list of prognostic crop types. [default: %(default)s] """, - action="store_false", + action="store_true", dest="crop_flag", - default=True, + default=False, ) parser.add_argument( "-f", @@ -183,7 +194,8 @@ def main (): res = args.res ssp_rcp = args.ssp_rcp input_path = args.input_path - crop_flag = args.crop_flag + nocrop_flag = args.crop_flag + nosurfdata_flag = args.surfdata_flag vic_flag = args.vic_flag glc_flag = args.glc_flag potveg = args.potveg_flag @@ -194,12 +206,10 @@ def main (): else: hires_pft = 'off' -# hostname = subprocess.check_output('hostname').strip().decode(encoding='UTF-8') -# print (f"hostname is {hostname}") -# logname = subprocess.check_output('logname').strip().decode(encoding='UTF-8') -# print (f"logname is {logname}") - hostname = 'foo' - logname = 'foo' + hostname = os.getenv("HOSTNAME") + print (f"hostname is {hostname}") + logname = os.getenv("LOGNAME") + print (f"logname is {logname}") # determine pft_years - needed to parse xml file if int(start_year) == 1850 and int(end_year) == 1850: @@ -232,11 +242,13 @@ def main (): attribute_list = {'hires_pft':hires_pft, 'pft_years':pft_years, 'ssp_rcp':ssp_rcp, - 'mergeGIS':merge_gis} + 'mergeGIS':merge_gis, + 'res':res} # create dictionary for raw data files names rawdata_files = {} + # determine input rawdata tree1 = ET.parse('./gen_mksurfdata_namelist.xml') root = tree1.getroot() root.tag @@ -280,6 +292,7 @@ def main (): print(f"ERROR: mesh file {rawdata_files[new_key]} does not exist") sys.exit() + # determine output mesh tree2 = ET.parse('../../ccs_config/component_grids_nuopc.xml') root = tree2.getroot() model_mesh = "" @@ -305,11 +318,17 @@ def main (): sys.exit() # Determine num_pft - if crop_flag: + if nocrop_flag: + num_pft = "16" + else: num_pft = "78" + print(f"num_pft is {num_pft}") + + # Write out if surface dataset will be created + if nosurfdata_flag: + print(f"surface dataset will not be created") else: - num_pft = "16" - logger.debug(f" crop_flag = {str(crop_flag)} => num_pft = {num_pft}") + print(f"surface dataset will be created") # Create land-use txt file for a transient case. # Determine the run type and if a transient run create output landuse txt file @@ -317,7 +336,7 @@ def main (): run_type = "transient" else: run_type = "timeslice" - logger.info(f" run_type = {run_type}") + print(f"run_type = {run_type}") if run_type == 'transient': landuse_fname = f"transient_timeseries_hist_{num_pft}pfts_simyr{start_year}-{end_year}.txt" with open(landuse_fname, "w", encoding='utf-8') as landuse_file: @@ -338,7 +357,7 @@ def main (): landuse_fname = "" time_stamp = datetime.today().strftime("%y%m%d") - if end_year == start_year: + if int(end_year) == int(start_year): nlfname = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.namelist" fsurdat = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.nc" fsurlog = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.log" @@ -347,53 +366,75 @@ def main (): nlfname = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.namelist" fsurdat = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.nc" fsurlog = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.log" - fdyndat = f"landuse.timeseries_{res}_{ssp_rcp}_{num_pft}_CMIP6_{start_year}-{end_year}_c{time_stamp}.log" + fdyndat = f"landuse.timeseries_{res}_{ssp_rcp}_{num_pft}_CMIP6_{start_year}-{end_year}_c{time_stamp}.nc" gitdescribe = subprocess.check_output('git describe', shell=True).strip() gitdescribe = gitdescribe.decode('utf-8') + # The below two overrides are only used for testing an validation + # it takes a long time to generate the mapping files + # from 1km to the following two resolutions since the output mesh has so few points + if res == "10x15": + mksrf_ftopostats_override = os.path.join(input_path,"lnd","clm2","rawdata","surfdata_topo_10x15_c220303.nc") + print (f"will override mksrf_ftopostats with = {mksrf_ftopostats_override}") + else: + mksrf_ftopostats_override = "" + + # ---------------------------------------- + # Write output namelist file + # ---------------------------------------- + print (f"Creating input namelist file {nlfname}") with open(nlfname, "w",encoding='utf-8') as nlfile: nlfile.write("&mksurfdata_input \n") + # raw input data for key,value in rawdata_files.items(): if key == 'mksrf_fgrid_mesh_nx' or key == 'mksrf_fgrid_mesh_ny': nlfile.write(f" {key} = {value} \n") elif key != "mksrf_fvic" and key != "mksrf_fvic_mesh": nlfile.write(f" {key} = \'{value}\' \n") - + if key == 'mksrf_ftopostats' and mksrf_ftopostats_override != '': + nlfile.write(f" mksrf_ftopostats_override = \'{mksrf_ftopostats_override}\' \n") + mksrf_hrvtyp = rawdata_files["mksrf_fvegtyp"] nlfile.write( f" mksrf_fhrvtyp = \'{mksrf_hrvtyp}\' \n") mksrf_hrvtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] nlfile.write( f" mksrf_fhrvtyp_mesh = \'{mksrf_hrvtyp_mesh}\' \n") - nlfile.write(f" numpft = {num_pft} \n") - nlfile.write( " no_inlandwet = .true. \n") - nlfile.write( " fdyndat = \' \' \n") - nlfile.write(f" fsurdat = \'{fsurdat}\' \n") + if vic_flag: + mksrf_fvic = rawdata_files["mksrf_fvic"] + nlfile.write(f" mksrf_fvic = \'{mksrf_fvic}\' \n") + mksrf_fvic_mesh = rawdata_files["mksrf_fvic_mesh"] + nlfile.write(f" mksrf_fvic_mesh = \'{mksrf_fvic_mesh}\' \n") + + nlfile.write( f" mksrf_fdynuse = \'{landuse_fname} \' \n") + + # output data files + if nosurfdata_flag: + nlfile.write(f" fsurdat = \' \' \n") + else: + nlfile.write(f" fsurdat = \'{fsurdat}'\n") nlfile.write(f" fsurlog = \'{fsurlog}\' \n") - nlfile.write(f" mksrf_fdynuse = \'{landuse_fname} \' \n") - nlfile.write(f" gitdescribe = \'{gitdescribe}\' \n") - nlfile.write( " outnc_large_files = .false. \n") - nlfile.write( " outnc_double = .true. \n") + nlfile.write(f" fdyndat = \'{fdyndat}\' \n") + # output data logicals + nlfile.write(f" numpft = {num_pft} \n") + nlfile.write( " no_inlandwet = .true. \n") if glc_flag: nlfile.write( " outnc_3dglc = .true. \n") else: nlfile.write( " outnc_3dglc = .false. \n") - if vic_flag: nlfile.write( " outnc_vic = .true. \n") - mksrf_fvic = rawdata_files["mksrf_fvic"] - nlfile.write(f" mksrf_fvic = \'{mksrf_fvic}\' \n") - mksrf_fvic_mesh = rawdata_files["mksrf_fvic_mesh"] - nlfile.write(f" mksrf_fvic_mesh = \'{mksrf_fvic_mesh}\' \n") else: nlfile.write(" outnc_vic = .false. \n") - + nlfile.write( " outnc_large_files = .false. \n") + nlfile.write( " outnc_double = .true. \n") nlfile.write(f" logname = \'{logname}\' \n") nlfile.write(f" hostname = \'{hostname}\' \n") + nlfile.write(f" gitdescribe = \'{gitdescribe}\' \n") nlfile.write("/ \n") diff --git a/tools/mksurfdata_esmf/src/mkdomainMod.F90 b/tools/mksurfdata_esmf/src/mkdomainMod.F90 index a2ebda4a59..8bb6f0f5d7 100644 --- a/tools/mksurfdata_esmf/src/mkdomainMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdomainMod.F90 @@ -24,13 +24,12 @@ module mkdomainMod contains !================================================================================= - subroutine mkdomain(mesh_o, lon_o, lat_o, pioid_o, rc) + subroutine mkdomain(mesh_o, lon_o, lat_o, rc) ! input output variables type(ESMF_Mesh) , intent(in) :: mesh_o real(r8) , intent(out) :: lon_o(:) real(r8) , intent(out) :: lat_o(:) - type(file_desc_t) , intent(inout) :: pioid_o integer , intent(out) :: rc ! local variables: @@ -61,15 +60,6 @@ subroutine mkdomain(mesh_o, lon_o, lat_o, pioid_o, rc) lat_o(no) = ownedElemCoords(2*no) end do - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out model grid" - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" - call mkfile_output(pioid_o, mesh_o, 'LONGXY', lon_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LATIXY" - call mkfile_output(pioid_o, mesh_o, 'LATIXY', lat_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call pio_syncfile(pioid_o) - if (root_task) then write (ndiag,'(a)') 'Successfully made model lats and lons' end if diff --git a/tools/mksurfdata_esmf/src/mkinputMod.F90 b/tools/mksurfdata_esmf/src/mkinputMod.F90 index b8c5631be0..f8fe1451ad 100644 --- a/tools/mksurfdata_esmf/src/mkinputMod.F90 +++ b/tools/mksurfdata_esmf/src/mkinputMod.F90 @@ -95,6 +95,7 @@ module mkinputMod character(CX) , public :: mksrf_ftopostats = ' ' ! topography statistics data file name character(CX) , public :: mksrf_ftopostats_mesh = ' ' ! topography statistics mesh file name + character(CX) , public :: mksrf_ftopostats_override = ' ' ! read STD_ELEV and SLOPE from this file character(CX) , public :: mksrf_fvic = ' ' ! VIC parameters data file name character(CX) , public :: mksrf_fvic_mesh = ' ' ! VIC parameters mesh file name @@ -171,6 +172,7 @@ subroutine read_namelist_input(filename) mksrf_fabm_mesh, & mksrf_ftopostats, & mksrf_ftopostats_mesh, & + mksrf_ftopostats_override, & mksrf_fvic, & mksrf_fvic_mesh, & mksrf_fgrid_mesh, & @@ -272,6 +274,7 @@ subroutine read_namelist_input(filename) call mpi_bcast (mksrf_ftopostats, len(mksrf_ftopostats), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_ftopostats_mesh, len(mksrf_ftopostats_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_ftopostats_override, len(mksrf_ftopostats_override), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fvic, len(mksrf_fvic), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fvic_mesh, len(mksrf_fvic_mesh), MPI_CHARACTER, 0, mpicom, ier) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 1820a54cf4..3d60e72cae 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -54,6 +54,7 @@ program mksurfdata ! mksrf_fabm_mesh - Mesh for mksrf_fabm ! mksrf_ftopostats - Topography statistics dataset ! mksrf_ftopostats_mesh - Mesh for mksrf_ftopostats + ! mksrf_ftopostats_override - Use this file to read in STD_ELEV and SLOPE ! mksrf_fvic - VIC parameters dataset ! mksrf_fvic_mesh - Mesh for mksrf_fvic ! ====================================== @@ -317,13 +318,15 @@ program mksurfdata ! NOTE: do not deallocate pctlak, pctwet, pctglacier and pcturban ! ----------------------------------- - ! Write out coordinate variables + ! Write out natpft and cft ! ----------------------------------- - rcode = pio_inq_varid(pioid, 'natpft', pio_varid) - rcode = pio_put_var(pioid, pio_varid, (/(n,n=natpft_lb,natpft_ub)/)) - if (num_cft > 0) then - rcode = pio_inq_varid(pioid, 'cft', pio_varid) - rcode = pio_put_var(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/)) + if (fsurdat /= ' ') then + rcode = pio_inq_varid(pioid, 'natpft', pio_varid) + rcode = pio_put_var(pioid, pio_varid, (/(n,n=natpft_lb,natpft_ub)/)) + if (num_cft > 0) then + rcode = pio_inq_varid(pioid, 'cft', pio_varid) + rcode = pio_put_var(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/)) + end if end if ! ----------------------------------- @@ -331,20 +334,27 @@ program mksurfdata ! ----------------------------------- allocate (lon(lsize_o)) ; lon(:) = spval allocate (lat(lsize_o)) ; lat(:) = spval + call mkdomain(mesh_model, lon_o=lon, lat_o=lat, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') if (fsurdat /= ' ') then - call mkdomain(mesh_model, lon_o=lon, lat_o=lat, pioid_o=pioid, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out model grid" + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" + call mkfile_output(pioid, mesh_model, 'LONGXY', lon, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for LONGXY') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LATIXY" + call mkfile_output(pioid, mesh_model, 'LATIXY', lat, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for LATIXY') + call pio_syncfile(pioid) end if ! ----------------------------------- ! Make LAI and SAI from 1/2 degree data and write to surface dataset ! Write to netcdf file is done inside mklai routine ! ----------------------------------- - if (root_task) then - write(ndiag,'(a)')'calling mklai' + if (fsurdat /= ' ') then + call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') end if - call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') ! ----------------------------------- ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] @@ -393,8 +403,10 @@ program mksurfdata ! ----------------------------------- ! Note that this call must come after call to mkpftInit - since num_cft is set there ! Output data is written in mkharvest - call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, pioid_o=pioid, constant=.true., rc=rc ) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') + if (fsurdat /= ' ') then + call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, pioid, constant=.true., rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') + end if ! ----------------------------------- ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] @@ -521,7 +533,8 @@ program mksurfdata ! Compute topography statistics [topo_stddev, slope] from [ftopostats] ! ----------------------------------- if (fsurdat /= ' ') then - call mktopostats ( mksrf_ftopostats_mesh, mksrf_ftopostats, mesh_model, pioid, rc=rc) + call mktopostats ( mksrf_ftopostats_mesh, mksrf_ftopostats, mksrf_ftopostats_override, & + mesh_model, pioid, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mktopostats') end if @@ -639,8 +652,10 @@ program mksurfdata ! Make Urban Parameters from raw input data and write to surface dataset ! Write to netcdf file is done inside mkurbanpar routine - call mkurbanpar(mksrf_furban, pioid, mesh_model, urban_region, urban_classes_g, & - urban_skip_abort_on_invalid_data_check) + if (fsurdat /= ' ') then + call mkurbanpar(mksrf_furban, pioid, mesh_model, urban_region, urban_classes_g, & + urban_skip_abort_on_invalid_data_check) + end if deallocate(urban_region) ! ----------------------------------- @@ -648,6 +663,13 @@ program mksurfdata ! PCT_NATVEG, PCT_NAT_PFT, PCT_CROP and PCT_CFT ! ----------------------------------- + allocate(pctnatveg(lsize_o)) + allocate(pctcrop(lsize_o)) + allocate(pct_nat_pft(lsize_o, 0:num_natpft)) + if (num_cft > 0) then + allocate(pct_cft(lsize_o, num_cft)) + end if + if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing out PCT_URBAN" call mkfile_output(pioid, mesh_model, 'PCT_URBAN', urban_classes_g, lev1name='numurbl', rc=rc) @@ -666,26 +688,22 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in in mkfile_output for pctwet') if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_NATVEG" - allocate(pctnatveg(lsize_o)) call get_pct_l2g_array(pctnatpft, pctnatveg) call mkfile_output(pioid, mesh_model, 'PCT_NATVEG', pctnatveg, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NATVEG') if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_CROP" - allocate(pctcrop(lsize_o)) call get_pct_l2g_array(pctcft, pctcrop) call mkfile_output(pioid, mesh_model, 'PCT_CROP', pctcrop, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP') if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_NAT_PFT" - allocate(pct_nat_pft(lsize_o, 0:num_natpft)) call get_pct_p2l_array(pctnatpft, ndim1=lsize_o, ndim2=num_natpft+1, pct_p2l=pct_nat_pft) call mkfile_output(pioid, mesh_model, 'PCT_NAT_PFT', pct_nat_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NAT_PFT') if (num_cft > 0) then if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_CFT" - allocate(pct_cft(lsize_o, num_cft)) call get_pct_p2l_array(pctcft, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) call mkfile_output(pioid, mesh_model, 'PCT_CFT', pct_cft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CFT') @@ -705,14 +723,14 @@ program mksurfdata ! ---------------------------------------------------------------------- ! Close surface dataset ! ---------------------------------------------------------------------- - - call pio_closefile(pioid) - - if (root_task) then - write(ndiag,*) - write(ndiag,'(a)') 'Successfully created surface data output file = '//trim(fsurdat) - write(ndiag,'(a)') ' This file contains the land model surface data' - write(ndiag,*) + if (fsurdat /= ' ') then + call pio_closefile(pioid) + if (root_task) then + write(ndiag,*) + write(ndiag,'(a)') 'Successfully created surface data output file = '//trim(fsurdat) + write(ndiag,'(a)') ' This file contains the land model surface data' + write(ndiag,*) + end if end if ! ====================================================================== @@ -752,7 +770,7 @@ program mksurfdata ! Define variables call mkfile_define_vars(pioid, dynlanduse = .true.) - ! End define model + ! End define mode rcode = pio_enddef(pioid) ! Write out natpft @@ -851,13 +869,12 @@ program mksurfdata rcode = pio_put_var(pioid, pio_varid, (/ntim/), year) rcode = pio_inq_varid(pioid, 'time', pio_varid) rcode = pio_put_var(pioid, pio_varid, (/ntim/), year) - ! rcode = pio_inq_varid(pioid, 'input_pftdata_filename', pio_varid) - ! rcode = pio_put_var(pioid, pio_varid, (/1,ntim/), (/len_trim(string),1/), trim(string)) + !rcode = pio_inq_varid(pioid, 'input_pftdata_filename', pio_varid) + !rcode = pio_put_var(pioid, pio_varid, (/1,ntim/), (/len_trim(string),1/), trim(string)) call pio_syncfile(pioid) ! Create pctpft data at model resolution from file fname ! Note that pctlnd_o below is different than the above call and returns pctlnd_pft_dyn - call mkpft( mksrf_fvegtyp_mesh, fname, mesh_model, & pctlnd_o=pctlnd_pft_dyn, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpft') @@ -883,8 +900,7 @@ program mksurfdata ! Create harvesting data at model resolution ! Output data is written in mkharvest - call mkharvest( mksrf_fhrvtyp_mesh, fhrvname, mesh_model, & - pioid_o=pioid, constant=.false., ntime=ntim, rc=rc ) + call mkharvest( mksrf_fhrvtyp_mesh, fhrvname, mesh_model, pioid, constant=.false., ntime=ntim, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest') call pio_syncfile(pioid) @@ -977,7 +993,6 @@ program mksurfdata ! ----------------------------------- close (ndiag) - ! TODO: fix the error condition here call ESMF_Finalize() !----------------------------------------------------------------------- diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index 63e37ce94d..836799b661 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -29,7 +29,7 @@ module mktopostatsMod contains !=============================================================== - subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) + subroutine mktopostats(file_mesh_i, file_data_i, file_data_i_override, mesh_o, pioid_o, rc) ! make various topography statistics ! @@ -37,9 +37,10 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) use mkchecksMod , only : min_bad, max_bad ! ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! input model mesh + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + character(len=*) , intent(in) :: file_data_i_override ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! input model mesh type(file_desc_t) , intent(inout) :: pioid_o integer , intent(out) :: rc ! @@ -86,6 +87,30 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) RETURN end if + ! Determine ns_o and allocate output data + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate (topo_stddev_o(ns_o)) ; topo_stddev_o(:) = spval + allocate (slope_o(ns_o)) ; slope_o(:) = spval + + ! Read file_data_i_override for data that is assumed to already be on the output grid + if (file_data_i_override /= ' ' ) then + if (root_task) write(ndiag, '(a)') trim(subname)//" reading STD_ELEV and SLOPE from "//trim(file_data_i_override) + ! TODO: get dimensions and make sure that they match the dimensions of mesh_o + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i_override), pio_nowrite) + call mkpio_get_rawdata(pioid_i, 'STD_ELEV', mesh_o, topo_stddev_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call mkpio_get_rawdata(pioid_i, 'SLOPE', mesh_o, slope_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag, '(a)') trim(subname)//" writing topo_stddev " + call mkfile_output(pioid_o, mesh_o, 'STD_ELEV', topo_stddev_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for STD_ELEV') + call mkfile_output(pioid_o, mesh_o, 'SLOPE', slope_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for SLOPE') + call pio_syncfile(pioid_o) + RETURN + end if + ! Open input data file ! Read in data with PIO_IOTYPE_NETCDF rather than PIO_IOTYPE_PNETCDF since there are problems ! with the pnetcdf read of this high resolution data @@ -101,12 +126,6 @@ subroutine mktopostats(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Determine ns_o and allocate output data - call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate (topo_stddev_o(ns_o)) ; topo_stddev_o(:) = spval - allocate (slope_o(ns_o)) ; slope_o(:) = spval - ! Read in input data data_i allocate(data_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort(subname//' error in allocating data_i') From 2eb56f1f3622ce22559892b39a4cd0d55f6a9581 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 4 Mar 2022 12:49:37 -0700 Subject: [PATCH 090/614] Updated syntax in gen_mksurfdata_all for it to work again --- tools/mksurfdata_esmf/gen_mksurfdata_all | 32 +++++++++++++++--------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_all b/tools/mksurfdata_esmf/gen_mksurfdata_all index c3267ac8b7..e6e10fa2f1 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_all +++ b/tools/mksurfdata_esmf/gen_mksurfdata_all @@ -27,43 +27,45 @@ cd $rundir # ne16 for testing SE dycore # f05 for running full chemistry model # nldas for NWP working with WRF +# 4x5 and 10x15 for testing purposes # ------------- standard_res_no_crop=( '0.9x1.25' '1.9x2.5' '4x5' ) for res in "${standard_res_no_crop[@]}"; do - input=`./gen_mksurfdata_namelist.py --nocrop --vic --start-year 2000 --end-year 2000 --res $res | cut -d' ' -f5` + input=$(echo `./gen_mksurfdata_namelist.py --nocrop --vic --start-year 2000 --end-year 2000 --res $res` | cut -d' ' -f 22) mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input done # ------------- -input=`./gen_mksurfdata_namelist.py --nocrop --start-year 2000 --end-year 2000 --res 64x128 | cut -d' ' -f5` +# TODO DIDN'T WORK? +input=$(echo `./gen_mksurfdata_namelist.py --nocrop --start-year 2000 --end-year 2000 --res 64x128` | cut -d' ' -f 22) mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input # ------------- -input=`./gen_mksurfdata_namelist.py --nocrop --hires_pft --start-year 2005 --end-year 2005 --res 0.125nldas2 | cut -d' ' -f5` +input=$(echo `./gen_mksurfdata_namelist.py --nocrop --hires_pft --start-year 2005 --end-year 2005 --res 0.125nldas2` | cut -d' ' -f 22) mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input # ------------- standard_res=( '0.9x1.25' '1.9x2.5' '10x15' '4x5' 'ne30np4' 'C96' 'ne30pg2' 'ne30pg3' 'ne30pg4' 'ne120np4pg3' 'ne0np4ARCTICGRISne30x8' 'ne0np4ARCTICne30x4' 'ne0np4CONUSne30x8' ) for res in "${standard_res[@]}"; do - input=`./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res $res | cut -d' ' -f5` + input=$(echo `./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res $res` | cut -d' ' -f 22) mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input - input=`./gen_mksurfdata_namelist.py --start-year 1850 --end-year 1850 --ssp_rcp SSP5-8.5 --res $res | cut -d' ' -f5` + input=$(echo `./gen_mksurfdata_namelist.py --start-year 1850 --end-year 1850 --ssp-rcp SSP5-8.5 --res $res` | cut -d' ' -f 22) mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input done # ------------- -input=`./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res ne16np4 | cut -d' ' -f5` +input=$(echo `./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res ne16np4` | cut -d' ' -f 22) mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input # ------------- -input=`./gen_mksurfdata_namelist.py --hires_pft --start-year 2000 --end-year 2000 --res 0.125x0.125 | cut -d' ' -f5` +input=$(echo `./gen_mksurfdata_namelist.py --hires_pft --start-year 2000 --end-year 2000 --res 0.125x0.125` | cut -d' ' -f 22) mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input # ------------- @@ -72,30 +74,36 @@ resolutions=( '0.47x0.63' 'ne120np4' ) years=( 1850 2000 ) for y in "${years[@]}"; do for res in "${resolutions[@]}"; do - input=`./gen_mksurfdata_namelist.py --start-year $y --end-year $y --res $res | cut -d' ' -f5` + input=$(echo `./gen_mksurfdata_namelist.py --start-year $y --end-year $y --res $res` | cut -d' ' -f 22) mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input done done # ------------- -# TODO --no_surfdata option not available, yet # slevis adding to trans_res: ne120np4, 0.47x0.63 +# TODO Currently have access to files 1850-1855 and 2000-2007. When remaining +# files become available, uncomment the commented-out line and delete the one +# after it. trans_res=( '0.9x1.25' '1.9x2.5' '10x15' 'ne30np4' 'ne0np4ARCTICGRISne30x8' 'ne0np4ARCTICne30x4' 'ne0np4CONUSne30x8' 'ne120np4' '0.47x0.63' ) for res in "${trans_res[@]}"; do - input=`./gen_mksurfdata_namelist.py --no_surfdata --start-year 1850 --end-year 2000 --res $res | cut -d' ' -f5` +# input=$(echo `./gen_mksurfdata_namelist.py --nosurfdata --start-year 1850 --end-year 2000 --res $res` | cut -d' ' -f 22) + input=$(echo `./gen_mksurfdata_namelist.py --nosurfdata --start-year 1850 --end-year 1855 --res $res` | cut -d' ' -f 22) mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input done # ------------- # Crop with future scenarios -# TODO --no_surfdata option not available, yet +# TODO Currently have access to files 1850-1855 and 2000-2007. When remaining +# files become available, uncomment the commented-out line and delete the one +# after it. future_res=( '0.9x1.25' '1.9x2.5' '10x15' ) ssp_list=( 'SSP1-2.6' 'SSP3-7.0' 'SSP5-3.4' 'SSP2-4.5' 'SSP1-1.9' 'SSP4-3.4' 'SSP4-6.0' 'SSP5-8.5' ) for res in "${future_res[@]}"; do for ssp in "${ssp_list[@]}"; do - input=`./gen_mksurfdata_namelist.py --no_surfdata --start-year 1850 --end-year 2100 --ssp-rcp $ssp --res $res | cut -d' ' -f5` +# input=$(echo `./gen_mksurfdata_namelist.py --nosurfdata --start-year 1850 --end-year 2100 --ssp-rcp $ssp --res $res` | cut -d' ' -f 22) + input=$(echo `./gen_mksurfdata_namelist.py --nosurfdata --start-year 2000 --end-year 2007 --ssp-rcp $ssp --res $res` | cut -d' ' -f 22) mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input done done From 2d66cca3b48cd84fb3dfbf3c86a8d4dff70a1616 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 4 Mar 2022 16:40:20 -0700 Subject: [PATCH 091/614] Added echo statmts & corrected a resolution name in gen_mksurfdata_all --- tools/mksurfdata_esmf/gen_mksurfdata_all | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_all b/tools/mksurfdata_esmf/gen_mksurfdata_all index e6e10fa2f1..1cd5e5d12d 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_all +++ b/tools/mksurfdata_esmf/gen_mksurfdata_all @@ -33,40 +33,54 @@ cd $rundir standard_res_no_crop=( '0.9x1.25' '1.9x2.5' '4x5' ) for res in "${standard_res_no_crop[@]}"; do input=$(echo `./gen_mksurfdata_namelist.py --nocrop --vic --start-year 2000 --end-year 2000 --res $res` | cut -d' ' -f 22) + echo $input ATTEMPT mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input + echo $input DONE? done # ------------- # TODO DIDN'T WORK? input=$(echo `./gen_mksurfdata_namelist.py --nocrop --start-year 2000 --end-year 2000 --res 64x128` | cut -d' ' -f 22) +echo $input ATTEMPT mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input +echo $input DONE? # ------------- input=$(echo `./gen_mksurfdata_namelist.py --nocrop --hires_pft --start-year 2005 --end-year 2005 --res 0.125nldas2` | cut -d' ' -f 22) +echo $input ATTEMPT mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input +echo $input DONE? # ------------- -standard_res=( '0.9x1.25' '1.9x2.5' '10x15' '4x5' 'ne30np4' 'C96' 'ne30pg2' 'ne30pg3' 'ne30pg4' 'ne120np4pg3' 'ne0np4ARCTICGRISne30x8' 'ne0np4ARCTICne30x4' 'ne0np4CONUSne30x8' ) +standard_res=( '0.9x1.25' '1.9x2.5' '10x15' '4x5' 'ne30np4' 'C96' 'ne30pg2' 'ne30pg3' 'ne30pg4' 'ne120np4pg3' 'ne0np4.ARCTICGRIS.ne30x8' 'ne0np4ARCTICne30x4' 'ne0np4CONUSne30x8' ) for res in "${standard_res[@]}"; do input=$(echo `./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res $res` | cut -d' ' -f 22) + echo $input ATTEMPT mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input + echo $input DONE? input=$(echo `./gen_mksurfdata_namelist.py --start-year 1850 --end-year 1850 --ssp-rcp SSP5-8.5 --res $res` | cut -d' ' -f 22) + echo $input ATTEMPT mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input + echo $input DONE? done # ------------- input=$(echo `./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res ne16np4` | cut -d' ' -f 22) +echo $input ATTEMPT mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input +echo $input DONE? # ------------- input=$(echo `./gen_mksurfdata_namelist.py --hires_pft --start-year 2000 --end-year 2000 --res 0.125x0.125` | cut -d' ' -f 22) +echo $input ATTEMPT mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input +echo $input DONE? # ------------- @@ -75,7 +89,9 @@ years=( 1850 2000 ) for y in "${years[@]}"; do for res in "${resolutions[@]}"; do input=$(echo `./gen_mksurfdata_namelist.py --start-year $y --end-year $y --res $res` | cut -d' ' -f 22) + echo $input ATTEMPT mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input + echo $input DONE? done done @@ -85,11 +101,13 @@ done # TODO Currently have access to files 1850-1855 and 2000-2007. When remaining # files become available, uncomment the commented-out line and delete the one # after it. -trans_res=( '0.9x1.25' '1.9x2.5' '10x15' 'ne30np4' 'ne0np4ARCTICGRISne30x8' 'ne0np4ARCTICne30x4' 'ne0np4CONUSne30x8' 'ne120np4' '0.47x0.63' ) +trans_res=( '0.9x1.25' '1.9x2.5' '10x15' 'ne30np4' 'ne0np4.ARCTICGRIS.ne30x8' 'ne0np4ARCTICne30x4' 'ne0np4CONUSne30x8' 'ne120np4' '0.47x0.63' ) for res in "${trans_res[@]}"; do # input=$(echo `./gen_mksurfdata_namelist.py --nosurfdata --start-year 1850 --end-year 2000 --res $res` | cut -d' ' -f 22) input=$(echo `./gen_mksurfdata_namelist.py --nosurfdata --start-year 1850 --end-year 1855 --res $res` | cut -d' ' -f 22) + echo $input ATTEMPT mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input + echo $input DONE? done # ------------- @@ -104,7 +122,9 @@ for res in "${future_res[@]}"; do for ssp in "${ssp_list[@]}"; do # input=$(echo `./gen_mksurfdata_namelist.py --nosurfdata --start-year 1850 --end-year 2100 --ssp-rcp $ssp --res $res` | cut -d' ' -f 22) input=$(echo `./gen_mksurfdata_namelist.py --nosurfdata --start-year 2000 --end-year 2007 --ssp-rcp $ssp --res $res` | cut -d' ' -f 22) + echo $input ATTEMPT mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input + echo $input DONE? done done From c6fa13eb2174eadf6b5cc5df18f9940536bf90b3 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 6 Mar 2022 18:06:13 -0700 Subject: [PATCH 092/614] updates for replacement of Makefile.data --- .../gen_mksurfdata_jobscript.py | 214 +++++++++++ .../gen_mksurfdata_namelist.py | 171 ++++++--- .../gen_mksurfdata_namelist.xml | 24 +- ..._timeseries_hist_78pfts_simyr1850-2015.txt | 332 ------------------ 4 files changed, 347 insertions(+), 394 deletions(-) create mode 100755 tools/mksurfdata_esmf/gen_mksurfdata_jobscript.py delete mode 100644 tools/mksurfdata_map/landuse_timeseries_hist_78pfts_simyr1850-2015.txt diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript.py new file mode 100755 index 0000000000..824a779e89 --- /dev/null +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python3 + +import sys, os, shutil +import logging +import argparse, textwrap +import subprocess +from datetime import datetime + +valid_scenarios=["all", + "standard", + "global-present", + "global-present-T42", + "global-present-nldas", + "tropics", + "crop-tropics-present", + "crop-tropics-historical", + "crop-tropics-transient", + "crop", + "crop-global-present", + "crop-global-present-ne16np4", + "crop-global-present-ne120np4", + "crop-global-present-0.125", + "crop-global-present-f05", + "crop-global-historical", + "crop-global-historical-f05", + "crop-global-historical-ne120np4", + "crop-global-transient", + "crop-global-transient-ne120np4", + "crop-global-transient-f05", + "crop-global-future", + "crop-global-SSP1-2.6", + "crop-global-SSP3-7.0", + "crop-global-SSP5-3.4", + "crop-global-SSP2-4.5", + "crop-global-SSP1-1.9", + "crop-global-SSP4-3.4", + "crop-global-SSP4-6.0", + "crop-global-SSP5-8.5"] + +def get_parser(): + """ + Get parser object for this script. + """ + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + + parser.print_usage = parser.print_help + + parser.add_argument( + '-v', '--verbose', + help="ncrease output verbosity", + action="store_true", + ) + parser.add_argument( + "--mpi_tasks", + help="number of mpi tasks requested", + action="store", + dest="mpi_tasks", + required=True, + ) + parser.add_argument( + "--scenario", + help="""scenario""", + choices=valid_scenarios, + action="store", + dest="scenario", + required=True, + ) + return parser + +def main (): + + # -------------------------- + # Obtain input args + # -------------------------- + args = get_parser().parse_args() + scenario = args.scenario + mpi_tasks = args.mpi_tasks + + # -------------------------- + # Determine target list + # -------------------------- + target_list = [] + if scenario == 'all': + target_list = ["global-present", + "global-present-T42", + "global-present-nldas", + "crop-global-present", + "crop-global-present-ne16np4", + "crop-global-present-ne120np4", + "crop-global-historical", + "crop-global-transient", + "crop-tropics-present", + "crop-global-SSP1-2.6", + "crop-global-SSP3-7.0", + "crop-global-SSP5-3.4", + "crop-global-SSP2-4.5", + "crop-global-SSP1-1.9", + "crop-global-SSP4-3.4", + "crop-global-SSP4-6.0", + "crop-global-SSP5-8.5"] + elif scenario == 'standard': + target_list = ["global-present", + "global-present-T42", + "global-present-nldas"] + elif scenario == "crop": + target_list = ["crop-global-present", + "crop-global-present-ne16np4", + "crop-global-present-ne120np4", + "crop-global-historical", + "crop-global-transient"] + elif scenario == "crop-global-future": + target_list = ["crop-global-SSP1-2.6", + "crop-global-SSP3-7.0", + "crop-global-SSP5-3.4", + "crop-global-SSP2-4.5", + "crop-global-SSP1-1.9", + "crop-global-SSP4-3.4", + "crop-global-SSP4-6.0", + "crop-global-SSP5-8.5"] + elif scenario == "tropics": + target_list = ["crop-tropics-present"] + else: + target_list = [scenario] + + print (f"DEBUG: target_list is {target_list}") + + # -------------------------- + # Determine resolution sets that are referenced in commands + # -------------------------- + resolution_dict = { + "standard_res_no_crop" : ["0.9x1.25","1.9x2.5","10x15"], + "standard_res" : ['0.9x1.25','1.9x2.5','10x15','4x5','C96', + 'ne30np4','ne30np4.pg2','ne30np4.pg3','ne30np4.pg4','ne120np4.pg3', + 'ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4','ne0np4CONUS.ne30x8'], + "future_res" : ["0.9x1.25","1.9x2.5","10x15"], + "trans_res" : ['0.9x1.25','1.9x2.5','10x15', + 'ne30np4','ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4','ne0np4CONUS.ne30x8','ne120np4'], + "T42_res" : ['T42'], + "nldas_res" : ['0.125nldas2'], + "5x5_amazon_res" : ['5x5_amazon'], + "ne16np4_res" : ['ne120np4'], + "ne120np4_res" : ['ne120np4'], + } + + # -------------------------- + # Determine commands for each target list + # -------------------------- + dataset_dict={"global-present" : ("--start-year 2000 --end-year 2000 --nocrop --vic --res", "standard_res_no_crop"), + "global-present-T42" : ("--start-year 2000 --end-year 2000 --nocrop --vic --res", "T42_res"), + "global-present-nldas" : ("--start-year 2000 --end-year 2000 --nocrop --vic --res", "nldas_res"), + "crop-tropics-present" : ("--start-year 2000 --end-year 2000 --res", "5x5_amazon_res"), + "crop-global-present" : ("--start-year 2000 --end-year 2000 --res", "standard_res"), + "crop-global-present-ne16np4" : ("--start-year 2000 --end-year 2000 --res", "ne16np4_res"), + "crop-global-present-ne120np4" : ("--start-year 2000 --end-year 2000 --res", "ne120np4_res"), + "crop-global-present-0.125" : ("--start-year 2000 --end-year 2000 --hirespft --res", "nldas_res"), + "crop-global-historical" : ("--start-year 1850 --end-year 1850 --ssp-rcp SSP5-8.5 --res", "standard_res"), + "crop-global-historical-ne120np4" : ("--start-year 1850 --end-year 1850 --ssp-rcp SSP5-8.5 --res", "ne120np4_res"), + "crop-global-transient" : ("--start-year 1850 --end-year 2000 --nosurfdata --res", "trans_res"), + "crop-global-transient-ne120np4" : ("--start-year 1850 --end-year 2000 --nosurfdata --res", "ne120np4_res"), + "crop-global-SSP1-2.6" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-2.6 --res", "future_res"), + "crop-global-SSP3-7.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-7.0 --res", "future_res"), + "crop-global-SSP5-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-3.4 --res", "future_res"), + "crop-global-SSP2-4.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-4.5 --res", "future_res"), + "crop-global-SSP1-1.9" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-1.9 --res", "future_res"), + "crop-global-SSP4-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-3.4 --res", "future_res"), + "crop-global-SSP4-6.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-6.0 --res", "future_res"), + "crop-global-SSP5-8.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-8.5 --res", "future_res") + } + + # -------------------------- + # Write run script + # -------------------------- + with open("./runfile", "w",encoding='utf-8') as runfile: + + np = int(mpi_tasks) + tasks_per_node = 12 + nodes = int(np / tasks_per_node) + print (f"DEBUG: number of nodes is {nodes}") + print (f"DEBUG: number of tasks is {np}") + + runfile.write('#!/bin/bash') + runfile.write('#PBS -A P93300606 \n') + runfile.write('#PBS -N mksurfdata \n') + runfile.write('#PBS -j oe \n') + runfile.write('#PBS -q regular \n') + runfile.write('#PBS -l walltime=30:00 \n') + runfile.write(f"#PBS -l select={nodes}:ncpus=36:mpiprocs=12 \n") + + runfile.write("\n") + runfile.write("export TMPDIR=/glade/scratch/\$USER/temp \n") + runfile.write("mkdir -p \$TMPDIR \n") + runfile.write("\n") + + for target in target_list: + res_set = dataset_dict[target][1] + for res in resolution_dict[res_set]: + command = os.path.join(os.getcwd(), "gen_mksurfdata_namelist.py") + command = command + " " + dataset_dict[target][0] + " " + res + print (f"command is {command}") + commands = [x for x in command.split(' ') if x] + run_cmd = subprocess.run(commands, check=True, capture_output=True) + if run_cmd.returncode != 0: + print ("Error in calling gen_mksurfdata_namelist.py") + sys.exit(1) + output = run_cmd.stdout.decode('utf-8').strip() + namelist = output.split(' ')[-1] + print (f"generated namelist {namelist}") + output = f"mpiexec_mpt -p \"%g:\" -np {np} ./src/mksurfdata < {namelist}" + runfile.write(f"{output} \n") + +if __name__ == "__main__": + main() diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 62c49070a6..6ba0b9b66f 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -10,7 +10,7 @@ logger = logging.getLogger(__name__) # valid options for SSP scenarios and pft years: -valid_opts = {"ssp_rcp": ["hist","SSP1-2.6","SSP3-7.0","SSP5-3.4","SSP2-4.5","SSP1-1.9","SSP4-3.4","SSP4-6.0","SSP5-8.5"]} +valid_opts = {"ssp-rcp": ["none","SSP1-2.6","SSP3-7.0","SSP5-3.4","SSP2-4.5","SSP1-1.9","SSP4-3.4","SSP4-6.0","SSP5-8.5"]} def get_parser(): """ @@ -22,10 +22,15 @@ def get_parser(): parser.print_usage = parser.print_help + parser.add_argument( + '-v', '--verbose', + help="ncrease output verbosity", + action="store_true", + ) parser.add_argument( "--start-year", help = textwrap.dedent('''\ - Simulation start year. + Simulation start year. [Required]'''), action="store", dest="start_year", @@ -35,7 +40,7 @@ def get_parser(): parser.add_argument( "--end-year", help = textwrap.dedent('''\ - Simulation end year. + Simulation end year. [Required]'''), action="store", dest="end_year", @@ -85,8 +90,8 @@ def get_parser(): action="store", dest="ssp_rcp", required=False, - choices=valid_opts["ssp_rcp"], - default="hist", + choices=valid_opts["ssp-rcp"], + default="none", ) parser.add_argument( "--rawdata-dir", @@ -101,7 +106,7 @@ def get_parser(): parser.add_argument( "--vic", help=""" - Flag for adding the fields required for the VIC model. + Flag for adding the fields required for the VIC model. [default: %(default)s] """, action="store_true", @@ -203,13 +208,25 @@ def main (): merge_gis = args.merge_gis if args.hres_flag: hires_pft = 'on' - else: + else: hires_pft = 'off' + verbose = args.verbose hostname = os.getenv("HOSTNAME") - print (f"hostname is {hostname}") logname = os.getenv("LOGNAME") - print (f"logname is {logname}") + if args.verbose: + print (f"hostname is {hostname}") + print (f"logname is {logname}") + + if ssp_rcp == 'none': + if int(start_year) > 2015: + print(f"ERROR: if start-year is > 2015 must specify and SSP_RCP argument that is not 'none") + sys.exit(10) + elif int(end_year) > 2015: + print(f"ERROR: if end-year is > 2015 must specify and SSP_RCP argument that is not 'none") + sys.exit(10) + + pft_years_ssp = "-999" # determine pft_years - needed to parse xml file if int(start_year) == 1850 and int(end_year) == 1850: @@ -220,27 +237,41 @@ def main (): pft_years = "2005" elif int(start_year) >= 850 and int(end_year) <= 1849: pft_years = "0850-1849" - elif int(start_year) >= 1850 and int(start_year) <= 2100 and int(end_year) <= 2005: + elif int(start_year) >= 1850 and int(start_year) <= 2100 and int(end_year) <= 2015: pft_years = "1850-2015" + elif int(start_year) >= 1850 and int(start_year) <= 2100 and int(end_year) <= 2100: + pft_years = "1850-2015" + pft_years_ssp = "2016-2100" elif int(start_year) >= 2016 and int(start_year) <= 2100 and int(end_year) <=2100: - pft_years = "2016-2100" + pft_years = "-999" + pft_years_ssp = "2016-2100" elif potveg: pft_years = "PtVg" else: print (f"start_year is {start_year} and end_year is {end_year}") print (f"ERROR: start and end years should be between 850 and 2105 or pot_veg flag needs to be set") - sys.exit() + sys.exit(10) + + if verbose: + print (f"pft_years = {pft_years}") + + # Create land-use txt file for a transient case. + # Determine the run type and if a transient run create output landuse txt file + if end_year > start_year: + run_type = "transient" + else: + run_type = "timeslice" + if verbose: + print(f"run_type = {run_type}") # error check on glc_nec if (glc_nec <= 0) or (glc_nec >= 100): raise argparse.ArgumentTypeError("ERROR: glc_nec must be between 1 and 99.") - # if args.debug: - # logging.basicConfig(level=logging.DEBUG) - # create attribute list for parsing xml file attribute_list = {'hires_pft':hires_pft, 'pft_years':pft_years, + 'pft_years_ssp':pft_years_ssp, 'ssp_rcp':ssp_rcp, 'mergeGIS':merge_gis, 'res':res} @@ -267,30 +298,41 @@ def main (): elif childval is not None: num_match = -1 break - if num_match > max_match_num: + if num_match > max_match_num: max_match_num = num_match max_match_child = child2 if max_match_child is None: - print (f"{child1.tag} has no matches") - raise "ERROR" + # For years greater than 2015 - mksrf_fvegtyp_ssp must have a match + if start_year <= 2015: + if 'mksrf_fvegtyp_ssp' not in child1.tag: + print (f"ERROR: {child1.tag} has no matches") + sys.exit(15) + else: + continue + else: + # For years less than 2015 - mksrf_fvegtyp must have a match + if 'mksrf_fvegtyp' not in child1.tag: + print (f"ERROR: {child1.tag} has no matches") + sys.exit(15) + else: + continue for item in max_match_child: - if item.tag == 'data_filename': + if item.tag == 'data_filename': rawdata_files[child1.tag] = os.path.join(input_path, item.text) - if '%y' in rawdata_files[child1.tag]: - # ERROR: keep %y here and do the replacement later + if '%y' in rawdata_files[child1.tag] and run_type == 'timeslice': rawdata_files[child1.tag] = rawdata_files[child1.tag].replace("%y",str(start_year)) - if not os.path.isfile(rawdata_files[child1.tag]): - print(f"ERROR: intput rawdata file {rawdata_files[child1.tag]} does not exist") - sys.exit() + if not os.path.isfile(rawdata_files[child1.tag]): + print(f"ERROR: intput rawdata file {rawdata_files[child1.tag]} does not exist") + sys.exit(20) if item.tag == 'mesh_filename': new_key = f"{child1.tag}_mesh" rawdata_files[new_key] = os.path.join(input_path, item.text) if not os.path.isfile(rawdata_files[new_key]): print(f"ERROR: mesh file {rawdata_files[new_key]} does not exist") - sys.exit() + sys.exit(30) # determine output mesh tree2 = ET.parse('../../ccs_config/component_grids_nuopc.xml') @@ -315,38 +357,44 @@ def main (): for name, value in child1.attrib.items(): valid_grids.append(value) print (f"valid grid values are {valid_grids}") - sys.exit() + sys.exit(40) # Determine num_pft if nocrop_flag: num_pft = "16" else: num_pft = "78" - print(f"num_pft is {num_pft}") + if verbose: + print (f"num_pft is {num_pft}") # Write out if surface dataset will be created - if nosurfdata_flag: - print(f"surface dataset will not be created") - else: - print(f"surface dataset will be created") + if verbose: + if nosurfdata_flag: + print(f"surface dataset will not be created") + else: + print(f"surface dataset will be created") - # Create land-use txt file for a transient case. - # Determine the run type and if a transient run create output landuse txt file - if end_year > start_year: - run_type = "transient" - else: - run_type = "timeslice" - print(f"run_type = {run_type}") if run_type == 'transient': - landuse_fname = f"transient_timeseries_hist_{num_pft}pfts_simyr{start_year}-{end_year}.txt" + if ssp_rcp == 'none': + landuse_fname = f"landuse_timeseries_hist_{num_pft}pfts_simyr{start_year}-{end_year}.txt" + else: + landuse_fname = f"landuse_timeseries_{ssp_rcp}_{num_pft}pfts_CMIP6_simyr{start_year}-{end_year}.txt" + with open(landuse_fname, "w", encoding='utf-8') as landuse_file: for year in range(start_year, end_year + 1): - file1 = rawdata_files["mksrf_fvegtyp"] - landuse_input_fname = file1.replace("%y",str(start_year)) - if not os.path.isfile(landuse_input_fname): - logger.warning(f"landunit_input_fname: {landuse_input_fname}") + if year <= 2015: + file1 = rawdata_files["mksrf_fvegtyp"] + else: + file1 = rawdata_files["mksrf_fvegtyp_ssp"] + + landuse_input_fname = file1.replace("%y",str(year)) + # if not os.path.isfile(landuse_input_fname): + # TODO: turn on this error once the new cdf5 data is available + # print(f"ERROR: landunit_input_fname: {landuse_input_fname} does not exit") + # sys.exit(60) + + # -- Each line is written twice in the original perl code: landuse_line = f"{landuse_input_fname:<196}{str(year)}\n" - # -- Each line is written twice in the original pl code: landuse_file.write(landuse_line) landuse_file.write(landuse_line) logger.debug(f"year : {year}") @@ -376,7 +424,8 @@ def main (): # from 1km to the following two resolutions since the output mesh has so few points if res == "10x15": mksrf_ftopostats_override = os.path.join(input_path,"lnd","clm2","rawdata","surfdata_topo_10x15_c220303.nc") - print (f"will override mksrf_ftopostats with = {mksrf_ftopostats_override}") + if args.verbose: + print (f"will override mksrf_ftopostats with = {mksrf_ftopostats_override}") else: mksrf_ftopostats_override = "" @@ -388,20 +437,31 @@ def main (): with open(nlfname, "w",encoding='utf-8') as nlfile: nlfile.write("&mksurfdata_input \n") + # ------------------- # raw input data + # ------------------- for key,value in rawdata_files.items(): - if key == 'mksrf_fgrid_mesh_nx' or key == 'mksrf_fgrid_mesh_ny': - nlfile.write(f" {key} = {value} \n") - elif key != "mksrf_fvic" and key != "mksrf_fvic_mesh": - nlfile.write(f" {key} = \'{value}\' \n") if key == 'mksrf_ftopostats' and mksrf_ftopostats_override != '': nlfile.write(f" mksrf_ftopostats_override = \'{mksrf_ftopostats_override}\' \n") + elif '_fvic not in key' and 'fvegtyp' not in key: + # write everything else + nlfile.write(f" {key} = \'{value}\' \n") - mksrf_hrvtyp = rawdata_files["mksrf_fvegtyp"] - nlfile.write( f" mksrf_fhrvtyp = \'{mksrf_hrvtyp}\' \n") + if start_year <= 2015: + mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp"] + mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] + mksrf_fhrvtyp = rawdata_files["mksrf_fvegtyp"] + mksrf_fhrvtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] + else: + mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp_ssp"] + mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] + mksrf_fhrvtyp = rawdata_files["mksrf_fvegtyp_ssp"] + mksrf_fhrvtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] - mksrf_hrvtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] - nlfile.write( f" mksrf_fhrvtyp_mesh = \'{mksrf_hrvtyp_mesh}\' \n") + nlfile.write( f" mksrf_fvegtyp = \'{mksrf_fvegtyp}\' \n") + nlfile.write( f" mksrf_fvegtyp_mesh = \'{mksrf_fvegtyp_mesh}\' \n") + nlfile.write( f" mksrf_fhrvtyp = \'{mksrf_fhrvtyp}\' \n") + nlfile.write( f" mksrf_fhrvtyp_mesh = \'{mksrf_fhrvtyp_mesh}\' \n") if vic_flag: mksrf_fvic = rawdata_files["mksrf_fvic"] @@ -411,7 +471,9 @@ def main (): nlfile.write( f" mksrf_fdynuse = \'{landuse_fname} \' \n") + # ------------------- # output data files + # ------------------- if nosurfdata_flag: nlfile.write(f" fsurdat = \' \' \n") else: @@ -419,7 +481,9 @@ def main (): nlfile.write(f" fsurlog = \'{fsurlog}\' \n") nlfile.write(f" fdyndat = \'{fdyndat}\' \n") + # ------------------- # output data logicals + # ------------------- nlfile.write(f" numpft = {num_pft} \n") nlfile.write( " no_inlandwet = .true. \n") if glc_flag: @@ -437,6 +501,7 @@ def main (): nlfile.write(f" gitdescribe = \'{gitdescribe}\' \n") nlfile.write("/ \n") + sys.exit(0) if __name__ == "__main__": main() diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 1f308b32ce..3af6cf5f0f 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -255,38 +255,44 @@ version of the raw dataset will probably go away. lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - - - + + + + + + + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_%y.c181217.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_%y.c181217.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_%y.c181217.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_%y.c181217.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_%y.c181217.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_%y.c171005.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - + + diff --git a/tools/mksurfdata_map/landuse_timeseries_hist_78pfts_simyr1850-2015.txt b/tools/mksurfdata_map/landuse_timeseries_hist_78pfts_simyr1850-2015.txt deleted file mode 100644 index 3c622f3965..0000000000 --- a/tools/mksurfdata_map/landuse_timeseries_hist_78pfts_simyr1850-2015.txt +++ /dev/null @@ -1,332 +0,0 @@ -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1850.c170412.nc 1850 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1850.c170412.nc 1850 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1851.c170412.nc 1851 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1851.c170412.nc 1851 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1852.c170412.nc 1852 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1852.c170412.nc 1852 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1853.c170412.nc 1853 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1853.c170412.nc 1853 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1854.c170412.nc 1854 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1854.c170412.nc 1854 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1855.c170412.nc 1855 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1855.c170412.nc 1855 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1856.c170412.nc 1856 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1856.c170412.nc 1856 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1857.c170412.nc 1857 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1857.c170412.nc 1857 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1858.c170412.nc 1858 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1858.c170412.nc 1858 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1859.c170412.nc 1859 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1859.c170412.nc 1859 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1860.c170412.nc 1860 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1860.c170412.nc 1860 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1861.c170412.nc 1861 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1861.c170412.nc 1861 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1862.c170412.nc 1862 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1862.c170412.nc 1862 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1863.c170412.nc 1863 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1863.c170412.nc 1863 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1864.c170412.nc 1864 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1864.c170412.nc 1864 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1865.c170412.nc 1865 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1865.c170412.nc 1865 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1866.c170412.nc 1866 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1866.c170412.nc 1866 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1867.c170412.nc 1867 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1867.c170412.nc 1867 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1868.c170412.nc 1868 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1868.c170412.nc 1868 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1869.c170412.nc 1869 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1869.c170412.nc 1869 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1870.c170412.nc 1870 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1870.c170412.nc 1870 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1871.c170412.nc 1871 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1871.c170412.nc 1871 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1872.c170412.nc 1872 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1872.c170412.nc 1872 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1873.c170412.nc 1873 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1873.c170412.nc 1873 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1874.c170412.nc 1874 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1874.c170412.nc 1874 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1875.c170412.nc 1875 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1875.c170412.nc 1875 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1876.c170412.nc 1876 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1876.c170412.nc 1876 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1877.c170412.nc 1877 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1877.c170412.nc 1877 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1878.c170412.nc 1878 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1878.c170412.nc 1878 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1879.c170412.nc 1879 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1879.c170412.nc 1879 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1880.c170412.nc 1880 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1880.c170412.nc 1880 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1881.c170412.nc 1881 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1881.c170412.nc 1881 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1882.c170412.nc 1882 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1882.c170412.nc 1882 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1883.c170412.nc 1883 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1883.c170412.nc 1883 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1884.c170412.nc 1884 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1884.c170412.nc 1884 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1885.c170412.nc 1885 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1885.c170412.nc 1885 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1886.c170412.nc 1886 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1886.c170412.nc 1886 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1887.c170412.nc 1887 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1887.c170412.nc 1887 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1888.c170412.nc 1888 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1888.c170412.nc 1888 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1889.c170412.nc 1889 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1889.c170412.nc 1889 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1890.c170412.nc 1890 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1890.c170412.nc 1890 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1891.c170412.nc 1891 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1891.c170412.nc 1891 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1892.c170412.nc 1892 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1892.c170412.nc 1892 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1893.c170412.nc 1893 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1893.c170412.nc 1893 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1894.c170412.nc 1894 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1894.c170412.nc 1894 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1895.c170412.nc 1895 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1895.c170412.nc 1895 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1896.c170412.nc 1896 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1896.c170412.nc 1896 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1897.c170412.nc 1897 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1897.c170412.nc 1897 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1898.c170412.nc 1898 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1898.c170412.nc 1898 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1899.c170412.nc 1899 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1899.c170412.nc 1899 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1900.c170412.nc 1900 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1900.c170412.nc 1900 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1901.c170412.nc 1901 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1901.c170412.nc 1901 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1902.c170412.nc 1902 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1902.c170412.nc 1902 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1903.c170412.nc 1903 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1903.c170412.nc 1903 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1904.c170412.nc 1904 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1904.c170412.nc 1904 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1905.c170412.nc 1905 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1905.c170412.nc 1905 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1906.c170412.nc 1906 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1906.c170412.nc 1906 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1907.c170412.nc 1907 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1907.c170412.nc 1907 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1908.c170412.nc 1908 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1908.c170412.nc 1908 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1909.c170412.nc 1909 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1909.c170412.nc 1909 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1910.c170412.nc 1910 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1910.c170412.nc 1910 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1911.c170412.nc 1911 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1911.c170412.nc 1911 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1912.c170412.nc 1912 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1912.c170412.nc 1912 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1913.c170412.nc 1913 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1913.c170412.nc 1913 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1914.c170412.nc 1914 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1914.c170412.nc 1914 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1915.c170412.nc 1915 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1915.c170412.nc 1915 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1916.c170412.nc 1916 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1916.c170412.nc 1916 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1917.c170412.nc 1917 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1917.c170412.nc 1917 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1918.c170412.nc 1918 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1918.c170412.nc 1918 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1919.c170412.nc 1919 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1919.c170412.nc 1919 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1920.c170412.nc 1920 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1920.c170412.nc 1920 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1921.c170412.nc 1921 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1921.c170412.nc 1921 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1922.c170412.nc 1922 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1922.c170412.nc 1922 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1923.c170412.nc 1923 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1923.c170412.nc 1923 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1924.c170412.nc 1924 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1924.c170412.nc 1924 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1925.c170412.nc 1925 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1925.c170412.nc 1925 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1926.c170412.nc 1926 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1926.c170412.nc 1926 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1927.c170412.nc 1927 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1927.c170412.nc 1927 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1928.c170412.nc 1928 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1928.c170412.nc 1928 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1929.c170412.nc 1929 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1929.c170412.nc 1929 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1930.c170412.nc 1930 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1930.c170412.nc 1930 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1931.c170412.nc 1931 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1931.c170412.nc 1931 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1932.c170412.nc 1932 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1932.c170412.nc 1932 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1933.c170412.nc 1933 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1933.c170412.nc 1933 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1934.c170412.nc 1934 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1934.c170412.nc 1934 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1935.c170412.nc 1935 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1935.c170412.nc 1935 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1936.c170412.nc 1936 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1936.c170412.nc 1936 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1937.c170412.nc 1937 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1937.c170412.nc 1937 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1938.c170412.nc 1938 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1938.c170412.nc 1938 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1939.c170412.nc 1939 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1939.c170412.nc 1939 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1940.c170412.nc 1940 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1940.c170412.nc 1940 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1941.c170412.nc 1941 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1941.c170412.nc 1941 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1942.c170412.nc 1942 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1942.c170412.nc 1942 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1943.c170412.nc 1943 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1943.c170412.nc 1943 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1944.c170412.nc 1944 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1944.c170412.nc 1944 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1945.c170412.nc 1945 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1945.c170412.nc 1945 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1946.c170412.nc 1946 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1946.c170412.nc 1946 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1947.c170412.nc 1947 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1947.c170412.nc 1947 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1948.c170412.nc 1948 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1948.c170412.nc 1948 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1949.c170412.nc 1949 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1949.c170412.nc 1949 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1950.c170412.nc 1950 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1950.c170412.nc 1950 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1951.c170412.nc 1951 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1951.c170412.nc 1951 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1952.c170412.nc 1952 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1952.c170412.nc 1952 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1953.c170412.nc 1953 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1953.c170412.nc 1953 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1954.c170412.nc 1954 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1954.c170412.nc 1954 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1955.c170412.nc 1955 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1955.c170412.nc 1955 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1956.c170412.nc 1956 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1956.c170412.nc 1956 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1957.c170412.nc 1957 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1957.c170412.nc 1957 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1958.c170412.nc 1958 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1958.c170412.nc 1958 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1959.c170412.nc 1959 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1959.c170412.nc 1959 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1960.c170412.nc 1960 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1960.c170412.nc 1960 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1961.c170412.nc 1961 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1961.c170412.nc 1961 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1962.c170412.nc 1962 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1962.c170412.nc 1962 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1963.c170412.nc 1963 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1963.c170412.nc 1963 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1964.c170412.nc 1964 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1964.c170412.nc 1964 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1965.c170412.nc 1965 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1965.c170412.nc 1965 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1966.c170412.nc 1966 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1966.c170412.nc 1966 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1967.c170412.nc 1967 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1967.c170412.nc 1967 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1968.c170412.nc 1968 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1968.c170412.nc 1968 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1969.c170412.nc 1969 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1969.c170412.nc 1969 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1970.c170412.nc 1970 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1970.c170412.nc 1970 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1971.c170412.nc 1971 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1971.c170412.nc 1971 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1972.c170412.nc 1972 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1972.c170412.nc 1972 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1973.c170412.nc 1973 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1973.c170412.nc 1973 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1974.c170412.nc 1974 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1974.c170412.nc 1974 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1975.c170412.nc 1975 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1975.c170412.nc 1975 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1976.c170412.nc 1976 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1976.c170412.nc 1976 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1977.c170412.nc 1977 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1977.c170412.nc 1977 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1978.c170412.nc 1978 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1978.c170412.nc 1978 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1979.c170412.nc 1979 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1979.c170412.nc 1979 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1980.c170412.nc 1980 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1980.c170412.nc 1980 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1981.c170412.nc 1981 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1981.c170412.nc 1981 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1982.c170412.nc 1982 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1982.c170412.nc 1982 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1983.c170412.nc 1983 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1983.c170412.nc 1983 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1984.c170412.nc 1984 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1984.c170412.nc 1984 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1985.c170412.nc 1985 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1985.c170412.nc 1985 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1986.c170412.nc 1986 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1986.c170412.nc 1986 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1987.c170412.nc 1987 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1987.c170412.nc 1987 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1988.c170412.nc 1988 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1988.c170412.nc 1988 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1989.c170412.nc 1989 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1989.c170412.nc 1989 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1990.c170412.nc 1990 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1990.c170412.nc 1990 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1991.c170412.nc 1991 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1991.c170412.nc 1991 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1992.c170412.nc 1992 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1992.c170412.nc 1992 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1993.c170412.nc 1993 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1993.c170412.nc 1993 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1994.c170412.nc 1994 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1994.c170412.nc 1994 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1995.c170412.nc 1995 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1995.c170412.nc 1995 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1996.c170412.nc 1996 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1996.c170412.nc 1996 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1997.c170412.nc 1997 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1997.c170412.nc 1997 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1998.c170412.nc 1998 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1998.c170412.nc 1998 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1999.c170412.nc 1999 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_1999.c170412.nc 1999 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2000.c170412.nc 2000 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2000.c170412.nc 2000 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2001.c170412.nc 2001 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2001.c170412.nc 2001 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2002.c170412.nc 2002 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2002.c170412.nc 2002 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2003.c170412.nc 2003 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2003.c170412.nc 2003 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2004.c170412.nc 2004 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2004.c170412.nc 2004 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2005.c170412.nc 2005 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2005.c170412.nc 2005 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2006.c170412.nc 2006 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2006.c170412.nc 2006 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2007.c170412.nc 2007 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2007.c170412.nc 2007 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2008.c170412.nc 2008 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2008.c170412.nc 2008 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2009.c170412.nc 2009 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2009.c170412.nc 2009 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2010.c170412.nc 2010 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2010.c170412.nc 2010 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2011.c170412.nc 2011 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2011.c170412.nc 2011 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2012.c170412.nc 2012 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2012.c170412.nc 2012 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2013.c170412.nc 2013 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2013.c170412.nc 2013 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2014.c170412.nc 2014 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2014.c170412.nc 2014 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2015.c170412.nc 2015 -/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2015.c170412.nc 2015 From 2647ec48a31d1f8dce6a047817ef8d8fb38eeca1 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 6 Mar 2022 19:24:27 -0700 Subject: [PATCH 093/614] more bug fixes --- .../gen_mksurfdata_jobscript.py | 18 ++-- .../gen_mksurfdata_namelist.py | 82 +++++++++++++++---- .../gen_mksurfdata_namelist.xml | 13 ++- 3 files changed, 83 insertions(+), 30 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript.py index 824a779e89..27425b815b 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript.py @@ -124,8 +124,6 @@ def main (): else: target_list = [scenario] - print (f"DEBUG: target_list is {target_list}") - # -------------------------- # Determine resolution sets that are referenced in commands # -------------------------- @@ -159,14 +157,14 @@ def main (): "crop-global-historical-ne120np4" : ("--start-year 1850 --end-year 1850 --ssp-rcp SSP5-8.5 --res", "ne120np4_res"), "crop-global-transient" : ("--start-year 1850 --end-year 2000 --nosurfdata --res", "trans_res"), "crop-global-transient-ne120np4" : ("--start-year 1850 --end-year 2000 --nosurfdata --res", "ne120np4_res"), - "crop-global-SSP1-2.6" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-2.6 --res", "future_res"), - "crop-global-SSP3-7.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-7.0 --res", "future_res"), - "crop-global-SSP5-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-3.4 --res", "future_res"), - "crop-global-SSP2-4.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-4.5 --res", "future_res"), "crop-global-SSP1-1.9" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-1.9 --res", "future_res"), - "crop-global-SSP4-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-3.4 --res", "future_res"), - "crop-global-SSP4-6.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-6.0 --res", "future_res"), - "crop-global-SSP5-8.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-8.5 --res", "future_res") + "crop-global-SSP1-2.6" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-2.6 --res", "future_res"), + "crop-global-SSP2-4.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", "future_res"), + "crop-global-SSP3-7.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP3-7.0 --res", "future_res"), + "crop-global-SSP4-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-3.4 --res", "future_res"), + "crop-global-SSP4-6.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-6.0 --res", "future_res"), + "crop-global-SSP5-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-3.4 --res", "future_res"), + "crop-global-SSP5-8.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-8.5 --res", "future_res") } # -------------------------- @@ -177,8 +175,6 @@ def main (): np = int(mpi_tasks) tasks_per_node = 12 nodes = int(np / tasks_per_node) - print (f"DEBUG: number of nodes is {nodes}") - print (f"DEBUG: number of tasks is {np}") runfile.write('#!/bin/bash') runfile.write('#PBS -A P93300606 \n') diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 6ba0b9b66f..6b11008044 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -59,6 +59,39 @@ def get_parser(): required=False, default="4x5", ) + parser.add_argument( + "--model-mesh", + help=""" + model mesh [default: %(default)s] + Ignore the --res option and force the model mesh file to be this input + """, + action="store", + dest="force_model_mesh_file", + required=False, + default="none", + ) + parser.add_argument( + "--model-mesh-nx", + help=""" + model mesh [default: %(default)s] + Ignore the --res option and force the model mesh to have this nx + """, + action="store", + dest="force_model_mesh_nx", + required=False, + default="-999", + ) + parser.add_argument( + "--model-mesh-ny", + help=""" + model mesh [default: %(default)s] + Ignore the --res option and force the model mesh to have this ny + """, + action="store", + dest="force_model_mesh_ny", + required=False, + default="-999", + ) parser.add_argument( "--glc-nec", help=""" @@ -196,8 +229,11 @@ def main (): start_year = args.start_year end_year = args.end_year - res = args.res ssp_rcp = args.ssp_rcp + res = args.res + force_model_mesh_file = args.force_model_mesh_file + force_model_mesh_nx = args.force_model_mesh_nx + force_model_mesh_ny = args.force_model_mesh_ny input_path = args.input_path nocrop_flag = args.crop_flag nosurfdata_flag = args.surfdata_flag @@ -212,6 +248,9 @@ def main (): hires_pft = 'off' verbose = args.verbose + if force_model_mesh_file != 'none': + res = force_model_mesh_nx + 'x' + force_model_mesh_ny + hostname = os.getenv("HOSTNAME") logname = os.getenv("LOGNAME") if args.verbose: @@ -350,7 +389,7 @@ def main (): if child2.tag == 'ny': rawdata_files["mksrf_fgrid_mesh_ny"] = child2.text - if len(model_mesh) == 0: + if force_model_mesh_file == 'none' and len(model_mesh) == 0: print (f"ERROR: input res {res} is invalid") valid_grids = [] for child1 in root: # this is domain tag @@ -405,16 +444,18 @@ def main (): landuse_fname = "" time_stamp = datetime.today().strftime("%y%m%d") + if ssp_rcp == 'none': + ssp_rcp_name = 'hist' if int(end_year) == int(start_year): - nlfname = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.namelist" - fsurdat = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.nc" - fsurlog = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.log" + nlfname = f"surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.namelist" + fsurdat = f"surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.nc" + fsurlog = f"surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.log" fdyndat = "" else: - nlfname = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.namelist" - fsurdat = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.nc" - fsurlog = f"surfdata_{res}_{ssp_rcp}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.log" - fdyndat = f"landuse.timeseries_{res}_{ssp_rcp}_{num_pft}_CMIP6_{start_year}-{end_year}_c{time_stamp}.nc" + nlfname = f"surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.namelist" + fsurdat = f"surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.nc" + fsurlog = f"surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.log" + fdyndat = f"landuse.timeseries_{res}_{ssp_rcp_name}_{num_pft}_CMIP6_{start_year}-{end_year}_c{time_stamp}.nc" gitdescribe = subprocess.check_output('git describe', shell=True).strip() gitdescribe = gitdescribe.decode('utf-8') @@ -443,21 +484,32 @@ def main (): for key,value in rawdata_files.items(): if key == 'mksrf_ftopostats' and mksrf_ftopostats_override != '': nlfile.write(f" mksrf_ftopostats_override = \'{mksrf_ftopostats_override}\' \n") - elif '_fvic not in key' and 'fvegtyp' not in key: + elif '_fvic not in key' and 'fvegtyp' and 'fgrid_mesh' not in key: # write everything else nlfile.write(f" {key} = \'{value}\' \n") + if force_model_mesh_file != 'none': + mksrf_fgrid_mesh = force_model_mesh_file + mksrf_fgrid_nx = force_model_mesh_nx + mksrf_fgrid_ny = force_model_mesh_ny + else: + mksrf_fgrid_mesh = rawdata_files["mksrf_fgrid_mesh"] + mksrf_fgrid_nx = rawdata_files["mksrf_fgrid_mesh_nx"] + mksrf_fgrid_ny = rawdata_files["mksrf_fgrid_mesh_ny"] + nlfile.write( f" mksrf_fgrid_mesh =\'{mksrf_fgrid_mesh}\' \n") + nlfile.write( f" mksrf_fgrid_nx ={mksrf_fgrid_nx} \n") + nlfile.write( f" mksrf_fgrid_ny ={mksrf_fgrid_ny} \n") + if start_year <= 2015: - mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp"] - mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] + mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp"] + mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] mksrf_fhrvtyp = rawdata_files["mksrf_fvegtyp"] mksrf_fhrvtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] else: - mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp_ssp"] - mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] + mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp_ssp"] + mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] mksrf_fhrvtyp = rawdata_files["mksrf_fvegtyp_ssp"] mksrf_fhrvtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] - nlfile.write( f" mksrf_fvegtyp = \'{mksrf_fvegtyp}\' \n") nlfile.write( f" mksrf_fvegtyp_mesh = \'{mksrf_fvegtyp_mesh}\' \n") nlfile.write( f" mksrf_fhrvtyp = \'{mksrf_fhrvtyp}\' \n") diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 3af6cf5f0f..adf088949f 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -259,21 +259,26 @@ version of the raw dataset will probably go away. - + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_%y.c181217.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_%y.c181217.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_%y.c181217.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - - - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_%y.c181217.nc + + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_%y.c181217.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc From c36cad4e70af0674a6f3d2d6314cf32fedafa409 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 6 Mar 2022 21:03:18 -0700 Subject: [PATCH 094/614] introduced new force_model_mesh_file --- .../gen_mksurfdata_namelist.py | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 6b11008044..0a6910e3fc 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -363,7 +363,7 @@ def main (): if '%y' in rawdata_files[child1.tag] and run_type == 'timeslice': rawdata_files[child1.tag] = rawdata_files[child1.tag].replace("%y",str(start_year)) if not os.path.isfile(rawdata_files[child1.tag]): - print(f"ERROR: intput rawdata file {rawdata_files[child1.tag]} does not exist") + print(f"ERROR: intput rawdata file {rawdata_files[child1.tag]} for {child1.tag} does not exist") sys.exit(20) if item.tag == 'mesh_filename': @@ -481,25 +481,25 @@ def main (): # ------------------- # raw input data # ------------------- + if force_model_mesh_file != 'none': + mksrf_fgrid_mesh_nx = force_model_mesh_nx + mksrf_fgrid_mesh_ny = force_model_mesh_ny + mksrf_fgrid_mesh = force_model_mesh_file + else: + mksrf_fgrid_mesh_nx = rawdata_files["mksrf_fgrid_mesh_nx"] + mksrf_fgrid_mesh_ny = rawdata_files["mksrf_fgrid_mesh_ny"] + mksrf_fgrid_mesh = rawdata_files["mksrf_fgrid_mesh"] + nlfile.write( f" mksrf_fgrid_mesh = \'{mksrf_fgrid_mesh}\' \n") + nlfile.write( f" mksrf_fgrid_mesh_nx = {mksrf_fgrid_mesh_nx} \n") + nlfile.write( f" mksrf_fgrid_mesh_ny = {mksrf_fgrid_mesh_ny} \n") + for key,value in rawdata_files.items(): if key == 'mksrf_ftopostats' and mksrf_ftopostats_override != '': nlfile.write(f" mksrf_ftopostats_override = \'{mksrf_ftopostats_override}\' \n") - elif '_fvic not in key' and 'fvegtyp' and 'fgrid_mesh' not in key: + elif '_fvic' not in key and 'mksrf_fvegtyp' not in key and 'mksrf_fgrid' not in key: # write everything else nlfile.write(f" {key} = \'{value}\' \n") - if force_model_mesh_file != 'none': - mksrf_fgrid_mesh = force_model_mesh_file - mksrf_fgrid_nx = force_model_mesh_nx - mksrf_fgrid_ny = force_model_mesh_ny - else: - mksrf_fgrid_mesh = rawdata_files["mksrf_fgrid_mesh"] - mksrf_fgrid_nx = rawdata_files["mksrf_fgrid_mesh_nx"] - mksrf_fgrid_ny = rawdata_files["mksrf_fgrid_mesh_ny"] - nlfile.write( f" mksrf_fgrid_mesh =\'{mksrf_fgrid_mesh}\' \n") - nlfile.write( f" mksrf_fgrid_nx ={mksrf_fgrid_nx} \n") - nlfile.write( f" mksrf_fgrid_ny ={mksrf_fgrid_ny} \n") - if start_year <= 2015: mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp"] mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] From e69e46a3eb8d6fa50340f4a70554cb1a15280c63 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 7 Mar 2022 11:50:46 -0700 Subject: [PATCH 095/614] fixed problem with %y parsing --- .../gen_mksurfdata_namelist.py | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 0a6910e3fc..5e0a39b93a 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -259,10 +259,12 @@ def main (): if ssp_rcp == 'none': if int(start_year) > 2015: - print(f"ERROR: if start-year is > 2015 must specify and SSP_RCP argument that is not 'none") + print(f"ERROR: if start-year is > 2015 must add an --ssp_rcp argument that is not 'none") + print(f" valid opts for ssp-rcp are {valid_opts}") sys.exit(10) elif int(end_year) > 2015: - print(f"ERROR: if end-year is > 2015 must specify and SSP_RCP argument that is not 'none") + print(f"ERROR: if end-year is > 2015 must add an --ssp-rcp argument that is not 'none") + print(f" valid opts for ssp-rcp are {valid_opts}") sys.exit(10) pft_years_ssp = "-999" @@ -360,17 +362,16 @@ def main (): for item in max_match_child: if item.tag == 'data_filename': rawdata_files[child1.tag] = os.path.join(input_path, item.text) - if '%y' in rawdata_files[child1.tag] and run_type == 'timeslice': - rawdata_files[child1.tag] = rawdata_files[child1.tag].replace("%y",str(start_year)) + if '%y' not in rawdata_files[child1.tag]: if not os.path.isfile(rawdata_files[child1.tag]): - print(f"ERROR: intput rawdata file {rawdata_files[child1.tag]} for {child1.tag} does not exist") + print(f"ERROR: input data file {rawdata_files[child1.tag]} for {child1.tag} does not exist") sys.exit(20) if item.tag == 'mesh_filename': new_key = f"{child1.tag}_mesh" rawdata_files[new_key] = os.path.join(input_path, item.text) if not os.path.isfile(rawdata_files[new_key]): - print(f"ERROR: mesh file {rawdata_files[new_key]} does not exist") + print(f"ERROR: input mesh file {rawdata_files[new_key]} does not exist") sys.exit(30) # determine output mesh @@ -438,14 +439,15 @@ def main (): landuse_file.write(landuse_line) logger.debug(f"year : {year}") logger.debug(landuse_line) - logger.info("Successfully created land use file : {landuse_fname}.") - logger.info("-------------------------------------------------------") + print(f"Successfully created input landuse file {landuse_fname}") else: landuse_fname = "" time_stamp = datetime.today().strftime("%y%m%d") if ssp_rcp == 'none': ssp_rcp_name = 'hist' + else: + ssp_rcp_name = ssp_rcp if int(end_year) == int(start_year): nlfname = f"surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.namelist" fsurdat = f"surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.nc" @@ -474,7 +476,6 @@ def main (): # Write output namelist file # ---------------------------------------- - print (f"Creating input namelist file {nlfname}") with open(nlfname, "w",encoding='utf-8') as nlfile: nlfile.write("&mksurfdata_input \n") @@ -510,6 +511,16 @@ def main (): mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] mksrf_fhrvtyp = rawdata_files["mksrf_fvegtyp_ssp"] mksrf_fhrvtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] + if '%y' in mksrf_fvegtyp: + mksrf_fvegtyp = mksrf_fvegtyp.replace("%y",str(start_year)) + if '%y' in mksrf_fhrvtyp: + mksrf_fhrvtyp = mksrf_fhrvtyp.replace("%y",str(start_year)) + if not os.path.isfile(mksrf_fvegtyp): + print(f"ERROR: input mksrf_fvegtyp file {mksrf_fvegtyp} does not exist") + sys.exit(20) + if not os.path.isfile(mksrf_fhrvtyp): + print(f"ERROR: input mksrf_fhrvtyp file {mksrf_fhrvtyp} does not exist") + sys.exit(20) nlfile.write( f" mksrf_fvegtyp = \'{mksrf_fvegtyp}\' \n") nlfile.write( f" mksrf_fvegtyp_mesh = \'{mksrf_fvegtyp_mesh}\' \n") nlfile.write( f" mksrf_fhrvtyp = \'{mksrf_fhrvtyp}\' \n") @@ -553,7 +564,9 @@ def main (): nlfile.write(f" gitdescribe = \'{gitdescribe}\' \n") nlfile.write("/ \n") - sys.exit(0) + + print (f"Successfully created input namelist file {nlfname}") + sys.exit(0) if __name__ == "__main__": main() From c8dc1160cedc9657c3189df62fbbf7e9e7a59432 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 7 Mar 2022 22:43:55 -0700 Subject: [PATCH 096/614] updates for single and multi jobscript creations --- tools/mksurfdata_esmf/README | 37 +++++-- tools/mksurfdata_esmf/gen_mksurfdata | 25 ----- ...t.py => gen_mksurfdata_jobscript_multi.py} | 45 ++++++-- .../gen_mksurfdata_jobscript_single.py | 104 ++++++++++++++++++ .../gen_mksurfdata_namelist.py | 7 +- .../gen_mksurfdata_namelist.xml | 18 ++- tools/mksurfdata_esmf/src/mkfileMod.F90 | 14 +-- tools/mksurfdata_esmf/src/mkinputMod.F90 | 7 +- tools/mksurfdata_esmf/src/mkpftMod.F90 | 16 ++- tools/mksurfdata_esmf/src/mksurfdata.F90 | 5 +- 10 files changed, 199 insertions(+), 79 deletions(-) delete mode 100755 tools/mksurfdata_esmf/gen_mksurfdata rename tools/mksurfdata_esmf/{gen_mksurfdata_jobscript.py => gen_mksurfdata_jobscript_multi.py} (88%) create mode 100755 tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index edd3e976fa..dad4956acd 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -34,15 +34,29 @@ building the executable > make clean # REMEMBER to be in bash > make VERBOSE=1 -======= -running -======= +======================= +running for a single submission: +======================= +> cd ../ +> run ./gen_mksurfdata_namelist.py to generate your target namelist (call it foo.namelist here) +> run ./gen_mksurfdata_jobscript_single.py --help to see commands - as an example +> run ./gen_mksurfdata_jobscript_single.py --mpi-tasks 768 --namelist-file foo.namelist +> qsub mksurfdata_jobscript + +======================= +running for the generation of multiple datasets +======================= > cd ../ -# Edit gen_mksurfdata to generate a single surface dataset that you want -> qsub gen_mksurfdata # OR qsub gen_mksurfdata_all ...to generate all the surface datasets +Note that gen_mksurfdata_jobscript_multi.py runs ./gen_mksurfdata_namelist.py +> run ./gen_mksurfdata_jobscript_multi.py --help to see commands - as an example +> run ./gen_mksurfdata_jobscript_multi.py --mpi-tasks 768 --namelist-file foo.namelist +> run ./gen_mksurfdata_jobscript_multi.py --mpi-tasks 768 --scenario all +> qsub mksurfdata_jobscript ------ +================ NOTES +================ + ------------------------------------------------------------ slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED ------------------------------------------------------------ @@ -55,9 +69,9 @@ slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED .log file issues: - Successfully made PFTs, harvest and grazing, glacier, urban, -topo stats, and organic don't show input/output for comparison + topo stats, and organic don't show input/output for comparison - soil texture category 3 and soil color category 15 inputs/outputs -problematic or just that we set ocean to loam? + problematic or just that we set ocean to loam? - agricultural fire peak month: output areas increase for all categories - voc emission factors all zero @@ -71,13 +85,14 @@ Coordinate with Peter Lawrence. Use this command to translate: Python script for generating namelists has NOT ADDRESSED: -------------------------------------------------------- * Regional/1x1: handled by subset.py -* nocrop: should work * hires_pft: should work * ssp_rcp: should work; needs files converted to cdf5 first? * potveg: needs file(s) converted to cdf5 first? * merge_gis -* no_surfdat -* Override options removed: + +-------------------------------------------------------- +Override options removed: +-------------------------------------------------------- -- all_veg = .true. handled by fsurdat_modifier zero_nonveg = .true. -- all_urban = .true. handle w fsurdat_modifier new option -- no_inlandwet = .false. same diff --git a/tools/mksurfdata_esmf/gen_mksurfdata b/tools/mksurfdata_esmf/gen_mksurfdata deleted file mode 100755 index f7d1bb69a5..0000000000 --- a/tools/mksurfdata_esmf/gen_mksurfdata +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -#PBS -A P93300641 -#PBS -N mksurfdata -#PBS -j oe -#PBS -q regular -#PBS -l walltime=30:00 -#PBS -l select=16:ncpus=36:mpiprocs=9 -##PBS -l select=24:ncpus=36:mpiprocs=12 -##PBS -l select=32:ncpus=36:mpiprocs=12 -##PBS -l select=200:ncpus=36:mpiprocs=12 - -export TMPDIR=/glade/scratch/$USER/temp -mkdir -p $TMPDIR - -# note for -l input above -# -l select={num_nodes}:ncpus={max_tasks_per_node}:mpiprocs={tasks_per_node} -# note for mpiexec below -# -np {total_tasks} - -# Run the model -#mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata -#mpiexec_mpt -p "%g:" -np 288 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata - mpiexec_mpt -p "%g:" -np 384 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata -#mpiexec_mpt -p "%g:" -np 2400 /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/src/mksurfdata - diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py similarity index 88% rename from tools/mksurfdata_esmf/gen_mksurfdata_jobscript.py rename to tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 27425b815b..ee5901d570 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -52,6 +52,14 @@ def get_parser(): help="ncrease output verbosity", action="store_true", ) + parser.add_argument( + "--account", + help="""account number (default P93300606)""", + action="store", + dest="account", + required=False, + default="P93300606" + ) parser.add_argument( "--mpi_tasks", help="number of mpi tasks requested", @@ -59,6 +67,14 @@ def get_parser(): dest="mpi_tasks", required=True, ) + parser.add_argument( + "--tasks-per-node", + help="""number of mpi tasks per node for cheyenne requested (default is 12)""", + action="store", + dest="tasks_per_node", + required=False, + default="12", + ) parser.add_argument( "--scenario", help="""scenario""", @@ -67,6 +83,14 @@ def get_parser(): dest="scenario", required=True, ) + parser.add_argument( + "--jobscript-file", + help="""output jobscript file to be submitted on cheyenne (default is mksurfdata_jobscript_multi)]""", + action="store", + dest="jobscript_file", + required=False, + default="mksurfdata_jobscript_multi" + ) return parser def main (): @@ -76,7 +100,10 @@ def main (): # -------------------------- args = get_parser().parse_args() scenario = args.scenario + jobscript_file = args.jobscript_file mpi_tasks = args.mpi_tasks + tasks_per_node = args.tasks_per_node + account = args.account # -------------------------- # Determine target list @@ -170,23 +197,22 @@ def main (): # -------------------------- # Write run script # -------------------------- - with open("./runfile", "w",encoding='utf-8') as runfile: + with open(jobscript_file, "w",encoding='utf-8') as runfile: np = int(mpi_tasks) - tasks_per_node = 12 - nodes = int(np / tasks_per_node) + nodes = int(np / int(tasks_per_node)) - runfile.write('#!/bin/bash') - runfile.write('#PBS -A P93300606 \n') + runfile.write('#!/bin/bash \n') + runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -N mksurfdata \n') runfile.write('#PBS -j oe \n') runfile.write('#PBS -q regular \n') runfile.write('#PBS -l walltime=30:00 \n') - runfile.write(f"#PBS -l select={nodes}:ncpus=36:mpiprocs=12 \n") + runfile.write(f"#PBS -l select={nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") runfile.write("\n") - runfile.write("export TMPDIR=/glade/scratch/\$USER/temp \n") - runfile.write("mkdir -p \$TMPDIR \n") + runfile.write("export TMPDIR=/glade/scratch/$USER/temp \n") + runfile.write("mkdir -p $TMPDIR \n") runfile.write("\n") for target in target_list: @@ -206,5 +232,8 @@ def main (): output = f"mpiexec_mpt -p \"%g:\" -np {np} ./src/mksurfdata < {namelist}" runfile.write(f"{output} \n") + print (f"Successfully created jobscript {jobscript_file}") + sys.exit(0) + if __name__ == "__main__": main() diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py new file mode 100755 index 0000000000..f468292000 --- /dev/null +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 + +import sys, os, shutil +import logging +import argparse, textwrap +import subprocess +from datetime import datetime + +def get_parser(): + """ + Get parser object for this script. + """ + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + + parser.print_usage = parser.print_help + + parser.add_argument( + '-v', '--verbose', + help="increase output verbosity", + action="store_true", + ) + parser.add_argument( + "--account", + help="""account number (default P93300606)""", + action="store", + dest="account", + required=False, + default="P93300606" + ) + parser.add_argument( + "--mpi-tasks", + help="""number of mpi tasks requested (required)""", + action="store", + dest="mpi_tasks", + required=True, + ) + parser.add_argument( + "--tasks-per-node", + help="""number of mpi tasks per node for cheyenne requested (default is 12)""", + action="store", + dest="tasks_per_node", + required=False, + default="12", + ) + parser.add_argument( + "--namelist-file", + help="""input namelist file (required)""", + action="store", + dest="namelist_file", + required=True, + ) + parser.add_argument( + "--jobscript-file", + help="""output jobscript file to be submitted on cheyenne (default is mksurfdata_jobscript_single)]""", + action="store", + dest="jobscript_file", + required=False, + default="mksurfdata_jobscript_single" + ) + return parser + +def main (): + + # -------------------------- + # Obtain input args + # -------------------------- + args = get_parser().parse_args() + namelist_file = args.namelist_file + jobscript_file = args.jobscript_file + mpi_tasks = args.mpi_tasks + tasks_per_node = args.tasks_per_node + account = args.account + + # -------------------------- + # Write run script + # -------------------------- + with open(jobscript_file, "w",encoding='utf-8') as runfile: + + np = int(mpi_tasks) + nodes = int(np / int(tasks_per_node)) + + runfile.write('#!/bin/bash \n') + runfile.write(f"#PBS -A {account} \n") + runfile.write('#PBS -N mksurfdata \n') + runfile.write('#PBS -j oe \n') + runfile.write('#PBS -q regular \n') + runfile.write('#PBS -l walltime=30:00 \n') + runfile.write(f"#PBS -l select={nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") + + runfile.write("\n") + runfile.write("export TMPDIR=/glade/scratch/$USER/temp \n") + runfile.write("mkdir -p $TMPDIR \n") + runfile.write("\n") + + output = f"mpiexec_mpt -p \"%g:\" -np {np} ./src/mksurfdata < {namelist_file}" + runfile.write(f"{output} \n") + + print (f"Successfully created jobscript {jobscript_file}") + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 5e0a39b93a..ed44ba0957 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -428,10 +428,9 @@ def main (): file1 = rawdata_files["mksrf_fvegtyp_ssp"] landuse_input_fname = file1.replace("%y",str(year)) - # if not os.path.isfile(landuse_input_fname): - # TODO: turn on this error once the new cdf5 data is available - # print(f"ERROR: landunit_input_fname: {landuse_input_fname} does not exit") - # sys.exit(60) + if not os.path.isfile(landuse_input_fname): + print(f"ERROR: landunit_input_fname: {landuse_input_fname} does not exit") + sys.exit(60) # -- Each line is written twice in the original perl code: landuse_line = f"{landuse_input_fname:<196}{str(year)}\n" diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index adf088949f..e345e26cdc 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -223,8 +223,6 @@ version of the raw dataset will probably go away. lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.cdf5.c170629/mksrf_landuse_histclm50_LUH2_1850.cdf5.c170629.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc @@ -251,7 +249,7 @@ version of the raw dataset will probably go away. - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.cdf5.c170629/mksrf_landuse_histclm50_LUH2_%y.cdf5.c170629.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20220305/mksrf_landuse_ctsm52_histLUH2_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc @@ -263,37 +261,37 @@ version of the raw dataset will probably go away. - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_%y.c181217.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP26_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_%y.c181217.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP19_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_%y.c181217.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP2RCP45_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_%y.c181217.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP3RCP70_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_%y.c181217.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP34_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_%y.c181217.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP60_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_%y.c171005.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP5RCP85_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 3408bf9d85..cdb5192c8f 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -137,10 +137,6 @@ subroutine mkfile_define_atts(pioid, dynlanduse) ! Raw data file names str = get_filename(mksrf_fgrid_mesh) rcode = pio_put_att(pioid, pio_global, 'Input_grid_dataset', trim(str)) - if (.not. dynlanduse) then - str = get_filename(mksrf_fvocef) - rcode = pio_put_att(pioid, pio_global, 'VOC_EF_raw_data_file_name', trim(str)) - end if str = get_filename(mksrf_flakwat) rcode = pio_put_att(pioid, pio_global, 'Inland_lake_raw_data_file_name', trim(str)) str = get_filename(mksrf_fwetlnd) @@ -153,10 +149,8 @@ subroutine mkfile_define_atts(pioid, dynlanduse) rcode = pio_put_att(pioid, pio_global, 'Urban_Topography_raw_data_file_name', trim(str)) str = get_filename(mksrf_furban) rcode = pio_put_att(pioid, pio_global, 'Urban_raw_data_file_name', trim(str)) - if (.not. dynlanduse .and. (numpft == numstdpft) ) then - str = get_filename(mksrf_flai) - rcode = pio_put_att(pioid, pio_global, 'Lai_raw_data_file_name', trim(str)) - end if + str = get_filename(mksrf_fvegtyp) + rcode = pio_put_att(pioid, pio_global, 'Vegetation_type_raw_data_filename', trim(str)) str = get_filename(mksrf_fabm) rcode = pio_put_att(pioid, pio_global, 'agfirepkmon_raw_data_file_name', trim(str)) str = get_filename(mksrf_fgdp) @@ -219,6 +213,8 @@ subroutine mkfile_define_atts(pioid, dynlanduse) end if if (.not. dynlanduse) then + str = get_filename(mksrf_flai) + rcode = pio_put_att(pioid, pio_global, 'lai_raw_data_file_name', trim(str)) str = get_filename(mksrf_fsoicol) rcode = pio_put_att(pioid, pio_global, 'soil_color_raw_data_file_name', trim(str)) str = get_filename(mksrf_fsoitex) @@ -227,6 +223,8 @@ subroutine mkfile_define_atts(pioid, dynlanduse) rcode = pio_put_att(pioid, pio_global, 'fmax_raw_data_file_name', trim(str)) str = get_filename(mksrf_forganic) rcode = pio_put_att(pioid, pio_global, 'organic_matter_raw_data_file_name', trim(str)) + str = get_filename(mksrf_fvocef) + rcode = pio_put_att(pioid, pio_global, 'VOC_EF_raw_data_file_name', trim(str)) end if end subroutine mkfile_define_atts diff --git a/tools/mksurfdata_esmf/src/mkinputMod.F90 b/tools/mksurfdata_esmf/src/mkinputMod.F90 index f8fe1451ad..9afcbfce51 100644 --- a/tools/mksurfdata_esmf/src/mkinputMod.F90 +++ b/tools/mksurfdata_esmf/src/mkinputMod.F90 @@ -116,13 +116,10 @@ module mkinputMod contains !=============================================================== - subroutine read_namelist_input(filename) + subroutine read_namelist_input() ! Read in input namelist - ! input/output variables - character(len=*), intent(in) :: filename ! now unused - ! local variables integer :: ier integer :: k @@ -210,7 +207,7 @@ subroutine read_namelist_input(filename) if (root_task) then read(5, nml=mksurfdata_input, iostat=ier) if (ier > 0) then - call shr_sys_abort(subname//' error reading in mksurfdata_input namelist from '//trim(filename)) + call shr_sys_abort(subname//' error reading in mksurfdata_input namelist from standard input') end if end if diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index cdf04aefe9..d4783400a9 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -305,14 +305,20 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! is okay if the input raw dataset has prognostic crops and the output does not. if (numpft_i /= numpft+1) then if (numpft_i == numstdpft+1) then - write(6,*) subname//' ERROR: trying to use non-crop input file' - write(6,*) 'for a surface dataset with crops.' + if (root_task) then + write(ndiag,*) subname//' ERROR: trying to use non-crop input file' + write(ndiag,*) 'for a surface dataset with crops.' + end if call shr_sys_abort() else if (numpft_i > numstdpft+1 .and. numpft_i == maxpft+1) then - write(6,*) subname//' WARNING: using a crop input raw dataset for a non-crop output surface dataset' + if (root_task) then + write(ndiag,*) subname//' WARNING: using a crop input raw dataset for a non-crop output surface dataset' + end if else - write(6,*) subname//': parameter numpft+1= ',numpft+1, & - 'does not equal input dataset numpft= ',numpft_i + if (root_task) then + write(ndiag,*) subname//': parameter numpft+1= ',numpft+1, & + 'does not equal input dataset numpft= ',numpft_i + end if call shr_sys_abort() end if endif diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 3d60e72cae..016a6e4824 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -227,7 +227,7 @@ program mksurfdata call pio_init(iam, mpicom, max(1,petcount/stride), 0, stride, PIO_REARR_SUBSET, pio_iosystem) pio_iotype = PIO_IOTYPE_PNETCDF - pio_ioformat = PIO_64BIT_DATA + pio_ioformat = PIO_64BIT_DATA call ESMF_LogWrite("finished initializing PIO", ESMF_LOGMSG_INFO) @@ -237,8 +237,7 @@ program mksurfdata ! Read input namelist on root_task and broadcast to all pes ! root_task is a module variable in mkvarctl - ! Assumne that input namelist file is 'mksurfdata_in' - call read_namelist_input(filename='mksurfdata_in') + call read_namelist_input() ! open output ndiag file if (fsurlog == ' ') then From fc0b93bd7c42247038673598cf37c5e9eb7d077b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 9 Mar 2022 15:25:05 -0700 Subject: [PATCH 097/614] update for running 5x5_amazon --- tools/mksurfdata_esmf/README | 11 +++---- .../gen_mksurfdata_jobscript_multi.py | 12 ++++---- .../gen_mksurfdata_jobscript_single.py | 20 ++++++------- tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 | 4 +-- tools/mksurfdata_esmf/src/mksurfdata.F90 | 29 ++++++++++++++----- 5 files changed, 44 insertions(+), 32 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index dad4956acd..44c03bce50 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -40,17 +40,16 @@ running for a single submission: > cd ../ > run ./gen_mksurfdata_namelist.py to generate your target namelist (call it foo.namelist here) > run ./gen_mksurfdata_jobscript_single.py --help to see commands - as an example -> run ./gen_mksurfdata_jobscript_single.py --mpi-tasks 768 --namelist-file foo.namelist +> run ./gen_mksurfdata_jobscript_single.py --number-of-nodes 24 --tasks-per-node 12 --namelist-file foo.namelist > qsub mksurfdata_jobscript ======================= running for the generation of multiple datasets ======================= -> cd ../ Note that gen_mksurfdata_jobscript_multi.py runs ./gen_mksurfdata_namelist.py +> cd ../ > run ./gen_mksurfdata_jobscript_multi.py --help to see commands - as an example -> run ./gen_mksurfdata_jobscript_multi.py --mpi-tasks 768 --namelist-file foo.namelist -> run ./gen_mksurfdata_jobscript_multi.py --mpi-tasks 768 --scenario all +> run ./gen_mksurfdata_jobscript_multi.py --number-of-nodes 24 --tasks-per-node 12 --scenario all > qsub mksurfdata_jobscript ================ @@ -76,9 +75,8 @@ slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED - voc emission factors all zero ------------------------------------------------------ -DYNAMIC LU: NOT ALL FILES HAVE BEEN TRANSLATED to cdf5 +NOT ALL FILES HAVE BEEN TRANSLATED to cdf5 - need to check last millenium ------------------------------------------------------ -Coordinate with Peter Lawrence. Use this command to translate: > nccopy -k cdf5 oldfile newfile -------------------------------------------------------- @@ -86,7 +84,6 @@ Python script for generating namelists has NOT ADDRESSED: -------------------------------------------------------- * Regional/1x1: handled by subset.py * hires_pft: should work -* ssp_rcp: should work; needs files converted to cdf5 first? * potveg: needs file(s) converted to cdf5 first? * merge_gis diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index ee5901d570..a28c334e6d 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -61,10 +61,10 @@ def get_parser(): default="P93300606" ) parser.add_argument( - "--mpi_tasks", - help="number of mpi tasks requested", + "--number-of-nodes", + help="""number of cheyenne nodes requested (required)""", action="store", - dest="mpi_tasks", + dest="number_of_nodes", required=True, ) parser.add_argument( @@ -101,7 +101,7 @@ def main (): args = get_parser().parse_args() scenario = args.scenario jobscript_file = args.jobscript_file - mpi_tasks = args.mpi_tasks + number_of_nodes = args.number_of_nodes tasks_per_node = args.tasks_per_node account = args.account @@ -208,13 +208,15 @@ def main (): runfile.write('#PBS -j oe \n') runfile.write('#PBS -q regular \n') runfile.write('#PBS -l walltime=30:00 \n') - runfile.write(f"#PBS -l select={nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") + runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") runfile.write("\n") runfile.write("export TMPDIR=/glade/scratch/$USER/temp \n") runfile.write("mkdir -p $TMPDIR \n") runfile.write("\n") + np = int(tasks_per_node) * int(number_of_nodes) + for target in target_list: res_set = dataset_dict[target][1] for res in resolution_dict[res_set]: diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index f468292000..8259e829e3 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -30,19 +30,18 @@ def get_parser(): default="P93300606" ) parser.add_argument( - "--mpi-tasks", - help="""number of mpi tasks requested (required)""", + "--number-of-nodes", + help="""number of cheyenne nodes requested (required)""", action="store", - dest="mpi_tasks", + dest="number_of_nodes", required=True, ) parser.add_argument( "--tasks-per-node", - help="""number of mpi tasks per node for cheyenne requested (default is 12)""", + help="""number of mpi tasks per node for cheyenne requested (required)""", action="store", dest="tasks_per_node", - required=False, - default="12", + required=True, ) parser.add_argument( "--namelist-file", @@ -69,7 +68,7 @@ def main (): args = get_parser().parse_args() namelist_file = args.namelist_file jobscript_file = args.jobscript_file - mpi_tasks = args.mpi_tasks + number_of_nodes = args.number_of_nodes tasks_per_node = args.tasks_per_node account = args.account @@ -78,22 +77,21 @@ def main (): # -------------------------- with open(jobscript_file, "w",encoding='utf-8') as runfile: - np = int(mpi_tasks) - nodes = int(np / int(tasks_per_node)) - runfile.write('#!/bin/bash \n') runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -N mksurfdata \n') runfile.write('#PBS -j oe \n') runfile.write('#PBS -q regular \n') runfile.write('#PBS -l walltime=30:00 \n') - runfile.write(f"#PBS -l select={nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") + runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") runfile.write("\n") runfile.write("export TMPDIR=/glade/scratch/$USER/temp \n") runfile.write("mkdir -p $TMPDIR \n") runfile.write("\n") + np = int(tasks_per_node) * int(number_of_nodes) + output = f"mpiexec_mpt -p \"%g:\" -np {np} ./src/mksurfdata < {namelist_file}" runfile.write(f"{output} \n") diff --git a/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 b/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 index 230d9ca6a0..b52a2754b3 100644 --- a/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpctPftTypeMod.F90 @@ -542,8 +542,8 @@ subroutine get_pct_p2l_array(pct_pft_arr, ndim1, ndim2, pct_p2l) call shr_sys_abort(subname//' ndim1 and size(pct_pft_arr) must be equal') end if if (ndim2 /= pft_ubound-pft_lbound+1) then - write(6,*) 'ndim1,pft_ubound-pft_lbound+1 = ',ndim1,pft_ubound-pft_lbound+1 - call shr_sys_abort(subname//' ndim1 and pft_ubound-pft_lbound+1 must be equal') + write(6,*) 'ndim2,pft_ubound-pft_lbound+1 = ',ndim2,pft_ubound-pft_lbound+1 + call shr_sys_abort(subname//' ndim2 and pft_ubound-pft_lbound+1 must be equal') end if do arr_index = 1, size(pct_pft_arr) if (lbound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_lbound .or. & diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 016a6e4824..d5919c18cb 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -697,13 +697,21 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP') if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_NAT_PFT" - call get_pct_p2l_array(pctnatpft, ndim1=lsize_o, ndim2=num_natpft+1, pct_p2l=pct_nat_pft) + if (lsize_o /= 0) then + call get_pct_p2l_array(pctnatpft, ndim1=lsize_o, ndim2=num_natpft+1, pct_p2l=pct_nat_pft) + else + pct_nat_pft(:,:) = 0. + end if call mkfile_output(pioid, mesh_model, 'PCT_NAT_PFT', pct_nat_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NAT_PFT') - + if (num_cft > 0) then if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_CFT" - call get_pct_p2l_array(pctcft, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) + if (lsize_o /= 0) then + call get_pct_p2l_array(pctcft, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) + else + pct_cft(:,:) = 0. + end if call mkfile_output(pioid, mesh_model, 'PCT_CFT', pct_cft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CFT') end if @@ -1058,10 +1066,17 @@ subroutine normalize_and_check_landuse(ns_o) suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) if (suma > (100._r8 + tol_loose)) then - write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla must be' - write(6,*) '<= 100% before calling this subroutine' - write(6,*) 'n, pctlak, pctwet, pcturb, pctgla = ', & - n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) + if (root_task) then + write(ndiag,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla must be' + write(ndiag,*) '<= 100% before calling this subroutine' + write(ndiag,*) 'n, pctlak, pctwet, pcturb, pctgla = ', & + n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) + else + write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla must be' + write(6,*) '<= 100% before calling this subroutine' + write(6,*) 'n, pctlak, pctwet, pcturb, pctgla = ', & + n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) + end if call shr_sys_abort() end if From f6fa0c11240498273c9e46fb4e6c7f9fe45b1fbf Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 9 Mar 2022 15:47:02 -0700 Subject: [PATCH 098/614] simplified job script --- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py | 4 ---- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py | 4 ---- 2 files changed, 8 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index a28c334e6d..14b47c62a6 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -209,10 +209,6 @@ def main (): runfile.write('#PBS -q regular \n') runfile.write('#PBS -l walltime=30:00 \n') runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") - - runfile.write("\n") - runfile.write("export TMPDIR=/glade/scratch/$USER/temp \n") - runfile.write("mkdir -p $TMPDIR \n") runfile.write("\n") np = int(tasks_per_node) * int(number_of_nodes) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index 8259e829e3..4072349cef 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -84,10 +84,6 @@ def main (): runfile.write('#PBS -q regular \n') runfile.write('#PBS -l walltime=30:00 \n') runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") - - runfile.write("\n") - runfile.write("export TMPDIR=/glade/scratch/$USER/temp \n") - runfile.write("mkdir -p $TMPDIR \n") runfile.write("\n") np = int(tasks_per_node) * int(number_of_nodes) From 988ddd8a49b1c00b53b16be7fcc23273c1f6fb41 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 16 Mar 2022 11:16:46 -0600 Subject: [PATCH 099/614] Correct gen_mksurfdata_jobscript_multi.py and update README Updated README instructions. gen_mksurfdata_jobscript_multi.py needed 2 lines removed so as to work. --- tools/mksurfdata_esmf/README | 26 ++++++++++--------- .../gen_mksurfdata_jobscript_multi.py | 3 --- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 44c03bce50..971761526e 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -1,6 +1,6 @@ Updated on, by: -3/2/2022 slevis -2/23/2022 mvertens +3/16/2022 slevis +3/11/2022 mvertens ================ Getting the code @@ -8,7 +8,7 @@ Getting the code > cd > git clone https://github.com/ESCOMP/CTSM.git > cd -> git checkout feature/new_toolchain +> git checkout feature/new_mksurfdata # Save time by checking out ccs_config only > ./manage_externals/checkout_externals ccs_config @@ -38,19 +38,21 @@ building the executable running for a single submission: ======================= > cd ../ -> run ./gen_mksurfdata_namelist.py to generate your target namelist (call it foo.namelist here) -> run ./gen_mksurfdata_jobscript_single.py --help to see commands - as an example -> run ./gen_mksurfdata_jobscript_single.py --number-of-nodes 24 --tasks-per-node 12 --namelist-file foo.namelist -> qsub mksurfdata_jobscript +# to generate your target namelist: +> ./gen_mksurfdata_namelist.py --help +# for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: +> ./gen_mksurfdata_namelist.py --res --start-year --end-year +# to generate your target jobscript (again --help for instructions): +> ./gen_mksurfdata_jobscript_single.py --number-of-nodes 24 --tasks-per-node 12 --namelist-file target.namelist +> qsub mksurfdata_jobscript_single ======================= running for the generation of multiple datasets ======================= -Note that gen_mksurfdata_jobscript_multi.py runs ./gen_mksurfdata_namelist.py -> cd ../ -> run ./gen_mksurfdata_jobscript_multi.py --help to see commands - as an example -> run ./gen_mksurfdata_jobscript_multi.py --number-of-nodes 24 --tasks-per-node 12 --scenario all -> qsub mksurfdata_jobscript +# Note that gen_mksurfdata_jobscript_multi.py runs ./gen_mksurfdata_namelist.py +> ./gen_mksurfdata_jobscript_multi.py --help +> ./gen_mksurfdata_jobscript_multi.py --number-of-nodes 24 --tasks-per-node 12 --scenario all +> qsub mksurfdata_jobscript_multi ================ NOTES diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 14b47c62a6..b1a98ec9e4 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -199,9 +199,6 @@ def main (): # -------------------------- with open(jobscript_file, "w",encoding='utf-8') as runfile: - np = int(mpi_tasks) - nodes = int(np / int(tasks_per_node)) - runfile.write('#!/bin/bash \n') runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -N mksurfdata \n') From 8a1138486c82e84b6dc979de2958fd651f5aaea0 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 16 Mar 2022 11:44:18 -0600 Subject: [PATCH 100/614] cleanup --- tools/mksurfdata_esmf/gen_mksurfdata_all | 132 ----------------------- 1 file changed, 132 deletions(-) delete mode 100755 tools/mksurfdata_esmf/gen_mksurfdata_all diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_all b/tools/mksurfdata_esmf/gen_mksurfdata_all deleted file mode 100755 index 1cd5e5d12d..0000000000 --- a/tools/mksurfdata_esmf/gen_mksurfdata_all +++ /dev/null @@ -1,132 +0,0 @@ -#!/bin/bash -#PBS -A P93300641 -#PBS -N mksurfdata -#PBS -j oe -#PBS -q regular -#PBS -l walltime=12:00:00 -#PBS -l select=64:ncpus=36:mpiprocs=12 - -export TMPDIR=/glade/scratch/$USER/temp -mkdir -p $TMPDIR - -# note for -l input above -# -l select={num_nodes}:ncpus={max_tasks_per_node}:mpiprocs={tasks_per_node} -# note for mpiexec below -# -np {total_tasks} = {num_nodes} x {tasks_per_node} - -rundir=/glade/work/$USER/git_mvertens/ctsm_1663/tools/mksurfdata_esmf -cd $rundir - -# Run the model - -# ------------- -# Notes -# ------------- -# T42 is needed for SCAM -# ne120np4 for high resolution SE dycore -# ne16 for testing SE dycore -# f05 for running full chemistry model -# nldas for NWP working with WRF -# 4x5 and 10x15 for testing purposes -# ------------- - -standard_res_no_crop=( '0.9x1.25' '1.9x2.5' '4x5' ) -for res in "${standard_res_no_crop[@]}"; do - input=$(echo `./gen_mksurfdata_namelist.py --nocrop --vic --start-year 2000 --end-year 2000 --res $res` | cut -d' ' -f 22) - echo $input ATTEMPT - mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input - echo $input DONE? -done - -# ------------- - -# TODO DIDN'T WORK? -input=$(echo `./gen_mksurfdata_namelist.py --nocrop --start-year 2000 --end-year 2000 --res 64x128` | cut -d' ' -f 22) -echo $input ATTEMPT -mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input -echo $input DONE? - -# ------------- - -input=$(echo `./gen_mksurfdata_namelist.py --nocrop --hires_pft --start-year 2005 --end-year 2005 --res 0.125nldas2` | cut -d' ' -f 22) -echo $input ATTEMPT -mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input -echo $input DONE? - -# ------------- - -standard_res=( '0.9x1.25' '1.9x2.5' '10x15' '4x5' 'ne30np4' 'C96' 'ne30pg2' 'ne30pg3' 'ne30pg4' 'ne120np4pg3' 'ne0np4.ARCTICGRIS.ne30x8' 'ne0np4ARCTICne30x4' 'ne0np4CONUSne30x8' ) -for res in "${standard_res[@]}"; do - input=$(echo `./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res $res` | cut -d' ' -f 22) - echo $input ATTEMPT - mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input - echo $input DONE? - - input=$(echo `./gen_mksurfdata_namelist.py --start-year 1850 --end-year 1850 --ssp-rcp SSP5-8.5 --res $res` | cut -d' ' -f 22) - echo $input ATTEMPT - mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input - echo $input DONE? -done - -# ------------- - -input=$(echo `./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res ne16np4` | cut -d' ' -f 22) -echo $input ATTEMPT -mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input -echo $input DONE? - -# ------------- - -input=$(echo `./gen_mksurfdata_namelist.py --hires_pft --start-year 2000 --end-year 2000 --res 0.125x0.125` | cut -d' ' -f 22) -echo $input ATTEMPT -mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input -echo $input DONE? - -# ------------- - -resolutions=( '0.47x0.63' 'ne120np4' ) -years=( 1850 2000 ) -for y in "${years[@]}"; do - for res in "${resolutions[@]}"; do - input=$(echo `./gen_mksurfdata_namelist.py --start-year $y --end-year $y --res $res` | cut -d' ' -f 22) - echo $input ATTEMPT - mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input - echo $input DONE? - done -done - -# ------------- - -# slevis adding to trans_res: ne120np4, 0.47x0.63 -# TODO Currently have access to files 1850-1855 and 2000-2007. When remaining -# files become available, uncomment the commented-out line and delete the one -# after it. -trans_res=( '0.9x1.25' '1.9x2.5' '10x15' 'ne30np4' 'ne0np4.ARCTICGRIS.ne30x8' 'ne0np4ARCTICne30x4' 'ne0np4CONUSne30x8' 'ne120np4' '0.47x0.63' ) -for res in "${trans_res[@]}"; do -# input=$(echo `./gen_mksurfdata_namelist.py --nosurfdata --start-year 1850 --end-year 2000 --res $res` | cut -d' ' -f 22) - input=$(echo `./gen_mksurfdata_namelist.py --nosurfdata --start-year 1850 --end-year 1855 --res $res` | cut -d' ' -f 22) - echo $input ATTEMPT - mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input - echo $input DONE? -done - -# ------------- - -# Crop with future scenarios -# TODO Currently have access to files 1850-1855 and 2000-2007. When remaining -# files become available, uncomment the commented-out line and delete the one -# after it. -future_res=( '0.9x1.25' '1.9x2.5' '10x15' ) -ssp_list=( 'SSP1-2.6' 'SSP3-7.0' 'SSP5-3.4' 'SSP2-4.5' 'SSP1-1.9' 'SSP4-3.4' 'SSP4-6.0' 'SSP5-8.5' ) -for res in "${future_res[@]}"; do - for ssp in "${ssp_list[@]}"; do -# input=$(echo `./gen_mksurfdata_namelist.py --nosurfdata --start-year 1850 --end-year 2100 --ssp-rcp $ssp --res $res` | cut -d' ' -f 22) - input=$(echo `./gen_mksurfdata_namelist.py --nosurfdata --start-year 2000 --end-year 2007 --ssp-rcp $ssp --res $res` | cut -d' ' -f 22) - echo $input ATTEMPT - mpiexec_mpt -p "%g:" -np 768 ./src/mksurfdata < $input - echo $input DONE? - done -done - -# ------------- - From 70a10382dabd4d31f8bdf7749282842c5b0133ff Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 21 Mar 2022 12:09:50 -0600 Subject: [PATCH 101/614] Manually introduce the changes found in #1586 - The code builds and a non-transient case completes: mpiexec_mpt -p "%g:" -np 288 ./src/mksurfdata < surfdata_1.9x2.5_hist_78pfts_CMIP6_1850_c220316.namelist - Transient case gives error: mpiexec_mpt -p "%g:" -np 288 ./src/mksurfdata < surfdata_1.9x2.5_hist_78pfts_CMIP6_1850-1899_c220316.namelist mksrfdata error: year for urban not equal to year for PFT files ...but I don't, yet, see a mistake in my implementation: from mksurfdata_map/src/mksurfdat.F90 lines 1117-1130 to mksurfdata_esmf/src/mksurfdat.F90 lines 883-908 --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 15 ++++ tools/mksurfdata_esmf/src/mkinputMod.F90 | 2 + tools/mksurfdata_esmf/src/mklanwatMod.F90 | 25 ++++++ tools/mksurfdata_esmf/src/mksurfdata.F90 | 96 +++++++++++++++++++-- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 27 ++++++ 5 files changed, 157 insertions(+), 8 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index cdb5192c8f..01d6453000 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -526,6 +526,21 @@ subroutine mkfile_define_vars(pioid, dynlanduse) else + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_URBAN', xtype=xtype, & + lev1name = 'numurbl', lev2name='time', & + long_name = "percent urban for each density type", units = "unitless") + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_URBAN_MAX', xtype=xtype, & + lev1name = 'numurbl', & + long_name = "maximum percent urban for each density type", units = "unitless") + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_LAKE', xtype=xtype, & + lev1name = 'time', & + long_name = "percent lake", units = "unitless") + + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_LAKE_MAX', xtype=xtype, & + long_name = "maximum percent lake", units = "unitless") + call mkpio_def_spatial_var(pioid=pioid, varname='HARVEST_VH1', xtype=xtype, & lev1name='time', & long_name = "harvest from primary forest", units = "gC/m2/yr") diff --git a/tools/mksurfdata_esmf/src/mkinputMod.F90 b/tools/mksurfdata_esmf/src/mkinputMod.F90 index 9afcbfce51..1d5c3a38a9 100644 --- a/tools/mksurfdata_esmf/src/mkinputMod.F90 +++ b/tools/mksurfdata_esmf/src/mkinputMod.F90 @@ -31,6 +31,8 @@ module mkinputMod character(CL) , public :: fsurlog ! output surface log file name character(CL) , public :: fdyndat ! dynamic landuse data file name character(CL) , public :: fhrvname ! generic harvest filename + character(CL) , public :: furbname ! generic transient urban land cover filename + character(CL) , public :: flakname ! generic lake filename character(CX) , public :: mksrf_fgrid_mesh = ' ' ! land grid file name to use integer , public :: mksrf_fgrid_mesh_nx = -999 diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index f380a0109b..30c53a5ee9 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -22,6 +22,7 @@ module mklanwatMod public :: mklakwat ! make %lake and lake dpeth public :: mkwetlnd ! make %wetland + public :: update_max_array_lake ! Update the maximum lake percent character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -328,4 +329,28 @@ subroutine mkwetlnd(file_mesh_i, file_data_i, mesh_o, swmp_o, rc) end subroutine mkwetlnd +!=============================================================== +subroutine update_max_array_lake(pct_lakmax_arr,pct_lake_arr) + ! + ! !DESCRIPTION: + ! Update the maximum lake percent for landuse.timeseries file + ! + ! !ARGUMENTS: + real(r8) , intent(inout):: pct_lakmax_arr(:) ! max lake percent + real(r8) , intent(in):: pct_lake_arr(:) ! lake percent that is used to update the old pct_lakmax_arr + ! + ! !LOCAL VARIABLES: + integer :: n,ns ! indices + + character(len=*), parameter :: subname = 'update_max_array_lake' + !----------------------------------------------------------------------- + ns = size(pct_lake_arr,1) + do n = 1, ns + if (pct_lake_arr(n) > pct_lakmax_arr(n)) then + pct_lakmax_arr(n) = pct_lake_arr(n) + end if + end do + +end subroutine update_max_array_lake + end module mklanwatMod diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index d5919c18cb..8295873178 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -60,7 +60,7 @@ program mksurfdata ! ====================================== ! Optionally specify setting for: ! ====================================== - ! mksrf_fdynuse ----- ASCII text file that lists each year of pft files to use + ! mksrf_fdynuse ----- ASCII text file that lists each year of pft, urban, and lake files to use ! mksrf_gridtype ---- Type of grid (default is 'global') ! outnc_double ------ If output should be in double precision ! outnc_large_files - If output should be in NetCDF large file format @@ -106,8 +106,8 @@ program mksurfdata use mksoilfmaxMod , only : mksoilfmax use mksoildepthMod , only : mksoildepth use mksoilcolMod , only : mksoilcol - use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, mkurban_topo, numurbl - use mklanwatMod , only : mklakwat, mkwetlnd + use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, mkurban_topo, numurbl, update_max_array_urban + use mklanwatMod , only : mklakwat, mkwetlnd, update_max_array_lake use mkorganicMod , only : mkorganic use mkutilsMod , only : normalize_classes_by_gcell, chkerr use mkfileMod , only : mkfile_define_dims, mkfile_define_atts, mkfile_define_vars @@ -161,13 +161,17 @@ program mksurfdata ! inland water data, glacier data and urban data real(r8), allocatable :: pctlak(:) ! percent of grid cell that is lake + real(r8), allocatable :: pctlak_max(:) ! maximum percent of grid cell that is lake real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland real(r8), allocatable :: pctgla(:) ! percent of grid cell that is glacier integer , allocatable :: urban_region(:) ! urban region ID real(r8), allocatable :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) + real(r8), allocatable :: pcturb_max(:,:) ! maximum percent cover of each urban class, as % of grid cell real(r8), allocatable :: urban_classes(:,:) ! percent cover of each urban class, as % of total urban area real(r8), allocatable :: urban_classes_g(:,:) ! percent cover of each urban class, as % of grid cell real(r8), allocatable :: elev(:) ! glc elevation (m) + real(r8), allocatable :: pctwet_orig(:) ! percent wetland of gridcell before dynamic land use adjustments + real(r8), allocatable :: pctgla_orig(:) ! percent glacier of gridcell before dynamic land use adjustments ! pio/esmf variables type(file_desc_t) :: pioid @@ -413,10 +417,12 @@ program mksurfdata ! LAKEDEPTH is written out in the subroutine ! Need to keep pctlak and pctwet external for use below allocate ( pctlak(lsize_o)) ; pctlak(:) = spval + allocate ( pctlak_max(lsize_o)) ; pctlak_max(:) = spval call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, pctlak, pioid, fsurdat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') allocate ( pctwet(lsize_o)) ; pctwet(:) = spval + allocate ( pctwet_orig(lsize_o)) ; pctwet_orig(:) = spval call mkwetlnd(mksrf_fwetlnd_mesh, mksrf_fwetlnd, mesh_model, pctwet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkwetlnd') @@ -424,6 +430,7 @@ program mksurfdata ! Make glacier fraction [pctgla] from [fglacier] dataset ! ----------------------------------- allocate (pctgla(lsize_o)) ; pctgla(:) = spval + allocate (pctgla_orig(lsize_o)) ; pctgla_orig(:) = spval call mkglacier (mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, glac_o=pctgla, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacier') @@ -500,6 +507,7 @@ program mksurfdata ! Make urban fraction [pcturb] from [furban] dataset and ! ----------------------------------- allocate (pcturb(lsize_o)) ; pcturb(:) = spval + allocate (pcturb_max(lsize_o, numurbl)) ; pcturb_max(:,:) = spval allocate (urban_classes(lsize_o,numurbl)) ; urban_classes(:,:) = spval allocate (urban_region(lsize_o)) ; urban_region(:) = -999 call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, pcturb, urban_classes, urban_region, rc=rc) @@ -526,7 +534,6 @@ program mksurfdata where (elev > elev_thresh) pcturb = 0._r8 end where - deallocate(elev) ! ----------------------------------- ! Compute topography statistics [topo_stddev, slope] from [ftopostats] @@ -611,6 +618,10 @@ program mksurfdata end if end do + ! Save special land unit areas of surface dataset + pctwet_orig(:) = pctwet(:) + pctgla_orig(:) = pctgla(:) + ! ----------------------------------- ! Perform other normalizations ! ----------------------------------- @@ -835,6 +846,8 @@ program mksurfdata pctnatpft_max = pctnatpft pctcft_max = pctcft + pcturb_max = urban_classes_g + pctlak_max = pctlak end_of_fdynloop = .false. ntim = 0 @@ -867,6 +880,33 @@ program mksurfdata end if call shr_sys_abort() end if + ! Read input urban data + if (root_task) then + read(nfdyn, '(A195,1x,I4)', iostat=ier) furbname, year2 + write(ndiag,*)'input urban dynamic dataset for year ', year2, ' is : ', trim(furbname) + end if + call mpi_bcast (furbname, len(furbname), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (year2, 1, MPI_INTEGER, 0, mpicom, ier) + if ( year2 /= year ) then + if (root_task) then + write(ndiag,*) subname, ' error: year for urban not equal to year for PFT files' + end if + call shr_sys_abort() + end if + ! Read input lake data + if (root_task) then + read(nfdyn, '(A195,1x,I4)', iostat=ier) flakname, year2 + write(ndiag,*)'input lake dynamic dataset for year ', year2, ' is : ', trim(flakname) + end if + call mpi_bcast (flakname, len(flakname), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (year2, 1, MPI_INTEGER, 0, mpicom, ier) + if ( year2 /= year ) then + if (root_task) then + write(ndiag,*) subname, ' error: year for lake not equal to year for PFT files' + end if + call shr_sys_abort() + end if + ntim = ntim + 1 if (root_task) then write(ndiag,'(a,i8)')subname//' ntime = ',ntim @@ -911,6 +951,23 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest') call pio_syncfile(pioid) + ! Create pctlak data at model resolution (use original mapping file from lake data) + call mklakwat(mksrf_flakwat_mesh, flakname, mesh_model, pctlak, pioid, fsurdat, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklakwat') + call pio_syncfile(pioid) + + call mkurban(mksrf_furban_mesh, furbname, mesh_model, pcturb, urban_classes, urban_region, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') + call pio_syncfile(pioid) + ! screen pcturb using elevation + where (elev > elev_thresh) + pcturb = 0._r8 + end where + + ! For landunits NOT read each year: reset to their pre-adjustment values in preparation for redoing landunit area normalization + pctwet(:) = pctwet_orig(:) + pctgla(:) = pctgla_orig(:) + ! Do landuse changes such as for the poles, etc. ! If have pole points on grid - set south pole to glacier ! north pole is assumed as non-land @@ -935,10 +992,13 @@ program mksurfdata write(ndiag,'(a)')' calling normalize_and_check_landuse' end if call normalize_and_check_landuse(lsize_o) + call normalize_classes_by_gcell(urban_classes, pcturb, urban_classes_g) ! Given an array of pct_pft_type variables, update all the max_p2l variables. call update_max_array(pctnatpft_max, pctnatpft) call update_max_array(pctcft_max, pctcft) + call update_max_array_urban(pcturb_max,urban_classes_g) + call update_max_array_lake(pctlak_max,pctlak) if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_NAT_PFT for year ",year rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT', pio_varid) @@ -956,6 +1016,20 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP') call pio_syncfile(pioid) + if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_URBAN for year ",year + rcode = pio_inq_varid(pioid, 'PCT_URBAN', pio_varid) + call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) + call mkfile_output(pioid, mesh_model, 'PCT_URBAN', urban_classes_g, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_URBAN') + call pio_syncfile(pioid) + + if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_LAKE for year ",year + rcode = pio_inq_varid(pioid, 'PCT_LAKE', pio_varid) + call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) + call mkfile_output(pioid, mesh_model, 'PCT_LAKE', pctlak, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_LAKE') + call pio_syncfile(pioid) + if (num_cft > 0) then if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CFT for year ",year rcode = pio_inq_varid(pioid, 'PCT_CFT', pio_varid) @@ -983,6 +1057,14 @@ program mksurfdata call mkfile_output(pioid, mesh_model, 'PCT_CROP_MAX', pctcrop, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP') + if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_URBAN_MAX" + call mkfile_output(pioid, mesh_model, 'PCT_URBAN_MAX', pcturb_max, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_URBAN_MAX') + + if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_LAKE_MAX" + call mkfile_output(pioid, mesh_model, 'PCT_LAKE_MAX', pctlak_max, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_LAKE_MAX') + if (num_cft > 0) then if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CFT_MAX" call get_pct_p2l_array(pctcft_max, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) @@ -1011,8 +1093,6 @@ subroutine normalize_and_check_landuse(ns_o) ! Normalize land use and make sure things add up to 100% as well as ! checking that things are as they should be. ! - ! Precondition: pctlak + pctwet + pcturb + pctgla <= 100 (within roundoff) - ! use mkpftConstantsMod , only : baregroundindex use mkpftUtilsMod , only : adjust_total_veg_area @@ -1068,12 +1148,12 @@ subroutine normalize_and_check_landuse(ns_o) if (suma > (100._r8 + tol_loose)) then if (root_task) then write(ndiag,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla must be' - write(ndiag,*) '<= 100% before calling this subroutine' + write(ndiag,*) '<= 100% before normalizing vegetated area' write(ndiag,*) 'n, pctlak, pctwet, pcturb, pctgla = ', & n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) else write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla must be' - write(6,*) '<= 100% before calling this subroutine' + write(6,*) '<= 100% before normalizing vegetated area' write(6,*) 'n, pctlak, pctwet, pcturb, pctgla = ', & n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) end if diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 959a75dd7b..0726672642 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -24,6 +24,7 @@ module mkurbanparMod public :: mkurbanInit public :: mkurban public :: mkurbanpar + public :: update_max_array_urban public :: normalize_urbn_by_tot public :: mkurban_topo ! Get elevation to reduce urban for high elevation areas public :: mkurban_pct_diagnostics ! print diagnostics related to pct urban @@ -954,4 +955,30 @@ subroutine mkurban_topo(file_mesh_i, file_data_i, mesh_o, varname, elev_o, rc) end subroutine mkurban_topo + !=============================================================== + subroutine update_max_array_urban(pct_urbmax_arr,pct_urban_arr) + ! + ! !DESCRIPTION: + ! Update the maximum percent cover of each urban class for landuse.timeseries file + ! + ! !ARGUMENTS: + real(r8) , intent(inout):: pct_urbmax_arr(:,:) ! max percent cover of each urban class + real(r8) , intent(in):: pct_urban_arr(:,:) ! percent cover of each urban class that is used to update the old pct_urbmax_arr + ! + ! !LOCAL VARIABLES: + integer :: n,k,ns ! indices + + character(len=*), parameter :: subname = 'update_max_array_urban' + !----------------------------------------------------------------------- + ns = size(pct_urban_arr,1) + do n = 1, ns + do k =1, numurbl + if (pct_urban_arr(n,k) > pct_urbmax_arr(n,k)) then + pct_urbmax_arr(n,k) = pct_urban_arr(n,k) + end if + end do + end do + + end subroutine update_max_array_urban + end module mkurbanparMod From c660b745684bddaba47d170850ff452d1a951c05 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 21 Mar 2022 17:08:02 -0600 Subject: [PATCH 102/614] Manually introduce the changes found in #1587 Repeated same tests as for the previous commit with same outcomes: - non-transient PASS - transient FAIL with same error as last time --- tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 | 38 ---- tools/mksurfdata_esmf/src/mksurfdata.F90 | 206 +++++--------------- 2 files changed, 49 insertions(+), 195 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 b/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 index ed985c4f07..7bfae0c0b1 100644 --- a/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 @@ -13,7 +13,6 @@ module mkpftUtilsMod private public :: convert_from_p2g ! Convert a p2g array into pct_pft_type objects - public :: adjust_total_veg_area ! Adjust the total vegetated area (natural veg & crop) to a new specified total private :: get_default_natpft ! Get the default natural pft breakdown, for a 0-area natural veg. landunit private :: get_default_cft ! Get the default cft breakdown, for a 0-area crop landunit @@ -197,43 +196,6 @@ function get_default_cft() result(default_cft) end function get_default_cft - !----------------------------------------------------------------------- - subroutine adjust_total_veg_area(new_total_pct, pctnatpft, pctcft) - ! - ! !DESCRIPTION: - ! Adjust the total vegetated area on the grid cell (natural veg & crop) to a new - ! specified total. - ! - ! If the old areas are 0%, then all the new area goes into pctnatpft. - ! - ! !USES: - use mkpctPftTypeMod, only : pct_pft_type - ! - ! !ARGUMENTS: - real(r8), intent(in) :: new_total_pct ! new total % of natural veg + crop landunits - class(pct_pft_type), intent(inout) :: pctnatpft ! natural veg cover information - class(pct_pft_type), intent(inout) :: pctcft ! crop cover information - ! - ! !LOCAL VARIABLES: - real(r8) :: natpft_l2g ! grid cell % cover of nat. veg. - real(r8) :: cft_l2g ! grid cell % cover of crop - real(r8) :: old_total ! old total % cover of natural veg + crop landunits - - character(len=*), parameter :: subname = 'adjust_total_veg_area' - !----------------------------------------------------------------------- - - natpft_l2g = pctnatpft%get_pct_l2g() - cft_l2g = pctcft%get_pct_l2g() - old_total = natpft_l2g + cft_l2g - if (old_total > 0._r8) then - call pctnatpft%set_pct_l2g(natpft_l2g * new_total_pct / old_total) - call pctcft%set_pct_l2g(cft_l2g * new_total_pct / old_total) - else - call pctnatpft%set_pct_l2g(new_total_pct) - end if - - end subroutine adjust_total_veg_area - end module mkpftUtilsMod diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 8295873178..13e4a7a511 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -601,20 +601,17 @@ program mksurfdata pcturb(n) = 0._r8 end if - ! Make sure sum of land cover types does not exceed 100. If it does, - ! subtract excess from most dominant land cover. - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - if (suma > 250._r4) then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb and pctgla is greater than 250%' - write (6,*)'n,pctlak,pctwet,pcturb,pctgla= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n) - call shr_sys_abort() - else if (suma > 100._r4) then + ! Make sure sum of all land cover types except natural vegetation + ! does not exceed 100. If it does, subtract excess from these land cover + ! types proportionally. + + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() + if (suma > 100._r4) then pctlak(n) = pctlak(n) * 100._r8/suma pctwet(n) = pctwet(n) * 100._r8/suma pcturb(n) = pcturb(n) * 100._r8/suma pctgla(n) = pctgla(n) * 100._r8/suma + call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8/suma) end if end do @@ -964,7 +961,8 @@ program mksurfdata pcturb = 0._r8 end where - ! For landunits NOT read each year: reset to their pre-adjustment values in preparation for redoing landunit area normalization + ! For landunits NOT read each year: reset to their pre-adjustment values + ! in preparation for redoing landunit area normalization pctwet(:) = pctwet_orig(:) pctgla(:) = pctgla_orig(:) @@ -1093,9 +1091,6 @@ subroutine normalize_and_check_landuse(ns_o) ! Normalize land use and make sure things add up to 100% as well as ! checking that things are as they should be. ! - use mkpftConstantsMod , only : baregroundindex - use mkpftUtilsMod , only : adjust_total_veg_area - ! input/output variables: integer, intent(in) :: ns_o @@ -1104,22 +1099,12 @@ subroutine normalize_and_check_landuse(ns_o) integer :: nsmall ! number of small PFT values for a single check integer :: nsmall_tot ! total number of small PFT values in all grid cells real(r8) :: suma ! sum for error check - real(r8) :: suma2 ! another sum for error check - real(r8) :: new_total_veg_pct ! new % veg (% of grid cell, total of natural veg & crop) - real(r8) :: bare_pct_p2g ! % of bare soil, as % of grid cell - real(r8) :: bare_urb_diff ! difference between bare soil and urban % - real(r8) :: pcturb_excess ! excess urban % not accounted for by bare soil - real(r8) :: sum8, sum8a ! sum for error check - real(r4) :: sum4a ! sum for error check + real(r8) :: new_total_natveg_pct ! new % veg (% of grid cell, natural veg) real(r8), parameter :: tol_loose = 1.e-4_r8 ! tolerance for some 'loose' error checks real(r8), parameter :: toosmallPFT = 1.e-10_r8 ! tolerance for PFT's to ignore character(len=32) :: subname = 'normalizencheck_landuse' ! subroutine name !----------------------------------------------------------------------- - ! ------------------------------------------------------------------------ - ! Normalize vegetated area so that vegetated + special area is 100% - ! ------------------------------------------------------------------------ - do n = 1,ns_o ! Check preconditions @@ -1143,86 +1128,33 @@ subroutine normalize_and_check_landuse(ns_o) write(6,*) 'n, pctgla = ', n, pctgla(n) call shr_sys_abort() end if - - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - if (suma > (100._r8 + tol_loose)) then - if (root_task) then - write(ndiag,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla must be' - write(ndiag,*) '<= 100% before normalizing vegetated area' - write(ndiag,*) 'n, pctlak, pctwet, pcturb, pctgla = ', & - n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) - else - write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla must be' - write(6,*) '<= 100% before normalizing vegetated area' - write(6,*) 'n, pctlak, pctwet, pcturb, pctgla = ', & - n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) - end if + if ( pctcft(n)%get_pct_l2g() < 0.0_r8 )then + write(6,*) subname, ' ERROR: pctcrop is negative!' + write(6,*) 'n, pctcrop = ', n, pctcft(n)%get_pct_l2g() call shr_sys_abort() end if - ! First normalize vegetated (natural veg + crop) cover so that the total of - ! (vegetated + (special excluding urban)) is 100%. We'll deal with urban later. - ! - ! Note that, in practice, the total area of natural veg + crop is typically 100% - ! going into this routine. However, the following code does NOT rely on this, and - ! will work properly regardless of the initial area of natural veg + crop (even if - ! that initial area is 0%). - - suma = pctlak(n)+pctwet(n)+pctgla(n) - new_total_veg_pct = 100._r8 - suma - - ! correct for rounding error: - new_total_veg_pct = max(new_total_veg_pct, 0._r8) - call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) - - ! Make sure we did the above rescaling correctly - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - if (abs(suma - 100._r8) > tol_loose) then - write(6,*) subname, ' ERROR in rescaling veg based on (special excluding urban)' - write(6,*) 'suma = ', suma + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() + if (suma > (100._r8 + tol_loose)) then + write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla + pctcrop must be' + write(6,*) '<= 100% before normalizing natural vegetation area' + write(6,*) 'n, pctlak, pctwet, pcturb, pctgla, pctcrop = ', & + n, pctlak(n), pctwet(n), pcturb(n), pctgla(n), pctcft(n)%get_pct_l2g() call shr_sys_abort() end if - ! Now decrease the vegetated area to account for urban area. Urban needs to be - ! handled specially because we replace bare soil preferentially with urban, rather - ! than rescaling all PFTs equally. - - if (pcturb(n) > 0._r8) then - - ! Replace bare soil preferentially with urban - bare_pct_p2g = pctnatpft(n)%get_one_pct_p2g(baregroundindex) - bare_urb_diff = bare_pct_p2g - pcturb(n) - bare_pct_p2g = max(0._r8, bare_urb_diff) - call pctnatpft(n)%set_one_pct_p2g(baregroundindex, bare_pct_p2g) - pcturb_excess = abs(min(0._r8,bare_urb_diff)) - - ! For any urban not accounted for by bare soil, replace other PFTs - ! proportionally - if (pcturb_excess > 0._r8) then - ! Note that, in this case, we will have already reduced bare ground to 0% - - new_total_veg_pct = pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - pcturb_excess - if (new_total_veg_pct < 0._r8) then - if (abs(new_total_veg_pct) < tol_loose) then - ! only slightly less than 0; correct it - new_total_veg_pct = 0._r8 - else - write(6,*) subname, ' ERROR: trying to replace veg with urban,' - write(6,*) 'but pcturb_excess exceeds current vegetation percent' - call shr_sys_abort() - end if - end if - - call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) + ! Natural vegetated cover is 100% minus the sum of all other landunits - end if + new_total_natveg_pct = 100._r8 - suma + ! correct for rounding error: + new_total_natveg_pct = max(new_total_natveg_pct, 0._r8) - end if ! pcturb(n) > 0 + call pctnatpft(n)%set_pct_l2g(new_total_natveg_pct) ! Confirm that we have done the rescaling correctly: now the sum of all landunits - ! should be 100% - suma = pctlak(n)+pctwet(n)+pctgla(n)+pcturb(n) - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + ! should be 100% within tol_loose + suma = pctlak(n) + pctwet(n) + pctgla(n) + pcturb(n) + pctcft(n)%get_pct_l2g() + suma = suma + pctnatpft(n)%get_pct_l2g() if (abs(suma - 100._r8) > tol_loose) then write(6,*) subname, ' ERROR: landunits do not sum to 100%' write(6,*) 'n, suma, pctlak, pctwet, pctgla, pcturb, pctnatveg, pctcrop = ' @@ -1259,21 +1191,26 @@ subroutine normalize_and_check_landuse(ns_o) call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8/suma) end if - ! Roundoff error fix - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - suma2 = pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + ! This roundoff error fix is needed to handle the situation where new_total_natveg_pct + ! ends up near 0 but not exactly 0 due to roundoff issues. In this situation, we set the + ! natveg landunit area to exactly 0 and put the remainder into some other landunit. Since + ! the remainder is very small, it doesn't really matter which other landunit we add it to, + ! so we just pick some landunit that already has at least 1% cover. + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() if ( (suma < 100._r8 .and. suma > (100._r8 - 1.e-6_r8)) .or. & - (suma2 > 0.0_r8 .and. suma2 < 1.e-6_r8) ) then - write (6,*) 'Special land units near 100%, but not quite for n,suma =',n,suma - write (6,*) 'Adjusting special land units to 100%' - if (pctlak(n) >= 25._r8) then - pctlak(n) = 100._r8 - (pctwet(n) + pcturb(n) + pctgla(n)) - else if (pctwet(n) >= 25._r8) then - pctwet(n) = 100._r8 - (pctlak(n) + pcturb(n) + pctgla(n)) - else if (pcturb(n) >= 25._r8) then - pcturb(n) = 100._r8 - (pctlak(n) + pctwet(n) + pctgla(n)) - else if (pctgla(n) >= 25._r8) then - pctgla(n) = 100._r8 - (pctlak(n) + pctwet(n) + pcturb(n)) + (pctnatpft(n)%get_pct_l2g() > 0.0_r8 .and. pctnatpft(n)%get_pct_l2g() < 1.e-6_r8) ) then + write (6,*) 'Special plus crop land units near 100%, but not quite for n,suma =',n,suma + write (6,*) 'Adjusting special plus crop land units to 100%' + if (pctlak(n) >= 1.0_r8) then + pctlak(n) = 100._r8 - (pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g()) + else if (pctwet(n) >= 1.0_r8) then + pctwet(n) = 100._r8 - (pctlak(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g()) + else if (pcturb(n) >= 1.0_r8) then + pcturb(n) = 100._r8 - (pctlak(n) + pctwet(n) + pctgla(n) + pctcft(n)%get_pct_l2g()) + else if (pctgla(n) >= 1.0_r8) then + pctgla(n) = 100._r8 - (pctlak(n) + pctwet(n) + pcturb(n) + pctcft(n)%get_pct_l2g()) + else if (pctcft(n)%get_pct_l2g() >= 1.0_r8) then + call pctcft(n)%set_pct_l2g(100._r8 - (pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n))) else write (6,*) subname, 'Error: sum of special land units nearly 100% but none is >= 25% at ', & 'n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),pctnatveg(n),pctcrop(n),suma = ', & @@ -1281,7 +1218,7 @@ subroutine normalize_and_check_landuse(ns_o) pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(),suma call shr_sys_abort() end if - call pctnatpft(n)%set_pct_l2g(0._r8) + call pctcft(n)%set_pct_l2g(0._r8) call pctcft(n)%set_pct_l2g(0._r8) end if if ( any(pctnatpft(n)%get_pct_p2g() > 0.0_r8 .and. pctnatpft(n)%get_pct_p2g() < toosmallPFT ) .or. & @@ -1294,15 +1231,8 @@ subroutine normalize_and_check_landuse(ns_o) call shr_sys_abort() end if - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - if (suma < 100._r8-epsilon(suma) .and. suma > (100._r8 - 4._r8*epsilon(suma))) then - write (6,*) subname, 'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& - pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() - call shr_sys_abort() - end if - - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() + suma = suma + pctnatpft(n)%get_pct_l2g() if ( abs(suma-100._r8) > 1.e-10_r8) then write (6,*) subname, ' error: sum of pctlak, pctwet,', & 'pcturb, pctgla, pctnatveg and pctcrop is NOT equal to 100' @@ -1314,44 +1244,6 @@ subroutine normalize_and_check_landuse(ns_o) end do - ! Check that when pctnatveg+pctcrop identically zero, sum of special landunits is identically 100% - if ( .not. outnc_double )then - do n = 1,ns_o - sum8 = real(pctlak(n),r4) - sum8 = sum8 + real(pctwet(n),r4) - sum8 = sum8 + real(pcturb(n),r4) - sum8 = sum8 + real(pctgla(n),r4) - sum4a = real(pctnatpft(n)%get_pct_l2g(),r4) - sum4a = sum4a + real(pctcft(n)%get_pct_l2g(),r4) - if ( sum4a==0.0_r4 .and. sum8 < 100._r4-2._r4*epsilon(sum4a) )then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 - write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n), & - pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g() - call shr_sys_abort() - end if - end do - else - do n = 1,ns_o - sum8 = pctlak(n) - sum8 = sum8 + pctwet(n) - sum8 = sum8 + pcturb(n) - sum8 = sum8 + pctgla(n) - sum8a = pctnatpft(n)%get_pct_l2g() - sum8a = sum8a + pctcft(n)%get_pct_l2g() - if ( sum8a==0._r8 .and. sum8 < (100._r8-4._r8*epsilon(sum8)) )then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 - write (6,*) 'Total error, error/epsilon = ',100._r8-sum8, ((100._r8-sum8)/epsilon(sum8)) - write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,epsilon= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& - pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), epsilon(sum8) - call shr_sys_abort() - end if - end do - end if - ! Make sure that there is no vegetation outside the pft mask do n = 1,ns_o if (pftdata_mask(n) == 0 .and. (pctnatpft(n)%get_pct_l2g() > 0 .or. pctcft(n)%get_pct_l2g() > 0)) then From fc1e118dbc76b0b1ce6bfb8cc3c750c82571c6e3 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 22 Mar 2022 18:14:20 -0600 Subject: [PATCH 103/614] Update for potveg namelist to be generated correctly --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index ed44ba0957..26a6547788 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -193,7 +193,7 @@ def get_parser(): parser.add_argument( "-f", "--fast", - help="Toggle fast mode which does not user the large mapping file", + help="Toggle fast mode which does not use the large mapping file", action="store_true", dest="fast_flag", default=False, @@ -204,7 +204,7 @@ def get_parser(): Use Potential Vegetation for pft_years [default: %(default)s] """, - action="store_false", + action="store_true", dest="potveg_flag", default=False, ) @@ -270,7 +270,9 @@ def main (): pft_years_ssp = "-999" # determine pft_years - needed to parse xml file - if int(start_year) == 1850 and int(end_year) == 1850: + if potveg: + pft_years = "PtVg" + elif int(start_year) == 1850 and int(end_year) == 1850: pft_years = "1850" elif int(start_year) == 2000 and int(end_year) == 2000: pft_years = "2000" @@ -286,8 +288,6 @@ def main (): elif int(start_year) >= 2016 and int(start_year) <= 2100 and int(end_year) <=2100: pft_years = "-999" pft_years_ssp = "2016-2100" - elif potveg: - pft_years = "PtVg" else: print (f"start_year is {start_year} and end_year is {end_year}") print (f"ERROR: start and end years should be between 850 and 2105 or pot_veg flag needs to be set") From 8de1c8cdc65a454dda10844fbfc11e68b2f035b9 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 22 Mar 2022 18:15:29 -0600 Subject: [PATCH 104/614] Updating README with latest test results --- tools/mksurfdata_esmf/README | 42 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 971761526e..7fb80d06bd 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -61,34 +61,34 @@ NOTES ------------------------------------------------------------ slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED ------------------------------------------------------------ -1) ./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc +1) 1x1_brazil good except: + time = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0 ; + instead of + time = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ; -.nc file issues: -- URBAN vars have bigger diffs likely bc using newer raw datasets -- abm, std elev, organic have some bigger diffs -- glacier region MV confirmed w BillS that Greenland diff is ok +2) 10x15 mostly good BUT: +- bigger diffs than I would like for NAT_PFT, though .log file shows global PFT + areas same => Gridcell-level diffs due to mapping files? Confirm we have no + discrepancy between .log and .nc files +- LAI in .log comes out shifted by one +- Soil color, ag fire peak month outputs too high in .log +- Soil txt, peat, fmax, lakes, harvest too low in .log unless raw data changed +- Slope, stddev, soildepth, urban, glaciers not appearing in .log +- VOC em factors from input not appearing in .log -.log file issues: -- Successfully made PFTs, harvest and grazing, glacier, urban, - topo stats, and organic don't show input/output for comparison -- soil texture category 3 and soil color category 15 inputs/outputs - problematic or just that we set ocean to loam? -- agricultural fire peak month: output areas increase for all categories -- voc emission factors all zero +3) --merge_gis, --nocrop work +4) --hires_pft works, but must abort for years /= 2005 (and 1850?) +5) --potveg_flag needs file(s) converted to cdf5 +6) --fast doesn't do anything as far as I can tell; do we need it? + +old) ./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc +Issues: See newer testing above ------------------------------------------------------ -NOT ALL FILES HAVE BEEN TRANSLATED to cdf5 - need to check last millenium +NOT ALL FILES HAVE BEEN TRANSLATED to cdf5 : check last millenium & PtVg ------------------------------------------------------ > nccopy -k cdf5 oldfile newfile --------------------------------------------------------- -Python script for generating namelists has NOT ADDRESSED: --------------------------------------------------------- -* Regional/1x1: handled by subset.py -* hires_pft: should work -* potveg: needs file(s) converted to cdf5 first? -* merge_gis - -------------------------------------------------------- Override options removed: -------------------------------------------------------- From a849f9548cdf227b1db0f42263b94ffb8231004f Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 23 Mar 2022 12:48:34 -0600 Subject: [PATCH 105/614] new soil texture dataset --- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 351 +++++++++++---------- tools/mksurfdata_esmf/src/mksurfdata.F90 | 22 +- 2 files changed, 206 insertions(+), 167 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 6ca1aecfec..8b165e75d3 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -33,13 +33,13 @@ module mksoiltexMod contains !================================================================================= - subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc) + subroutine mksoiltex(file_grid_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc) ! ! make %sand and %clay from IGBP soil data, which includes ! igbp soil 'mapunits' and their corresponding textures ! ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_grid_i ! input grid file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh type(file_desc_t) , intent(inout) :: pioid_o @@ -48,6 +48,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc ! local variables type(ESMF_RouteHandle) :: routehandle + type(ESMF_Grid) :: grid_i type(ESMF_Mesh) :: mesh_i type(ESMF_Field) :: field_i type(ESMF_Field) :: field_o @@ -89,7 +90,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc write(ndiag,*) write(ndiag,'(a)') 'Attempting to make %sand and %clay .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) - write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) + write(ndiag,'(a)') ' Input grid file is '//trim(file_grid_i) end if ! Determine ns_o and allocate output data @@ -104,77 +105,103 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) ! Read in input mesh + call ESMF_VMLogMemInfo("Before create grid_i in "//trim(subname)) + if (root_task) write(ndiag,*)"DEBUG: before create grid_i in "//trim(subname) + grid_i = ESMF_GridCreate(filename=trim(file_grid_i), & + fileformat=ESMF_FILEFORMAT_GRIDSPEC, addCornerStagger=.true., addmask=.true., varname='MU', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag,*)"DEBUG: before create mesh_i in "//trim(subname) call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) - mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + mesh_i = esmf_meshcreate(grid_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + if (root_task) write(ndiag,*)"DEBUG: after create mesh_i in "//trim(subname) - ! Determine ns_i + ! Determine ns_i (use the distgrid to the number of elements) call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Get the landmask from the file and reset the mesh mask based on that - allocate(rmask_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(mask_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do ni = 1,ns_i - if (rmask_i(ni) > 0._r4) then - mask_i(ni) = 1 - else - mask_i(ni) = 0 - end if - end do - call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! allocate(rmask_i(ns_i), stat=ier) + ! if (ier/=0) call shr_sys_abort() + ! allocate(mask_i(ns_i), stat=ier) + ! if (ier/=0) call shr_sys_abort() + ! call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return + ! do ni = 1,ns_i + ! if (rmask_i(ni) > 0._r4) then + ! mask_i(ni) = 1 + ! else + ! mask_i(ni) = 0 + ! end if + ! end do + ! call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return ! Read in mapunit data + if (root_task) write(ndiag,*)"DEBUG: before mapunit read in "//trim(subname) allocate(mapunit_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid_i, 'MAPUNITS', mesh_i, mapunit_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'MU', mesh_i, mapunit_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + if (root_task) write(ndiag,*)"DEBUG: after mapunit read in "//trim(subname) ! Set mapunit values to zero where the input mask is 0 + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() do ni = 1,ns_i - mapunit_i(ni) = mapunit_i(ni) * rmask_i(ni) + if (mapunit_i(ni) == 0.) then + mask_i(ni) = 0 + end if end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return ! Determine mapunit_value_max (set it as a module variable so that it can be ! accessible to gen_dominant_mapunit) - rcode = pio_inq_dimid (pioid_i, 'max_value_mapunit', dimid) - rcode = pio_inq_dimlen (pioid_i, dimid, mapunit_value_max) + ! TODO: add the max_value_mapunit to the netcdf file + ! rcode = pio_inq_dimid (pioid_i, 'max_value_mapunit', dimid) + ! rcode = pio_inq_dimlen (pioid_i, dimid, mapunit_value_max) + mapunit_value_max = 32056 ! Create ESMF fields that will be used below + if (root_task) write(ndiag,*)"DEBUG: before field_i creation "//trim(subname) field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag,*)"DEBUG: before field_o creation "//trim(subname) field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - field_dstfrac = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! field_dstfrac = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle + if (root_task) write(ndiag,*)"DEBUG: before route handle creation "//trim(subname) + ! call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + ! regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & + ! ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & + ! dstFracField= field_dstfrac, rc=rc) call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & - ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & - dstFracField= field_dstfrac, rc=rc) + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) + if (root_task) write(ndiag,*)"DEBUG: after route handle creation "//trim(subname) ! Determin frac_o - call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(frac_o(ns_o)) - frac_o(:) = dataptr_r8(:) + ! call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return + ! allocate(frac_o(ns_o)) + ! frac_o(:) = dataptr_r8(:) ! Create a dynamic mask object ! The dynamic mask object further holds a pointer to the routine that will be called in order to ! handle dynamically masked elements - in this case its DynMaskProc (see below) + if (root_task) write(ndiag,*)"DEBUG: before call to dynamic mas set creation "//trim(subname) call ESMF_DynamicMaskSetR4R8R4(dynamicMask, dynamicMaskRoutine=get_dominant_mapunit, & handleAllElements=.true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag,*)"DEBUG: after call to dynamic mas set creation "//trim(subname) ! Determine dominant soil color in the field regrid call below call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) @@ -193,143 +220,143 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc end do ! Get dimensions from input file and allocate memory for sand_i and clay_i - rcode = pio_inq_dimid (pioid_i, 'number_of_layers', dimid) - rcode = pio_inq_dimlen (pioid_i, dimid, nlay) - allocate(sand_i(mapunit_value_max,nlay), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(clay_i(mapunit_value_max,nlay), stat=ier) - if (ier/=0) call shr_sys_abort() - - ! read in sand_i and clay_i (they will read in total on all processors) - rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid) - rcode = pio_get_var(pioid_i, pio_varid, sand_i) - rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid) - rcode = pio_get_var(pioid_i, pio_varid, clay_i) - - ! Set soil texture as follows: - ! a. Use dominant igbp soil mapunit based on area of overlap unless 'no data' is dominant - ! b. If this has no data, use loam for soil texture - - do no = 1,ns_o - if (mapunit_o(no) > 0) then - ! valid value is obtained - if (mapunit_o(no) > mapunit_value_max) then - write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) - ! call shr_sys_abort("mapunit_o is out of bounds") - end if - do l = 1, nlay - sand_o(no,l) = sand_i(mapunit_o(no),l) - clay_o(no,l) = clay_i(mapunit_o(no),l) - end do - else - ! use loam - do l = 1, nlay - sand_o(no,l) = 43. - clay_o(no,l) = 18. - end do - end if - end do - - ! Define the model surface types: 0:4 - soil(0) = 'no soil: ocean, glacier, lake, no data' - soil(1) = 'clays ' - soil(2) = 'sands ' - soil(3) = 'loams ' - soil(4) = 'silts ' - - ! input grid: determine soil_i for global area comparison - allocate(soil_i(ns_i)) - do l = 1, nlay - do ni = 1,ns_i - mapunit = nint(mapunit_i(ni)) - if (mapunit==0) then - typ = 'no soil: ocean, glacier, lake, no data' - else if (clay_i(mapunit,l) >= 40.) then - typ = 'clays' - else if (sand_i(mapunit,l) >= 50.) then - typ = 'sands' - else if (clay_i(mapunit,l)+sand_i(mapunit,l) < 50.) then - if (rmask_i(ni) /= 0.) then - typ = 'silts' - else - typ = 'no soil: ocean, glacier, lake, no data' - end if - else - typ = 'loams' - end if - do m = 0, nlsm - if (typ == soil(m)) go to 101 - end do - write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunit,l), & - ' clay = ',clay_i(mapunit,l),' not assigned to soil type for input grid lon,lat,layer = ',ni,l - call shr_sys_abort() -101 continue - soil_i(ni) = m ! allocate memory for this - end do - end do - - ! output grid: determine soil_o for global area comparison - allocate(soil_o(ns_o)) - do l = 1, nlay - do no = 1,ns_o - if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then - typ = 'no soil: ocean, glacier, lake, no data' - else if (clay_o(no,l) >= 40.) then - typ = 'clays' - else if (sand_o(no,l) >= 50.) then - typ = 'sands' - else if (clay_o(no,l)+sand_o(no,l) < 50.) then - typ = 'silts' - else - typ = 'loams' - end if - do m = 0, nlsm - if (typ == soil(m)) go to 102 - end do - write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & - ' clay = ',clay_o(no,l), ' not assigned to soil type for output grid lon,lat,layer = ',no,l - call shr_sys_abort() -102 continue - soil_o(no) = m - end do - end do - - ! Compare global areas - if (root_task) then - write (ndiag,'(a)') 'The following table of soil texture classes is for comparison only.' - write (ndiag,'(a)') 'The actual data is continuous %sand, %silt and %clay not textural classes' - end if - call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & - 0, nlsm, soil_i, soil_o, 'soil texture class', ndiag, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Adjust pct sand and pct clay to be nearest integers and to be loam if pctlnd_pft is < 1.e-6 - ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero - ! (not a very small number such as 1e-16) where it really should be zero - do no = 1,ns_o - do k = 1,nlevsoi - sand_o(no,k) = float(nint(sand_o(no,k))) - clay_o(no,k) = float(nint(clay_o(no,k))) - end do - if (pctlnd_pft_o(no) < 1.e-6_r8) then - sand_o(no,:) = 43._r8 - clay_o(no,:) = 18._r8 - end if - end do +! rcode = pio_inq_dimid (pioid_i, 'number_of_layers', dimid) +! rcode = pio_inq_dimlen (pioid_i, dimid, nlay) +! allocate(sand_i(mapunit_value_max,nlay), stat=ier) +! if (ier/=0) call shr_sys_abort() +! allocate(clay_i(mapunit_value_max,nlay), stat=ier) +! if (ier/=0) call shr_sys_abort() + +! ! read in sand_i and clay_i (they will read in total on all processors) +! rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid) +! rcode = pio_get_var(pioid_i, pio_varid, sand_i) +! rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid) +! rcode = pio_get_var(pioid_i, pio_varid, clay_i) + +! ! Set soil texture as follows: +! ! a. Use dominant igbp soil mapunit based on area of overlap unless 'no data' is dominant +! ! b. If this has no data, use loam for soil texture + +! do no = 1,ns_o +! if (mapunit_o(no) > 0) then +! ! valid value is obtained +! if (mapunit_o(no) > mapunit_value_max) then +! write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) +! ! call shr_sys_abort("mapunit_o is out of bounds") +! end if +! do l = 1, nlay +! sand_o(no,l) = sand_i(mapunit_o(no),l) +! clay_o(no,l) = clay_i(mapunit_o(no),l) +! end do +! else +! ! use loam +! do l = 1, nlay +! sand_o(no,l) = 43. +! clay_o(no,l) = 18. +! end do +! end if +! end do + +! ! Define the model surface types: 0:4 +! soil(0) = 'no soil: ocean, glacier, lake, no data' +! soil(1) = 'clays ' +! soil(2) = 'sands ' +! soil(3) = 'loams ' +! soil(4) = 'silts ' + +! ! input grid: determine soil_i for global area comparison +! allocate(soil_i(ns_i)) +! do l = 1, nlay +! do ni = 1,ns_i +! mapunit = nint(mapunit_i(ni)) +! if (mapunit==0) then +! typ = 'no soil: ocean, glacier, lake, no data' +! else if (clay_i(mapunit,l) >= 40.) then +! typ = 'clays' +! else if (sand_i(mapunit,l) >= 50.) then +! typ = 'sands' +! else if (clay_i(mapunit,l)+sand_i(mapunit,l) < 50.) then +! if (mask_i(ni) /= 0) then +! typ = 'silts' +! else +! typ = 'no soil: ocean, glacier, lake, no data' +! end if +! else +! typ = 'loams' +! end if +! do m = 0, nlsm +! if (typ == soil(m)) go to 101 +! end do +! write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunit,l), & +! ' clay = ',clay_i(mapunit,l),' not assigned to soil type for input grid lon,lat,layer = ',ni,l +! call shr_sys_abort() +! 101 continue +! soil_i(ni) = m ! allocate memory for this +! end do +! end do + +! ! output grid: determine soil_o for global area comparison +! allocate(soil_o(ns_o)) +! do l = 1, nlay +! do no = 1,ns_o +! if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then +! typ = 'no soil: ocean, glacier, lake, no data' +! else if (clay_o(no,l) >= 40.) then +! typ = 'clays' +! else if (sand_o(no,l) >= 50.) then +! typ = 'sands' +! else if (clay_o(no,l)+sand_o(no,l) < 50.) then +! typ = 'silts' +! else +! typ = 'loams' +! end if +! do m = 0, nlsm +! if (typ == soil(m)) go to 102 +! end do +! write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & +! ' clay = ',clay_o(no,l), ' not assigned to soil type for output grid lon,lat,layer = ',no,l +! call shr_sys_abort() +! 102 continue +! soil_o(no) = m +! end do +! end do + +! ! Compare global areas +! if (root_task) then +! write (ndiag,'(a)') 'The following table of soil texture classes is for comparison only.' +! write (ndiag,'(a)') 'The actual data is continuous %sand, %silt and %clay not textural classes' +! end if +! ! call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & +! ! 0, nlsm, soil_i, soil_o, 'soil texture class', ndiag, rc) +! ! if (chkerr(rc,__LINE__,u_FILE_u)) return + +! ! Adjust pct sand and pct clay to be nearest integers and to be loam if pctlnd_pft is < 1.e-6 +! ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero +! ! (not a very small number such as 1e-16) where it really should be zero +! do no = 1,ns_o +! do k = 1,nlevsoi +! sand_o(no,k) = float(nint(sand_o(no,k))) +! clay_o(no,k) = float(nint(clay_o(no,k))) +! end do +! if (pctlnd_pft_o(no) < 1.e-6_r8) then +! sand_o(no,:) = 43._r8 +! clay_o(no,:) = 18._r8 +! end if +! end do ! Write out fields if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" call mkfile_output(pioid_o, mesh_o, 'mapunits', mapunit_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" - call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" + ! call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" - call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call pio_syncfile(pioid_o) + ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" + ! call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + ! call pio_syncfile(pioid_o) ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 8295873178..60de3cf141 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -320,6 +320,18 @@ program mksurfdata ! NOTE: do not deallocate pctlak, pctwet, pctglacier and pcturban + ! DEBUG + if (fsurdat /= ' ') then + ! mapunits, PCT_SAND and PCT_CLAY are written out in the subroutine + mksrf_fsoitex = '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v2_grid.nc' + mksrf_fsoitex_mesh = '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v2_grid.nc' + call mksoiltex( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pioid, pctlnd_pft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') + end if + call pio_closefile(pioid) + ! DEBUG + call shr_sys_abort('stopping just for soiltex output') + ! ----------------------------------- ! Write out natpft and cft ! ----------------------------------- @@ -446,11 +458,11 @@ program mksurfdata ! ----------------------------------- ! Make soil texture [pctsand, pctclay] ! ----------------------------------- - if (fsurdat /= ' ') then - ! mapunits, PCT_SAND and PCT_CLAY are written out in the subroutine - call mksoiltex( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pioid, pctlnd_pft, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') - end if + ! if (fsurdat /= ' ') then + ! ! mapunits, PCT_SAND and PCT_CLAY are written out in the subroutine + ! call mksoiltex( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pioid, pctlnd_pft, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') + ! end if ! ----------------------------------- ! Make soil color classes [soicol] [fsoicol] From 717bbd3a8be68d10ce767dd5561d5fd8b09f87aa Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 24 Mar 2022 17:45:28 -0600 Subject: [PATCH 106/614] Add transient urban & lake entries to the landuse_timeseries...txt file Next clarify whether this should happen for specific year ranges since the urban spans 2000-2100 and the lake spans 1850-2017 --- .../gen_mksurfdata_namelist.py | 26 ++++++++++++++++++- .../gen_mksurfdata_namelist.xml | 9 +++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 26a6547788..cf2382907a 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -374,6 +374,14 @@ def main (): print(f"ERROR: input mesh file {rawdata_files[new_key]} does not exist") sys.exit(30) + if item.tag == 'lake_filename': + new_key = f"{child1.tag}_lake" + rawdata_files[new_key] = os.path.join(input_path, item.text) + + if item.tag == 'urban_filename': + new_key = f"{child1.tag}_urban" + rawdata_files[new_key] = os.path.join(input_path, item.text) + # determine output mesh tree2 = ET.parse('../../ccs_config/component_grids_nuopc.xml') root = tree2.getroot() @@ -424,18 +432,34 @@ def main (): for year in range(start_year, end_year + 1): if year <= 2015: file1 = rawdata_files["mksrf_fvegtyp"] + file2 = rawdata_files["mksrf_fvegtyp_urban"] + file3 = rawdata_files["mksrf_fvegtyp_lake"] else: file1 = rawdata_files["mksrf_fvegtyp_ssp"] + file2 = rawdata_files["mksrf_fvegtyp_ssp_urban"] + file3 = rawdata_files["mksrf_fvegtyp_ssp_lake"] landuse_input_fname = file1.replace("%y",str(year)) + landuse_input_fnam2 = file2.replace("%y",str(year)) + landuse_input_fnam3 = file3.replace("%y",str(year)) if not os.path.isfile(landuse_input_fname): - print(f"ERROR: landunit_input_fname: {landuse_input_fname} does not exit") + print(f"ERROR: landunit_input_fname: {landuse_input_fname} does not exist") + sys.exit(60) +# if not os.path.isfile(landuse_input_fnam2): +# print(f"ERROR: landunit_input_fnam2: {landuse_input_fnam2} does not exist") +# sys.exit(60) + if not os.path.isfile(landuse_input_fnam3): + print(f"ERROR: landunit_input_fnam3: {landuse_input_fnam3} does not exist") sys.exit(60) # -- Each line is written twice in the original perl code: landuse_line = f"{landuse_input_fname:<196}{str(year)}\n" + landuse_lin2 = f"{landuse_input_fnam2:<196}{str(year)}\n" + landuse_lin3 = f"{landuse_input_fnam3:<196}{str(year)}\n" landuse_file.write(landuse_line) landuse_file.write(landuse_line) + landuse_file.write(landuse_lin2) + landuse_file.write(landuse_lin3) logger.debug(f"year : {year}") logger.debug(landuse_line) print(f"Successfully created input landuse file {landuse_fname}") diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index e345e26cdc..59c0cfdf7d 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -251,6 +251,8 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20220305/mksrf_landuse_ctsm52_histLUH2_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + /glade/work/ivanderk/inputdata/rawdata/timeseries/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y_c20200305.nc + /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc @@ -263,36 +265,43 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP26_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP19_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP2RCP45_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP3RCP70_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP34_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP60_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP5RCP85_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc From 5c6c5b38d4ffedde3b8d89cf8abf78c42318fbc0 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 24 Mar 2022 18:10:01 -0600 Subject: [PATCH 107/614] Uncomment error check for completeness --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index cf2382907a..c35ec7b0e7 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -445,9 +445,9 @@ def main (): if not os.path.isfile(landuse_input_fname): print(f"ERROR: landunit_input_fname: {landuse_input_fname} does not exist") sys.exit(60) -# if not os.path.isfile(landuse_input_fnam2): -# print(f"ERROR: landunit_input_fnam2: {landuse_input_fnam2} does not exist") -# sys.exit(60) + if not os.path.isfile(landuse_input_fnam2): + print(f"ERROR: landunit_input_fnam2: {landuse_input_fnam2} does not exist") + sys.exit(60) if not os.path.isfile(landuse_input_fnam3): print(f"ERROR: landunit_input_fnam3: {landuse_input_fnam3} does not exist") sys.exit(60) From 64162f3c7c01ee47705b4cfeb5ec97d574030a66 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 24 Mar 2022 18:19:10 -0600 Subject: [PATCH 108/614] Added notes to README --- tools/mksurfdata_esmf/README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 7fb80d06bd..60c8bbdcdc 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -61,12 +61,12 @@ NOTES ------------------------------------------------------------ slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED ------------------------------------------------------------ -1) 1x1_brazil good except: +1) 1x1_brazil good (min number-of-nodes tested: 4) except: time = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0 ; instead of time = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ; -2) 10x15 mostly good BUT: +2) 10x15 mostly good (min number-of-nodes tested: 3) BUT: - bigger diffs than I would like for NAT_PFT, though .log file shows global PFT areas same => Gridcell-level diffs due to mapping files? Confirm we have no discrepancy between .log and .nc files From f7f4182312b0994052f6b376ce0e3cf872b7c05b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 25 Mar 2022 19:07:10 -0600 Subject: [PATCH 109/614] Skip over lakedepth when transient; update .xml for transient --- .../gen_mksurfdata_namelist.xml | 25 +++--- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 78 ++++++++++--------- tools/mksurfdata_esmf/src/mksurfdata.F90 | 2 +- 3 files changed, 58 insertions(+), 47 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 59c0cfdf7d..d21fb582b2 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -251,8 +251,8 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20220305/mksrf_landuse_ctsm52_histLUH2_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - /glade/work/ivanderk/inputdata/rawdata/timeseries/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y_c20200305.nc - /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc + /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc @@ -265,43 +265,50 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP26_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc + /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP19_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc + /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP2RCP45_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc + /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP3RCP70_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc + /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP34_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc + /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP60_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc + /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP5RCP85_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc - /glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_%y_NoAdjust_c20220215.nc + /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 30c53a5ee9..e6cf8641fc 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -31,7 +31,7 @@ module mklanwatMod contains !=============================================================== - subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, fsurdat, rc) + subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, fsurdat, rc, do_depth) ! ------------------- ! make %lake and lake depth @@ -47,6 +47,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, fsurdat, real(r8) , intent(out) :: lake_o(:) ! output grid: %lake character(len=*) , intent(in) :: fsurdat integer , intent(out) :: rc + logical, optional , intent(in) :: do_depth ! do the depth part of the subroutine ! local variables type(ESMF_RouteHandle) :: routehandle @@ -71,7 +72,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, fsurdat, write(ndiag,*) write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) - write(ndiag,'(a)')'Attempting to %lake, %wetland and lakdepth data' + write(ndiag,'(a)')'Attempting to make lake data' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if @@ -154,42 +155,46 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, fsurdat, ! Create lake parameter (lakedepth) ! ---------------------------------------- - if (root_task) then - write (ndiag,*) 'Attempting to make lake depth .....' - end if - - ! lakedepth - allocate(lakedepth_i(ns_i), stat=rcode) - if (rcode/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid_i, 'LAKEDEPTH', mesh_i, lakedepth_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! regrid lakedepth_i to lakedepth_o - this also returns lakedepth_i to be used in the global sums below - allocate (lakedepth_o(ns_o)); lakedepth_o(:) = spval - call regrid_rawdata(mesh_i, mesh_o, routehandle, lakedepth_i, lakedepth_o, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regrid_rawdata for lakedepth in "//trim(subname)) - do no = 1,ns_o - if (frac_o(no) == 0._r8) then - lakedepth_o(no) = 10._r8 + if (present(do_depth)) then + if (do_depth) then + if (root_task) then + write (ndiag,*) 'Attempting to make lake depth .....' + end if + + ! lakedepth + allocate(lakedepth_i(ns_i), stat=rcode) + if (rcode/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid_i, 'LAKEDEPTH', mesh_i, lakedepth_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! regrid lakedepth_i to lakedepth_o - this also returns lakedepth_i to be used in the global sums below + allocate (lakedepth_o(ns_o)); lakedepth_o(:) = spval + call regrid_rawdata(mesh_i, mesh_o, routehandle, lakedepth_i, lakedepth_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regrid_rawdata for lakedepth in "//trim(subname)) + do no = 1,ns_o + if (frac_o(no) == 0._r8) then + lakedepth_o(no) = 10._r8 + end if + enddo + if (min_bad(lakedepth_o, min_valid_lakedepth, 'lakedepth')) then + call shr_sys_abort() + end if + + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out lakedepth" + call mkfile_output(pioid_o, mesh_o, 'LAKEDEPTH', lakedepth_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) + end if + + ! Check global areas for lake depth + call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & + lakedepth_i, lakedepth_o, "lake depth", "m", ndiag, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - enddo - if (min_bad(lakedepth_o, min_valid_lakedepth, 'lakedepth')) then - call shr_sys_abort() - end if - - if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out lakedepth" - call mkfile_output(pioid_o, mesh_o, 'LAKEDEPTH', lakedepth_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call pio_syncfile(pioid_o) end if - ! Check global areas for lake depth - call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - lakedepth_i, lakedepth_o, "lake depth", "m", ndiag, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! ---------------------------------------- ! Wrap things up ! ---------------------------------------- @@ -204,8 +209,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, fsurdat, if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() if (root_task) then - write (ndiag,*) 'Successfully made %lake' - write (ndiag,*) 'Successfully made lake depth' + write (ndiag,*) 'Successfully made lake data' end if call ESMF_VMLogMemInfo("At end of "//trim(subname)) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 13e4a7a511..4fc67fa02f 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -418,7 +418,7 @@ program mksurfdata ! Need to keep pctlak and pctwet external for use below allocate ( pctlak(lsize_o)) ; pctlak(:) = spval allocate ( pctlak_max(lsize_o)) ; pctlak_max(:) = spval - call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, pctlak, pioid, fsurdat, rc=rc) + call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, pctlak, pioid, fsurdat, rc=rc, do_depth=.true.) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') allocate ( pctwet(lsize_o)) ; pctwet(:) = spval From ac9a2508edcfa60d48a909b273ac9d3cc079f377 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 28 Mar 2022 15:26:13 -0600 Subject: [PATCH 110/614] Delete deallocate statement for transient urban to work correctly --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 4fc67fa02f..59edf1d19d 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -663,7 +663,6 @@ program mksurfdata call mkurbanpar(mksrf_furban, pioid, mesh_model, urban_region, urban_classes_g, & urban_skip_abort_on_invalid_data_check) end if - deallocate(urban_region) ! ----------------------------------- ! Write out PCT_URBAN, PCT_GLACIER, PCT_LAKE and PCT_WETLAND and From 6ce95449d8eae214c5739a65636c534bb5cd8ad6 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 28 Mar 2022 15:39:59 -0600 Subject: [PATCH 111/614] Revert "Merge remote-tracking branch 'olyson/dynurb_mksurf_ctsm5.2.mksurfdata_I1564' into feature/new_mksurfdata" This reverts commit ff4d156803c27aa35770f83ce42db8abcf7c4d78, reversing changes made to 8a1138486c82e84b6dc979de2958fd651f5aaea0. I'm reverting this merge (1587 --> 1663) because I have failed to run mksurfdata_map (the old fsurdat tool) when I'm told that it should work. I suspect my merge is missing something needed for the old fsurdat tool to work. For a version that has worked, see @olyson's comment: https://github.com/ESCOMP/CTSM/pull/1663#issuecomment-1079500923 --- tools/mksurfdata_map/mksurfdata.pl | 6 - tools/mksurfdata_map/src/mkfileMod.F90 | 13 - tools/mksurfdata_map/src/mklanwatMod.F90 | 33 +- tools/mksurfdata_map/src/mkpftUtilsMod.F90 | 40 +++ tools/mksurfdata_map/src/mksurfdat.F90 | 377 ++++++++++++--------- tools/mksurfdata_map/src/mkurbanparMod.F90 | 29 +- 6 files changed, 257 insertions(+), 241 deletions(-) diff --git a/tools/mksurfdata_map/mksurfdata.pl b/tools/mksurfdata_map/mksurfdata.pl index ac8ba8ef84..b0363704ae 100755 --- a/tools/mksurfdata_map/mksurfdata.pl +++ b/tools/mksurfdata_map/mksurfdata.pl @@ -284,12 +284,6 @@ sub write_transient_timeseries_file { my $hrvtypyr = `$scrdir/../../bld/queryDefaultNamelist.pl $queryfilopts $resolhrv -options sim_year='$yr',ssp_rcp=${ssp_rcp}${mkcrop} -var mksrf_fvegtyp -namelist clmexp`; chomp( $hrvtypyr ); printf $fh_landuse_timeseries $dynpft_format, $hrvtypyr, $yr; - my $urbanyr = "/glade/scratch/keerzhang/archive/BNU_NoAdjust/05deg_".$yr."_new_NoAdjust.nc"; - chomp( $urbanyr); # !KZ I hard coded this part just to generate a txt file with urban raw data file locations - printf $fh_landuse_timeseries $dynpft_format, $urbanyr, $yr; # And note that I made no change to the "landuse_timeseries_override_$desc.txt" because I am not sure how to deal with the the 'pft_override' option - my $lakeyr = "/glade/work/ivanderk/inputdata/rawdata/timeseries/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_2017_c20200305.nc"; - chomp( $lakeyr); - printf $fh_landuse_timeseries $dynpft_format, $lakeyr, $yr; if ( $yr % 100 == 0 ) { print "year: $yr\n"; } diff --git a/tools/mksurfdata_map/src/mkfileMod.F90 b/tools/mksurfdata_map/src/mkfileMod.F90 index abba061b69..43bdda4c12 100644 --- a/tools/mksurfdata_map/src/mkfileMod.F90 +++ b/tools/mksurfdata_map/src/mkfileMod.F90 @@ -540,20 +540,7 @@ subroutine mkfile(domain, fname, harvdata, dynlanduse) deallocate(ind1D, ind2D) else - call ncd_def_spatial_var(ncid=ncid, varname='PCT_URBAN', xtype=xtype, & - lev1name='numurbl', lev2name='time', & - long_name='percent urban for each density type', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_URBAN_MAX', xtype=xtype, & - lev1name='numurbl', & - long_name='maximum percent urban for each density type', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_LAKE', xtype=xtype, & - lev1name="time", long_name='percent lake', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='PCT_LAKE_MAX', xtype=xtype, & - long_name='maximum percent lake', units='unitless') - call harvdata%getFieldsIdx( ind1D, ind2D ) do j = 1, harvdata%num1Dfields() call ncd_def_spatial_var(ncid=ncid, varname=mkharvest_fieldname(ind1D(j),constant=.false.), xtype=xtype, & diff --git a/tools/mksurfdata_map/src/mklanwatMod.F90 b/tools/mksurfdata_map/src/mklanwatMod.F90 index 67b03723bd..4e1c590803 100644 --- a/tools/mksurfdata_map/src/mklanwatMod.F90 +++ b/tools/mksurfdata_map/src/mklanwatMod.F90 @@ -24,10 +24,10 @@ module mklanwatMod private ! !PUBLIC MEMBER FUNCTIONS: - public mklakwat ! make % lake - public mkwetlnd ! make % wetland - public mklakparams ! make lake parameters - public update_max_array_lake ! Update the maximum lake percent + public mklakwat ! make % lake + public mkwetlnd ! make % wetland + public mklakparams ! make lake parameters + !EOP !=============================================================== contains @@ -499,30 +499,5 @@ subroutine mklakparams(ldomain, mapfname, datfname, ndiag, & call shr_sys_flush(6) end subroutine mklakparams -!------------------------------------------------------------------------------ - -!----------------------------------------------------------------------- -subroutine update_max_array_lake(pct_lakmax_arr,pct_lake_arr) - ! - ! !DESCRIPTION: - ! Update the maximum lake percent for landuse.timeseries file - ! - ! !ARGUMENTS: - real(r8) , intent(inout):: pct_lakmax_arr(:) ! max lake percent - real(r8) , intent(in):: pct_lake_arr(:) ! lake percent that is used to update the old pct_lakmax_arr - ! - ! !LOCAL VARIABLES: - integer :: n,ns ! indices - - character(len=*), parameter :: subname = 'update_max_array_lake' - !----------------------------------------------------------------------- - ns = size(pct_lake_arr,1) - do n = 1, ns - if (pct_lake_arr(n) > pct_lakmax_arr(n)) then - pct_lakmax_arr(n) = pct_lake_arr(n) - end if - end do - -end subroutine update_max_array_lake end module mklanwatMod diff --git a/tools/mksurfdata_map/src/mkpftUtilsMod.F90 b/tools/mksurfdata_map/src/mkpftUtilsMod.F90 index 0faede43a1..4a9ea12f97 100644 --- a/tools/mksurfdata_map/src/mkpftUtilsMod.F90 +++ b/tools/mksurfdata_map/src/mkpftUtilsMod.F90 @@ -24,6 +24,7 @@ module mkpftUtilsMod ! !PUBLIC MEMBER FUNCTIONS: ! public :: convert_from_p2g ! Convert a p2g array into pct_pft_type objects + public :: adjust_total_veg_area ! Adjust the total vegetated area (natural veg & crop) to a new specified total ! ! !PRIVATE MEMBER FUNCTIONS: @@ -212,6 +213,45 @@ function get_default_cft() result(default_cft) end function get_default_cft + + !----------------------------------------------------------------------- + subroutine adjust_total_veg_area(new_total_pct, pctnatpft, pctcft) + ! + ! !DESCRIPTION: + ! Adjust the total vegetated area on the grid cell (natural veg & crop) to a new + ! specified total. + ! + ! If the old areas are 0%, then all the new area goes into pctnatpft. + ! + ! !USES: + use mkpctPftTypeMod, only : pct_pft_type + ! + ! !ARGUMENTS: + real(r8), intent(in) :: new_total_pct ! new total % of natural veg + crop landunits + class(pct_pft_type), intent(inout) :: pctnatpft ! natural veg cover information + class(pct_pft_type), intent(inout) :: pctcft ! crop cover information + ! + ! !LOCAL VARIABLES: + real(r8) :: natpft_l2g ! grid cell % cover of nat. veg. + real(r8) :: cft_l2g ! grid cell % cover of crop + real(r8) :: old_total ! old total % cover of natural veg + crop landunits + + character(len=*), parameter :: subname = 'adjust_total_veg_area' + !----------------------------------------------------------------------- + + natpft_l2g = pctnatpft%get_pct_l2g() + cft_l2g = pctcft%get_pct_l2g() + old_total = natpft_l2g + cft_l2g + if (old_total > 0._r8) then + call pctnatpft%set_pct_l2g(natpft_l2g * new_total_pct / old_total) + call pctcft%set_pct_l2g(cft_l2g * new_total_pct / old_total) + else + call pctnatpft%set_pct_l2g(new_total_pct) + end if + + end subroutine adjust_total_veg_area + + end module mkpftUtilsMod diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 index ba51a4480c..aa965f097d 100644 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ b/tools/mksurfdata_map/src/mksurfdat.F90 @@ -22,14 +22,14 @@ program mksurfdat soil_color, mksoilcol, mkorganic, & soil_fmax, mkfmax use mkvocefMod , only : mkvocef - use mklanwatMod , only : mklakwat, mkwetlnd, mklakparams, update_max_array_lake + use mklanwatMod , only : mklakwat, mkwetlnd, mklakparams use mkglacierregionMod , only : mkglacierregion use mkglcmecMod , only : nglcec, mkglcmec, mkglcmecInit, mkglacier use mkharvestMod , only : mkharvest, mkharvest_init, mkharvest_fieldname use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride use mkharvestMod , only : harvestDataType use mkurbanparCommonMod, only : mkelev - use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, numurbl, update_max_array_urban + use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, numurbl use mkutilsMod , only : normalize_classes_by_gcell use mkfileMod , only : mkfile use mkvarpar , only : nlevsoi, elev_thresh, numstdpft @@ -80,8 +80,6 @@ program mksurfdat character(len=256) :: fdyndat ! dynamic landuse data file name character(len=256) :: fname ! generic filename character(len=256) :: fhrvname ! generic harvest filename - character(len=256) :: furbname ! generic transient urban land cover filename - character(len=256) :: flakname ! generic lake filename character(len=256) :: string ! string read in integer :: t1 ! timer real(r8),parameter :: p5 = 0.5_r8 ! constant @@ -108,10 +106,8 @@ program mksurfdat real(r8), allocatable :: elevclass(:) ! glacier_mec elevation classes integer, allocatable :: glacier_region(:) ! glacier region ID real(r8), allocatable :: pctlak(:) ! percent of grid cell that is lake - real(r8), allocatable :: pctlak_max(:) ! maximum percent of grid cell that is lake real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland real(r8), allocatable :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) - real(r8), allocatable :: pcturb_max(:,:) ! maximum percent cover of each urban class, as % of grid cell real(r8), allocatable :: urbn_classes(:,:) ! percent cover of each urban class, as % of total urban area real(r8), allocatable :: urbn_classes_g(:,:)! percent cover of each urban class, as % of grid cell real(r8), allocatable :: elev(:) ! glc elevation (m) @@ -137,9 +133,7 @@ program mksurfdat real(r8), allocatable :: vic_ws(:) ! VIC Ws parameter (unitless) real(r8), allocatable :: vic_dsmax(:) ! VIC Dsmax parameter (mm/day) real(r8), allocatable :: vic_ds(:) ! VIC Ds parameter (unitless) - real(r8), allocatable :: lakedepth(:) ! lake depth (m) - real(r8), allocatable :: pctwet_orig(:) ! percent wetland of gridcell before dynamic land use adjustments - real(r8), allocatable :: pctgla_orig(:) ! percent glacier of gridcell before dynamic land use adjustments + real(r8), allocatable :: lakedepth(:) ! lake depth (m) real(r8) :: std_elev = -999.99_r8 ! Standard deviation of elevation (m) to use for entire grid @@ -279,7 +273,7 @@ program mksurfdat ! ====================================== ! Optionally specify setting for: ! ====================================== - ! mksrf_fdynuse ----- ASCII text file that lists each year of pft, urban, and lake files to use + ! mksrf_fdynuse ----- ASCII text file that lists each year of pft files to use ! mksrf_gridtype ---- Type of grid (default is 'global') ! outnc_double ------ If output should be in double precision ! outnc_large_files - If output should be in NetCDF large file format @@ -446,11 +440,9 @@ program mksurfdat pctcft(ns_o) , & pctcft_max(ns_o) , & pctgla(ns_o) , & - pctlak(ns_o) , & - pctlak_max(ns_o) , & + pctlak(ns_o) , & pctwet(ns_o) , & pcturb(ns_o) , & - pcturb_max(ns_o,numurbl) , & urban_region(ns_o) , & urbn_classes(ns_o,numurbl) , & urbn_classes_g(ns_o,numurbl) , & @@ -468,9 +460,7 @@ program mksurfdat vic_dsmax(ns_o) , & vic_ds(ns_o) , & lakedepth(ns_o) , & - glacier_region(ns_o) , & - pctwet_orig(ns_o) , & - pctgla_orig(ns_o) ) + glacier_region(ns_o) ) landfrac_pft(:) = spval pctlnd_pft(:) = spval pftdata_mask(:) = -999 @@ -653,10 +643,6 @@ program mksurfdat ndiag=ndiag, zero_out=all_veg, urbn_o=pcturb, urbn_classes_o=urbn_classes, & region_o=urban_region) - ! Save special land unit areas of surface dataset - pctwet_orig(:) = pctwet(:) - pctgla_orig(:) = pctgla(:) - ! Make elevation [elev] from [ftopo, ffrac] dataset ! Used only to screen pcturb ! Screen pcturb by elevation threshold from elev dataset @@ -675,6 +661,7 @@ program mksurfdat where (elev .gt. elev_thresh) pcturb = 0._r8 end where + deallocate(elev) end if ! Compute topography statistics [topo_stddev, slope] from [ftopostats] @@ -721,6 +708,62 @@ program mksurfdat call change_landuse( ldomain, dynpft=.false. ) + do n = 1,ns_o + + ! Truncate all percentage fields on output grid. This is needed to + ! insure that wt is zero (not a very small number such as + ! 1e-16) where it really should be zero + + do k = 1,nlevsoi + pctsand(n,k) = float(nint(pctsand(n,k))) + pctclay(n,k) = float(nint(pctclay(n,k))) + end do + pctlak(n) = float(nint(pctlak(n))) + pctwet(n) = float(nint(pctwet(n))) + pctgla(n) = float(nint(pctgla(n))) + + ! Assume wetland, glacier and/or lake when dataset landmask implies ocean + ! (assume medium soil color (15) and loamy texture). + ! Also set pftdata_mask here + + if (pctlnd_pft(n) < 1.e-6_r8) then + pftdata_mask(n) = 0 + soicol(n) = 15 + if (pctgla(n) < 1.e-6_r8) then + pctwet(n) = 100._r8 - pctlak(n) + pctgla(n) = 0._r8 + else + pctwet(n) = max(100._r8 - pctgla(n) - pctlak(n), 0.0_r8) + end if + pcturb(n) = 0._r8 + call pctnatpft(n)%set_pct_l2g(0._r8) + call pctcft(n)%set_pct_l2g(0._r8) + pctsand(n,:) = 43._r8 + pctclay(n,:) = 18._r8 + organic(n,:) = 0._r8 + else + pftdata_mask(n) = 1 + end if + + ! Make sure sum of land cover types does not exceed 100. If it does, + ! subtract excess from most dominant land cover. + + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + if (suma > 250._r4) then + write (6,*) subname, ' error: sum of pctlak, pctwet,', & + 'pcturb and pctgla is greater than 250%' + write (6,*)'n,pctlak,pctwet,pcturb,pctgla= ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n) + call abort() + else if (suma > 100._r4) then + pctlak(n) = pctlak(n) * 100._r8/suma + pctwet(n) = pctwet(n) * 100._r8/suma + pcturb(n) = pcturb(n) * 100._r8/suma + pctgla(n) = pctgla(n) * 100._r8/suma + end if + + end do + call normalizencheck_landuse(ldomain) ! Write out sum of PFT's @@ -1018,11 +1061,14 @@ program mksurfdat ! Deallocate arrays NOT needed for dynamic-pft section of code + deallocate ( organic ) deallocate ( ef1_btr, ef1_fet, ef1_fdt, ef1_shr, ef1_grs, ef1_crp ) deallocate ( pctglcmec, topoglcmec) if ( outnc_3dglc ) deallocate ( pctglc_gic, pctglc_icesheet) deallocate ( elevclass ) deallocate ( fmax ) + deallocate ( pctsand, pctclay ) + deallocate ( soicol ) deallocate ( gdp, fpeat, agfirepkmon ) deallocate ( soildepth ) deallocate ( topo_stddev, slope ) @@ -1083,8 +1129,6 @@ program mksurfdat pctnatpft_max = pctnatpft pctcft_max = pctcft - pcturb_max = urbn_classes_g - pctlak_max = pctlak ntim = 0 do @@ -1114,21 +1158,6 @@ program mksurfdat call abort() end if end if - ! Read input urban data - read(nfdyn, '(A195,1x,I4)', iostat=ier) furbname, year2 - if ( year2 /= year ) then - write(6,*) subname, ' error: year for urban not equal to year for PFT files' - call abort() - end if - write(6,*)'input urban dynamic dataset for year ', year2, ' is : ', trim(furbname) - ! Read input lake data - read(nfdyn, '(A195,1x,I4)', iostat=ier) flakname, year2 - if ( year2 /= year ) then - write(6,*) subname, ' error: year for lake not equal to year for PFT files' - call abort() - end if - write(6,*)'input lake dynamic dataset for year ', year2, ' is : ', trim(flakname) - ntim = ntim + 1 ! Create pctpft data at model resolution @@ -1157,49 +1186,21 @@ program mksurfdat end if end do - ! Create pctlak data at model resolution (use original mapping file from lake data) - call mklakwat (ldomain, mapfname=map_flakwat, datfname=flakname, & - ndiag=ndiag, zero_out=all_urban.or.all_veg, lake_o=pctlak) - - call mkurban (ldomain, mapfname=map_furban, datfname=furbname, & - ndiag=ndiag, zero_out=all_veg, urbn_o=pcturb, urbn_classes_o=urbn_classes, & - region_o=urban_region) - ! screen pcturb using elevation - if ( .not. all_urban .and. .not. all_veg )then - where (elev .gt. elev_thresh) - pcturb = 0._r8 - end where - end if - - ! For landunits NOT read each year: reset to their pre-adjustment values in - ! preparation for redoing landunit area normalization - pctwet(:) = pctwet_orig(:) - pctgla(:) = pctgla_orig(:) - call change_landuse(ldomain, dynpft=.true.) call normalizencheck_landuse(ldomain) - call normalize_classes_by_gcell(urbn_classes, pcturb, urbn_classes_g) - + call update_max_array(pctnatpft_max,pctnatpft) call update_max_array(pctcft_max,pctcft) - call update_max_array_urban(pcturb_max,urbn_classes_g) - call update_max_array_lake(pctlak_max,pctlak) ! Output time-varying data for current year - + call check_ret(nf_inq_varid(ncid, 'PCT_NAT_PFT', varid), subname) call ncd_put_time_slice(ncid, varid, ntim, get_pct_p2l_array(pctnatpft)) call check_ret(nf_inq_varid(ncid, 'PCT_CROP', varid), subname) call ncd_put_time_slice(ncid, varid, ntim, get_pct_l2g_array(pctcft)) - - call check_ret(nf_inq_varid(ncid, 'PCT_URBAN', varid), subname) - call ncd_put_time_slice(ncid, varid, ntim, urbn_classes_g) - - call check_ret(nf_inq_varid(ncid, 'PCT_LAKE', varid), subname) - call ncd_put_time_slice(ncid, varid, ntim, pctlak) - + if (num_cft > 0) then call check_ret(nf_inq_varid(ncid, 'PCT_CFT', varid), subname) call ncd_put_time_slice(ncid, varid, ntim, get_pct_p2l_array(pctcft)) @@ -1232,19 +1233,13 @@ program mksurfdat call check_ret(nf_sync(ncid), subname) end do ! end of read loop - + call check_ret(nf_inq_varid(ncid, 'PCT_NAT_PFT_MAX', varid), subname) call check_ret(nf_put_var_double(ncid, varid, get_pct_p2l_array(pctnatpft_max)), subname) call check_ret(nf_inq_varid(ncid, 'PCT_CROP_MAX', varid), subname) call check_ret(nf_put_var_double(ncid, varid, get_pct_l2g_array(pctcft_max)), subname) - call check_ret(nf_inq_varid(ncid, 'PCT_URBAN_MAX', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pcturb_max), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_LAKE_MAX', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pctlak_max), subname) - if (num_cft > 0) then call check_ret(nf_inq_varid(ncid, 'PCT_CFT_MAX', varid), subname) call check_ret(nf_put_var_double(ncid, varid, get_pct_p2l_array(pctcft_max)), subname) @@ -1343,9 +1338,11 @@ subroutine normalizencheck_landuse(ldomain) ! Normalize land use and make sure things add up to 100% as well as ! checking that things are as they should be. ! -! +! Precondition: pctlak + pctwet + pcturb + pctgla <= 100 (within roundoff) ! ! !USES: + use mkpftConstantsMod , only : baregroundindex + use mkpftUtilsMod , only : adjust_total_veg_area implicit none ! !ARGUMENTS: type(domain_type) :: ldomain @@ -1360,61 +1357,24 @@ subroutine normalizencheck_landuse(ldomain) integer :: nsmall ! number of small PFT values for a single check integer :: nsmall_tot ! total number of small PFT values in all grid cells real(r8) :: suma ! sum for error check - real(r8) :: new_total_natveg_pct ! new % veg (% of grid cell, natural veg) + real(r8) :: suma2 ! another sum for error check + real(r8) :: new_total_veg_pct ! new % veg (% of grid cell, total of natural veg & crop) + real(r8) :: bare_pct_p2g ! % of bare soil, as % of grid cell + real(r8) :: bare_urb_diff ! difference between bare soil and urban % + real(r8) :: pcturb_excess ! excess urban % not accounted for by bare soil + real(r8) :: sum8, sum8a ! sum for error check + real(r4) :: sum4a ! sum for error check real(r8), parameter :: tol_loose = 1.e-4_r8 ! tolerance for some 'loose' error checks real(r8), parameter :: toosmallPFT = 1.e-10_r8 ! tolerance for PFT's to ignore character(len=32) :: subname = 'normalizencheck_landuse' ! subroutine name !----------------------------------------------------------------------- - ns_o = ldomain%ns - do n = 1,ns_o - ! Truncate all percentage fields on output grid. This is needed to - ! insure that wt is zero (not a very small number such as - ! 1e-16) where it really should be zero - - do k = 1,nlevsoi - pctsand(n,k) = float(nint(pctsand(n,k))) - pctclay(n,k) = float(nint(pctclay(n,k))) - end do - pctlak(n) = float(nint(pctlak(n))) - pctwet(n) = float(nint(pctwet(n))) - pctgla(n) = float(nint(pctgla(n))) - - ! Assume wetland, glacier and/or lake when dataset landmask implies ocean - ! (assume medium soil color (15) and loamy texture). - ! Also set pftdata_mask here - - if (pctlnd_pft(n) < 1.e-6_r8) then - pftdata_mask(n) = 0 - soicol(n) = 15 - if (pctgla(n) < 1.e-6_r8) then - pctwet(n) = 100._r8 - pctlak(n) - pctgla(n) = 0._r8 - else - pctwet(n) = max(100._r8 - pctgla(n) - pctlak(n), 0.0_r8) - end if - pcturb(n) = 0._r8 - call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) - pctsand(n,:) = 43._r8 - pctclay(n,:) = 18._r8 - organic(n,:) = 0._r8 - else - pftdata_mask(n) = 1 - end if - - ! Make sure sum of all land cover types except natural vegetation - ! does not exceed 100. If it does, subtract excess from these land cover - ! types proportionally. + ! ------------------------------------------------------------------------ + ! Normalize vegetated area so that vegetated + special area is 100% + ! ------------------------------------------------------------------------ - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() - if (suma > 100._r4) then - pctlak(n) = pctlak(n) * 100._r8/suma - pctwet(n) = pctwet(n) * 100._r8/suma - pcturb(n) = pcturb(n) * 100._r8/suma - pctgla(n) = pctgla(n) * 100._r8/suma - call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8/suma) - end if + ns_o = ldomain%ns + do n = 1,ns_o ! Check preconditions if ( pctlak(n) < 0.0_r8 )then @@ -1437,33 +1397,79 @@ subroutine normalizencheck_landuse(ldomain) write(6,*) 'n, pctgla = ', n, pctgla(n) call abort() end if - if ( pctcft(n)%get_pct_l2g() < 0.0_r8 )then - write(6,*) subname, ' ERROR: pctcrop is negative!' - write(6,*) 'n, pctcrop = ', n, pctcft(n)%get_pct_l2g() + + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + if (suma > (100._r8 + tol_loose)) then + write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla must be' + write(6,*) '<= 100% before calling this subroutine' + write(6,*) 'n, pctlak, pctwet, pcturb, pctgla = ', & + n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) call abort() end if - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() - if (suma > (100._r8 + tol_loose)) then - write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla + pctcrop must be' - write(6,*) '<= 100% before normalizing natural vegetation area' - write(6,*) 'n, pctlak, pctwet, pcturb, pctgla, pctcrop = ', & - n, pctlak(n), pctwet(n), pcturb(n), pctgla(n), pctcft(n)%get_pct_l2g() + ! First normalize vegetated (natural veg + crop) cover so that the total of + ! (vegetated + (special excluding urban)) is 100%. We'll deal with urban later. + ! + ! Note that, in practice, the total area of natural veg + crop is typically 100% + ! going into this routine. However, the following code does NOT rely on this, and + ! will work properly regardless of the initial area of natural veg + crop (even if + ! that initial area is 0%). + + suma = pctlak(n)+pctwet(n)+pctgla(n) + new_total_veg_pct = 100._r8 - suma + ! correct for rounding error: + new_total_veg_pct = max(new_total_veg_pct, 0._r8) + + call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) + + ! Make sure we did the above rescaling correctly + + suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + if (abs(suma - 100._r8) > tol_loose) then + write(6,*) subname, ' ERROR in rescaling veg based on (special excluding urban' + write(6,*) 'suma = ', suma call abort() end if - ! Natural vegetated cover is 100% minus the sum of all other landunits + ! Now decrease the vegetated area to account for urban area. Urban needs to be + ! handled specially because we replace bare soil preferentially with urban, rather + ! than rescaling all PFTs equally. - new_total_natveg_pct = 100._r8 - suma - ! correct for rounding error: - new_total_natveg_pct = max(new_total_natveg_pct, 0._r8) + if (pcturb(n) > 0._r8) then + + ! Replace bare soil preferentially with urban + bare_pct_p2g = pctnatpft(n)%get_one_pct_p2g(baregroundindex) + bare_urb_diff = bare_pct_p2g - pcturb(n) + bare_pct_p2g = max(0._r8, bare_urb_diff) + call pctnatpft(n)%set_one_pct_p2g(baregroundindex, bare_pct_p2g) + pcturb_excess = abs(min(0._r8,bare_urb_diff)) + + ! For any urban not accounted for by bare soil, replace other PFTs + ! proportionally + if (pcturb_excess > 0._r8) then + ! Note that, in this case, we will have already reduced bare ground to 0% + + new_total_veg_pct = pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - pcturb_excess + if (new_total_veg_pct < 0._r8) then + if (abs(new_total_veg_pct) < tol_loose) then + ! only slightly less than 0; correct it + new_total_veg_pct = 0._r8 + else + write(6,*) subname, ' ERROR: trying to replace veg with urban,' + write(6,*) 'but pcturb_excess exceeds current vegetation percent' + call abort() + end if + end if + + call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) + end if + + end if ! pcturb(n) > 0 - call pctnatpft(n)%set_pct_l2g(new_total_natveg_pct) - ! Confirm that we have done the rescaling correctly: now the sum of all landunits - ! should be 100% within tol_loose - suma = pctlak(n)+pctwet(n)+pctgla(n)+pcturb(n)+pctcft(n)%get_pct_l2g() - suma = suma + pctnatpft(n)%get_pct_l2g() + ! should be 100% + suma = pctlak(n)+pctwet(n)+pctgla(n)+pcturb(n) + suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() if (abs(suma - 100._r8) > tol_loose) then write(6,*) subname, ' ERROR: landunits do not sum to 100%' write(6,*) 'n, suma, pctlak, pctwet, pctgla, pcturb, pctnatveg, pctcrop = ' @@ -1500,34 +1506,30 @@ subroutine normalizencheck_landuse(ldomain) call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8/suma) end if - ! This roundoff error fix is needed to handle the situation where new_total_natveg_pct - ! ends up near 0 but not exactly 0 due to roundoff issues. In this situation, we set the - ! natveg landunit area to exactly 0 and put the remainder into some other landunit. Since - ! the remainder is very small, it doesn't really matter which other landunit we add it to, - ! so we just pick some landunit that already has at least 1% cover. - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() + ! Roundoff error fix + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + suma2 = pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() if ( (suma < 100._r8 .and. suma > (100._r8 - 1.e-6_r8)) .or. & - (pctnatpft(n)%get_pct_l2g() > 0.0_r8 .and. pctnatpft(n)%get_pct_l2g() < 1.e-6_r8) ) then - write (6,*) 'Special plus crop land units near 100%, but not quite for n,suma =',n,suma - write (6,*) 'Adjusting special plus crop land units to 100%' - if (pctlak(n) >= 1.0_r8) then - pctlak(n) = 100._r8 - (pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g()) - else if (pctwet(n) >= 1.0_r8) then - pctwet(n) = 100._r8 - (pctlak(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g()) - else if (pcturb(n) >= 1.0_r8) then - pcturb(n) = 100._r8 - (pctlak(n) + pctwet(n) + pctgla(n) + pctcft(n)%get_pct_l2g()) - else if (pctgla(n) >= 1.0_r8) then - pctgla(n) = 100._r8 - (pctlak(n) + pctwet(n) + pcturb(n) + pctcft(n)%get_pct_l2g()) - else if (pctcft(n)%get_pct_l2g() >= 1.0_r8) then - call pctcft(n)%set_pct_l2g(100._r8 - (pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n))) + (suma2 > 0.0_r8 .and. suma2 < 1.e-6_r8) ) then + write (6,*) 'Special land units near 100%, but not quite for n,suma =',n,suma + write (6,*) 'Adjusting special land units to 100%' + if (pctlak(n) >= 25._r8) then + pctlak(n) = 100._r8 - (pctwet(n) + pcturb(n) + pctgla(n)) + else if (pctwet(n) >= 25._r8) then + pctwet(n) = 100._r8 - (pctlak(n) + pcturb(n) + pctgla(n)) + else if (pcturb(n) >= 25._r8) then + pcturb(n) = 100._r8 - (pctlak(n) + pctwet(n) + pctgla(n)) + else if (pctgla(n) >= 25._r8) then + pctgla(n) = 100._r8 - (pctlak(n) + pctwet(n) + pcturb(n)) else - write (6,*) subname, 'Error: sum of special plus crop land units nearly 100% but none is >= 1.0% at ', & + write (6,*) subname, 'Error: sum of special land units nearly 100% but none is >= 25% at ', & 'n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),pctnatveg(n),pctcrop(n),suma = ', & n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(),suma call abort() end if call pctnatpft(n)%set_pct_l2g(0._r8) + call pctcft(n)%set_pct_l2g(0._r8) end if if ( any(pctnatpft(n)%get_pct_p2g() > 0.0_r8 .and. pctnatpft(n)%get_pct_p2g() < toosmallPFT ) .or. & any(pctcft(n)%get_pct_p2g() > 0.0_r8 .and. pctcft(n)%get_pct_p2g() < toosmallPFT )) then @@ -1539,8 +1541,14 @@ subroutine normalizencheck_landuse(ldomain) call abort() end if - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() - suma = suma + pctnatpft(n)%get_pct_l2g() + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + if (suma < 100._r8-epsilon(suma) .and. suma > (100._r8 - 4._r8*epsilon(suma))) then + write (6,*) subname, 'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& + pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() + call abort() + end if + suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() if ( abs(suma-100._r8) > 1.e-10_r8) then write (6,*) subname, ' error: sum of pctlak, pctwet,', & 'pcturb, pctgla, pctnatveg and pctcrop is NOT equal to 100' @@ -1552,6 +1560,45 @@ subroutine normalizencheck_landuse(ldomain) end do + ! Check that when pctnatveg+pctcrop identically zero, sum of special landunits is identically 100% + + if ( .not. outnc_double )then + do n = 1,ns_o + sum8 = real(pctlak(n),r4) + sum8 = sum8 + real(pctwet(n),r4) + sum8 = sum8 + real(pcturb(n),r4) + sum8 = sum8 + real(pctgla(n),r4) + sum4a = real(pctnatpft(n)%get_pct_l2g(),r4) + sum4a = sum4a + real(pctcft(n)%get_pct_l2g(),r4) + if ( sum4a==0.0_r4 .and. sum8 < 100._r4-2._r4*epsilon(sum4a) )then + write (6,*) subname, ' error: sum of pctlak, pctwet,', & + 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 + write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n), & + pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g() + call abort() + end if + end do + else + do n = 1,ns_o + sum8 = pctlak(n) + sum8 = sum8 + pctwet(n) + sum8 = sum8 + pcturb(n) + sum8 = sum8 + pctgla(n) + sum8a = pctnatpft(n)%get_pct_l2g() + sum8a = sum8a + pctcft(n)%get_pct_l2g() + if ( sum8a==0._r8 .and. sum8 < (100._r8-4._r8*epsilon(sum8)) )then + write (6,*) subname, ' error: sum of pctlak, pctwet,', & + 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 + write (6,*) 'Total error, error/epsilon = ',100._r8-sum8, ((100._r8-sum8)/epsilon(sum8)) + write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,epsilon= ', & + n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& + pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), epsilon(sum8) + call abort() + end if + end do + end if + ! Make sure that there is no vegetation outside the pft mask do n = 1,ns_o if (pftdata_mask(n) == 0 .and. (pctnatpft(n)%get_pct_l2g() > 0 .or. pctcft(n)%get_pct_l2g() > 0)) then diff --git a/tools/mksurfdata_map/src/mkurbanparMod.F90 b/tools/mksurfdata_map/src/mkurbanparMod.F90 index 0323502665..49ce95dd07 100644 --- a/tools/mksurfdata_map/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_map/src/mkurbanparMod.F90 @@ -23,8 +23,7 @@ module mkurbanparMod public :: mkurbanInit public :: mkurban public :: mkurbanpar - public :: update_max_array_urban - + ! The following could be private, but because there are associated test routines in a ! separate module, it needs to be public public :: normalize_urbn_by_tot @@ -757,30 +756,4 @@ end subroutine lookup_and_check_err end subroutine mkurbanpar !------------------------------------------------------------------------------ -!----------------------------------------------------------------------- -subroutine update_max_array_urban(pct_urbmax_arr,pct_urban_arr) - ! - ! !DESCRIPTION: - ! Update the maximum percent cover of each urban class for landuse.timeseries file - ! - ! !ARGUMENTS: - real(r8) , intent(inout):: pct_urbmax_arr(:,:) ! max percent cover of each urban class - real(r8) , intent(in):: pct_urban_arr(:,:) ! percent cover of each urban class that is used to update the old pct_urbmax_arr - ! - ! !LOCAL VARIABLES: - integer :: n,k,ns ! indices - - character(len=*), parameter :: subname = 'update_max_array_urban' - !----------------------------------------------------------------------- - ns = size(pct_urban_arr,1) - do n = 1, ns - do k =1, numurbl - if (pct_urban_arr(n,k) > pct_urbmax_arr(n,k)) then - pct_urbmax_arr(n,k) = pct_urban_arr(n,k) - end if - end do - end do - -end subroutine update_max_array_urban - end module mkurbanparMod From ae11c13c045a6247b8c332f26b6540c5f3fdc01a Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 28 Mar 2022 17:50:14 -0600 Subject: [PATCH 112/614] Updating a comment so as to remove some TODOs --- tools/mksurfdata_esmf/src/mklaiMod.F90 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mklaiMod.F90 b/tools/mksurfdata_esmf/src/mklaiMod.F90 index 78fc406e3d..480cf1ecb5 100644 --- a/tools/mksurfdata_esmf/src/mklaiMod.F90 +++ b/tools/mksurfdata_esmf/src/mklaiMod.F90 @@ -197,6 +197,7 @@ subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! Below - copy LAI, SAI, & heights from the C3 crop (pft15) ! to the irrigated (pft16) whether crop is on or off + ! Hence loop to numpft_i - 1 for other pfts ! Read in one time slice of data for mlai, regrid and write out rcode = pio_inq_varid(pioid_i, 'MONTHLY_LAI', pio_varid_i) @@ -204,7 +205,7 @@ subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) call mkpio_get_rawdata_level(pioid_i, pio_iodesc_i, nt, 'MONTHLY_LAI', data_i) call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft_i, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - do l = 0,numpft_i-1 ! TODO: why -1? + do l = 0,numpft_i-1 do no = 1,ns_o mlai_o(no,l) = data_o(l,no) end do @@ -221,7 +222,7 @@ subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) call mkpio_get_rawdata_level(pioid_i, pio_iodesc_i, nt, 'MONTHLY_SAI', data_i) call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft_i, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - do l = 0,numpft_i-1 ! TODO: why -1? + do l = 0,numpft_i-1 do no = 1,ns_o msai_o(no,l) = data_o(l,no) end do @@ -236,7 +237,7 @@ subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) call mkpio_get_rawdata_level(pioid_i, pio_iodesc_i, nt, 'MONTHLY_HEIGHT_TOP', data_i) call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft_i, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - do l = 0,numpft_i-1 ! TODO: why -1? + do l = 0,numpft_i-1 do no = 1,ns_o mhgtt_o(no,l) = data_o(l,no) end do @@ -251,7 +252,7 @@ subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) call mkpio_get_rawdata_level(pioid_i, pio_iodesc_i, nt, 'MONTHLY_HEIGHT_BOT', data_i) call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 0, numpft_i, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - do l = 0,numpft_i-1 ! TODO: why -1? + do l = 0,numpft_i-1 do no = 1,ns_o mhgtb_o(no,l) = data_o(l,no) end do From bfdae1578d4f446a06298a93871ecb780bfdeaa0 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 28 Mar 2022 19:01:34 -0600 Subject: [PATCH 113/614] Some cleanup --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 01d6453000..4582e584b8 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -7,9 +7,7 @@ module mkfileMod use mkutilsMod , only : get_filename, chkerr use mkvarpar , only : nlevsoi, numrad, numstdpft use mkurbanparMod , only : numurbl, nlevurb, mkurbanpar - use mklaiMod , only : mklai - use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft, num_natpft - use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array + use mkpftConstantsMod , only : num_cft, num_natpft use mkpioMod use mkinputMod use mkvarctl From 5ba4e6871ea06682caa6f90cfcab6b0b673744ec Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 28 Mar 2022 19:02:56 -0600 Subject: [PATCH 114/614] Trying to add month values to the time variable ...but failing I'm using the cft and natpft variables as templates, but time ends up with 12 zeros instead of values from 1 to 12... --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 59edf1d19d..7709a72b02 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -173,6 +173,10 @@ program mksurfdata real(r8), allocatable :: pctwet_orig(:) ! percent wetland of gridcell before dynamic land use adjustments real(r8), allocatable :: pctgla_orig(:) ! percent glacier of gridcell before dynamic land use adjustments + ! time parameters + integer, parameter :: n_jan = 1 + integer, parameter :: n_dec = 12 + ! pio/esmf variables type(file_desc_t) :: pioid type(var_desc_t) :: pio_varid @@ -321,7 +325,7 @@ program mksurfdata ! NOTE: do not deallocate pctlak, pctwet, pctglacier and pcturban ! ----------------------------------- - ! Write out natpft and cft + ! Write out natpft, cft, and time ! ----------------------------------- if (fsurdat /= ' ') then rcode = pio_inq_varid(pioid, 'natpft', pio_varid) @@ -330,6 +334,9 @@ program mksurfdata rcode = pio_inq_varid(pioid, 'cft', pio_varid) rcode = pio_put_var(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/)) end if + ! time is months for LAI, SAI, and pft heights + rcode = pio_inq_varid(pioid, 'time', pio_varid) + rcode = pio_put_var(pioid, pio_varid, (/(n,n=n_jan,n_dec)/)) end if ! ----------------------------------- @@ -787,16 +794,6 @@ program mksurfdata ! End define mode rcode = pio_enddef(pioid) - ! Write out natpft - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out natpft" - rcode = pio_inq_varid(pioid, 'natpft', pio_varid) - rcode = pio_put_var(pioid, pio_varid, (/(n,n=natpft_lb,natpft_ub)/)) - - ! Write out cft - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out cft" - rcode = pio_inq_varid(pioid, 'cft', pio_varid) - rcode = pio_put_var(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/)) - ! Write out model grid if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" call mkfile_output(pioid, mesh_model, 'LONGXY', lon, rc=rc) From 7cbc5f8874a27d58c7f980fc22710f50a6b1bcf9 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 28 Mar 2022 19:17:40 -0600 Subject: [PATCH 115/614] Removing obsolete option --fast --- tools/mksurfdata_esmf/README | 1 - tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 8 -------- 2 files changed, 9 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 60c8bbdcdc..d101723a12 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -79,7 +79,6 @@ slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED 3) --merge_gis, --nocrop work 4) --hires_pft works, but must abort for years /= 2005 (and 1850?) 5) --potveg_flag needs file(s) converted to cdf5 -6) --fast doesn't do anything as far as I can tell; do we need it? old) ./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc Issues: See newer testing above diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index c35ec7b0e7..934bba08ef 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -190,14 +190,6 @@ def get_parser(): dest="crop_flag", default=False, ) - parser.add_argument( - "-f", - "--fast", - help="Toggle fast mode which does not use the large mapping file", - action="store_true", - dest="fast_flag", - default=False, - ) parser.add_argument( "--potveg_flag", help=""" From 1c3b0218a44feacecf728f72ccd4e5a7e3bccf51 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 28 Mar 2022 19:37:51 -0600 Subject: [PATCH 116/614] Added error check to ensure years are 1850 or 2005 for --hires_pft --- tools/mksurfdata_esmf/README | 3 +-- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 7 ++++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index d101723a12..795aa2a128 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -77,8 +77,7 @@ slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED - VOC em factors from input not appearing in .log 3) --merge_gis, --nocrop work -4) --hires_pft works, but must abort for years /= 2005 (and 1850?) -5) --potveg_flag needs file(s) converted to cdf5 +4) --potveg_flag needs file(s) converted to cdf5 old) ./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc Issues: See newer testing above diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 934bba08ef..64eaf289e5 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -235,7 +235,12 @@ def main (): glc_nec = args.glc_nec merge_gis = args.merge_gis if args.hres_flag: - hires_pft = 'on' + if (start_year == 1850 and end_year == 1850) or \ + (start_year == 2005 and end_year == 2005): + hires_pft = 'on' + else: + print(f"ERROR: for --hires_pft you must set both start-year & end-year to 1850 or to 2005") + sys.exit(5) else: hires_pft = 'off' verbose = args.verbose From 8de015df4c0ff1461bd694dc42e34c5f93ad85f5 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 29 Mar 2022 10:10:45 -0600 Subject: [PATCH 117/614] new soil texture file --- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 351 ++++++++--------- tools/mksurfdata_esmf/src/mksoiltexNewMod.F90 | 363 ++++++++++++++++++ 2 files changed, 525 insertions(+), 189 deletions(-) create mode 100644 tools/mksurfdata_esmf/src/mksoiltexNewMod.F90 diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 8b165e75d3..6ca1aecfec 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -33,13 +33,13 @@ module mksoiltexMod contains !================================================================================= - subroutine mksoiltex(file_grid_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc) + subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc) ! ! make %sand and %clay from IGBP soil data, which includes ! igbp soil 'mapunits' and their corresponding textures ! ! input/output variables - character(len=*) , intent(in) :: file_grid_i ! input grid file name + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh type(file_desc_t) , intent(inout) :: pioid_o @@ -48,7 +48,6 @@ subroutine mksoiltex(file_grid_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc ! local variables type(ESMF_RouteHandle) :: routehandle - type(ESMF_Grid) :: grid_i type(ESMF_Mesh) :: mesh_i type(ESMF_Field) :: field_i type(ESMF_Field) :: field_o @@ -90,7 +89,7 @@ subroutine mksoiltex(file_grid_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc write(ndiag,*) write(ndiag,'(a)') 'Attempting to make %sand and %clay .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) - write(ndiag,'(a)') ' Input grid file is '//trim(file_grid_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if ! Determine ns_o and allocate output data @@ -105,103 +104,77 @@ subroutine mksoiltex(file_grid_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) ! Read in input mesh - call ESMF_VMLogMemInfo("Before create grid_i in "//trim(subname)) - if (root_task) write(ndiag,*)"DEBUG: before create grid_i in "//trim(subname) - grid_i = ESMF_GridCreate(filename=trim(file_grid_i), & - fileformat=ESMF_FILEFORMAT_GRIDSPEC, addCornerStagger=.true., addmask=.true., varname='MU', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag,*)"DEBUG: before create mesh_i in "//trim(subname) call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) - mesh_i = esmf_meshcreate(grid_i, rc=rc) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - if (root_task) write(ndiag,*)"DEBUG: after create mesh_i in "//trim(subname) - ! Determine ns_i (use the distgrid to the number of elements) + ! Determine ns_i call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Get the landmask from the file and reset the mesh mask based on that - ! allocate(rmask_i(ns_i), stat=ier) - ! if (ier/=0) call shr_sys_abort() - ! allocate(mask_i(ns_i), stat=ier) - ! if (ier/=0) call shr_sys_abort() - ! call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return - ! do ni = 1,ns_i - ! if (rmask_i(ni) > 0._r4) then - ! mask_i(ni) = 1 - ! else - ! mask_i(ni) = 0 - ! end if - ! end do - ! call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(rmask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (rmask_i(ni) > 0._r4) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return ! Read in mapunit data - if (root_task) write(ndiag,*)"DEBUG: before mapunit read in "//trim(subname) allocate(mapunit_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid_i, 'MU', mesh_i, mapunit_i, rc=rc) + call mkpio_get_rawdata(pioid_i, 'MAPUNITS', mesh_i, mapunit_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - if (root_task) write(ndiag,*)"DEBUG: after mapunit read in "//trim(subname) ! Set mapunit values to zero where the input mask is 0 - allocate(mask_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() do ni = 1,ns_i - if (mapunit_i(ni) == 0.) then - mask_i(ni) = 0 - end if + mapunit_i(ni) = mapunit_i(ni) * rmask_i(ni) end do - call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return ! Determine mapunit_value_max (set it as a module variable so that it can be ! accessible to gen_dominant_mapunit) - ! TODO: add the max_value_mapunit to the netcdf file - ! rcode = pio_inq_dimid (pioid_i, 'max_value_mapunit', dimid) - ! rcode = pio_inq_dimlen (pioid_i, dimid, mapunit_value_max) - mapunit_value_max = 32056 + rcode = pio_inq_dimid (pioid_i, 'max_value_mapunit', dimid) + rcode = pio_inq_dimlen (pioid_i, dimid, mapunit_value_max) ! Create ESMF fields that will be used below - if (root_task) write(ndiag,*)"DEBUG: before field_i creation "//trim(subname) field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag,*)"DEBUG: before field_o creation "//trim(subname) field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! field_dstfrac = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return + field_dstfrac = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle - if (root_task) write(ndiag,*)"DEBUG: before route handle creation "//trim(subname) - ! call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & - ! regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & - ! ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & - ! dstFracField= field_dstfrac, rc=rc) call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & - ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & + dstFracField= field_dstfrac, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - if (root_task) write(ndiag,*)"DEBUG: after route handle creation "//trim(subname) ! Determin frac_o - ! call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return - ! allocate(frac_o(ns_o)) - ! frac_o(:) = dataptr_r8(:) + call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(frac_o(ns_o)) + frac_o(:) = dataptr_r8(:) ! Create a dynamic mask object ! The dynamic mask object further holds a pointer to the routine that will be called in order to ! handle dynamically masked elements - in this case its DynMaskProc (see below) - if (root_task) write(ndiag,*)"DEBUG: before call to dynamic mas set creation "//trim(subname) call ESMF_DynamicMaskSetR4R8R4(dynamicMask, dynamicMaskRoutine=get_dominant_mapunit, & handleAllElements=.true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag,*)"DEBUG: after call to dynamic mas set creation "//trim(subname) ! Determine dominant soil color in the field regrid call below call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) @@ -220,143 +193,143 @@ subroutine mksoiltex(file_grid_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc end do ! Get dimensions from input file and allocate memory for sand_i and clay_i -! rcode = pio_inq_dimid (pioid_i, 'number_of_layers', dimid) -! rcode = pio_inq_dimlen (pioid_i, dimid, nlay) -! allocate(sand_i(mapunit_value_max,nlay), stat=ier) -! if (ier/=0) call shr_sys_abort() -! allocate(clay_i(mapunit_value_max,nlay), stat=ier) -! if (ier/=0) call shr_sys_abort() - -! ! read in sand_i and clay_i (they will read in total on all processors) -! rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid) -! rcode = pio_get_var(pioid_i, pio_varid, sand_i) -! rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid) -! rcode = pio_get_var(pioid_i, pio_varid, clay_i) - -! ! Set soil texture as follows: -! ! a. Use dominant igbp soil mapunit based on area of overlap unless 'no data' is dominant -! ! b. If this has no data, use loam for soil texture - -! do no = 1,ns_o -! if (mapunit_o(no) > 0) then -! ! valid value is obtained -! if (mapunit_o(no) > mapunit_value_max) then -! write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) -! ! call shr_sys_abort("mapunit_o is out of bounds") -! end if -! do l = 1, nlay -! sand_o(no,l) = sand_i(mapunit_o(no),l) -! clay_o(no,l) = clay_i(mapunit_o(no),l) -! end do -! else -! ! use loam -! do l = 1, nlay -! sand_o(no,l) = 43. -! clay_o(no,l) = 18. -! end do -! end if -! end do - -! ! Define the model surface types: 0:4 -! soil(0) = 'no soil: ocean, glacier, lake, no data' -! soil(1) = 'clays ' -! soil(2) = 'sands ' -! soil(3) = 'loams ' -! soil(4) = 'silts ' - -! ! input grid: determine soil_i for global area comparison -! allocate(soil_i(ns_i)) -! do l = 1, nlay -! do ni = 1,ns_i -! mapunit = nint(mapunit_i(ni)) -! if (mapunit==0) then -! typ = 'no soil: ocean, glacier, lake, no data' -! else if (clay_i(mapunit,l) >= 40.) then -! typ = 'clays' -! else if (sand_i(mapunit,l) >= 50.) then -! typ = 'sands' -! else if (clay_i(mapunit,l)+sand_i(mapunit,l) < 50.) then -! if (mask_i(ni) /= 0) then -! typ = 'silts' -! else -! typ = 'no soil: ocean, glacier, lake, no data' -! end if -! else -! typ = 'loams' -! end if -! do m = 0, nlsm -! if (typ == soil(m)) go to 101 -! end do -! write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunit,l), & -! ' clay = ',clay_i(mapunit,l),' not assigned to soil type for input grid lon,lat,layer = ',ni,l -! call shr_sys_abort() -! 101 continue -! soil_i(ni) = m ! allocate memory for this -! end do -! end do - -! ! output grid: determine soil_o for global area comparison -! allocate(soil_o(ns_o)) -! do l = 1, nlay -! do no = 1,ns_o -! if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then -! typ = 'no soil: ocean, glacier, lake, no data' -! else if (clay_o(no,l) >= 40.) then -! typ = 'clays' -! else if (sand_o(no,l) >= 50.) then -! typ = 'sands' -! else if (clay_o(no,l)+sand_o(no,l) < 50.) then -! typ = 'silts' -! else -! typ = 'loams' -! end if -! do m = 0, nlsm -! if (typ == soil(m)) go to 102 -! end do -! write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & -! ' clay = ',clay_o(no,l), ' not assigned to soil type for output grid lon,lat,layer = ',no,l -! call shr_sys_abort() -! 102 continue -! soil_o(no) = m -! end do -! end do - -! ! Compare global areas -! if (root_task) then -! write (ndiag,'(a)') 'The following table of soil texture classes is for comparison only.' -! write (ndiag,'(a)') 'The actual data is continuous %sand, %silt and %clay not textural classes' -! end if -! ! call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & -! ! 0, nlsm, soil_i, soil_o, 'soil texture class', ndiag, rc) -! ! if (chkerr(rc,__LINE__,u_FILE_u)) return - -! ! Adjust pct sand and pct clay to be nearest integers and to be loam if pctlnd_pft is < 1.e-6 -! ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero -! ! (not a very small number such as 1e-16) where it really should be zero -! do no = 1,ns_o -! do k = 1,nlevsoi -! sand_o(no,k) = float(nint(sand_o(no,k))) -! clay_o(no,k) = float(nint(clay_o(no,k))) -! end do -! if (pctlnd_pft_o(no) < 1.e-6_r8) then -! sand_o(no,:) = 43._r8 -! clay_o(no,:) = 18._r8 -! end if -! end do + rcode = pio_inq_dimid (pioid_i, 'number_of_layers', dimid) + rcode = pio_inq_dimlen (pioid_i, dimid, nlay) + allocate(sand_i(mapunit_value_max,nlay), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(clay_i(mapunit_value_max,nlay), stat=ier) + if (ier/=0) call shr_sys_abort() + + ! read in sand_i and clay_i (they will read in total on all processors) + rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid) + rcode = pio_get_var(pioid_i, pio_varid, sand_i) + rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid) + rcode = pio_get_var(pioid_i, pio_varid, clay_i) + + ! Set soil texture as follows: + ! a. Use dominant igbp soil mapunit based on area of overlap unless 'no data' is dominant + ! b. If this has no data, use loam for soil texture + + do no = 1,ns_o + if (mapunit_o(no) > 0) then + ! valid value is obtained + if (mapunit_o(no) > mapunit_value_max) then + write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) + ! call shr_sys_abort("mapunit_o is out of bounds") + end if + do l = 1, nlay + sand_o(no,l) = sand_i(mapunit_o(no),l) + clay_o(no,l) = clay_i(mapunit_o(no),l) + end do + else + ! use loam + do l = 1, nlay + sand_o(no,l) = 43. + clay_o(no,l) = 18. + end do + end if + end do + + ! Define the model surface types: 0:4 + soil(0) = 'no soil: ocean, glacier, lake, no data' + soil(1) = 'clays ' + soil(2) = 'sands ' + soil(3) = 'loams ' + soil(4) = 'silts ' + + ! input grid: determine soil_i for global area comparison + allocate(soil_i(ns_i)) + do l = 1, nlay + do ni = 1,ns_i + mapunit = nint(mapunit_i(ni)) + if (mapunit==0) then + typ = 'no soil: ocean, glacier, lake, no data' + else if (clay_i(mapunit,l) >= 40.) then + typ = 'clays' + else if (sand_i(mapunit,l) >= 50.) then + typ = 'sands' + else if (clay_i(mapunit,l)+sand_i(mapunit,l) < 50.) then + if (rmask_i(ni) /= 0.) then + typ = 'silts' + else + typ = 'no soil: ocean, glacier, lake, no data' + end if + else + typ = 'loams' + end if + do m = 0, nlsm + if (typ == soil(m)) go to 101 + end do + write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunit,l), & + ' clay = ',clay_i(mapunit,l),' not assigned to soil type for input grid lon,lat,layer = ',ni,l + call shr_sys_abort() +101 continue + soil_i(ni) = m ! allocate memory for this + end do + end do + + ! output grid: determine soil_o for global area comparison + allocate(soil_o(ns_o)) + do l = 1, nlay + do no = 1,ns_o + if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then + typ = 'no soil: ocean, glacier, lake, no data' + else if (clay_o(no,l) >= 40.) then + typ = 'clays' + else if (sand_o(no,l) >= 50.) then + typ = 'sands' + else if (clay_o(no,l)+sand_o(no,l) < 50.) then + typ = 'silts' + else + typ = 'loams' + end if + do m = 0, nlsm + if (typ == soil(m)) go to 102 + end do + write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & + ' clay = ',clay_o(no,l), ' not assigned to soil type for output grid lon,lat,layer = ',no,l + call shr_sys_abort() +102 continue + soil_o(no) = m + end do + end do + + ! Compare global areas + if (root_task) then + write (ndiag,'(a)') 'The following table of soil texture classes is for comparison only.' + write (ndiag,'(a)') 'The actual data is continuous %sand, %silt and %clay not textural classes' + end if + call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & + 0, nlsm, soil_i, soil_o, 'soil texture class', ndiag, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Adjust pct sand and pct clay to be nearest integers and to be loam if pctlnd_pft is < 1.e-6 + ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero + ! (not a very small number such as 1e-16) where it really should be zero + do no = 1,ns_o + do k = 1,nlevsoi + sand_o(no,k) = float(nint(sand_o(no,k))) + clay_o(no,k) = float(nint(clay_o(no,k))) + end do + if (pctlnd_pft_o(no) < 1.e-6_r8) then + sand_o(no,:) = 43._r8 + clay_o(no,:) = 18._r8 + end if + end do ! Write out fields if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" call mkfile_output(pioid_o, mesh_o, 'mapunits', mapunit_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" - ! call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" + call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" - ! call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - ! call pio_syncfile(pioid_o) + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" + call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mksoiltexNewMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexNewMod.F90 new file mode 100644 index 0000000000..0a7d5a406a --- /dev/null +++ b/tools/mksurfdata_esmf/src/mksoiltexNewMod.F90 @@ -0,0 +1,363 @@ +module mksoiltexNewMod + + !----------------------------------------------------------------------- + ! Make soil data (texture) + !----------------------------------------------------------------------- + + use ESMF + use pio + use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 + use shr_sys_mod , only : shr_sys_abort + use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths + use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem + use mkutilsMod , only : chkerr + use mkdiagnosticsMod , only : output_diagnostics_index + use mkfileMod , only : mkfile_output + use mkvarctl , only : root_task, ndiag, spval + use mkvarctl , only : unsetsoil + use mkvarpar , only : nlevsoi + + implicit none + private ! By default make data private + + public :: mksoiltex ! Set soil texture + + integer :: mapunit_value_max + integer :: num_soil_textures + type(ESMF_DynamicMask) :: dynamicMask + + character(len=*) , parameter :: u_FILE_u = & + __FILE__ + +!================================================================================= +contains +!================================================================================= + + subroutine mksoiltexnew(file_grid_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o, pctlnd_pft_o, rc) + ! + ! make %sand and %clay from IGBP soil data, which includes + ! igbp soil 'mapunits' and their corresponding textures + ! + ! input/output variables + character(len=*) , intent(in) :: file_grid_i ! input grid file name + character(len=*) , intent(in) :: file_mapunit_i ! input mapunit file name + character(len=*) , intent(in) :: file_lookup_i ! input lookup file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + type(file_desc_t) , intent(inout) :: pioid_o + real(r8) , intent(in) :: pctlnd_pft_o(:) ! PFT data: % of gridcell for PFTs + integer , intent(out) :: rc + + ! local variables + type(ESMF_RouteHandle) :: routehandle + type(ESMF_Grid) :: grid_i + type(ESMF_Mesh) :: mesh_i + type(ESMF_Field) :: field_i + type(ESMF_Field) :: field_o + type(ESMF_Field) :: field_dstfrac + type(file_desc_t) :: pioid_i + type(var_desc_t) :: pio_varid + integer :: pio_vartype + integer :: dimid + integer :: ni,no + integer :: ns_i, ns_o + integer :: k,l,m,n + integer :: nlay ! number of soil layers + integer , allocatable :: mask_i(:) + real(r4), allocatable :: rmask_i(:) + real(r8), allocatable :: frac_o(:) + real(r4), allocatable :: sand_i(:,:) ! input grid: percent sand + real(r4), allocatable :: clay_i(:,:) ! input grid: percent clay + real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits + real(r8), allocatable :: sand_o(:,:) ! % sand (output grid) + real(r8), allocatable :: clay_o(:,:) ! % clay (output grid) + integer , allocatable :: mapunit_o(:) + real(r4), pointer :: dataptr(:) + real(r8), pointer :: dataptr_r8(:) + real(r4) :: sumtex + integer :: mapunit ! temporary igbp soil mapunit + integer, allocatable :: soil_i(:) + integer, allocatable :: soil_o(:) + integer :: rcode, ier ! error status + integer :: srcTermProcessing_Value = 0 + integer :: starts(3) ! starting indices for reading lookup table + integer :: counts(3) ! dimension counts for reading lookup table + integer, parameter :: nlsm=4 ! number of soil textures + character(len=38) :: soil(0:nlsm) ! name of each soil texture + character(len=38) :: typ ! soil texture based on ... + character(len=*), parameter :: subname = 'mksoiltex' + !----------------------------------------------------------------------- + + if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) + write(ndiag,*) + write(ndiag,'(a)') 'Attempting to make %sand and %clay .....' + write(ndiag,'(a)') ' Input file is '//trim(file_mapunit_i) + write(ndiag,'(a)') ' Input grid file is '//trim(file_grid_i) + end if + + ! Determine ns_o and allocate output data + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(mapunit_o(ns_o)) ; mapunit_o(:) = 0 + allocate(sand_o(ns_o,nlevsoi)) ; sand_o(:,:) = spval + allocate(clay_o(ns_o,nlevsoi)) ; clay_o(:,:) = spval + + !--------------------------------- + ! Determine mapunits on output grid + !--------------------------------- + + ! Open input data file + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_mapunit_i)) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_mapunit_i), pio_nowrite) + + ! Read in input mapunit mesh + call ESMF_VMLogMemInfo("Before create grid_i in "//trim(subname)) + if (root_task) write(ndiag,*)"DEBUG: before create grid_i in "//trim(subname) + grid_i = ESMF_GridCreate(filename=trim(file_grid_i), & + fileformat=ESMF_FILEFORMAT_GRIDSPEC, addCornerStagger=.true., addmask=.true., varname='MU', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag,*)"DEBUG: before create mesh_i in "//trim(subname) + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + mesh_i = esmf_meshcreate(grid_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + if (root_task) write(ndiag,*)"DEBUG: after create mesh_i in "//trim(subname) + + ! Determine ns_i (use the distgrid to the number of elements) + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Read in mapunit data + if (root_task) write(ndiag,*)"DEBUG: before mapunit read in "//trim(subname) + allocate(mapunit_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid_i, 'MU', mesh_i, mapunit_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + if (root_task) write(ndiag,*)"DEBUG: after mapunit read in "//trim(subname) + + ! Set mapunit values to zero where the input mask is 0 + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + do ni = 1,ns_i + if (mapunit_i(ni) == 0.) then + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create ESMF fields that will be used below + if (root_task) write(ndiag,*)"DEBUG: before field_i creation "//trim(subname) + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag,*)"DEBUG: before field_o creation "//trim(subname) + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! field_dstfrac = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create a route handle + if (root_task) write(ndiag,*)"DEBUG: before route handle creation "//trim(subname) + call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & + dstFracField= field_dstfrac, rc=rc) + call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) + if (root_task) write(ndiag,*)"DEBUG: after route handle creation "//trim(subname) + + ! Determin frac_o + ! call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return + ! allocate(frac_o(ns_o)) + ! frac_o(:) = dataptr_r8(:) + + ! Create a dynamic mask object + ! The dynamic mask object further holds a pointer to the routine that will be called in order to + ! handle dynamically masked elements - in this case its DynMaskProc (see below) + if (root_task) write(ndiag,*)"DEBUG: before call to dynamic mas set creation "//trim(subname) + call ESMF_DynamicMaskSetR4R8R4(dynamicMask, dynamicMaskRoutine=get_dominant_mapunit, & + handleAllElements=.true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag,*)"DEBUG: after call to dynamic mas set creation "//trim(subname) + + ! Determine dominant soil color in the field regrid call below + call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) + dataptr(:) = real(mapunit_i(:), kind=r4) + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr(:) = 0._r4 + + call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, dynamicMask=dynamicMask, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do no = 1,ns_o + mapunit_o(no) = int(dataptr(no)) + end do + + call pio_closefile(pioid_i) + + !--------------------------------- + ! Determine %sand and %clay on output grid - using above mapunits + !--------------------------------- + + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_lookup_i), pio_nowrite) + + rcode = pio_inq_dimid (pioid_i, 'MapUnit', dimid) + rcode = pio_inq_dimlen (pioid_i, dimid, n_mapunits) + + rcode = pio_inq_dimid (pioid_i, 'soil_layer', dimid) + rcode = pio_inq_dimlen (pioid_i, dimid, nlay) + + ! Read In MapUnits from the input file + allocate(MapUnits(n_mapunits), stat=ier) + rcode = pio_inq_varid(pioid_i, 'MapUnit', pio_varid) + rcode = pio_get_var(pioid_i, pio_varid, MapUnits) + + ! Determine the mapunit lookup index from the value of the MapUnit variable + mapunit_value_max = maxval(MapUnits) + allocate(mapunit_lookup(mapunit_value_max)) + mapunit_lookup(:) = -999 + do n = 1,size(MapUnits) + mapunit_lookup(MapUnits(n)) = n + end do + + allocate(sand_i(mapunit_value_max,nlay), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(clay_i(mapunit_value_max,nlay), stat=ier) + if (ier/=0) call shr_sys_abort() + + ! Get dimensions from input file and allocate memory for sand_i and clay_i + + rcode = pio_inq_varid(pioid, 'PCT_SAND', pio_varid_sand) + rcode = pio_inq_varid(pioid, 'PCT_CLAY', pio_varid_clay) + starts(1:3) = 1 + counts(1) = n_mapunits + counts(2) = 1 + counts(3) = nlay + + allocate(sand_i(n_mapuntis,nlay)) + allocate(caly_i(n_mapunits,nlay)) + rcode = pio_get_var(pioid, pio_varid, starts, counts, sand_i) + rcode = pio_get_var(pioid, pio_varid, starts, counts, clay_i) + + do no = 1,ns_o + if (mapunit_o(no) > 0) then + ! valid value is obtained + if (mapunit_o(no) > mapunit_value_max) then + write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) + ! call shr_sys_abort("mapunit_o is out of bounds") + end if + lookup_index = mapunit_lookup(mapunit_o(no)) + do l = 1, nlay + sand_o(no,l) = sand_i(lookup_index,l) + clay_o(no,l) = clay_i(lookup_index,l) + end do + else + ! use loam + do l = 1, nlay + sand_o(no,l) = 43. + clay_o(no,l) = 18. + end do + end if + end do + + ! Adjust pct sand and pct clay to be nearest integers and to be loam if pctlnd_pft is < 1.e-6 + ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero + ! (not a very small number such as 1e-16) where it really should be zero + do no = 1,ns_o + do k = 1,nlevsoi + sand_o(no,k) = float(nint(sand_o(no,k))) + clay_o(no,k) = float(nint(clay_o(no,k))) + end do + if (pctlnd_pft_o(no) < 1.e-6_r8) then + sand_o(no,:) = 43._r8 + clay_o(no,:) = 18._r8 + end if + end do + + ! Write out fields + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" + call mkfile_output(pioid_o, mesh_o, 'mapunits', mapunit_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') + + ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" + ! call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + + ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" + ! call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + ! call pio_syncfile(pioid_o) + + ! Release memory + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) + + if (root_task) then + write (ndiag,'(a)') 'Successfully made %sand and %clay' + end if + + end subroutine mksoiltexnew + + !================================================================================================ + subroutine get_dominant_mapunit(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, rc) + + use ESMF, only : ESMF_RC_ARG_BAD + + ! input/output arguments + type(ESMF_DynamicMaskElementR4R8R4) , pointer :: dynamicMaskList(:) + real(ESMF_KIND_R4) , intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R4) , intent(in), optional :: dynamicDstMaskValue + integer , intent(out) :: rc + + ! local variables + integer :: ni, no, n + real(ESMF_KIND_R4) :: wts_o(0:mapunit_value_max) + integer :: maxindex(1) + real(ESMF_KIND_R4) :: maxvalue + character(len=*), parameter :: subname = 'mksoiltex' + !--------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (associated(dynamicMaskList)) then + do no = 1, size(dynamicMaskList) + dynamicMaskList(no)%dstElement = 0.d0 + wts_o(:) = 0.d0 + do ni = 1, size(dynamicMaskList(no)%factor) + if (dynamicMaskList(no)%srcElement(ni) > 0.d0) then + do n = 0,mapunit_value_max + if (dynamicMaskList(no)%srcElement(ni) == n) then + wts_o(n) = wts_o(n) + dynamicMaskList(no)%factor(ni) + end if + enddo + end if + end do + + ! Determine the most dominant index of wts_o + maxvalue = -999._r4 + maxindex = -999 + do n = 0,mapunit_value_max + if (wts_o(n) > maxvalue) then + maxindex(1) = n + maxvalue = wts_o(n) + end if + end do + if (maxindex(1) > mapunit_value_max) then + write(6,*)'mapunit_o is out of bounds ',maxindex(1) + call shr_sys_abort(subname//" mapunit_o is out of bounds") + end if + dynamicMaskList(no)%dstElement = real(maxindex(1), kind=r4) + end do + end if + + end subroutine get_dominant_mapunit + +end module mksoiltexNewMod From 16e5a44151c43dba81f0fa5406352117a3398bd3 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 29 Mar 2022 17:29:02 -0600 Subject: [PATCH 118/614] Updated PtVeg files to cdf5 --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index d21fb582b2..4a8af81c6a 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -101,7 +101,7 @@ lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc - lnd/clm2/rawdata/mksrf_urban_0.05x0.05_zerourbanpct.c181014.nc + /glade/p/cgd/tss/people/slevis/pot_veg/mksrf_urban_0.05x0.05_zerourbanpct.cdf5.c181014.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc @@ -160,7 +160,7 @@ version of the raw dataset will probably go away. lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc - lnd/clm2/rawdata/mksrf_gdp_0.5x0_zerogdp.c200413.nc + /glade/p/cgd/tss/people/slevis/pot_veg/mksrf_gdp_0.5x0_zerogdp.cdf5.c200413.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc @@ -185,7 +185,7 @@ version of the raw dataset will probably go away. lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc - lnd/clm2/rawdata/mksrf_abm_0.5x0.5_missingabm.c200413.nc + /glade/p/cgd/tss/people/slevis/pot_veg/mksrf_abm_0.5x0.5_missingabm.cdf5.c200413.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc @@ -219,7 +219,7 @@ version of the raw dataset will probably go away. - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.simyrPtVg.c181106/mksrf_landuse_potvegclm50_LUH2.c181106.nc + /glade/p/cgd/tss/people/slevis/pot_veg/mksrf_landuse_potvegclm50_LUH2.cdf5.c181106.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc From 8ca612c47d915b30d9ca535a321d341f642f61a3 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 29 Mar 2022 19:06:03 -0600 Subject: [PATCH 119/614] Fixed: LAI output had shifted by one pft index in the .log global sums --- tools/mksurfdata_esmf/README | 9 +++------ tools/mksurfdata_esmf/src/mklaiMod.F90 | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 795aa2a128..7edf349dc6 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -70,20 +70,17 @@ slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED - bigger diffs than I would like for NAT_PFT, though .log file shows global PFT areas same => Gridcell-level diffs due to mapping files? Confirm we have no discrepancy between .log and .nc files -- LAI in .log comes out shifted by one -- Soil color, ag fire peak month outputs too high in .log +--> Soil color, ag fire peak month outputs too high in .log + TODO: RUNNING NEW vs OLD with write statements - Soil txt, peat, fmax, lakes, harvest too low in .log unless raw data changed - Slope, stddev, soildepth, urban, glaciers not appearing in .log - VOC em factors from input not appearing in .log -3) --merge_gis, --nocrop work -4) --potveg_flag needs file(s) converted to cdf5 - old) ./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc Issues: See newer testing above ------------------------------------------------------ -NOT ALL FILES HAVE BEEN TRANSLATED to cdf5 : check last millenium & PtVg +NOT ALL FILES HAVE BEEN TRANSLATED to cdf5 : check last millenium ------------------------------------------------------ > nccopy -k cdf5 oldfile newfile diff --git a/tools/mksurfdata_esmf/src/mklaiMod.F90 b/tools/mksurfdata_esmf/src/mklaiMod.F90 index 480cf1ecb5..a61df40cf7 100644 --- a/tools/mksurfdata_esmf/src/mklaiMod.F90 +++ b/tools/mksurfdata_esmf/src/mklaiMod.F90 @@ -288,6 +288,8 @@ subroutine check_global_sums(name, ns_i, ns_o, numpft_i, nt, & data_i, data_o, area_i, area_o, mask_i, frac_o) ! Compare global areas on input and output grids + ! NB. data_i and data_o started at 0 outside this subroutine but start + ! at 1 within the subroutine, so the loops in the subroutine start at 1 ! input/otuput variables character(len=*) , intent(in) :: name @@ -305,15 +307,15 @@ subroutine check_global_sums(name, ns_i, ns_o, numpft_i, nt, & ! local variables integer :: ni, no, l, k integer :: ier - real(r8) :: local_i(0:numpft_i) ! local global area, by surface type - real(r8) :: local_o(0:numpft_i) ! local global area, by surface type - real(r8) :: global_i(0:numpft_i) ! input grid: global area pfts - real(r8) :: global_o(0:numpft_i) ! output grid: global area pfts + real(r8) :: local_i(numpft_i) ! local global area, by surface type + real(r8) :: local_o(numpft_i) ! local global area, by surface type + real(r8) :: global_i(numpft_i) ! input grid: global area pfts + real(r8) :: global_o(numpft_i) ! output grid: global area pfts !----------------------------------------------------------------------- ! Input grid global area local_i(:) = 0. - do l = 0, numpft_i - 1 + do l = 1, numpft_i do ni = 1, ns_i local_i(l) = local_i(l) + data_i(l,ni) *area_i(ni)*mask_i(ni) end do @@ -322,7 +324,7 @@ subroutine check_global_sums(name, ns_i, ns_o, numpft_i, nt, & ! Output grid global area local_o(:) = 0. - do l = 0, numpft_i - 1 + do l = 1, numpft_i do no = 1, ns_o local_o(l) = local_o(l) + data_o(l,no) *area_o(no)*frac_o(no) end do @@ -339,8 +341,8 @@ subroutine check_global_sums(name, ns_i, ns_o, numpft_i, nt, & 1x,3x,' 10**6 km**2',' 10**6 km**2') write (ndiag,'(1x,70a1)') ('.',k=1,70) write (ndiag,*) - do l = 0, numpft_i-1 - write (ndiag,102) l, global_i(l)*1.e-06*1.e-02, global_o(l)*1.e-06*1.e-02 + do l = 1, numpft_i + write (ndiag,102) l-1, global_i(l)*1.e-06*1.e-02, global_o(l)*1.e-06*1.e-02 102 format (1x,i3,f16.3,f17.3) end do end if From 3da0c0ab18d7f73006cd3c495f10fbc79318338c Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 29 Mar 2022 23:59:23 -0600 Subject: [PATCH 120/614] more changes to mksoiltexnewMod.F90 --- tools/mksurfdata_esmf/src/CMakeLists.txt | 1 + ...ksoiltexNewMod.F90 => mksoiltexnewMod.F90} | 94 +++++++++---------- tools/mksurfdata_esmf/src/mksurfdata.F90 | 10 +- 3 files changed, 48 insertions(+), 57 deletions(-) rename tools/mksurfdata_esmf/src/{mksoiltexNewMod.F90 => mksoiltexnewMod.F90} (82%) diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 597dadaf9e..26c3853338 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -40,6 +40,7 @@ set(SRCFILES mkagfirepkmonthMod.F90 mksoilcolMod.F90 mksoilfmaxMod.F90 mksoiltexMod.F90 + mksoiltexnewMod.F90 mksoildepthMod.F90 mktopostatsMod.F90 mkurbanparMod.F90 diff --git a/tools/mksurfdata_esmf/src/mksoiltexNewMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 similarity index 82% rename from tools/mksurfdata_esmf/src/mksoiltexNewMod.F90 rename to tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 index 0a7d5a406a..2d9b98f783 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexNewMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 @@ -1,4 +1,4 @@ -module mksoiltexNewMod +module mksoiltexnewMod !----------------------------------------------------------------------- ! Make soil data (texture) @@ -20,7 +20,7 @@ module mksoiltexNewMod implicit none private ! By default make data private - public :: mksoiltex ! Set soil texture + public :: mksoiltexnew ! Set soil texture integer :: mapunit_value_max integer :: num_soil_textures @@ -33,16 +33,15 @@ module mksoiltexNewMod contains !================================================================================= - subroutine mksoiltexnew(file_grid_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o, pctlnd_pft_o, rc) + subroutine mksoiltexnew(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc) ! ! make %sand and %clay from IGBP soil data, which includes ! igbp soil 'mapunits' and their corresponding textures ! ! input/output variables - character(len=*) , intent(in) :: file_grid_i ! input grid file name - character(len=*) , intent(in) :: file_mapunit_i ! input mapunit file name - character(len=*) , intent(in) :: file_lookup_i ! input lookup file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh type(file_desc_t) , intent(inout) :: pioid_o real(r8) , intent(in) :: pctlnd_pft_o(:) ! PFT data: % of gridcell for PFTs integer , intent(out) :: rc @@ -63,28 +62,27 @@ subroutine mksoiltexnew(file_grid_i, file_mapunit_i, file_lookup_i, mesh_o, pioi integer :: k,l,m,n integer :: nlay ! number of soil layers integer , allocatable :: mask_i(:) - real(r4), allocatable :: rmask_i(:) - real(r8), allocatable :: frac_o(:) real(r4), allocatable :: sand_i(:,:) ! input grid: percent sand real(r4), allocatable :: clay_i(:,:) ! input grid: percent clay - real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits real(r8), allocatable :: sand_o(:,:) ! % sand (output grid) real(r8), allocatable :: clay_o(:,:) ! % clay (output grid) integer , allocatable :: mapunit_o(:) real(r4), pointer :: dataptr(:) - real(r8), pointer :: dataptr_r8(:) - real(r4) :: sumtex integer :: mapunit ! temporary igbp soil mapunit - integer, allocatable :: soil_i(:) - integer, allocatable :: soil_o(:) - integer :: rcode, ier ! error status - integer :: srcTermProcessing_Value = 0 + ! + integer :: n_mapunits + integer :: lookup_index + real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits + integer , allocatable :: MapUnits(:) + integer , allocatable :: mapunit_lookup(:) + type(var_desc_t) :: pio_varid_sand + type(var_desc_t) :: pio_varid_clay integer :: starts(3) ! starting indices for reading lookup table integer :: counts(3) ! dimension counts for reading lookup table - integer, parameter :: nlsm=4 ! number of soil textures - character(len=38) :: soil(0:nlsm) ! name of each soil texture - character(len=38) :: typ ! soil texture based on ... - character(len=*), parameter :: subname = 'mksoiltex' + ! + integer :: srcTermProcessing_Value = 0 + integer :: rcode, ier ! error status + character(len=*), parameter :: subname = 'mksoiltexnew' !----------------------------------------------------------------------- if (root_task) then @@ -92,8 +90,7 @@ subroutine mksoiltexnew(file_grid_i, file_mapunit_i, file_lookup_i, mesh_o, pioi write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to make %sand and %clay .....' - write(ndiag,'(a)') ' Input file is '//trim(file_mapunit_i) - write(ndiag,'(a)') ' Input grid file is '//trim(file_grid_i) + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) end if ! Determine ns_o and allocate output data @@ -108,13 +105,13 @@ subroutine mksoiltexnew(file_grid_i, file_mapunit_i, file_lookup_i, mesh_o, pioi !--------------------------------- ! Open input data file - call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_mapunit_i)) - rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_mapunit_i), pio_nowrite) + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) ! Read in input mapunit mesh call ESMF_VMLogMemInfo("Before create grid_i in "//trim(subname)) if (root_task) write(ndiag,*)"DEBUG: before create grid_i in "//trim(subname) - grid_i = ESMF_GridCreate(filename=trim(file_grid_i), & + grid_i = ESMF_GridCreate(filename=trim(file_data_i), & fileformat=ESMF_FILEFORMAT_GRIDSPEC, addCornerStagger=.true., addmask=.true., varname='MU', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (root_task) write(ndiag,*)"DEBUG: before create mesh_i in "//trim(subname) @@ -155,8 +152,8 @@ subroutine mksoiltexnew(file_grid_i, file_mapunit_i, file_lookup_i, mesh_o, pioi if (root_task) write(ndiag,*)"DEBUG: before field_o creation "//trim(subname) field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! field_dstfrac = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return + field_dstfrac = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle if (root_task) write(ndiag,*)"DEBUG: before route handle creation "//trim(subname) @@ -167,24 +164,19 @@ subroutine mksoiltexnew(file_grid_i, file_mapunit_i, file_lookup_i, mesh_o, pioi call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) if (root_task) write(ndiag,*)"DEBUG: after route handle creation "//trim(subname) - ! Determin frac_o - ! call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return - ! allocate(frac_o(ns_o)) - ! frac_o(:) = dataptr_r8(:) - ! Create a dynamic mask object ! The dynamic mask object further holds a pointer to the routine that will be called in order to ! handle dynamically masked elements - in this case its DynMaskProc (see below) - if (root_task) write(ndiag,*)"DEBUG: before call to dynamic mas set creation "//trim(subname) + if (root_task) write(ndiag,*)"DEBUG: before call to dynamic mask set creation "//trim(subname) call ESMF_DynamicMaskSetR4R8R4(dynamicMask, dynamicMaskRoutine=get_dominant_mapunit, & handleAllElements=.true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag,*)"DEBUG: after call to dynamic mas set creation "//trim(subname) + if (root_task) write(ndiag,*)"DEBUG: after call to dynamic mask set creation "//trim(subname) ! Determine dominant soil color in the field regrid call below call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) dataptr(:) = real(mapunit_i(:), kind=r4) + call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:) = 0._r4 @@ -198,14 +190,12 @@ subroutine mksoiltexnew(file_grid_i, file_mapunit_i, file_lookup_i, mesh_o, pioi mapunit_o(no) = int(dataptr(no)) end do - call pio_closefile(pioid_i) + return !--------------------------------- ! Determine %sand and %clay on output grid - using above mapunits !--------------------------------- - rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_lookup_i), pio_nowrite) - rcode = pio_inq_dimid (pioid_i, 'MapUnit', dimid) rcode = pio_inq_dimlen (pioid_i, dimid, n_mapunits) @@ -232,17 +222,17 @@ subroutine mksoiltexnew(file_grid_i, file_mapunit_i, file_lookup_i, mesh_o, pioi ! Get dimensions from input file and allocate memory for sand_i and clay_i - rcode = pio_inq_varid(pioid, 'PCT_SAND', pio_varid_sand) - rcode = pio_inq_varid(pioid, 'PCT_CLAY', pio_varid_clay) + rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid_sand) + rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid_clay) starts(1:3) = 1 counts(1) = n_mapunits counts(2) = 1 counts(3) = nlay - allocate(sand_i(n_mapuntis,nlay)) - allocate(caly_i(n_mapunits,nlay)) - rcode = pio_get_var(pioid, pio_varid, starts, counts, sand_i) - rcode = pio_get_var(pioid, pio_varid, starts, counts, clay_i) + allocate(sand_i(n_mapunits,nlay)) + allocate(clay_i(n_mapunits,nlay)) + rcode = pio_get_var(pioid_i, pio_varid_sand, starts, counts, sand_i) + rcode = pio_get_var(pioid_i, pio_varid_clay, starts, counts, clay_i) do no = 1,ns_o if (mapunit_o(no) > 0) then @@ -284,14 +274,14 @@ subroutine mksoiltexnew(file_grid_i, file_mapunit_i, file_lookup_i, mesh_o, pioi call mkfile_output(pioid_o, mesh_o, 'mapunits', mapunit_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" - ! call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" + call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" - ! call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - ! call pio_syncfile(pioid_o) + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" + call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) @@ -360,4 +350,4 @@ subroutine get_dominant_mapunit(dynamicMaskList, dynamicSrcMaskValue, dynamicDst end subroutine get_dominant_mapunit -end module mksoiltexNewMod +end module mksoiltexnewMod diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 29de172459..4f95ca6212 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -103,6 +103,7 @@ program mksurfdata use mkglcmecMod , only : mkglcmecInit, mkglcmec, mkglacier use mkglacierregionMod , only : mkglacierregion use mksoiltexMod , only : mksoiltex + use mksoiltexnewMod , only : mksoiltexnew use mksoilfmaxMod , only : mksoilfmax use mksoildepthMod , only : mksoildepth use mksoilcolMod , only : mksoilcol @@ -326,15 +327,14 @@ program mksurfdata ! DEBUG if (fsurdat /= ' ') then - ! mapunits, PCT_SAND and PCT_CLAY are written out in the subroutine - mksrf_fsoitex = '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v2_grid.nc' - mksrf_fsoitex_mesh = '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v2_grid.nc' - call mksoiltex( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pioid, pctlnd_pft, rc=rc) + mksrf_fsoitex = '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v1_merged_new7.nc' + mksrf_fsoitex_mesh = trim(mksrf_fsoitex) + call mksoiltexnew( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pioid, pctlnd_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') end if call pio_closefile(pioid) - ! DEBUG call shr_sys_abort('stopping just for soiltex output') + ! DEBUG ! ----------------------------------- ! Write out natpft, cft, and time From 98c78b18a8500d0d3db757ac5ab10acb31e6aff9 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 30 Mar 2022 11:20:44 -0600 Subject: [PATCH 121/614] more updates to mksoiltexnewMod.F90 --- tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 | 172 +++++++++--------- 1 file changed, 85 insertions(+), 87 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 index 2d9b98f783..246a2f4b69 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 @@ -190,98 +190,96 @@ subroutine mksoiltexnew(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, mapunit_o(no) = int(dataptr(no)) end do - return + ! Write out mapunits + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out mapunits" + call mkfile_output(pioid_o, mesh_o, 'mapunits', mapunit_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') !--------------------------------- ! Determine %sand and %clay on output grid - using above mapunits !--------------------------------- - rcode = pio_inq_dimid (pioid_i, 'MapUnit', dimid) - rcode = pio_inq_dimlen (pioid_i, dimid, n_mapunits) - - rcode = pio_inq_dimid (pioid_i, 'soil_layer', dimid) - rcode = pio_inq_dimlen (pioid_i, dimid, nlay) - - ! Read In MapUnits from the input file - allocate(MapUnits(n_mapunits), stat=ier) - rcode = pio_inq_varid(pioid_i, 'MapUnit', pio_varid) - rcode = pio_get_var(pioid_i, pio_varid, MapUnits) - - ! Determine the mapunit lookup index from the value of the MapUnit variable - mapunit_value_max = maxval(MapUnits) - allocate(mapunit_lookup(mapunit_value_max)) - mapunit_lookup(:) = -999 - do n = 1,size(MapUnits) - mapunit_lookup(MapUnits(n)) = n - end do - - allocate(sand_i(mapunit_value_max,nlay), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(clay_i(mapunit_value_max,nlay), stat=ier) - if (ier/=0) call shr_sys_abort() - - ! Get dimensions from input file and allocate memory for sand_i and clay_i - - rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid_sand) - rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid_clay) - starts(1:3) = 1 - counts(1) = n_mapunits - counts(2) = 1 - counts(3) = nlay - - allocate(sand_i(n_mapunits,nlay)) - allocate(clay_i(n_mapunits,nlay)) - rcode = pio_get_var(pioid_i, pio_varid_sand, starts, counts, sand_i) - rcode = pio_get_var(pioid_i, pio_varid_clay, starts, counts, clay_i) - - do no = 1,ns_o - if (mapunit_o(no) > 0) then - ! valid value is obtained - if (mapunit_o(no) > mapunit_value_max) then - write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) - ! call shr_sys_abort("mapunit_o is out of bounds") - end if - lookup_index = mapunit_lookup(mapunit_o(no)) - do l = 1, nlay - sand_o(no,l) = sand_i(lookup_index,l) - clay_o(no,l) = clay_i(lookup_index,l) - end do - else - ! use loam - do l = 1, nlay - sand_o(no,l) = 43. - clay_o(no,l) = 18. - end do - end if - end do - - ! Adjust pct sand and pct clay to be nearest integers and to be loam if pctlnd_pft is < 1.e-6 - ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero - ! (not a very small number such as 1e-16) where it really should be zero - do no = 1,ns_o - do k = 1,nlevsoi - sand_o(no,k) = float(nint(sand_o(no,k))) - clay_o(no,k) = float(nint(clay_o(no,k))) - end do - if (pctlnd_pft_o(no) < 1.e-6_r8) then - sand_o(no,:) = 43._r8 - clay_o(no,:) = 18._r8 - end if - end do - - ! Write out fields - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" - call mkfile_output(pioid_o, mesh_o, 'mapunits', mapunit_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" - call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" - call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call pio_syncfile(pioid_o) + ! rcode = pio_inq_dimid (pioid_i, 'MapUnit', dimid) + ! rcode = pio_inq_dimlen (pioid_i, dimid, n_mapunits) + + ! rcode = pio_inq_dimid (pioid_i, 'soil_layer', dimid) + ! rcode = pio_inq_dimlen (pioid_i, dimid, nlay) + + ! ! Read In MapUnits from the input file + ! allocate(MapUnits(n_mapunits), stat=ier) + ! rcode = pio_inq_varid(pioid_i, 'MapUnit', pio_varid) + ! rcode = pio_get_var(pioid_i, pio_varid, MapUnits) + + ! ! Determine the mapunit lookup index from the value of the MapUnit variable + ! mapunit_value_max = maxval(MapUnits) + ! allocate(mapunit_lookup(mapunit_value_max)) + ! mapunit_lookup(:) = -999 + ! do n = 1,size(MapUnits) + ! mapunit_lookup(MapUnits(n)) = n + ! end do + + ! allocate(sand_i(mapunit_value_max,nlay), stat=ier) + ! if (ier/=0) call shr_sys_abort() + ! allocate(clay_i(mapunit_value_max,nlay), stat=ier) + ! if (ier/=0) call shr_sys_abort() + + ! ! Get dimensions from input file and allocate memory for sand_i and clay_i + + ! rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid_sand) + ! rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid_clay) + ! starts(1:3) = 1 + ! counts(1) = n_mapunits + ! counts(2) = 1 + ! counts(3) = nlay + + ! allocate(sand_i(n_mapunits,nlay)) + ! allocate(clay_i(n_mapunits,nlay)) + ! rcode = pio_get_var(pioid_i, pio_varid_sand, starts, counts, sand_i) + ! rcode = pio_get_var(pioid_i, pio_varid_clay, starts, counts, clay_i) + + ! do no = 1,ns_o + ! if (mapunit_o(no) > 0) then + ! ! valid value is obtained + ! if (mapunit_o(no) > mapunit_value_max) then + ! write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) + ! ! call shr_sys_abort("mapunit_o is out of bounds") + ! end if + ! lookup_index = mapunit_lookup(mapunit_o(no)) + ! do l = 1, nlay + ! sand_o(no,l) = sand_i(lookup_index,l) + ! clay_o(no,l) = clay_i(lookup_index,l) + ! end do + ! else + ! ! use loam + ! do l = 1, nlay + ! sand_o(no,l) = 43. + ! clay_o(no,l) = 18. + ! end do + ! end if + ! end do + + ! ! Adjust pct sand and pct clay to be nearest integers and to be loam if pctlnd_pft is < 1.e-6 + ! ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero + ! ! (not a very small number such as 1e-16) where it really should be zero + ! do no = 1,ns_o + ! do k = 1,nlevsoi + ! sand_o(no,k) = float(nint(sand_o(no,k))) + ! clay_o(no,k) = float(nint(clay_o(no,k))) + ! end do + ! if (pctlnd_pft_o(no) < 1.e-6_r8) then + ! sand_o(no,:) = 43._r8 + ! clay_o(no,:) = 18._r8 + ! end if + ! end do + + ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" + ! call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + + ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" + ! call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + ! call pio_syncfile(pioid_o) ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) From 048dc94e8725f621e91aca168e803a888bfbab58 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 30 Mar 2022 16:28:55 -0600 Subject: [PATCH 122/614] fixes to get mapunits mapped and generated correctly --- tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 | 291 +++++++++++------- tools/mksurfdata_esmf/src/mksurfdata.F90 | 2 +- 2 files changed, 185 insertions(+), 108 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 index 246a2f4b69..9f12b79f72 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 @@ -20,7 +20,7 @@ module mksoiltexnewMod implicit none private ! By default make data private - public :: mksoiltexnew ! Set soil texture + public :: mksoiltexnew ! Set soil texture integer :: mapunit_value_max integer :: num_soil_textures @@ -33,13 +33,13 @@ module mksoiltexnewMod contains !================================================================================= - subroutine mksoiltexnew(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc) + subroutine mksoiltexnew(file_grid_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc) ! ! make %sand and %clay from IGBP soil data, which includes ! igbp soil 'mapunits' and their corresponding textures ! ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_grid_i ! input grid file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh type(file_desc_t) , intent(inout) :: pioid_o @@ -62,26 +62,25 @@ subroutine mksoiltexnew(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, integer :: k,l,m,n integer :: nlay ! number of soil layers integer , allocatable :: mask_i(:) + real(r4), allocatable :: rmask_i(:) + real(r8), allocatable :: frac_o(:) real(r4), allocatable :: sand_i(:,:) ! input grid: percent sand real(r4), allocatable :: clay_i(:,:) ! input grid: percent clay + real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits real(r8), allocatable :: sand_o(:,:) ! % sand (output grid) real(r8), allocatable :: clay_o(:,:) ! % clay (output grid) integer , allocatable :: mapunit_o(:) real(r4), pointer :: dataptr(:) + real(r8), pointer :: dataptr_r8(:) + real(r4) :: sumtex integer :: mapunit ! temporary igbp soil mapunit - ! - integer :: n_mapunits - integer :: lookup_index - real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits - integer , allocatable :: MapUnits(:) - integer , allocatable :: mapunit_lookup(:) - type(var_desc_t) :: pio_varid_sand - type(var_desc_t) :: pio_varid_clay - integer :: starts(3) ! starting indices for reading lookup table - integer :: counts(3) ! dimension counts for reading lookup table - ! - integer :: srcTermProcessing_Value = 0 + integer, allocatable :: soil_i(:) + integer, allocatable :: soil_o(:) integer :: rcode, ier ! error status + integer :: srcTermProcessing_Value = 0 + integer, parameter :: nlsm=4 ! number of soil textures + character(len=38) :: soil(0:nlsm) ! name of each soil texture + character(len=38) :: typ ! soil texture based on ... character(len=*), parameter :: subname = 'mksoiltexnew' !----------------------------------------------------------------------- @@ -91,6 +90,7 @@ subroutine mksoiltexnew(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, write(ndiag,*) write(ndiag,'(a)') 'Attempting to make %sand and %clay .....' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input grid file is '//trim(file_grid_i) end if ! Determine ns_o and allocate output data @@ -100,18 +100,14 @@ subroutine mksoiltexnew(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, allocate(sand_o(ns_o,nlevsoi)) ; sand_o(:,:) = spval allocate(clay_o(ns_o,nlevsoi)) ; clay_o(:,:) = spval - !--------------------------------- - ! Determine mapunits on output grid - !--------------------------------- - ! Open input data file call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) - ! Read in input mapunit mesh + ! Read in input mesh call ESMF_VMLogMemInfo("Before create grid_i in "//trim(subname)) if (root_task) write(ndiag,*)"DEBUG: before create grid_i in "//trim(subname) - grid_i = ESMF_GridCreate(filename=trim(file_data_i), & + grid_i = ESMF_GridCreate(filename=trim(file_grid_i), & fileformat=ESMF_FILEFORMAT_GRIDSPEC, addCornerStagger=.true., addmask=.true., varname='MU', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (root_task) write(ndiag,*)"DEBUG: before create mesh_i in "//trim(subname) @@ -125,6 +121,23 @@ subroutine mksoiltexnew(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Get the landmask from the file and reset the mesh mask based on that + ! allocate(rmask_i(ns_i), stat=ier) + ! if (ier/=0) call shr_sys_abort() + ! allocate(mask_i(ns_i), stat=ier) + ! if (ier/=0) call shr_sys_abort() + ! call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return + ! do ni = 1,ns_i + ! if (rmask_i(ni) > 0._r4) then + ! mask_i(ni) = 1 + ! else + ! mask_i(ni) = 0 + ! end if + ! end do + ! call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Read in mapunit data if (root_task) write(ndiag,*)"DEBUG: before mapunit read in "//trim(subname) allocate(mapunit_i(ns_i), stat=ier) @@ -145,6 +158,13 @@ subroutine mksoiltexnew(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Determine mapunit_value_max (set it as a module variable so that it can be + ! accessible to gen_dominant_mapunit) + ! TODO: add the max_value_mapunit to the netcdf file + ! rcode = pio_inq_dimid (pioid_i, 'max_value_mapunit', dimid) + ! rcode = pio_inq_dimlen (pioid_i, dimid, mapunit_value_max) + mapunit_value_max = 32056 + ! Create ESMF fields that will be used below if (root_task) write(ndiag,*)"DEBUG: before field_i creation "//trim(subname) field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) @@ -152,31 +172,40 @@ subroutine mksoiltexnew(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, if (root_task) write(ndiag,*)"DEBUG: before field_o creation "//trim(subname) field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - field_dstfrac = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! field_dstfrac = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle if (root_task) write(ndiag,*)"DEBUG: before route handle creation "//trim(subname) + ! call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & + ! regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & + ! ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & + ! dstFracField= field_dstfrac, rc=rc) call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & - ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & - dstFracField= field_dstfrac, rc=rc) + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) if (root_task) write(ndiag,*)"DEBUG: after route handle creation "//trim(subname) + ! Determin frac_o + ! call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return + ! allocate(frac_o(ns_o)) + ! frac_o(:) = dataptr_r8(:) + ! Create a dynamic mask object ! The dynamic mask object further holds a pointer to the routine that will be called in order to ! handle dynamically masked elements - in this case its DynMaskProc (see below) - if (root_task) write(ndiag,*)"DEBUG: before call to dynamic mask set creation "//trim(subname) + if (root_task) write(ndiag,*)"DEBUG: before call to dynamic mas set creation "//trim(subname) call ESMF_DynamicMaskSetR4R8R4(dynamicMask, dynamicMaskRoutine=get_dominant_mapunit, & handleAllElements=.true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag,*)"DEBUG: after call to dynamic mask set creation "//trim(subname) + if (root_task) write(ndiag,*)"DEBUG: after call to dynamic mas set creation "//trim(subname) ! Determine dominant soil color in the field regrid call below call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) dataptr(:) = real(mapunit_i(:), kind=r4) - call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:) = 0._r4 @@ -190,88 +219,136 @@ subroutine mksoiltexnew(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, mapunit_o(no) = int(dataptr(no)) end do - ! Write out mapunits - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out mapunits" + ! Get dimensions from input file and allocate memory for sand_i and clay_i +! rcode = pio_inq_dimid (pioid_i, 'number_of_layers', dimid) +! rcode = pio_inq_dimlen (pioid_i, dimid, nlay) +! allocate(sand_i(mapunit_value_max,nlay), stat=ier) +! if (ier/=0) call shr_sys_abort() +! allocate(clay_i(mapunit_value_max,nlay), stat=ier) +! if (ier/=0) call shr_sys_abort() + +! ! read in sand_i and clay_i (they will read in total on all processors) +! rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid) +! rcode = pio_get_var(pioid_i, pio_varid, sand_i) +! rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid) +! rcode = pio_get_var(pioid_i, pio_varid, clay_i) + +! ! Set soil texture as follows: +! ! a. Use dominant igbp soil mapunit based on area of overlap unless 'no data' is dominant +! ! b. If this has no data, use loam for soil texture + +! do no = 1,ns_o +! if (mapunit_o(no) > 0) then +! ! valid value is obtained +! if (mapunit_o(no) > mapunit_value_max) then +! write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) +! ! call shr_sys_abort("mapunit_o is out of bounds") +! end if +! do l = 1, nlay +! sand_o(no,l) = sand_i(mapunit_o(no),l) +! clay_o(no,l) = clay_i(mapunit_o(no),l) +! end do +! else +! ! use loam +! do l = 1, nlay +! sand_o(no,l) = 43. +! clay_o(no,l) = 18. +! end do +! end if +! end do + +! ! Define the model surface types: 0:4 +! soil(0) = 'no soil: ocean, glacier, lake, no data' +! soil(1) = 'clays ' +! soil(2) = 'sands ' +! soil(3) = 'loams ' +! soil(4) = 'silts ' + +! ! input grid: determine soil_i for global area comparison +! allocate(soil_i(ns_i)) +! do l = 1, nlay +! do ni = 1,ns_i +! mapunit = nint(mapunit_i(ni)) +! if (mapunit==0) then +! typ = 'no soil: ocean, glacier, lake, no data' +! else if (clay_i(mapunit,l) >= 40.) then +! typ = 'clays' +! else if (sand_i(mapunit,l) >= 50.) then +! typ = 'sands' +! else if (clay_i(mapunit,l)+sand_i(mapunit,l) < 50.) then +! if (mask_i(ni) /= 0) then +! typ = 'silts' +! else +! typ = 'no soil: ocean, glacier, lake, no data' +! end if +! else +! typ = 'loams' +! end if +! do m = 0, nlsm +! if (typ == soil(m)) go to 101 +! end do +! write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunit,l), & +! ' clay = ',clay_i(mapunit,l),' not assigned to soil type for input grid lon,lat,layer = ',ni,l +! call shr_sys_abort() +! 101 continue +! soil_i(ni) = m ! allocate memory for this +! end do +! end do + +! ! output grid: determine soil_o for global area comparison +! allocate(soil_o(ns_o)) +! do l = 1, nlay +! do no = 1,ns_o +! if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then +! typ = 'no soil: ocean, glacier, lake, no data' +! else if (clay_o(no,l) >= 40.) then +! typ = 'clays' +! else if (sand_o(no,l) >= 50.) then +! typ = 'sands' +! else if (clay_o(no,l)+sand_o(no,l) < 50.) then +! typ = 'silts' +! else +! typ = 'loams' +! end if +! do m = 0, nlsm +! if (typ == soil(m)) go to 102 +! end do +! write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & +! ' clay = ',clay_o(no,l), ' not assigned to soil type for output grid lon,lat,layer = ',no,l +! call shr_sys_abort() +! 102 continue +! soil_o(no) = m +! end do +! end do + +! ! Compare global areas +! if (root_task) then +! write (ndiag,'(a)') 'The following table of soil texture classes is for comparison only.' +! write (ndiag,'(a)') 'The actual data is continuous %sand, %silt and %clay not textural classes' +! end if +! ! call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & +! ! 0, nlsm, soil_i, soil_o, 'soil texture class', ndiag, rc) +! ! if (chkerr(rc,__LINE__,u_FILE_u)) return + +! ! Adjust pct sand and pct clay to be nearest integers and to be loam if pctlnd_pft is < 1.e-6 +! ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero +! ! (not a very small number such as 1e-16) where it really should be zero +! do no = 1,ns_o +! do k = 1,nlevsoi +! sand_o(no,k) = float(nint(sand_o(no,k))) +! clay_o(no,k) = float(nint(clay_o(no,k))) +! end do +! if (pctlnd_pft_o(no) < 1.e-6_r8) then +! sand_o(no,:) = 43._r8 +! clay_o(no,:) = 18._r8 +! end if +! end do + + ! Write out fields + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" call mkfile_output(pioid_o, mesh_o, 'mapunits', mapunit_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') - !--------------------------------- - ! Determine %sand and %clay on output grid - using above mapunits - !--------------------------------- - - ! rcode = pio_inq_dimid (pioid_i, 'MapUnit', dimid) - ! rcode = pio_inq_dimlen (pioid_i, dimid, n_mapunits) - - ! rcode = pio_inq_dimid (pioid_i, 'soil_layer', dimid) - ! rcode = pio_inq_dimlen (pioid_i, dimid, nlay) - - ! ! Read In MapUnits from the input file - ! allocate(MapUnits(n_mapunits), stat=ier) - ! rcode = pio_inq_varid(pioid_i, 'MapUnit', pio_varid) - ! rcode = pio_get_var(pioid_i, pio_varid, MapUnits) - - ! ! Determine the mapunit lookup index from the value of the MapUnit variable - ! mapunit_value_max = maxval(MapUnits) - ! allocate(mapunit_lookup(mapunit_value_max)) - ! mapunit_lookup(:) = -999 - ! do n = 1,size(MapUnits) - ! mapunit_lookup(MapUnits(n)) = n - ! end do - - ! allocate(sand_i(mapunit_value_max,nlay), stat=ier) - ! if (ier/=0) call shr_sys_abort() - ! allocate(clay_i(mapunit_value_max,nlay), stat=ier) - ! if (ier/=0) call shr_sys_abort() - - ! ! Get dimensions from input file and allocate memory for sand_i and clay_i - - ! rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid_sand) - ! rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid_clay) - ! starts(1:3) = 1 - ! counts(1) = n_mapunits - ! counts(2) = 1 - ! counts(3) = nlay - - ! allocate(sand_i(n_mapunits,nlay)) - ! allocate(clay_i(n_mapunits,nlay)) - ! rcode = pio_get_var(pioid_i, pio_varid_sand, starts, counts, sand_i) - ! rcode = pio_get_var(pioid_i, pio_varid_clay, starts, counts, clay_i) - - ! do no = 1,ns_o - ! if (mapunit_o(no) > 0) then - ! ! valid value is obtained - ! if (mapunit_o(no) > mapunit_value_max) then - ! write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) - ! ! call shr_sys_abort("mapunit_o is out of bounds") - ! end if - ! lookup_index = mapunit_lookup(mapunit_o(no)) - ! do l = 1, nlay - ! sand_o(no,l) = sand_i(lookup_index,l) - ! clay_o(no,l) = clay_i(lookup_index,l) - ! end do - ! else - ! ! use loam - ! do l = 1, nlay - ! sand_o(no,l) = 43. - ! clay_o(no,l) = 18. - ! end do - ! end if - ! end do - - ! ! Adjust pct sand and pct clay to be nearest integers and to be loam if pctlnd_pft is < 1.e-6 - ! ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero - ! ! (not a very small number such as 1e-16) where it really should be zero - ! do no = 1,ns_o - ! do k = 1,nlevsoi - ! sand_o(no,k) = float(nint(sand_o(no,k))) - ! clay_o(no,k) = float(nint(clay_o(no,k))) - ! end do - ! if (pctlnd_pft_o(no) < 1.e-6_r8) then - ! sand_o(no,:) = 43._r8 - ! clay_o(no,:) = 18._r8 - ! end if - ! end do - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" ! call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 4f95ca6212..afe5d5f632 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -327,7 +327,7 @@ program mksurfdata ! DEBUG if (fsurdat /= ' ') then - mksrf_fsoitex = '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v1_merged_new7.nc' + mksrf_fsoitex = '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v5_grid.nc' mksrf_fsoitex_mesh = trim(mksrf_fsoitex) call mksoiltexnew( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pioid, pctlnd_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') From 17982dfc5fa6ba44f98e77741aad713942bd69be Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 6 Apr 2022 15:08:27 -0600 Subject: [PATCH 123/614] Bringing in code recommended in #1695 - correctly outputs time variable with unlimited time dimension - adds a -g to the Makefile --- tools/mksurfdata_esmf/src/Makefile | 2 +- tools/mksurfdata_esmf/src/mklaiMod.F90 | 5 +++++ tools/mksurfdata_esmf/src/mksurfdata.F90 | 7 ------- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/tools/mksurfdata_esmf/src/Makefile b/tools/mksurfdata_esmf/src/Makefile index f89482a85c..dc3570168d 100644 --- a/tools/mksurfdata_esmf/src/Makefile +++ b/tools/mksurfdata_esmf/src/Makefile @@ -45,7 +45,7 @@ include $(ESMFMKFILE) # ----------------------------------------------------------------------------- mksurfdata: mksurfdata.o - $(ESMF_F90LINKER) $(LINKPATH) $(PIO_LINKPATH) $(ESMF_F90LINKOPTS) $(ESMF_F90LINKPATHS) $(ESMF_F90LINKRPATHS) -o $@ $^ $(ESMF_F90ESMFLINKLIBS) -l mksurfdata -l piof -l pnetcdf -lnetcdf + $(ESMF_F90LINKER) -g $(LINKPATH) $(PIO_LINKPATH) $(ESMF_F90LINKOPTS) $(ESMF_F90LINKPATHS) $(ESMF_F90LINKRPATHS) -o $@ $^ $(ESMF_F90ESMFLINKLIBS) -l mksurfdata -l piof -l pnetcdf -lnetcdf # ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------- diff --git a/tools/mksurfdata_esmf/src/mklaiMod.F90 b/tools/mksurfdata_esmf/src/mklaiMod.F90 index a61df40cf7..84069bded4 100644 --- a/tools/mksurfdata_esmf/src/mklaiMod.F90 +++ b/tools/mksurfdata_esmf/src/mklaiMod.F90 @@ -193,8 +193,13 @@ subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) msai_o(:,:) = 0. mhgtt_o(:,:) = 0. mhgtb_o(:,:) = 0. + do nt = 1, ntime + ! time is months for LAI, SAI, and pft heights + rcode = pio_inq_varid(pioid_o, 'time', pio_varid_o) + rcode = pio_put_var(pioid_o, pio_varid_o, (/nt/), nt) + ! Below - copy LAI, SAI, & heights from the C3 crop (pft15) ! to the irrigated (pft16) whether crop is on or off ! Hence loop to numpft_i - 1 for other pfts diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 7709a72b02..8f7135cc6d 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -173,10 +173,6 @@ program mksurfdata real(r8), allocatable :: pctwet_orig(:) ! percent wetland of gridcell before dynamic land use adjustments real(r8), allocatable :: pctgla_orig(:) ! percent glacier of gridcell before dynamic land use adjustments - ! time parameters - integer, parameter :: n_jan = 1 - integer, parameter :: n_dec = 12 - ! pio/esmf variables type(file_desc_t) :: pioid type(var_desc_t) :: pio_varid @@ -334,9 +330,6 @@ program mksurfdata rcode = pio_inq_varid(pioid, 'cft', pio_varid) rcode = pio_put_var(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/)) end if - ! time is months for LAI, SAI, and pft heights - rcode = pio_inq_varid(pioid, 'time', pio_varid) - rcode = pio_put_var(pioid, pio_varid, (/(n,n=n_jan,n_dec)/)) end if ! ----------------------------------- From 2491f62a093738de1942214a826f4fd54c17fead Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 6 Apr 2022 18:21:47 -0600 Subject: [PATCH 124/614] more updates to get PCT_SAND and PCT_CLAY output for new soil dataset --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 4 +- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 1 + tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 | 387 ++++++++---------- tools/mksurfdata_esmf/src/mksurfdata.F90 | 61 +-- 4 files changed, 216 insertions(+), 237 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 4582e584b8..611eb42165 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -261,11 +261,11 @@ subroutine mkfile_define_vars(pioid, dynlanduse) call mkpio_def_spatial_var(pioid=pioid, varname='SOIL_COLOR', xtype=PIO_INT, & long_name='soil color', units='unitless') - call mkpio_def_spatial_var(pioid=pioid, varname='PCT_SAND', xtype=xtype, & + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_SAND', xtype=PIO_REAL, & lev1name='nlevsoi', & long_name='percent sand', units='unitless') - call mkpio_def_spatial_var(pioid=pioid, varname='PCT_CLAY', xtype=xtype, & + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_CLAY', xtype=PIO_REAL, & lev1name='nlevsoi', & long_name='percent clay', units='unitless') diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 6ca1aecfec..4f2e190a6d 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -195,6 +195,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc ! Get dimensions from input file and allocate memory for sand_i and clay_i rcode = pio_inq_dimid (pioid_i, 'number_of_layers', dimid) rcode = pio_inq_dimlen (pioid_i, dimid, nlay) + allocate(sand_i(mapunit_value_max,nlay), stat=ier) if (ier/=0) call shr_sys_abort() allocate(clay_i(mapunit_value_max,nlay), stat=ier) diff --git a/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 index 9f12b79f72..51a544d828 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 @@ -33,15 +33,16 @@ module mksoiltexnewMod contains !================================================================================= - subroutine mksoiltexnew(file_grid_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc) + subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o, pctlnd_pft_o, rc) ! ! make %sand and %clay from IGBP soil data, which includes ! igbp soil 'mapunits' and their corresponding textures ! ! input/output variables - character(len=*) , intent(in) :: file_grid_i ! input grid file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + character(len=*) , intent(in) :: file_mesh_i ! input mesh/grid file name + character(len=*) , intent(in) :: file_mapunit_i ! input mapunit file name + character(len=*) , intent(in) :: file_lookup_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh type(file_desc_t) , intent(inout) :: pioid_o real(r8) , intent(in) :: pctlnd_pft_o(:) ! PFT data: % of gridcell for PFTs integer , intent(out) :: rc @@ -52,7 +53,6 @@ subroutine mksoiltexnew(file_grid_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, type(ESMF_Mesh) :: mesh_i type(ESMF_Field) :: field_i type(ESMF_Field) :: field_o - type(ESMF_Field) :: field_dstfrac type(file_desc_t) :: pioid_i type(var_desc_t) :: pio_varid integer :: pio_vartype @@ -62,25 +62,30 @@ subroutine mksoiltexnew(file_grid_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, integer :: k,l,m,n integer :: nlay ! number of soil layers integer , allocatable :: mask_i(:) - real(r4), allocatable :: rmask_i(:) - real(r8), allocatable :: frac_o(:) - real(r4), allocatable :: sand_i(:,:) ! input grid: percent sand - real(r4), allocatable :: clay_i(:,:) ! input grid: percent clay - real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits - real(r8), allocatable :: sand_o(:,:) ! % sand (output grid) - real(r8), allocatable :: clay_o(:,:) ! % clay (output grid) - integer , allocatable :: mapunit_o(:) real(r4), pointer :: dataptr(:) - real(r8), pointer :: dataptr_r8(:) - real(r4) :: sumtex integer :: mapunit ! temporary igbp soil mapunit - integer, allocatable :: soil_i(:) - integer, allocatable :: soil_o(:) - integer :: rcode, ier ! error status + ! + integer, allocatable :: sand_i(:,:,:) ! input grid: percent sand + integer, allocatable :: clay_i(:,:,:) ! input grid: percent clay + real(r4), allocatable :: sand_o(:,:) ! % sand (output grid) + real(r4), allocatable :: clay_o(:,:) ! % clay (output grid) + integer :: n_mapunits + integer :: lookup_index + integer :: SCID + real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits + integer , allocatable :: mapunit_o(:) + integer , allocatable :: MapUnits(:) + integer , allocatable :: mapunit_lookup(:) + type(var_desc_t) :: pio_varid_sand + type(var_desc_t) :: pio_varid_clay + integer :: starts(3) ! starting indices for reading lookup table + integer :: counts(3) ! dimension counts for reading lookup table + ! integer :: srcTermProcessing_Value = 0 - integer, parameter :: nlsm=4 ! number of soil textures - character(len=38) :: soil(0:nlsm) ! name of each soil texture - character(len=38) :: typ ! soil texture based on ... + integer :: rcode, ier ! error status + ! DEBUG + integer :: i,j + ! DEBUG character(len=*), parameter :: subname = 'mksoiltexnew' !----------------------------------------------------------------------- @@ -89,8 +94,9 @@ subroutine mksoiltexnew(file_grid_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to make %sand and %clay .....' - write(ndiag,'(a)') ' Input file is '//trim(file_data_i) - write(ndiag,'(a)') ' Input grid file is '//trim(file_grid_i) + write(ndiag,'(a)') ' Input mapunit file is '//trim(file_mapunit_i) + write(ndiag,'(a)') ' Input lookup table file is '//trim(file_lookup_i) + write(ndiag,'(a)') ' Input mesh/grid file is '//trim(file_mesh_i) end if ! Determine ns_o and allocate output data @@ -100,54 +106,47 @@ subroutine mksoiltexnew(file_grid_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, allocate(sand_o(ns_o,nlevsoi)) ; sand_o(:,:) = spval allocate(clay_o(ns_o,nlevsoi)) ; clay_o(:,:) = spval - ! Open input data file - call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) - rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) - - ! Read in input mesh - call ESMF_VMLogMemInfo("Before create grid_i in "//trim(subname)) - if (root_task) write(ndiag,*)"DEBUG: before create grid_i in "//trim(subname) - grid_i = ESMF_GridCreate(filename=trim(file_grid_i), & - fileformat=ESMF_FILEFORMAT_GRIDSPEC, addCornerStagger=.true., addmask=.true., varname='MU', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag,*)"DEBUG: before create mesh_i in "//trim(subname) - call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) - mesh_i = esmf_meshcreate(grid_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - if (root_task) write(ndiag,*)"DEBUG: after create mesh_i in "//trim(subname) + !--------------------------------- + ! Determine mapunits on output grid + !--------------------------------- + + ! Determine input mesh + if (trim(file_mesh_i) == trim(file_mapunit_i)) then + ! input format is GRIDSPEC and read in grid and then create mesh + if (root_task) write(ndiag,*)"reading grid_i and then creating mesh_i in "//trim(subname) + call ESMF_VMLogMemInfo("Before create read in grid_i in "//trim(subname)) + grid_i = ESMF_GridCreate(filename=trim(file_mesh_i), & + fileformat=ESMF_FILEFORMAT_GRIDSPEC, addCornerStagger=.true., addmask=.true., varname='MU', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + mesh_i = esmf_meshcreate(grid_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + else + ! Read in mesh directly + if (root_task) write(ndiag,*)"reading mesh_i directly in "//trim(subname) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if ! Determine ns_i (use the distgrid to the number of elements) call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Get the landmask from the file and reset the mesh mask based on that - ! allocate(rmask_i(ns_i), stat=ier) - ! if (ier/=0) call shr_sys_abort() - ! allocate(mask_i(ns_i), stat=ier) - ! if (ier/=0) call shr_sys_abort() - ! call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return - ! do ni = 1,ns_i - ! if (rmask_i(ni) > 0._r4) then - ! mask_i(ni) = 1 - ! else - ! mask_i(ni) = 0 - ! end if - ! end do - ! call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Opne input mapunit data file + if (root_task) write(ndiag,*)"Reading in mapunit data in "//trim(subname) + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_mapunit_i)) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_mapunit_i), pio_nowrite) ! Read in mapunit data - if (root_task) write(ndiag,*)"DEBUG: before mapunit read in "//trim(subname) allocate(mapunit_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid_i, 'MU', mesh_i, mapunit_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - if (root_task) write(ndiag,*)"DEBUG: after mapunit read in "//trim(subname) - ! Set mapunit values to zero where the input mask is 0 + ! Set mesh mask to zero where the mapunit values are 0 + if (root_task) write(ndiag,*)"Setting mask in mesh where mapunit data is 0 "//trim(subname) allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() do ni = 1,ns_i @@ -158,29 +157,14 @@ subroutine mksoiltexnew(file_grid_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Determine mapunit_value_max (set it as a module variable so that it can be - ! accessible to gen_dominant_mapunit) - ! TODO: add the max_value_mapunit to the netcdf file - ! rcode = pio_inq_dimid (pioid_i, 'max_value_mapunit', dimid) - ! rcode = pio_inq_dimlen (pioid_i, dimid, mapunit_value_max) - mapunit_value_max = 32056 - ! Create ESMF fields that will be used below - if (root_task) write(ndiag,*)"DEBUG: before field_i creation "//trim(subname) field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag,*)"DEBUG: before field_o creation "//trim(subname) field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! field_dstfrac = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle if (root_task) write(ndiag,*)"DEBUG: before route handle creation "//trim(subname) - ! call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & - ! regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & - ! ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & - ! dstFracField= field_dstfrac, rc=rc) call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) @@ -188,12 +172,6 @@ subroutine mksoiltexnew(file_grid_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) if (root_task) write(ndiag,*)"DEBUG: after route handle creation "//trim(subname) - ! Determin frac_o - ! call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return - ! allocate(frac_o(ns_o)) - ! frac_o(:) = dataptr_r8(:) - ! Create a dynamic mask object ! The dynamic mask object further holds a pointer to the routine that will be called in order to ! handle dynamically masked elements - in this case its DynMaskProc (see below) @@ -203,160 +181,145 @@ subroutine mksoiltexnew(file_grid_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, if (chkerr(rc,__LINE__,u_FILE_u)) return if (root_task) write(ndiag,*)"DEBUG: after call to dynamic mas set creation "//trim(subname) - ! Determine dominant soil color in the field regrid call below + ! Determine values in field_i call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) dataptr(:) = real(mapunit_i(:), kind=r4) + + ! Determine mapunit_value_max (set it as a module variable so that it can be + ! accessible to gen_dominant_mapunit) - this is needed in the dynamic mask routine + mapunit_value_max = maxval(dataptr) + + ! Determine values in field_o call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:) = 0._r4 + ! Determine mapunit_o call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, dynamicMask=dynamicMask, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do no = 1,ns_o mapunit_o(no) = int(dataptr(no)) end do + call pio_closefile(pioid_i) + + !--------------------------------- + ! Determine %sand and %clay on output grid - using above mapunits + !--------------------------------- + + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_lookup_i), pio_nowrite) + + rcode = pio_inq_dimid (pioid_i, 'MapUnit', dimid) + rcode = pio_inq_dimlen (pioid_i, dimid, n_mapunits) + write(6,*)'DEBUG: n_mapunits = ',n_mapunits + + rcode = pio_inq_dimid (pioid_i, 'soil_layer', dimid) + rcode = pio_inq_dimlen (pioid_i, dimid, nlay) + write(6,*)'DEBUG: nlay = ',nlay + + rcode = pio_inq_dimid (pioid_i, 'SCID', dimid) + rcode = pio_inq_dimlen (pioid_i, dimid, SCID) + write(6,*)'DEBUG: SCID= ',SCID + + ! Read In MapUnits from the input file + allocate(MapUnits(n_mapunits), stat=ier) + rcode = pio_inq_varid(pioid_i, 'MapUnit', pio_varid) + rcode = pio_get_var(pioid_i, pio_varid, MapUnits) + + ! Determine the mapunit lookup index from the value of the MapUnit variable + mapunit_value_max = maxval(MapUnits) + allocate(mapunit_lookup(mapunit_value_max)) + mapunit_lookup(:) = -999 + do n = 1,size(MapUnits) + mapunit_lookup(MapUnits(n)) = n + end do + + allocate(sand_i(nlay,SCID,n_mapunits)) + if (ier/=0) call shr_sys_abort() + allocate(clay_i(nlay,SCID,n_mapunits)) + if (ier/=0) call shr_sys_abort() + ! Get dimensions from input file and allocate memory for sand_i and clay_i -! rcode = pio_inq_dimid (pioid_i, 'number_of_layers', dimid) -! rcode = pio_inq_dimlen (pioid_i, dimid, nlay) -! allocate(sand_i(mapunit_value_max,nlay), stat=ier) -! if (ier/=0) call shr_sys_abort() -! allocate(clay_i(mapunit_value_max,nlay), stat=ier) -! if (ier/=0) call shr_sys_abort() - -! ! read in sand_i and clay_i (they will read in total on all processors) -! rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid) -! rcode = pio_get_var(pioid_i, pio_varid, sand_i) -! rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid) -! rcode = pio_get_var(pioid_i, pio_varid, clay_i) - -! ! Set soil texture as follows: -! ! a. Use dominant igbp soil mapunit based on area of overlap unless 'no data' is dominant -! ! b. If this has no data, use loam for soil texture - -! do no = 1,ns_o -! if (mapunit_o(no) > 0) then -! ! valid value is obtained -! if (mapunit_o(no) > mapunit_value_max) then -! write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) -! ! call shr_sys_abort("mapunit_o is out of bounds") -! end if -! do l = 1, nlay -! sand_o(no,l) = sand_i(mapunit_o(no),l) -! clay_o(no,l) = clay_i(mapunit_o(no),l) -! end do -! else -! ! use loam -! do l = 1, nlay -! sand_o(no,l) = 43. -! clay_o(no,l) = 18. -! end do -! end if -! end do - -! ! Define the model surface types: 0:4 -! soil(0) = 'no soil: ocean, glacier, lake, no data' -! soil(1) = 'clays ' -! soil(2) = 'sands ' -! soil(3) = 'loams ' -! soil(4) = 'silts ' - -! ! input grid: determine soil_i for global area comparison -! allocate(soil_i(ns_i)) -! do l = 1, nlay -! do ni = 1,ns_i -! mapunit = nint(mapunit_i(ni)) -! if (mapunit==0) then -! typ = 'no soil: ocean, glacier, lake, no data' -! else if (clay_i(mapunit,l) >= 40.) then -! typ = 'clays' -! else if (sand_i(mapunit,l) >= 50.) then -! typ = 'sands' -! else if (clay_i(mapunit,l)+sand_i(mapunit,l) < 50.) then -! if (mask_i(ni) /= 0) then -! typ = 'silts' -! else -! typ = 'no soil: ocean, glacier, lake, no data' -! end if -! else -! typ = 'loams' -! end if -! do m = 0, nlsm -! if (typ == soil(m)) go to 101 -! end do -! write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunit,l), & -! ' clay = ',clay_i(mapunit,l),' not assigned to soil type for input grid lon,lat,layer = ',ni,l -! call shr_sys_abort() -! 101 continue -! soil_i(ni) = m ! allocate memory for this -! end do -! end do - -! ! output grid: determine soil_o for global area comparison -! allocate(soil_o(ns_o)) -! do l = 1, nlay -! do no = 1,ns_o -! if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then -! typ = 'no soil: ocean, glacier, lake, no data' -! else if (clay_o(no,l) >= 40.) then -! typ = 'clays' -! else if (sand_o(no,l) >= 50.) then -! typ = 'sands' -! else if (clay_o(no,l)+sand_o(no,l) < 50.) then -! typ = 'silts' -! else -! typ = 'loams' -! end if -! do m = 0, nlsm -! if (typ == soil(m)) go to 102 -! end do -! write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & -! ' clay = ',clay_o(no,l), ' not assigned to soil type for output grid lon,lat,layer = ',no,l -! call shr_sys_abort() -! 102 continue -! soil_o(no) = m -! end do -! end do - -! ! Compare global areas -! if (root_task) then -! write (ndiag,'(a)') 'The following table of soil texture classes is for comparison only.' -! write (ndiag,'(a)') 'The actual data is continuous %sand, %silt and %clay not textural classes' -! end if -! ! call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & -! ! 0, nlsm, soil_i, soil_o, 'soil texture class', ndiag, rc) -! ! if (chkerr(rc,__LINE__,u_FILE_u)) return - -! ! Adjust pct sand and pct clay to be nearest integers and to be loam if pctlnd_pft is < 1.e-6 -! ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero -! ! (not a very small number such as 1e-16) where it really should be zero -! do no = 1,ns_o -! do k = 1,nlevsoi -! sand_o(no,k) = float(nint(sand_o(no,k))) -! clay_o(no,k) = float(nint(clay_o(no,k))) -! end do -! if (pctlnd_pft_o(no) < 1.e-6_r8) then -! sand_o(no,:) = 43._r8 -! clay_o(no,:) = 18._r8 -! end if -! end do + rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid_sand) + rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid_clay) + + rcode = pio_get_var(pioid_i, pio_varid_sand, sand_i) + rcode = pio_get_var(pioid_i, pio_varid_clay, clay_i) + + if (root_task) then + do i = 1,n_mapunits + do j = 1,SCID + do k = 1,nlay + write(6,'(a,4(i8,2x))')'DEBUG: lev,scid,mapunit,sand_i= ',k,j,i,sand_i(k,j,i) + end do + end do + end do + end if + + do no = 1,ns_o + if (mapunit_o(no) > 0) then + ! valid value is obtained + if (mapunit_o(no) > mapunit_value_max) then + write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) + ! call shr_sys_abort("mapunit_o is out of bounds") + end if + lookup_index = mapunit_lookup(mapunit_o(no)) + do l = 1, nlay + sand_o(no,l) = float(sand_i(l,1,lookup_index)) + clay_o(no,l) = float(clay_i(l,1,lookup_index)) + if (sand_o(no,l) < 0. .and. l > 1) then + sand_o(no,l) = sand_o(no,l-1) + end if + if (clay_o(no,l) < 0. .and. l > 1) then + clay_o(no,l) = clay_o(no,l-1) + end if + end do + write(6,'(a,3(i8,2x),3(f14.5,2x))') & + 'DEBUG: no,mapunit_o(no),lookup_index,pctlnd_pft_o(no),sand_o(no,1),clay_o(no,1) = ',& + no,mapunit_o(no),lookup_index,pctlnd_pft_o(no),sand_o(no,1),clay_o(no,1) + else + ! use loam + do l = 1, nlay + sand_o(no,l) = 43. + clay_o(no,l) = 18. + end do + end if + end do + + ! Adjust pct sand and pct clay to be nearest integers and to be loam if pctlnd_pft is < 1.e-6 + ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero + ! (not a very small number such as 1e-16) where it really should be zero + do no = 1,ns_o + if (pctlnd_pft_o(no) < 1.e-6_r8) then + sand_o(no,:) = 43._r4 + clay_o(no,:) = 18._r4 + end if + end do - ! Write out fields if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" + call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" + call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) + + ! Write out fields + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out mapunits " call mkfile_output(pioid_o, mesh_o, 'mapunits', mapunit_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" - ! call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" + call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - ! if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" - ! call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - ! call pio_syncfile(pioid_o) + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" + call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) ! Release memory call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index afe5d5f632..ff4385ef25 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -136,7 +136,7 @@ program mksurfdata integer :: ntim ! time sample for dynamic land use integer :: year ! year for dynamic land use integer :: year2 ! year for dynamic land use for harvest file - real(r8) :: suma ! local sum for error check + real(r8) :: suma ! local sum for error check real(r8) :: loc_suma, glob_suma ! local and global sum for error check with mpi_allreduce ! model grid @@ -196,6 +196,10 @@ program mksurfdata character(len=CL) :: fname character(len=*), parameter :: subname = 'mksrfdata' ! program name + ! TODO: temporary for new soil texture data + character(len=CL) :: mksrf_fsoitex_mapunit + character(len=CL) :: mksrf_fsoitex_lookup + character(len=*), parameter :: u_FILE_u = & __FILE__ @@ -325,17 +329,6 @@ program mksurfdata ! NOTE: do not deallocate pctlak, pctwet, pctglacier and pcturban - ! DEBUG - if (fsurdat /= ' ') then - mksrf_fsoitex = '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v5_grid.nc' - mksrf_fsoitex_mesh = trim(mksrf_fsoitex) - call mksoiltexnew( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pioid, pctlnd_pft, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') - end if - call pio_closefile(pioid) - call shr_sys_abort('stopping just for soiltex output') - ! DEBUG - ! ----------------------------------- ! Write out natpft, cft, and time ! ----------------------------------- @@ -369,15 +362,6 @@ program mksurfdata call pio_syncfile(pioid) end if - ! ----------------------------------- - ! Make LAI and SAI from 1/2 degree data and write to surface dataset - ! Write to netcdf file is done inside mklai routine - ! ----------------------------------- - if (fsurdat /= ' ') then - call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') - end if - ! ----------------------------------- ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] ! Make landfrac_pft and pftdata_mask @@ -420,6 +404,37 @@ program mksurfdata call pio_syncfile(pioid) end if + ! DEBUG + if (fsurdat /= ' ') then + ! --- for a 3 second input mapunit --- + ! mksrf_fsoitex_mapunit = & + ! '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v5_grid.nc' + + ! --- for a 5min input mapunit--- + mksrf_fsoitex_mesh = & + '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' + mksrf_fsoitex_mapunit = & + '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/soiltex_mapunits_4320x2160_c220329.nc' + mksrf_fsoitex_lookup = & + '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v5_lookup.nc' + + call mksoiltexnew( mksrf_fsoitex_mesh, file_mapunit_i=mksrf_fsoitex_mapunit, file_lookup_i=mksrf_fsoitex_lookup, & + mesh_o=mesh_model, pioid_o=pioid, pctlnd_pft_o=pctlnd_pft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') + end if + call pio_closefile(pioid) + call shr_sys_abort('stopping just for soiltex output') + ! DEBUG + + ! ----------------------------------- + ! Make LAI and SAI from 1/2 degree data and write to surface dataset + ! Write to netcdf file is done inside mklai routine + ! ----------------------------------- + ! if (fsurdat /= ' ') then + ! call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') + ! end if + ! ----------------------------------- ! Make constant harvesting data at model resolution ! ----------------------------------- @@ -634,7 +649,7 @@ program mksurfdata end if end do - ! Save special land unit areas of surface dataset + ! Save special land unit areas of surface dataset pctwet_orig(:) = pctwet(:) pctgla_orig(:) = pctgla(:) @@ -730,7 +745,7 @@ program mksurfdata end if call mkfile_output(pioid, mesh_model, 'PCT_NAT_PFT', pct_nat_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NAT_PFT') - + if (num_cft > 0) then if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_CFT" if (lsize_o /= 0) then From 8829bd7ef74cbeec00932d67b1b86ff49ca134fc Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 6 Apr 2022 18:43:14 -0600 Subject: [PATCH 125/614] .log stats looking more similar between the new and old mksurfdata I'm keeping track of pending issues in the README --- tools/mksurfdata_esmf/README | 26 +++++-------- .../mksurfdata_esmf/src/mkdiagnosticsMod.F90 | 14 ++++++- tools/mksurfdata_esmf/src/mkglcmecMod.F90 | 37 +++---------------- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 6 +-- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 10 ++--- tools/mksurfdata_esmf/src/mkpeatMod.F90 | 6 +-- tools/mksurfdata_esmf/src/mksoildepthMod.F90 | 5 +++ tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 | 7 ++-- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 2 +- 9 files changed, 48 insertions(+), 65 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 7edf349dc6..54d76ec205 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -1,6 +1,5 @@ -Updated on, by: -3/16/2022 slevis -3/11/2022 mvertens +Most recent update of README: +4/6/2022 slevis ================ Getting the code @@ -61,20 +60,15 @@ NOTES ------------------------------------------------------------ slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED ------------------------------------------------------------ -1) 1x1_brazil good (min number-of-nodes tested: 4) except: - time = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0 ; - instead of - time = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ; +1) 1x1_brazil good (min number-of-nodes tested: 4) -2) 10x15 mostly good (min number-of-nodes tested: 3) BUT: -- bigger diffs than I would like for NAT_PFT, though .log file shows global PFT - areas same => Gridcell-level diffs due to mapping files? Confirm we have no - discrepancy between .log and .nc files ---> Soil color, ag fire peak month outputs too high in .log - TODO: RUNNING NEW vs OLD with write statements -- Soil txt, peat, fmax, lakes, harvest too low in .log unless raw data changed -- Slope, stddev, soildepth, urban, glaciers not appearing in .log -- VOC em factors from input not appearing in .log +2) 10x15 mostly good (min number-of-nodes tested: 3) +- Soil color & ag fire peak month outputs too high in .log + TODO: frac_o agfire always 1. Change? How? +- Pct lake has changed in the .log; has the raw data changed? +- Soil texture too low in .log; has the raw data changed? +- Slope, stddev, urban not appearing in .log +- REMEMBER TO also compare against existing fsurdat files in /glade/p/cesmdata/cseg/inputdata/lnd/clm2/surfdata_map/release-clm5.0.18 old) ./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc Issues: See newer testing above diff --git a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 index fbd0b3da5d..9aaf181925 100644 --- a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 @@ -29,7 +29,8 @@ module mkdiagnosticsMod contains !=============================================================== - subroutine output_diagnostics_area(mesh_i, mesh_o, mask_i, data_i, data_o, name, percent, ndiag, rc) + subroutine output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o, & + data_i, data_o, name, percent, ndiag, rc) ! Output diagnostics for a field that gives either fraction or percent of grid cell area @@ -37,6 +38,7 @@ subroutine output_diagnostics_area(mesh_i, mesh_o, mask_i, data_i, data_o, name, type(ESMF_Mesh) , intent(in) :: mesh_i type(ESMF_Mesh) , intent(in) :: mesh_o integer , intent(in) :: mask_i(:) + real(r8) , intent(in) :: frac_o(:) ! land fraction output grid real(r8) , intent(in) :: data_i(:) ! data on input grid real(r8) , intent(in) :: data_o(:) ! data on output grid character(len=*) , intent(in) :: name ! name of field @@ -84,6 +86,12 @@ subroutine output_diagnostics_area(mesh_i, mesh_o, mask_i, data_i, data_o, name, write(6,*) 'ns_i = ', ns_i call shr_sys_abort() end if + if (size(frac_o) /= ns_o) then + write(6,*) subname//' ERROR: incorrect size of frac_o' + write(6,*) 'size(frac_o) = ', size(frac_o) + write(6,*) 'ns_o = ', ns_o + call shr_sys_abort() + end if ! Sums on input grid loc_gdata_i = 0. @@ -93,15 +101,17 @@ subroutine output_diagnostics_area(mesh_i, mesh_o, mask_i, data_i, data_o, name, loc_gdata_i = loc_gdata_i + data_i(ni) * area_i(ni) * mask_i(ni) end do call mpi_reduce(loc_gdata_i,gdata_i,1,MPI_REAL8,MPI_SUM,0,mpicom,ier) + call mpi_reduce(loc_garea_i,garea_i,1,MPI_REAL8,MPI_SUM,0,mpicom,ier) ! Sums on output grid loc_gdata_o = 0. loc_garea_o = 0. do no = 1,ns_o loc_garea_o = loc_garea_o + area_o(no) - loc_gdata_o = loc_gdata_o + data_o(no) * area_o(no) + loc_gdata_o = loc_gdata_o + data_o(no) * area_o(no) * frac_o(no) end do call mpi_reduce(loc_gdata_o,gdata_o,1,MPI_REAL8,MPI_SUM,0,mpicom,ier) + call mpi_reduce(loc_garea_o,garea_o,1,MPI_REAL8,MPI_SUM,0,mpicom,ier) ! Correct units if (percent) then diff --git a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 index 198c4f6451..d3bec92b15 100644 --- a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 @@ -18,6 +18,7 @@ module mkglcmecMod use mkutilsMod , only : chkerr use mkutilsMod , only : slightly_below, slightly_above use mkfileMod , only : mkfile_output + use mkdiagnosticsMod , only : output_diagnostics_area implicit none private ! By default make data private @@ -599,38 +600,10 @@ subroutine mkglacier(file_mesh_i, file_data_i, mesh_o, glac_o, rc) end if enddo - ! Compare global areas on input and output grids - ! Some error checking and writing of global values before and after the regrid - ! ! Input grid - ! gglac_i = 0. - ! garea_i = 0. - ! do ni = 1,ns_i - ! garea_i = garea_i + area_i(ni) - ! gglac_i = gglac_i + glac_i(ni)*(area_i(ni)/100.) * mask_i(ni) - ! end do - - ! ! Output grid - ! gglac_o = 0. - ! garea_o = 0. - ! do no = 1,ns_o - ! garea_o = garea_o + area_o(no) - ! gglac_o = gglac_o + glac_o(no)*(area_o(no)/100.) * frac_o(no) - ! end do - - ! ! Diagnostic output - - ! write (ndiag,*) - ! write (ndiag,*) - ! write (ndiag,'(1x,70a1)') ('.',k=1,70) - ! write (ndiag,2001) - ! 2001 format (1x,'surface type input grid area output grid area'/ & - ! 1x,' 10**6 km**2 10**6 km**2 ') - ! write (ndiag,'(1x,70a1)') ('.',k=1,70) - ! write (ndiag,*) - ! write (ndiag,2002) gglac_i*1.e-06,gglac_o*1.e-06 - ! write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 - ! 2002 format (1x,'glaciers ',f14.3,f17.3) - ! 2004 format (1x,'all surface ',f14.3,f17.3) + ! Check global areas + call output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o, & + glac_i, glac_o, "pct glacier", percent=.true., ndiag=ndiag, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Deallocate dynamic memory deallocate (glac_i, frac_o, mask_i) diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index 87b6d65f2a..efe1f725e3 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -16,7 +16,7 @@ module mkharvestMod use mkesmfMod , only : regrid_rawdata, create_routehandle_r8, get_meshareas use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag, mpicom - use mkdiagnosticsMod , only : output_diagnostics_continuous + use mkdiagnosticsMod , only : output_diagnostics_area implicit none private @@ -203,8 +203,8 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, constant, ntime, call pio_syncfile(pioid_o) ! Compare global areas on input and output grids for 1d variables - call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - data1d_i, data1d_o, trim(varname_o), "gC/m2/yr", ndiag, rc=rc) + call output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o, & + data1d_i*0.01_r8, data1d_o*0.01_r8, trim(varname_o), percent=.false., ndiag=ndiag, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return deallocate(data1d_i) diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index e6cf8641fc..2b2a6691c1 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -11,7 +11,7 @@ module mklanwatMod use shr_sys_mod , only : shr_sys_abort use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 - use mkdiagnosticsMod , only : output_diagnostics_continuous + use mkdiagnosticsMod , only : output_diagnostics_continuous, output_diagnostics_area use mkchecksMod , only : min_bad use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag, spval, no_inlandwet @@ -145,8 +145,8 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, fsurdat, enddo ! Check global areas - call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - lake_i, lake_o, "pct lake", "unitless", ndiag, nomask=.true., rc=rc) + call output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o, & + lake_i, lake_o, "pct lake", percent=.true., ndiag=ndiag, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return deallocate (lake_i) @@ -313,8 +313,8 @@ subroutine mkwetlnd(file_mesh_i, file_data_i, mesh_o, swmp_o, rc) enddo ! Check global areas - call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - swmp_i, swmp_o, "pct wetland", "unitless", ndiag, nomask=.true., rc=rc) + call output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o, & + swmp_i, swmp_o, "pct wetland", percent=.true., ndiag=ndiag, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Close the single input data file diff --git a/tools/mksurfdata_esmf/src/mkpeatMod.F90 b/tools/mksurfdata_esmf/src/mkpeatMod.F90 index 87ce2dd6c8..6dad412427 100644 --- a/tools/mksurfdata_esmf/src/mkpeatMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpeatMod.F90 @@ -12,7 +12,7 @@ module mkpeatMod use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 use mkvarctl , only : ndiag, root_task, mpicom, spval use mkchecksMod , only : min_bad, max_bad - use mkdiagnosticsMod , only : output_diagnostics_continuous + use mkdiagnosticsMod , only : output_diagnostics_area use mkutilsMod , only : chkerr use mkfileMod , only : mkfile_output @@ -126,8 +126,8 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) call pio_syncfile(pioid_o) ! Output diagnostic info - call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - peat_i, peat_o, "Peat", "unitless", ndiag, rc) + call output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o, & + peat_i, peat_o, "Peat", percent=.false., ndiag=ndiag, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() ! Close the file diff --git a/tools/mksurfdata_esmf/src/mksoildepthMod.F90 b/tools/mksurfdata_esmf/src/mksoildepthMod.F90 index 7d60c34fe7..e8f09b20aa 100644 --- a/tools/mksurfdata_esmf/src/mksoildepthMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoildepthMod.F90 @@ -11,6 +11,7 @@ module mksoildepthMod use mkpioMod , only : mkpio_get_rawdata use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 + use mkdiagnosticsMod , only : output_diagnostics_area use mkutilsMod , only : chkerr use mkchecksMod , only : min_bad, max_bad use mkfileMod , only : mkfile_output @@ -160,6 +161,10 @@ subroutine mksoildepth(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') call pio_syncfile(pioid_o) + ! Output diagnostic info + call output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o, & + soildepth_i, soildepth_o, "Soildepth", percent=.false., ndiag=ndiag, rc=rc) + ! Close the input file call pio_closefile(pioid_i) call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) diff --git a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 index d1a7fe7f13..291e2e9e08 100644 --- a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 @@ -10,7 +10,7 @@ module mksoilfmaxMod use pio , only : file_desc_t, pio_openfile, pio_closefile, pio_nowrite, pio_syncfile use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_iosystem use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 - use mkdiagnosticsMod , only : output_diagnostics_continuous + use mkdiagnosticsMod , only : output_diagnostics_area use mkvarctl , only : ndiag, root_task, spval use mkutilsMod , only : chkerr use mkfileMod , only : mkfile_output @@ -142,8 +142,9 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) enddo ! Compare global areas on input and output grids - call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - fmax_i, fmax_o, "Maximum Fractional Sataturated output", "unitless", ndiag, rc) + call output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o, & + fmax_i*0.01_r8, fmax_o*0.01_r8, "Max Fractional Sataturated Area", & + percent=.false., ndiag=ndiag, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Write output data diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 6ca1aecfec..04e68c60d0 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -139,7 +139,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc ! Set mapunit values to zero where the input mask is 0 do ni = 1,ns_i - mapunit_i(ni) = mapunit_i(ni) * rmask_i(ni) + mapunit_i(ni) = mapunit_i(ni) * mask_i(ni) end do ! Determine mapunit_value_max (set it as a module variable so that it can be From f855effd4fa735fb43f25995886b7c004c2fca1d Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 7 Apr 2022 20:49:57 -0600 Subject: [PATCH 126/614] turned on other fields --- tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 | 98 +++++++++++++++---- tools/mksurfdata_esmf/src/mksurfdata.F90 | 55 +++++------ 2 files changed, 101 insertions(+), 52 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 index 51a544d828..72dd0dc0a3 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 @@ -61,6 +61,7 @@ subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioi integer :: ns_i, ns_o integer :: k,l,m,n integer :: nlay ! number of soil layers + integer :: n_scid integer , allocatable :: mask_i(:) real(r4), pointer :: dataptr(:) integer :: mapunit ! temporary igbp soil mapunit @@ -213,15 +214,12 @@ subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioi rcode = pio_inq_dimid (pioid_i, 'MapUnit', dimid) rcode = pio_inq_dimlen (pioid_i, dimid, n_mapunits) - write(6,*)'DEBUG: n_mapunits = ',n_mapunits rcode = pio_inq_dimid (pioid_i, 'soil_layer', dimid) rcode = pio_inq_dimlen (pioid_i, dimid, nlay) - write(6,*)'DEBUG: nlay = ',nlay rcode = pio_inq_dimid (pioid_i, 'SCID', dimid) - rcode = pio_inq_dimlen (pioid_i, dimid, SCID) - write(6,*)'DEBUG: SCID= ',SCID + rcode = pio_inq_dimlen (pioid_i, dimid, n_scid) ! Read In MapUnits from the input file allocate(MapUnits(n_mapunits), stat=ier) @@ -236,9 +234,9 @@ subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioi mapunit_lookup(MapUnits(n)) = n end do - allocate(sand_i(nlay,SCID,n_mapunits)) + allocate(sand_i(nlay,n_scid,n_mapunits)) if (ier/=0) call shr_sys_abort() - allocate(clay_i(nlay,SCID,n_mapunits)) + allocate(clay_i(nlay,n_scid,n_mapunits)) if (ier/=0) call shr_sys_abort() ! Get dimensions from input file and allocate memory for sand_i and clay_i @@ -248,17 +246,18 @@ subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioi rcode = pio_get_var(pioid_i, pio_varid_sand, sand_i) rcode = pio_get_var(pioid_i, pio_varid_clay, clay_i) - if (root_task) then - do i = 1,n_mapunits - do j = 1,SCID - do k = 1,nlay - write(6,'(a,4(i8,2x))')'DEBUG: lev,scid,mapunit,sand_i= ',k,j,i,sand_i(k,j,i) - end do - end do - end do - end if + ! if (root_task) then + ! do i = 1,n_mapunits + ! do j = 1,SCID + ! do k = 1,nlay + ! write(6,'(a,4(i8,2x))')'DEBUG: lev,scid,mapunit,sand_i= ',k,j,i,sand_i(k,j,i) + ! end do + ! end do + ! end do + ! end if do no = 1,ns_o + if (mapunit_o(no) > 0) then ! valid value is obtained if (mapunit_o(no) > mapunit_value_max) then @@ -266,29 +265,86 @@ subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioi ! call shr_sys_abort("mapunit_o is out of bounds") end if lookup_index = mapunit_lookup(mapunit_o(no)) - do l = 1, nlay + + !--------------------- + ! Determine sand_o + !--------------------- + + ! Determine the top soil layer sand_o + sand_o(no,1) = float(sand_i(1,1,lookup_index)) + + ! If its less than 0 search within the SCID array for the first index + ! that gives a pct sand that is greater than or equal to 0 + if (sand_o(no,1) < 0.) then + do l = 2,n_scid + write(6,*)'DEBUG1: lookup_index,l,sand_i(1,l,lookup_index= ',& + lookup_index,l,sand_i(1,l,lookup_index) + if (float(sand_i(1,l,lookup_index)) >= 0.) then + sand_o(no,1) = float(sand_i(1,l,lookup_index)) + exit + end if + end do + end if + if (sand_o(no,1) < 0.) then + write(6,*)'ERROR: at no, lookup_index = ',no,lookup_index + call shr_sys_abort('could not find a value >= 0 for sand_i') + end if + + ! Now determine the other soil layers sand_o + do l = 2,nlay sand_o(no,l) = float(sand_i(l,1,lookup_index)) - clay_o(no,l) = float(clay_i(l,1,lookup_index)) if (sand_o(no,l) < 0. .and. l > 1) then sand_o(no,l) = sand_o(no,l-1) end if + end do + + !--------------------- + ! Determine clay_o + !--------------------- + + ! Determine the top soil layer clay_o + clay_o(no,1) = float(clay_i(1,1,lookup_index)) + + ! If its less than 0 search within the SCID array for the first index + ! that gives a pct clay that is greater than or equal to 0 + if (clay_o(no,1) < 0.) then + do l = 2,n_scid + if (float(clay_i(1,l,lookup_index)) >= 0.) then + clay_o(no,1) = float(clay_i(1,l,lookup_index)) + exit + end if + end do + end if + if (clay_o(no,1) < 0.) then + write(6,*)'ERROR: at no, lookup_index = ',no,lookup_index + call shr_sys_abort('could not find a value >= 0 for sand_i') + end if + + ! Now determine the other soil layers clay_o + do l = 2,nlay + clay_o(no,l) = float(clay_i(l,1,lookup_index)) if (clay_o(no,l) < 0. .and. l > 1) then clay_o(no,l) = clay_o(no,l-1) end if end do - write(6,'(a,3(i8,2x),3(f14.5,2x))') & - 'DEBUG: no,mapunit_o(no),lookup_index,pctlnd_pft_o(no),sand_o(no,1),clay_o(no,1) = ',& - no,mapunit_o(no),lookup_index,pctlnd_pft_o(no),sand_o(no,1),clay_o(no,1) + + ! write(6,'(a,3(i8,2x),3(f14.5,2x))') & + ! 'DEBUG: no,mapunit_o(no),lookup_index,pctlnd_pft_o(no),sand_o(no,1),clay_o(no,1) = ',& + ! no,mapunit_o(no),lookup_index,pctlnd_pft_o(no),sand_o(no,1),clay_o(no,1) else + + write(6,*)'DEBUG: i am here for no = ',no ! use loam do l = 1, nlay sand_o(no,l) = 43. clay_o(no,l) = 18. end do + end if + end do - ! Adjust pct sand and pct clay to be nearest integers and to be loam if pctlnd_pft is < 1.e-6 + ! Adjust sand and clay be loam if pctlnd_pft is < 1.e-6 ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero ! (not a very small number such as 1e-16) where it really should be zero do no = 1,ns_o diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index ff4385ef25..3dc5f3902a 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -404,36 +404,14 @@ program mksurfdata call pio_syncfile(pioid) end if - ! DEBUG - if (fsurdat /= ' ') then - ! --- for a 3 second input mapunit --- - ! mksrf_fsoitex_mapunit = & - ! '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v5_grid.nc' - - ! --- for a 5min input mapunit--- - mksrf_fsoitex_mesh = & - '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' - mksrf_fsoitex_mapunit = & - '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/soiltex_mapunits_4320x2160_c220329.nc' - mksrf_fsoitex_lookup = & - '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v5_lookup.nc' - - call mksoiltexnew( mksrf_fsoitex_mesh, file_mapunit_i=mksrf_fsoitex_mapunit, file_lookup_i=mksrf_fsoitex_lookup, & - mesh_o=mesh_model, pioid_o=pioid, pctlnd_pft_o=pctlnd_pft, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') - end if - call pio_closefile(pioid) - call shr_sys_abort('stopping just for soiltex output') - ! DEBUG - ! ----------------------------------- ! Make LAI and SAI from 1/2 degree data and write to surface dataset ! Write to netcdf file is done inside mklai routine ! ----------------------------------- - ! if (fsurdat /= ' ') then - ! call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') - ! end if + if (fsurdat /= ' ') then + call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') + end if ! ----------------------------------- ! Make constant harvesting data at model resolution @@ -480,11 +458,26 @@ program mksurfdata ! ----------------------------------- ! Make soil texture [pctsand, pctclay] ! ----------------------------------- - ! if (fsurdat /= ' ') then - ! ! mapunits, PCT_SAND and PCT_CLAY are written out in the subroutine - ! call mksoiltex( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pioid, pctlnd_pft, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') - ! end if + if (fsurdat /= ' ') then + ! mapunits, PCT_SAND and PCT_CLAY are written out in the subroutine + ! call mksoiltex( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pioid, pctlnd_pft, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') + + ! --- for a 3 second input mapunit --- + ! mksrf_fsoitex_mapunit = & + ! '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v5_grid.nc' + ! --- for a 5min input mapunit--- + mksrf_fsoitex_mesh = & + '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' + mksrf_fsoitex_mapunit = & + '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/soiltex_mapunits_4320x2160_c220329.nc' + mksrf_fsoitex_lookup = & + '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v5_lookup.nc' + + call mksoiltexnew( mksrf_fsoitex_mesh, file_mapunit_i=mksrf_fsoitex_mapunit, file_lookup_i=mksrf_fsoitex_lookup, & + mesh_o=mesh_model, pioid_o=pioid, pctlnd_pft_o=pctlnd_pft, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') + end if ! ----------------------------------- ! Make soil color classes [soicol] [fsoicol] From c5e496b85f176472b2e105d3ecc682e5d97ed8f5 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 7 Apr 2022 20:59:09 -0600 Subject: [PATCH 127/614] revert any changes to original mksoiltexMod.F90 --- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 4f2e190a6d..6ca1aecfec 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -195,7 +195,6 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc ! Get dimensions from input file and allocate memory for sand_i and clay_i rcode = pio_inq_dimid (pioid_i, 'number_of_layers', dimid) rcode = pio_inq_dimlen (pioid_i, dimid, nlay) - allocate(sand_i(mapunit_value_max,nlay), stat=ier) if (ier/=0) call shr_sys_abort() allocate(clay_i(mapunit_value_max,nlay), stat=ier) From 191803ffc92f2174094d3a46222b81a624c29b2e Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 7 Apr 2022 22:22:46 -0600 Subject: [PATCH 128/614] fixed order in calls of mksurfdata --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index f0742b6ee8..da78f8b947 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -355,6 +355,15 @@ program mksurfdata call pio_syncfile(pioid) end if + ! ----------------------------------- + ! Make LAI and SAI from 1/2 degree data and write to surface dataset + ! Write to netcdf file is done inside mklai routine + ! ----------------------------------- + if (fsurdat /= ' ') then + call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') + end if + ! ----------------------------------- ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] ! Make landfrac_pft and pftdata_mask @@ -397,15 +406,6 @@ program mksurfdata call pio_syncfile(pioid) end if - ! ----------------------------------- - ! Make LAI and SAI from 1/2 degree data and write to surface dataset - ! Write to netcdf file is done inside mklai routine - ! ----------------------------------- - if (fsurdat /= ' ') then - call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') - end if - ! ----------------------------------- ! Make constant harvesting data at model resolution ! ----------------------------------- From d7e2da65acddf91ef72bc2e56992cab0e7af154a Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 13 Apr 2022 10:46:15 -0600 Subject: [PATCH 129/614] %sand and %clay are now being computed without any zero values --- tools/mksurfdata_esmf/README | 4 +- tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 | 156 +++++++----------- tools/mksurfdata_esmf/src/mksurfdata.F90 | 103 ++++++------ 3 files changed, 114 insertions(+), 149 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 54d76ec205..f6d2f9a81c 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -19,8 +19,8 @@ building the executable > rm -rf bld # (or the contents of /bld) before rerunning CC=... > mkdir ./bld > cd bld -> module load intel # I found I need the latest version of intel -> module load python # in case need latest version of python +> module load intel/2021.2 # I found I need the latest version of intel +> module load python # in case need latest version of python > module load cmake > bash > CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src/ diff --git a/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 index 72dd0dc0a3..f44cbb181f 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 @@ -60,33 +60,28 @@ subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioi integer :: ni,no integer :: ns_i, ns_o integer :: k,l,m,n - integer :: nlay ! number of soil layers + integer :: nlay ! number of soil layers integer :: n_scid integer , allocatable :: mask_i(:) real(r4), pointer :: dataptr(:) - integer :: mapunit ! temporary igbp soil mapunit - ! - integer, allocatable :: sand_i(:,:,:) ! input grid: percent sand - integer, allocatable :: clay_i(:,:,:) ! input grid: percent clay - real(r4), allocatable :: sand_o(:,:) ! % sand (output grid) - real(r4), allocatable :: clay_o(:,:) ! % clay (output grid) + integer :: mapunit ! temporary igbp soil mapunit + integer, allocatable :: sand_i(:,:,:) ! input grid: percent sand + integer, allocatable :: clay_i(:,:,:) ! input grid: percent clay + real(r4), allocatable :: sand_o(:,:) ! % sand (output grid) + real(r4), allocatable :: clay_o(:,:) ! % clay (output grid) integer :: n_mapunits integer :: lookup_index integer :: SCID - real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits - integer , allocatable :: mapunit_o(:) + real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits + integer , allocatable :: mapunit_o(:) ! output grid: igbp soil mapunits integer , allocatable :: MapUnits(:) integer , allocatable :: mapunit_lookup(:) type(var_desc_t) :: pio_varid_sand type(var_desc_t) :: pio_varid_clay - integer :: starts(3) ! starting indices for reading lookup table - integer :: counts(3) ! dimension counts for reading lookup table - ! + integer :: starts(3) ! starting indices for reading lookup table + integer :: counts(3) ! dimension counts for reading lookup table integer :: srcTermProcessing_Value = 0 - integer :: rcode, ier ! error status - ! DEBUG - integer :: i,j - ! DEBUG + integer :: rcode, ier ! error status character(len=*), parameter :: subname = 'mksoiltexnew' !----------------------------------------------------------------------- @@ -134,17 +129,16 @@ subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioi call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Opne input mapunit data file + ! Read in mapunit data if (root_task) write(ndiag,*)"Reading in mapunit data in "//trim(subname) call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_mapunit_i)) rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_mapunit_i), pio_nowrite) - - ! Read in mapunit data allocate(mapunit_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid_i, 'MU', mesh_i, mapunit_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + call pio_closefile(pioid_i) ! Set mesh mask to zero where the mapunit values are 0 if (root_task) write(ndiag,*)"Setting mask in mesh where mapunit data is 0 "//trim(subname) @@ -165,22 +159,22 @@ subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioi if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle - if (root_task) write(ndiag,*)"DEBUG: before route handle creation "//trim(subname) + if (root_task) write(ndiag,*)" before route handle creation "//trim(subname) call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - if (root_task) write(ndiag,*)"DEBUG: after route handle creation "//trim(subname) + if (root_task) write(ndiag,*)" after route handle creation "//trim(subname) ! Create a dynamic mask object ! The dynamic mask object further holds a pointer to the routine that will be called in order to ! handle dynamically masked elements - in this case its DynMaskProc (see below) - if (root_task) write(ndiag,*)"DEBUG: before call to dynamic mas set creation "//trim(subname) + if (root_task) write(ndiag,*)" before call to dynamic mask set creation "//trim(subname) call ESMF_DynamicMaskSetR4R8R4(dynamicMask, dynamicMaskRoutine=get_dominant_mapunit, & handleAllElements=.true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag,*)"DEBUG: after call to dynamic mas set creation "//trim(subname) + if (root_task) write(ndiag,*)" after call to dynamic mask set creation "//trim(subname) ! Determine values in field_i call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) @@ -204,7 +198,18 @@ subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioi mapunit_o(no) = int(dataptr(no)) end do - call pio_closefile(pioid_i) + do no = 1,ns_o + if (mapunit_o(no) > mapunit_value_max) then + write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) + ! call shr_sys_abort("mapunit_o is out of bounds") + end if + end do + + ! Write out mapunit_o + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out mapunits " + call mkfile_output(pioid_o, mesh_o, 'mapunits', mapunit_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') + call pio_syncfile(pioid_o) !--------------------------------- ! Determine %sand and %clay on output grid - using above mapunits @@ -246,39 +251,26 @@ subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioi rcode = pio_get_var(pioid_i, pio_varid_sand, sand_i) rcode = pio_get_var(pioid_i, pio_varid_clay, clay_i) - ! if (root_task) then - ! do i = 1,n_mapunits - ! do j = 1,SCID - ! do k = 1,nlay - ! write(6,'(a,4(i8,2x))')'DEBUG: lev,scid,mapunit,sand_i= ',k,j,i,sand_i(k,j,i) - ! end do - ! end do - ! end do - ! end if - do no = 1,ns_o - if (mapunit_o(no) > 0) then - ! valid value is obtained - if (mapunit_o(no) > mapunit_value_max) then - write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) - ! call shr_sys_abort("mapunit_o is out of bounds") - end if - lookup_index = mapunit_lookup(mapunit_o(no)) + if (pctlnd_pft_o(no) < 1.e-6_r8 .or. mapunit_o(no) == 0) then - !--------------------- - ! Determine sand_o - !--------------------- + ! Adjust sand and clay be loam if pctlnd_pft is < 1.e-6 or mapunit is 0 + sand_o(no,:) = 43._r4 + clay_o(no,:) = 18._r4 - ! Determine the top soil layer sand_o - sand_o(no,1) = float(sand_i(1,1,lookup_index)) + else + ! Determine lookup_index + lookup_index = mapunit_lookup(mapunit_o(no)) + + ! Determine the top soil layer sand_o and clay_o ! If its less than 0 search within the SCID array for the first index ! that gives a pct sand that is greater than or equal to 0 + ! Then determine the other soil layers sand_o + sand_o(no,1) = float(sand_i(1,1,lookup_index)) if (sand_o(no,1) < 0.) then do l = 2,n_scid - write(6,*)'DEBUG1: lookup_index,l,sand_i(1,l,lookup_index= ',& - lookup_index,l,sand_i(1,l,lookup_index) if (float(sand_i(1,l,lookup_index)) >= 0.) then sand_o(no,1) = float(sand_i(1,l,lookup_index)) exit @@ -286,11 +278,14 @@ subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioi end do end if if (sand_o(no,1) < 0.) then - write(6,*)'ERROR: at no, lookup_index = ',no,lookup_index - call shr_sys_abort('could not find a value >= 0 for sand_i') + if (int(sand_o(no,1)) == -4) then + write(6,'(a,i8)')'WARNING: changing sand_o from -4 to 99% at no = ',no + sand_o(no,:) = 99._r4 + else + write(6,'(a,i8,a,i8)')'WARNING: changing sand_o from ',int(sand_o(no,1)),' to 43 at no = ',no + sand_o(no,:) = 43._r4 + end if end if - - ! Now determine the other soil layers sand_o do l = 2,nlay sand_o(no,l) = float(sand_i(l,1,lookup_index)) if (sand_o(no,l) < 0. .and. l > 1) then @@ -298,15 +293,10 @@ subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioi end if end do - !--------------------- - ! Determine clay_o - !--------------------- - - ! Determine the top soil layer clay_o - clay_o(no,1) = float(clay_i(1,1,lookup_index)) - ! If its less than 0 search within the SCID array for the first index ! that gives a pct clay that is greater than or equal to 0 + ! Now determine the other soil layers clay_o + clay_o(no,1) = float(clay_i(1,1,lookup_index)) if (clay_o(no,1) < 0.) then do l = 2,n_scid if (float(clay_i(1,l,lookup_index)) >= 0.) then @@ -315,12 +305,19 @@ subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioi end if end do end if + if (clay_o(no,1) < 0.) then + if (int(clay_o(no,1)) == -4) then + write(6,'(a,i8)')'WARNING: changing clay_o from -4 to 1% at no = ',no + clay_o(no,:) = 1._r4 + else + write(6,'(a,i8,a,i8)')'WARNING: changing clay_o from ',int(clay_o(no,1)),' to 18 at no = ',no + clay_o(no,:) = 18._r4 + end if + end if if (clay_o(no,1) < 0.) then write(6,*)'ERROR: at no, lookup_index = ',no,lookup_index - call shr_sys_abort('could not find a value >= 0 for sand_i') + call shr_sys_abort('could not find a value >= 0 for clay_i') end if - - ! Now determine the other soil layers clay_o do l = 2,nlay clay_o(no,l) = float(clay_i(l,1,lookup_index)) if (clay_o(no,l) < 0. .and. l > 1) then @@ -328,32 +325,10 @@ subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioi end if end do - ! write(6,'(a,3(i8,2x),3(f14.5,2x))') & - ! 'DEBUG: no,mapunit_o(no),lookup_index,pctlnd_pft_o(no),sand_o(no,1),clay_o(no,1) = ',& - ! no,mapunit_o(no),lookup_index,pctlnd_pft_o(no),sand_o(no,1),clay_o(no,1) - else - - write(6,*)'DEBUG: i am here for no = ',no - ! use loam - do l = 1, nlay - sand_o(no,l) = 43. - clay_o(no,l) = 18. - end do - end if end do - ! Adjust sand and clay be loam if pctlnd_pft is < 1.e-6 - ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero - ! (not a very small number such as 1e-16) where it really should be zero - do no = 1,ns_o - if (pctlnd_pft_o(no) < 1.e-6_r8) then - sand_o(no,:) = 43._r4 - clay_o(no,:) = 18._r4 - end if - end do - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') @@ -361,20 +336,7 @@ subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioi if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call pio_syncfile(pioid_o) - - ! Write out fields - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out mapunits " - call mkfile_output(pioid_o, mesh_o, 'mapunits', mapunit_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" - call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" - call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') call pio_syncfile(pioid_o) ! Release memory diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index da78f8b947..a6b0e1e904 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -355,14 +355,14 @@ program mksurfdata call pio_syncfile(pioid) end if - ! ----------------------------------- - ! Make LAI and SAI from 1/2 degree data and write to surface dataset - ! Write to netcdf file is done inside mklai routine - ! ----------------------------------- - if (fsurdat /= ' ') then - call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') - end if + ! ! ----------------------------------- + ! ! Make LAI and SAI from 1/2 degree data and write to surface dataset + ! ! Write to netcdf file is done inside mklai routine + ! ! ----------------------------------- + ! if (fsurdat /= ' ') then + ! call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') + ! end if ! ----------------------------------- ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] @@ -406,47 +406,47 @@ program mksurfdata call pio_syncfile(pioid) end if - ! ----------------------------------- - ! Make constant harvesting data at model resolution - ! ----------------------------------- - ! Note that this call must come after call to mkpftInit - since num_cft is set there - ! Output data is written in mkharvest - if (fsurdat /= ' ') then - call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, pioid, constant=.true., rc=rc ) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') - end if - - ! ----------------------------------- - ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] - ! ----------------------------------- - ! LAKEDEPTH is written out in the subroutine - ! Need to keep pctlak and pctwet external for use below - allocate ( pctlak(lsize_o)) ; pctlak(:) = spval - allocate ( pctlak_max(lsize_o)) ; pctlak_max(:) = spval - call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, pctlak, pioid, fsurdat, rc=rc, do_depth=.true.) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') - - allocate ( pctwet(lsize_o)) ; pctwet(:) = spval - allocate ( pctwet_orig(lsize_o)) ; pctwet_orig(:) = spval - call mkwetlnd(mksrf_fwetlnd_mesh, mksrf_fwetlnd, mesh_model, pctwet, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkwetlnd') - - ! ----------------------------------- - ! Make glacier fraction [pctgla] from [fglacier] dataset - ! ----------------------------------- - allocate (pctgla(lsize_o)) ; pctgla(:) = spval - allocate (pctgla_orig(lsize_o)) ; pctgla_orig(:) = spval - call mkglacier (mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, glac_o=pctgla, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacier') - - ! ----------------------------------- - ! Make glacier region ID [glacier_region] from [fglacierregion] dataset - ! ----------------------------------- - if (fsurdat /= ' ') then - ! GLACIER_REGION is written out in the subroutine - call mkglacierregion(mksrf_fglacierregion_mesh, mksrf_fglacierregion, mesh_model, pioid, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacierregion') - end if + ! ! ----------------------------------- + ! ! Make constant harvesting data at model resolution + ! ! ----------------------------------- + ! ! Note that this call must come after call to mkpftInit - since num_cft is set there + ! ! Output data is written in mkharvest + ! if (fsurdat /= ' ') then + ! call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, pioid, constant=.true., rc=rc ) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') + ! end if + + ! ! ----------------------------------- + ! ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] + ! ! ----------------------------------- + ! ! LAKEDEPTH is written out in the subroutine + ! ! Need to keep pctlak and pctwet external for use below + ! allocate ( pctlak(lsize_o)) ; pctlak(:) = spval + ! allocate ( pctlak_max(lsize_o)) ; pctlak_max(:) = spval + ! call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, pctlak, pioid, fsurdat, rc=rc, do_depth=.true.) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') + + ! allocate ( pctwet(lsize_o)) ; pctwet(:) = spval + ! allocate ( pctwet_orig(lsize_o)) ; pctwet_orig(:) = spval + ! call mkwetlnd(mksrf_fwetlnd_mesh, mksrf_fwetlnd, mesh_model, pctwet, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkwetlnd') + + ! ! ----------------------------------- + ! ! Make glacier fraction [pctgla] from [fglacier] dataset + ! ! ----------------------------------- + ! allocate (pctgla(lsize_o)) ; pctgla(:) = spval + ! allocate (pctgla_orig(lsize_o)) ; pctgla_orig(:) = spval + ! call mkglacier (mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, glac_o=pctgla, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacier') + + ! ! ----------------------------------- + ! ! Make glacier region ID [glacier_region] from [fglacierregion] dataset + ! ! ----------------------------------- + ! if (fsurdat /= ' ') then + ! ! GLACIER_REGION is written out in the subroutine + ! call mkglacierregion(mksrf_fglacierregion_mesh, mksrf_fglacierregion, mesh_model, pioid, rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacierregion') + ! end if ! ----------------------------------- ! Make soil texture [pctsand, pctclay] @@ -465,11 +465,14 @@ program mksurfdata mksrf_fsoitex_mapunit = & '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/soiltex_mapunits_4320x2160_c220329.nc' mksrf_fsoitex_lookup = & - '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v5_lookup.nc' + '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v1_lookup2.nc' call mksoiltexnew( mksrf_fsoitex_mesh, file_mapunit_i=mksrf_fsoitex_mapunit, file_lookup_i=mksrf_fsoitex_lookup, & mesh_o=mesh_model, pioid_o=pioid, pctlnd_pft_o=pctlnd_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') + + call pio_closefile(pioid) + call shr_sys_abort("stopping for debugging") end if ! ----------------------------------- From 057714ff590d495bc0931ab1c424dc39a739efb7 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 13 Apr 2022 11:33:38 -0600 Subject: [PATCH 130/614] mksurfdata now generates the entire surface dataset --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 101 +++++++++++------------ 1 file changed, 49 insertions(+), 52 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index a6b0e1e904..4dd8bd9f56 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -355,14 +355,14 @@ program mksurfdata call pio_syncfile(pioid) end if - ! ! ----------------------------------- - ! ! Make LAI and SAI from 1/2 degree data and write to surface dataset - ! ! Write to netcdf file is done inside mklai routine - ! ! ----------------------------------- - ! if (fsurdat /= ' ') then - ! call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') - ! end if + ! ----------------------------------- + ! Make LAI and SAI from 1/2 degree data and write to surface dataset + ! Write to netcdf file is done inside mklai routine + ! ----------------------------------- + if (fsurdat /= ' ') then + call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') + end if ! ----------------------------------- ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] @@ -406,47 +406,47 @@ program mksurfdata call pio_syncfile(pioid) end if - ! ! ----------------------------------- - ! ! Make constant harvesting data at model resolution - ! ! ----------------------------------- - ! ! Note that this call must come after call to mkpftInit - since num_cft is set there - ! ! Output data is written in mkharvest - ! if (fsurdat /= ' ') then - ! call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, pioid, constant=.true., rc=rc ) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') - ! end if - - ! ! ----------------------------------- - ! ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] - ! ! ----------------------------------- - ! ! LAKEDEPTH is written out in the subroutine - ! ! Need to keep pctlak and pctwet external for use below - ! allocate ( pctlak(lsize_o)) ; pctlak(:) = spval - ! allocate ( pctlak_max(lsize_o)) ; pctlak_max(:) = spval - ! call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, pctlak, pioid, fsurdat, rc=rc, do_depth=.true.) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') - - ! allocate ( pctwet(lsize_o)) ; pctwet(:) = spval - ! allocate ( pctwet_orig(lsize_o)) ; pctwet_orig(:) = spval - ! call mkwetlnd(mksrf_fwetlnd_mesh, mksrf_fwetlnd, mesh_model, pctwet, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkwetlnd') - - ! ! ----------------------------------- - ! ! Make glacier fraction [pctgla] from [fglacier] dataset - ! ! ----------------------------------- - ! allocate (pctgla(lsize_o)) ; pctgla(:) = spval - ! allocate (pctgla_orig(lsize_o)) ; pctgla_orig(:) = spval - ! call mkglacier (mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, glac_o=pctgla, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacier') - - ! ! ----------------------------------- - ! ! Make glacier region ID [glacier_region] from [fglacierregion] dataset - ! ! ----------------------------------- - ! if (fsurdat /= ' ') then - ! ! GLACIER_REGION is written out in the subroutine - ! call mkglacierregion(mksrf_fglacierregion_mesh, mksrf_fglacierregion, mesh_model, pioid, rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacierregion') - ! end if + ! ----------------------------------- + ! Make constant harvesting data at model resolution + ! ----------------------------------- + ! Note that this call must come after call to mkpftInit - since num_cft is set there + ! Output data is written in mkharvest + if (fsurdat /= ' ') then + call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, pioid, constant=.true., rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') + end if + + ! ----------------------------------- + ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] + ! ----------------------------------- + ! LAKEDEPTH is written out in the subroutine + ! Need to keep pctlak and pctwet external for use below + allocate ( pctlak(lsize_o)) ; pctlak(:) = spval + allocate ( pctlak_max(lsize_o)) ; pctlak_max(:) = spval + call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, pctlak, pioid, fsurdat, rc=rc, do_depth=.true.) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') + + allocate ( pctwet(lsize_o)) ; pctwet(:) = spval + allocate ( pctwet_orig(lsize_o)) ; pctwet_orig(:) = spval + call mkwetlnd(mksrf_fwetlnd_mesh, mksrf_fwetlnd, mesh_model, pctwet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkwetlnd') + + ! ----------------------------------- + ! Make glacier fraction [pctgla] from [fglacier] dataset + ! ----------------------------------- + allocate (pctgla(lsize_o)) ; pctgla(:) = spval + allocate (pctgla_orig(lsize_o)) ; pctgla_orig(:) = spval + call mkglacier (mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, glac_o=pctgla, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacier') + + ! ----------------------------------- + ! Make glacier region ID [glacier_region] from [fglacierregion] dataset + ! ----------------------------------- + if (fsurdat /= ' ') then + ! GLACIER_REGION is written out in the subroutine + call mkglacierregion(mksrf_fglacierregion_mesh, mksrf_fglacierregion, mesh_model, pioid, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacierregion') + end if ! ----------------------------------- ! Make soil texture [pctsand, pctclay] @@ -470,9 +470,6 @@ program mksurfdata call mksoiltexnew( mksrf_fsoitex_mesh, file_mapunit_i=mksrf_fsoitex_mapunit, file_lookup_i=mksrf_fsoitex_lookup, & mesh_o=mesh_model, pioid_o=pioid, pctlnd_pft_o=pctlnd_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') - - call pio_closefile(pioid) - call shr_sys_abort("stopping for debugging") end if ! ----------------------------------- From 0c0dfee3052f1b0c3ea5830cfdcce06e973de485 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 13 Apr 2022 19:21:37 -0600 Subject: [PATCH 131/614] Updates to the diagnostics written to the .log file --- tools/mksurfdata_esmf/README | 37 ++++++------ tools/mksurfdata_esmf/src/mkVICparamsMod.F90 | 16 +++--- .../mksurfdata_esmf/src/mkdiagnosticsMod.F90 | 56 ++++++++++++------- tools/mksurfdata_esmf/src/mkgdpMod.F90 | 4 +- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 5 +- tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 | 3 - tools/mksurfdata_esmf/src/mksurfdata.F90 | 2 +- tools/mksurfdata_esmf/src/mktopostatsMod.F90 | 30 ++++------ tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 15 ++--- 9 files changed, 89 insertions(+), 79 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 54d76ec205..0f1162d8a5 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -60,18 +60,15 @@ NOTES ------------------------------------------------------------ slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED ------------------------------------------------------------ -1) 1x1_brazil good (min number-of-nodes tested: 4) - -2) 10x15 mostly good (min number-of-nodes tested: 3) -- Soil color & ag fire peak month outputs too high in .log - TODO: frac_o agfire always 1. Change? How? -- Pct lake has changed in the .log; has the raw data changed? -- Soil texture too low in .log; has the raw data changed? -- Slope, stddev, urban not appearing in .log -- REMEMBER TO also compare against existing fsurdat files in /glade/p/cesmdata/cseg/inputdata/lnd/clm2/surfdata_map/release-clm5.0.18 - -old) ./gen_mksurfdata_namelist.py --start-year 2000 --end-year 2000 --res 1.9x2.5 --vic --glc -Issues: See newer testing above +REMEMBER TO compare against existing fsurdat files in +/glade/p/cesmdata/cseg/inputdata/lnd/clm2/surfdata_map/release-clm5.0.18 +0) TODO: Test --no_inlandwet = .false. +1) OK: 1x1_brazil min number-of-nodes tested: 4 +2) OK: 10x15 min number-of-nodes tested: 3 +3) Soil color & texture and ag fire peak month outputs too high in .log + TODO: Change frac_o from always 1. +4) Pct lake has chged in the .log bc the old diagnostic omitted mask_i frac_o +5) Slope, stddev have chged in the .log bc the old diag. used frac_o ------------------------------------------------------ NOT ALL FILES HAVE BEEN TRANSLATED to cdf5 : check last millenium @@ -79,11 +76,13 @@ NOT ALL FILES HAVE BEEN TRANSLATED to cdf5 : check last millenium > nccopy -k cdf5 oldfile newfile -------------------------------------------------------- -Override options removed: +Override options removed that need to be placed in fsurdat_modifier +and/or subset_data: -------------------------------------------------------- --- all_veg = .true. handled by fsurdat_modifier zero_nonveg = .true. --- all_urban = .true. handle w fsurdat_modifier new option --- no_inlandwet = .false. same --- soil_... --- pft_... - +--soil_clay --soil_sand for setting to these values everywhere +--all_urban = .true. +Normalize so that sum(urban_classes_o(n,:)) = 100 for all n, even for grid +cells where pcturb_o(n) = 0 (in the case where pcturb_o(n) = 0, come up with an +arbitrary assignment of urban into the different classes). +See comments in the normalize_urbn_by_tot subroutine for how urban_classes_o is +determined when the total % urban is 0, according to the input data. diff --git a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 index 62f7b68d64..7742eb282a 100644 --- a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 @@ -152,8 +152,8 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) end if ! Calculate global diagnostics for binfl - call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - data_i, binfl_o, "VIC b parameter", "unitless", ndiag, rc=rc) + call output_diagnostics_continuous(mesh_i, mesh_o, data_i, binfl_o, & + "VIC b parameter", "unitless", ndiag=ndiag, rc=rc, mask_i=mask_i, frac_o=frac_o) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! ----------------------------------------------------------------- @@ -178,8 +178,8 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) end if ! Calculate global diagnostics for Ws - call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - data_i, ws_o, "VIC Ws parameter", "unitless", ndiag, rc) + call output_diagnostics_continuous(mesh_i, mesh_o, data_i, ws_o, & + "VIC Ws parameter", "unitless", ndiag=ndiag, rc=rc, mask_i=mask_i, frac_o=frac_o) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! ----------------------------------------------------------------- @@ -204,8 +204,8 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) end if ! Calculate global diagnostics for Dsmax - call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - data_i, dsmax_o, "VIC Dsmax parameter", "mm/day", ndiag, rc) + call output_diagnostics_continuous(mesh_i, mesh_o, data_i, dsmax_o, & + "VIC Dsmax parameter", "mm/day", ndiag=ndiag, rc=rc, mask_i=mask_i, frac_o=frac_o) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! ----------------------------------------------------------------- @@ -230,8 +230,8 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) end if ! Calculate global diagnostics for Ws - call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - data_i, ds_o, "VIC Ds parameter", "unitless", ndiag, rc) + call output_diagnostics_continuous(mesh_i, mesh_o, data_i, ds_o, & + "VIC Ds parameter", "unitless", ndiag=ndiag, rc=rc, mask_i=mask_i, frac_o=frac_o) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! ----------------------------------------------------------------- diff --git a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 index 9aaf181925..8b8730f83b 100644 --- a/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdiagnosticsMod.F90 @@ -138,8 +138,8 @@ subroutine output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o, & end subroutine output_diagnostics_area !=============================================================== - subroutine output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - data_i, data_o, name, units, ndiag, rc, nomask) + subroutine output_diagnostics_continuous(mesh_i, mesh_o, data_i, data_o, & + name, units, ndiag, rc, mask_i, frac_o, nomask) ! Output diagnostics for a continuous field (but not area, for ! which there is a different routine) @@ -147,14 +147,14 @@ subroutine output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & ! input/output variables type(ESMF_Mesh) , intent(in) :: mesh_i type(ESMF_Mesh) , intent(in) :: mesh_o - integer , intent(in) :: mask_i(:) - real(r8) , intent(in) :: frac_o(:) real(r8) , intent(in) :: data_i(:) ! data on input grid real(r8) , intent(in) :: data_o(:) ! data on output grid character(len=*) , intent(in) :: name ! name of field character(len=*) , intent(in) :: units ! units of field integer , intent(in) :: ndiag logical, optional, intent(in) :: nomask + integer, optional, intent(in) :: mask_i(:) + real(r8),optional, intent(in) :: frac_o(:) integer , intent(out) :: rc ! local variables @@ -178,7 +178,12 @@ subroutine output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & rc = ESMF_SUCCESS lnomask = .false. - if (present(nomask)) lnomask = nomask + if (present(nomask)) then + lnomask = nomask + else if (.not. (present(mask_i) .and. present(frac_o))) then + write(6,*) 'Must pass argument nomask if not passing mask_i and frac_o.' + call shr_sys_abort() + end if ! Determine ns_i and ns_o call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) @@ -203,17 +208,19 @@ subroutine output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & write(6,*) 'ns_o = ', ns_o call shr_sys_abort() end if - if (size(frac_o) /= ns_o) then - write(6,*) subname//' ERROR: incorrect size of frac_o' - write(6,*) 'size(frac_o) = ', size(frac_o) - write(6,*) 'ns_o = ', ns_o - call shr_sys_abort() - end if - if (size(mask_i) /= ns_i) then - write(6,*) subname//' ERROR: incorrect size of mask_i' - write(6,*) 'size(mask_i) = ', size(mask_i) - write(6,*) 'ns_i = ', ns_i - call shr_sys_abort() + if (present(mask_i) .and. present(frac_o)) then + if (size(frac_o) /= ns_o) then + write(6,*) subname//' ERROR: incorrect size of frac_o' + write(6,*) 'size(frac_o) = ', size(frac_o) + write(6,*) 'ns_o = ', ns_o + call shr_sys_abort() + end if + if (size(mask_i) /= ns_i) then + write(6,*) subname//' ERROR: incorrect size of mask_i' + write(6,*) 'size(mask_i) = ', size(mask_i) + write(6,*) 'ns_i = ', ns_i + call shr_sys_abort() + end if end if ! Sums on input grid @@ -263,21 +270,23 @@ subroutine output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & end subroutine output_diagnostics_continuous !=============================================================== - subroutine output_diagnostics_continuous_outonly(area_o, frac_o, data_o, name, units, ndiag) + subroutine output_diagnostics_continuous_outonly(mesh_o, frac_o, data_o, name, units, ndiag, rc) ! ! Output diagnostics for a continuous field, just on the output grid ! This is used when the average of the field on the input grid is not of interest (e.g., ! when the output quantity is the standard deviation of the input field) ! ! input/output variables - real(r8) , intent(in) :: area_o(:) + type(ESMF_Mesh) , intent(in) :: mesh_o real(r8) , intent(in) :: frac_o(:) real(r8) , intent(in) :: data_o(:) ! data on output grid character(len=*) , intent(in) :: name ! name of field character(len=*) , intent(in) :: units ! units of field integer , intent(in) :: ndiag ! unit number for diagnostic output + integer , intent(out) :: rc ! local variables: + real(r8), allocatable :: area_o(:) real(r8) :: gdata_o ! global sum of output data real(r8) :: gwt_o ! global sum of output weights (area * frac) integer :: ns_o ! size of output grid @@ -285,7 +294,16 @@ subroutine output_diagnostics_continuous_outonly(area_o, frac_o, data_o, name, u character(len=*), parameter :: subname = "output_diagnostics_continuous_outonly" !------------------------------------------------------------------------------ - ns_o = size(area_o) + rc = ESMF_SUCCESS + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine area_o + allocate(area_o(ns_o)) + call get_meshareas(mesh_o, area_o, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return ! Error check for array size consistencies if (size(data_o) /= ns_o) then diff --git a/tools/mksurfdata_esmf/src/mkgdpMod.F90 b/tools/mksurfdata_esmf/src/mkgdpMod.F90 index 4d60c63daf..801ba5e604 100644 --- a/tools/mksurfdata_esmf/src/mkgdpMod.F90 +++ b/tools/mksurfdata_esmf/src/mkgdpMod.F90 @@ -132,8 +132,8 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) call pio_syncfile(pioid_o) ! Output diagnostic info - call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - gdp_i, gdp_o, "GDP", "x1000 US$ per capita", ndiag, rc) + call output_diagnostics_continuous(mesh_i, mesh_o, gdp_i, gdp_o, & + "GDP", "x1000 US$ per capita", ndiag=ndiag, rc=rc, mask_i=mask_i, frac_o=frac_o) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() ! Clean up memory diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 2b2a6691c1..d8a07d8ae3 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -189,8 +189,9 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, fsurdat, end if ! Check global areas for lake depth - call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - lakedepth_i, lakedepth_o, "lake depth", "m", ndiag, rc) + call output_diagnostics_continuous(mesh_i, mesh_o, & + lakedepth_i, lakedepth_o, "lake depth", "m", & + ndiag=ndiag, rc=rc, mask_i=mask_i, frac_o=frac_o) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if diff --git a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 index 291e2e9e08..65534ed00a 100644 --- a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 @@ -66,9 +66,6 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) end if call ESMF_VMLogMemInfo("At start of "//trim(subname)) - ! Note soil_fmax_override has been removed - instead should now use tools - ! subset_data and modify_fsurdat - ! Open input data file rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 8f7135cc6d..f02e9291d3 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -70,13 +70,13 @@ program mksurfdata ! gitdescribe ------- Description of this version from git ! numpft ------------ Iif different than default of 16 ! urban_skip_abort_on_invalid_data_check--- work around urban bug + ! no_inlandwet ------ If wetland should be set to 0% over land ! ====================================== ! Note: the folloiwng Optional settings have been REMOVED - ! instead should now use tools subset_data and modify_fsurdat ! ====================================== ! all_veg ----------- If entire area is to be vegetated (pft_idx and pft_frc then required) ! all_urban --------- If entire area is urban - ! no_inlandwet ------ If wetland should be set to 0% over land ! soil_clay --------- If you want to change the soil_clay % to this value everywhere ! soil_fmax --------- If you want to change the soil_fmax to this value everywhere ! soil_sand --------- If you want to change the soil_sand % to this value everywhere diff --git a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 index 836799b661..fac41a082a 100644 --- a/tools/mksurfdata_esmf/src/mktopostatsMod.F90 +++ b/tools/mksurfdata_esmf/src/mktopostatsMod.F90 @@ -33,7 +33,7 @@ subroutine mktopostats(file_mesh_i, file_data_i, file_data_i_override, mesh_o, p ! make various topography statistics ! - use mkdiagnosticsMod, only : output_diagnostics_continuous, output_diagnostics_continuous_outonly + use mkdiagnosticsMod, only : output_diagnostics_continuous use mkchecksMod , only : min_bad, max_bad ! ! input/output variables @@ -56,8 +56,6 @@ subroutine mktopostats(file_mesh_i, file_data_i, file_data_i_override, mesh_o, p real(r4), pointer :: dataptr(:) real(r4), allocatable :: topo_stddev_o(:) ! output grid: standard deviation of elevation (m) real(r4), allocatable :: slope_o(:) ! output grid: slope (degrees) - real(r8), allocatable :: area_i(:) - real(r8), allocatable :: area_o(:) integer :: ier, rcode ! error status integer :: srcTermProcessing_Value = 0 real(r4), parameter :: min_valid = 0._r4 ! minimum valid value @@ -177,15 +175,12 @@ subroutine mktopostats(file_mesh_i, file_data_i, file_data_i_override, mesh_o, p if (chkerr(rc,__LINE__,u_FILE_u)) return topo_stddev_o(:) = dataptr(:) - ! call output_diagnostics_continuous_outonly(topo_stddev_o, tgridmap, "Topo Std Dev", "m", ndiag) ! Check validity of output data - !if (min_bad(topo_stddev_o, min_valid_topo_stddev, 'topo_stddev')) then - !call shr_sys_abort() - !end if - - ! TODO: get the output diagnostics working - ! call output_diagnostics_continuous_outonly(area_i, area_o, mask_i, frac_o, & - ! data_i, topo_stddev_o, "Topo Std Dev", "m", ndiag) + if (min_bad(topo_stddev_o, min_valid_topo_stddev, 'topo_stddev')) then + call shr_sys_abort() + end if + call output_diagnostics_continuous(mesh_i, mesh_o, real(data_i,8), real(topo_stddev_o,8), & + "Topo Std Dev", "m", ndiag=ndiag, rc=rc, nomask=.true.) ! ----------------------------- ! Obtain the slope @@ -208,14 +203,13 @@ subroutine mktopostats(file_mesh_i, file_data_i, file_data_i_override, mesh_o, p if (chkerr(rc,__LINE__,u_FILE_u)) return slope_o(:) = dataptr(:) - ! call output_diagnostics_continuous(data_i, slope_o, tgridmap, - !"Slope", "degrees", ndiag, tdomain%mask, tgridmap%frac_dst) - ! Check validity of output data - !if (min_bad(slope_o, min_valid_slope, 'slope') .or. & - ! max_bad(slope_o, max_valid_slope, 'slope')) then - !call shr_sys_abort() - !end if + if (min_bad(slope_o, min_valid_slope, 'slope') .or. & + max_bad(slope_o, max_valid_slope, 'slope')) then + call shr_sys_abort() + end if + call output_diagnostics_continuous(mesh_i, mesh_o, real(data_i,8), real(slope_o,8), & + "Slope", "degrees", ndiag=ndiag, rc=rc, nomask=.true.) ! Write out output data if (root_task) write(ndiag, '(a)') trim(subname)//" writing topo_stddev " diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 0726672642..97a93c7721 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -14,7 +14,7 @@ module mkurbanparMod use mkutilsMod , only : chkerr use mkvarctl , only : root_task, ndiag, ispval, outnc_double use mkutilsMod , only : normalize_classes_by_gcell - use mkdiagnosticsMod , only : output_diagnostics_index + use mkdiagnosticsMod , only : output_diagnostics_index, output_diagnostics_continuous use mkindexmapMod , only : dim_slice_type, lookup_2d_netcdf use mkvarpar , only : numrad, numsolar, re @@ -91,9 +91,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, urban_classes_o, ! arbitrary assignment of urban into the different classes). ! ! See comments under the normalize_urbn_by_tot subroutine for how urban_classes_o is - ! determined when the total % urban is 0, according to the input data. Note that this - ! also applies when all_urban=.true., for points that have 0 urban according to the input - ! data. + ! determined when the total % urban is 0, according to the input data. ! ! TODO (WJS 6-12-14): I think this could be rewritten slightly to take advantage of the ! new mkpctPftTypeMod (which should then be renamed to something more general; or maybe @@ -314,7 +312,10 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, urban_classes_o, end if ! Output diagnostics - ! TODO: (not currently done) + call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & + 1, max_regions, region_i, region_o, 'urban region', ndiag, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + ! Close the file call pio_closefile(pioid) @@ -939,8 +940,8 @@ subroutine mkurban_topo(file_mesh_i, file_data_i, mesh_o, varname, elev_o, rc) call regrid_rawdata(mesh_i, mesh_o, routehandle, elev_i, elev_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! call output_diagnostics_continuous(mesh_i, mesh_o, mask_i, frac_o, & - ! data_i, data_o, "Urban elev variable", "m", ndiag) + call output_diagnostics_continuous(mesh_i, mesh_o, elev_i, elev_o, & + "Urban elev variable", "m", ndiag=ndiag, rc=rc, nomask=.true.) ! Deallocate dynamic memory deallocate (elev_i) From d80eb3fd8fc1be4adfa944b355d28b99b55bff7d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 14 Apr 2022 16:33:25 -0600 Subject: [PATCH 132/614] Update mksrf_lai and _soilcolor files; reintroduce the inlandwet option 1) New files generated by Peter Lawrence 2) --inlandwet can now be added to the namelist, but mksurfdata fails with it for some reason 3) Also I just discovered that mksurfdata fails when generating a 1-deg surface dataset --- tools/mksurfdata_esmf/README | 13 +++++----- .../gen_mksurfdata_namelist.py | 25 +++++++++++-------- .../gen_mksurfdata_namelist.xml | 4 +-- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 0f1162d8a5..662e04f346 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -62,13 +62,14 @@ slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED ------------------------------------------------------------ REMEMBER TO compare against existing fsurdat files in /glade/p/cesmdata/cseg/inputdata/lnd/clm2/surfdata_map/release-clm5.0.18 -0) TODO: Test --no_inlandwet = .false. -1) OK: 1x1_brazil min number-of-nodes tested: 4 -2) OK: 10x15 min number-of-nodes tested: 3 -3) Soil color & texture and ag fire peak month outputs too high in .log +0) 0.9x1.25 gives error about sum of PFTs... +1) --no_inlandwet = .false. FAIL and --rundir DOESN'T DO ANYTHING +2) Soil color & texture and ag fire peak month outputs too high in .log TODO: Change frac_o from always 1. -4) Pct lake has chged in the .log bc the old diagnostic omitted mask_i frac_o -5) Slope, stddev have chged in the .log bc the old diag. used frac_o +3) Pct lake has chged in the .log bc the old diagnostic omitted mask_i frac_o +4) Slope, stddev have chged in the .log bc the old diag. used frac_o +5) OK: 1x1_brazil min number-of-nodes tested: 4 +6) OK: 10x15 min number-of-nodes tested: 3 ------------------------------------------------------ NOT ALL FILES HAVE BEEN TRANSLATED to cdf5 : check last millenium diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 64eaf289e5..ae3f62e5c6 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -24,7 +24,7 @@ def get_parser(): parser.add_argument( '-v', '--verbose', - help="ncrease output verbosity", + help="increase output verbosity", action="store_true", ) parser.add_argument( @@ -146,6 +146,16 @@ def get_parser(): dest="vic_flag", default=False, ) + parser.add_argument( + "--inlandwet", + help=""" + Flag for including inland wetlands. + [default: %(default)s] + """, + action="store_true", + dest="inlandwet", + default=False, + ) parser.add_argument( "--glc", help=""" @@ -230,6 +240,7 @@ def main (): nocrop_flag = args.crop_flag nosurfdata_flag = args.surfdata_flag vic_flag = args.vic_flag + inlandwet = args.inlandwet glc_flag = args.glc_flag potveg = args.potveg_flag glc_nec = args.glc_nec @@ -568,15 +579,9 @@ def main (): # output data logicals # ------------------- nlfile.write(f" numpft = {num_pft} \n") - nlfile.write( " no_inlandwet = .true. \n") - if glc_flag: - nlfile.write( " outnc_3dglc = .true. \n") - else: - nlfile.write( " outnc_3dglc = .false. \n") - if vic_flag: - nlfile.write( " outnc_vic = .true. \n") - else: - nlfile.write(" outnc_vic = .false. \n") + nlfile.write(f" no_inlandwet = .{str(not inlandwet).lower()}. \n") + nlfile.write(f" outnc_3dglc = .{str(glc_flag).lower()}. \n") + nlfile.write(f" outnc_vic = .{str(vic_flag).lower()}. \n") nlfile.write( " outnc_large_files = .false. \n") nlfile.write( " outnc_double = .true. \n") nlfile.write(f" logname = \'{logname}\' \n") diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 4a8af81c6a..5ea0b982d0 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -10,7 +10,7 @@ - lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.cdf5.c220206.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20220305/mksrf_lai_ctsm52_histLUH2_2005.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc @@ -39,7 +39,7 @@ - lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_soilcolor_CMIP6_simyr2005_cd5.c220126.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20220305/mksrf_soilcolor_ctsm52_histLUH2_2005.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc From 2616c03e16abe967e680c60eb067fc140fe9750d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 14 Apr 2022 17:18:43 -0600 Subject: [PATCH 133/614] Correct bug that caused creation of 1-deg fsurdat to fail --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index f02e9291d3..ddc141798f 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -1207,7 +1207,7 @@ subroutine normalize_and_check_landuse(ns_o) pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(),suma call shr_sys_abort() end if - call pctcft(n)%set_pct_l2g(0._r8) + call pctnatpft(n)%set_pct_l2g(0._r8) call pctcft(n)%set_pct_l2g(0._r8) end if if ( any(pctnatpft(n)%get_pct_p2g() > 0.0_r8 .and. pctnatpft(n)%get_pct_p2g() < toosmallPFT ) .or. & From 446bd2fa0bee492fdb9603c4b7aacd7ebdd0922b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 15 Apr 2022 10:57:01 -0600 Subject: [PATCH 134/614] Fully correct bug that caused 1-deg fsurdat to not be created --- tools/mksurfdata_esmf/README | 7 +++---- tools/mksurfdata_esmf/src/mksurfdata.F90 | 3 +-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 662e04f346..c52e05b45c 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -62,14 +62,13 @@ slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED ------------------------------------------------------------ REMEMBER TO compare against existing fsurdat files in /glade/p/cesmdata/cseg/inputdata/lnd/clm2/surfdata_map/release-clm5.0.18 -0) 0.9x1.25 gives error about sum of PFTs... -1) --no_inlandwet = .false. FAIL and --rundir DOESN'T DO ANYTHING +1) --no_inlandwet = .false. FAIL not due to lack of cdf5 +and --rundir DOESN'T DO ANYTHING 2) Soil color & texture and ag fire peak month outputs too high in .log TODO: Change frac_o from always 1. 3) Pct lake has chged in the .log bc the old diagnostic omitted mask_i frac_o 4) Slope, stddev have chged in the .log bc the old diag. used frac_o -5) OK: 1x1_brazil min number-of-nodes tested: 4 -6) OK: 10x15 min number-of-nodes tested: 3 +5) 1x1_brazil min number-of-nodes tested: 4; 10x15 min tested: 3 ------------------------------------------------------ NOT ALL FILES HAVE BEEN TRANSLATED to cdf5 : check last millenium diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index ddc141798f..dbc162a0fb 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -1201,14 +1201,13 @@ subroutine normalize_and_check_landuse(ns_o) else if (pctcft(n)%get_pct_l2g() >= 1.0_r8) then call pctcft(n)%set_pct_l2g(100._r8 - (pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n))) else - write (6,*) subname, 'Error: sum of special land units nearly 100% but none is >= 25% at ', & + write (6,*) subname, 'Error: sum of special land units nearly 100% but none is >= 1% at ', & 'n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),pctnatveg(n),pctcrop(n),suma = ', & n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(),suma call shr_sys_abort() end if call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) end if if ( any(pctnatpft(n)%get_pct_p2g() > 0.0_r8 .and. pctnatpft(n)%get_pct_p2g() < toosmallPFT ) .or. & any(pctcft(n)%get_pct_p2g() > 0.0_r8 .and. pctcft(n)%get_pct_p2g() < toosmallPFT )) then From b0c0502b3c90154f26557b635500db07a0aeefdd Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 15 Apr 2022 16:01:58 -0600 Subject: [PATCH 135/614] Correction needed for inland wetlands to work --- tools/mksurfdata_esmf/README | 12 +++++------- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 3 +++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index c52e05b45c..c719e0df74 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -62,13 +62,11 @@ slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED ------------------------------------------------------------ REMEMBER TO compare against existing fsurdat files in /glade/p/cesmdata/cseg/inputdata/lnd/clm2/surfdata_map/release-clm5.0.18 -1) --no_inlandwet = .false. FAIL not due to lack of cdf5 -and --rundir DOESN'T DO ANYTHING -2) Soil color & texture and ag fire peak month outputs too high in .log - TODO: Change frac_o from always 1. -3) Pct lake has chged in the .log bc the old diagnostic omitted mask_i frac_o -4) Slope, stddev have chged in the .log bc the old diag. used frac_o -5) 1x1_brazil min number-of-nodes tested: 4; 10x15 min tested: 3 +1) Soil color & texture and ag fire peak month outputs too high in .log + TODO? Change frac_o from always 1. +2) Pct lake has chged in the .log bc the old diagnostic omitted mask_i frac_o +3) Slope, stddev have chged in the .log bc the old diag. used frac_o +4) 1x1_brazil min number-of-nodes tested: 4; 10x15 min tested: 3 ------------------------------------------------------ NOT ALL FILES HAVE BEEN TRANSLATED to cdf5 : check last millenium diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index d8a07d8ae3..426c6d2857 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -262,6 +262,9 @@ subroutine mkwetlnd(file_mesh_i, file_data_i, mesh_o, swmp_o, rc) write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if + ! Open input data file + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) + ! Read in input mesh mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return From 5517e2052b863e0b76a675c94e5ba9efca561956 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 18 Apr 2022 16:24:03 -0600 Subject: [PATCH 136/614] Ensure sum(landunits) = 100% in transient before normalizing the terms ...else was getting an error. Seems connected to introducing transient urban and lakes. Not clear why I didn't get the error a few weeks ago when I originally brought over the transient urban and lake code to this PR. --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 38 ++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index dbc162a0fb..b55f33bc75 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -960,14 +960,48 @@ program mksurfdata ! north pole is assumed as non-land ! pctlak, pctwet, pcturb and pctgla were calculated ABOVE ! pctnatpft and pctcft were calculated ABOVE + ! TODO slevis: Same loop as when not transient, so use a subroutine as + ! in the old mksurfdata_map BUT should normalization be done differently + ! here to accept the changes in transient terms at that expense of + ! non transient terms? do n = 1,lsize_o if (abs(lat(n) - 90._r8) < 1.e-6_r8) then pctlak(n) = 0._r8 pctwet(n) = 0._r8 pcturb(n) = 0._r8 pctgla(n) = 100._r8 - call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) + call pctnatpft(n)%set_pct_l2g(0._r8) ! TODO slevis: add these... + call pctcft(n)%set_pct_l2g(0._r8) ! ...to non transient? + end if + + ! Truncate all percentage fields on output grid to ensure wt = 0 + ! (not a very small number such as 1e-16) where it should be zero + pctlak(n) = float(nint(pctlak(n))) + pctwet(n) = float(nint(pctwet(n))) + pctgla(n) = float(nint(pctgla(n))) + + ! Assume wetland, glacier and/or lake when dataset landmask implies ocean + if (pctlnd_pft(n) < 1.e-6_r8) then + if (pctgla(n) < 1.e-6_r8) then + pctwet(n) = 100._r8 - pctlak(n) + pctgla(n) = 0._r8 + else + pctwet(n) = max(100._r8 - pctgla(n) - pctlak(n), 0.0_r8) + end if + pcturb(n) = 0._r8 + end if + + ! Make sure sum of all land cover types except natural vegetation + ! does not exceed 100. If it does, subtract excess from these land + ! cover types proportionally. + + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() + if (suma > 100._r4) then + pctlak(n) = pctlak(n) * 100._r8 / suma + pctwet(n) = pctwet(n) * 100._r8 / suma + pcturb(n) = pcturb(n) * 100._r8 / suma + pctgla(n) = pctgla(n) * 100._r8 / suma + call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8 / suma) end if end do From 255486bd45cb68b106158cac48d6ffe7d2fa185b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 18 Apr 2022 17:54:35 -0600 Subject: [PATCH 137/614] Subroutinize previous commit similar to what was done in mksurfdata_map --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 107 +++++++++-------------- 1 file changed, 42 insertions(+), 65 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index b55f33bc75..4fb7c0ae0c 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -584,35 +584,6 @@ program mksurfdata pctgla(n) = 100._r8 end if - ! Truncate all percentage fields on output grid. This is needed to insure that - ! wt is zero (not a very small number such as 1e-16) where it should be zero - pctlak(n) = float(nint(pctlak(n))) - pctwet(n) = float(nint(pctwet(n))) - pctgla(n) = float(nint(pctgla(n))) - - ! Assume wetland, glacier and/or lake when dataset landmask implies ocean - if (pctlnd_pft(n) < 1.e-6_r8) then - if (pctgla(n) < 1.e-6_r8) then - pctwet(n) = 100._r8 - pctlak(n) - pctgla(n) = 0._r8 - else - pctwet(n) = max(100._r8 - pctgla(n) - pctlak(n), 0.0_r8) - end if - pcturb(n) = 0._r8 - end if - - ! Make sure sum of all land cover types except natural vegetation - ! does not exceed 100. If it does, subtract excess from these land cover - ! types proportionally. - - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() - if (suma > 100._r4) then - pctlak(n) = pctlak(n) * 100._r8/suma - pctwet(n) = pctwet(n) * 100._r8/suma - pcturb(n) = pcturb(n) * 100._r8/suma - pctgla(n) = pctgla(n) * 100._r8/suma - call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8/suma) - end if end do ! Save special land unit areas of surface dataset @@ -955,54 +926,20 @@ program mksurfdata pctwet(:) = pctwet_orig(:) pctgla(:) = pctgla_orig(:) - ! Do landuse changes such as for the poles, etc. ! If have pole points on grid - set south pole to glacier ! north pole is assumed as non-land ! pctlak, pctwet, pcturb and pctgla were calculated ABOVE ! pctnatpft and pctcft were calculated ABOVE - ! TODO slevis: Same loop as when not transient, so use a subroutine as - ! in the old mksurfdata_map BUT should normalization be done differently - ! here to accept the changes in transient terms at that expense of - ! non transient terms? do n = 1,lsize_o if (abs(lat(n) - 90._r8) < 1.e-6_r8) then pctlak(n) = 0._r8 pctwet(n) = 0._r8 pcturb(n) = 0._r8 pctgla(n) = 100._r8 - call pctnatpft(n)%set_pct_l2g(0._r8) ! TODO slevis: add these... - call pctcft(n)%set_pct_l2g(0._r8) ! ...to non transient? - end if - - ! Truncate all percentage fields on output grid to ensure wt = 0 - ! (not a very small number such as 1e-16) where it should be zero - pctlak(n) = float(nint(pctlak(n))) - pctwet(n) = float(nint(pctwet(n))) - pctgla(n) = float(nint(pctgla(n))) - - ! Assume wetland, glacier and/or lake when dataset landmask implies ocean - if (pctlnd_pft(n) < 1.e-6_r8) then - if (pctgla(n) < 1.e-6_r8) then - pctwet(n) = 100._r8 - pctlak(n) - pctgla(n) = 0._r8 - else - pctwet(n) = max(100._r8 - pctgla(n) - pctlak(n), 0.0_r8) - end if - pcturb(n) = 0._r8 + call pctnatpft(n)%set_pct_l2g(0._r8) + call pctcft(n)%set_pct_l2g(0._r8) end if - ! Make sure sum of all land cover types except natural vegetation - ! does not exceed 100. If it does, subtract excess from these land - ! cover types proportionally. - - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() - if (suma > 100._r4) then - pctlak(n) = pctlak(n) * 100._r8 / suma - pctwet(n) = pctwet(n) * 100._r8 / suma - pcturb(n) = pcturb(n) * 100._r8 / suma - pctgla(n) = pctgla(n) * 100._r8 / suma - call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8 / suma) - end if end do ! Normalize land use and make sure things add up to 100% as well as @@ -1130,6 +1067,46 @@ subroutine normalize_and_check_landuse(ns_o) do n = 1,ns_o + ! Truncate all percentage fields on output grid. This is needed to + ! insure that wt is zero (not a very small number such as + ! 1e-16) where it really should be zero + + pctlak(n) = float(nint(pctlak(n))) + pctwet(n) = float(nint(pctwet(n))) + pctgla(n) = float(nint(pctgla(n))) + + ! Assume wetland, glacier and/or lake when dataset landmask implies ocean + ! (assume medium soil color (15) and loamy texture). + ! Also set pftdata_mask here + + if (pctlnd_pft(n) < 1.e-6_r8) then + pftdata_mask(n) = 0 + if (pctgla(n) < 1.e-6_r8) then + pctwet(n) = 100._r8 - pctlak(n) + pctgla(n) = 0._r8 + else + pctwet(n) = max(100._r8 - pctgla(n) - pctlak(n), 0.0_r8) + end if + pcturb(n) = 0._r8 + call pctnatpft(n)%set_pct_l2g(0._r8) + call pctcft(n)%set_pct_l2g(0._r8) + else + pftdata_mask(n) = 1 + end if + + ! Make sure sum of all land cover types except natural vegetation does + ! not exceed 100. If it does, subtract excess from these land cover + ! types proportionally. + + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() + if (suma > 100._r4) then + pctlak(n) = pctlak(n) * 100._r8/suma + pctwet(n) = pctwet(n) * 100._r8/suma + pcturb(n) = pcturb(n) * 100._r8/suma + pctgla(n) = pctgla(n) * 100._r8/suma + call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8/suma) + end if + ! Check preconditions if ( pctlak(n) < 0.0_r8 )then write(6,*) subname, ' ERROR: pctlak is negative!' From c4a4fc1c798380620eef384b6250589c3e2f914d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 19 Apr 2022 19:04:57 -0600 Subject: [PATCH 138/614] In /tools/README replace mksurfdata_map with mksurfdata_esmf --- tools/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/README b/tools/README index 4a15242651..e71016486e 100644 --- a/tools/README +++ b/tools/README @@ -6,7 +6,7 @@ modification of CTSM input files. I. General directory structure: $CTSMROOT/tools - mksurfdata_map --- Create surface datasets. + mksurfdata_esmf -- Create surface datasets. mkmapgrids ------- Create regular lat/lon SCRIP grid files needed by mkmapdata mkmapdata -------- Create SCRIP mapping data from SCRIP grid files (uses ESMF) From 2f040bcd5c5d45e367d17767f1f016ede0c8bb98 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 20 Apr 2022 10:51:41 -0600 Subject: [PATCH 139/614] git rm -r mksurfdata_map in prep for first ctsm5.2.mksurfdata tag --- tools/mksurfdata_map/Makefile.data | 266 --- tools/mksurfdata_map/README | 73 - tools/mksurfdata_map/README.developers | 227 --- tools/mksurfdata_map/mksurfdata.pl | 881 --------- tools/mksurfdata_map/mksurfdata_map.namelist | 52 - .../single_point_dynpft_files/README | 4 - ...imeseries_smallvilleIA_hist_simyr1850-1855 | 23 - ...eries_smallvilleIA_hist_simyr1850-1855.txt | 6 - tools/mksurfdata_map/src/CMakeLists.txt | 43 - tools/mksurfdata_map/src/Filepath | 1 - tools/mksurfdata_map/src/Makefile | 10 - tools/mksurfdata_map/src/Makefile.common | 360 ---- tools/mksurfdata_map/src/Mkdepends | 328 --- tools/mksurfdata_map/src/README.unit_testing | 9 - tools/mksurfdata_map/src/Srcfiles | 40 - tools/mksurfdata_map/src/fileutils.F90 | 254 --- tools/mksurfdata_map/src/mkVICparamsMod.F90 | 200 -- .../mksurfdata_map/src/mkagfirepkmonthMod.F90 | 272 --- tools/mksurfdata_map/src/mkchecksMod.F90 | 233 --- tools/mksurfdata_map/src/mkdiagnosticsMod.F90 | 452 ----- tools/mksurfdata_map/src/mkdomainMod.F90 | 967 --------- tools/mksurfdata_map/src/mkfileMod.F90 | 566 ------ tools/mksurfdata_map/src/mkgdpMod.F90 | 147 -- .../mksurfdata_map/src/mkglacierregionMod.F90 | 139 -- tools/mksurfdata_map/src/mkglcmecMod.F90 | 794 -------- tools/mksurfdata_map/src/mkgridmapMod.F90 | 915 --------- tools/mksurfdata_map/src/mkharvestMod.F90 | 1105 ----------- tools/mksurfdata_map/src/mkindexmapMod.F90 | 697 ------- tools/mksurfdata_map/src/mklaiMod.F90 | 445 ----- tools/mksurfdata_map/src/mklanwatMod.F90 | 503 ----- tools/mksurfdata_map/src/mkncdio.F90 | 558 ------ tools/mksurfdata_map/src/mkpctPftTypeMod.F90 | 626 ------ tools/mksurfdata_map/src/mkpeatMod.F90 | 149 -- .../mksurfdata_map/src/mkpftConstantsMod.F90 | 43 - tools/mksurfdata_map/src/mkpftMod.F90 | 1259 ------------ tools/mksurfdata_map/src/mkpftUtilsMod.F90 | 257 --- tools/mksurfdata_map/src/mksoilMod.F90 | 1237 ------------ tools/mksurfdata_map/src/mksoilUtilsMod.F90 | 224 --- tools/mksurfdata_map/src/mksoildepthMod.F90 | 172 -- tools/mksurfdata_map/src/mksurfdat.F90 | 1630 --------------- tools/mksurfdata_map/src/mktopostatsMod.F90 | 183 -- .../src/mkurbanparCommonMod.F90 | 365 ---- tools/mksurfdata_map/src/mkurbanparMod.F90 | 759 ------- tools/mksurfdata_map/src/mkutilsMod.F90 | 197 -- tools/mksurfdata_map/src/mkvarctl.F90 | 90 - tools/mksurfdata_map/src/mkvarpar.F90 | 32 - tools/mksurfdata_map/src/mkvocefMod.F90 | 209 -- tools/mksurfdata_map/src/nanMod.F90 | 41 - tools/mksurfdata_map/src/shr_const_mod.F90 | 58 - tools/mksurfdata_map/src/shr_file_mod.F90 | 1023 ---------- tools/mksurfdata_map/src/shr_kind_mod.F90 | 19 - tools/mksurfdata_map/src/shr_log_mod.F90 | 13 - tools/mksurfdata_map/src/shr_string_mod.F90 | 1753 ----------------- tools/mksurfdata_map/src/shr_sys_mod.F90 | 352 ---- tools/mksurfdata_map/src/shr_timer_mod.F90 | 425 ---- tools/mksurfdata_map/src/test/CMakeLists.txt | 7 - .../src/test/mkdomain_test/CMakeLists.txt | 7 - .../src/test/mkdomain_test/test_mkdomain.pf | 93 - .../src/test/mkgridmap_test/CMakeLists.txt | 4 - .../src/test/mkgridmap_test/test_mkgridmap.pf | 106 - .../src/test/mkindexmap_test/CMakeLists.txt | 4 - .../test/mkindexmap_test/test_mkindexmap.pf | 258 --- .../src/test/mkpctPftType_test/CMakeLists.txt | 4 - .../mkpctPftType_test/test_mkpctPftType.pf | 253 --- .../src/test/mkpftUtils_test/CMakeLists.txt | 8 - .../test_adjust_total_veg_area.pf | 59 - .../mkpftUtils_test/test_convert_from_p2g.pf | 151 -- .../src/test/mkpftmod_test/CMakeLists.txt | 9 - .../src/test/mkpftmod_test/test_pftInit.pf | 297 --- .../src/test/mkpftmod_test/test_pft_oride.pf | 127 -- .../src/test/mkpftmod_test/test_pftrun.pf | 204 -- .../src/test/mksoilUtils_test/CMakeLists.txt | 7 - .../test_dominant_soil_color.pf | 140 -- .../src/unit_test_stubs/abort.F90 | 25 - .../src/unit_test_stubs/mkncdio.F90 | 223 --- tools/mksurfdata_map/unit_testers/Filepath | 2 - tools/mksurfdata_map/unit_testers/Makefile | 10 - tools/mksurfdata_map/unit_testers/README | 6 - tools/mksurfdata_map/unit_testers/Srcfiles | 32 - .../unit_testers/test_mkchecksMod.F90 | 101 - .../unit_testers/test_mkdomainMod.F90 | 95 - .../unit_testers/test_mkgridmapMod.F90 | 476 ----- .../unit_testers/test_mkharvest.F90 | 316 --- .../unit_testers/test_mkindexmapMod.F90 | 573 ------ .../unit_testers/test_mkncdio.F90 | 82 - .../unit_testers/test_mksurfdata_map.F90 | 52 - .../unit_testers/test_mkurbanparMod.F90 | 75 - .../unit_testers/test_mkutilsMod.F90 | 112 -- .../mksurfdata_map/unit_testers/test_mod.F90 | 339 ---- 89 files changed, 25943 deletions(-) delete mode 100644 tools/mksurfdata_map/Makefile.data delete mode 100644 tools/mksurfdata_map/README delete mode 100644 tools/mksurfdata_map/README.developers delete mode 100755 tools/mksurfdata_map/mksurfdata.pl delete mode 100644 tools/mksurfdata_map/mksurfdata_map.namelist delete mode 100644 tools/mksurfdata_map/single_point_dynpft_files/README delete mode 100644 tools/mksurfdata_map/single_point_dynpft_files/README.landuse_timeseries_smallvilleIA_hist_simyr1850-1855 delete mode 100644 tools/mksurfdata_map/single_point_dynpft_files/landuse_timeseries_smallvilleIA_hist_simyr1850-1855.txt delete mode 100644 tools/mksurfdata_map/src/CMakeLists.txt delete mode 100644 tools/mksurfdata_map/src/Filepath delete mode 100644 tools/mksurfdata_map/src/Makefile delete mode 100644 tools/mksurfdata_map/src/Makefile.common delete mode 100755 tools/mksurfdata_map/src/Mkdepends delete mode 100644 tools/mksurfdata_map/src/README.unit_testing delete mode 100644 tools/mksurfdata_map/src/Srcfiles delete mode 100644 tools/mksurfdata_map/src/fileutils.F90 delete mode 100644 tools/mksurfdata_map/src/mkVICparamsMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkagfirepkmonthMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkchecksMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkdiagnosticsMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkdomainMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkfileMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkgdpMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkglacierregionMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkglcmecMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkgridmapMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkharvestMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkindexmapMod.F90 delete mode 100644 tools/mksurfdata_map/src/mklaiMod.F90 delete mode 100644 tools/mksurfdata_map/src/mklanwatMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkncdio.F90 delete mode 100644 tools/mksurfdata_map/src/mkpctPftTypeMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkpeatMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkpftConstantsMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkpftMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkpftUtilsMod.F90 delete mode 100644 tools/mksurfdata_map/src/mksoilMod.F90 delete mode 100644 tools/mksurfdata_map/src/mksoilUtilsMod.F90 delete mode 100644 tools/mksurfdata_map/src/mksoildepthMod.F90 delete mode 100644 tools/mksurfdata_map/src/mksurfdat.F90 delete mode 100644 tools/mksurfdata_map/src/mktopostatsMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkurbanparCommonMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkurbanparMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkutilsMod.F90 delete mode 100644 tools/mksurfdata_map/src/mkvarctl.F90 delete mode 100644 tools/mksurfdata_map/src/mkvarpar.F90 delete mode 100644 tools/mksurfdata_map/src/mkvocefMod.F90 delete mode 100644 tools/mksurfdata_map/src/nanMod.F90 delete mode 100644 tools/mksurfdata_map/src/shr_const_mod.F90 delete mode 100644 tools/mksurfdata_map/src/shr_file_mod.F90 delete mode 100644 tools/mksurfdata_map/src/shr_kind_mod.F90 delete mode 100644 tools/mksurfdata_map/src/shr_log_mod.F90 delete mode 100644 tools/mksurfdata_map/src/shr_string_mod.F90 delete mode 100644 tools/mksurfdata_map/src/shr_sys_mod.F90 delete mode 100644 tools/mksurfdata_map/src/shr_timer_mod.F90 delete mode 100644 tools/mksurfdata_map/src/test/CMakeLists.txt delete mode 100644 tools/mksurfdata_map/src/test/mkdomain_test/CMakeLists.txt delete mode 100644 tools/mksurfdata_map/src/test/mkdomain_test/test_mkdomain.pf delete mode 100644 tools/mksurfdata_map/src/test/mkgridmap_test/CMakeLists.txt delete mode 100644 tools/mksurfdata_map/src/test/mkgridmap_test/test_mkgridmap.pf delete mode 100644 tools/mksurfdata_map/src/test/mkindexmap_test/CMakeLists.txt delete mode 100644 tools/mksurfdata_map/src/test/mkindexmap_test/test_mkindexmap.pf delete mode 100644 tools/mksurfdata_map/src/test/mkpctPftType_test/CMakeLists.txt delete mode 100644 tools/mksurfdata_map/src/test/mkpctPftType_test/test_mkpctPftType.pf delete mode 100644 tools/mksurfdata_map/src/test/mkpftUtils_test/CMakeLists.txt delete mode 100644 tools/mksurfdata_map/src/test/mkpftUtils_test/test_adjust_total_veg_area.pf delete mode 100644 tools/mksurfdata_map/src/test/mkpftUtils_test/test_convert_from_p2g.pf delete mode 100644 tools/mksurfdata_map/src/test/mkpftmod_test/CMakeLists.txt delete mode 100644 tools/mksurfdata_map/src/test/mkpftmod_test/test_pftInit.pf delete mode 100644 tools/mksurfdata_map/src/test/mkpftmod_test/test_pft_oride.pf delete mode 100644 tools/mksurfdata_map/src/test/mkpftmod_test/test_pftrun.pf delete mode 100644 tools/mksurfdata_map/src/test/mksoilUtils_test/CMakeLists.txt delete mode 100644 tools/mksurfdata_map/src/test/mksoilUtils_test/test_dominant_soil_color.pf delete mode 100644 tools/mksurfdata_map/src/unit_test_stubs/abort.F90 delete mode 100644 tools/mksurfdata_map/src/unit_test_stubs/mkncdio.F90 delete mode 100644 tools/mksurfdata_map/unit_testers/Filepath delete mode 100644 tools/mksurfdata_map/unit_testers/Makefile delete mode 100644 tools/mksurfdata_map/unit_testers/README delete mode 100644 tools/mksurfdata_map/unit_testers/Srcfiles delete mode 100644 tools/mksurfdata_map/unit_testers/test_mkchecksMod.F90 delete mode 100644 tools/mksurfdata_map/unit_testers/test_mkdomainMod.F90 delete mode 100644 tools/mksurfdata_map/unit_testers/test_mkgridmapMod.F90 delete mode 100644 tools/mksurfdata_map/unit_testers/test_mkharvest.F90 delete mode 100644 tools/mksurfdata_map/unit_testers/test_mkindexmapMod.F90 delete mode 100644 tools/mksurfdata_map/unit_testers/test_mkncdio.F90 delete mode 100644 tools/mksurfdata_map/unit_testers/test_mksurfdata_map.F90 delete mode 100644 tools/mksurfdata_map/unit_testers/test_mkurbanparMod.F90 delete mode 100644 tools/mksurfdata_map/unit_testers/test_mkutilsMod.F90 delete mode 100644 tools/mksurfdata_map/unit_testers/test_mod.F90 diff --git a/tools/mksurfdata_map/Makefile.data b/tools/mksurfdata_map/Makefile.data deleted file mode 100644 index d0c000ba63..0000000000 --- a/tools/mksurfdata_map/Makefile.data +++ /dev/null @@ -1,266 +0,0 @@ -# -*- mode:Makefile -*- -# -# To generate all surface data sets, run: -# make -f Makefile.data all -# -# To generate a single dataset, run make with the name of the rule you -# want to build. For example, to generate the crop data set for 1x1_numaIA: -# -# make -f Makefile.data crop-numa -# -# NOTE: The default behavior is to parallelize data set creation using -# the batch system by submitting jobs to the batch queue (on cheyenne). -# On yellowstone we submit to an interactive queue in the -# background. Standard out and standard error are redirected to a text -# file. To change this behavior, you can comment out the BATCHJOBS and -# BACKGROUND variables and replace them with empty variables. -# -# WARNING: Do not put more than one mksurfdata call per rule. output -# redirection is based on the rule name, and multiple rules will over -# write the previous output or incomprehensively merge output from -# simultaneously running jobs. -# -# Note that we typically use -no_surfdata in rules for transient files, having -# separate rules to make the year-1850 and year-2000 surface datasets. This -# results in extra processes, but ensures that the surface datasets have the -# correct name (rather than having 'hist' or 'rcpXXX' in their file name). -# - -# Set up special characters -null := - -# Set a few things needed for batch handling -PROJECT = $(shell cat $(HOME)/.cesm_proj) -LOGOUT = $@.stdout.txt -PWD = $(shell pwd) - -# Setup batch handling for either cheyenne or yellowstone -# Determine what to use by machine hostname -BATCHJOBS_ys = execgy -# Send to regular queue for 2 processors with extra memory, combine stdout/stderr output to log file, and send email on abort or exit -BATCHJOBS_ch = qsub -A $(PROJECT) -q regular -l select=1:ncpus=2:mem=110GB -l walltime=4:00:00 -j oe -N $(LOGOUT) -m ae -- -HOST = $(shell hostname) -FINDCH = $(findstring cheyenne,$(HOST)) -ifeq ($(FINDCH),$(null)) - ifeq ($(PROJECT),$(null)) - $(error Can NOT find PROJECT number from ~/.cesm_proj file create it and try again) - endif - BATCHJOBS = $(BATCHJOBS_ys) - BACKGROUND = &> $(LOGOUT) & -else - BATCHJOBS = $(BATCHJOBS_ch) - BACKGROUND = -rundir $(PWD) -endif - -MKSURFDATA = $(BATCHJOBS) $(PWD)/mksurfdata.pl - -# f19 and f09 are standard resolutions, f10 is used for testing, f45 is used for FATES -# ne30np4 is standard resolution for SE dycore in CAM, C96 is standard for fv3 dycore -# The ne30np4 series (including pg2, pg3, pg4) are standard for SE dycore -# The variable resolution grids for ARCTIC, ARCTICGRIS and CONUS are also standard -STANDARD_RES_NO_CROP = 0.9x1.25,1.9x2.5,10x15 -STANDARD_RES = 0.9x1.25,1.9x2.5,10x15,4x5,ne30np4,C96,ne30pg2,ne30pg3,ne30pg4,ne120np4pg3,ne0np4ARCTICGRISne30x8,ne0np4ARCTICne30x4,ne0np4CONUSne30x8 - -# For future CMIP6 scenarios: SSP-RCP's -FUTURE_RES = 0.9x1.25,1.9x2.5,10x15 -# For historical transient cases (TRY TO KEEP THIS LIST AS SHORT AS POSSIBLE) -TRANS_RES = 0.9x1.25,1.9x2.5,10x15,ne30np4,ne0np4ARCTICGRISne30x8,ne0np4ARCTICne30x4,ne0np4CONUSne30x8 - -# ne120np4 is for high resolution SE dycore, ne16 is for testing SE dycore -# T42 is for SCAM -# f05 is needed for running full chemistry model -# nldas is for NWP working with WRF -STANDARD = \ - global-present \ - global-present-nldas \ - global-present-T42 - -TROPICS = \ - crop-tropics-present \ - crop-tropics-historical \ - crop-tropics-transient - -CROP = \ - crop-global-present \ - crop-global-present-ne16np4 \ - crop-global-present-ne120np4 \ - crop-numa-present \ - crop-numa-historical \ - crop-smallville \ - crop-smallville-historical \ - crop-global-historical \ - crop-global-transient \ - crop-global-future - -all : standard tropics crop urban landuse-timeseries - -DEBUG: - @echo "HOST := $(HOST)" - @echo "PROJECT := $(PROJECT)" - @echo "BATCHJOBS := $(BATCHJOBS)" - @echo "BACKGROUND := $(BACKGROUND)" -# -# standard -# -standard : $(STANDARD) - -global-present : FORCE - $(MKSURFDATA) -no-crop -vic -glc_nec 10 -y 2000 -res $(STANDARD_RES_NO_CROP) $(BACKGROUND) - -# T42 is needed for SCAM -global-present-T42 : FORCE - $(MKSURFDATA) -no-crop -glc_nec 10 -y 2000 -res 64x128 $(BACKGROUND) - -global-present-nldas : FORCE - $(MKSURFDATA) -no-crop -hirespft -glc_nec 10 -y 2005 -res 0.125nldas2 $(BACKGROUND) - -# -# tropics -# -tropics : $(TROPICS) - -crop-tropics-present : FORCE - $(MKSURFDATA) -glc_nec 10 -y 2000 -res 5x5_amazon,1x1_brazil $(BACKGROUND) - -crop-tropics-historical : FORCE - $(MKSURFDATA) -glc_nec 10 -y 1850 -res 1x1_brazil $(BACKGROUND) - -crop-tropics-transient : FORCE - $(MKSURFDATA) -glc_nec 10 -no_surfdata -y 1850-2000 -res 1x1_brazil $(BACKGROUND) - -# -# crop -# -crop : $(CROP) - -crop-global-present : FORCE - $(MKSURFDATA) -glc_nec 10 -y 2000 -r $(STANDARD_RES) $(BACKGROUND) - -crop-global-present-0.125 : FORCE - $(MKSURFDATA) -hirespft -glc_nec 10 -y 2000 -r 0.125x0.125 $(BACKGROUND) - -crop-global-present-f05 : FORCE - $(MKSURFDATA) -glc_nec 10 -y 1850,2000 -res 0.47x0.63 $(BACKGROUND) - -crop-numa-present : FORCE - $(MKSURFDATA) -glc_nec 10 -y 2000 -r 1x1_numaIA $(BACKGROUND) - -crop-numa-historical : FORCE - $(MKSURFDATA) -glc_nec 10 -y 1850 -r 1x1_numaIA $(BACKGROUND) - -crop-smallville : FORCE - $(MKSURFDATA) -glc_nec 10 -y 2000 -r 1x1_smallvilleIA \ - -pft_idx 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78 \ - -pft_frc 6.5,1.5,1.6,1.7,1.8,1.9,1.5,1.6,1.7,1.8,1.9,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5 \ - $(BACKGROUND) - -crop-global-present-ne16np4 : FORCE - $(MKSURFDATA) -glc_nec 10 -y 2000 -res ne16np4 $(BACKGROUND) - -crop-global-present-ne120np4 : FORCE - $(MKSURFDATA) -glc_nec 10 -y 2000 -res ne120np4 $(BACKGROUND) - -# Note that the smallville 1850 dataset is entirely natural vegetation. This -# facilitates testing a transient case that starts with no crop, and then later -# adds crop (to make sure that it works properly to add crop in a grid cell -# where there used to be no crop). -crop-smallville-historical : FORCE - $(MKSURFDATA) -glc_nec 10 -y 1850 -r 1x1_smallvilleIA -pft_idx 13 -pft_frc 100 $(BACKGROUND) - -# Setup the historical case for SSP5-8.5 so that historical can be used to go into the future. -crop-global-historical : FORCE - $(MKSURFDATA) -glc_nec 10 -y 1850 -ssp_rcp SSP5-8.5 -res $(STANDARD_RES) $(BACKGROUND) - -crop-global-historical-f05 : FORCE - $(MKSURFDATA) -glc_nec 10 -y 1850 -r 0.47x0.63 $(BACKGROUND) - -crop-global-historical-ne120np4 : FORCE - $(MKSURFDATA) -glc_nec 10 -y 1850 -res ne120np4 $(BACKGROUND) - -crop-global-transient: FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2000 -res $(TRANS_RES) $(BACKGROUND) - -crop-global-transient-ne120np4 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2000 -res ne120np4 $(BACKGROUND) - -crop-global-transient-f05 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2000 -res 0.47x0.63 $(BACKGROUND) - -# -# Crop with future scenarios -# -crop-global-future : crop-global-SSP1-2.6 crop-global-SSP3-7.0 crop-global-SSP5-3.4 crop-global-SSP2-4.5 \ - crop-global-SSP1-1.9 crop-global-SSP4-3.4 crop-global-SSP4-6.0 crop-global-SSP5-8.5 - -crop-global-SSP1-2.6 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP1-2.6 -res $(FUTURE_RES) $(BACKGROUND) - -crop-global-SSP3-7.0 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP3-7.0 -res $(FUTURE_RES) $(BACKGROUND) - -crop-global-SSP5-3.4 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP5-3.4 -res $(FUTURE_RES) $(BACKGROUND) - -crop-global-SSP2-4.5 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP2-4.5 -res $(FUTURE_RES) $(BACKGROUND) - -crop-global-SSP1-1.9 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP1-1.9 -res $(FUTURE_RES) $(BACKGROUND) - -crop-global-SSP4-3.4 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP4-3.4 -res $(FUTURE_RES) $(BACKGROUND) - -crop-global-SSP4-6.0 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP4-6.0 -res $(FUTURE_RES) $(BACKGROUND) - -crop-global-SSP5-8.5 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP5-8.5 -res $(FUTURE_RES) $(BACKGROUND) - -# -# urban -# -urban : urban-present urban-alpha - -urban-present : FORCE - $(MKSURFDATA) -y 2000 -no-crop -glc_nec 10 -r 1x1_vancouverCAN,1x1_mexicocityMEX $(BACKGROUND) - -# NOTE(bja, 2015-01) skip abort on invalid data necessary as of 2015-01. See -# /glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 -urban-alpha : FORCE - $(MKSURFDATA) -y 2000 -no-crop -glc_nec 10 -r 1x1_urbanc_alpha -urban_skip_abort_on_invalid_data_check $(BACKGROUND) - - -# -# landuse timeseries -# -landuse-timeseries : landuse-timeseries-smallville - -landuse-timeseries-smallville : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-1855 -r 1x1_smallvilleIA \ - -pft_idx 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78 \ - -pft_frc 6.5,1.5,1.6,1.7,1.8,1.9,1.5,1.6,1.7,1.8,1.9,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5 \ - -dynpft single_point_dynpft_files/landuse_timeseries_smallvilleIA_hist_simyr1850-1855.txt \ - $(BACKGROUND) - -# -# clean up the working directory by removing generated files -# -clean : FORCE - -rm *~ - -clobber : clean - -rm surfdata_*.nc surfdata_*.log surfdata_*.namelist - -# -# generic rule to force things to happen -# -FORCE : - diff --git a/tools/mksurfdata_map/README b/tools/mksurfdata_map/README deleted file mode 100644 index bd324580bb..0000000000 --- a/tools/mksurfdata_map/README +++ /dev/null @@ -1,73 +0,0 @@ -$CTSMROOT/tools/mksurfdata_map/README Jun 08, 2018 - -The routines in this directory create a surface dataset. -The output grid is read in from the input namelist and -can correspond to either a global or regional grid. - -Supported model resolutions are those found in the repository input data directory - $DIN_LOC_ROOT/lnd/clm2/mappingdata/maps - -Surface datasets can either be created for two separate cases - a) for supported model resolutions - b) for unsupported (user-specified) model resolutions - -The following steps provide a method to create the executable -and generate the surface dataset: - -1) Make the mksurfdata_map executable - - Starting from this directory $CTSMROOT/tools/mksurfdata_map - > cd src - > gmake - By default code compiles optimized so it's reasonably fast. If you want - to use the debugger, with bounds-checking, and float trapping on do the - following: - gmake OPT=FALSE - See Also: See the $CTSMROOT/tools/README file for notes about setting - the path for NetCDF and running with shared-memory parallelism. - -2) For supported model resolutions - skip this step - - For unsupported model resolutions - do the following... - determine the pathname of the model resolution SCRIP grid file - - Starting from this directory $CTSMROOT/tools/mksurfdata_map - > cd ../mkmapdata - invoke one of the following commands - (for global resolution) - > ./mkmapdata.sh -f -res -type global - (for regional resolution) - > ./mkmapdata.sh -f -res -type regional - > cd ../ - - note: the mapping files generated in ./mkmapdata will be used to - generate the surface dataset - note: the res argument above () MUST be identical to the one provided to - mksurfdata.pl (see below) - -3) make surface dataset(s) - - Starting from this directory $CTSMROOT/tools/mksurfdata_map - > mksurfdata.pl --help (for full usage instructions) - For supported model resolution () - > mksurfdata.pl -res [options] - - For supported model resolutions for SSP scenarios - > mksurfdata.pl -res -ssp_rcp -years 1850-2100 - - For unsupported, user specified model resolutions - > mksurfdata.pl -res usrspec -usr_gname -usr_gdate - - Note that the argument to usr_gname MUST be the same as the -res argument value - when invoking mkmapdata - - Example, for gridname=1x1_boulderCO with maps created on Jan/13/2012 - - > mksurfdata.pl -res usrspec -usr_gname 1x_boulderCO -usr_gdate 20120113 - -Lists of input files for range of dates historical or future scenarios: - - landuse_timeseries_hist_16pfts_simyr1850-2015.txt --- List of historical input PFT files from 1850 to 2015 - -(Historical period from 1850-2015 datafiles all point to the historical files) - diff --git a/tools/mksurfdata_map/README.developers b/tools/mksurfdata_map/README.developers deleted file mode 100644 index 6513aeb131..0000000000 --- a/tools/mksurfdata_map/README.developers +++ /dev/null @@ -1,227 +0,0 @@ -$CTSMROOT/tools/mksurfdata_map/README.developers Jun/08/2018 - -============================================================================ -============================================================================ -Developer's guide for mksurfdata_map -============================================================================ -============================================================================ - -============================================================================ -Table of Contents -============================================================================ - -I. Adding a new raw data file - -II. Adding mapping files for a raw data file with a new grid / landmask - -III. Checks that should be done when making new surface datasets - -============================================================================ -I. Adding a new raw data file -============================================================================ - -Here is what you need to change when adding a new raw data file, with one or -more fields that need to be remapped to the CLM resolution. Note that -additional steps are needed (beyond what's listed here) when the field -you're adding specifies something about the subgrid breakdown (into -landunits, columns & pfts): for those fields, additional code is needed to -ensure that percentages add to 100%. - -Note: The following assumes that the new file uses an existing set of -mapping files, or that you have already done everything necessary to add a -new set of mapping files. If your raw data file has a new grid, or a new -landmask on an existing grid, see the instructions for adding mapping files -in a separate section of this document. - -- Add a new module in $CTSMROOT/tools/mksurfdata_map/src that provides a routine for - remapping your new field(s). - - Note that there is generally one module per input file; multiple fields - can be regridded using a single subroutine or multiple subroutines. - -- Add your new file in $CTSMROOT/tools/mksurfdata_map/src/Srcfiles - -- Add new namelist options in $CTSMROOT/tools/mksurfdata_map/src/mkvarctl.F90; e.g., for a - new field xxx: - - mksrf_fxxx - - map_fxxx - -- Add output calls in $CTSMROOT/tools/mksurfdata_map/src/mkfileMod.F90; you need to add - calls in 3 places: - - raw data file name attribute (nf_put_att_text call) - - mapping file name attribute (nf_put_att_text call) - - variable definition (ncd_defvar calls) - Make sure this goes in an 'if (.not dynlanduse)' conditional, if - appropriate - -- Add code in $CTSMROOT/tools/mksurfdata_map/src/mksurfdat.F90; you need to add the - following: - - add a 'use' statement to use your new regridding routine(s) - - declare array(s) to hold data on the output grid - - add your new mksrf_fxxx and map_fxxx variables to the 'namelist - /clmexp/' declaration - - document your new mksrf_fxxx and map_fxxx variables in the long - comment following the 'namelist /clmexp/' declaration - - add your new array(s) to the allocation statement under the heading - "Allocate and initialize dynamic memory" - - initialize your new array(s) in the initialization section following - the allocation - - add output to ndiag (the log file) documenting your new mksrf_fxxx and - map_fxxx variables - - add call(s) to your new subroutine(s) for regridding the data - - add calls to nf_inq_varid & nf_put_var_double (or nf_put_var_int) for - each new output variable; make sure to put these calls in the section - for dynlanduse = false and/or true, as appropriate - - add a deallocation statement for each new output variable - -- Add your new file in $CTSMROOT/bld/namelist_files/namelist_definition_ctsm.xml; - e.g. (replace xxx with your new field): - - - XXX dataset for mksurfdata - - -- Add your new mksrf_fxxx variable to the list of valid_values for - mksrf_filename in $CTSMROOT/bld/namelist_files/namelist_definition_ctsm.xml - -- Add defaults in $CTSMROOT/bld/namelist_files/namelist_defaults_ctsm_tools.xml; - note that the "type" attribute is a short code that can be used in - mksurfdata.pl, and doesn't have to match the "xxx" that is used elsewhere - - lmask - - hgrid - - mksrf_filename - - mksrf_fxxx (including hgrid and lmask attributes) - -- Add hooks to your new files in $CTSMROOT/tools/mksurfdata_map/mksurfdata.pl: - - add new string in the list following 'foreach my $typ' - - add the new mapping file to clmexp, as in: - map_fxxx = '$map{'xxx'}' - - add the new raw data file to clmexp, as in: - mksrf_fxxx = '$datfil{'xxx'}' - -- Add new raw data file to the inputdata repository: lnd/clm2/rawdata - - locally - - check in to the inputdata svn repository - -- Add documentation for your new mksrf_fxxx in $CTSMROOT/doc/UsersGuide/tools.xml - -============================================================================ -II. Adding mapping files for a raw data file with a new grid / landmask -============================================================================ - -If your raw data file is on a new grid, or just has a new landmask on an -existing grid, you will need to perform a number of additional steps, as -laid out here. - -- First, move your data file to the inputdata directory and give it its - final name. (This will ensure that the appropriate metadata is put in the - SCRIP grid file.) - -- Make a scrip grid file from your data file using mkmapgrids, and move it - to the inputdata directory - -- Add a scripgriddata entry for the new scrip grid file in - $CTSMROOT/bld/namelist_files/namelist_defaults_ctsm_tools.xml - -- If necessary, add other entries in - $CTSMROOT/bld/namelist_files/namelist_defaults_ctsm_tools.xml giving information about your - scrip grid file: - - If this is a high resolution grid (e.g., 3min or higher), add a - scripgriddata_lrgfile_needed entry, saying we need 64bit_offset - (or netcdf4) support for mapping files made with this scrip grid - file - - If the grid file is in UGRID format rather than SCRIP grid - format, add scripgriddata_type and scripgriddata_meshname - entries. If you don't know what I'm talking about, then your - grid file is in SCRIP format and you can ignore this. - -- If necessary, add new grid and/or landmask to lists of valid values for - hgrid, res and lmask in $CTSMROOT/bld/namelist_files/namelist_definition_ctsm.xml - - Note that a new resolution currently needs to be added to both the hgrid - and res lists of valid values, although in the future this - should probably be changed so that these raw data grids just - appear in hgrid - -- Add the new grid-landmask combo to the 'mapgrids' list in - $CTSMROOT/bld/namelist_files/checkmapfiles.ncl - -- Add the new grid-landmask combo to the 'grids' list in - $CTSMROOT/tools/shared/mkmapdata/mkmapdata.sh (in the clm4_5 branch of the - conditional) - -- Make mapping files, from $CTSMROOT/tools/shared/mkmapdata - - Modify mkmapdata.sh: - - edit the grids list so it only contains your new grid - - Modify regridbatch.sh as desired, e.g.: - - project number - - number of processors (BSUB -n line, span, and the regrid_num_proc setting) - - wall-clock limit - - if ESMFBIN_PATH is in your environment, you may want to unset it; - this can be important to allow mkmapdata.sh choose a different - executable for mpi vs serial runs - - if you renamed the mkmapdata.sh script, be sure to call the - renamed script at the bottom of regridbatch.sh - - Submit regridbatch.sh - -- When mapping files have all been created, run createXMLEntries.pl from - $CTSMROOT/tools/shared/mkmapdata (usage: just run the script with no arguments) - -- Cut and paste the xml entries from mapping_entries.txt (created by - createXMLEntries.pl) into $CTSMROOT/bld/namelist_files/namelist_defaults_ctsm.xml, - in the correct locations - -- Move mapping files to correct location, either using mv_cmds.sh created by - createXMLEntries.pl, or using $CTSMROOT/tools/shared/mkmapdata/mvNimport.sh. - - Note that the latter also imports to the inputdata directory; if you - don't use that, you'll need to add the files to the inputdata - directory yourself - - -============================================================================ -III. Checks that should be done when making new surface datasets -============================================================================ - -Remaking all surface datasets carries the risk of introducing unintended -changes, particularly when you are expecting answer changes (so you -don't notice unintended answer changes that are mixed with the expected -changes). - -Here are some things to check after making a new set of surface -datasets: - -- For at least one global dataset (probably a production resolution - rather than a low resolution that is just used for testing): Compare - the new dataset against the previous version: - - - Compare header (via ncdump -h) and/or log file: ensure that the same - source data were used, except where you expect differences - - - Compare all fields with a tool like cprnc: make sure that the only - fields that differ are those you expect to differ - - - Visually compare all fields that differ: make sure differences look - reasonable and as expected - -And here are some things to check for when making new landuse.timeseries -datasets (which often happens at the same time, and most of the above applies -as well): - -- Compare one of the production resolution datasets to a previous version. - - - If part of it should be identical (for example the historical period) make - sure it is identical as expected (using cprnc make sure the historical period - is identical and only the future scenario changes). - - - If the historical period should be identical, make sure the 1850 surface dataset - created is identical to the previous one. - - - Visually compare all fields/times that differ: make sure differences look - reasonable and as expected. Go through at least the first and last time to see - that the change in time is as expected. - - - Quickly going through the time differences for at least one field that changes - can also be useful to see that there isn't a sudden jump for a particular time. - - - Go through the list of raw PFT files that were used to create the dataset and make - sure it appears to be correct (ncdump -v input_pftdata_filename) diff --git a/tools/mksurfdata_map/mksurfdata.pl b/tools/mksurfdata_map/mksurfdata.pl deleted file mode 100755 index b0363704ae..0000000000 --- a/tools/mksurfdata_map/mksurfdata.pl +++ /dev/null @@ -1,881 +0,0 @@ -#!/usr/bin/env perl -# -# Oct/30/2008 Erik Kluzek -# -# mksurfdata.pl Perl script to make surface datasets for all resolutions. -# -# -use Cwd; -use strict; -use English; -use IO::File; -use Getopt::Long; - - -#Figure out where configure directory is and where can use the XML/Lite module from -my $ProgName; -($ProgName = $PROGRAM_NAME) =~ s!(.*)/!!; # name of program -my $ProgDir = $1; # name of directory where program lives - -my $cwd = getcwd(); # current working directory -my $scrdir; - -if ($ProgDir) { $scrdir = $ProgDir; } -else { $scrdir = $cwd; } - -my $debug = 0; - -#----------------------------------------------------------------------------------------------- -# Add $scrdir to the list of paths that Perl searches for modules -my @dirs = ( "$scrdir/../../cime/utils/perl5lib", - "$scrdir/../../../../cime/utils/perl5lib" - ); -unshift @INC, @dirs; -my $result = eval "require XML::Lite"; -if ( ! defined($result) ) { - die <<"EOF"; -** Cannot find perl module \"XML/Lite.pm\" from directories: @dirs ** -EOF -} -my $result = eval "require Build::NamelistDefinition"; -if ( ! defined($result) ) { - die <<"EOF"; -** Cannot find perl module \"Build/NamelistDefinition.pm\" from directories: @dirs ** -EOF -} -my $nldef_file = "$scrdir/../../bld/namelist_files/namelist_definition_ctsm.xml"; - -my $definition = Build::NamelistDefinition->new( $nldef_file ); - -my $CSMDATA = "/glade/p/cesm/cseg/inputdata"; - -my %opts = ( - hgrid=>"all", - vic=>0, - glc=>0, - ssp_rcp=>"hist", - debug=>0, - exedir=>undef, - allownofile=>undef, - crop=>1, - fast_maps=>0, - hirespft=>undef, - years=>"1850,2000", - glc_nec=>10, - merge_gis=>undef, - inlandwet=>undef, - help=>0, - no_surfdata=>0, - pft_override=>undef, - pft_frc=>undef, - pft_idx=>undef, - soil_override=>undef, - soil_cly=>undef, - soil_snd=>undef, - soil_col=>undef, - soil_fmx=>undef, - outnc_double=>undef, - outnc_dims=>"2", - usrname=>"", - rundir=>"$cwd", - usr_mapdir=>"../mkmapdata", - dynpft=>undef, - csmdata=>$CSMDATA, - urban_skip_abort_on_invalid_data_check=>undef, - ); - -my $numpft = 78; - -#----------------------------------------------------------------------------------------------- -sub usage { - die < [OPTIONS] - -res [or -r] "resolution" is the supported resolution(s) to use for files (by default $opts{'hgrid'} ). - - - For unsupported, user-specified resolutions: - $ProgName -res usrspec -usr_gname -usr_gdate [OPTIONS] - -usr_gname "user_gname" User resolution name to find grid file with - (only used if -res is set to 'usrspec') - -usr_gdate "user_gdate" User map date to find mapping files with - (only used if -res is set to 'usrspec') - NOTE: all mapping files are assumed to be in mkmapdata - - and the user needs to have invoked mkmapdata in - that directory first - -usr_mapdir "mapdirectory" Directory where the user-supplied mapping files are - Default: $opts{'usr_mapdir'} - -OPTIONS - NOTE: The three critical options are (-years, -glc_nec, and -ssp_rcp) they are marked as such. - - -allownofile Allow the script to run even if one of the input files - does NOT exist. - -dinlc [or -l] Enter the directory location for inputdata - (default $opts{'csmdata'}) - -debug [or -d] Do not actually run -- just print out what - would happen if ran. - -dynpft "filename" Dynamic PFT/harvesting file to use if you have a manual list you want to use - (rather than create it on the fly, must be consistent with first year) - (Normally NOT used) - -fast_maps Toggle fast mode which doesn't use the large mapping files - -glc_nec "number" Number of glacier elevation classes to use (by default $opts{'glc_nec'}) - (CRITICAL OPTION) - -merge_gis If you want to use the glacier dataset that merges in - the Greenland Ice Sheet data that CISM uses (typically - used only if consistency with CISM is important) - -hirespft If you want to use the high-resolution pft dataset rather - than the default lower resolution dataset - (low resolution is at half-degree, high resolution at 3minute) - (hires only available for present-day [2000]) - -exedir "directory" Directory where mksurfdata_map program is - (by default assume it is in the current directory) - -inlandwet If you want to allow inland wetlands - -no-crop Create datasets without the extensive list of prognostic crop types - -no_surfdata Do not output a surface dataset - This is useful if you only want a landuse_timeseries file - -years [or -y] "years" Simulation year(s) to run over (by default $opts{'years'}) - (can also be a simulation year range: i.e. 1850-2000 or 1850-2100 for ssp_rcp future scenarios) - (CRITICAL OPTION) - -help [or -h] Display this help. - - -rundir "directory" Directory to run in - (by default current directory $opts{'rundir'}) - - -ssp_rcp "scenario-name" Shared Socioeconomic Pathway and Representative Concentration Pathway Scenario name(s). - "hist" for historical, otherwise in form of SSPn-m.m where n is the SSP number - and m.m is the radiative forcing in W/m^2 at the peak or 2100. - (normally use thiw with -years 1850-2100) - (CRITICAL OPTION) - - -usrname "clm_usrdat_name" CLM user data name to find grid file with. - - -vic Add the fields required for the VIC model - -glc Add the optional 3D glacier fields for verification of the glacier model - - NOTE: years, res, and ssp_rcp can be comma delimited lists. - - -OPTIONS to override the mapping of the input gridded data with hardcoded input - - -pft_frc "list of fractions" Comma delimited list of percentages for veg types - -pft_idx "list of veg index" Comma delimited veg index for each fraction - -soil_cly "% of clay" % of soil that is clay - -soil_col "soil color" Soil color (1 [light] to 20 [dark]) - -soil_fmx "soil fmax" Soil maximum saturated fraction (0-1) - -soil_snd "% of sand" % of soil that is sand - -OPTIONS to work around bugs? - -urban_skip_abort_on_invalid_data_check - do not abort on an invalid data check in urban. - Added 2015-01 to avoid recompiling as noted in - /glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 - -EOF -} - -sub check_soil { -# -# check that the soil options are set correctly -# - foreach my $type ( "soil_cly", "soil_snd" ) { - if ( ! defined($opts{$type} ) ) { - die "ERROR: Soil variables were set, but $type was NOT set\n"; - } - } - #if ( $opts{'soil_col'} < 0 || $opts{'soil_col'} > 20 ) { - # die "ERROR: Soil color is out of range = ".$opts{'soil_col'}."\n"; - #} - my $texsum = $opts{'soil_cly'} + $opts{'soil_snd'}; - my $loam = 100.0 - $texsum; - if ( $texsum < 0.0 || $texsum > 100.0 ) { - die "ERROR: Soil textures are out of range: clay = ".$opts{'soil_cly'}. - " sand = ".$opts{'soil_snd'}." loam = $loam\n"; - } -} - -sub check_soil_col_fmx { -# -# check that the soil color or soil fmax option is set correctly -# - if ( defined($opts{'soil_col'}) ) { - if ( $opts{'soil_col'} < 0 || $opts{'soil_col'} > 20 ) { - die "ERROR: Soil color is out of range = ".$opts{'soil_col'}."\n"; - } - } - if ( defined($opts{'soil_fmx'}) ) { - if ( $opts{'soil_fmx'} < 0.0 || $opts{'soil_fmx'} > 1.0 ) { - die "ERROR: Soil fmax is out of range = ".$opts{'soil_fmx'}."\n"; - } - } -} - -sub check_pft { -# -# check that the pft options are set correctly -# - # Eliminate starting and ending square brackets - $opts{'pft_idx'} =~ s/^\[//; - $opts{'pft_idx'} =~ s/\]$//; - $opts{'pft_frc'} =~ s/^\[//; - $opts{'pft_frc'} =~ s/\]$//; - foreach my $type ( "pft_idx", "pft_frc" ) { - if ( ! defined($opts{$type} ) ) { - die "ERROR: PFT variables were set, but $type was NOT set\n"; - } - } - my @pft_idx = split( /,/, $opts{'pft_idx'} ); - my @pft_frc = split( /,/, $opts{'pft_frc'} ); - if ( $#pft_idx != $#pft_frc ) { - die "ERROR: PFT arrays are different sizes: pft_idx and pft_frc\n"; - } - my $sumfrc = 0.0; - for( my $i = 0; $i <= $#pft_idx; $i++ ) { - # check index in range - if ( $pft_idx[$i] < 0 || $pft_idx[$i] > $numpft ) { - die "ERROR: pft_idx out of range = ".$opts{'pft_idx'}."\n"; - } - # make sure there are no duplicates - for( my $j = 0; $j < $i; $j++ ) { - if ( $pft_idx[$i] == $pft_idx[$j] ) { - die "ERROR: pft_idx has duplicates = ".$opts{'pft_idx'}."\n"; - } - } - # check fraction in range - if ( $pft_frc[$i] <= 0.0 || $pft_frc[$i] > 100.0 ) { - die "ERROR: pft_frc out of range (>0.0 and <=100.0) = ".$opts{'pft_frc'}."\n"; - } - $sumfrc = $sumfrc + $pft_frc[$i]; - } - # check that fraction sums up to 100% - if ( abs( $sumfrc - 100.0) > 1.e-6 ) { - die "ERROR: pft_frc does NOT add up to 100% = ".$opts{'pft_frc'}."\n"; - } - -} - -# Perl trim function to remove whitespace from the start and end of the string -sub trim($) -{ - my $string = shift; - $string =~ s/^\s+//; - $string =~ s/\s+$//; - return $string; -} - -sub write_transient_timeseries_file { - my ($transient, $desc, $sim_yr0, $sim_yrn, $queryfilopts, $resol, $resolhrv, $ssp_rcp, $mkcrop, $sim_yr_surfdat) = @_; - - my $strlen = 195; - my $dynpft_format = "%-${strlen}.${strlen}s %4.4d\n"; - my $landuse_timeseries_text_file = ""; - if ( $transient ) { - if ( ! defined($opts{'dynpft'}) && ! $opts{'pft_override'} ) { - $landuse_timeseries_text_file = "landuse_timeseries_$desc.txt"; - my $fh_landuse_timeseries = IO::File->new; - $fh_landuse_timeseries->open( ">$landuse_timeseries_text_file" ) or die "** can't open file: $landuse_timeseries_text_file\n"; - print "Writing out landuse_timeseries text file: $landuse_timeseries_text_file\n"; - for( my $yr = $sim_yr0; $yr <= $sim_yrn; $yr++ ) { - my $vegtypyr = `$scrdir/../../bld/queryDefaultNamelist.pl $queryfilopts $resol -options sim_year='$yr',ssp_rcp=${ssp_rcp}${mkcrop} -var mksrf_fvegtyp -namelist clmexp`; - chomp( $vegtypyr ); - printf $fh_landuse_timeseries $dynpft_format, $vegtypyr, $yr; - my $hrvtypyr = `$scrdir/../../bld/queryDefaultNamelist.pl $queryfilopts $resolhrv -options sim_year='$yr',ssp_rcp=${ssp_rcp}${mkcrop} -var mksrf_fvegtyp -namelist clmexp`; - chomp( $hrvtypyr ); - printf $fh_landuse_timeseries $dynpft_format, $hrvtypyr, $yr; - if ( $yr % 100 == 0 ) { - print "year: $yr\n"; - } - } - $fh_landuse_timeseries->close; - print "Done writing file\n"; - } elsif ( $opts{'pft_override'} && defined($opts{'dynpft'}) ) { - $landuse_timeseries_text_file = $opts{'dynpft'}; - } else { - $landuse_timeseries_text_file = "landuse_timeseries_override_$desc.txt"; - my $fh_landuse_timeseries = IO::File->new; - $fh_landuse_timeseries->open( ">$landuse_timeseries_text_file" ) or die "** can't open file: $landuse_timeseries_text_file\n"; - my $frstpft = "$opts{'pft_frc'}" . - "$opts{'pft_idx'}" . - "0,0,0,0,00"; - print "Writing out landuse_timeseries text file: $landuse_timeseries_text_file\n"; - if ( (my $len = length($frstpft)) > $strlen ) { - die "ERROR PFT line is too long ($len): $frstpft\n"; - } - # NOTE(wjs, 2014-12-04) Using sim_yr_surfdat here rather than - # sim_yr0. As far as I can tell, it seems somewhat arbitrary which one - # we use, but sim_yr_surfdat seems more like what's intended. - printf $fh_landuse_timeseries $dynpft_format, $frstpft, $sim_yr_surfdat; - $fh_landuse_timeseries->close; - print "Done writing file\n"; - } - } - return $landuse_timeseries_text_file; -} - -sub write_namelist_file { - my ($namelist_fname, $logfile_fname, $fsurdat_fname, $fdyndat_fname, - $glc_nec, $griddata, $gridtype, $map, $datfil, $double, - $all_urb, $no_inlandwet, $vegtyp, $hrvtyp, - $landuse_timeseries_text_file, $setnumpft) = @_; - - - my $gitdescribe = `cd $scrdir; git describe; cd -`; - chomp( $gitdescribe ); - my $fh = IO::File->new; - $fh->open( ">$namelist_fname" ) or die "** can't open file: $namelist_fname\n"; - print $fh <<"EOF"; -&clmexp - nglcec = $glc_nec - mksrf_fgrid = '$griddata' - mksrf_gridtype = '$gridtype' - map_fpft = '$map->{'veg'}' - map_fglacier = '$map->{'glc'}' - map_fglacierregion = '$map->{'glcregion'}' - map_fsoicol = '$map->{'col'}' - map_furban = '$map->{'urb'}' - map_fmax = '$map->{'fmx'}' - map_forganic = '$map->{'org'}' - map_flai = '$map->{'lai'}' - map_fharvest = '$map->{'hrv'}' - map_flakwat = '$map->{'lak'}' - map_fwetlnd = '$map->{'wet'}' - map_fvocef = '$map->{'voc'}' - map_fsoitex = '$map->{'tex'}' - map_furbtopo = '$map->{'utp'}' - map_fgdp = '$map->{'gdp'}' - map_fpeat = '$map->{'peat'}' - map_fsoildepth = '$map->{'soildepth'}' - map_fabm = '$map->{'abm'}' - mksrf_fsoitex = '$datfil->{'tex'}' - mksrf_forganic = '$datfil->{'org'}' - mksrf_flakwat = '$datfil->{'lak'}' - mksrf_fwetlnd = '$datfil->{'wet'}' - mksrf_fmax = '$datfil->{'fmx'}' - mksrf_fglacier = '$datfil->{'glc'}' - mksrf_fglacierregion = '$datfil->{'glcregion'}' - mksrf_fvocef = '$datfil->{'voc'}' - mksrf_furbtopo = '$datfil->{'utp'}' - mksrf_fgdp = '$datfil->{'gdp'}' - mksrf_fpeat = '$datfil->{'peat'}' - mksrf_fsoildepth = '$datfil->{'soildepth'}' - mksrf_fabm = '$datfil->{'abm'}' - outnc_double = $double - all_urban = $all_urb - no_inlandwet = $no_inlandwet - mksrf_furban = '$datfil->{'urb'}' - gitdescribe = '$gitdescribe' -EOF - if ( $opts{'vic'} ) { - print $fh <<"EOF"; - map_fvic = '$map->{'vic'}' - mksrf_fvic = '$datfil->{'vic'}' - outnc_vic = .true. -EOF - } - if ( $opts{'glc'} ) { - print $fh <<"EOF"; - outnc_3dglc = .true. -EOF - } - if ( $opts{'glc'} ) { - print $fh <<"EOF"; - outnc_3dglc = .true. -EOF - } - if ( ! $opts{'fast_maps'} ) { - print $fh <<"EOF"; - map_ftopostats = '$map->{'topostats'}' - mksrf_ftopostats = '$datfil->{'topostats'}' -EOF - } else { - print $fh <<"EOF"; - std_elev = 371.0d00 -EOF - } - if ( defined($opts{'soil_override'}) ) { - print $fh <<"EOF"; - soil_clay = $opts{'soil_cly'} - soil_sand = $opts{'soil_snd'} -EOF - } - if ( defined($opts{'pft_override'}) ) { - print $fh <<"EOF"; - all_veg = .true. - pft_frc = $opts{'pft_frc'} - pft_idx = $opts{'pft_idx'} -EOF - } - - print $fh <<"EOF"; - mksrf_fvegtyp = '$vegtyp' - mksrf_fhrvtyp = '$hrvtyp' - mksrf_fsoicol = '$datfil->{'col'}' - mksrf_flai = '$datfil->{'lai'}' -EOF - - # Note that some of the file names in the following may be empty strings - # (except for logfile_fname) - print $fh <<"EOF"; - fsurdat = '$fsurdat_fname' - fsurlog = '$logfile_fname' - mksrf_fdynuse = '$landuse_timeseries_text_file' - fdyndat = '$fdyndat_fname' -EOF - - if ( $setnumpft ) { - print $fh <<"EOF"; - $setnumpft -EOF - } - - if ( $opts{'urban_skip_abort_on_invalid_data_check'} ) { - print $fh <<"EOF"; - urban_skip_abort_on_invalid_data_check = .true. -EOF - } - # end the namelist - print $fh <<"EOF"; -/ -EOF - - $fh->close; - # - # Print namelist file - $fh->open( "<$namelist_fname" ) or die "** can't open file: $namelist_fname\n"; - while( $_ = <$fh> ) { - print $_; - } - $fh->close; -} - -#----------------------------------------------------------------------------------------------- - - my $cmdline = "@ARGV"; - GetOptions( - "allownofile" => \$opts{'allownofile'}, - "r|res=s" => \$opts{'hgrid'}, - "usr_gname=s" => \$opts{'usr_gname'}, - "usr_gdate=s" => \$opts{'usr_gdate'}, - "usr_mapdir=s" => \$opts{'usr_mapdir'}, - "crop!" => \$opts{'crop'}, - "hirespft" => \$opts{'hirespft'}, - "l|dinlc=s" => \$opts{'csmdata'}, - "d|debug" => \$opts{'debug'}, - "fast_maps" => \$opts{'fast_maps'}, - "dynpft=s" => \$opts{'dynpft'}, - "y|years=s" => \$opts{'years'}, - "exedir=s" => \$opts{'exedir'}, - "h|help" => \$opts{'help'}, - "usrname=s" => \$opts{'usrname'}, - "glc_nec=i" => \$opts{'glc_nec'}, - "merge_gis" => \$opts{'merge_gis'}, - "inlandwet" => \$opts{'inlandwet'}, - "no_surfdata" => \$opts{'no_surfdata'}, - "pft_frc=s" => \$opts{'pft_frc'}, - "pft_idx=s" => \$opts{'pft_idx'}, - "ssp_rcp=s" => \$opts{'ssp_rcp'}, - "vic!" => \$opts{'vic'}, - "glc!" => \$opts{'glc'}, - "rundir=s" => \$opts{'rundir'}, - "soil_col=i" => \$opts{'soil_col'}, - "soil_fmx=f" => \$opts{'soil_fmx'}, - "soil_cly=f" => \$opts{'soil_cly'}, - "soil_snd=f" => \$opts{'soil_snd'}, - "urban_skip_abort_on_invalid_data_check" => \$opts{'urban_skip_abort_on_invalid_data_check'}, - ) or usage(); - - # Check for unparsed arguments - if (@ARGV) { - print "ERROR: unrecognized arguments: @ARGV\n"; - usage(); - } - if ( $opts{'help'} ) { - usage(); - } - - chdir( $opts{'rundir'} ) or die "** can't change to directory: $opts{'rundir'}\n"; - # If csmdata was changed from the default - if ( $CSMDATA ne $opts{'csmdata'} ) { - $CSMDATA = $opts{'csmdata'}; - } - my $glc_nec = $opts{'glc_nec'}; - if ( $glc_nec <= 0 ) { - print "** glc_nec must be at least 1\n"; - usage(); - } - my $no_inlandwet = ".true."; - if (defined($opts{'inlandwet'})) { - $no_inlandwet = ".false."; - } - # - # Set disk location to send files to, and list resolutions to operate over, - # set filenames, and short-date-name - # - my @hresols; - my $mapdate; - if ( $opts{'hgrid'} eq "all" ) { - my @all_hresols = $definition->get_valid_values( "res" ); - @hresols = @all_hresols; - } elsif ( $opts{'hgrid'} eq "usrspec" ) { - @hresols = $opts{'usr_gname'}; - $mapdate = $opts{'usr_gdate'}; - } else { - @hresols = split( ",", $opts{'hgrid'} ); - # Check that resolutions are valid - foreach my $res ( @hresols ) { - if ( ! $definition->is_valid_value( "res", "'$res'" ) ) { - if ( $opts{'usrname'} eq "" || $res ne $opts{'usrname'} ) { - print "** Invalid resolution: $res\n"; - usage(); - } - } - } - } - # - # Set years to run over - # - my @years = split( ",", $opts{'years'} ); - # Check that resolutions are valid - foreach my $sim_year ( @years ) { - if ( ("-" eq substr($sim_year, 4, 1)) || ("-" eq substr($sim_year, 3, 1)) ) { - # range of years for transient run - if ( ! $definition->is_valid_value( "sim_year_range", "'$sim_year'" ) ) { - print "** Invalid simulation simulation year range: $sim_year\n"; - usage(); - } - } else { - # single year. - if ( ! $definition->is_valid_value( "sim_year", "'$sim_year'" ) ) { - print "** Invalid simulation year: $sim_year\n"; - usage(); - } - } - } - # - # Set ssp_rcp to use - # - my @rcpaths = split( ",", $opts{'ssp_rcp'} ); - # Check that ssp_rcp is valid - foreach my $ssp_rcp ( @rcpaths ) { - if ( ! $definition->is_valid_value( "ssp_rcp", "'$ssp_rcp'" ) ) { - print "** Invalid ssp_rcp: $ssp_rcp\n"; - usage(); - } - } - - # CMIP series input data is corresponding to - my $cmip_series = "CMIP6"; - # Check if soil set - if ( defined($opts{'soil_cly'}) || - defined($opts{'soil_snd'}) ) { - &check_soil( ); - $opts{'soil_override'} = 1; - } - # Check if pft set - if ( ! $opts{'crop'} ) { $numpft = 16; } # First set numpft if crop is off - if ( defined($opts{'pft_frc'}) || defined($opts{'pft_idx'}) ) { - &check_pft( ); - $opts{'pft_override'} = 1; - } - # Check if dynpft set and is valid filename - if ( defined($opts{'dynpft'}) ) { - if ( ! -f $opts{'dynpft'} ) { - print "** Dynamic PFT file does NOT exist: $opts{'dynpft'}\n"; - usage(); - } - } - - my $sdate = "c" . `date +%y%m%d`; - chomp( $sdate ); - - my $cfile = "clm.input_data_list"; - if ( -f "$cfile" ) { - `/bin/mv -f $cfile ${cfile}.previous`; - } - my $cfh = IO::File->new; - $cfh->open( ">$cfile" ) or die "** can't open file: $cfile\n"; - system( "\rm -f $cfile" ); - system( "touch $cfile" ); - print $cfh <<"EOF"; -#! /bin/csh -f -set CSMDATA = $CSMDATA -EOF - system( "chmod +x $cfile" ); - my $surfdir = "lnd/clm2/surfdata"; - - # string to add to options for crop off or on - my $mkcrop_off = ",crop='on'"; - my $mkcrop_on = ",crop='on'"; - - # - # Loop over all resolutions and sim-years listed - # - foreach my $res ( @hresols ) { - # - # Query the XML default file database to get the appropriate files - # - my $queryopts, my $queryfilopts; - if ( $opts{'hgrid'} eq "usrspec" ) { - $queryopts = "-csmdata $CSMDATA -silent -justvalue"; - } else { - $queryopts = "-res $res -csmdata $CSMDATA -silent -justvalue"; - } - $queryfilopts = "$queryopts -onlyfiles "; - my $mkcrop = $mkcrop_off; - my $setnumpft = ""; - $mkcrop = $mkcrop_on; - $setnumpft = "numpft = $numpft"; - my $usrnam = ""; - if ( $opts{'usrname'} ne "" && $res eq $opts{'usrname'} ) { - $usrnam = "-usrname ".$opts{'usrname'}; - } - # - # Mapping files - # - my %map; my %hgrd; my %lmsk; my %datfil; my %filnm; - my $hirespft = "off"; - if ( defined($opts{'hirespft'}) ) { - $hirespft = "on"; - } - my $merge_gis = "off"; - if ( defined($opts{'merge_gis'}) ) { - $merge_gis = "on"; - } - my $mopts = "$queryopts -namelist default_settings $usrnam"; - my $mkopts = "-csmdata $CSMDATA -silent -justvalue -namelist clmexp $usrnam"; - my @typlist = ( "lak", "veg", "voc", "tex", "col", "hrv", - "fmx", "lai", "urb", "org", "glc", "glcregion", "utp", "wet", - "gdp", "peat","soildepth","abm"); - if ( $opts{'vic'} ) { - push( @typlist, "vic" ); - } - if ( ! $opts{'fast_maps'} ) { - push( @typlist, "topostats" ); - } - foreach my $typ ( @typlist ) { - my $lmask = `$scrdir/../../bld/queryDefaultNamelist.pl $mopts -options type=$typ,mergeGIS=$merge_gis,hirespft=$hirespft -var lmask`; - $lmask = trim($lmask); - my $hgrid_cmd = "$scrdir/../../bld/queryDefaultNamelist.pl $mopts -options type=$typ,hirespft=$hirespft -var hgrid"; - my $hgrid = `$hgrid_cmd`; - if ($debug) { - print "query to determine hgrid:\n $hgrid_cmd \n\n"; - } - $hgrid = trim($hgrid); - my $filnm = `$scrdir/../../bld/queryDefaultNamelist.pl $mopts -options type=$typ -var mksrf_filename`; - $filnm = trim($filnm); - $filnm{$typ} = $filnm; - $hgrd{$typ} = $hgrid; - $lmsk{$typ} = $lmask; - if ( $opts{'hgrid'} eq "usrspec" ) { - $map{$typ} = $opts{'usr_mapdir'}."/map_${hgrid}_${lmask}_to_${res}_nomask_aave_da_c${mapdate}\.nc"; - } else { - $map{$typ} = `$scrdir/../../bld/queryDefaultNamelist.pl $queryfilopts -namelist clmexp -options frm_hgrid=$hgrid,frm_lmask=$lmask,to_hgrid=$res,to_lmask=nomask -var map`; - } - $map{$typ} = trim($map{$typ}); - if ( $map{$typ} !~ /[^ ]+/ ) { - die "ERROR: could NOT find a mapping file for this resolution: $res and type: $typ at $hgrid and $lmask.\n"; - } - if ( ! defined($opts{'allownofile'}) && ! -f $map{$typ} ) { - die "ERROR: mapping file for this resolution does NOT exist ($map{$typ}).\n"; - } - } - # - # Grid file from the pft map file or grid if not found - # - my $griddata = trim($map{'veg'}); - if ( $griddata eq "" ) { - $griddata = `$scrdir/../../bld/queryDefaultNamelist.pl $queryfilopts $usrnam -var fatmgrid`; - if ( $griddata eq "" ) { - die "ERROR: could NOT find a grid data file for this resolution: $res.\n"; - } - } - my $desc; - my $desc_surfdat; - # - # Check if all urban single point dataset - # - my @all_urb = ( "1x1_vancouverCAN", "1x1_mexicocityMEX", "1x1_urbanc_alpha" ); - my $all_urb = ".false."; - my $urb_pt = 0; - foreach my $urb_res ( @all_urb ) { - if ( $res eq $urb_res ) { - $all_urb = ".true."; - $urb_pt = 1; - } - } - # - # Always run at double precision for output - # - my $double = ".true."; - # - # Loop over each SSP-RCP scenario - # - RCP: foreach my $ssp_rcp ( @rcpaths ) { - # - # Loop over each sim_year - # - SIM_YEAR: foreach my $sim_year ( @years ) { - # - # Skip if urban unless sim_year=2000 - # - if ( $urb_pt && $sim_year ne '2000' ) { - print "For urban -- skip this simulation year = $sim_year\n"; - next SIM_YEAR; - } - # - # If year is 1850-2000 actually run 1850-2015 - # - if ( $sim_year eq "1850-2000" ) { - my $actual = "1850-2015"; - print "For $sim_year actually run $actual\n"; - $sim_year = $actual; - } - my $urbdesc = "urb3den"; - my $resol = "-res $hgrd{'veg'}"; - my $resolhrv = "-res $hgrd{'hrv'}"; - my $sim_yr0 = $sim_year; - my $sim_yrn = $sim_year; - my $transient = 0; - if ( $sim_year =~ /([0-9]+)-([0-9]+)/ ) { - $sim_yr0 = $1; - $sim_yrn = $2; - $transient = 1; - } - # - # Find the file for each of the types - # - foreach my $typ ( @typlist ) { - my $hgrid = $hgrd{$typ}; - my $lmask = $lmsk{$typ}; - my $filnm = $filnm{$typ}; - my $typ_cmd = "$scrdir/../../bld/queryDefaultNamelist.pl $mkopts -options " . - "hgrid=$hgrid,lmask=$lmask,mergeGIS=$merge_gis$mkcrop,sim_year=$sim_yr0 -var $filnm"; - $datfil{$typ} = `$typ_cmd`; - $datfil{$typ} = trim($datfil{$typ}); - if ( $datfil{$typ} !~ /[^ ]+/ ) { - die "ERROR: could NOT find a $filnm data file for this resolution: $hgrid and type: $typ and $lmask.\n$typ_cmd\n\n"; - } - if ( ! defined($opts{'allownofile'}) && ! -f $datfil{$typ} ) { - die "ERROR: data file for this resolution does NOT exist ($datfil{$typ}).\n"; - } - } - # determine simulation year to use for the surface dataset: - my $sim_yr_surfdat = "$sim_yr0"; - - my $cmd = "$scrdir/../../bld/queryDefaultNamelist.pl $queryfilopts $resol -options sim_year='${sim_yr_surfdat}'$mkcrop,ssp_rcp=${ssp_rcp}${mkcrop} -var mksrf_fvegtyp -namelist clmexp"; - my $vegtyp = `$cmd`; - chomp( $vegtyp ); - if ( $vegtyp eq "" ) { - die "** trouble getting vegtyp file with: $cmd\n"; - } - my $cmd = "$scrdir/../../bld/queryDefaultNamelist.pl $queryfilopts $resolhrv -options sim_year='${sim_yr_surfdat}'$mkcrop,ssp_rcp=${ssp_rcp}${mkcrop} -var mksrf_fvegtyp -namelist clmexp"; - my $hrvtyp = `$cmd`; - chomp( $hrvtyp ); - if ( $hrvtyp eq "" ) { - die "** trouble getting hrvtyp file with: $cmd\n"; - } - my $options = ""; - my $crpdes = sprintf("%2.2dpfts", $numpft); - if ( $numpft == 16 ) { - $crpdes .= "_Irrig"; - } - if ( $mkcrop ne "" ) { - $options = "-options $mkcrop"; - } - $desc = sprintf( "%s_%s_%s_simyr%s-%4.4d", $ssp_rcp, $crpdes, $cmip_series, $sim_yr0, $sim_yrn ); - $desc_surfdat = sprintf( "%s_%s_%s_simyr%s", $ssp_rcp, $crpdes, $cmip_series, $sim_yr_surfdat ); - - my $fsurdat_fname_base = ""; - my $fsurdat_fname = ""; - if ( ! $opts{'no_surfdata'} ) { - $fsurdat_fname_base = "surfdata_${res}_${desc_surfdat}_${sdate}"; - $fsurdat_fname = "${fsurdat_fname_base}.nc"; - } - - my $fdyndat_fname_base = ""; - my $fdyndat_fname = ""; - if ($transient) { - $fdyndat_fname_base = "landuse.timeseries_${res}_${desc}_${sdate}"; - $fdyndat_fname = "${fdyndat_fname_base}.nc"; - } - - if (!$fsurdat_fname && !$fdyndat_fname) { - die("ERROR: Tried to run mksurfdata_map without creating either a surface dataset or a landuse.timeseries file") - } - - my $logfile_fname; - my $namelist_fname; - if ($fsurdat_fname_base) { - $logfile_fname = "${fsurdat_fname_base}.log"; - $namelist_fname = "${fsurdat_fname_base}.namelist"; - } - else { - $logfile_fname = "${fdyndat_fname_base}.log"; - $namelist_fname = "${fdyndat_fname_base}.namelist"; - } - - my ($landuse_timeseries_text_file) = write_transient_timeseries_file( - $transient, $desc, $sim_yr0, $sim_yrn, - $queryfilopts, $resol, $resolhrv, $ssp_rcp, $mkcrop, - $sim_yr_surfdat); - - print "CSMDATA is $CSMDATA \n"; - print "resolution: $res ssp_rcp=$ssp_rcp sim_year = $sim_year\n"; - print "namelist: $namelist_fname\n"; - - my $gridtype; - $gridtype = "global"; - if (index($res, '1x1_') != -1) { - $gridtype = "regional"; - } - if (index($res, '5x5_amazon') != -1) { - $gridtype = "regional"; - } - - write_namelist_file( - $namelist_fname, $logfile_fname, $fsurdat_fname, $fdyndat_fname, - $glc_nec, $griddata, $gridtype, \%map, \%datfil, $double, - $all_urb, $no_inlandwet, $vegtyp, $hrvtyp, - $landuse_timeseries_text_file, $setnumpft); - - # - # Delete previous versions of files that will be created - # - system( "/bin/rm -f $fsurdat_fname $logfile_fname" ); - # - # Run mksurfdata_map with the namelist file - # - my $exedir = $scrdir; - if ( defined($opts{'exedir'}) ) { - $exedir = $opts{'exedir'}; - } - print "$exedir/mksurfdata_map < $namelist_fname\n"; - if ( ! $opts{'debug'} ) { - system( "$exedir/mksurfdata_map < $namelist_fname" ); - if ( $? ) { die "ERROR in mksurfdata_map: $?\n"; } - } - print "\n===========================================\n\n"; - - # - # If urban point, overwrite urban variables from previous surface dataset to this one - # - if ( $urb_pt && ! $opts{'no_surfdata'} ) { - my $prvsurfdata = `$scrdir/../../bld/queryDefaultNamelist.pl $queryopts -var fsurdat`; - if ( $? != 0 ) { - die "ERROR:: previous surface dataset file NOT found\n"; - } - chomp( $prvsurfdata ); - my $varlist = "CANYON_HWR,EM_IMPROAD,EM_PERROAD,EM_ROOF,EM_WALL,HT_ROOF,THICK_ROOF,THICK_WALL,T_BUILDING_MIN,WIND_HGT_CANYON,WTLUNIT_ROOF,WTROAD_PERV,ALB_IMPROAD_DIR,ALB_IMPROAD_DIF,ALB_PERROAD_DIR,ALB_PERROAD_DIF,ALB_ROOF_DIR,ALB_ROOF_DIF,ALB_WALL_DIR,ALB_WALL_DIF,TK_ROOF,TK_WALL,TK_IMPROAD,CV_ROOF,CV_WALL,CV_IMPROAD,NLEV_IMPROAD,PCT_URBAN,URBAN_REGION_ID"; - print "Overwrite urban parameters with previous surface dataset values\n"; - $cmd = "ncks -A -v $varlist $prvsurfdata $fsurdat_fname"; - print "$cmd\n"; - if ( ! $opts{'debug'} ) { system( $cmd ); } - } - - } # End of sim_year loop - } # End of ssp_rcp loop - } - close( $cfh ); - print "Successfully created fsurdat files\n"; diff --git a/tools/mksurfdata_map/mksurfdata_map.namelist b/tools/mksurfdata_map/mksurfdata_map.namelist deleted file mode 100644 index 4e00ae1805..0000000000 --- a/tools/mksurfdata_map/mksurfdata_map.namelist +++ /dev/null @@ -1,52 +0,0 @@ -&clmexp - nglcec = 10 - mksrf_fgrid = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_0.25x0.25_nomask_to_10x15_nomask_aave_da_c200309.nc' - map_fpft = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_0.25x0.25_nomask_to_10x15_nomask_aave_da_c200309.nc' - map_fglacier = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_3x3min_nomask_to_10x15_nomask_aave_da_c200309.nc' - map_fglacierregion = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_10x10min_nomask_to_10x15_nomask_aave_da_c200206.nc' - map_fsoicol = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_0.25x0.25_nomask_to_10x15_nomask_aave_da_c200309.nc' - map_furban = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_3x3min_nomask_to_10x15_nomask_aave_da_c200309.nc' - map_fmax = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_0.125x0.125_nomask_to_10x15_nomask_aave_da_c200206.nc' - map_forganic = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_5x5min_nomask_to_10x15_nomask_aave_da_c200309.nc' - map_flai = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_0.25x0.25_nomask_to_10x15_nomask_aave_da_c200309.nc' - map_fharvest = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_0.25x0.25_nomask_to_10x15_nomask_aave_da_c200309.nc' - map_flakwat = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_3x3min_nomask_to_10x15_nomask_aave_da_c200309.nc' - map_fwetlnd = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_0.5x0.5_nomask_to_10x15_nomask_aave_da_c200206.nc' - map_fvocef = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_0.5x0.5_nomask_to_10x15_nomask_aave_da_c200206.nc' - map_fsoitex = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_5x5min_nomask_to_10x15_nomask_aave_da_c200309.nc' - map_furbtopo = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_10x10min_nomask_to_10x15_nomask_aave_da_c200206.nc' - map_fgdp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_0.5x0.5_nomask_to_10x15_nomask_aave_da_c200206.nc' - map_fpeat = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_0.5x0.5_nomask_to_10x15_nomask_aave_da_c200206.nc' - map_fsoildepth = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_5x5min_nomask_to_10x15_nomask_aave_da_c200309.nc' - map_fabm = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_0.5x0.5_nomask_to_10x15_nomask_aave_da_c200206.nc' - map_ftopostats = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_1km-merge-10min_HYDRO1K-merge-nomask_to_10x15_nomask_aave_da_c130411.nc' - map_fvic = '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/maps/10x15/map_0.9x1.25_nomask_to_10x15_nomask_aave_da_c200206.nc' - mksrf_fsoitex = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_soitex.10level.c010119.nc' - mksrf_forganic = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_organic_10level_5x5min_ISRIC-WISE-NCSCD_nlev7_c120830.nc' - mksrf_flakwat = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_LakePnDepth_3x3min_simyr2004_csplk_c151015.nc' - mksrf_fwetlnd = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_lanwat.050425.nc' - mksrf_fmax = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_fmax_0.125x0.125_c200220.nc' - mksrf_fglacier = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000.c120926.nc' - mksrf_fglacierregion = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_GlacierRegion_10x10min_nomask_c191120.nc' - mksrf_fvocef = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_vocef_0.5x0.5_simyr2000.c110531.nc' - mksrf_furbtopo = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_topo.10min.c191120.nc' - mksrf_fgdp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_gdp_0.5x0.5_AVHRR_simyr2000.c130228.nc' - mksrf_fpeat = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_peatf_0.5x0.5_AVHRR_simyr2000.c130228.nc' - mksrf_fsoildepth = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksf_soilthk_5x5min_ORNL-Soil_simyr1900-2015_c170630.nc' - mksrf_fabm = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_abm_0.5x0.5_AVHRR_simyr2000.c130201.nc' - mksrf_ftopostats = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_topostats_1km-merge-10min_HYDRO1K-merge-nomask_simyr2000.c130402.nc' - mksrf_fvic = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_vic_0.9x1.25_GRDC_simyr2000.c130307.nc' - outnc_double = .true. - all_urban = .false. - no_inlandwet = .true. - mksrf_furban = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/mksrf_urban_0.05x0.05_simyr2000.c170724.nc' - mksrf_fvegtyp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2000.c170412.nc' - mksrf_fhrvtyp = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_landuse_histclm50_LUH2_2000.c170412.nc' - mksrf_fsoicol = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_soilcolor_simyr2005.c170413.nc' - mksrf_flai = '/glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.c170413.nc' - fsurdat = 'surfdata_10x15_78pfts_simyr2000_c170531.nc' - fsurlog = 'surfdata_10x15_78pfts_simyr2000_c170531.log' - mksrf_fdynuse = '' - fdyndat = '' - numpft = 78 -/ diff --git a/tools/mksurfdata_map/single_point_dynpft_files/README b/tools/mksurfdata_map/single_point_dynpft_files/README deleted file mode 100644 index 04334d4cb2..0000000000 --- a/tools/mksurfdata_map/single_point_dynpft_files/README +++ /dev/null @@ -1,4 +0,0 @@ -$CTSMROOT/tools/mksurfdata_map/single_point_dynpft_files - -This directory contains files that can be used with the -dynpft option to -mksurfdata.pl when creating the respective single-point transient datasets. diff --git a/tools/mksurfdata_map/single_point_dynpft_files/README.landuse_timeseries_smallvilleIA_hist_simyr1850-1855 b/tools/mksurfdata_map/single_point_dynpft_files/README.landuse_timeseries_smallvilleIA_hist_simyr1850-1855 deleted file mode 100644 index 9cc79f0ecd..0000000000 --- a/tools/mksurfdata_map/single_point_dynpft_files/README.landuse_timeseries_smallvilleIA_hist_simyr1850-1855 +++ /dev/null @@ -1,23 +0,0 @@ -The file landuse_timeseries_smallvilleIA_hist_simyr1850-1855.txt is meant for -use with the 1x1_smallvilleIA test case. It tests a number of aspects of -transient crops: - -- It starts with two years of 100% natural veg (1850 & 1851) - -- It then transitions to 100% crop (1852) - -- It then shifts PCT_CFT while keeping PCT_CROP at 100% (1853) - -- It then increases natural veg to > 0, while also shifting PCT_CFT (1854) - -- It then adjusts both PCT_CROP and PCT_CFT (1855) - -To create a surface dataset and transient dataset that use this file: - -mksurfdata.pl -crop -y 1850-2000 -r 1x1_smallvilleIA -pft_idx 13 -pft_frc 100 -dynpft single_point_dynpft_files/landuse_timeseries_smallvilleIA_hist_simyr1850-1855.txt -mv landuse.timeseries_1x1_smallvilleIA_hist_simyr1850-2005_cYYMMDD.nc landuse.timeseries_1x1_smallvilleIA_hist_simyr1850-1855_cYYMMDD.nc - - -This should be run with a transient crop case that starts in 1850 and runs for -at least 6 years. - diff --git a/tools/mksurfdata_map/single_point_dynpft_files/landuse_timeseries_smallvilleIA_hist_simyr1850-1855.txt b/tools/mksurfdata_map/single_point_dynpft_files/landuse_timeseries_smallvilleIA_hist_simyr1850-1855.txt deleted file mode 100644 index f6943e957f..0000000000 --- a/tools/mksurfdata_map/single_point_dynpft_files/landuse_timeseries_smallvilleIA_hist_simyr1850-1855.txt +++ /dev/null @@ -1,6 +0,0 @@ -100130,0,0,0,00 1850 -100130,0,0,0,00 1851 -1,1,1,1,1,1,1,1,1,9115,16,17,18,19,20,21,22,23,240,0,0,0,00 1852 -91,1,1,1,1,1,1,1,1,115,16,17,18,19,20,21,22,23,240,0,0,0,00 1853 -50,1,2,2,3,3,4,4,5,5,2113,15,16,17,18,19,20,21,22,23,240,0,0,0,00 1854 -75,1,1,1,1,1,1,1,1,1,1613,15,16,17,18,19,20,21,22,23,240,0,0,0,00 1855 diff --git a/tools/mksurfdata_map/src/CMakeLists.txt b/tools/mksurfdata_map/src/CMakeLists.txt deleted file mode 100644 index 3179c3cdc9..0000000000 --- a/tools/mksurfdata_map/src/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -# This CMakeLists.txt file is currently used just for building unit tests. - -cmake_minimum_required(VERSION 2.8) -list(APPEND CMAKE_MODULE_PATH ${CIME_CMAKE_MODULE_DIRECTORY}) -include(CIME_initial_setup) - -project(mksurfdat_tests Fortran) - -include(CIME_utils) - -# Build library containing stuff needed for the unit tests -list(APPEND mksurfdat_sources - shr_kind_mod.F90 - shr_log_mod.F90 - nanMod.F90 - shr_string_mod.F90 - fileutils.F90 - shr_timer_mod.F90 - shr_file_mod.F90 - mkgridmapMod.F90 - mkindexmapMod.F90 - mkpftConstantsMod.F90 - mkpctPftTypeMod.F90 - mkpftMod.F90 - mkdomainMod.F90 - mkgridmapMod.F90 - mkutilsMod.F90 - mkpftUtilsMod.F90 - mksoilUtilsMod.F90 - mkvarctl.F90 - mkvarpar.F90 - shr_const_mod.F90 - shr_sys_mod.F90 - unit_test_stubs/abort.F90 - unit_test_stubs/mkncdio.F90) -add_library(mksurfdat ${mksurfdat_sources}) - -# Tell cmake to look for libraries & mod files here, because this is where we built libraries -include_directories(${CMAKE_CURRENT_BINARY_DIR}) -link_directories(${CMAKE_CURRENT_BINARY_DIR}) - -# Add the test directory -add_subdirectory(test) diff --git a/tools/mksurfdata_map/src/Filepath b/tools/mksurfdata_map/src/Filepath deleted file mode 100644 index 9c558e357c..0000000000 --- a/tools/mksurfdata_map/src/Filepath +++ /dev/null @@ -1 +0,0 @@ -. diff --git a/tools/mksurfdata_map/src/Makefile b/tools/mksurfdata_map/src/Makefile deleted file mode 100644 index 248a913565..0000000000 --- a/tools/mksurfdata_map/src/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# Makefile for mksurfdata_map - -EXENAME = ../mksurfdata_map - -# Set optimization on by default -ifeq ($(OPT),$(null)) - OPT := TRUE -endif - -include Makefile.common \ No newline at end of file diff --git a/tools/mksurfdata_map/src/Makefile.common b/tools/mksurfdata_map/src/Makefile.common deleted file mode 100644 index ab79f94144..0000000000 --- a/tools/mksurfdata_map/src/Makefile.common +++ /dev/null @@ -1,360 +0,0 @@ -#----------------------------------------------------------------------- -# This Makefile is for building clm tools on AIX, Linux (with pgf90 or -# lf95 compiler), Darwin or IRIX platforms. -# -# These macros can be changed by setting environment variables: -# -# LIB_NETCDF --- Library directory location of netcdf. (defaults to /usr/local/lib) -# INC_NETCDF --- Include directory location of netcdf. (defaults to /usr/local/include) -# MOD_NETCDF --- Module directory location of netcdf. (defaults to $LIB_NETCDF) -# USER_FC ------ Allow user to override the default Fortran compiler specified in Makefile. -# USER_FCTYP --- Allow user to override the default type of Fortran compiler (linux and USER_FC=ftn only). -# USER_CC ------ Allow user to override the default C compiler specified in Makefile (linux only). -# USER_LINKER -- Allow user to override the default linker specified in Makefile. -# USER_CPPDEFS - Additional CPP defines. -# USER_CFLAGS -- Additional C compiler flags that the user wishes to set. -# USER_FFLAGS -- Additional Fortran compiler flags that the user wishes to set. -# USER_LDLAGS -- Additional load flags that the user wishes to set. -# SMP ---------- Shared memory Multi-processing (TRUE or FALSE) [default is FALSE] -# OPT ---------- Use optimized options. -# -#------------------------------------------------------------------------ - -# Set up special characters -null := - -# Newer makes set the CURDIR variable. -CURDIR := $(shell pwd) - -RM = rm - -# Check for the netcdf library and include directories -ifeq ($(LIB_NETCDF),$(null)) - LIB_NETCDF := /usr/local/lib -endif - -ifeq ($(INC_NETCDF),$(null)) - INC_NETCDF := /usr/local/include -endif - -ifeq ($(MOD_NETCDF),$(null)) - MOD_NETCDF := $(LIB_NETCDF) -endif - -# Set user specified Fortran compiler -ifneq ($(USER_FC),$(null)) - FC := $(USER_FC) -endif - -# Set user specified C compiler -ifneq ($(USER_CC),$(null)) - CC := $(USER_CC) -endif - -# Set if Shared memory multi-processing will be used -ifeq ($(SMP),$(null)) - SMP := FALSE -endif - -CPPDEF := $(USER_CPPDEFS) - -# Set optimization on by default -ifeq ($(OPT),$(null)) - OPT := TRUE -endif - -ifeq ($(OPT),TRUE) - CPPDEF := -DOPT -endif - -# Determine platform -UNAMES := $(shell uname -s) - -# Load dependency search path. -dirs := . $(shell cat Filepath) - -# Set cpp search path, include netcdf -cpp_dirs := $(dirs) $(INC_NETCDF) $(MOD_NETCDF) -cpp_path := $(foreach dir,$(cpp_dirs),-I$(dir)) # format for command line - -# Expand any tildes in directory names. Change spaces to colons. -# (the vpath itself is set elsewhere, based on this variable) -vpath_dirs := $(foreach dir,$(cpp_dirs),$(wildcard $(dir))) -vpath_dirs := $(subst $(space),:,$(vpath_dirs)) - -#Primary Target: build the tool -all: $(EXENAME) - -# Get list of files and build dependency file for all .o files -# using perl scripts mkSrcfiles and mkDepends - -SOURCES := $(shell cat Srcfiles) - -OBJS := $(addsuffix .o, $(basename $(SOURCES))) - -# Set path to Mkdepends script; assumes that any Makefile including -# this file is in a sibling of the src directory, in which Mkdepends -# resides -Mkdepends := ../src/Mkdepends - -$(CURDIR)/Depends: $(CURDIR)/Srcfiles $(CURDIR)/Filepath - $(Mkdepends) Filepath Srcfiles > $@ - - -# Architecture-specific flags and rules -#------------------------------------------------------------------------ -# AIX -#------------------------------------------------------------------------ - -ifeq ($(UNAMES),AIX) -CPPDEF += -DAIX -cpre = $(null)-WF,-D$(null) -FPPFLAGS := $(patsubst -D%,$(cpre)%,$(CPPDEF)) -FFLAGS = -c -I$(INC_NETCDF) -q64 -qsuffix=f=f90 -qsuffix=f=f90:cpp=F90 \ - $(FPPFLAGS) -g -qfullpath -qarch=auto -qtune=auto -qsigtrap=xl__trcedump -qsclk=micro - -LDFLAGS = -L$(LIB_NETCDF) -q64 -lnetcdff -lnetcdf -ifneq ($(OPT),TRUE) - FFLAGS += -qinitauto=7FF7FFFF -qflttrap=ov:zero:inv:en -qspillsize=4000 -C -else - FFLAGS += -O2 -qmaxmem=-1 -Q - LDFLAGS += -Q -endif -CFLAGS := -q64 -g $(CPPDEF) -O2 -FFLAGS += $(cpp_path) -CFLAGS += $(cpp_path) - -ifeq ($(SMP),TRUE) - FC = xlf90_r - FFLAGS += -qsmp=omp - LDFLAGS += -qsmp=omp -else - FC = xlf90 -endif - -endif - -#------------------------------------------------------------------------ -# Darwin -#------------------------------------------------------------------------ - -ifeq ($(UNAMES),Darwin) - -# Set the default Fortran compiler -ifeq ($(USER_FC),$(null)) - FC := g95 -endif -ifeq ($(USER_CC),$(null)) - CC := gcc -endif - -CFLAGS := -g -O2 -CPPDEF += -DSYSDARWIN -DDarwin -DLINUX -LDFLAGS := - -ifeq ($(FC),g95) - - CPPDEF += -DG95 - FFLAGS := -c -fno-second-underscore $(CPPDEF) $(cpp_path) -I$(MOD_NETCDF) - ifeq ($(OPT),TRUE) - FFLAGS += -O2 - else - FFLAGS += -g -fbounds-check - endif - -endif - -ifeq ($(FC),gfortran) - - CPPDEF += -DG95 - FFLAGS := -c -fno-second-underscore $(CPPDEF) $(cpp_path) -I$(MOD_NETCDF) \ - -fno-range-check - ifeq ($(OPT),TRUE) - FFLAGS += -O2 - else - FFLAGS += -g -fbounds-check - endif - -endif - -ifeq ($(FC),ifort) - - CPPDEF += -DFORTRANUNDERSCORE - FFLAGS += -c -ftz -g -fp-model precise $(CPPDEF) $(cpp_path) \ - -convert big_endian -assume byterecl -traceback -FR - LDFLAGS += -m64 - - ifneq ($(OPT),TRUE) - FFLAGS += -CB -O0 - else - FFLAGS += -O2 - endif - ifeq ($(SMP),TRUE) - FFLAGS += -qopenmp - LDFLAGS += -qopenmp - endif -endif - -ifeq ($(FC),pgf90) - - CPPDEF += -DFORTRANUNDERSCORE - FFLAGS += -c $(CPPDEF) $(cpp_path) - ifneq ($(OPT),TRUE) - FFLAGS += -g -Ktrap=fp -Mbounds -Kieee - else - FFLAGS += -fast -Kieee - endif - - ifeq ($(SMP),TRUE) - FFLAGS += -mp - LDFLAGS += -mp - endif - -endif - -ifeq ($(CC),icc) - CFLAGS += -m64 -g - ifeq ($(SMP),TRUE) - CFLAGS += -qopenmp - endif -endif -ifeq ($(CC),pgcc) - CFLAGS += -g -fast -endif - -CFLAGS += $(CPPDEF) $(cpp_path) -LDFLAGS += -L$(LIB_NETCDF) -lnetcdf -lnetcdff - -endif - -#------------------------------------------------------------------------ -# Linux -#------------------------------------------------------------------------ - -ifeq ($(UNAMES),Linux) - ifeq ($(USER_FC),$(null)) - FC := ifort - FCTYP := ifort - else - ifeq ($(USER_FC),ftn) - ifneq ($(USER_FCTYP),$(null)) - FCTYP := $(USER_FCTYP) - else - FCTYP := pgf90 - endif - else - FCTYP := $(USER_FC) - endif - endif - CPPDEF += -DLINUX -DFORTRANUNDERSCORE - CFLAGS := $(CPPDEF) - LDFLAGS := $(shell $(LIB_NETCDF)/../bin/nf-config --flibs) - FFLAGS = - - ifeq ($(FCTYP),pgf90) - CC := pgcc - ifneq ($(OPT),TRUE) - FFLAGS += -g -Ktrap=fp -Mbounds -Kieee - else - FFLAGS += -fast -Kieee - CFLAGS += -fast - endif - - ifeq ($(SMP),TRUE) - FFLAGS += -mp - LDFLAGS += -mp - endif - - endif - - ifeq ($(FCTYP),lf95) - ifneq ($(OPT),TRUE) - FFLAGS += -g --chk a,e,s,u -O0 - else - FFLAGS += -O - endif - # Threading only works by putting thread memory on the heap rather than the stack - # (--threadheap). - # As of lf95 version 6.2 the thread stacksize limits are (still) too small to run - # even small - # resolution problems (FV at 10x15 res fails). - ifeq ($(SMP),TRUE) - FFLAGS += --openmp --threadheap 4096 - LDFLAGS += --openmp --threadheap 4096 - endif - endif - ifeq ($(FCTYP),pathf90) - FFLAGS += -extend_source -ftpp -fno-second-underscore - ifneq ($(OPT),TRUE) - FFLAGS += -g -O0 - else - FFLAGS += -O - endif - ifeq ($(SMP),TRUE) - FFLAGS += -mp - LDFLAGS += -mp - endif - endif - ifeq ($(FCTYP),ifort) - - FFLAGS += -ftz -g -fp-model precise -convert big_endian -assume byterecl -traceback -FR - CFLAGS += -m64 -g - LDFLAGS += -m64 - - ifneq ($(OPT),TRUE) - FFLAGS += -CB -O0 - else - FFLAGS += -O2 - endif - ifeq ($(SMP),TRUE) - FFLAGS += -qopenmp - CFLAGS += -qopenmp - LDFLAGS += -qopenmp - endif - endif - FFLAGS += -c -I$(INC_NETCDF) $(CPPDEF) $(cpp_path) - CFLAGS += $(cpp_path) -endif - -#------------------------------------------------------------------------ -# Default rules and macros -#------------------------------------------------------------------------ - -.SUFFIXES: -.SUFFIXES: .F90 .c .o - -# Set the vpath for all file types EXCEPT .o -# We do this for individual file types rather than generally using -# VPATH, because for .o files, we don't want to use files from a -# different build (e.g., in building the unit tester, we don't want to -# use .o files from the main build) -vpath %.F90 $(vpath_dirs) -vpath %.c $(vpath_dirs) -vpath %.h $(vpath_dirs) - -# Append user defined compiler and load flags to Makefile defaults -CFLAGS += $(USER_CFLAGS) -FFLAGS += $(USER_FFLAGS) -LDFLAGS += $(USER_LDFLAGS) - -# Set user specified linker -ifneq ($(USER_LINKER),$(null)) - LINKER := $(USER_LINKER) -else - LINKER := $(FC) -endif - -.F90.o: - $(FC) $(FFLAGS) $< - -.c.o: - $(CC) -c $(CFLAGS) $< - - -$(EXENAME): $(OBJS) - $(LINKER) -o $@ $(OBJS) $(LDFLAGS) - -clean: - $(RM) -f $(OBJS) *.mod Depends - -include $(CURDIR)/Depends diff --git a/tools/mksurfdata_map/src/Mkdepends b/tools/mksurfdata_map/src/Mkdepends deleted file mode 100755 index ddb1682da4..0000000000 --- a/tools/mksurfdata_map/src/Mkdepends +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env perl - -# Generate dependencies in a form suitable for inclusion into a Makefile. -# The source filenames are provided in a file, one per line. Directories -# to be searched for the source files and for their dependencies are provided -# in another file, one per line. Output is written to STDOUT. -# -# For CPP type dependencies (lines beginning with #include) the dependency -# search is recursive. Only dependencies that are found in the specified -# directories are included. So, for example, the standard include file -# stdio.h would not be included as a dependency unless /usr/include were -# one of the specified directories to be searched. -# -# For Fortran module USE dependencies (lines beginning with a case -# insensitive "USE", possibly preceded by whitespace) the Fortran compiler -# must be able to access the .mod file associated with the .o file that -# contains the module. In order to correctly generate these dependencies -# two restrictions must be observed. -# 1) All modules must be contained in files that have the same base name as -# the module, in a case insensitive sense. This restriction implies that -# there can only be one module per file. -# 2) All modules that are to be contained in the dependency list must be -# contained in one of the source files in the list provided on the command -# line. -# The reason for the second restriction is that since the makefile doesn't -# contain rules to build .mod files the dependency takes the form of the .o -# file that contains the module. If a module is being used for which the -# source code is not available (e.g., a module from a library), then adding -# a .o dependency for that module is a mistake because make will attempt to -# build that .o file, and will fail if the source code is not available. -# -# Author: B. Eaton -# Climate Modelling Section, NCAR -# Feb 2001 - -use Getopt::Std; -use File::Basename; -use File::Glob ':bsd_glob'; - -# Check for usage request. -@ARGV >= 2 or usage(); - -# Process command line. -my %opt = (); -getopts( "t:w", \%opt ) or usage(); -my $filepath_arg = shift() or usage(); -my $srcfile_arg = shift() or usage(); -@ARGV == 0 or usage(); # Check that all args were processed. - -my $obj_dir; -if ( defined $opt{'t'} ) { $obj_dir = $opt{'t'}; } - -open(FILEPATH, $filepath_arg) or die "Can't open $filepath_arg: $!\n"; -open(SRCFILES, $srcfile_arg) or die "Can't open $srcfile_arg: $!\n"; - -# Make list of paths to use when looking for files. -# Prepend "." so search starts in current directory. This default is for -# consistency with the way GNU Make searches for dependencies. -my @file_paths = ; -close(FILEPATH); -chomp @file_paths; -unshift(@file_paths,'.'); -foreach $dir (@file_paths) { # (could check that directories exist here) - $dir =~ s!/?\s*$!!; # remove / and any whitespace at end of directory name - ($dir) = bsd_glob $dir; # Expand tildes in path names. -} - -# Make list of files containing source code. -my @src = ; -close(SRCFILES); -chomp @src; - -# For each file that may contain a Fortran module (*.[fF]90 *.[fF]) convert the -# file's basename to uppercase and use it as a hash key whose value is the file's -# basename. This allows fast identification of the files that contain modules. -# The only restriction is that the file's basename and the module name must match -# in a case insensitive way. -my %module_files = (); -my ($f, $name, $path, $suffix, $mod); -my @suffixes = ('\.[fF]90', '\.[fF]' ); -foreach $f (@src) { - ($name, $path, $suffix) = fileparse($f, @suffixes); - ($mod = $name) =~ tr/a-z/A-Z/; - $module_files{$mod} = $name; -} - -# Now make a list of .mod files in the file_paths. If a .o source dependency -# can't be found based on the module_files list above, then maybe a .mod -# module dependency can if the mod file is visible. -my %trumod_files = (); -my ($dir); -my ($f, $name, $path, $suffix, $mod); -my @suffixes = ('\.mod' ); -foreach $dir (@file_paths) { - @filenames = (bsd_glob("$dir/*.mod")); - foreach $f (@filenames) { - ($name, $path, $suffix) = fileparse($f, @suffixes); - ($mod = $name) =~ tr/a-z/A-Z/; - $trumod_files{$mod} = $name; - } -} - -#print STDERR "\%module_files\n"; -#while ( ($k,$v) = each %module_files ) { -# print STDERR "$k => $v\n"; -#} - -# Find module and include dependencies of the source files. -my ($file_path, $rmods, $rincs); -my %file_modules = (); -my %file_includes = (); -my @check_includes = (); -foreach $f ( @src ) { - - # Find the file in the seach path (@file_paths). - unless ($file_path = find_file($f)) { - if (defined $opt{'w'}) {print STDERR "$f not found\n";} - next; - } - - # Find the module and include dependencies. - ($rmods, $rincs) = find_dependencies( $file_path ); - - # Remove redundancies (a file can contain multiple procedures that have - # the same dependencies). - $file_modules{$f} = rm_duplicates($rmods); - $file_includes{$f} = rm_duplicates($rincs); - - # Make a list of all include files. - push @check_includes, @{$file_includes{$f}}; -} - -#print STDERR "\%file_modules\n"; -#while ( ($k,$v) = each %file_modules ) { -# print STDERR "$k => @$v\n"; -#} -#print STDERR "\%file_includes\n"; -#while ( ($k,$v) = each %file_includes ) { -# print STDERR "$k => @$v\n"; -#} -#print STDERR "\@check_includes\n"; -#print STDERR "@check_includes\n"; - -# Find include file dependencies. -my %include_depends = (); -while (@check_includes) { - $f = shift @check_includes; - if (defined($include_depends{$f})) { next; } - - # Mark files not in path so they can be removed from the dependency list. - unless ($file_path = find_file($f)) { - $include_depends{$f} = -1; - next; - } - - # Find include file dependencies. - ($rmods, $include_depends{$f}) = find_dependencies($file_path); - - # Add included include files to the back of the check_includes list so - # that their dependencies can be found. - push @check_includes, @{$include_depends{$f}}; - - # Add included modules to the include_depends list. - if ( @$rmods ) { push @{$include_depends{$f}}, @$rmods; } -} - -#print STDERR "\%include_depends\n"; -#while ( ($k,$v) = each %include_depends ) { -# print STDERR (ref $v ? "$k => @$v\n" : "$k => $v\n"); -#} - -# Remove include file dependencies that are not in the Filepath. -my $i, $ii; -foreach $f (keys %include_depends) { - - unless (ref $include_depends{$f}) { next; } - $rincs = $include_depends{$f}; - unless (@$rincs) { next; } - $ii = 0; - $num_incs = @$rincs; - for ($i = 0; $i < $num_incs; ++$i) { - if ($include_depends{$$rincs[$ii]} == -1) { - splice @$rincs, $ii, 1; - next; - } - ++$ii; - } -} - -# Substitute the include file dependencies into the %file_includes lists. -foreach $f (keys %file_includes) { - my @expand_incs = (); - - # Initialize the expanded %file_includes list. - my $i; - unless (@{$file_includes{$f}}) { next; } - foreach $i (@{$file_includes{$f}}) { - push @expand_incs, $i unless ($include_depends{$i} == -1); - } - unless (@expand_incs) { - $file_includes{$f} = []; - next; - } - - # Expand - for ($i = 0; $i <= $#expand_incs; ++$i) { - push @expand_incs, @{ $include_depends{$expand_incs[$i]} }; - } - - $file_includes{$f} = rm_duplicates(\@expand_incs); -} - -#print STDERR "expanded \%file_includes\n"; -#while ( ($k,$v) = each %file_includes ) { -# print STDERR "$k => @$v\n"; -#} - -# Print dependencies to STDOUT. -foreach $f (sort keys %file_modules) { - $f =~ /(.+)\./; - $target = "$1.o"; - if ( defined $opt{'t'} ) { $target = "$opt{'t'}/$1.o"; } - print "$target : $f @{$file_modules{$f}} @{$file_includes{$f}}\n"; -} - -#-------------------------------------------------------------------------------------- - -sub find_dependencies { - - # Find dependencies of input file. - # Use'd Fortran 90 modules are returned in \@mods. - # Files that are "#include"d by the cpp preprocessor are returned in \@incs. - - my( $file ) = @_; - my( @mods, @incs ); - - open(FH, $file) or die "Can't open $file: $!\n"; - - while ( ) { - # Search for "#include" and strip filename when found. - if ( /^#include\s+[<"](.*)[>"]/ ) { - push @incs, $1; - } - # Search for Fortran include dependencies. - elsif ( /^\s*include\s+['"](.*)['"]/ ) { #" for emacs fontlock - push @incs, $1; - } - # Search for module dependencies. - elsif ( /^\s*USE\s+(\w+)/i ) { - ($module = $1) =~ tr/a-z/A-Z/; - # Return dependency in the form of a .o version of the file that contains - # the module. this is from the source list. - if ( defined $module_files{$module} ) { - if ( defined $obj_dir ) { - push @mods, "$obj_dir/$module_files{$module}.o"; - } else { - push @mods, "$module_files{$module}.o"; - } - } - # Return dependency in the form of a .mod version of the file that contains - # the module. this is from the .mod list. only if .o version not found - elsif ( defined $trumod_files{$module} ) { - if ( defined $obj_dir ) { - push @mods, "$obj_dir/$trumod_files{$module}.mod"; - } else { - push @mods, "$trumod_files{$module}.mod"; - } - } - } - } - close( FH ); - return (\@mods, \@incs); -} - -#-------------------------------------------------------------------------------------- - -sub find_file { - -# Search for the specified file in the list of directories in the global -# array @file_paths. Return the first occurance found, or the null string if -# the file is not found. - - my($file) = @_; - my($dir, $fname); - - foreach $dir (@file_paths) { - $fname = "$dir/$file"; - if ( -f $fname ) { return $fname; } - } - return ''; # file not found -} - -#-------------------------------------------------------------------------------------- - -sub rm_duplicates { - -# Return a list with duplicates removed. - - my ($in) = @_; # input arrary reference - my @out = (); - my $i; - my %h = (); - foreach $i (@$in) { - $h{$i} = ''; - } - @out = keys %h; - return \@out; -} - -#-------------------------------------------------------------------------------------- - -sub usage { - ($ProgName = $0) =~ s!.*/!!; # name of program - die <abort if file not found 1=>do not abort -! -! !REVISION HISTORY: -! Created by Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - integer i !loop index - integer klen !length of fulpath character string - logical lexist !true if local file exists -!------------------------------------------------------------------------ - - ! get local file name from full name - - locfn = get_filename( fulpath ) - if (len_trim(locfn) == 0) then - write(iulog,*)'(GETFIL): local filename has zero length' - call shr_sys_abort - else - write(iulog,*)'(GETFIL): attempting to find local file ', & - trim(locfn) - endif - - ! first check if file is in current working directory. - - inquire (file=locfn,exist=lexist) - if (lexist) then - write(iulog,*) '(GETFIL): using ',trim(locfn), & - ' in current working directory' - RETURN - endif - - ! second check for full pathname on disk - locfn = fulpath - - inquire (file=fulpath,exist=lexist) - if (lexist) then - write(iulog,*) '(GETFIL): using ',trim(fulpath) - RETURN - else - write(iulog,*)'(GETFIL): failed getting file from full path: ', fulpath - if (present(iflag) .and. iflag==0) then - call shr_sys_abort ('GETFIL: FAILED to get '//trim(fulpath)) - else - RETURN - endif - endif - - end subroutine getfil - -!------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: opnfil -! -! !INTERFACE: - subroutine opnfil (locfn, iun, form) -! -! !DESCRIPTION: -! Open file locfn in unformatted or formatted form on unit iun -! -! !ARGUMENTS: -! - implicit none - character(len=*), intent(in):: locfn !file name - integer, intent(in):: iun !fortran unit number - character(len=1), intent(in):: form !file format: u = unformatted, - !f = formatted -! -! !REVISION HISTORY: -! Created by Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - integer ioe !error return from fortran open - character(len=11) ft !format type: formatted. unformatted -!------------------------------------------------------------------------ - - if (len_trim(locfn) == 0) then - write(iulog,*)'(OPNFIL): local filename has zero length' - call shr_sys_abort - endif - if (form=='u' .or. form=='U') then - ft = 'unformatted' - else - ft = 'formatted ' - end if - open (unit=iun,file=locfn,status='unknown',form=ft,iostat=ioe) - if (ioe /= 0) then - write(iulog,*)'(OPNFIL): failed to open file ',trim(locfn), & - & ' on unit ',iun,' ierr=',ioe - call shr_sys_abort - else - write(iulog,*)'(OPNFIL): Successfully opened file ',trim(locfn), & - & ' on unit= ',iun - end if - - end subroutine opnfil - -!------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: getavu -! -! !INTERFACE: - integer function getavu() -! -! !DESCRIPTION: -! Get next available Fortran unit number. -! -! !USES: - use shr_file_mod, only : shr_file_getUnit -! -! !ARGUMENTS: - implicit none -! -! !REVISION HISTORY: -! Created by Gordon Bonan -! Modified for clm2 by Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP -!------------------------------------------------------------------------ - - getavu = shr_file_getunit() - - end function getavu - -!------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: relavu -! -! !INTERFACE: - subroutine relavu (iunit) -! -! !DESCRIPTION: -! Close and release Fortran unit no longer in use! -! -! !USES: - use shr_file_mod, only : shr_file_freeUnit -! -! !ARGUMENTS: - implicit none - integer, intent(in) :: iunit !Fortran unit number -! -! !REVISION HISTORY: -! Created by Gordon Bonan -! -!EOP -!------------------------------------------------------------------------ - - close(iunit) - call shr_file_freeUnit(iunit) - - end subroutine relavu - -end module fileutils diff --git a/tools/mksurfdata_map/src/mkVICparamsMod.F90 b/tools/mksurfdata_map/src/mkVICparamsMod.F90 deleted file mode 100644 index 431e43cb28..0000000000 --- a/tools/mksurfdata_map/src/mkVICparamsMod.F90 +++ /dev/null @@ -1,200 +0,0 @@ -module mkVICparamsMod - -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkVICparamsMod -! -! !DESCRIPTION: -! make parameters for VIC -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -!----------------------------------------------------------------------- -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - use mkdomainMod , only : domain_checksame - - implicit none - - private - -! !PUBLIC MEMBER FUNCTIONS: - public mkVICparams ! make VIC parameters -! -!EOP -!=============================================================== -contains -!=============================================================== - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkVICparams -! -! !INTERFACE: -subroutine mkVICparams(ldomain, mapfname, datfname, ndiag, & - binfl_o, ws_o, dsmax_o, ds_o) -! -! !DESCRIPTION: -! make VIC parameters -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_continuous - use mkchecksMod, only : min_bad -! -! !ARGUMENTS: - - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: binfl_o(:) ! output grid: VIC b parameter for the Variable Infiltration Capacity Curve (unitless) - real(r8) , intent(out):: ws_o(:) ! output grid: VIC Ws parameter for the ARNO curve (unitless) - real(r8) , intent(out):: dsmax_o(:) ! output grid: VIC Dsmax parameter for the ARNO curve (mm/day) - real(r8) , intent(out):: ds_o(:) ! output grid: VIC Ds parameter for the ARNO curve (unitless) -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: data_i(:) ! data on input grid - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - - real(r8), parameter :: min_valid_binfl = 0._r8 - real(r8), parameter :: min_valid_ws = 0._r8 - real(r8), parameter :: min_valid_dsmax = 0._r8 - real(r8), parameter :: min_valid_ds = 0._r8 - - character(len=32) :: subname = 'mkVICparams' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make VIC parameters.....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - call domain_read(tdomain,datfname) - - call gridmap_mapread(tgridmap, mapfname ) - - ! Obtain frac_dst - allocate(frac_dst(ldomain%ns), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write(6,*)'Open VIC parameter file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(data_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() - - ! ----------------------------------------------------------------- - ! Regrid binfl - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'binfl', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, binfl_o, nodata=0.1_r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(binfl_o, min_valid_binfl, 'binfl')) then - call abort() - end if - - call output_diagnostics_continuous(data_i, binfl_o, tgridmap, "VIC b parameter", "unitless", ndiag, tdomain%mask, frac_dst) - - ! ----------------------------------------------------------------- - ! Regrid Ws - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'Ws', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, ws_o, nodata=0.75_r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(ws_o, min_valid_ws, 'Ws')) then - call abort() - end if - - call output_diagnostics_continuous(data_i, ws_o, tgridmap, "VIC Ws parameter", "unitless", ndiag, tdomain%mask, frac_dst) - - ! ----------------------------------------------------------------- - ! Regrid Dsmax - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'Dsmax', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, dsmax_o, nodata=10._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(dsmax_o, min_valid_dsmax, 'Dsmax')) then - call abort() - end if - - call output_diagnostics_continuous(data_i, dsmax_o, tgridmap, "VIC Dsmax parameter", "mm/day", ndiag, tdomain%mask, frac_dst) - - ! ----------------------------------------------------------------- - ! Regrid Ds - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'Ds', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, ds_o, nodata=0.1_r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(ds_o, min_valid_ds, 'Ds')) then - call abort() - end if - - call output_diagnostics_continuous(data_i, ds_o, tgridmap, "VIC Ds parameter", "unitless", ndiag, tdomain%mask, frac_dst) - - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- - - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (data_i) - deallocate (frac_dst) - deallocate (mask_r8) - - write (6,*) 'Successfully made VIC parameters' - write (6,*) - call shr_sys_flush(6) - -end subroutine mkVICparams - - -end module mkVICparamsMod diff --git a/tools/mksurfdata_map/src/mkagfirepkmonthMod.F90 b/tools/mksurfdata_map/src/mkagfirepkmonthMod.F90 deleted file mode 100644 index 35b308ce0f..0000000000 --- a/tools/mksurfdata_map/src/mkagfirepkmonthMod.F90 +++ /dev/null @@ -1,272 +0,0 @@ -module mkagfirepkmonthMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkagfirepkmonthMod -! -! !DESCRIPTION: -! Make agricultural fire peak month data -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -!----------------------------------------------------------------------- -!!USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - use mkdomainMod , only : domain_checksame - implicit none - - SAVE - private ! By default make data private -! -! !PUBLIC MEMBER FUNCTIONS: -! - public mkagfirepkmon ! Set agricultural fire peak month -! -! !PRIVATE MEMBER FUNCTIONS: - private define_months ! define month strings -! -! !PRIVATE DATA MEMBERS: -! - integer , parameter :: min_valid_value = 1 - integer , parameter :: max_valid_value = 13 -! -! !PRIVATE DATA MEMBERS: -! -!EOP -!=============================================================== -contains -!=============================================================== - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkagfirepkmon -! -! !INTERFACE: -subroutine mkagfirepkmon(ldomain, mapfname, datfname, ndiag, & - agfirepkmon_o) -! -! !DESCRIPTION: -! Make agricultural fire peak month data from higher resolution data -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkindexmapMod, only : get_dominant_indices - use mkvarpar, only : re - use mkncdio - use mkchecksMod, only : min_bad, max_bad -! -! !ARGUMENTS: - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - integer , intent(out):: agfirepkmon_o(:) ! agricultural fire peak month -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: gast_i(:) ! global area, by surface type - real(r8), allocatable :: gast_o(:) ! global area, by surface type - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer , allocatable :: agfirepkmon_i(:) ! input grid: agricultural fire peak month - integer :: nagfirepkmon ! number of peak months - character(len=35), allocatable :: month(:)! name of each month - integer :: k,ni,no,ns_i,ns_o ! indices - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - - integer, parameter :: miss = unsetmon ! missing data indicator - integer, parameter :: min_valid = 1 ! minimum valid value - integer, parameter :: max_valid = 13 ! maximum valid value - character(len=32) :: subname = 'mkagfirepkmon' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make agricultural fire peak month data .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - call domain_read( tdomain,datfname ) - - call gridmap_mapread( tgridmap, mapfname ) - - ! Obtain frac_dst - ns_o = ldomain%ns - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ns_i = tdomain%ns - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write (6,*) 'Open agricultural fire peak month file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(agfirepkmon_i(ns_i), stat=ier) - if (ier/=0) call abort() - - ! ----------------------------------------------------------------- - ! Regrid ag fire peak month - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'abm', varid), subname) - call check_ret(nf_get_var_int (ncid, varid, agfirepkmon_i), subname) - ! Note that any input point that is outside the range [min_valid_value,max_valid_value] - ! will be ignored; this ignores input points with value of unsetmon - call get_dominant_indices(tgridmap, agfirepkmon_i, agfirepkmon_o, & - min_valid_value, max_valid_value, miss, mask_src=tdomain%mask) - - ! Check validity of output data - if (min_bad(agfirepkmon_o, min_valid, 'agfirepkmon') .or. & - max_bad(agfirepkmon_o, max_valid, 'agfirepkmon')) then - call abort() - end if - - - ! ----------------------------------------------------------------- - ! Output diagnostics comparing global area of each peak month on input and output grids - ! - ! WJS (3-4-13): I am trying to generally put these diagnostics in mkdiagnosticsMod, but - ! so far there isn't a general diagnostics routine for categorical data - ! - ! TODO(wjs, 2016-01-22) Now there is a routine for this: output_diagnostics_index. - ! However, it currently doesn't provide the capability for named months. Either add - ! that capability or decide it's not important, then delete the below code, instead - ! calling output_diagnostics_index. - ! ----------------------------------------------------------------- - - nagfirepkmon = maxval(agfirepkmon_i) - allocate(gast_i(1:nagfirepkmon),gast_o(1:nagfirepkmon),month(1:nagfirepkmon)) - call define_months(nagfirepkmon, month) - - gast_i(:) = 0.0_r8 - do ni = 1,ns_i - k = agfirepkmon_i(ni) - gast_i(k) = gast_i(k) + tgridmap%area_src(ni)*tdomain%mask(ni)*re**2 - end do - - gast_o(:) = 0.0_r8 - do no = 1,ns_o - k = agfirepkmon_o(no) - gast_o(k) = gast_o(k) + tgridmap%area_dst(no)*frac_dst(no)*re**2 - end do - - ! area comparison - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Agricultural fire peak month Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,1001) -1001 format (1x,'peak month',20x,' input grid area output grid area',/ & - 1x,33x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - - do k = 1, nagfirepkmon - write (ndiag,1002) month(k),gast_i(k)*1.e-6,gast_o(k)*1.e-6 -1002 format (1x,a35,f16.3,f17.3) - end do - - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- - - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (agfirepkmon_i,gast_i,gast_o,month, frac_dst, mask_r8) - - write (6,*) 'Successfully made Agricultural fire peak month' - write (6,*) - call shr_sys_flush(6) - -end subroutine mkagfirepkmon - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: define_months -! -! !INTERFACE: -subroutine define_months(nagfirepkmon, month) -! -! !DESCRIPTION: -! Define month strings -! -! !USES: -! -! !ARGUMENTS: - implicit none - integer , intent(in) :: nagfirepkmon ! max input value (including the 'unset' special value) - character(len=*), intent(out):: month(:) ! name of each month value -! -! !CALLED FROM: -! subroutine mkagfirepkmon -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP -!----------------------------------------------------------------------- - - if (nagfirepkmon == unsetmon) then - if (size(month) < 13) then - write(6,*) 'month array too small: ', size(month), ' < 13' - call abort() - end if - month(1) = 'January ' - month(2) = 'February ' - month(3) = 'March ' - month(4) = 'April ' - month(5) = 'May ' - month(6) = 'June ' - month(7) = 'July ' - month(8) = 'August ' - month(9) = 'September ' - month(10) = 'October ' - month(11) = 'November ' - month(12) = 'December ' - month(13) = 'no agricultural fire peak month data' - else - write(6,*)'nagfirepkmon value of ',nagfirepkmon,' not supported' - call abort() - end if - -end subroutine define_months -!----------------------------------------------------------------------- - - -end module mkagfirepkmonthMod diff --git a/tools/mksurfdata_map/src/mkchecksMod.F90 b/tools/mksurfdata_map/src/mkchecksMod.F90 deleted file mode 100644 index 94b8fe5930..0000000000 --- a/tools/mksurfdata_map/src/mkchecksMod.F90 +++ /dev/null @@ -1,233 +0,0 @@ -module mkchecksMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkchecks -! -! !DESCRIPTION: -! Generic routines to check validity of output fields -! -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - - implicit none - private -! -! !PUBLIC MEMBER FUNCTIONS: - public :: min_bad ! check the minimum value of a field - public :: max_bad ! check the maximum value of a field - - interface min_bad - module procedure min_bad_int - module procedure min_bad_r8 - end interface min_bad - - interface max_bad - module procedure max_bad_int - module procedure max_bad_r8 - end interface max_bad -! -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -!EOP -!------------------------------------------------------------------------------ -contains - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: min_bad_r8 -! -! !INTERFACE: -logical function min_bad_r8(data, min_allowed, varname) -! -! !DESCRIPTION: -! Confirm that no value of data is less than min_allowed. -! Returns true if errors found, false otherwise. -! Also prints offending points -! -! -! !USES: -! -! !ARGUMENTS: - implicit none - real(r8) , intent(in) :: data(:) ! array of data to check - real(r8) , intent(in) :: min_allowed ! minimum valid value - character(len=*) , intent(in) :: varname ! name of field -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - logical :: errors_found ! true if any errors have been found - integer :: n ! index - - character(len=*), parameter :: subname = 'min_bad_r8' -!------------------------------------------------------------------------------ - - errors_found = .false. - - do n = 1, size(data) - if (data(n) < min_allowed) then - write(6,*) subname//' ERROR: ', trim(varname), ' = ', data(n), ' less than ',& - min_allowed, ' at ', n - errors_found = .true. - end if - end do - - call shr_sys_flush(6) - min_bad_r8 = errors_found -end function min_bad_r8 - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: min_bad_int -! -! !INTERFACE: -logical function min_bad_int(data, min_allowed, varname) -! -! !DESCRIPTION: -! Confirm that no value of data is less than min_allowed. -! Returns true if errors found, false otherwise. -! Also prints offending points -! -! -! !USES: -! -! !ARGUMENTS: - implicit none - integer , intent(in) :: data(:) ! array of data to check - integer , intent(in) :: min_allowed ! minimum valid value - character(len=*) , intent(in) :: varname ! name of field -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - logical :: errors_found ! true if any errors have been found - integer :: n ! index - - character(len=*), parameter :: subname = 'min_bad_int' -!------------------------------------------------------------------------------ - - errors_found = .false. - - do n = 1, size(data) - if (data(n) < min_allowed) then - write(6,*) subname//' ERROR: ', trim(varname), ' = ', data(n), ' less than ',& - min_allowed, ' at ', n - errors_found = .true. - end if - end do - - call shr_sys_flush(6) - min_bad_int = errors_found -end function min_bad_int - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: max_bad_r8 -! -! !INTERFACE: -logical function max_bad_r8(data, max_allowed, varname) -! -! !DESCRIPTION: -! Confirm that no value of data is greate than max_allowed. -! Returns true if errors found, false otherwise. -! Also prints offending points -! -! -! !USES: -! -! !ARGUMENTS: - implicit none - real(r8) , intent(in) :: data(:) ! array of data to check - real(r8) , intent(in) :: max_allowed ! maximum valid value - character(len=*) , intent(in) :: varname ! name of field -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - logical :: errors_found ! true if any errors have been found - integer :: n ! index - - character(len=*), parameter :: subname = 'max_bad_r8' -!------------------------------------------------------------------------------ - - errors_found = .false. - - do n = 1, size(data) - if (data(n) > max_allowed) then - write(6,*) subname//' ERROR: ', trim(varname), ' = ', data(n), ' greater than ',& - max_allowed, ' at ', n - errors_found = .true. - end if - end do - - call shr_sys_flush(6) - max_bad_r8 = errors_found -end function max_bad_r8 - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: max_bad_int -! -! !INTERFACE: -logical function max_bad_int(data, max_allowed, varname) -! -! !DESCRIPTION: -! Confirm that no value of data is greate than max_allowed. -! Returns true if errors found, false otherwise. -! Also prints offending points -! -! -! !USES: -! -! !ARGUMENTS: - implicit none - integer , intent(in) :: data(:) ! array of data to check - integer , intent(in) :: max_allowed ! maximum valid value - character(len=*) , intent(in) :: varname ! name of field -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - logical :: errors_found ! true if any errors have been found - integer :: n ! index - - character(len=*), parameter :: subname = 'max_bad_int' -!------------------------------------------------------------------------------ - - errors_found = .false. - - do n = 1, size(data) - if (data(n) > max_allowed) then - write(6,*) subname//' ERROR: ', trim(varname), ' = ', data(n), ' greater than ',& - max_allowed, ' at ', n - errors_found = .true. - end if - end do - - call shr_sys_flush(6) - max_bad_int = errors_found -end function max_bad_int - - -end module mkchecksMod diff --git a/tools/mksurfdata_map/src/mkdiagnosticsMod.F90 b/tools/mksurfdata_map/src/mkdiagnosticsMod.F90 deleted file mode 100644 index 91769a5823..0000000000 --- a/tools/mksurfdata_map/src/mkdiagnosticsMod.F90 +++ /dev/null @@ -1,452 +0,0 @@ -module mkdiagnosticsMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkdiagnostics -! -! !DESCRIPTION: -! Output diagnostics to log file -! -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - - implicit none - private -! -! !PUBLIC MEMBER FUNCTIONS: - public :: output_diagnostics_area ! output diagnostics for field that is % of grid area - public :: output_diagnostics_continuous ! output diagnostics for a continuous (real-valued) field - public :: output_diagnostics_continuous_outonly ! output diagnostics for a continuous (real-valued) field, just on the output grid - public :: output_diagnostics_index ! output diagnostics for an index field -! -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -!EOP -!------------------------------------------------------------------------------ -contains - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: output_diagnostics_area -! -! !INTERFACE: -subroutine output_diagnostics_area(data_i, data_o, gridmap, name, percent, ndiag, mask_src, frac_dst) -! -! !DESCRIPTION: -! Output diagnostics for a field that gives either fraction or percent of grid cell area -! -! !USES: - use mkgridmapMod, only : gridmap_type - use mkvarpar, only : re -! -! !ARGUMENTS: - implicit none - real(r8) , intent(in) :: data_i(:) ! data on input grid - real(r8) , intent(in) :: data_o(:) ! data on output grid - type(gridmap_type), intent(in) :: gridmap ! mapping info - character(len=*) , intent(in) :: name ! name of field - logical , intent(in) :: percent ! is field specified as percent? (alternative is fraction) - integer , intent(in) :: ndiag ! unit number for diagnostic output - integer, intent(in) :: mask_src(:) - real(r8), intent(in) :: frac_dst(:) -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - real(r8) :: gdata_i ! global sum of input data - real(r8) :: gdata_o ! global sum of output data - real(r8) :: garea_i ! global sum of input area - real(r8) :: garea_o ! global sum of output area - integer :: ns_i, ns_o ! sizes of input & output grids - integer :: ni,no,k ! indices - - character(len=*), parameter :: subname = "output_diagnostics_area" -!------------------------------------------------------------------------------ - - ! Error check for array size consistencies - - ns_i = gridmap%na - ns_o = gridmap%nb - if (size(data_i) /= ns_i .or. & - size(data_o) /= ns_o) then - write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) - write(6,*) 'size(data_i) = ', size(data_i) - write(6,*) 'ns_i = ', ns_i - write(6,*) 'size(data_o) = ', size(data_o) - write(6,*) 'ns_o = ', ns_o - call abort() - end if - if (size(frac_dst) /= ns_o) then - write(6,*) subname//' ERROR: incorrect size of frac_dst' - write(6,*) 'size(frac_dst) = ', size(frac_dst) - write(6,*) 'ns_o = ', ns_o - call abort() - end if - if (size(mask_src) /= ns_i) then - write(6,*) subname//' ERROR: incorrect size of mask_src' - write(6,*) 'size(mask_src) = ', size(mask_src) - write(6,*) 'ns_i = ', ns_i - call abort() - end if - - ! Sums on input grid - - gdata_i = 0. - garea_i = 0. - do ni = 1,ns_i - garea_i = garea_i + gridmap%area_src(ni)*re**2 - gdata_i = gdata_i + data_i(ni) * gridmap%area_src(ni) * mask_src(ni) * re**2 - end do - - ! Sums on output grid - - gdata_o = 0. - garea_o = 0. - do no = 1,ns_o - garea_o = garea_o + gridmap%area_dst(no)*re**2 - gdata_o = gdata_o + data_o(no) * gridmap%area_dst(no) * frac_dst(no) * re**2 - end do - - ! Correct units - - if (percent) then - gdata_i = gdata_i / 100._r8 - gdata_o = gdata_o / 100._r8 - end if - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) trim(name), ' Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) -2001 format (1x,'surface type input grid area output grid area'/ & - 1x,' 10**6 km**2 10**6 km**2 ') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2002) name, gdata_i*1.e-06, gdata_o*1.e-06 - write (ndiag,2002) 'all surface', garea_i*1.e-06, garea_o*1.e-06 -2002 format (1x,a12, f14.3,f17.3) - -end subroutine output_diagnostics_area -!------------------------------------------------------------------------------ - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: output_diagnostics_continuous -! -! !INTERFACE: -subroutine output_diagnostics_continuous(data_i, data_o, gridmap, name, units, ndiag, mask_src, frac_dst) -! -! !DESCRIPTION: -! Output diagnostics for a continuous field (but not area, for which there is a different routine) -! -! !USES: - use mkgridmapMod, only : gridmap_type - use mkvarpar, only : re -! -! !ARGUMENTS: - implicit none - real(r8) , intent(in) :: data_i(:) ! data on input grid - real(r8) , intent(in) :: data_o(:) ! data on output grid - type(gridmap_type), intent(in) :: gridmap ! mapping info - character(len=*) , intent(in) :: name ! name of field - character(len=*) , intent(in) :: units ! units of field - integer , intent(in) :: ndiag ! unit number for diagnostic output - integer, intent(in) :: mask_src(:) - real(r8), intent(in) :: frac_dst(:) -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - real(r8) :: gdata_i ! global sum of input data - real(r8) :: gdata_o ! global sum of output data - real(r8) :: gwt_i ! global sum of input weights (area * frac) - real(r8) :: gwt_o ! global sum of output weights (area * frac) - integer :: ns_i, ns_o ! sizes of input & output grids - integer :: ni,no,k ! indices - - character(len=*), parameter :: subname = "output_diagnostics_continuous" -!------------------------------------------------------------------------------ - - ! Error check for array size consistencies - - ns_i = gridmap%na - ns_o = gridmap%nb - if (size(data_i) /= ns_i .or. & - size(data_o) /= ns_o) then - write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) - write(6,*) 'size(data_i) = ', size(data_i) - write(6,*) 'ns_i = ', ns_i - write(6,*) 'size(data_o) = ', size(data_o) - write(6,*) 'ns_o = ', ns_o - call abort() - end if - if (size(frac_dst) /= ns_o) then - write(6,*) subname//' ERROR: incorrect size of frac_dst' - write(6,*) 'size(frac_dst) = ', size(frac_dst) - write(6,*) 'ns_o = ', ns_o - call abort() - end if - if (size(mask_src) /= ns_i) then - write(6,*) subname//' ERROR: incorrect size of mask_src' - write(6,*) 'size(mask_src) = ', size(mask_src) - write(6,*) 'ns_i = ', ns_i - call abort() - end if - - ! Sums on input grid - - gdata_i = 0. - gwt_i = 0. - do ni = 1,ns_i - gdata_i = gdata_i + data_i(ni) * gridmap%area_src(ni) * mask_src(ni) - gwt_i = gwt_i + gridmap%area_src(ni) * mask_src(ni) - end do - - ! Sums on output grid - - gdata_o = 0. - gwt_o = 0. - do no = 1,ns_o - gdata_o = gdata_o + data_o(no) * gridmap%area_dst(no) * frac_dst(no) - gwt_o = gwt_o + gridmap%area_dst(no) * frac_dst(no) - end do - - ! Correct units - - gdata_i = gdata_i / gwt_i - gdata_o = gdata_o / gwt_o - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) trim(name), ' Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) - write (ndiag,2002) units, units -2001 format (1x,' parameter input grid output grid') -2002 format (1x,' ', a24, a24) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2003) name, gdata_i, gdata_o -2003 format (1x,a12, f22.3,f17.3) - -end subroutine output_diagnostics_continuous -!------------------------------------------------------------------------------ - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: output_diagnostics_continuous_outonly -! -! !INTERFACE: -subroutine output_diagnostics_continuous_outonly(data_o, gridmap, name, units, ndiag) -! -! !DESCRIPTION: -! Output diagnostics for a continuous field, just on the output grid -! This is used when the average of the field on the input grid is not of interest (e.g., -! when the output quantity is the standard deviation of the input field) -! -! !USES: - use mkgridmapMod, only : gridmap_type - use mkvarpar, only : re -! -! !ARGUMENTS: - implicit none - real(r8) , intent(in) :: data_o(:) ! data on output grid - type(gridmap_type), intent(in) :: gridmap ! mapping info - character(len=*) , intent(in) :: name ! name of field - character(len=*) , intent(in) :: units ! units of field - integer , intent(in) :: ndiag ! unit number for diagnostic output -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - real(r8) :: gdata_o ! global sum of output data - real(r8) :: gwt_o ! global sum of output weights (area * frac) - integer :: ns_o ! size of output grid - integer :: no,k ! indices - - character(len=*), parameter :: subname = "output_diagnostics_continuous_outonly" -!------------------------------------------------------------------------------ - - ! Error check for array size consistencies - - ns_o = gridmap%nb - if (size(data_o) /= ns_o) then - write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) - write(6,*) 'size(data_o) = ', size(data_o) - write(6,*) 'ns_o = ', ns_o - call abort() - end if - - ! Sums on output grid - - gdata_o = 0. - gwt_o = 0. - do no = 1,ns_o - gdata_o = gdata_o + data_o(no)*gridmap%area_dst(no)*gridmap%frac_dst(no) - gwt_o = gwt_o + gridmap%area_dst(no)*gridmap%frac_dst(no) - end do - - ! Correct units - - gdata_o = gdata_o / gwt_o - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) trim(name), ' Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) - write (ndiag,2002) units -2001 format (1x,' parameter output grid') -2002 format (1x,' ', a24) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2003) name, gdata_o -2003 format (1x,a12, f22.3) - -end subroutine output_diagnostics_continuous_outonly -!------------------------------------------------------------------------------ - -!----------------------------------------------------------------------- -subroutine output_diagnostics_index(data_i, data_o, gridmap, name, & - minval, maxval, ndiag, mask_src, frac_dst) - ! - ! !DESCRIPTION: - ! Output diagnostics for an index field: area of each index in input and output - ! - ! !USES: - use mkvarpar, only : re - use mkgridmapMod, only : gridmap_type - ! - ! !ARGUMENTS: - integer , intent(in) :: data_i(:) ! data on input grid - integer , intent(in) :: data_o(:) ! data on output grid - type(gridmap_type) , intent(in) :: gridmap ! mapping info - character(len=*) , intent(in) :: name ! name of field - integer , intent(in) :: minval ! minimum valid value - integer , intent(in) :: maxval ! minimum valid value - integer , intent(in) :: ndiag ! unit number for diagnostic output - integer , intent(in) :: mask_src(:) - real(r8) , intent(in) :: frac_dst(:) - ! - ! !LOCAL VARIABLES: - integer :: ns_i, ns_o ! sizes of input & output grids - integer :: ni, no, k ! indices - real(r8), allocatable :: garea_i(:) ! input grid: global area of each index - real(r8), allocatable :: garea_o(:) ! output grid: global area of each index - integer :: ier ! error status - - character(len=*), parameter :: subname = 'output_diagnostics_index' - !----------------------------------------------------------------------- - - ! Error check for array size consistencies - - ns_i = gridmap%na - ns_o = gridmap%nb - if (size(data_i) /= ns_i .or. & - size(data_o) /= ns_o) then - write(6,*) subname//' ERROR: array size inconsistencies for ', trim(name) - write(6,*) 'size(data_i) = ', size(data_i) - write(6,*) 'ns_i = ', ns_i - write(6,*) 'size(data_o) = ', size(data_o) - write(6,*) 'ns_o = ', ns_o - call abort() - end if - if (size(frac_dst) /= ns_o) then - write(6,*) subname//' ERROR: incorrect size of frac_dst' - write(6,*) 'size(frac_dst) = ', size(frac_dst) - write(6,*) 'ns_o = ', ns_o - call abort() - end if - if (size(mask_src) /= ns_i) then - write(6,*) subname//' ERROR: incorrect size of mask_src' - write(6,*) 'size(mask_src) = ', size(mask_src) - write(6,*) 'ns_i = ', ns_i - call abort() - end if - - ! Sum areas on input grid - - allocate(garea_i(minval:maxval), stat=ier) - if (ier/=0) call abort() - - garea_i(:) = 0. - do ni = 1, ns_i - k = data_i(ni) - if (k >= minval .and. k <= maxval) then - garea_i(k) = garea_i(k) + gridmap%area_src(ni) * mask_src(ni) * re**2 - end if - end do - - ! Sum areas on output grid - - allocate(garea_o(minval:maxval), stat=ier) - if (ier/=0) call abort() - - garea_o(:) = 0. - do no = 1, ns_o - k = data_o(no) - if (k >= minval .and. k <= maxval) then - garea_o(k) = garea_o(k) + gridmap%area_dst(no) * frac_dst(no) * re**2 - end if - end do - - ! Write results - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) trim(name), ' Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) -2001 format (1x,'index input grid area output grid area',/ & - 1x,' 10**6 km**2 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - - do k = minval, maxval - write (ndiag,2002) k, garea_i(k)*1.e-06, garea_o(k)*1.e-06 -2002 format (1x,i9,f17.3,f18.3) - end do - - ! Deallocate memory - - deallocate(garea_i, garea_o) - -end subroutine output_diagnostics_index - - - -end module mkdiagnosticsMod diff --git a/tools/mksurfdata_map/src/mkdomainMod.F90 b/tools/mksurfdata_map/src/mkdomainMod.F90 deleted file mode 100644 index 89106f3b79..0000000000 --- a/tools/mksurfdata_map/src/mkdomainMod.F90 +++ /dev/null @@ -1,967 +0,0 @@ -module mkdomainMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: domain1Mod -! -! !DESCRIPTION: -! Module containing 2-d global surface boundary data information -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkvarpar , only : re - use nanMod , only : nan, bigint -! -! !PUBLIC TYPES: - implicit none - private -! - public :: domain_type - - type domain_type - character*16 :: set ! flag to check if domain is set - integer :: ns ! global size of domain - integer :: ni,nj ! for 2d domains only - real(r8) :: edgen ! lsmedge north - real(r8) :: edgee ! lsmedge east - real(r8) :: edges ! lsmedge south - real(r8) :: edgew ! lsmedge west - integer ,pointer :: mask(:) ! land mask: 1 = land, 0 = ocean - real(r8),pointer :: frac(:) ! fractional land - real(r8),pointer :: latc(:) ! latitude of grid cell (deg) - real(r8),pointer :: lonc(:) ! longitude of grid cell (deg) - real(r8),pointer :: lats(:) ! grid cell latitude, S edge (deg) - real(r8),pointer :: latn(:) ! grid cell latitude, N edge (deg) - real(r8),pointer :: lonw(:) ! grid cell longitude, W edge (deg) - real(r8),pointer :: lone(:) ! grid cell longitude, E edge (deg) - real(r8),pointer :: area(:) ! grid cell area (km**2) (only used for output grid) - logical :: is_2d ! if this is a 2-d domain - logical :: fracset ! if frac is set - logical :: maskset ! if mask is set - end type domain_type - -! -! !PUBLIC MEMBER FUNCTIONS: - public domain_clean - public domain_check - public domain_read - public domain_read_dims ! get dimensions from a domain file (only public for unit testing) - public domain_read_map - public domain_write - public domain_checksame - public is_domain_0to360_longs ! Does this domain have longitude on a 0 to 360 degree range - public for_test_create_domain ! For unit testing create a simple domain -! -! -! !REVISION HISTORY: -! Originally clm_varsur by Mariana Vertenstein -! Migrated from clm_varsur to domainMod by T Craig -! - character*16,parameter :: set = 'domain_set ' - character*16,parameter :: unset = 'NOdomain_unsetNO' - - real(r8) :: flandmin = 0.001 !minimum land frac for land cell -! -! !PRIVATE MEMBER FUNCTIONS: - private domain_init -! -!EOP -!------------------------------------------------------------------------------ - -contains - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: domain_init -! -! !INTERFACE: - subroutine domain_init(domain,ns) -! -! !DESCRIPTION: -! This subroutine allocates and nans the domain type -! -! !ARGUMENTS: - implicit none - type(domain_type) :: domain ! domain datatype - integer :: ns ! grid size, 2d -! -! !REVISION HISTORY: -! Created by T Craig -! -! -! !LOCAL VARIABLES: -!EOP - integer ier - integer nb,ne -! -!------------------------------------------------------------------------------ - - nb = 1 - ne = ns - - if (domain%set == set) then - call domain_clean(domain) - endif - - allocate(domain%mask(ns), & - domain%frac(ns), & - domain%latc(ns), & - domain%lonc(ns), & - domain%lats(ns), & - domain%latn(ns), & - domain%lonw(ns), & - domain%lone(ns), & - domain%area(ns), stat=ier) - if (ier /= 0) then - write(6,*) 'domain_init ERROR: allocate mask, frac, lat, lon, area ' - endif - - domain%ns = ns - domain%mask = -9999 - domain%frac = -1.0e36 - domain%latc = nan - domain%lonc = nan - domain%area = nan - domain%set = set - domain%fracset = .false. - domain%maskset = .false. - - end subroutine domain_init - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: domain_clean -! -! !INTERFACE: - subroutine domain_clean(domain) -! -! !DESCRIPTION: -! This subroutine deallocates the domain type -! -! !ARGUMENTS: - implicit none - type(domain_type) :: domain ! domain datatype -! -! !REVISION HISTORY: -! Created by T Craig -! -! -! !LOCAL VARIABLES: -!EOP - integer ier -! -!------------------------------------------------------------------------------ - - if (domain%set == set) then - write(6,*) 'domain_clean: cleaning ',domain%ns - deallocate(domain%mask, & - domain%frac, & - domain%latc, & - domain%lonc, & - domain%lats, & - domain%latn, & - domain%lonw, & - domain%lone, & - domain%area, stat=ier) - if (ier /= 0) then - write(6,*) 'domain_clean ERROR: deallocate mask, frac, lat, lon, area ' - call abort() - endif - else - write(6,*) 'domain_clean WARN: clean domain unecessary ' - endif - - domain%ns = bigint - domain%set = unset - domain%fracset = .false. - domain%maskset = .false. - -end subroutine domain_clean - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: domain_check -! -! !INTERFACE: - subroutine domain_check(domain) -! -! !DESCRIPTION: -! This subroutine write domain info -! -! !ARGUMENTS: - implicit none - type(domain_type),intent(in) :: domain ! domain datatype -! -! !REVISION HISTORY: -! Created by T Craig -! -! -! !LOCAL VARIABLES: -! -!EOP -!------------------------------------------------------------------------------ - - write(6,*) ' domain_check set = ',trim(domain%set) - write(6,*) ' domain_check ns = ',domain%ns - write(6,*) ' domain_check lonc = ',minval(domain%lonc),maxval(domain%lonc) - write(6,*) ' domain_check latc = ',minval(domain%latc),maxval(domain%latc) - write(6,*) ' domain_check mask = ',minval(domain%mask),maxval(domain%mask) - write(6,*) ' domain_check frac = ',minval(domain%frac),maxval(domain%frac) - write(6,*) ' ' - -end subroutine domain_check - -!---------------------------------------------------------------------------- -!BOP -! -! !IROUTINE: domain_read_map -! -! !INTERFACE: - logical function domain_read_map(domain, fname) -! -! !DESCRIPTION: -! Read a grid file -! -! !USES: - use mkncdio, only : convert_latlon -! -! !ARGUMENTS: - implicit none - type(domain_type),intent(inout) :: domain - character(len=*) ,intent(in) :: fname ! this assumes a SCRIP mapping file - look at destination grid -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - include 'netcdf.inc' - integer :: i,j,n ! indices - integer :: grid_rank ! rank of domain grid - integer :: ns ! size of domain grid - integer :: ncid ! netCDF file id - integer :: dimid ! netCDF dimension id - integer :: varid ! netCDF variable id - integer :: ndims ! number of dims for variable - integer :: ier ! error status - real(r8), allocatable :: xv(:,:) ! local array for corner lons - real(r8), allocatable :: yv(:,:) ! local array for corner lats - integer :: grid_dims(2) - character(len= 32) :: subname = 'domain_read' -!----------------------------------------------------------------- - - domain_read_map = .true. - - ! Read domain file and compute stuff as needed - - call check_ret(nf_open(fname, 0, ncid), subname) - - ! Assume unstructured grid - - domain%ni = -9999 - domain%nj = -9999 - domain%is_2d = .false. - - ier = nf_inq_dimid (ncid, 'n_b', dimid) - if ( ier /= NF_NOERR )then - domain_read_map = .false. - else - call check_ret(nf_inq_dimlen (ncid, dimid, domain%ns), subname) - - call check_ret(nf_inq_dimid (ncid, 'dst_grid_rank', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, grid_rank), subname) - - if (grid_rank == 2) then - call check_ret(nf_inq_varid (ncid, 'dst_grid_dims', varid), subname) - call check_ret(nf_get_var_int (ncid, varid, grid_dims), subname) - domain%ni = grid_dims(1) - domain%nj = grid_dims(2) - domain%is_2d = .true. - end if - - call domain_init(domain, domain%ns) - ns = domain%ns - - call check_ret(nf_inq_varid (ncid, 'xc_b', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, domain%lonc), subname) - call convert_latlon(ncid, 'xc_b', domain%lonc) - - call check_ret(nf_inq_varid (ncid, 'yc_b', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, domain%latc), subname) - call convert_latlon(ncid, 'yc_b', domain%latc) - - if (grid_rank == 2 ) then - allocate(yv(4,ns), xv(4,ns)) - call check_ret(nf_inq_varid (ncid, 'yv_b', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, yv), subname) - call check_ret(nf_inq_varid (ncid, 'xv_b', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, xv), subname) - - domain%lats(:) = yv(1,:) - call convert_latlon(ncid, 'yv_b', domain%lats(:)) - - domain%latn(:) = yv(3,:) - call convert_latlon(ncid, 'yv_b', domain%latn(:)) - - domain%lonw(:) = xv(1,:) - call convert_latlon(ncid, 'xv_b', domain%lonw(:)) - - domain%lone(:) = xv(2,:) - call convert_latlon(ncid, 'xv_b', domain%lone(:)) - - domain%edgen = maxval(domain%latn) - domain%edgee = maxval(domain%lone) - domain%edges = minval(domain%lats) - domain%edgew = minval(domain%lonw) - deallocate(yv,xv) - end if - - call check_ret(nf_inq_varid (ncid, 'frac_b', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, domain%frac), subname) - - call check_ret(nf_inq_varid (ncid, 'area_b', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, domain%area), subname) - domain%area = domain%area * re**2 - end if - domain%maskset = .true. - domain%fracset = .true. - - call check_ret(nf_close(ncid), subname) - - end function domain_read_map - -!---------------------------------------------------------------------------- -!BOP -! -! !IROUTINE: domain_read -! -! !INTERFACE: - subroutine domain_read(domain, fname, readmask) -! -! !DESCRIPTION: -! Read a grid file -! -! !USES: - use mkncdio, only : convert_latlon -! -! !ARGUMENTS: - implicit none - type(domain_type),intent(inout) :: domain - character(len=*) ,intent(in) :: fname - logical,optional, intent(in) :: readmask ! true => read mask instead of landmask for urban parameters -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - include 'netcdf.inc' - integer :: i,j,n - real(r8), allocatable :: lon1d(:) ! local array for 1d lon - real(r8), allocatable :: lat1d(:) ! local array for 1d lat - real(r8), allocatable :: xv(:,:) ! local array for corner lons - real(r8), allocatable :: yv(:,:) ! local array for corner lats - integer :: ncid ! netCDF file id - integer :: varid ! netCDF variable id - logical :: edgeNESWset ! local EDGE[NESW] - logical :: lonlatset ! local lon(:,:), lat(:,:) - logical :: llneswset ! local lat[ns],lon[we] - logical :: landfracset ! local landfrac - logical :: maskset ! local mask - integer :: ndims ! number of dims for variable - integer :: ier ! error status - logical :: lreadmask ! local readmask - character(len= 32) :: lonvar ! name of 2-d longitude variable - character(len= 32) :: latvar ! name of 2-d latitude variable - character(len= 32) :: subname = 'domain_read' -!----------------------------------------------------------------- - - lonlatset = .false. - edgeNESWset = .false. - llneswset = .false. - landfracset = .false. - maskset = .false. - lreadmask = .false. - - if (present(readmask)) then - lreadmask = readmask - end if - - call check_ret(nf_open(fname, 0, ncid), subname) - - call domain_read_dims(domain, ncid) - call domain_init(domain, domain%ns) - write(6,*) trim(subname),' initialized domain' - - ! ----- Set lat/lon variable ------ - - lonvar = ' ' - latvar = ' ' - - if (.not. lonlatset) then - ier = nf_inq_varid (ncid, 'LONGXY', varid) - if (ier == NF_NOERR) then - lonvar = 'LONGXY' - latvar = 'LATIXY' - lonlatset = .true. - end if - end if - - if (.not. lonlatset) then - ier = nf_inq_varid (ncid, 'lon', varid) - if (ier == NF_NOERR) then - lonvar = 'lon' - latvar = 'lat' - lonlatset = .true. - end if - end if - - if (.not. lonlatset) then - ier = nf_inq_varid (ncid, 'LONGITUDE', varid) - if (ier == NF_NOERR) then - lonvar = 'LONGITUDE' - latvar = 'LATITUDE' - lonlatset = .true. - end if - end if - - if (.not. lonlatset) then - write(6,*)'lon/lat values not set' - write(6,*)'currently assume either that lon/lat or LONGXY/LATIXY', & - ' or LONGITUDE/LATITUDE variables are on input dataset' - call abort() - end if - - call check_ret(nf_inq_varid (ncid, lonvar, varid), subname) - call check_ret(nf_get_var_double (ncid, varid, domain%lonc), subname) - call convert_latlon(ncid, lonvar, domain%lonc) - - call check_ret(nf_inq_varid (ncid, latvar, varid), subname) - call check_ret(nf_get_var_double (ncid, varid, domain%latc), subname) - call convert_latlon(ncid, latvar, domain%latc) - - ! ----- Set landmask/landfrac ------ - - ier = nf_inq_varid (ncid, 'frac', varid) - if (ier == NF_NOERR) then - if (landfracset) write(6,*) trim(subname),' WARNING, overwriting frac' - landfracset = .true. - write(6,*) trim(subname),' read frac' - call check_ret(nf_inq_varid (ncid, 'frac', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, domain%frac), subname) - endif - - ier = nf_inq_varid (ncid, 'LANDFRAC', varid) - if (ier == NF_NOERR) then - if (landfracset) write(6,*) trim(subname),' WARNING, overwriting frac' - landfracset = .true. - write(6,*) trim(subname),' read LANDFRAC' - call check_ret(nf_inq_varid (ncid, 'LANDFRAC', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, domain%frac), subname) - endif - - if (lreadmask) then - ier = nf_inq_varid (ncid, 'mask', varid) - if (ier == NF_NOERR) then - if (maskset) write(6,*) trim(subname),' WARNING, overwriting mask' - maskset = .true. - write(6,*) trim(subname),' read mask with lreadmask set' - call check_ret(nf_inq_varid (ncid, 'mask', varid), subname) - call check_ret(nf_get_var_int (ncid, varid, domain%mask), subname) - endif - else - ier = nf_inq_varid (ncid, 'mask', varid) - if (ier == NF_NOERR) then - if (maskset) write(6,*) trim(subname),' WARNING, overwriting mask' - maskset = .true. - write(6,*) trim(subname),' read mask' - call check_ret(nf_inq_varid (ncid, 'mask', varid), subname) - call check_ret(nf_get_var_int (ncid, varid, domain%mask), subname) - endif - ier = nf_inq_varid (ncid, 'LANDMASK', varid) - if (ier == NF_NOERR) then - if (maskset) write(6,*) trim(subname),' WARNING, overwriting mask' - maskset = .true. - write(6,*) trim(subname),' read LANDMASK' - call check_ret(nf_inq_varid (ncid, 'LANDMASK', varid), subname) - call check_ret(nf_get_var_int (ncid, varid, domain%mask), subname) - endif - end if - - call check_ret(nf_close(ncid), subname) - - ! ----- set derived variables ---- - - if (.not.maskset.and.landfracset) then - maskset = .true. - where (domain%frac < flandmin) - domain%mask = 0 !ocean - elsewhere - domain%mask = 1 !land - endwhere - endif - - if (.not.landfracset.and.maskset) then - landfracset = .true. - do n = 1,domain%ns - if ( domain%mask(n) == 0 )then - domain%frac(n) = 0._r8 !ocean - else - domain%frac(n) = 1._r8 !land - end if - end do - endif - domain%maskset = maskset - domain%fracset = landfracset - - end subroutine domain_read - -!---------------------------------------------------------------------------- -!BOP -! -! !IROUTINE: domain_read_dims -! -! !INTERFACE: - subroutine domain_read_dims(domain, ncid) -! -! !DESCRIPTION: -! get dimension size(s) from a domain file -! sets domain%ns, domain%is_2d; and (if 2-d) domain%ni and domain%nj -! -! !ARGUMENTS: - implicit none - type(domain_type),intent(inout) :: domain - integer ,intent(in) :: ncid ! ID of an open netcdf file -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - logical :: dimset ! has dimension information been set? - character(len= 32) :: subname = 'domain_read_dims' -!----------------------------------------------------------------- - - ! Assume unstructured grid - domain%ni = -9999 - domain%nj = -9999 - domain%is_2d = .false. - - dimset = .false. - - ! Note: We use the first dimension that is found in the following list - - ! ----- First try to find 2-d info ------ - - call domain_read_dims_2d(domain, dimset, ncid, 'lsmlon', 'lsmlat') - call domain_read_dims_2d(domain, dimset, ncid, 'ni', 'nj') - call domain_read_dims_2d(domain, dimset, ncid, 'lon', 'lat') - - ! ----- If we haven't found 2-d info, try to find 1-d info ----- - - call domain_read_dims_1d(domain, dimset, ncid, 'num_pixels') - - ! ----- If we haven't found any info, abort ----- - - if (.not. dimset) then - write(6,*) trim(subname),' ERROR: dims not set' - call abort() - endif - - contains - -!---------------------------------------------------------------------------- -!BOP -! -! !IROUTINE: domain_read_dims_2d -! -! !INTERFACE: - subroutine domain_read_dims_2d(domain, dimset, ncid, lon_name, lat_name) -! -! !DESCRIPTION: -! Try to read 2-d dimension size information -! -! Checks whether the given lon_name is found in the netcdf file. If it is: -! (a) If dimset is already true, then it issues a warning and returns -! (b) If dimset is false, then this sets: -! - domain%ni -! - domain%nj -! - domain%ns -! - domain%is_2d -! - dimset = true -! -! If the given lon_name is not found, the above variables are left unchanged -! -! !ARGUMENTS: - implicit none - type(domain_type),intent(inout) :: domain - logical ,intent(inout) :: dimset ! has dimension information been set? - integer ,intent(in) :: ncid ! ID of an open netCDF file - character(len=*) ,intent(in) :: lon_name - character(len=*) ,intent(in) :: lat_name -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - include 'netcdf.inc' - integer :: dimid ! netCDF dimension id - integer :: nlon,nlat ! size - integer :: ier ! error status - - character(len= 32) :: subname = 'domain_read_dims_2d' - -!----------------------------------------------------------------- - - ier = nf_inq_dimid (ncid, lon_name, dimid) - if (ier == NF_NOERR) then - if (dimset) then - write(6,*) trim(subname),' WARNING: dimension sizes already set; skipping ', & - lon_name, '/', lat_name - else - write(6,*) trim(subname),' read lon and lat dims from ', lon_name, '/', lat_name - call check_ret(nf_inq_dimid (ncid, lon_name, dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, nlon), subname) - call check_ret(nf_inq_dimid (ncid, lat_name, dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, nlat), subname) - domain%ni = nlon - domain%nj = nlat - domain%ns = nlon * nlat - domain%is_2d = .true. - dimset = .true. - end if - endif - - end subroutine domain_read_dims_2d - - -!---------------------------------------------------------------------------- -!BOP -! -! !IROUTINE: domain_read_dims_1d -! -! !INTERFACE: - subroutine domain_read_dims_1d(domain, dimset, ncid, dim_name) -! -! !DESCRIPTION: -! Try to read 1-d dimension size information -! -! Checks whether the given dim_name is found in the netcdf file. If it is: -! (a) If dimset is already true, then it issues a warning and returns -! (b) If dimset is false, then this sets: -! - domain%ns -! - domain%is_2d -! - dimset = true -! -! If the given dim_name is not found, the above variables are left unchanged -! -! !ARGUMENTS: - implicit none - type(domain_type),intent(inout) :: domain - logical ,intent(inout) :: dimset ! has dimension information been set? - integer ,intent(in) :: ncid ! ID of an open netCDF file - character(len=*) ,intent(in) :: dim_name -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - include 'netcdf.inc' - integer :: dimid ! netCDF dimension id - integer :: npts ! size - integer :: ier ! error status - - character(len= 32) :: subname = 'domain_read_dims_1d' - -!----------------------------------------------------------------- - - ier = nf_inq_dimid (ncid, dim_name, dimid) - if (ier == NF_NOERR) then - if (dimset) then - write(6,*) trim(subname),' WARNING: dimension sizes already set; skipping ', dim_name - else - write(6,*) trim(subname),' read 1-d length from ', dim_name - call check_ret(nf_inq_dimid (ncid, dim_name, dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, npts), subname) - domain%ns = npts - domain%is_2d = .false. - dimset = .true. - end if - endif - - end subroutine domain_read_dims_1d - - end subroutine domain_read_dims - - -!---------------------------------------------------------------------------- -!BOP -! -! !IROUTINE: domain_write -! -! !INTERFACE: - subroutine domain_write(domain,fname) -! -! !DESCRIPTION: -! Write a domain to netcdf - -! !ARGUMENTS: - implicit none - include 'netcdf.inc' - type(domain_type),intent(inout) :: domain - character(len=*) ,intent(in) :: fname -! -! !REVISION HISTORY: -! Author: T Craig -! -! -! !LOCAL VARIABLES: -!EOP - integer :: varid !netCDF variable id - integer :: ncid !netCDF file id - integer :: omode !netCDF output mode - character(len= 32) :: subname = 'domain_write' -!----------------------------------------------------------------- - - call check_ret(nf_open(trim(fname), nf_write, ncid), subname) - ! File will be in define mode. Set fill mode to "no fill" to optimize performance - - call check_ret(nf_set_fill (ncid, nf_nofill, omode), subname) - - ! Write domain fields - - call check_ret(nf_inq_varid(ncid, 'AREA', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, domain%area), subname) - - call check_ret(nf_inq_varid(ncid, 'LONGXY', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, domain%lonc), subname) - - call check_ret(nf_inq_varid(ncid, 'LATIXY', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, domain%latc), subname) - - ! Synchronize the disk copy of a netCDF dataset with in-memory buffers - - call check_ret(nf_sync(ncid), subname) - - ! Close grid data dataset - - call check_ret(nf_close(ncid), subname) - - end subroutine domain_write - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: check_ret -! -! !INTERFACE: - subroutine check_ret(ret, calling) -! -! !DESCRIPTION: -! Check return status from netcdf call -! -! !ARGUMENTS: - implicit none - include 'netcdf.inc' - integer, intent(in) :: ret - character(len=*) :: calling -! -! !REVISION HISTORY: -! -!EOP -!----------------------------------------------------------------------- - - if (ret /= NF_NOERR) then - write(6,*)'netcdf error from ',trim(calling), ' rcode = ', ret, & - ' error = ', NF_STRERROR(ret) - call abort() - end if - - end subroutine check_ret - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: domain_checksame -! -! !INTERFACE: - subroutine domain_checksame( srcdomain, dstdomain, tgridmap ) -! -! !DESCRIPTION: -! Check that the input domains agree with the input map -! -! USES: - use mkgridmapMod, only : gridmap_type, gridmap_setptrs -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: srcdomain ! input domain - type(domain_type), intent(in) :: dstdomain ! output domain - type(gridmap_type),intent(in) :: tgridmap ! grid map -! -! !REVISION HISTORY: -! -!EOP -!----------------------------------------------------------------------- - integer :: na, nb, ns ! gridmap sizes - integer :: n, ni ! indices - real(r8), pointer :: xc_src(:) ! Source longitude - real(r8), pointer :: yc_src(:) ! Source latitude - integer, pointer :: src_indx(:) ! Source index - real(r8), pointer :: xc_dst(:) ! Destination longitude - real(r8), pointer :: yc_dst(:) ! Destination latitude - integer, pointer :: dst_indx(:) ! Destination index - character(len= 32) :: subname = 'domain_checksame' - - ! tolerance for checking equality of lat & lon - ! We allow for single-precision rounding-level differences (approx. 1.2e-7 relative - ! error) For a value of 360 (max value for lat / lon), this means we can allow - ! absolute errors of about 5e-5. - real(r8), parameter :: eps = 5.e-5_r8 - - - if (srcdomain%set == unset) then - write(6,*) trim(subname)//'ERROR: source domain is unset!' - call abort() - end if - if (dstdomain%set == unset) then - write(6,*) trim(subname)//'ERROR: destination domain is unset!' - call abort() - end if - - call gridmap_setptrs( tgridmap, nsrc=na, ndst=nb, ns=ns, & - xc_src=xc_src, yc_src=yc_src, & - xc_dst=xc_dst, yc_dst=yc_dst, & - src_indx=src_indx, dst_indx=dst_indx & - ) - - if (srcdomain%ns /= na) then - write(6,*) trim(subname)// & - ' ERROR: input domain size and gridmap source size are not the same size' - write(6,*)' domain size = ',srcdomain%ns - write(6,*)' map src size= ',na - call abort() - end if - if (dstdomain%ns /= nb) then - write(6,*) trim(subname)// & - ' ERROR: output domain size and gridmap destination size are not the same size' - write(6,*)' domain size = ',dstdomain%ns - write(6,*)' map dst size= ',nb - call abort() - end if - do n = 1,ns - ni = src_indx(n) - if (abs(srcdomain%lonc(ni) - xc_src(ni)) > eps) then - write(6,*) trim(subname)// & - ' ERROR: input domain lon and gridmap lon not the same at ni = ',ni - write(6,*)' domain lon= ',srcdomain%lonc(ni) - write(6,*)' gridmap lon= ',xc_src(ni) - call abort() - end if - if (abs(srcdomain%latc(ni) - yc_src(ni)) > eps) then - write(6,*) trim(subname)// & - ' ERROR: input domain lat and gridmap lat not the same at ni = ',ni - write(6,*)' domain lat= ',srcdomain%latc(ni) - write(6,*)' gridmap lat= ',yc_src(ni) - call abort() - end if - end do - do n = 1,ns - ni = dst_indx(n) - if (abs(dstdomain%lonc(ni) - xc_dst(ni)) > eps) then - write(6,*) trim(subname)// & - ' ERROR: output domain lon and gridmap lon not the same at ni = ',ni - write(6,*)' domain lon= ',dstdomain%lonc(ni) - write(6,*)' gridmap lon= ',xc_dst(ni) - call abort() - end if - if (abs(dstdomain%latc(ni) - yc_dst(ni)) > eps) then - write(6,*) trim(subname)// & - ' ERROR: output domain lat and gridmap lat not the same at ni = ',ni - write(6,*)' domain lat= ',dstdomain%latc(ni) - write(6,*)' gridmap lat= ',yc_dst(ni) - call abort() - end if - end do - end subroutine domain_checksame - - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: is_domain_0to360_longs -! -! !INTERFACE: - logical function is_domain_0to360_longs( domain ) -! -! !DESCRIPTION: -! Check if the domain has longitudes on a -180 to 180 grid or a 0 to 360 grid. -! CESM requires the later right now. -! -! USES: - use mkgridmapMod, only : gridmap_type, gridmap_setptrs -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: domain ! input domain -! -! !REVISION HISTORY: -! -!EOP -!----------------------------------------------------------------------- - if ( any(domain%lonc < 0.0_r8) )then - is_domain_0to360_longs = .false. - else - is_domain_0to360_longs = .true. - end if - end function is_domain_0to360_longs - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: for_test_create_domain -! -! !INTERFACE: - subroutine for_test_create_domain( domain ) -! -! !DESCRIPTION: -! Create a simple domain for unit testing -! -! USES: - implicit none -! !ARGUMENTS: - type(domain_type), intent(inout) :: domain ! input domain -! !LOCAL VARIABLES: - integer, parameter :: ns_o = 2 - - call domain_init( domain, ns_o ) - domain%latc = (/ 42.0_r8, 40.0_r8 /) - domain%lonc = (/ -105.0_r8, -100.0_r8 /) - domain%latn = (/ 43.0_r8, 41.0_r8 /) - domain%lats = (/ 41.0_r8, 39.0_r8 /) - domain%lone = (/ -104.0_r8, -99.0_r8 /) - domain%lonw = (/ -106.0_r8, -101.0_r8 /) - domain%mask = (/ 1, 1 /) - domain%frac = (/ 1.0_r8, 1.0_r8 /) - domain%area = (/ 49284.0_r8, 49284.0_r8 /) ! This is NOT the correct area! - - domain%edgen = maxval( domain%latn ) - domain%edges = minval( domain%lats ) - domain%edgew = minval( domain%lonw ) - domain%edgee = maxval( domain%lone ) - - domain%maskset = .true. - domain%fracset = .true. - domain%is_2d = .false. - - end subroutine for_test_create_domain - -end module mkdomainMod diff --git a/tools/mksurfdata_map/src/mkfileMod.F90 b/tools/mksurfdata_map/src/mkfileMod.F90 deleted file mode 100644 index 43bdda4c12..0000000000 --- a/tools/mksurfdata_map/src/mkfileMod.F90 +++ /dev/null @@ -1,566 +0,0 @@ -module mkfileMod - -contains - -!----------------------------------------------------------------------- - subroutine mkfile(domain, fname, harvdata, dynlanduse) - - use shr_kind_mod , only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_getenv - use fileutils , only : get_filename - use mkvarpar , only : nlevsoi, numrad, numstdpft - use mkvarctl - use mkurbanparMod, only : numurbl, nlevurb - use mkglcmecMod , only : nglcec - use mkpftMod , only : mkpftAtt - use mksoilMod , only : mksoilAtt - use mkharvestMod , only : mkharvest_fieldname, mkharvest_numtypes, mkharvest_longname - use mkharvestMod , only : mkharvest_units, harvestDataType - use mkncdio , only : check_ret, ncd_defvar, ncd_def_spatial_var - use mkdomainMod - - implicit none - include 'netcdf.inc' - type(domain_type) , intent(in) :: domain - character(len=*) , intent(in) :: fname - logical , intent(in) :: dynlanduse - type(harvestDataType), intent(in) :: harvdata - - integer :: ncid - integer :: j ! index - integer :: dimid ! temporary - integer :: values(8) ! temporary - character(len=256) :: str ! global attribute string - character(len=256) :: name ! name of attribute - character(len=256) :: unit ! units of attribute - character(len= 18) :: datetime ! temporary - character(len= 8) :: date ! temporary - character(len= 10) :: time ! temporary - character(len= 5) :: zone ! temporary - integer :: ier ! error status - integer :: omode ! netCDF output mode - integer :: xtype ! external type - integer, allocatable :: ind1D(:)! Indices of 1D harvest variables - integer, allocatable :: ind2D(:)! Indices of 2D harvest variables - character(len=32) :: subname = 'mkfile' ! subroutine name -!----------------------------------------------------------------------- - - call check_ret(nf_create(trim(fname), ior(nf_clobber,nf_64bit_offset), & - ncid), subname) - - call check_ret(nf_set_fill (ncid, nf_nofill, omode), subname) - - ! Define dimensions. - - if (outnc_1d) then - call check_ret(nf_def_dim (ncid, 'gridcell', domain%ns, dimid), subname) - else - call check_ret(nf_def_dim (ncid, 'lsmlon' , domain%ni, dimid), subname) - call check_ret(nf_def_dim (ncid, 'lsmlat' , domain%nj, dimid), subname) - end if - - if (.not. dynlanduse) then - call check_ret(nf_def_dim (ncid, 'nglcec' , nglcec , dimid), subname) - call check_ret(nf_def_dim (ncid, 'nglcecp1', nglcec+1 , dimid), subname) - end if - call check_ret(nf_def_dim (ncid, 'numurbl' , numurbl , dimid), subname) - call check_ret(nf_def_dim (ncid, 'nlevurb' , nlevurb , dimid), subname) - call check_ret(nf_def_dim (ncid, 'numrad' , numrad , dimid), subname) - call check_ret(nf_def_dim (ncid, 'nchar' , 256 , dimid), subname) - - ! Create global attributes. - - str = 'NCAR-CSM' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'Conventions', len_trim(str), trim(str)), subname) - - call date_and_time (date, time, zone, values) - datetime(1:8) = date(5:6) // '-' // date(7:8) // '-' // date(3:4) - datetime(9:) = ' ' // time(1:2) // ':' // time(3:4) // ':' // time(5:6) // ' ' - str = 'created on: ' // datetime - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'History_Log', len_trim(str), trim(str)), subname) - - call shr_sys_getenv ('LOGNAME', str, ier) - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'Logname', len_trim(str), trim(str)), subname) - - call shr_sys_getenv ('HOST', str, ier) - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'Host', len_trim(str), trim(str)), subname) - - str = 'Community Land Model: CLM5' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'Source', len_trim(str), trim(str)), subname) - - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'Version', len_trim(gitdescribe), trim(gitdescribe)), subname) - -#ifdef OPT - str = 'TRUE' -#else - str = 'FALSE' -#endif - - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'Compiler_Optimized', len_trim(str), trim(str)), subname) - - if ( all_urban )then - str = 'TRUE' - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'all_urban', len_trim(str), trim(str)), subname) - end if - - if ( no_inlandwet )then - str = 'TRUE' - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'no_inlandwet', len_trim(str), trim(str)), subname) - end if - - call check_ret(nf_put_att_int(ncid, NF_GLOBAL, & - 'nglcec', nf_int, 1, nglcec), subname) - - ! Raw data file names - - str = get_filename(mksrf_fgrid) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Input_grid_dataset', len_trim(str), trim(str)), subname) - - str = trim(mksrf_gridtype) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Input_gridtype', len_trim(str), trim(str)), subname) - - if (.not. dynlanduse) then - str = get_filename(mksrf_fvocef) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'VOC_EF_raw_data_file_name', len_trim(str), trim(str)), subname) - end if - - str = get_filename(mksrf_flakwat) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Inland_lake_raw_data_file_name', len_trim(str), trim(str)), subname) - - str = get_filename(mksrf_fwetlnd) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Inland_wetland_raw_data_file_name', len_trim(str), trim(str)), subname) - - str = get_filename(mksrf_fglacier) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Glacier_raw_data_file_name', len_trim(str), trim(str)), subname) - - str = get_filename(mksrf_fglacierregion) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Glacier_region_raw_data_file_name', len_trim(str), trim(str)), subname) - - str = get_filename(mksrf_furbtopo) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Urban_Topography_raw_data_file_name', len_trim(str), trim(str)), subname) - - str = get_filename(mksrf_furban) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Urban_raw_data_file_name', len_trim(str), trim(str)), subname) - - if (.not. dynlanduse .and. (numpft == numstdpft) ) then - str = get_filename(mksrf_flai) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Lai_raw_data_file_name', len_trim(str), trim(str)), subname) - end if - - str = get_filename(mksrf_fabm) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'agfirepkmon_raw_data_file_name', len_trim(str), trim(str)), subname) - - str = get_filename(mksrf_fgdp) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'gdp_raw_data_file_name', len_trim(str), trim(str)), subname) - - str = get_filename(mksrf_fpeat) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'peatland_raw_data_file_name', len_trim(str), trim(str)), subname) - - str = get_filename(mksrf_fsoildepth) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'soildepth_raw_data_file_name', len_trim(str), trim(str)), subname) - - str = get_filename(mksrf_ftopostats) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'topography_stats_raw_data_file_name', len_trim(str), trim(str)), subname) - - if ( outnc_vic )then - str = get_filename(mksrf_fvic) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'vic_raw_data_file_name', len_trim(str), trim(str)), subname) - end if - - ! Mapping file names - - str = get_filename(map_fpft) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_pft_file_name', len_trim(str), trim(str)), subname) - - str = get_filename(map_flakwat) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_lakwat_file', len_trim(str), trim(str)), subname) - - str = get_filename(map_fwetlnd) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_wetlnd_file', len_trim(str), trim(str)), subname) - - str = get_filename(map_fglacier) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_glacier_file', len_trim(str), trim(str)), subname) - - str = get_filename(map_fglacierregion) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_glacier_region_file', len_trim(str), trim(str)), subname) - - str = get_filename(map_fsoitex) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_soil_texture_file', len_trim(str), trim(str)), subname) - - str = get_filename(map_fsoicol) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_soil_color_file', len_trim(str), trim(str)), subname) - - str = get_filename(map_forganic) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_soil_organic_file', len_trim(str), trim(str)), subname) - - str = get_filename(map_furban) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_urban_file', len_trim(str), trim(str)), subname) - - str = get_filename(map_fmax) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_fmax_file', len_trim(str), trim(str)), subname) - - str = get_filename(map_fvocef) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_VOC_EF_file', len_trim(str), trim(str)), subname) - - str = get_filename(map_fharvest) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_harvest_file', len_trim(str), trim(str)), subname) - - if ( numpft == numstdpft )then - str = get_filename(map_flai) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_lai_sai_file', len_trim(str), trim(str)), subname) - end if - - str = get_filename(map_furbtopo) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_urban_topography_file', len_trim(str), trim(str)), subname) - - str = get_filename(map_fabm) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_agfirepkmon_file', len_trim(str), trim(str)), subname) - - str = get_filename(map_fgdp) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_gdp_file', len_trim(str), trim(str)), subname) - - str = get_filename(map_fpeat) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_peatland_file', len_trim(str), trim(str)), subname) - - str = get_filename(map_fsoildepth) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_soildepth_file', len_trim(str), trim(str)), subname) - - str = get_filename(map_ftopostats) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_topography_stats_file', len_trim(str), trim(str)), subname) - - if ( outnc_vic )then - str = get_filename(map_fvic) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'map_vic_file', len_trim(str), trim(str)), subname) - end if - - ! ---------------------------------------------------------------------- - ! Define variables - ! ---------------------------------------------------------------------- - - if ( .not. outnc_double )then - xtype = nf_float - else - xtype = nf_double - end if - - call mksoilAtt( ncid, dynlanduse, xtype ) - - call mkpftAtt( ncid, dynlanduse, xtype ) - - call ncd_def_spatial_var(ncid=ncid, varname='AREA' , xtype=nf_double, & - long_name='area', units='km^2') - - call ncd_def_spatial_var(ncid=ncid, varname='LONGXY', xtype=nf_double, & - long_name='longitude', units='degrees east') - - call ncd_def_spatial_var(ncid=ncid, varname='LATIXY', xtype=nf_double, & - long_name='latitude', units='degrees north') - - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='EF1_BTR', xtype=xtype, & - long_name='EF btr (isoprene)', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='EF1_FET', xtype=xtype, & - long_name='EF fet (isoprene)', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='EF1_FDT', xtype=xtype, & - long_name='EF fdt (isoprene)', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='EF1_SHR', xtype=xtype, & - long_name='EF shr (isoprene)', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='EF1_GRS', xtype=xtype, & - long_name='EF grs (isoprene)', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='EF1_CRP', xtype=xtype, & - long_name='EF crp (isoprene)', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='CANYON_HWR', xtype=xtype, & - lev1name='numurbl', & - long_name='canyon height to width ratio', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='EM_IMPROAD', xtype=xtype, & - lev1name='numurbl', & - long_name='emissivity of impervious road', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='EM_PERROAD', xtype=xtype, & - lev1name='numurbl', & - long_name='emissivity of pervious road', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='EM_ROOF', xtype=xtype, & - lev1name='numurbl', & - long_name='emissivity of roof', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='EM_WALL', xtype=xtype, & - lev1name='numurbl', & - long_name='emissivity of wall', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='HT_ROOF', xtype=xtype, & - lev1name='numurbl', & - long_name='height of roof', units='meters') - - call ncd_def_spatial_var(ncid=ncid, varname='THICK_ROOF', xtype=xtype, & - lev1name='numurbl', & - long_name='thickness of roof', units='meters') - - call ncd_def_spatial_var(ncid=ncid, varname='THICK_WALL', xtype=xtype, & - lev1name='numurbl', & - long_name='thickness of wall', units='meters') - - call ncd_def_spatial_var(ncid=ncid, varname='T_BUILDING_MIN', xtype=xtype, & - lev1name='numurbl', & - long_name='minimum interior building temperature', units='K') - - call ncd_def_spatial_var(ncid=ncid, varname='WIND_HGT_CANYON', xtype=xtype, & - lev1name='numurbl', & - long_name='height of wind in canyon', units='meters') - - call ncd_def_spatial_var(ncid=ncid, varname='WTLUNIT_ROOF', xtype=xtype, & - lev1name='numurbl', & - long_name='fraction of roof', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='WTROAD_PERV', xtype=xtype, & - lev1name='numurbl', & - long_name='fraction of pervious road', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='ALB_IMPROAD_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='direct albedo of impervious road', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='ALB_IMPROAD_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='diffuse albedo of impervious road', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='ALB_PERROAD_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='direct albedo of pervious road', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='ALB_PERROAD_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='diffuse albedo of pervious road', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='ALB_ROOF_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='direct albedo of roof', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='ALB_ROOF_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='diffuse albedo of roof', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='ALB_WALL_DIR', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='direct albedo of wall', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='ALB_WALL_DIF', xtype=xtype, & - lev1name='numurbl', lev2name='numrad', & - long_name='diffuse albedo of wall', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='TK_ROOF', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='thermal conductivity of roof', units='W/m*K') - - call ncd_def_spatial_var(ncid=ncid, varname='TK_WALL', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='thermal conductivity of wall', units='W/m*K') - - call ncd_def_spatial_var(ncid=ncid, varname='TK_IMPROAD', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='thermal conductivity of impervious road', units='W/m*K') - - call ncd_def_spatial_var(ncid=ncid, varname='CV_ROOF', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='volumetric heat capacity of roof', units='J/m^3*K') - - call ncd_def_spatial_var(ncid=ncid, varname='CV_WALL', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='volumetric heat capacity of wall', units='J/m^3*K') - - call ncd_def_spatial_var(ncid=ncid, varname='CV_IMPROAD', xtype=xtype, & - lev1name='numurbl', lev2name='nlevurb', & - long_name='volumetric heat capacity of impervious road', units='J/m^3*K') - - call ncd_def_spatial_var(ncid=ncid, varname='NLEV_IMPROAD', xtype=nf_int, & - lev1name='numurbl', & - long_name='number of impervious road layers', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='peatf', xtype=xtype, & - long_name='peatland fraction', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='zbedrock', xtype=xtype, & - long_name='soil depth', units='m') - - call ncd_def_spatial_var(ncid=ncid, varname='abm', xtype=nf_int, & - long_name='agricultural fire peak month', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='gdp', xtype=xtype, & - long_name='gdp', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='SLOPE', xtype=xtype, & - long_name='mean topographic slope', units='degrees') - - call ncd_def_spatial_var(ncid=ncid, varname='STD_ELEV', xtype=xtype, & - long_name='standard deviation of elevation', units='m') - - if ( outnc_vic )then - call ncd_def_spatial_var(ncid=ncid, varname='binfl', xtype=xtype, & - long_name='VIC b parameter for the Variable Infiltration Capacity Curve', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='Ws', xtype=xtype, & - long_name='VIC Ws parameter for the ARNO curve', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='Dsmax', xtype=xtype, & - long_name='VIC Dsmax parameter for the ARNO curve', units='mm/day') - - call ncd_def_spatial_var(ncid=ncid, varname='Ds', xtype=xtype, & - long_name='VIC Ds parameter for the ARNO curve', units='unitless') - - end if - call ncd_def_spatial_var(ncid=ncid, varname='LAKEDEPTH', xtype=xtype, & - long_name='lake depth', units='m') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_WETLAND', xtype=xtype, & - long_name='percent wetland', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_LAKE', xtype=xtype, & - long_name='percent lake', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_GLACIER', xtype=xtype, & - long_name='percent glacier', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='GLACIER_REGION', xtype=nf_int, & - long_name='glacier region ID', units='unitless') - - call ncd_defvar(ncid=ncid, varname='GLC_MEC', xtype=xtype, & - dim1name='nglcecp1', long_name='Glacier elevation class', units='m') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_GLC_MEC', xtype=xtype, & - lev1name='nglcec', & - long_name='percent glacier for each glacier elevation class (% of landunit)', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='TOPO_GLC_MEC', xtype=xtype, & - lev1name='nglcec', & - long_name='mean elevation on glacier elevation classes', units='m') - - if ( outnc_3dglc ) then - call ncd_def_spatial_var(ncid=ncid, varname='PCT_GLC_MEC_GIC', xtype=xtype, & - lev1name='nglcec', & - long_name='percent smaller glaciers and ice caps for each glacier elevation class (% of landunit)', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_GLC_MEC_ICESHEET', xtype=xtype, & - lev1name='nglcec', & - long_name='percent ice sheet for each glacier elevation class (% of landunit)', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_GLC_GIC', xtype=xtype, & - long_name='percent ice caps/glaciers (% of landunit)', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_GLC_ICESHEET', xtype=xtype, & - long_name='percent ice sheet (% of landunit)', units='unitless') - - end if - - if ( outnc_3dglc ) then - call ncd_def_spatial_var(ncid=ncid, varname='PCT_GLC_MEC_GIC', xtype=xtype, & - lev1name='nglcec', & - long_name='percent smaller glaciers and ice caps for each glacier elevation class (% of landunit)', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_GLC_MEC_ICESHEET', xtype=xtype, & - lev1name='nglcec', & - long_name='percent ice sheet for each glacier elevation class (% of landunit)', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_GLC_GIC', xtype=xtype, & - long_name='percent ice caps/glaciers (% of landunit)', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_GLC_ICESHEET', xtype=xtype, & - long_name='percent ice sheet (% of landunit)', units='unitless') - - end if - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_URBAN', xtype=xtype, & - lev1name='numurbl', & - long_name='percent urban for each density type', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='URBAN_REGION_ID', xtype=nf_int, & - long_name='urban region ID', units='unitless') - - call harvdata%getFieldsIdx( ind1D, ind2D ) - do j = 1, harvdata%num1Dfields() - call ncd_def_spatial_var(ncid=ncid, varname=mkharvest_fieldname(ind1D(j),constant=.true.), xtype=xtype, & - long_name=mkharvest_longname(ind1D(j)), units=mkharvest_units(ind1D(j)) ) - end do - do j = 1, harvdata%num2Dfields() - call ncd_def_spatial_var(ncid=ncid, varname=mkharvest_fieldname(ind2D(j),constant=.true.), xtype=xtype, & - lev1name=harvdata%getFieldsDim(ind2D(j)), & - long_name=mkharvest_longname(ind2D(j)), units=mkharvest_units(ind2D(j)) ) - end do - deallocate(ind1D, ind2D) - - else - - call harvdata%getFieldsIdx( ind1D, ind2D ) - do j = 1, harvdata%num1Dfields() - call ncd_def_spatial_var(ncid=ncid, varname=mkharvest_fieldname(ind1D(j),constant=.false.), xtype=xtype, & - lev1name='time', & - long_name=mkharvest_longname(ind1D(j)), units=mkharvest_units(ind1D(j)) ) - end do - do j = 1, harvdata%num2Dfields() - call ncd_def_spatial_var(ncid=ncid, varname=mkharvest_fieldname(ind2D(j),constant=.false.), xtype=xtype, & - lev1name=harvdata%getFieldsDim(ind2D(j)), lev2name="time", & - long_name=mkharvest_longname(ind2D(j)), units=mkharvest_units(ind2D(j)) ) - end do - deallocate(ind1D, ind2D) - - end if ! .not. dynlanduse - - ! End of define mode - - call check_ret(nf_enddef(ncid), subname) - call check_ret(nf_close(ncid), subname) - - end subroutine mkfile - -end module mkfileMod diff --git a/tools/mksurfdata_map/src/mkgdpMod.F90 b/tools/mksurfdata_map/src/mkgdpMod.F90 deleted file mode 100644 index 138ddf1805..0000000000 --- a/tools/mksurfdata_map/src/mkgdpMod.F90 +++ /dev/null @@ -1,147 +0,0 @@ -module mkgdpMod - -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkgdpMod -! -! !DESCRIPTION: -! make GDP from input GDP data -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -!----------------------------------------------------------------------- -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - use mkdomainMod , only : domain_checksame - - implicit none - - private - -! !PUBLIC MEMBER FUNCTIONS: - public mkgdp ! regrid gdp data -! -!EOP -!=============================================================== -contains -!=============================================================== - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkgdp -! -! !INTERFACE: -subroutine mkgdp(ldomain, mapfname, datfname, ndiag, gdp_o) -! -! !DESCRIPTION: -! make GDP from input GDP data -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_continuous - use mkchecksMod, only : min_bad -! -! !ARGUMENTS: - - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: gdp_o(:) ! output grid: GDP (x1000 1995 US$ per capita) -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: data_i(:) ! data on input grid - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - - real(r8), parameter :: min_valid = 0._r8 ! minimum valid value - - character(len=32) :: subname = 'mkgdp' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make GDP.....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - call domain_read(tdomain,datfname) - - call gridmap_mapread(tgridmap, mapfname ) - - ! Obtain frac_dst - allocate(frac_dst(ldomain%ns), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write(6,*)'Open GDP file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(data_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() - - ! ----------------------------------------------------------------- - ! Regrid gdp - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'gdp', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, gdp_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(gdp_o, min_valid, 'gdp')) then - call abort() - end if - - call output_diagnostics_continuous(data_i, gdp_o, tgridmap, "GDP", "x1000 US$ per capita", ndiag, tdomain%mask, frac_dst) - - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- - - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (data_i) - deallocate (frac_dst) - deallocate (mask_r8) - - write (6,*) 'Successfully made GDP' - write (6,*) - call shr_sys_flush(6) - -end subroutine mkgdp - -end module mkgdpMod diff --git a/tools/mksurfdata_map/src/mkglacierregionMod.F90 b/tools/mksurfdata_map/src/mkglacierregionMod.F90 deleted file mode 100644 index e644129ed3..0000000000 --- a/tools/mksurfdata_map/src/mkglacierregionMod.F90 +++ /dev/null @@ -1,139 +0,0 @@ -module mkglacierregionMod - - !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mkglacierregionMod - ! - ! !DESCRIPTION: - ! make glacier region ID - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! - !----------------------------------------------------------------------- - ! - ! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - implicit none - - private - - ! !PUBLIC MEMBER FUNCTIONS: - public mkglacierregion ! make glacier region ID - ! - !EOP - -contains - - !----------------------------------------------------------------------- - subroutine mkglacierregion(ldomain, mapfname, datfname, ndiag, & - glacier_region_o) - ! - ! !DESCRIPTION: - ! Make glacier region ID - ! - ! Regridding is done by finding the max index that overlaps each destination cell, - ! without regard to the weight of overlap or dominance of each overlapping index. - ! - ! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read, domain_checksame - use mkgridmapMod - use mkncdio - use mkindexmapMod, only : get_max_indices - use mkdiagnosticsMod, only : output_diagnostics_index - use mkchecksMod, only : min_bad - ! - ! !ARGUMENTS: - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - integer , intent(out) :: glacier_region_o(:) ! glacier region - ! - ! !LOCAL VARIABLES: - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - integer, allocatable :: glacier_region_i(:) ! glacier region on input grid - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - integer :: max_region ! max region ID - - character(len=*), parameter :: subname = 'mkglacierregion' - !----------------------------------------------------------------------- - - write (6,*) 'Attempting to make glacier region .....' - call shr_sys_flush(6) - - ! ------------------------------------------------------------------------ - ! Read domain and mapping information, check for consistency - ! ------------------------------------------------------------------------ - - call domain_read(tdomain, datfname) - - call gridmap_mapread(tgridmap, mapfname) - - ! Obtain frac_dst - allocate(frac_dst(ldomain%ns), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check(tgridmap, mask_r8, frac_dst, subname) - - call domain_checksame(tdomain, ldomain, tgridmap) - - ! ------------------------------------------------------------------------ - ! Open input file, allocate memory for input data - ! ------------------------------------------------------------------------ - - write (6,*) 'Open glacier region raw data file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(glacier_region_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() - - ! ------------------------------------------------------------------------ - ! Regrid glacier_region - ! ------------------------------------------------------------------------ - - call check_ret(nf_inq_varid(ncid, 'GLACIER_REGION', varid), subname) - call check_ret(nf_get_var_int(ncid, varid, glacier_region_i), subname) - if (min_bad(glacier_region_i, 0, 'GLACIER_REGION')) then - call abort() - end if - - call get_max_indices( & - gridmap = tgridmap, & - src_array = glacier_region_i, & - dst_array = glacier_region_o, & - nodata = 0, & - mask_src = tdomain%mask) - - max_region = maxval(glacier_region_i) - call output_diagnostics_index(glacier_region_i, glacier_region_o, tgridmap, & - 'Glacier Region ID', 0, max_region, ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! ------------------------------------------------------------------------ - ! Deallocate dynamic memory & other clean up - ! ------------------------------------------------------------------------ - - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate(glacier_region_i) - deallocate(frac_dst) - deallocate(mask_r8) - - write (6,*) 'Successfully made glacier region' - write (6,*) - call shr_sys_flush(6) - - end subroutine mkglacierregion - -end module mkglacierregionMod diff --git a/tools/mksurfdata_map/src/mkglcmecMod.F90 b/tools/mksurfdata_map/src/mkglcmecMod.F90 deleted file mode 100644 index 9fbad66689..0000000000 --- a/tools/mksurfdata_map/src/mkglcmecMod.F90 +++ /dev/null @@ -1,794 +0,0 @@ -module mkglcmecMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkglcmecMod -! -! !DESCRIPTION: -! Make glacier multi-elevation class data -! -! !REVISION HISTORY: -! Author: Erik Kluzek, Mariana Vertenstein -! -!----------------------------------------------------------------------- -!!USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - use mkdomainMod , only : domain_checksame - implicit none - - private ! By default make data private -! -! !PUBLIC MEMBER FUNCTIONS: -! - public mkglcmecInit ! Initialization - public mkglcmec ! Set glacier multi-elevation class - public mkglacier ! Set percent glacier -! -! !PUBLIC DATA MEMBERS: -! - integer, public :: nglcec = 10 ! number of elevation classes for glaciers - real(r8), pointer :: elevclass(:) ! elevation classes -! -! !PRIVATE MEMBER FUNCTIONS: - private get_elevclass ! get elevation class index - private mean_elevation_vc ! get the elevation of a virtual column -!EOP -!=============================================================== -contains -!=============================================================== - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkglcmecInit -! -! !INTERFACE: -subroutine mkglcmecInit( elevclass_o ) -! -! !DESCRIPTION: -! Initialize of Make glacier multi-elevation class data -! !USES: -! -! !ARGUMENTS: - implicit none - real(r8), intent(OUT) :: elevclass_o(:) ! elevation classes -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - character(len=32) :: subname = 'mkglcmecInit:: ' -!----------------------------------------------------------------------- - allocate( elevclass(nglcec+1) ) - - ! ----------------------------------------------------------------- - ! Define elevation classes, represents lower boundary of each class - ! ----------------------------------------------------------------- - - if ( nglcec == 36 )then - elevclass(:) = (/ 0., 200., 400., 600., 800., & - 1000., 1200., 1400., 1600., 1800., & - 2000., 2200., 2400., 2600., 2800., & - 3000., 3200., 3400., 3600., 3800., & - 4000., 4200., 4400., 4600., 4800., & - 5000., 5200., 5400., 5600., 5800., & - 6000., 6200., 6400., 6600., 6800., & - 7000., 10000./) - else if ( nglcec == 10 )then - elevclass(1) = 0. - elevclass(2) = 200. - elevclass(3) = 400. - elevclass(4) = 700. - elevclass(5) = 1000. - elevclass(6) = 1300. - elevclass(7) = 1600. - elevclass(8) = 2000. - elevclass(9) = 2500. - elevclass(10) = 3000. - elevclass(11) = 10000. - else if ( nglcec == 5 )then - elevclass(1) = 0. - elevclass(2) = 500. - elevclass(3) = 1000. - elevclass(4) = 1500. - elevclass(5) = 2000. - elevclass(6) = 10000. - else if ( nglcec == 3 )then - elevclass(1) = 0. - elevclass(2) = 1000. - elevclass(3) = 2000. - elevclass(4) = 10000. - else if ( nglcec == 1 )then - elevclass(1) = 0. - elevclass(2) = 10000. - else - write(6,*) subname//"ERROR:: nglcec must be 1, 3, 5, 10 or 36",& - " to work with CLM: " - call abort() - end if - - elevclass_o(:) = elevclass(:) - -end subroutine mkglcmecInit - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkglcmec -! -! !INTERFACE: -subroutine mkglcmec(ldomain, mapfname, & - datfname_fglacier, ndiag, & - pctglcmec_o, topoglcmec_o, & - pctglcmec_gic_o, pctglcmec_icesheet_o, & - pctglc_gic_o, pctglc_icesheet_o) -! -! !DESCRIPTION: -! make percent glacier on multiple elevation classes, mean elevation for each -! elevation class, and associated fields -! -! Note that the raw glacier data are specified by level, and thus implicitly include the -! necessary topo data for breaking pct glacier into elevation classes. Each level in the -! input data is assigned to an elevation (given by BIN_CENTERS in the input data). Thus, -! all of the input glacier in level 1 is treated as being at the same elevation, and -! likewise for each other level. These elevations are then used in assigning pct_glacier -! to the appropriate elevation class in the output data, as well as determining the mean -! topographic height of each elevation class in the output data. -! -! Note that the various percentages computed here are given as % of the glc_mec landunit. -! If the input glacier area is 0 for a given grid cell, this requires setting these % -! variables in an arbitrary way. -! -! !USES: - use shr_sys_mod, only : shr_sys_abort - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkutilsMod, only : slightly_below, slightly_above - use mkncdio - use mkvarctl , only : outnc_3dglc -! -! !ARGUMENTS: - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname_fglacier ! raw glacier data - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: pctglcmec_o (:,:) ! % for each elevation class on output glacier grid (% of landunit) - real(r8) , intent(out):: topoglcmec_o(:,:) ! mean elevation for each elevation classs on output glacier grid - real(r8), optional, intent(out):: pctglcmec_gic_o(:,:) ! % glc gic on output grid, by elevation class (% of landunit) - real(r8), optional, intent(out):: pctglcmec_icesheet_o(:,:) ! % glc ice sheet on output grid, by elevation class (% of landunit) - real(r8), optional, intent(out):: pctglc_gic_o(:) ! % glc gic on output grid, summed across elevation classes (% of landunit) - real(r8), optional, intent(out):: pctglc_icesheet_o(:) ! % glc ice sheet on output grid, summed across elevation classes (% of landunit) -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: David Lawrence -! 7/12/11: Bill Sacks: substantial rewrite to use input topo and % glacier at same resolution -! 9/25/12: Bill Sacks: substantial rewrite to use new format of fglacier, which provides -! percent by elevation bin (thus the separate topo dataset is no longer needed -! in this routine) -! -! -! !LOCAL VARIABLES: -!EOP - type(domain_type) :: tdomain ! local domain - type(gridmap_type) :: tgridmap ! local gridmap - real(r8), allocatable :: pctglc_gic_i(:) ! input GIC percentage for a single level - real(r8), allocatable :: pctglc_icesheet_i(:) ! input icesheet percentage for a single level - real(r8), allocatable :: topoglcmec_unnorm_o(:,:) ! same as topoglcmec_o, but unnormalized - real(r8), allocatable :: pctglc_tot_o(:) ! total glacier cover for the grid cell - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8) :: topoice_i ! topographic height of this level - real(r8) :: pctglc_i ! input total pct glacier for a single level & single point - real(r8) :: wt, frac ! weighting factors for remapping - integer :: ndims ! number of dimensions in input variables - integer :: dim_lengths(nf_max_var_dims) ! lengths of dimensions in input variables - integer, allocatable :: starts(:), counts(:) ! start indices & counts for reading variable slices - integer :: ni,no,ns_o,nst,lev ! indices - integer :: n,m ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: nlev ! number of levels in input file - real(r8) :: glc_sum ! temporary - integer :: ier ! error status - logical :: errors ! error status - - real(r8), parameter :: eps = 2.e-5_r8 ! epsilon for error checks (note that we use a large-ish value - ! because data are stored as single-precision floats in the - ! raw dataset) - real(r8), parameter :: eps_small = 1.e-12_r8 ! epsilon for error checks that expect close match - character(len=32) :: subname = 'mkglcmec' -!----------------------------------------------------------------------- - - ! Initialize all output fields to zero - - pctglcmec_o(:,:) = 0. - topoglcmec_o(:,:) = 0. - if ( outnc_3dglc )then - if ( (.not. present(pctglcmec_gic_o)) .or. (.not. present(pctglcmec_icesheet_o)) .or. & - (.not. present(pctglc_gic_o) ) .or. (.not. present(pctglc_icesheet_o) ) )then - call shr_sys_abort( subname//' ERROR: 3D glacier fields were NOT sent in and they are required' ) - end if - pctglcmec_gic_o(:,:) = 0. - pctglcmec_icesheet_o(:,:) = 0. - pctglc_gic_o(:) = 0. - pctglc_icesheet_o(:) = 0. - end if - - ! Set number of output points - - ns_o = ldomain%ns - - write (6,*) 'Attempting to make percent elevation class ',& - 'and mean elevation for glaciers .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read domain and dimension information from glacier raw data file - ! ----------------------------------------------------------------- - - call domain_read(tdomain,datfname_fglacier) - nst = tdomain%ns - - ! Read z dimension size - write (6,*) 'Open glacier file: ', trim(datfname_fglacier) - call check_ret(nf_open(datfname_fglacier, 0, ncid), subname) - ier = nf_inq_dimid (ncid, 'z', dimid) - if (ier /= NF_NOERR) then - write (6,*) trim(subname), ' ERROR: z dimension not found on glacier file:' - write (6,*) trim(datfname_fglacier) - write (6,*) 'Perhaps you are trying to use an old-format glacier file?' - write (6,*) '(prior to Sept., 2012)' - call abort() - end if - call check_ret(nf_inq_dimlen (ncid, dimid, nlev), subname) - - ! ----------------------------------------------------------------- - ! Read mapping data, check for consistency with domains - ! ----------------------------------------------------------------- - - ! Mapping for raw glacier -> model output grid - call gridmap_mapread(tgridmap, mapfname ) - - ! Error checks for domain and map consistencies - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Determine dimension lengths and create start & count arrays - ! for later reading one level at a time - ! ----------------------------------------------------------------- - - call get_dim_lengths(ncid, 'PCT_GLC_GIC', ndims, dim_lengths) - - allocate(starts(ndims), counts(ndims), stat=ier) - if (ier/=0) call abort() - - starts(1:ndims) = 1 - - ! We assume that the last dimension is the level dimension - counts(1:ndims-1) = dim_lengths(1:ndims-1) - counts(ndims) = 1 - - ! -------------------------------------------------------------------- - ! Compute fields on the output grid - ! -------------------------------------------------------------------- - - allocate(pctglc_gic_i(nst), pctglc_icesheet_i(nst), stat=ier) - if (ier/=0) call abort() - - allocate(topoglcmec_unnorm_o(ns_o,nglcec), stat=ier) - if (ier/=0) call abort() - - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() - - topoglcmec_unnorm_o(:,:) = 0. - - write(6,'(a,i4,a)',advance='no') 'Level (out of ', nlev, '): ' - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - do lev = 1, nlev - write(6,'(i4)',advance='no') lev - flush(6) - - ! Read this level's data - ! We assume that the last dimension is the level dimension - starts(ndims) = lev - call check_ret(nf_inq_varid (ncid, 'BIN_CENTERS', varid), subname) - call check_ret(nf_get_vara_double (ncid, varid, (/lev/), (/1/), topoice_i), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_GLC_GIC', varid), subname) - call check_ret(nf_get_vara_double (ncid, varid, starts, counts, pctglc_gic_i), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_GLC_ICESHEET', varid), subname) - call check_ret(nf_get_vara_double (ncid, varid, starts, counts, pctglc_icesheet_i), subname) - - ! Determine elevation class - m = get_elevclass(topoice_i) - if (m < 1 .or. m > nglcec) then - call abort() - end if - - do n = 1,tgridmap%ns - ni = tgridmap%src_indx(n) - no = tgridmap%dst_indx(n) - wt = tgridmap%wovr(n) * tdomain%mask(ni) - - ! fraction of this destination cell that is covered by source cells that are within the source landmask - frac = frac_dst(no) - - ! If frac == 0, then we can't do this, to avoid divide by 0. In this case, the - ! outputs remain equal to 0 (their initialized value). - if (frac > 0) then - pctglc_i = pctglc_gic_i(ni) + pctglc_icesheet_i(ni) - pctglcmec_o(no,m) = pctglcmec_o(no,m) + wt*pctglc_i / frac - if ( outnc_3dglc )then - pctglcmec_gic_o(no,m) = pctglcmec_gic_o(no,m) + wt*pctglc_gic_i(ni) / frac - pctglcmec_icesheet_o(no,m) = pctglcmec_icesheet_o(no,m) + wt*pctglc_icesheet_i(ni) / frac - end if - - ! note that, by weighting the following by pctglc_i, we are getting something - ! like the average topographic height over glaciated areas - NOT the average - ! topographic height of the entire grid cell - topoglcmec_unnorm_o(no,m) = topoglcmec_unnorm_o(no,m) + wt*pctglc_i*topoice_i / frac - end if - end do - end do - - ! Note: at this point, the various percentages are given as % of grid cell; below, we - ! renormalize these to be given as % of landunit. - - ! advance to next line (needed because of 'advance=no' writes above) - write(6,*) ' ' - - ! Close glacier input file - call check_ret(nf_close(ncid), subname) - - ! Normalize topoglcmec_o. To do this, note that pctglcmec_o(n,m) is equal to the sum of - ! the weights used in doing the weighted average of topoice_i (weight = - ! wt*pctglc_i/frac); hence pctglcmec_o(n,m) is the correct normalization factor - do no = 1,ns_o - do m = 1,nglcec - if (pctglcmec_o(no,m) > 0) then - topoglcmec_o(no,m) = topoglcmec_unnorm_o(no,m) / pctglcmec_o(no,m) - else - topoglcmec_o(no,m) = mean_elevation_vc(m) - end if - - ! Correct for rounding errors that put topoglcmec_o(no,m) slightly outside the - ! allowed bounds for this elevation class - if (slightly_below(topoglcmec_o(no,m), elevclass(m))) then - write(6,*) 'Warning: topoglcmec_o was slightly lower than lower bound; setting equal& - & to lower bound; for: ', no, m, topoglcmec_o(no,m), elevclass(m) - write(6,*) '(this is informational only, and probably just indicates rounding error)' - topoglcmec_o(no,m) = elevclass(m) - else if (slightly_above(topoglcmec_o(no,m), elevclass(m+1))) then - write(6,*) 'Warning: topoglcmec_o was slightly higher than upper bound; setting equal& - & to upper bound; for: ', no, m, topoglcmec_o(no,m), elevclass(m+1) - write(6,*) '(this is informational only, and probably just indicates rounding error)' - topoglcmec_o(no,m) = elevclass(m+1) - end if - end do - end do - - ! Renormalize percentages to be given as % of landunit rather than % of grid cell. - - allocate(pctglc_tot_o(ns_o), stat=ier) - if (ier/=0) call abort() - - do no = 1,ns_o - pctglc_tot_o(no) = sum(pctglcmec_o(no,:)) - - if (pctglc_tot_o(no) > 0._r8) then - pctglcmec_o(no,:) = pctglcmec_o(no,:) / pctglc_tot_o(no) * 100._r8 - if ( outnc_3dglc )then - pctglcmec_gic_o(no,:) = pctglcmec_gic_o(no,:) / pctglc_tot_o(no) * 100._r8 - pctglcmec_icesheet_o(no,:) = pctglcmec_icesheet_o(no,:) / pctglc_tot_o(no) * 100._r8 - end if - - else - ! Division of landunit is ambiguous. Apply the rule that all area is assigned to - ! the lowest elevation class, and all GIC. - pctglcmec_o(no,1) = 100._r8 - if ( outnc_3dglc )then - pctglcmec_gic_o(no,1) = 100._r8 - end if - end if - end do - - ! Set pctglc_gic_o to sum of pctglcmec_gic_o across elevation classes, and similarly for pctglc_icesheet_o - if ( outnc_3dglc )then - pctglc_gic_o = sum(pctglcmec_gic_o, dim=2) - pctglc_icesheet_o = sum(pctglcmec_icesheet_o, dim=2) - end if - - ! -------------------------------------------------------------------- - ! Perform various sanity checks - ! -------------------------------------------------------------------- - - errors = .false. - - ! Confirm that the sum over pctglcmec_o (from 1 to nglcec) is 100% - do no = 1,ns_o - glc_sum = sum(pctglcmec_o(no,:)) - if (abs(glc_sum - 100._r8) > eps_small) then - write(6,*)'glc_sum differs from 100% at no,pctglc= ',no,glc_sum - errors = .true. - end if - end do - - ! Confirm that GIC + ICESHEET = 100% - if ( outnc_3dglc )then - do no = 1,ns_o - if (abs((pctglc_gic_o(no) + pctglc_icesheet_o(no)) - 100._r8) > eps) then - write(6,*)'GIC + ICESHEET differs from 100% at no,pctglc_gic,pctglc_icesheet,lon,lat=', & - no,pctglc_gic_o(no),pctglc_icesheet_o(no),& - tgridmap%xc_dst(no),tgridmap%yc_dst(no) - errors = .true. - end if - end do - - ! Check that GIC + ICESHEET = total glacier at each elevation class - do m = 1, nglcec - do no = 1,ns_o - if (abs((pctglcmec_gic_o(no,m) + pctglcmec_icesheet_o(no,m)) - & - pctglcmec_o(no,m)) > eps) then - write(6,*)'GIC + ICESHEET differs from total GLC ' - write(6,*)'at no,m,pctglcmec,pctglcmec_gic,pctglcmec_icesheet = ' - write(6,*) no,m,pctglcmec_o(no,m),pctglcmec_gic_o(no,m),pctglcmec_icesheet_o(no,m) - errors = .true. - end if - end do - end do - end if - - - ! Error check: are all elevations within elevation class range - do no = 1,ns_o - do m = 1,nglcec - if (topoglcmec_o(no,m) < elevclass(m) .or. topoglcmec_o(no,m) > elevclass(m+1)) then - write(6,*) 'Error: mean elevation does not fall within elevation class ' - write(6,*) elevclass(m),elevclass(m+1),topoglcmec_o(no,m),m,no - errors = .true. - endif - end do - end do - - if (errors) then - call abort() - end if - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate(pctglc_gic_i, pctglc_icesheet_i) - deallocate(topoglcmec_unnorm_o) - deallocate(pctglc_tot_o) - deallocate(frac_dst) - deallocate(starts, counts) - - write (6,*) 'Successfully made percent elevation class and mean elevation for glaciers' - write (6,*) - call shr_sys_flush(6) - -end subroutine mkglcmec - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkglacier -! -! !INTERFACE: -subroutine mkglacier(ldomain, mapfname, datfname, ndiag, zero_out, glac_o) -! -! !DESCRIPTION: -! make percent glacier -! -! In contrast to mkglcmec, this uses a "flat" PCT_GLACIER field (not separated by -! elevation class, and not separated into icesheet vs GIC). -! -! This simpler routine is sufficient for cases when we run without multiple elevation -! classes. This routine is also used when running with multiple elevation classes: we -! first regrid the flat PCT_GLACIER field, then later create the multiple elevation class -! data. This multi-step process makes it easier to do corrections on the total -! PCT_GLACIER, and make sure these corrections apply appropriately to the multi-level -! output. The assumption is that PCT_GLACIER is the sum of both PCT_GLC_GIC and -! PCT_GLC_ICESHEET across all elevation bins. -! -! !USES: - use mkdomainMod , only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - logical , intent(in) :: zero_out ! if should zero glacier out - real(r8) , intent(out):: glac_o(:) ! output grid: %glacier -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: glac_i(:) ! input grid: percent glac - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: gglac_i ! input grid: global glac - real(r8) :: garea_i ! input grid: global area - real(r8) :: gglac_o ! output grid: global glac - real(r8) :: garea_o ! output grid: global area - integer :: ni,no,k,n,m,ns, ns_o ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mkglacier' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make %glacier .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns = tdomain%ns - ns_o = ldomain%ns - allocate(glac_i(ns), & - frac_dst(ns_o), & - stat=ier) - if (ier/=0) call abort() - - write (6,*) 'Open glacier file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_GLACIER', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, glac_i), subname) - call check_ret(nf_close(ncid), subname) - - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. - - if ( zero_out )then - - do no = 1, ns_o - glac_o(no) = 0. - enddo - - else - - call gridmap_mapread(tgridmap, mapfname ) - - ! Error checks for domain and map consistencies - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine glac_o on output grid - - call gridmap_areaave_srcmask(tgridmap, glac_i, glac_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - do no = 1, ns_o - if (glac_o(no) < 1.) glac_o(no) = 0. - enddo - end if - - ! Check for conservation - - do no = 1, ns_o - if ((glac_o(no)) > 100.000001_r8) then - write (6,*) 'MKGLACIER error: glacier = ',glac_o(no), & - ' greater than 100.000001 for column, row = ',no - call shr_sys_flush(6) - call abort() - end if - enddo - - ! Some error checking and writing of global values before and after the regrid - - if ( .not. zero_out )then - - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - - allocate(mask_r8(ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - - ! Input grid - - gglac_i = 0. - garea_i = 0. - do ni = 1, ns - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - gglac_i = gglac_i + glac_i(ni)*(tgridmap%area_src(ni)/100.)*& - tdomain%mask(ni)*re**2 - end do - - ! Output grid - - gglac_o = 0. - garea_o = 0. - do no = 1, ns_o - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - gglac_o = gglac_o + glac_o(no)*(tgridmap%area_dst(no)/100.)*& - frac_dst(no)*re**2 - end do - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Glacier Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) -2001 format (1x,'surface type input grid area output grid area'/ & - 1x,' 10**6 km**2 10**6 km**2 ') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2002) gglac_i*1.e-06,gglac_o*1.e-06 - write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 -2002 format (1x,'glaciers ',f14.3,f17.3) -2004 format (1x,'all surface ',f14.3,f17.3) - - end if - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - if ( .not. zero_out )then - call gridmap_clean(tgridmap) - deallocate (glac_i, frac_dst, mask_r8) - end if - - write (6,*) 'Successfully made %glacier' - write (6,*) - call shr_sys_flush(6) - -end subroutine mkglacier - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: get_elevclass -! -! !INTERFACE: -integer function get_elevclass(topo, writewarn) -! -! !DESCRIPTION: -! Returns elevation class index (1..nglcec) given the topographic height. -! If topo is lower than the lowest elevation class, returns 0. -! If topo is higher than the highest elevation class, returns (nglcec+1). -! In either of the two latter cases, the function also writes a warning message, unless -! writewarn is present and false. -! -! !ARGUMENTS: - implicit none - real(r8), intent(in) :: topo ! topographic height (m) - logical, intent(in), optional :: writewarn ! should warning messages be written? (default: true) -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! !LOCAL VARIABLES: -!EOP - integer :: m - logical :: my_writewarn - character(len=32) :: subname = 'get_elevclass' -!----------------------------------------------------------------------- - - if (present(writewarn)) then - my_writewarn = writewarn - else - my_writewarn = .true. - end if - - if (topo < elevclass(1)) then - if (my_writewarn) then - write(6,*) 'WARNING in ', trim(subname) - write(6,*) 'topo out of bounds' - write(6,*) 'topo = ', topo - write(6,*) 'elevclass(1) = ', elevclass(1) - end if - get_elevclass = 0 - return - end if - - do m = 1, nglcec - if (topo < elevclass(m+1)) then - ! note that we already know that topo >= elevclass(m), otherwise we would have - ! returned earlier - get_elevclass = m - return - end if - end do - - if (my_writewarn) then - write(6,*) 'WARNING in ', trim(subname) - write(6,*) 'topo out of bounds' - write(6,*) 'topo = ', topo - write(6,*) 'elevclass(nglcec+1) = ', elevclass(nglcec+1) - end if - get_elevclass = nglcec+1 - -end function get_elevclass - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mean_elevation_vc -! -! !INTERFACE: -real(r8) function mean_elevation_vc(class) -! -! !DESCRIPTION: -! For a virtual column (thus, a column that has no true elevation data), return the -! "mean" elevation of the given elevation class. -! -! !ARGUMENTS: - implicit none - integer, intent(in) :: class ! elevation class -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! !LOCAL VARIABLES: -!EOP - character(len=32) :: subname = 'mean_elevation_vc' -!----------------------------------------------------------------------- - - if (class < nglcec) then - mean_elevation_vc = 0.5_r8 * (elevclass(class) + elevclass(class+1)) - else if (class == nglcec) then - ! In the top elevation class; in this case, assignment of a "mean" elevation is - ! somewhat arbitrary - - if (nglcec > 1) then - mean_elevation_vc = 2.0_r8*elevclass(class) - elevclass(class-1) - else - ! entirely arbitrary - mean_elevation_vc = 1000._r8 - end if - else - write(6,*) 'ERROR in ', trim(subname), ': class out of bounds= ', class - call abort() - end if - -end function mean_elevation_vc - -end module mkglcmecMod diff --git a/tools/mksurfdata_map/src/mkgridmapMod.F90 b/tools/mksurfdata_map/src/mkgridmapMod.F90 deleted file mode 100644 index eeb5afdbb8..0000000000 --- a/tools/mksurfdata_map/src/mkgridmapMod.F90 +++ /dev/null @@ -1,915 +0,0 @@ -module mkgridmapMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkgridmapMod -! -! !DESCRIPTION: -! Module containing 2-d global surface boundary data information -! -! !NOTES: -! Avoid using the frac_src and frac_dst found here, because they -! are read from mapping files, and we have generally moved to "nomask" -! mapping files. This means that mapping files now typically contain -! mask and frac equal to 1 everywhere. So now during remapping we apply the -! source masks found in the raw datasets and ignore the masks found in the -! mapping files. Exception: we continue to use a masked mapping file to regrid -! the 1-km topography. -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - - implicit none - private - -! !PUBLIC TYPES: - type gridmap_type - character(len=32) :: set ! If set or not - integer :: na ! size of source domain - integer :: nb ! size of destination domain - integer :: ns ! number of non-zero elements in matrix - real(r8), pointer :: yc_src(:) ! "degrees" - real(r8), pointer :: yc_dst(:) ! "degrees" - real(r8), pointer :: xc_src(:) ! "degrees" - real(r8), pointer :: xc_dst(:) ! "degrees" - real(R8), pointer :: area_src(:) ! area of a grid in map (radians) - real(R8), pointer :: area_dst(:) ! area of b grid in map (radians) - real(r8), pointer :: frac_src(:) ! "unitless" - real(r8), pointer :: frac_dst(:) ! "unitless" - integer , pointer :: src_indx(:) ! correpsonding column index - integer , pointer :: dst_indx(:) ! correpsonding row index - real(r8), pointer :: wovr(:) ! wt of overlap input cell - end type gridmap_type - public :: gridmap_type -! -! !PUBLIC MEMBER FUNCTIONS: - public :: gridmap_setptrs ! Set pointers to gridmap data - public :: for_test_create_gridmap ! Set a gridmap directly, for testing - public :: gridmap_mapread ! Read in gridmap - public :: gridmap_check ! Check validity of a gridmap - public :: gridmap_calc_frac_dst ! Obtain frac_dst - public :: gridmap_areaave_no_srcmask ! do area average without passing mask - public :: gridmap_areaave_srcmask ! do area average with mask passed - public :: gridmap_areaave_scs ! area average, but multiply by ratio of source over destination weight - public :: gridmap_areastddev ! do area-weighted standard deviation - public :: gridmap_clean ! Clean and deallocate a gridmap structure -! -! -! !REVISION HISTORY: -! Author Mariana Vertenstein - - ! questions - how does the reverse mapping occur - ! is mask_dst read in - and what happens if this is very different - ! from frac_dst which is calculated by mapping frac_src? - ! in frac - isn't grid1_frac always 1 or 0? - - ! !PRIVATE MEMBER FUNCTIONS: - private :: set_gridmap_var - private :: gridmap_checkifset - - interface set_gridmap_var - module procedure set_gridmap_var_r8 - module procedure set_gridmap_var_int - end interface set_gridmap_var - - character(len=32), parameter :: isSet = "gridmap_IsSet" - -! -!EOP -!------------------------------------------------------------------------------ -contains - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: gridmap_setptrs -! -! !INTERFACE: - subroutine gridmap_setptrs(gridmap, nsrc, ndst, ns, yc_src, yc_dst, & - xc_src, xc_dst, & - frac_src, frac_dst, src_indx, dst_indx ) -! -! !DESCRIPTION: -! This subroutine assigns pointers to some of the map type data. -! -! !ARGUMENTS: - implicit none - type(gridmap_type), intent(in) :: gridmap ! mapping data - integer, optional :: nsrc ! size of source domain - integer, optional :: ndst ! size of destination domain - integer, optional :: ns ! number of non-zero elements in matrix - integer, optional, pointer :: dst_indx(:) ! Destination index - integer, optional, pointer :: src_indx(:) ! Destination index - real(r8), optional, pointer :: yc_src(:) ! "degrees" - real(r8), optional, pointer :: yc_dst(:) ! "degrees" - real(r8), optional, pointer :: xc_src(:) ! "degrees" - real(r8), optional, pointer :: xc_dst(:) ! "degrees" - real(r8), optional, pointer :: frac_src(:) ! "unitless" - real(r8), optional, pointer :: frac_dst(:) ! "unitless" -! -! !REVISION HISTORY: -! Created by Erik Kluzek -! -! !LOCAL VARIABLES: -!EOP -!------------------------------------------------------------------------------ - character(*),parameter :: subName = '(gridmap_setptrs) ' - - call gridmap_checkifset( gridmap, subname ) - if ( present(nsrc) ) nsrc = gridmap%na - if ( present(ndst) ) ndst = gridmap%nb - if ( present(ns) ) ns = gridmap%ns - if ( present(yc_src) ) yc_src => gridmap%yc_src - if ( present(xc_src) ) xc_src => gridmap%xc_src - if ( present(frac_src) ) frac_src => gridmap%frac_src - if ( present(yc_dst) ) yc_dst => gridmap%yc_dst - if ( present(xc_dst) ) xc_dst => gridmap%xc_dst - if ( present(frac_dst) ) frac_dst => gridmap%frac_dst - if ( present(dst_indx) ) dst_indx => gridmap%dst_indx - if ( present(src_indx) ) src_indx => gridmap%src_indx - end subroutine gridmap_setptrs - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: gridmap_mapread -! -! !INTERFACE: - subroutine gridmap_mapread(gridmap, fileName) -! -! !DESCRIPTION: -! This subroutine reads in the map file -! -! !USES: - use mkncdio, only : nf_open, nf_close, nf_strerror - use mkncdio, only : nf_inq_dimid, nf_inq_dimlen - use mkncdio, only : nf_inq_varid, nf_get_var_double, nf_get_var_int - use mkncdio, only : NF_NOWRITE, NF_NOERR - use mkncdio, only : convert_latlon -! -! !ARGUMENTS: - implicit none - type(gridmap_type), intent(out) :: gridmap ! mapping data - character(len=*) , intent(in) :: filename ! netCDF file to read -! -! !REVISION HISTORY: -! Created by Mariana Vertenstein -! -! !LOCAL VARIABLES: - integer :: n ! generic loop indicies - integer :: na ! size of source domain - integer :: nb ! size of destination domain - integer :: igrow ! aVect index for matrix row - integer :: igcol ! aVect index for matrix column - integer :: iwgt ! aVect index for matrix element - integer :: iarea ! aVect index for area - - - character,allocatable :: str(:) ! variable length char string - character(len=256) :: attstr ! netCDF attribute name string - integer :: rcode ! netCDF routine return code - integer :: fid ! netCDF file ID - integer :: vid ! netCDF variable ID - integer :: did ! netCDF dimension ID - integer :: ns ! size of array - - real(r8), parameter :: tol = 1.0e-4_r8 ! tolerance for checking that mapping data - ! are within expected bounds - - !--- formats --- - character(*),parameter :: subName = '(gridmap_map_read) ' - character(*),parameter :: F00 = '("(gridmap_map_read) ",4a)' - character(*),parameter :: F01 = '("(gridmap_map_read) ",2(a,i7))' -!EOP -!------------------------------------------------------------------------------ - - !------------------------------------------------------------------------------- - ! - !------------------------------------------------------------------------------- - - write(6,F00) "reading mapping matrix data..." - - ! open & read the file - write(6,F00) "* file name : ",trim(fileName) - - rcode = nf_open(filename ,NF_NOWRITE, fid) - if (rcode /= NF_NOERR) write(6,F00) nf_strerror(rcode) - - !--- allocate memory & get matrix data ---------- - rcode = nf_inq_dimid (fid, 'n_s', did) ! size of sparse matrix - rcode = nf_inq_dimlen(fid, did , gridmap%ns) - rcode = nf_inq_dimid (fid, 'n_a', did) ! size of input vector - rcode = nf_inq_dimlen(fid, did , gridmap%na) - rcode = nf_inq_dimid (fid, 'n_b', did) ! size of output vector - rcode = nf_inq_dimlen(fid, did , gridmap%nb) - - write(6,*) "* matrix dimensions rows x cols :",gridmap%na,' x',gridmap%nb - write(6,*) "* number of non-zero elements: ",gridmap%ns - - ns = gridmap%ns - na = gridmap%na - nb = gridmap%nb - allocate(gridmap%wovr(ns) , & - gridmap%src_indx(ns), & - gridmap%dst_indx(ns), & - gridmap%area_src(na), & - gridmap%frac_src(na), & - gridmap%area_dst(nb), & - gridmap%frac_dst(nb), & - gridmap%xc_dst(nb), & - gridmap%yc_dst(nb), & - gridmap%xc_src(na), & - gridmap%yc_src(na), stat=rcode) - if (rcode /= 0) then - write(6,*) SubName//' ERROR: allocate gridmap' - call abort() - endif - - rcode = nf_inq_varid(fid,'S' ,vid) - rcode = nf_get_var_double(fid,vid ,gridmap%wovr) - if (rcode /= NF_NOERR) write(6,F00) nf_strerror(rcode) - - rcode = nf_inq_varid(fid,'row',vid) - rcode = nf_get_var_int(fid, vid ,gridmap%dst_indx) - if (rcode /= NF_NOERR) write(6,F00) nf_strerror(rcode) - - rcode = nf_inq_varid(fid,'col',vid) - rcode = nf_get_var_int(fid, vid, gridmap%src_indx) - if (rcode /= NF_NOERR) write(6,F00) nf_strerror(rcode) - - rcode = nf_inq_varid(fid,'area_a',vid) - rcode = nf_get_var_double(fid, vid, gridmap%area_src) - if (rcode /= NF_NOERR) write(6,F00) nf_strerror(rcode) - - rcode = nf_inq_varid(fid,'area_b',vid) - rcode = nf_get_var_double(fid, vid, gridmap%area_dst) - if (rcode /= NF_NOERR) write(6,F00) nf_strerror(rcode) - - rcode = nf_inq_varid(fid,'frac_a',vid) - rcode = nf_get_var_double(fid, vid, gridmap%frac_src) - if (rcode /= NF_NOERR) write(6,F00) nf_strerror(rcode) - if ( any(gridmap%frac_src(:) < 0.0_r8 .or. gridmap%frac_src > (1.0_r8 + tol)) )then - write(6,*) SubName//' ERROR: frac_src out of bounds' - write(6,*) 'max = ', maxval(gridmap%frac_src), ' min = ', minval(gridmap%frac_src) - call abort() - end if - - rcode = nf_inq_varid(fid,'frac_b',vid) - rcode = nf_get_var_double(fid, vid, gridmap%frac_dst) - if (rcode /= NF_NOERR) write(6,F00) nf_strerror(rcode) - if ( any(gridmap%frac_dst(:) < 0.0_r8 .or. gridmap%frac_dst > (1.0_r8 + tol)) )then - write(6,*) SubName//' ERROR: frac_dst out of bounds' - write(6,*) 'max = ', maxval(gridmap%frac_dst), ' min = ', minval(gridmap%frac_dst) - call abort() - end if - - rcode = nf_inq_varid(fid,'xc_a',vid) - rcode = nf_get_var_double(fid, vid, gridmap%xc_src) - if (rcode /= NF_NOERR) write(6,F00) nf_strerror(rcode) - call convert_latlon(fid, 'xc_a', gridmap%xc_src) - - rcode = nf_inq_varid(fid,'yc_a',vid) - rcode = nf_get_var_double(fid, vid, gridmap%yc_src) - if (rcode /= NF_NOERR) write(6,F00) nf_strerror(rcode) - call convert_latlon(fid, 'yc_a', gridmap%yc_src) - - rcode = nf_inq_varid(fid,'xc_b',vid) - rcode = nf_get_var_double(fid, vid, gridmap%xc_dst) - if (rcode /= NF_NOERR) write(6,F00) nf_strerror(rcode) - call convert_latlon(fid, 'xc_b', gridmap%xc_dst) - - rcode = nf_inq_varid(fid,'yc_b',vid) - rcode = nf_get_var_double(fid, vid, gridmap%yc_dst) - if (rcode /= NF_NOERR) write(6,F00) nf_strerror(rcode) - call convert_latlon(fid, 'yc_b', gridmap%yc_dst) - - rcode = nf_close(fid) - - gridmap%set = IsSet - - end subroutine gridmap_mapread - -!========================================================================== - - !----------------------------------------------------------------------- - subroutine for_test_create_gridmap(gridmap, na, nb, ns, & - src_indx, dst_indx, wovr, & - frac_src, frac_dst, area_src, area_dst, & - xc_src, xc_dst, yc_src, yc_dst) - ! - ! !DESCRIPTION: - ! Creates a gridmap object directly from inputs - ! - ! This is meant for testing - ! - ! !ARGUMENTS: - type(gridmap_type), intent(out) :: gridmap - integer, intent(in) :: na - integer, intent(in) :: nb - integer, intent(in) :: ns - integer, intent(in) :: src_indx(:) - integer, intent(in) :: dst_indx(:) - real(r8), intent(in) :: wovr(:) - - ! If not provided, mask and frac values are set to 1 everywhere - real(r8), intent(in), optional :: frac_src(:) - real(r8), intent(in), optional :: frac_dst(:) - - ! If not provided, area values are set to a constant value everywhere - real(r8), intent(in), optional :: area_src(:) - real(r8), intent(in), optional :: area_dst(:) - - ! If not provided, xc and yc values are set to 0 everywhere - real(r8), intent(in), optional :: xc_src(:) - real(r8), intent(in), optional :: xc_dst(:) - real(r8), intent(in), optional :: yc_src(:) - real(r8), intent(in), optional :: yc_dst(:) - - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'for_test_create_gridmap' - !----------------------------------------------------------------------- - - ! ------------------------------------------------------------------------ - ! Error checking on sizes of arrays - ! ------------------------------------------------------------------------ - call check_input_size('src_indx', size(src_indx), ns) - call check_input_size('dst_indx', size(dst_indx), ns) - call check_input_size('wovr', size(wovr), ns) - - if (present(frac_src)) then - call check_input_size('frac_src', size(frac_src), na) - end if - if (present(area_src)) then - call check_input_size('area_src', size(area_src), na) - end if - if (present(xc_src)) then - call check_input_size('xc_src', size(xc_src), na) - end if - if (present(yc_src)) then - call check_input_size('yc_src', size(yc_src), na) - end if - - if (present(frac_dst)) then - call check_input_size('frac_dst', size(frac_dst), nb) - end if - if (present(area_dst)) then - call check_input_size('area_dst', size(area_dst), nb) - end if - if (present(xc_dst)) then - call check_input_size('xc_dst', size(xc_dst), nb) - end if - if (present(yc_dst)) then - call check_input_size('yc_dst', size(yc_dst), nb) - end if - - ! ------------------------------------------------------------------------ - ! Create gridmap object - ! ------------------------------------------------------------------------ - - gridmap%na = na - gridmap%nb = nb - gridmap%ns = ns - - allocate(gridmap%src_indx(ns)) - gridmap%src_indx = src_indx - allocate(gridmap%dst_indx(ns)) - gridmap%dst_indx = dst_indx - allocate(gridmap%wovr(ns)) - gridmap%wovr = wovr - - allocate(gridmap%frac_src(na)) - call set_gridmap_var(gridmap%frac_src, 1._r8, frac_src) - allocate(gridmap%frac_dst(nb)) - call set_gridmap_var(gridmap%frac_dst, 1._r8, frac_dst) - - allocate(gridmap%yc_src(na)) - call set_gridmap_var(gridmap%yc_src, 0._r8, yc_src) - allocate(gridmap%yc_dst(nb)) - call set_gridmap_var(gridmap%yc_dst, 0._r8, yc_dst) - allocate(gridmap%xc_src(na)) - call set_gridmap_var(gridmap%xc_src, 0._r8, xc_src) - allocate(gridmap%xc_dst(nb)) - call set_gridmap_var(gridmap%xc_dst, 0._r8, xc_dst) - allocate(gridmap%area_src(na)) - call set_gridmap_var(gridmap%area_src, 0._r8, area_src) - allocate(gridmap%area_dst(nb)) - call set_gridmap_var(gridmap%area_dst, 0._r8, area_dst) - - gridmap%set = isSet - - contains - subroutine check_input_size(varname, actual_size, expected_size) - character(len=*), intent(in) :: varname - integer, intent(in) :: actual_size - integer, intent(in) :: expected_size - - if (actual_size /= expected_size) then - write(6,*) subname, ' ERROR: ', trim(varname), ' wrong size: actual, expected = ', & - actual_size, expected_size - call abort() - end if - end subroutine check_input_size - - end subroutine for_test_create_gridmap - - subroutine set_gridmap_var_r8(var, default_val, input_val) - ! Convenience subroutine to set a variable to an optional input or a default value - real(r8), intent(out) :: var(:) - real(r8), intent(in) :: default_val - real(r8), intent(in), optional :: input_val(:) - - if (present(input_val)) then - var = input_val - else - var = default_val - end if - end subroutine set_gridmap_var_r8 - - subroutine set_gridmap_var_int(var, default_val, input_val) - ! Convenience subroutine to set a variable to an optional input or a default value - integer, intent(out) :: var(:) - integer, intent(in) :: default_val - integer, intent(in), optional :: input_val(:) - - if (present(input_val)) then - var = input_val - else - var = default_val - end if - end subroutine set_gridmap_var_int - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: gridmap_check -! -! !INTERFACE: - subroutine gridmap_check(gridmap, mask_src, frac_dst, caller) -! -! !DESCRIPTION: -! Check validity of a gridmap -! Aborts if there are any errors -! -! !USES: - use mkvarctl, only : mksrf_gridtype - use mkvarpar, only : re -! -! !ARGUMENTS: - implicit none - type(gridmap_type) , intent(in) :: gridmap ! mapping data - real(r8), intent(in) :: mask_src(:) ! input mask; could be declared integer but for the argument passed from subr. mktopostats - real(r8), intent(in) :: frac_dst(:) ! output fractions - character(len=*) , intent(in) :: caller ! calling subroutine (used for error messages) -! -! !REVISION HISTORY: -! Created by Bill Sacks -! -! !LOCAL VARIABLES: - real(r8) :: sum_area_i ! global sum of input area - real(r8) :: sum_area_o ! global sum of output area - integer :: ni,no,ns_i,ns_o ! indices - - real(r8), parameter :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=*), parameter :: subname = 'gridmap_check' -!EOP -!------------------------------------------------------------------------------ - - ns_i = gridmap%na - ns_o = gridmap%nb - - ! ----------------------------------------------------------------- - ! Error check prep - ! Global sum of output area -- must multiply by fraction of - ! output grid that is land as determined by input grid - ! ----------------------------------------------------------------- - - sum_area_i = 0.0_r8 - do ni = 1,ns_i - sum_area_i = sum_area_i + gridmap%area_src(ni)*mask_src(ni)*re**2 - enddo - - sum_area_o = 0. - do no = 1,ns_o - sum_area_o = sum_area_o + gridmap%area_dst(no)*frac_dst(no)*re**2 - end do - - ! ----------------------------------------------------------------- - ! Error check1 - ! Compare global sum_area_i to global sum_area_o. - ! ----------------------------------------------------------------- - - if ( trim(mksrf_gridtype) == 'global' ) then - if ( abs(sum_area_o/sum_area_i-1.) > relerr ) then - write (6,*) subname//' ERROR from '//trim(caller)//': mapping areas not conserved' - write (6,'(a30,e20.10)') 'global sum output field = ',sum_area_o - write (6,'(a30,e20.10)') 'global sum input field = ',sum_area_i - call abort() - end if - end if - - end subroutine gridmap_check - - -!========================================================================== - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: gridmap_areaave_scs -! -! !INTERFACE: - subroutine gridmap_areaave_scs (gridmap, src_array, dst_array, nodata, src_wt, dst_wt, frac_dst) -! -! !DESCRIPTION: -! This subroutine does a simple area average, but multiplies by the ratio of the source over -! the destination weight. Sets to zero if destination weight is zero. -! -! The src_wt must be multiplied by tdomain%mask to maintain consistency with the -! incoming frac_dst. -! -! Called by subroutine mkpft. -! -! !ARGUMENTS: - implicit none - type(gridmap_type) , intent(in) :: gridmap ! gridmap data - real(r8), intent(in) :: src_array(:) - real(r8), intent(out):: dst_array(:) - real(r8), intent(in) :: nodata ! value to apply where there are no input data - real(r8), intent(in) :: src_wt(:) ! Source weights - real(r8), intent(in) :: dst_wt(:) ! Destination weights - real(r8), intent(in) :: frac_dst(:) ! Output grid weights - -! -! !REVISION HISTORY: -! Created by Mariana Vertenstein, moditied by Sean Swenson -! -! !LOCAL VARIABLES: - integer :: n,ns,ni,no - real(r8):: wt,frac,swt,dwt - real(r8), allocatable :: sum_weights(:) ! sum of weights on the output grid - character(*),parameter :: subName = '(gridmap_areaave_scs) ' -!EOP -!------------------------------------------------------------------------------ - - ! Error check inputs and initialize local variables - - if (size(frac_dst) /= size(dst_array)) then - write(6,*) subname//' ERROR: incorrect size of frac_dst' - write(6,*) 'size(frac_dst) = ', size(frac_dst) - write(6,*) 'size(dst_array) = ', size(dst_array) - call abort() - end if - - call gridmap_checkifset( gridmap, subname ) - allocate(sum_weights(size(dst_array))) - sum_weights = 0._r8 - dst_array = 0._r8 - - do n = 1,gridmap%ns - ni = gridmap%src_indx(n) - no = gridmap%dst_indx(n) - wt = gridmap%wovr(n) - frac = frac_dst(no) - swt = src_wt(ni) - dwt = dst_wt(no) - wt = wt * swt - if(dwt > 0._r8) then - wt = wt / dwt - else - wt = 0._r8 - endif - if (frac > 0.) then - dst_array(no) = dst_array(no) + wt * src_array(ni)/frac - sum_weights(no) = sum_weights(no) + wt - end if - end do - - where (sum_weights == 0._r8) - dst_array = nodata - end where - - deallocate(sum_weights) - - end subroutine gridmap_areaave_scs - -!========================================================================== - -!========================================================================== - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: gridmap_areaave_srcmask -! -! !INTERFACE: - subroutine gridmap_areaave_srcmask (gridmap, src_array, dst_array, nodata, mask_src, frac_dst) -! -! !DESCRIPTION: -! This subroutine does an area average with the source mask -! -! !NOTES: -! We have generally moved to "nomask" mapping files. This means that mapping -! files now typically contain mask and frac equal to 1 everywhere. So now during -! remapping we apply the source masks found in the raw datasets and ignore the -! masks found in the mapping files. Exception: we continue to use a masked -! mapping file to regrid the 1-km topography. -! -! !ARGUMENTS: - implicit none - type(gridmap_type) , intent(in) :: gridmap ! gridmap data - real(r8), intent(in) :: src_array(:) - real(r8), intent(out):: dst_array(:) - real(r8), intent(in) :: nodata ! value to apply where there are no input data - integer, intent(in) :: mask_src(:) - real(r8), intent(in) :: frac_dst(:) -! -! !REVISION HISTORY: -! Created by Mariana Vertenstein -! -! !LOCAL VARIABLES: - integer :: n,ns,ni,no - real(r8):: wt - character(*),parameter :: subName = '(gridmap_areaave_srcmask) ' -!EOP -!------------------------------------------------------------------------------ - ! Error check inputs and initialize local variables - - ns = size(dst_array) - if (size(frac_dst) /= ns) then - write(6,*) subname//' ERROR: incorrect size of frac_dst' - write(6,*) 'size(frac_dst) = ', size(frac_dst) - write(6,*) 'size(dst_array) = ', ns - call abort() - end if - if (size(mask_src) /= size(src_array)) then - write(6,*) subname//' ERROR: incorrect size of mask_src' - write(6,*) 'size(mask_src) = ', size(mask_src) - write(6,*) 'size(src_array) = ', size(src_array) - call abort() - end if - - call gridmap_checkifset( gridmap, subname ) - - dst_array = 0._r8 - do n = 1,gridmap%ns - ni = gridmap%src_indx(n) - no = gridmap%dst_indx(n) - wt = gridmap%wovr(n) - if (mask_src(ni) > 0) then - dst_array(no) = dst_array(no) + wt*mask_src(ni)*src_array(ni)/frac_dst(no) - end if - end do - - where (frac_dst == 0._r8) - dst_array = nodata - end where - - end subroutine gridmap_areaave_srcmask - -!========================================================================== - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: gridmap_areastddev -! -! !INTERFACE: - subroutine gridmap_areastddev (gridmap, src_array, dst_array, nodata) -! -! !DESCRIPTION: -! Computes area-weighted standard deviation -! -! We use the definition of standard deviation that applies if you measure the full -! population (as opposed to the unbiased standard deviation that should be used when -! sampling a subset of the full population). (This is equivalent to using 1/N rather than -! 1/(N-1).) This makes sense if we assume that the underlying values are constant -! throughout each source grid cell -- in that case, we know the full population as long as -! we know the values in all source grid cells, which is generally the case. -! -! The formula is from -! (accessed 3-4-13). -! -! !ARGUMENTS: - implicit none - type(gridmap_type) , intent(in) :: gridmap ! gridmap data - real(r8), intent(in) :: src_array(:) - real(r8), intent(out):: dst_array(:) - real(r8), intent(in) :: nodata ! value to apply where there are no input data -! -! !REVISION HISTORY: -! Created by Bill Sacks -! -! !LOCAL VARIABLES: - integer :: n,ni,no - integer :: ns_o ! number of output points - real(r8):: wt ! weight of overlap - real(r8), allocatable :: weighted_means(:) ! weighted mean on the output grid - real(r8), allocatable :: sum_weights(:) ! sum of weights on the output grid - character(*),parameter :: subName = '(gridmap_areastddev) ' -!EOP -!------------------------------------------------------------------------------ - call gridmap_checkifset( gridmap, subname ) - - ns_o = size(dst_array) - allocate(weighted_means(ns_o)) - - ! Subr. gridmap_areaave_no_srcmask should NOT be used in general. We have - ! kept it to support the rare raw data files for which we have masking on - ! the mapping file and, therefore, we do not explicitly pass the src_mask - ! as an argument. In general, users are advised to use subroutine - ! gridmap_areaave_srcmask. - call gridmap_areaave_no_srcmask(gridmap, src_array, weighted_means, nodata=0._r8) - - ! WJS (3-5-13): I believe that sum_weights should be the same as gridmap%frac_dst, - ! but I'm not positive of this, so we compute it explicitly to be safe - allocate(sum_weights(ns_o)) - sum_weights(:) = 0._r8 - dst_array(:) = 0._r8 - do n = 1,gridmap%ns - ni = gridmap%src_indx(n) - no = gridmap%dst_indx(n) - wt = gridmap%wovr(n) - ! The following accumulates the numerator of the weighted sigma-squared - dst_array(no) = dst_array(no) + wt * (src_array(ni) - weighted_means(no))**2 - sum_weights(no) = sum_weights(no) + wt - end do - - do no = 1,ns_o - if (sum_weights(no) > 0._r8) then - dst_array(no) = sqrt(dst_array(no)/sum_weights(no)) - else - dst_array(no) = nodata - end if - end do - - deallocate(weighted_means, sum_weights) - - end subroutine gridmap_areastddev - -!========================================================================== - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: gridmap_clean -! -! !INTERFACE: - subroutine gridmap_clean(gridmap) -! -! !DESCRIPTION: -! This subroutine deallocates the gridmap type -! -! !ARGUMENTS: - implicit none - type(gridmap_type), intent(inout) :: gridmap -! -! !REVISION HISTORY: -! Created by Mariana Vertenstein -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subName = "gridmap_clean" - integer ier ! error flag -!EOP -!------------------------------------------------------------------------------ - if ( gridmap%set .eq. IsSet )then - deallocate(gridmap%wovr , & - gridmap%src_indx, & - gridmap%dst_indx, & - gridmap%area_src, & - gridmap%area_dst, & - gridmap%frac_src, & - gridmap%frac_dst, & - gridmap%xc_src, & - gridmap%yc_src, stat=ier) - if (ier /= 0) then - write(6,*) SubName//' ERROR: deallocate gridmap' - call abort() - endif - else - write(6,*) SubName//' Warning: calling '//trim(subName)//' on unallocated gridmap' - end if - gridmap%set = "NOT-set" - - end subroutine gridmap_clean - -!========================================================================== - - subroutine gridmap_checkifset( gridmap, subname ) - - implicit none - type(gridmap_type), intent(in) :: gridmap - character(len=*), intent(in) :: subname - - if ( gridmap%set .ne. IsSet )then - write(6,*) SubName//' ERROR: gridmap NOT set yet, run gridmap_mapread first' - call abort() - end if - end subroutine gridmap_checkifset - -!========================================================================== - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: gridmap_calc_frac_dst -! -! !INTERFACE: - subroutine gridmap_calc_frac_dst(gridmap, mask_src, frac_dst) -! -! !DESCRIPTION: -! This subroutine calculates frac_dst -! -! !ARGUMENTS: - implicit none - type(gridmap_type) , intent(in) :: gridmap ! gridmap data - integer, intent(in) :: mask_src(:) - real(r8), intent(out) :: frac_dst(:) -! -! !REVISION HISTORY: -! Created by Sam Levis -! -! !LOCAL VARIABLES: - integer :: n,ns,ni,no - real(r8):: wt - character(*),parameter :: subName = '(gridmap_calc_frac_dst) ' -!EOP -!------------------------------------------------------------------------------ - call gridmap_checkifset( gridmap, subname ) - frac_dst(:) = 0._r8 - - do n = 1,gridmap%ns - ni = gridmap%src_indx(n) - no = gridmap%dst_indx(n) - wt = gridmap%wovr(n) - if (mask_src(ni) > 0) then - frac_dst(no) = frac_dst(no) + wt*mask_src(ni) - end if - end do - - end subroutine gridmap_calc_frac_dst - -!========================================================================== - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: gridmap_areaave_no_srcmask -! -! !INTERFACE: - subroutine gridmap_areaave_no_srcmask (gridmap, src_array, dst_array, nodata) -! -! !DESCRIPTION: -! This subroutine should NOT be used in general. We have kept it to support the -! rare raw data files for which we have masking on the mapping file and, -! therefore, we do not explicitly pass the src_mask as an argument. In general, -! users are advised to use subroutine gridmap_areaave_srcmask. -! -! Perform simple area average without explicitly passing a src mask. The src -! mask may be implicit in gridmap%wovr. -! -! !ARGUMENTS: - implicit none - type(gridmap_type) , intent(in) :: gridmap ! gridmap data - real(r8), intent(in) :: src_array(:) - real(r8), intent(out):: dst_array(:) - real(r8), intent(in) :: nodata ! value to apply where there are no input data -! -! !REVISION HISTORY: -! Created by Mariana Vertenstein -! -! !LOCAL VARIABLES: - integer :: n,ns,ni,no - real(r8):: wt,frac - real(r8), allocatable :: sum_weights(:) ! sum of weights on the output grid - character(*),parameter :: subName = '(gridmap_areaave_no_srcmask) ' -!EOP -!------------------------------------------------------------------------------ - call gridmap_checkifset( gridmap, subname ) - allocate(sum_weights(size(dst_array))) - sum_weights = 0._r8 - dst_array = 0._r8 - - do n = 1,gridmap%ns - ni = gridmap%src_indx(n) - no = gridmap%dst_indx(n) - wt = gridmap%wovr(n) - frac = gridmap%frac_dst(no) - if (frac > 0.) then - dst_array(no) = dst_array(no) + wt * src_array(ni)/frac - sum_weights(no) = sum_weights(no) + wt - end if - end do - - where (sum_weights == 0._r8) - dst_array = nodata - end where - - deallocate(sum_weights) - - end subroutine gridmap_areaave_no_srcmask - -end module mkgridmapMod - - diff --git a/tools/mksurfdata_map/src/mkharvestMod.F90 b/tools/mksurfdata_map/src/mkharvestMod.F90 deleted file mode 100644 index e726fc81c9..0000000000 --- a/tools/mksurfdata_map/src/mkharvestMod.F90 +++ /dev/null @@ -1,1105 +0,0 @@ -module mkharvestMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkharvest -! -! !DESCRIPTION: -! Make harvest and grazing data to add to the dynamic PFT file. -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -!----------------------------------------------------------------------- -! !USES: - use shr_kind_mod , only : r8 => shr_kind_r8, CL => shr_kind_CL - use shr_sys_mod , only : shr_sys_flush - use mkdomainMod , only : domain_checksame - - implicit none - - private - -! !PUBLIC DATA MEMBERS: - - public :: harvestDataType - integer, private, parameter :: numharv = 9 ! number of harvest and grazing fields - - type :: harvestDataType - private - real(r8), pointer :: data1D(:,:) ! Input 1D data - real(r8), pointer :: data2DCFT(:,:,:) ! Input 2D data with CFT's - real(r8), pointer :: data2DPFT(:,:,:) ! Input 2D data with PFT's - real(r8), pointer :: OutData1D(:,:) ! Output 1D data - real(r8), pointer :: OutData2DCFT(:,:,:) ! Output 2D data with CFT's - real(r8), pointer :: OutData2DPFT(:,:,:) ! Output 2D data with natural PFT's - integer :: dims2nd(numharv) ! 2nd dimension size - integer :: CFTdimsize ! Size of CFT dimension - integer :: PFTdimsize ! Size of PFT dimension - integer :: indices1D(numharv) ! Field indices for CFT variables - integer :: indicesCFT(numharv) ! Field indices for CFT variables - integer :: indicesPFT(numharv) ! Field indices for PFT variables - contains - procedure :: init ! Initialization - procedure :: get1DFieldPtr ! Get a pointer to a 1D field - procedure :: get2DFieldPtr ! Get a pointer to a 2D field - procedure :: getFieldsIdx ! Get field indexes to 1D and 2D fields - procedure :: getFieldsDim ! Get dimension names for this field - procedure :: isField1D ! Return true if field is a 1D field - procedure :: isField2D ! Return true if field is a 2D field - procedure :: num1DFields ! Return the number of 1D fields - procedure :: num2DFields ! Return the number of 2D fields - procedure :: clean ! Clean and deallocate everything - end type harvestDataType - -! !PUBLIC MEMBER FUNCTIONS: - public mkharvest_init ! Initialization - public mkharvest ! Calculate the harvest values on output grid - public mkharvest_fieldname ! Field name for harvest fields on landuse.timeseries - public mkharvest_longname ! Long name - public mkharvest_units ! units - public mkharvest_numtypes ! Number of harvest types - public mkharvest_parse_oride ! Parse the over-ride string - -! !PRIVATE MEMBER FUNCTIONS: (but public because unit test uses them) - public mkharvest_fieldInBounds ! Check that field index is within bounds - -! !PRIVATE DATA MEMBERS: - - integer, parameter :: harlen = 25 ! length of strings for harvest fieldnames - character(len=harlen), parameter :: harvest_fieldnames(numharv) = (/ & - 'HARVEST_VH1 ', & - 'HARVEST_VH2 ', & - 'HARVEST_SH1 ', & - 'HARVEST_SH2 ', & - 'HARVEST_SH3 ', & - 'GRAZING ', & - 'FERTNITRO_CFT ', & - 'UNREPRESENTED_PFT_LULCC', & - 'UNREPRESENTED_CFT_LULCC' & - /) - character(len=harlen), parameter :: harvest_const_fieldnames(numharv) = (/ & - 'CONST_HARVEST_VH1 ', & - 'CONST_HARVEST_VH2 ', & - 'CONST_HARVEST_SH1 ', & - 'CONST_HARVEST_SH2 ', & - 'CONST_HARVEST_SH3 ', & - 'CONST_GRAZING ', & - 'CONST_FERTNITRO_CFT ', & - 'UNREPRESENTED_PFT_LULCC', & - 'UNREPRESENTED_CFT_LULCC' & - /) - - character(len=CL), parameter :: string_undef = 'UNSET' - real(r8), parameter :: real_undef = -999.99 - character(len=CL), save :: harvest_longnames(numharv) = string_undef - character(len=CL), save :: harvest_units(numharv) = string_undef - real(r8), pointer :: oride_harv(:) ! array that can override harvesting - logical , save :: initialized = .false. - -!EOP -!----------------------------------------------------------------------- -contains -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: init -! -! !INTERFACE: - subroutine init( this, dims2nd, ns_i, ns_o, init_value ) -! -! !DESCRIPTION: -! Initialization of the harvestData object -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(INOUT) :: this ! harvestData object - integer, intent(IN) :: dims2nd(:) ! 2nd Dimension sizes - integer, intent(IN) :: ns_i ! Input dimension size - integer, intent(IN) :: ns_o ! Output dimension size - real(r8), intent(IN) :: init_value ! Initial value -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'harvestData::init' - integer :: num2nd ! number of non 1D variables - integer :: numCFT, numPFT ! number of CFT and PFT variables respectively - integer :: num1D ! number of 1D variables - integer :: n ! index -!EOP -!----------------------------------------------------------------------- - if ( size(dims2nd) /= numharv )then - write(*,*) subname//':ERROR:: dims2nd given to init is not the right size' - call abort() - end if - this%CFTdimsize = 64 - this%PFTdimsize = 15 - this%dims2nd = dims2nd - num2nd = 0 - numCFT = 0 - numPFT = 0 - num1D = 0 - this%indices1D = -1 - this%indicesPFT = -1 - this%indicesCFT = -1 - do n = 1, numharv - if ( dims2nd(n) == 0 )then - num1D = num1D + 1 - this%indices1D(n) = num1D - else - num2nd = num2nd + 1 - if ( dims2nd(n) == this%CFTdimsize )then - numCFT = numCFT + 1 - this%indicesCFT(n) = numCFT - else if ( dims2nd(n) == this%PFTdimsize )then - numPFT = numPFT + 1 - this%indicesPFT(n) = numPFT - else - write(*,*) 'ERROR:: dims2nd is not the right size (should be 0, 15, or 64) = ', dims2nd(n) - call abort() - end if - end if - end do - - allocate( this%data1D(ns_i,num1D) ) - allocate( this%OutData1D(ns_o,num1D) ) - - this%OutData1D(:,:) = init_value - - if ( num2nd > 0 ) then - allocate( this%data2DCFT (ns_i,this%CFTdimsize,numCFT) ) - allocate( this%OutData2DCFT(ns_o,this%CFTdimsize,numCFT) ) - - this%OutData2DCFT(:,:,:) = init_value - - allocate( this%data2DPFT (ns_i,this%PFTdimsize,numPFT) ) - allocate( this%OutData2DPFT(ns_o,this%PFTdimsize,numPFT) ) - - this%OutData2DPFT(:,:,:) = init_value - end if - - end subroutine init - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: get1DFieldPtr -! -! !INTERFACE: - function get1DFieldPtr( this, nfield, output ) result(ptr1D) -! -! !DESCRIPTION: -! Returns 2D pointer to field data for this index -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object - integer, intent(in) :: nfield ! field index - real(r8), pointer :: ptr1D(:) ! Pointer to 1D data - logical, optional, intent(in) :: output ! Flag if this is the output pointer or not (input) -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'harvestData::get1DFieldPtr' - logical :: loutput ! Local output flag -!EOP -!----------------------------------------------------------------------- - loutput = .false. - if ( present(output) ) loutput = output - if ( mkharvest_fieldInBounds( nfield ) .and. this%isField1D(nfield) )then - if ( .not. loutput ) then - ptr1D => this%data1D(:,this%indices1D(nfield)) - else - ptr1D => this%OutData1D(:,this%indices1D(nfield)) - end if - else - call abort() - end if - end function get1DFieldPtr - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: get2DFieldPtr -! -! !INTERFACE: - function get2DFieldPtr( this, nfield, output ) result(ptr2D) -! -! !DESCRIPTION: -! Returns 2D pointer to field data for this index -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object - integer, intent(in) :: nfield ! field index - real(r8), pointer :: ptr2D(:,:) ! Pointer to 2D data - logical, optional, intent(in) :: output ! Flag if this is the output pointer or not (input) -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'harvestData::get2DFieldPtr' - logical :: loutput ! Local output flag -!EOP -!----------------------------------------------------------------------- - loutput = .false. - if ( present(output) ) loutput = output - if ( mkharvest_fieldInBounds( nfield ) .and. this%isField2D(nfield) )then - if ( .not. loutput ) then - if ( this%dims2nd(nfield) == this%CFTdimsize )then - ptr2D => this%data2DCFT(:,:,this%indicesCFT(nfield)) - else - ptr2D => this%data2DPFT(:,:,this%indicesPFT(nfield)) - end if - else - if ( this%dims2nd(nfield) == this%CFTdimsize )then - ptr2D => this%OutData2DCFT(:,:,this%indicesCFT(nfield)) - else - ptr2D => this%OutData2DPFT(:,:,this%indicesPFT(nfield)) - end if - end if - else - call abort() - end if - end function get2DFieldPtr - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: getFieldsIdx -! -! !INTERFACE: - subroutine getFieldsIdx( this, indices1D, indices2D ) -! -! !DESCRIPTION: -! Returns list of 1D and 2D fields indices -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object - integer, allocatable :: indices1D(:) ! List of 1D indices - integer, allocatable :: indices2D(:) ! List of 2D indices -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'harvestData::getFieldsIdx' - integer :: ifld, n1, n2 ! field index and field index -!EOP -!----------------------------------------------------------------------- - allocate( indices1D(max(1,this%num1DFields()) ) ) - allocate( indices2D(max(1,this%num2DFields()) ) ) - indices1D = -1 - indices2D = -1 - n1 = 0 - n2 = 0 - do ifld = 1, mkharvest_numtypes() - if ( this%isField1D(ifld) )then - n1 = n1 + 1 - indices1D(n1) = ifld - else if ( this%isField2D(ifld) )then - n2 = n2 + 1 - indices2D(n2) = ifld - end if - end do - end subroutine getFieldsIdx - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: getFieldsDim -! -! !INTERFACE: - function getFieldsDim( this, nfield ) result(dimname) -! -! !DESCRIPTION: -! Returns list of 1D and 2D fields indices -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object - integer, intent(in) :: nfield ! field index - character(len=10) :: dimname ! Dimension names -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'harvestData::getFieldsDim' -!EOP -!----------------------------------------------------------------------- - if ( this%dims2nd(nfield) == this%CFTdimsize )then - dimname = "cft" - else if ( this%dims2nd(nfield) == this%PFTdimsize )then - dimname = "natpft" - else - dimname = "none" - end if - end function getFieldsDim - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: isField1D -! -! !INTERFACE: - logical function isField1D( this, nfield ) -! -! !DESCRIPTION: -! Returns true if this field index is a 1D field -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object - integer, intent(in) :: nfield ! field index -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'harvestData::isField1D' -!EOP -!----------------------------------------------------------------------- - isField1D = .false. - if ( mkharvest_fieldInBounds( nfield ) )then - if ( this%dims2nd(nfield) == 0 ) isField1D = .true. - else - call abort() - end if - end function isField1D - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: isField2D -! -! !INTERFACE: - logical function isField2D( this, nfield ) -! -! !DESCRIPTION: -! Returns true if this field index is a 2D field -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object - integer, intent(in) :: nfield ! field index -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'harvestData::isField2D' -!EOP -!----------------------------------------------------------------------- - isField2D = .false. - if ( mkharvest_fieldInBounds( nfield ) )then - if ( this%dims2nd(nfield) /= 0 ) isField2D = .true. - else - call abort() - end if - end function isField2D - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: num1DFields -! -! !INTERFACE: - integer function num1DFields( this ) -! -! !DESCRIPTION: -! Returns the number of 1D fields -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'harvestData::num1DFields' -!EOP -!----------------------------------------------------------------------- - num1DFields = count( this%dims2nd == 0) - end function num1DFields - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: num2DFields -! -! !INTERFACE: - integer function num2DFields( this ) -! -! !DESCRIPTION: -! Returns the number of 2D fields -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(IN) :: this ! harvestData object -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'harvestData::num2DFields' -!EOP -!----------------------------------------------------------------------- - num2DFields = count( this%dims2nd /= 0) - end function num2DFields - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest_init -! -! !INTERFACE: - subroutine mkharvest_init( ns_o, init_val, harvdata, fharvest, constant ) -! -! !DESCRIPTION: -! Initialization of mkharvest module. -! -! !USES: - use mkncdio - implicit none -! -! !ARGUMENTS: - integer , intent(in) :: ns_o ! clm output grid resolution - real(r8) , intent(in) :: init_val ! initial value to set to - type(harvestDataType), intent(INOUT) :: harvdata ! Harvest data - character(len=*) , intent(in) :: fharvest ! input harvest dataset file name - logical, intent(in), optional :: constant ! Flag if variables are CONST_ version for surface dataset - ! rather than landuse.timeseries -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'mkharvest_init' - character(len=CL) :: lunits ! local units read in - integer :: ncid,varid ! input netCDF id's - integer :: ifld ! indices - integer :: ret ! return code - logical :: lconstant ! local version of constant flag - logical :: varexists ! If variable exists on file - integer :: dim_lengths(3) ! Dimension lengths on file - integer :: dims2nd(numharv) ! Dimension lengths of 3rd dimension for each variable on file - integer :: ndims ! Number of dimensions on file - integer :: ns_i ! clm input grid resolution (nlat*nlon) -!EOP -!----------------------------------------------------------------------- - lconstant = .false. - if ( present(constant) ) lconstant = constant - - initialized = .true. - call check_ret(nf_open(fharvest, 0, ncid), subname) - dims2nd(:) = 0 - ns_i = 0 - do ifld = 1, numharv - call check_ret(nf_inq_varid ( ncid, mkharvest_fieldname(ifld, constant=lconstant), varid), subname, varexists=varexists) - if ( .not. varexists )then - write(*,*) "SKIP: "//mkharvest_fieldname(ifld, constant=lconstant) - harvest_longnames(ifld) = trim(mkharvest_fieldname(ifld, constant=lconstant)) // " (zeroed out)" - harvest_units(ifld) = "not_read_in" - else - call check_ret(nf_get_att_text( ncid, varid, 'long_name', harvest_longnames(ifld)), subname ) - ret = nf_get_att_text( ncid, varid, 'units', harvest_units(ifld)) - if ( ret == nf_enotatt )then - harvest_units(ifld) = "unitless" - else if ( ret == nf_noerr )then - else - write(*,*) 'ERROR:: bad return code from NetCDF get attribute= '// nf_strerror(ret) - call abort() - end if - call get_dim_lengths(ncid, mkharvest_fieldname(ifld, constant=lconstant), ndims, dim_lengths) - if ( ns_i == 0 )then - ns_i = dim_lengths(1)*dim_lengths(2) - else if ( ns_i /= dim_lengths(1)*dim_lengths(2) )then - write(*,*) 'ERROR:: bad dimension sizes for variable = ', mkharvest_fieldname(ifld, constant=lconstant) - call abort() - end if - if ( ndims == 2 )then - dims2nd(ifld) = 0 - else if ( ndims == 3 )then - dims2nd(ifld) = dim_lengths(3) - else - write(*,*) 'ERROR:: bad dimensionality for variable = ', mkharvest_fieldname(ifld, constant=lconstant) - call abort() - end if - - end if - end do - call harvdata%init( dims2nd, ns_i, ns_o, init_val ) - - call check_ret(nf_close(ncid), subname) - - allocate( oride_harv(numharv) ) - oride_harv(:) = real_undef - - end subroutine mkharvest_init - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest_fieldInBounds -! -! !INTERFACE: - logical function mkharvest_fieldInBounds( nfield ) -! -! !DESCRIPTION: -! Return true if field index is in bounds and initialization done -! -! !USES: - implicit none -! -! !ARGUMENTS: - integer, intent(in) :: nfield ! field index -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'mkharvest_fieldInBounds' -!EOP -!----------------------------------------------------------------------- - if ( nfield < 1 )then - write(6,*) subname, ' ERROR nfield < 1' - mkharvest_fieldInBounds = .false. - else if ( nfield > numharv )then - write(6,*) subname, ' ERROR nfield > max fields' - mkharvest_fieldInBounds = .false. - else if ( .not. initialized ) then - write(6,*) subname, ' ERROR mkharvest NOT initialized yet!' - mkharvest_fieldInBounds = .false. - else - mkharvest_fieldInBounds = .true. - end if - - end function mkharvest_fieldInBounds - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest_fieldname -! -! !INTERFACE: - character(len=harlen) function mkharvest_fieldname( nfield, constant ) -! -! !DESCRIPTION: -! Return harvest fieldname of input field number. -! -! !USES: - implicit none -! -! !ARGUMENTS: - integer, intent(in) :: nfield - logical, intent(in), optional :: constant -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'mkharvest_fieldname' - logical :: lconstant ! local version of constant flag -!EOP -!----------------------------------------------------------------------- - lconstant = .false. - if ( present(constant) ) lconstant = constant - - if ( mkharvest_fieldInBounds( nfield ) )then - if ( .not. lconstant )then - mkharvest_fieldname = harvest_fieldnames(nfield) - else - mkharvest_fieldname = harvest_const_fieldnames(nfield) - end if - else - call abort() - end if - - end function mkharvest_fieldname - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest_units -! -! !INTERFACE: - character(len=CL) function mkharvest_units( nfield ) -! -! !DESCRIPTION: -! Return units description of harvest fields -! -! !USES: - implicit none -! -! !ARGUMENTS: - integer, intent(in) :: nfield -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'mkharvest_units' -!EOP -!----------------------------------------------------------------------- - - if ( mkharvest_fieldInBounds( nfield ) )then - mkharvest_units = harvest_units(nfield) - else - call abort() - end if - - end function mkharvest_units - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest_longname -! -! !INTERFACE: - character(len=CL) function mkharvest_longname( nfield ) -! -! !DESCRIPTION: -! Return longname description of given input field number. -! -! !USES: - implicit none -! -! !ARGUMENTS: - integer, intent(in) :: nfield -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'mkharvest_longname' -!EOP -!----------------------------------------------------------------------- - - if ( mkharvest_fieldInBounds( nfield ) )then - mkharvest_longname = harvest_longnames(nfield) - else - call abort() - end if - - end function mkharvest_longname - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest_numtypes -! -! !INTERFACE: - integer function mkharvest_numtypes( ) -! -! !DESCRIPTION: -! Return number of different harvest field types. -! -! !USES: - implicit none -! -! !ARGUMENTS: - character(len=*), parameter :: subname = 'mkharvest_numtypes' -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP -!----------------------------------------------------------------------- - mkharvest_numtypes = numharv - - end function mkharvest_numtypes - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: clean -! -! !INTERFACE: - subroutine clean( this ) -! -! !DESCRIPTION: -! Clean and deallocate the harvestData object -! -! !USES: - implicit none -! -! !ARGUMENTS: - class(harvestDataType), intent(INOUT) :: this ! harvestData object -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! !LOCAL VARIABLES: - character(len=*), parameter :: subname = 'harvestData::clean' -!EOP -!----------------------------------------------------------------------- - this%CFTdimsize = -1 - this%PFTdimsize = -1 - - if ( associated(this%data1D) ) deallocate( this%data1D ) - if ( associated(this%Outdata1D) ) deallocate( this%OutData1D ) - - if ( associated(this%data2DCFT) ) deallocate( this%data2DCFT ) - if ( associated(this%OutData2DCFT)) deallocate( this%OutData2DCFT ) - if ( associated(this%data2DPFT ) ) deallocate( this%data2DPFT ) - if ( associated(this%OutData2DPFT)) deallocate( this%OutData2DPFT ) - this%data2DCFT => null() - this%OutData2DCFT => null() - this%data2DPFT => null() - this%OutData2DPFT => null() - - end subroutine clean - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest -! -! !INTERFACE: -subroutine mkharvest(ldomain, mapfname, datfname, ndiag, harvdata) -! -! !DESCRIPTION: -! Make harvest data for the dynamic PFT dataset. -! This dataset consists of the normalized harvest or grazing fraction (0-1) of -! the model. -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - implicit none - type(domain_type) , intent(in) :: ldomain ! - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - type(harvestDataType), intent(INOUT) :: harvdata ! Harvest data -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8) :: gharv_o(numharv) ! output grid: global area harvesting - real(r8) :: garea_o ! output grid: global area - real(r8) :: gharv_i(numharv) ! input grid: global area harvesting - real(r8) :: garea_i ! input grid: global area - integer :: ifld ! indices - integer :: k,n,m,ni,no,ns_i,ns_o ! indices - integer :: ncid,varid ! input netCDF id's - logical :: varexists ! If variable exists or not - integer :: ier ! error status - integer, allocatable :: ind1D(:) ! Index of 1D harvest fields - integer, allocatable :: ind2D(:) ! Index of 2D harvest fields - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), pointer :: data1D_i(:) ! 1D input data - real(r8), pointer :: data2D_i(:,:) ! 2D output data - real(r8), pointer :: data1D_o(:) ! 1D output data - real(r8), pointer :: data2D_o(:,:) ! 2D output data - - character(len=*), parameter :: unit = '10**6 km**2' ! Output units - real(r8), parameter :: fac = 1.e-06_r8 ! Output factor - real(r8), parameter :: rat = fac/100._r8 ! Output factor divided by 100% - character(len=*), parameter :: subname = 'mkharvest' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make harvest fields .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Normally read in the harvesting file, and then regrid to output grid - ! ----------------------------------------------------------------- - call harvdata%getFieldsIdx( ind1D, ind2D ) - - if ( all(oride_harv == real_undef ) )then - - ! ----------------------------------------------------------------- - ! Read input harvesting file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read HARVEST_VH1, HARVEST_VH2, ... GRAZING etc. - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - ns_o = ldomain%ns - allocate(frac_dst(ns_o), stat=ier) - if (ier /= 0) call abort() - - write (6,*) 'Open harvest file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - do k = 1, harvdata%num1Dfields() - ifld = ind1D(k) - call check_ret( nf_inq_varid(ncid, mkharvest_fieldname(ifld), varid), subname, varexists=varexists ) - data1D_i => harvdata%get1DFieldPtr( ifld ) - if ( .not. varexists )then - write(*,*) "SKIP: "//mkharvest_fieldname(ifld) - data1D_i(:) = 0.0_r8 - else - call check_ret(nf_get_var_double (ncid, varid, data1D_i), subname) - end if - end do - do k = 1, harvdata%num2Dfields() - ifld = ind2D(k) - call check_ret( nf_inq_varid(ncid, mkharvest_fieldname(ifld), varid), subname, varexists=varexists ) - data2D_i => harvdata%get2DFieldPtr( ifld ) - if ( .not. varexists )then - write(*,*) "SKIP: "//mkharvest_fieldname(ifld) - data2D_i(:,:) = 0.0_r8 - else - call check_ret(nf_get_var_double (ncid, varid, data2D_i), subname) - end if - end do - call check_ret(nf_close(ncid), subname) - - ! Area-average normalized harvest on input grid [data*_i] to output grid [data*_o] - - call gridmap_mapread(tgridmap, mapfname ) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine data* on output grid - - do k = 1, harvdata%num1Dfields() - ifld = ind1D(k) - data1D_i => harvdata%get1DFieldPtr( ifld ) - data1D_o => harvdata%get1DFieldPtr( ifld, output=.true. ) - call gridmap_areaave_srcmask(tgridmap, data1D_i, data1D_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - end do - do k = 1, harvdata%num2Dfields() - ifld = ind2D(k) - data2D_i => harvdata%get2DFieldPtr( ifld ) - data2D_o => harvdata%get2DFieldPtr( ifld, output=.true. ) - do m = lbound(data2D_i(:,:),dim=2), ubound(data2D_i(:,:),dim=2) - call gridmap_areaave_srcmask(tgridmap, data2D_i(:,m), data2D_o(:,m), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - end do - end do - - ! ----------------------------------------------------------------- - ! Error check - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - - gharv_i(:) = 0. - garea_i = 0. - do ni = 1, ns_i - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - do k = 1, harvdata%num1Dfields() - m = ind1D(k) - data1D_i => harvdata%get1DFieldPtr( m ) - gharv_i(m) = gharv_i(m) + data1D_i(ni)*tgridmap%area_src(ni)* & - tdomain%mask(ni)*re**2 - end do - end do - - gharv_o(:) = 0. - garea_o = 0. - do no = 1,ns_o - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - do k = 1, harvdata%num1Dfields() - m = ind1D(k) - data1D_o => harvdata%get1DFieldPtr( m, output=.true. ) - gharv_o(m) = gharv_o(m) + data1D_o(no)*tgridmap%area_dst(no)* & - frac_dst(no)*re**2 - end do - end do - - ! Write out to diagnostic output file - ! - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Harvesting Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,1001) unit, unit -1001 format (1x,'harvest type ',20x,' input grid area',' output grid area',/ & - 1x,33x,' ',A,' ',A) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - do k = 1, harvdata%num1Dfields() - m = ind1D(k) - write (ndiag,1002) mkharvest_fieldname(m), gharv_i(m)*rat,gharv_o(m)*rat - end do -1002 format (1x,a35,f16.3,f17.3) - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - - else - - ! ----------------------------------------------------------------- - ! Otherwise override the harvesting with the input harvest values - ! ----------------------------------------------------------------- - - if ( any(oride_harv == real_undef ) )then - write(6,*) subname, ' error some override harvesting fields set ', & - 'and others are not = ', oride_harv - call abort() - end if - do k = 1, harvdata%num1Dfields() - m = ind1D(k) - if ( oride_harv(m) < 0.0_r8 .or. oride_harv(m) > 100.0_r8 )then - write(6,*) subname, ' error override harvesting field out of range', & - oride_harv(m), ' field = ', mkharvest_fieldname(m) - call abort() - end if - end do - do no = 1,ns_o - do k = 1, harvdata%num1Dfields() - m = ind1D(k) - data1D_o => harvdata%get1DFieldPtr( m, output=.true. ) - data1D_o(no) = oride_harv(m) - end do - end do - - end if - - deallocate( ind1D, ind2D ) - write (6,*) 'Successfully made harvest and grazing' - write (6,*) - -end subroutine mkharvest - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkharvest_parse_oride -! -! !INTERFACE: -subroutine mkharvest_parse_oride( string ) -! -! !DESCRIPTION: -! Parse the string with harvest and grazing information on it, to override -! the file with this information rather than reading from a file. -! -! !USES: - use shr_string_mod, only: shr_string_betweenTags -! !ARGUMENTS: - character(len=256), intent(IN) :: string ! String to parse with harvest and grazing data -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - integer :: rc ! error return code - character(len=256) :: substring ! substring between tags - character(len=*), parameter :: harv_start = "" - character(len=*), parameter :: harv_end = "" - character(len=*), parameter :: graz_start = "" - character(len=*), parameter :: graz_end = "" - character(len=*), parameter :: subname = 'mkharvest_parse_oride' -!----------------------------------------------------------------------- - call shr_string_betweenTags( string, harv_start, harv_end, substring, rc ) - if ( rc /= 0 )then - write(6,*) subname//'Trouble finding harvest start end tags' - call abort() - end if - read(substring,*) oride_harv(1:numharv-1) - call shr_string_betweenTags( string, graz_start, graz_end, substring, rc ) - if ( rc /= 0 )then - write(6,*) subname//'Trouble finding grazing start end tags' - call abort() - end if - read(substring,*) oride_harv(numharv) - if ( harvest_fieldnames(numharv) /= 'GRAZING' )then - write(6,*) subname, ' grazing is NOT last field as was expected' - call abort() - end if - -!----------------------------------------------------------------------- - -end subroutine mkharvest_parse_oride - -!----------------------------------------------------------------------- - -end module mkharvestMod diff --git a/tools/mksurfdata_map/src/mkindexmapMod.F90 b/tools/mksurfdata_map/src/mkindexmapMod.F90 deleted file mode 100644 index 5f8e74af2b..0000000000 --- a/tools/mksurfdata_map/src/mkindexmapMod.F90 +++ /dev/null @@ -1,697 +0,0 @@ -module mkindexmapMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkindexmapMod -! -! !DESCRIPTION: -! Module containing subroutines for making maps of index data. -! -! This includes a routine for making a map using the dominant type among the input grid -! cells making up a given output cell, as well as routines for using an index map as -! indices into a lookup table, to essentially paint-by-number some other field, and some -! other related routines -! -! WJS (2-1-12): There is a lookup_2d subroutine, but not a lookup_1d (or any other -! dimensionality). That is simply because I needed lookup_2d, but have not yet needed a -! routine of other dimensionalities. In the future, it would probably be helpful to at -! least have lookup_1d and lookup_1d_netcdf. If this is done, see my notes under the -! lookup_2d_netcdf routine for some thoughts on avoiding duplication. -! -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkncdio, only : nf_max_name - use mkgridmapMod, only : gridmap_type - - implicit none - private - -! !PUBLIC TYPES: -! - ! dim_slice_type: stores information about dimensions that we use for slicing a multi- - ! dimensional variable - type dim_slice_type - character(len=nf_max_name) :: name ! name of this dimension - integer :: val ! index to use for the slice - end type dim_slice_type - public :: dim_slice_type -! -! !PUBLIC MEMBER FUNCTIONS: - public :: get_dominant_indices ! make output map based on dominant type in each grid cell - public :: get_max_indices ! make output map based on maximum type in each grid cell - public :: lookup_2d ! create map based on a 2-d lookup table - public :: lookup_2d_netcdf ! wrapper to lookup_2d; first read table from netcdf file - public :: which_max ! get index of the maximum value in an array -! -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -!EOP -!------------------------------------------------------------------------------ -contains - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: get_dominant_indices -! -! !INTERFACE: -subroutine get_dominant_indices(gridmap, src_array, dst_array, minval, maxval, nodata, filter, mask_src) -! -! !DESCRIPTION: -! Fills an output array on the destination grid (dst_array) whose values are equal to the -! (weighted) dominant value in the source grid cells overlapping a given destination grid -! cell -! -! Ignores all values in src_array that are less than minval or greater than maxval (treats -! those values the same as if they had wt=0). (Note: for memory-use efficiency, it is -! best if the indices are designed such that most values between minval and maxval are -! actually used, since an array is allocated of size (maxval - minval + 1)*gridmap%nb.) -! -! The filter argument can be used to exclude certain overlaps -- if provided, we only -! consider overlaps where filter is .true. If not provided, filter is treated as being -! .true. everywhere. -! -! Output grid cells with no contributing valid source points are given the nodata value -! -! !ARGUMENTS: - implicit none - type(gridmap_type), intent(in) :: gridmap ! provides mapping from src -> dst - integer , intent(in) :: src_array(:) ! input values; length gridmap%na - integer , intent(out):: dst_array(:) ! output values; length gridmap%nb - integer , intent(in) :: minval ! minimum valid value in src_array - integer , intent(in) :: maxval ! maximum valid value in src_array - integer , intent(in) :: nodata ! value to assign to dst_array where there are no valid source points - integer , intent(in) :: mask_src(:) - - logical, intent(in), optional :: filter(:) ! only consider overlaps where filter is .true.; length gridmap%ns -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - logical, allocatable :: lfilter(:) ! local version of filter - logical, allocatable :: hasdata(:) ! true if an output cell has any valid data; - real(r8), allocatable :: weights(:,:) ! summed weight of each index value for each output cell - - integer :: n, ni, no - integer :: k - integer :: maxindex - real(r8) :: wt - real(r8) :: maxwt - - character(len=*), parameter :: subname = "get_dominant_indices" -!----------------------------------------------------------------------- - - ! Error-check inputs and initialize local variables - - if (size(src_array) /= gridmap%na .or. & - size(dst_array) /= gridmap%nb) then - write(6,*) subname//' ERROR: incorrect sizes of src_array or dst_array' - write(6,*) 'size(src_array) = ', size(src_array) - write(6,*) 'gridmap%na = ', gridmap%na - write(6,*) 'size(dst_array) = ', size(dst_array) - write(6,*) 'gridmap%nb = ', gridmap%nb - call abort() - end if - if (size(mask_src) /= size(src_array)) then - write(6,*) subname//' ERROR: incorrect size of mask_src' - write(6,*) 'size(mask_src) = ', size(mask_src) - write(6,*) 'size(src_array) = ', size(src_array) - call abort() - end if - - allocate(lfilter(gridmap%ns)) - - if (present(filter)) then - if (size(filter) /= gridmap%ns) then - write(6,*) subname//' ERROR: incorrect size of filter' - write(6,*) 'size(filter) = ', size(filter) - write(6,*) 'gridmap%ns = ', gridmap%ns - call abort() - end if - - lfilter(:) = filter(:) - else - lfilter(:) = .true. - end if - - allocate(hasdata(gridmap%nb)) - hasdata(:) = .false. - allocate(weights(minval:maxval, gridmap%nb)) - weights(minval:maxval,:) = 0. - - ! Determine weight of each index value for each output (destination) cell - - do n = 1, gridmap%ns - if (lfilter(n)) then - ni = gridmap%src_indx(n) - no = gridmap%dst_indx(n) - wt = gridmap%wovr(n) * mask_src(ni) - k = src_array(ni) - if (k >= minval .and. k <= maxval) then - ! Note: if we were doing something like weighted sums, I think we would - ! want to divide wt by gridmap%frac_dst(no), as is done in - ! gridmap_areaave_default. But since all we care about is the relative - ! values of weights for a given destination cell, this is unnecessary - weights(k,no) = weights(k,no) + wt - hasdata(no) = .true. - end if - end if - end do - - ! Determine output values - ! Note: if a given destination cell has no contributing source points (thus - ! hasdata(no) = false), or the max weight of any index overlapping this destination - ! cell is <= 0, then the output value there will be nodata. - ! (I don't think this latter condition -- weight <= 0 -- is possible, but we handle - ! it anyway) - - dst_array(:) = nodata - do no = 1, gridmap%nb - if (hasdata(no)) then - call which_max(weights(:,no), maxwt, maxindex, lbound=minval) - if (maxwt > 0.) then - dst_array(no) = maxindex - end if - end if - end do - - deallocate(lfilter, weights, hasdata) - -end subroutine get_dominant_indices -!------------------------------------------------------------------------------ - -!----------------------------------------------------------------------- -subroutine get_max_indices(gridmap, src_array, dst_array, nodata, mask_src) - ! - ! !DESCRIPTION: - ! Fills an output array on the destination grid (dst_array) whose values are equal to - ! the maximum value in the source grid cells overlapping a given destination grid cell. - ! - ! The frequency of occurrence of the source values is irrelevant. For example, if the - ! value 1 appears in 99% of source cells overlapping a given destination cell and the - ! value 2 appears in just 1%, we'll put 2 in the destination cell because it is the - ! maximum value. - ! - ! Output grid cells with no contributing valid source points are given the nodata value - ! - ! !ARGUMENTS: - type(gridmap_type) , intent(in) :: gridmap ! provides mapping from src -> dst - integer , intent(in) :: src_array(:) ! input values; length gridmap%na - integer , intent(out) :: dst_array(:) ! output values; length gridmap%nb - integer , intent(in) :: nodata ! value to assign to dst_array where there are no valid source points - integer , intent(in) :: mask_src(:) ! mask at the source resolution - ! - ! !LOCAL VARIABLES: - logical, allocatable :: hasdata(:) ! true if an output cell has any valid data; - integer :: n, ni, no - real(r8) :: wt - integer :: src_val - - character(len=*), parameter :: subname = 'get_max_indices' - !----------------------------------------------------------------------- - - ! Error-check inputs - - if (size(src_array) /= gridmap%na .or. & - size(dst_array) /= gridmap%nb) then - write(6,*) subname//' ERROR: incorrect sizes of src_array or dst_array' - write(6,*) 'size(src_array) = ', size(src_array) - write(6,*) 'gridmap%na = ', gridmap%na - write(6,*) 'size(dst_array) = ', size(dst_array) - write(6,*) 'gridmap%nb = ', gridmap%nb - call abort() - end if - if (size(mask_src) /= size(src_array)) then - write(6,*) subname//' ERROR: incorrect size of mask_src' - write(6,*) 'size(mask_src) = ', size(mask_src) - write(6,*) 'size(src_array) = ', size(src_array) - call abort() - end if - - ! Initialize local variables - allocate(hasdata(gridmap%nb)) - hasdata(:) = .false. - - do n = 1, gridmap%ns - ni = gridmap%src_indx(n) - wt = gridmap%wovr(n) * mask_src(ni) - if (wt > 0._r8) then - no = gridmap%dst_indx(n) - src_val = src_array(ni) - if (.not. hasdata(no)) then - hasdata(no) = .true. - dst_array(no) = src_val - else if (src_val > dst_array(no)) then - dst_array(no) = src_val - end if - end if - end do - - do no = 1, gridmap%nb - if (.not. hasdata(no)) then - dst_array(no) = nodata - end if - end do - -end subroutine get_max_indices - - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: lookup_2d -! -! !INTERFACE: -subroutine lookup_2d(index1, index2, lookup_table, fill_val, data, ierr, & - nodata, valid_entries, invalid_okay) -! -! !DESCRIPTION: -! Creates a data array using a paint-by-number approach according to a lookup table -! -! This routine operates on a 2-d lookup table. There are therefore two index arrays -! (index1 and index2); these index arrays are on the same grid as the desired data array -! (thus, index1, index2 and data must all have the same length). Each output point, n, is -! then generally determined as: -! -! data(n) = lookup_table(index1(n), index2(n)) -! -! fill_val: value to put in data array where either: -! (a) index1 or index2 are equal to nodata (if nodata is given) -! Note that this condition does NOT result in ierr being set -! (b) valid_entries(index1(n), index2(n)) is false (if valid_entries is given) -! Note that this condition also results in ierr being set, unless invalid_okay is -! present and .true. -! (If valid_entries is not given, it is treated as being .true. everywhere) -! (c) index1 or index2 out of range -! Note that this condition also results in ierr being set -! -! ierr: error return code (if non-0, indicates first error encountered): -! 0: no error -! 1: attempt to assign values from the lookup table that are invalid according -! to valid_entries (note: this is not considered an error if invalid_okay is -! present and .true.) -! 2: attempt to access an out-of-range index in lookup table -! WJS (2-2-12): My main reason for using ierr rather than aborting in case of error -! is to facilitate unit testing -! -! !ARGUMENTS: - implicit none - integer , intent(in) :: index1(:) ! index into dim 1 of lookup_table - integer , intent(in) :: index2(:) ! index into dim 2 of lookup_table - real(r8), intent(in) :: lookup_table(:,:) - real(r8), intent(in) :: fill_val ! value to put in data where we don't have a valid value (see above for details) - real(r8), intent(out):: data(:) ! output arary - integer , intent(out):: ierr ! error return code (0 = no error) - - ! nodata flag in index1 and index2 (see above for details): - integer, intent(in), optional :: nodata - - ! which entries are considered valid (see above for details): - logical, intent(in), optional :: valid_entries(:,:) - - ! invalid_okay: if true, then assigning fill_val because valid_entries is false does - ! NOT raise an error flag (invalid_okay defaults to false, meaning an error is - ! raised in this case): - logical, intent(in), optional :: invalid_okay -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - integer :: n - integer :: i1, i2 - integer :: data_size ! size of index1, index2 and data arrays - integer :: table_n1 ! size of dimension 1 of lookup table - integer :: table_n2 ! size of dimension 2 of lookup table - logical :: linvalid_okay ! local version of invalid_okay - logical, allocatable :: lvalid_entries(:,:) ! local version of valid_entries - - character(len=*), parameter :: subname = 'lookup_2d' -!----------------------------------------------------------------------- - - ierr = 0 - - ! Error-check array sizes - - data_size = size(data) - if (size(index1) /= data_size .or. size(index2) /= data_size) then - write(6,*) subname//' ERROR: data array sizes do not match' - write(6,*) 'size(data) = ', data_size - write(6,*) 'size(index1) = ', size(index1) - write(6,*) 'size(index2) = ', size(index2) - call abort() - end if - - table_n1 = size(lookup_table,1) - table_n2 = size(lookup_table,2) - if (present(valid_entries)) then - if (size(valid_entries,1) /= table_n1 .or. size(valid_entries,2) /= table_n2) then - write(6,*) subname//' ERROR: size of valid_entries does not match lookup_table' - write(6,*) 'size(lookup_table) = ', table_n1, table_n2 - write(6,*) 'size(valid_entries) = ', size(valid_entries,1), & - size(valid_entries,2) - call abort() - end if - end if - - ! Set local version of invalid_okay & valid_entries - - if (present(invalid_okay)) then - linvalid_okay = invalid_okay - else - linvalid_okay = .false. - end if - - allocate(lvalid_entries(table_n1, table_n2)) - if (present(valid_entries)) then - lvalid_entries(:,:) = valid_entries(:,:) - else - lvalid_entries(:,:) = .true. - end if - - ! Do the lookups - - do n = 1, data_size - i1 = index1(n) - i2 = index2(n) - - ! First handle special cases: - - ! index is nodata flag (this is NOT an error) - if (present(nodata)) then - if (i1 == nodata .or. i2 == nodata) then - data(n) = fill_val - cycle - end if - end if - - ! index out of range - if (i1 <= 0 .or. i1 > table_n1 .or. & - i2 <= 0 .or. i2 > table_n2) then - data(n) = fill_val - if (ierr == 0) ierr = 2 - cycle - end if - - ! lookup table entry is invalid - if (.not. lvalid_entries(i1, i2)) then - data(n) = fill_val - if (.not. linvalid_okay) then - if (ierr == 0) ierr = 1 - end if - cycle - end if - - ! Finally, the "normal" case, if none of the special cases were triggered: - data(n) = lookup_table(i1, i2) - end do - - deallocate(lvalid_entries) - -end subroutine lookup_2d -!------------------------------------------------------------------------------ - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: lookup_2d_netcdf -! -! !INTERFACE: -subroutine lookup_2d_netcdf(ncid, tablename, lookup_has_invalid, & - dimname1, dimname2, n_extra_dims, & - index1, index2, fill_val, data, ierr, & - extra_dims, nodata, invalid_okay) -! -! !DESCRIPTION: -! Wrapper to lookup_2d that first reads the lookup table from a netcdf file -! -! If lookup_has_invalid is false, then we treat all lookup table entries as valid data -! (i.e., all valid_entries are true in the call to lookup_2d). If lookup_has_invalid is -! true, then we read the _FillValue attribute for the lookup table variable, and consider -! any table entry with value _FillValue to be an invalid entry, thus putting fill_val in -! these data locations (and raising an error flag unless invalid_okay is present and -! true). -! -! The dimension given by dimname1 -- with the associated indices given by index1 -- is the -! fastest-varying dimension in the lookup table. Dimension dimname2 (associated with -! index2) is the second-fastest-varying dimension. Similarly, extra_dims should be ordered -! from faster-varying to slowest-varying dimension. (The first dimension in extra_dims is -! the third-fastest-varying dimension in the lookup table.) -! -! n_extra_dims gives the number of extra dimensions (in addition to the first two) in the -! lookup table. We take a single 2-d slice of the lookup table, by using a single value of -! each of these other dimensions. If n_extra_dims > 0, then extra_dims must be present, -! with at least n_extra_dims entries. Each entry in extra_dims gives the name of a -! dimension and the dimension index to use for the slice. -! -! If size(extra_dims) > n_extra_dims, then we use the first n_extra_dims entries in -! extra_dims. If n_extra_dims = 0, then extra_dims is ignored. -! -! Note that we ignore any coordinate variables associated with the dimensions of the -! lookup table; we simply treat the lookup table indices as 1,2,3,... -! -! See the lookup_2d documentation for documentation of some other arguments -! -! WJS (2-1-12): Some thoughts on avoiding duplication if we eventually want similar -! routines, lookup_1d_netcdf, lookup_3d_netcdf, etc.: -! -! Much of the code in lookup_2d_netcdf could then be pulled out to a shared subroutine -! (e.g., much of the error-checking code). -! -! Or, maybe better: we could try to make a single lookup_netcdf subroutine that handles -! 1-d, 2-d and any other dimensionality. To do that, we would (1) make a generic interface -! (of which lookup_1d and lookup_2d would be implementations); (2) change the repeated -! arguments in lookup_2d_netcdf (*1 and *2) to arrays -- maybe using an array of a derived -! type containing these arguments; (3) if possible, initially read the lookup table into a -! 1-d array (if the netcdf call allows reading a n-d array into a 1-d array) (if netcdf -! doesn't allow this, then I think we could achieve the same thing by reading 1-d slices -! of the lookup table in a loop, building the full lookup table as a long 1-d array); (4) -! in the call to the generic 'lookup' function, reshape the 1-d lookup table -! appropriately. (Note: I think it would be challenging to combine lookup_1d and lookup_2d -! (etc.) into a single routine using a similar method.) -! -! !USES: - use mkncdio -! !ARGUMENTS: - implicit none - integer , intent(in) :: ncid ! ID of an open netcdf file - character(len=*), intent(in) :: tablename ! name of the lookup table variable - logical , intent(in) :: lookup_has_invalid ! should we use _FillValue? (see above) - character(len=*), intent(in) :: dimname1 ! name of the first (fastest-varying) dimension of the lookup table - character(len=*), intent(in) :: dimname2 ! name of the second dimension of the lookup table - integer , intent(in) :: n_extra_dims ! number of extra dimensions in the lookup table - ! The following arguments are passed directly to lookup_2d: - integer , intent(in) :: index1(:) ! index into dim 1 of lookup table - integer , intent(in) :: index2(:) ! index into dim 2 of lookup table - real(r8) , intent(in) :: fill_val ! value to put in data where we don't have a valid value - real(r8) , intent(out):: data(:) ! output array - integer , intent(out):: ierr ! error return code from the call to lookup_2d - - ! slice to use if lookup table variable has more than 2 dimensions: - type(dim_slice_type), intent(in), optional :: extra_dims(:) - - ! nodata flag in index1 and index2, passed directly to lookup_2d: - integer , intent(in), optional :: nodata - - ! flag for whether trying to use a lookup table value that is equal to the _FillValue - ! should raise an error flag - ! (irrelevant if lookup_has_invalid is .false.) - ! (passed directly to lookup_2d - see the documentation there for more details) - logical , intent(in), optional :: invalid_okay -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - integer :: varid ! netcdf variable id of the lookup table - integer :: ndims ! total number of dimensions of lookup table - integer :: ndims_expected ! value we expect for ndims, for error checking - integer :: i - real(r8) :: table_fillval ! value of the _FillValue attribute for the lookup table - character(len=nf_max_name), allocatable :: dimnames(:) ! dimension names - integer , allocatable :: dimids(:) ! dimension ids - integer , allocatable :: dimlens(:) ! dimension lengths - integer , allocatable :: starts(:) ! starting indices for reading lookup table - integer , allocatable :: counts(:) ! dimension counts for reading lookup table - real(r8), allocatable :: lookup_table(:,:) - logical , allocatable :: valid_entries(:,:) ! which entries of the lookup table are considered valid - - character(len=*), parameter :: subname = 'lookup_2d_netcdf' -!----------------------------------------------------------------------- - - ! Error-check extra_dims - - if (n_extra_dims > 0) then - if (.not. present(extra_dims)) then - write(6,*) subname//' ERROR: extra_dims must be present for n_extra_dims > 0' - call abort() - end if - - if (size(extra_dims) < n_extra_dims) then - write(6,*) subname//' ERROR: not enough extra dimensions given' - write(6,*) 'n_extra_dims = ', n_extra_dims - write(6,*) 'size(extra_dims) = ', size(extra_dims) - call abort() - end if - end if - - ! Determine number of expected dimensions in the table, and actual number of - ! dimensions in the netcdf file - - ndims_expected = 2 + n_extra_dims - - call check_ret(nf_inq_varid (ncid, tablename, varid), subname) - call check_ret(nf_inq_varndims (ncid, varid, ndims), subname) - if (ndims /= ndims_expected) then - write(6,*) subname//' ERROR: unexpected number of dimensions in ', & - trim(tablename) - write(6,*) 'ndims = ', ndims - write(6,*) 'expected (based on n_extra_dims): ', ndims_expected - call abort() - end if - - ! Get dimension names & sizes, and error-check them - - allocate(dimids(ndims), dimlens(ndims), dimnames(ndims)) - call check_ret(nf_inq_vardimid (ncid, varid, dimids), subname) - do i = 1, ndims - call check_ret(nf_inq_dimname (ncid, dimids(i), dimnames(i)), subname) - call check_ret(nf_inq_dimlen (ncid, dimids(i), dimlens(i)), subname) - end do - - call check_dimname(dimnames(1), dimname1, 1) - call check_dimname(dimnames(2), dimname2, 2) - do i = 1, n_extra_dims - call check_dimname(dimnames(2+i), extra_dims(i)%name, 2+i) - call check_dimsize(dimlens(2+i), extra_dims(i)%val, 2+i) - end do - - ! Read the lookup table; if the given variable has more than 2 dimensions, we read - ! a single 2-d slice - - allocate(starts(ndims), counts(ndims)) - allocate(lookup_table(dimlens(1), dimlens(2))) - starts(1:2) = 1 - counts(1:2) = dimlens(1:2) - do i = 1, n_extra_dims - starts(2+i) = extra_dims(i)%val - counts(2+i) = 1 - end do - call check_ret(nf_get_vara_double (ncid, varid, starts, counts, lookup_table), subname) - - ! Determine which entries are valid - - allocate(valid_entries(size(lookup_table, 1), size(lookup_table, 2))) - valid_entries(:,:) = .true. - if (lookup_has_invalid) then - call check_ret(nf_get_att_double (ncid, varid, '_FillValue', table_fillval), subname) - where (lookup_table == table_fillval) - valid_entries = .false. - end where - end if - - ! Do the lookups - - call lookup_2d(index1, index2, lookup_table, fill_val, data, ierr, nodata=nodata, & - valid_entries=valid_entries, invalid_okay=invalid_okay) - - deallocate(valid_entries) - deallocate(lookup_table) - deallocate(starts, counts) - deallocate(dimids, dimlens, dimnames) - -contains -!------------------------------------------------------------------------------ - subroutine check_dimname(actual, expected, i) - ! Make sure names are equal; if not, stop with an error message - - character(len=*), intent(in) :: actual, expected - integer , intent(in) :: i ! dimension number, for output purposes - - if (actual /= expected) then - write(6,*) subname//' ERROR: unexpected dimension name in ', trim(tablename) - write(6,*) 'dimension #', i - write(6,*) 'actual: ', trim(actual) - write(6,*) 'expected: ', trim(expected) - call abort() - end if - end subroutine check_dimname - -!------------------------------------------------------------------------------ - subroutine check_dimsize(length, index, i) - ! Make sure dimension length is long enough; if not, stop with an error message - - integer, intent(in) :: length, index - integer, intent(in) :: i ! dimension number, for output purposes - - if (index > length) then - write(6,*) subname//' ERROR: desired index exceeds dimension length in ', & - trim(tablename) - write(6,*) 'dimension #', i - write(6,*) 'index: ', index - write(6,*) 'length: ', length - call abort() - end if - end subroutine check_dimsize - -end subroutine lookup_2d_netcdf -!------------------------------------------------------------------------------ - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: which_max -! -! !INTERFACE: -subroutine which_max(arr, maxval, maxindex, lbound) -! -! !DESCRIPTION: -! Returns maximum value in arr along with the index of the maximum value -! -! If multiple values are tied, returns index of the first maximum -! -! !ARGUMENTS: - implicit none - real(r8), intent(in) :: arr(:) - real(r8), intent(out):: maxval ! maximum value in arr(:) - integer , intent(out):: maxindex ! first index of maxval - - ! lower bound of indices of arr; if not supplied, assumed to be 1: - integer , intent(in), optional :: lbound -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - integer :: i -!----------------------------------------------------------------------- - - maxindex = 1 - maxval = arr(1) - - do i = 2, size(arr) - if (arr(i) > maxval) then - maxindex = i - maxval = arr(i) - end if - end do - - if (present(lbound)) then - maxindex = maxindex + (lbound - 1) - end if -end subroutine which_max -!------------------------------------------------------------------------------ - -end module mkindexmapMod diff --git a/tools/mksurfdata_map/src/mklaiMod.F90 b/tools/mksurfdata_map/src/mklaiMod.F90 deleted file mode 100644 index e4b6d9bfa1..0000000000 --- a/tools/mksurfdata_map/src/mklaiMod.F90 +++ /dev/null @@ -1,445 +0,0 @@ -module mklaiMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mklai -! -! !DESCRIPTION: -! Make LAI/SAI/height data -! -! !REVISION HISTORY: -! Author: Sam Levis -! -!EOP -!----------------------------------------------------------------------- - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - use mkdomainMod , only : domain_checksame - use mkvarctl - - implicit none - - private - - public :: mklai - private :: pft_laicheck - -contains - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mklai -! -! !INTERFACE: -subroutine mklai(ldomain, mapfname, datfname, ndiag, ncido) -! -! !DESCRIPTION: -! Make LAI/SAI/height data -! Portions of this code could be moved out of the month loop -! for improved efficiency -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar , only : re - use mkvarctl - use mkncdio - use mkpftConstantsMod, only : c3cropindex, c3irrcropindex -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - integer , intent(in) :: ncido ! output netcdf file id -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - integer :: numpft_i ! number of plant types on input - real(r8) :: glai_o(0:numpft) ! output grid: global area pfts - real(r8) :: gsai_o(0:numpft) ! output grid: global area pfts - real(r8) :: ghgtt_o(0:numpft) ! output grid: global area pfts - real(r8) :: ghgtb_o(0:numpft) ! output grid: global area pfts - real(r8) :: glai_i(0:numpft) ! input grid: global area pfts - real(r8) :: gsai_i(0:numpft) ! input grid: global area pfts - real(r8) :: ghgtt_i(0:numpft) ! input grid: global area pfts - real(r8) :: ghgtb_i(0:numpft) ! input grid: global area pfts - - real(r8), allocatable :: mlai_o(:,:) ! monthly lai - real(r8), allocatable :: msai_o(:,:) ! monthly sai - real(r8), allocatable :: mhgtt_o(:,:) ! monthly height (top) - real(r8), allocatable :: mhgtb_o(:,:) ! monthly height (bottom) - real(r8), allocatable :: mlai_max(:,:) ! monthly lai - real(r8), allocatable :: msai_max(:,:) ! monthly sai - real(r8), allocatable :: mhgtt_max(:,:) ! monthly height (top) - real(r8), allocatable :: mhgtb_max(:,:) ! monthly height (bottom) - real(r8), allocatable :: mlai_i(:,:) ! monthly lai in - real(r8), allocatable :: msai_i(:,:) ! monthly sai in - real(r8), allocatable :: mhgtt_i(:,:) ! monthly height (top) in - real(r8), allocatable :: mhgtb_i(:,:) ! monthly height (bottom) in - real(r8), allocatable :: frac_dst(:) ! output fractions: same as frac_dst - integer, pointer :: laimask(:,:) ! lai+sai output mask for each plant function type - real(r8) :: garea_i ! input grid: global area - real(r8) :: garea_o ! output grid: global area - integer :: mwts ! number of weights - integer :: ni,no,ns_i,ns_o ! indices - integer :: k,l,n,m ! indices - integer :: ncidi,dimid,varid ! input netCDF id's - integer :: ndimsi,ndimso ! netCDF dimension sizes - integer :: dimids(4) ! netCDF dimension ids - integer :: bego(4),leno(4) ! netCDF bounds - integer :: begi(4),leni(4) ! netCDF bounds - integer :: ntim ! number of input time samples - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=256) :: name ! name of attribute - character(len=256) :: unit ! units of attribute - character(len= 32) :: subname = 'mklai' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make LAIs/SAIs/heights .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - ns_o = ldomain%ns - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - - write (6,*) 'Open LAI file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncidi), subname) - call check_ret(nf_inq_dimid(ncidi, 'pft', dimid), subname) - call check_ret(nf_inq_dimlen(ncidi, dimid, numpft_i), subname) - call check_ret(nf_inq_dimid(ncidi, 'time', dimid), subname) - call check_ret(nf_inq_dimlen(ncidi, dimid, ntim), subname) - - if (numpft_i /= numpft+1) then - write(6,*) 'WARNING: ' // trim(subname) // '(): parameter numpft+1 = ', numpft+1, & - 'does not equal input dataset numpft = ', numpft_i - write(6,*)'This inconsistency used to stop the program. Now we allow it ' - write(6,*)'because crop pfts 17-last are assumed to never use satellite lai data.' -! stop - if (numpft_i > numpft + 1) then - ! NOTE(bja, 2015-01) If this error check is determined to be - ! invalid, all the loop bounds over output data in this - ! routine will need to be double checked! - write(6, *) "ERROR:" // trim(subname) // "(): input numpft must be less than or equal to output numpft+1." - call abort() - end if - endif - if (ntim /= 12) then - write(6,*)'MKLAI: must have 12 time samples on input data' - call abort() - endif - - ! NOTE - close data set at bottom of routine - - ! Dynamic allocation of variables - - allocate(mlai_i(ns_i,0:numpft_i), & - msai_i(ns_i,0:numpft_i), & - mhgtt_i(ns_i,0:numpft_i), & - mhgtb_i(ns_i,0:numpft_i), & - frac_dst(ns_o), & - mlai_o(ns_o,0:numpft), & - msai_o(ns_o,0:numpft), & - mhgtt_o(ns_o,0:numpft), & - mhgtb_o(ns_o,0:numpft), & - laimask(ns_i,0:numpft), stat=ier ) - if (ier /= 0) then - write(6,*)'mklai allocation error'; call abort() - end if - - ! Determine mapping weights and map - - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Determine number of dimensions in input by querying MONTHLY_LAI - - call check_ret(nf_inq_varid(ncidi, 'MONTHLY_LAI', varid), subname) - call check_ret(nf_inq_vardimid(ncidi, varid, dimids), subname) - call check_ret(nf_inq_varndims(ncidi, varid, ndimsi), subname) - if (ndimsi ==4) then - begi(1) = 1 - begi(2) = 1 - begi(3) = 1 - leni(4) = 1 - call check_ret(nf_inq_dimlen(ncidi, dimids(1), leni(1)), subname) - call check_ret(nf_inq_dimlen(ncidi, dimids(2), leni(2)), subname) - call check_ret(nf_inq_dimlen(ncidi, dimids(3), leni(3)), subname) - else if (ndimsi== 3) then - begi(1) = 1 - begi(2) = 1 - leni(3) = 1 - call check_ret(nf_inq_dimlen(ncidi, dimids(1), leni(1)), subname) - call check_ret(nf_inq_dimlen(ncidi, dimids(2), leni(2)), subname) - end if - - ! Determine number of dimensions in output by querying MONTHLY_LAI - - call check_ret(nf_inq_varid(ncido, 'MONTHLY_LAI', varid), subname) - call check_ret(nf_inq_varndims(ncido, varid, ndimso), subname) - call check_ret(nf_inq_vardimid(ncido, varid, dimids), subname) - if (ndimso ==4) then - bego(1) = 1 - bego(2) = 1 - bego(3) = 1 - leno(4) = 1 - call check_ret(nf_inq_dimlen(ncido, dimids(1), leno(1)), subname) - call check_ret(nf_inq_dimlen(ncido, dimids(2), leno(2)), subname) - call check_ret(nf_inq_dimlen(ncido, dimids(3), leno(3)), subname) - else if (ndimso== 3) then - bego(1) = 1 - bego(2) = 1 - leno(3) = 1 - call check_ret(nf_inq_dimlen(ncido, dimids(1), leno(1)), subname) - call check_ret(nf_inq_dimlen(ncido, dimids(2), leno(2)), subname) - end if - - ! Loop over months - - do m = 1, ntim - - if (ndimsi == 4) begi(4)=m - if (ndimsi == 3) begi(3)=m - - call check_ret(nf_inq_varid (ncidi, 'MONTHLY_LAI', varid), subname) - call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & - mlai_i), subname) - - call check_ret(nf_inq_varid (ncidi, 'MONTHLY_SAI', varid), subname) - call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & - msai_i), subname) - - call check_ret(nf_inq_varid (ncidi, 'MONTHLY_HEIGHT_TOP', varid), subname) - call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & - mhgtt_i), subname) - - call check_ret(nf_inq_varid (ncidi, 'MONTHLY_HEIGHT_BOT', varid), subname) - call check_ret(nf_get_vara_double (ncidi, varid, begi(1:ndimsi), leni(1:ndimsi), & - mhgtb_i), subname) - - mlai_o(:,:) = 0. - msai_o(:,:) = 0. - mhgtt_o(:,:) = 0. - mhgtb_o(:,:) = 0. - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Loop over pft types to do mapping - do l = 0, numpft_i - 1 - call gridmap_areaave_srcmask(tgridmap, mlai_i(:,l) , mlai_o(:,l) , nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, msai_i(:,l) , msai_o(:,l) , nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, mhgtt_i(:,l), mhgtt_o(:,l), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, mhgtb_i(:,l), mhgtb_o(:,l), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - enddo - - ! Determine laimask - - laimask(:,:) = 0 - - ! copy LAI, SAI, & heights from the C3 crop (pft15) - ! to the irrigated (pft16) whether crop is on or off - mlai_o(:,c3irrcropindex) = mlai_o(:,c3cropindex) - msai_o(:,c3irrcropindex) = msai_o(:,c3cropindex) - mhgtt_o(:,c3irrcropindex) = mhgtt_o(:,c3cropindex) - mhgtb_o(:,c3irrcropindex) = mhgtb_o(:,c3cropindex) - - ! ----------------------------------------------------------------- - ! Output model resolution LAI/SAI/HEIGHT data - ! ----------------------------------------------------------------- - - ! Now write out all variables - - if (ndimso == 4) bego(4)=m - if (ndimso == 3) bego(3)=m - - call check_ret(nf_inq_varid(ncido, 'MONTHLY_LAI', varid), subname) - call check_ret(nf_put_vara_double(ncido, varid, bego, leno, mlai_o), subname) - - call check_ret(nf_inq_varid(ncido, 'MONTHLY_SAI', varid), subname) - call check_ret(nf_put_vara_double(ncido, varid, bego, leno, msai_o), subname) - - call check_ret(nf_inq_varid(ncido, 'MONTHLY_HEIGHT_TOP', varid), subname) - call check_ret(nf_put_vara_double(ncido, varid, bego, leno, mhgtt_o), subname) - - call check_ret(nf_inq_varid(ncido, 'MONTHLY_HEIGHT_BOT', varid), subname) - call check_ret(nf_put_vara_double(ncido, varid, bego, leno, mhgtb_o), subname) - - call check_ret(nf_inq_varid(ncido, 'time', varid), subname) - call check_ret(nf_put_vara_int(ncido, varid, bego(ndimso), leno(ndimso), m), subname) - - call check_ret(nf_sync(ncido), subname) - - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - - ! Input grid global area - - garea_i = 0. - do ni = 1,ns_i - garea_i = garea_i + tgridmap%area_src(ni) - end do - - glai_i(:) = 0. - gsai_i(:) = 0. - ghgtt_i(:) = 0. - ghgtb_i(:) = 0. - do l = 0, numpft_i - 1 - do ni = 1, ns_i - glai_i(l) = glai_i(l) + mlai_i(ni,l) *tgridmap%area_src(ni)*& - tdomain%mask(ni)*re**2 - gsai_i(l) = gsai_i(l) + msai_i(ni,l) *tgridmap%area_src(ni)*& - tdomain%mask(ni)*re**2 - ghgtt_i(l) = ghgtt_i(l)+ mhgtt_i(ni,l)*tgridmap%area_src(ni)*& - tdomain%mask(ni)*re**2 - ghgtb_i(l) = ghgtb_i(l)+ mhgtb_i(ni,l)*tgridmap%area_src(ni)*& - tdomain%mask(ni)*re**2 - end do - end do - - ! Output grid global area - - garea_o = 0. - do no = 1,ns_o - garea_o = garea_o + tgridmap%area_dst(no) - end do - - glai_o(:) = 0. - gsai_o(:) = 0. - ghgtt_o(:) = 0. - ghgtb_o(:) = 0. - do l = 0, numpft_i - 1 - do no = 1,ns_o - glai_o(l) = glai_o(l) + mlai_o(no,l)*tgridmap%area_dst(no)* & - frac_dst(no)*re**2 - gsai_o(l) = gsai_o(l) + msai_o(no,l)*tgridmap%area_dst(no)* & - frac_dst(no)*re**2 - ghgtt_o(l) = ghgtt_o(l)+ mhgtt_o(no,l)*tgridmap%area_dst(no)* & - frac_dst(no)*re**2 - ghgtb_o(l) = ghgtb_o(l)+ mhgtb_o(no,l)*tgridmap%area_dst(no)* & - frac_dst(no)*re**2 - end do - end do - - ! Comparison - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'LAI Output for month ',m - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,1001) -1001 format (1x,'PFT input grid area output grid area',/ & - 1x,3x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - do l = 0, numpft - write (ndiag,1002) l, glai_i(l)*1.e-06*1.e-02,glai_o(l)*1.e-06*1.e-02 -1002 format (1x,i3,f16.3,f17.3) - end do - - write (6,*) 'Successfully made LAIs/SAIs/heights for month ', m - call shr_sys_flush(6) - - enddo - write (6,*) - - ! Close input file - call check_ret(nf_close(ncidi), subname) - - ! consistency check that PFT and LAI+SAI make sense - !call pft_laicheck( ni_s, pft_i, laimask ) - - ! Deallocate dynamic memory - deallocate(mlai_i) - deallocate(msai_i) - deallocate(mhgtt_i) - deallocate(mhgtb_i) - deallocate(mlai_o) - deallocate(msai_o) - deallocate(mhgtt_o) - deallocate(mhgtb_o) - deallocate(laimask) - deallocate(frac_dst) - - call gridmap_clean(tgridmap) - call domain_clean(tdomain) - -end subroutine mklai - -!----------------------------------------------------------------------- -!BOP -! -! !INTERFACE: -subroutine pft_laicheck( ni_s, pctpft_i, laimask ) - -! !USES: -! -! !DESCRIPTION: -! -! consistency check that PFT and LAI+SAI make sense -! -! !ARGUMENTS: - implicit none - integer , intent(in) :: ni_s ! input PFT grid resolution - real(r8), pointer :: pctpft_i(:,:) ! % plant function types - integer, pointer :: laimask(:,:) ! mask where LAI+SAI > 0 -!EOP - - character(len=*), parameter :: subName="pft_laicheck" - integer :: ni,l,n,nc ! Indices -!----------------------------------------------------------------------- - - do l = 0, numpft - n = 0 - nc = 0 - do ni = 1,ni_s - if ( pctpft_i(ni,l) > 0.0_r8 ) nc = nc + 1 - if ( (pctpft_i(ni,l) > 0.0_r8) .and. (laimask(ni,l) /= 1) )then - write (6,*) subName//' :: warning: pft and LAI+SAI mask not consistent!' - write (6,*) 'ni,l = ', ni, l - write (6,*) 'pctpft_i = ',pctpft_i(ni,l) - write (6,*) 'laimask = ', laimask(ni,l) - n = n + 1 - end if - end do - if ( n > max(4,nc/4) ) then - write (6,*) subName//' :: pft/LAI+SAI inconsistency over more than 25% land-cover' - write (6,*) '# inconsistent points, total PFT pts, total LAI+SAI pts = ', & - n, nc, sum(laimask(:,l)) - call abort() - end if - end do - -end subroutine pft_laicheck - -!----------------------------------------------------------------------- - -end module mklaiMod diff --git a/tools/mksurfdata_map/src/mklanwatMod.F90 b/tools/mksurfdata_map/src/mklanwatMod.F90 deleted file mode 100644 index 4e1c590803..0000000000 --- a/tools/mksurfdata_map/src/mklanwatMod.F90 +++ /dev/null @@ -1,503 +0,0 @@ -module mklanwatMod - -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mklanwatMod -! -! !DESCRIPTION: -! make %lake and %wetland from input lake / wetland data -! also make lake parameters -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -!----------------------------------------------------------------------- -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - use mkdomainMod , only : domain_checksame - - implicit none - - private - -! !PUBLIC MEMBER FUNCTIONS: - public mklakwat ! make % lake - public mkwetlnd ! make % wetland - public mklakparams ! make lake parameters - -!EOP -!=============================================================== -contains -!=============================================================== - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mklakwat -! -! !INTERFACE: -subroutine mklakwat(ldomain, mapfname, datfname, ndiag, zero_out, lake_o) -! -! !DESCRIPTION: -! make %lake -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - logical , intent(in) :: zero_out ! if should zero glacier out - real(r8) , intent(out):: lake_o(:) ! output grid: %lake -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: lake_i(:) ! input grid: percent lake - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: glake_i ! input grid: global lake - real(r8) :: garea_i ! input grid: global area - real(r8) :: glake_o ! output grid: global lake - real(r8) :: garea_o ! output grid: global area - integer :: ni,no,k,n,m,ns_i,ns_o ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mklakwat' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make %lake and %wetland .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - ns_o = ldomain%ns - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - - if ( .not. zero_out )then - allocate(lake_i(ns_i), stat=ier) - if (ier/=0) call abort() - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() - - write(6,*)'Open lake file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_LAKE', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, lake_i), subname) - call check_ret(nf_close(ncid), subname) - - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. - - call gridmap_mapread(tgridmap, mapfname ) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine lake_o on output grid - - call gridmap_areaave_srcmask(tgridmap, lake_i,lake_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - do no = 1,ns_o - if (lake_o(no) < 1.) lake_o(no) = 0. - enddo - - ! ----------------------------------------------------------------- - ! Error check prep - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - ! ----------------------------------------------------------------- - - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - - ! Input grid - - glake_i = 0. - garea_i = 0. - do ni = 1,ns_i - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - glake_i = glake_i + lake_i(ni)*tgridmap%area_src(ni)/100.*re**2 - end do - - ! Output grid - - glake_o = 0. - garea_o = 0. - do no = 1,ns_o - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - glake_o = glake_o + lake_o(no)*tgridmap%area_dst(no)/100.*re**2 - end do - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Inland Water Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) -2001 format (1x,'surface type input grid area output grid area'/ & - 1x,' 10**6 km**2 10**6 km**2 ') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2002) glake_i*1.e-06,glake_o*1.e-06 - write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 -2002 format (1x,'lakes ',f14.3,f17.3) -2004 format (1x,'all surface ',f14.3,f17.3) - else - do no = 1,ns_o - lake_o(no) = 0. - enddo - end if - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - if ( .not. zero_out )then - call gridmap_clean(tgridmap) - deallocate (lake_i) - deallocate (frac_dst) - deallocate (mask_r8) - end if - - write (6,*) 'Successfully made %lake' - write (6,*) - call shr_sys_flush(6) - -end subroutine mklakwat - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkwetlnd -! -! !INTERFACE: -subroutine mkwetlnd(ldomain, mapfname, datfname, ndiag, zero_out, swmp_o) -! -! !DESCRIPTION: -! make %wetland -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - logical , intent(in) :: zero_out ! if should zero glacier out - real(r8) , intent(out):: swmp_o(:) ! output grid: %wetland -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: swmp_i(:) ! input grid: percent swamp - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: gswmp_i ! input grid: global swamp - real(r8) :: garea_i ! input grid: global area - real(r8) :: gswmp_o ! output grid: global swamp - real(r8) :: garea_o ! output grid: global area - integer :: ni,no,k,n,m,ns_i,ns_o ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mkwetlnd' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make %wetland .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - ns_o = ldomain%ns - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - - if ( .not. zero_out )then - allocate(swmp_i(ns_i), stat=ier) - if (ier/=0) call abort() - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() - - write(6,*)'Open wetland file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_WETLAND', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, swmp_i), subname) - call check_ret(nf_close(ncid), subname) - - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. - - call gridmap_mapread(tgridmap, mapfname ) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine swmp_o on output grid - - call gridmap_areaave_srcmask(tgridmap, swmp_i, swmp_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - do no = 1,ns_o - if (swmp_o(no) < 1.) swmp_o(no) = 0. - enddo - - ! ----------------------------------------------------------------- - ! Error check prep - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - ! ----------------------------------------------------------------- - - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - - ! Input grid - - gswmp_i = 0. - garea_i = 0. - do ni = 1,ns_i - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - gswmp_i = gswmp_i + swmp_i(ni)*tgridmap%area_src(ni)/100.*re**2 - end do - - ! Output grid - - gswmp_o = 0. - garea_o = 0. - do no = 1,ns_o - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - gswmp_o = gswmp_o + swmp_o(no)*tgridmap%area_dst(no)/100.*re**2 - end do - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Inland Water Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) -2001 format (1x,'surface type input grid area output grid area'/ & - 1x,' 10**6 km**2 10**6 km**2 ') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2003) gswmp_i*1.e-06,gswmp_o*1.e-06 - write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 -2003 format (1x,'wetlands ',f14.3,f17.3) -2004 format (1x,'all surface ',f14.3,f17.3) - else - do no = 1,ns_o - swmp_o(no) = 0. - enddo - end if - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - if ( .not. zero_out )then - call gridmap_clean(tgridmap) - deallocate (swmp_i) - deallocate (frac_dst) - deallocate (mask_r8) - end if - - write (6,*) 'Successfully made %wetland' - write (6,*) - call shr_sys_flush(6) - -end subroutine mkwetlnd - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mklakparams -! -! !INTERFACE: -subroutine mklakparams(ldomain, mapfname, datfname, ndiag, & - lakedepth_o) -! -! !DESCRIPTION: -! make lake parameters (currently just lake depth) -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_continuous - use mkchecksMod, only : min_bad -! -! !ARGUMENTS: - - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: lakedepth_o(:) ! output grid: lake depth (m) -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: data_i(:) ! data on input grid - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - - real(r8), parameter :: min_valid_lakedepth = 0._r8 - - character(len=32) :: subname = 'mklakparams' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make lake parameters.....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - call domain_read(tdomain,datfname) - - call gridmap_mapread(tgridmap, mapfname ) - - ! Obtain frac_dst - allocate(frac_dst(ldomain%ns), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write(6,*)'Open lake parameter file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(data_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() - - ! ----------------------------------------------------------------- - ! Regrid lake depth - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'LAKEDEPTH', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, lakedepth_o, nodata=10._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(lakedepth_o, min_valid_lakedepth, 'lakedepth')) then - call abort() - end if - - call output_diagnostics_continuous(data_i, lakedepth_o, tgridmap, "Lake Depth", "m", ndiag, tdomain%mask, frac_dst) - - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- - - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (data_i) - deallocate (frac_dst) - deallocate (mask_r8) - - write (6,*) 'Successfully made lake parameters' - write (6,*) - call shr_sys_flush(6) - -end subroutine mklakparams - -end module mklanwatMod diff --git a/tools/mksurfdata_map/src/mkncdio.F90 b/tools/mksurfdata_map/src/mkncdio.F90 deleted file mode 100644 index 555eb6ae80..0000000000 --- a/tools/mksurfdata_map/src/mkncdio.F90 +++ /dev/null @@ -1,558 +0,0 @@ -module mkncdio - -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkncdio -! -! !DESCRIPTION: -! Generic interfaces to write fields to netcdf files, and other useful netcdf operations -! -! !USES: - use shr_kind_mod , only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush -! -! !PUBLIC TYPES: - implicit none - include 'netcdf.inc' - save - - private - - public :: check_ret ! checks return status of netcdf calls - public :: ncd_defvar ! define netCDF input variable - public :: ncd_def_spatial_var ! define spatial netCDF variable (convenience wrapper to ncd_defvar) - public :: ncd_put_time_slice ! write a single time slice of a variable - public :: get_dim_lengths ! get dimension lengths of a netcdf variable - - interface ncd_def_spatial_var - module procedure ncd_def_spatial_var_0lev - module procedure ncd_def_spatial_var_1lev - module procedure ncd_def_spatial_var_2lev - end interface ncd_def_spatial_var - - interface ncd_put_time_slice - module procedure ncd_put_time_slice_1d - module procedure ncd_put_time_slice_2d - end interface ncd_put_time_slice - - public :: convert_latlon ! convert a latitude or longitude variable to degrees E / N -! -! !REVISION HISTORY: -! -! -! !PRIVATE MEMBER FUNCTIONS: -! - private :: get_time_slice_beg_and_len ! determine beg and len vectors for writing a time slice - - logical :: masterproc = .true. ! always use 1 proc - real(r8) :: spval = 1.e36 ! special value - - public :: nf_open - public :: nf_close - public :: nf_write - public :: nf_sync - public :: nf_inq_attlen - public :: nf_inq_dimlen - public :: nf_inq_dimname - public :: nf_inq_varid - public :: nf_inq_varndims - public :: nf_inq_vardimid - public :: nf_get_att_double - public :: nf_get_att_text - public :: nf_get_var_double - public :: nf_get_vara_double - public :: nf_get_var_int - public :: nf_get_vara_int - public :: nf_put_var_double - public :: nf_put_vara_double - public :: nf_put_var_int - public :: nf_put_vara_int - public :: nf_inq_dimid - public :: nf_max_name - public :: nf_max_var_dims - public :: nf_noerr - public :: nf_nowrite - public :: nf_enotatt - public :: nf_strerror -!EOP -!----------------------------------------------------------------------- - -contains - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: check_ret -! -! !INTERFACE: - subroutine check_ret(ret, calling, varexists) -! -! !DESCRIPTION: -! Check return status from netcdf call -! -! !ARGUMENTS: - implicit none - integer, intent(in) :: ret - character(len=*) :: calling - logical, intent(out), optional :: varexists -! -! !REVISION HISTORY: -! -!EOP -!----------------------------------------------------------------------- - - if ( present(varexists) ) varexists = .true. - if ( present(varexists) .and. ret == NF_ENOTVAR )then - varexists = .false. - else if (ret /= NF_NOERR) then - write(6,*)'netcdf error from ',trim(calling), ' rcode = ', ret, & - ' error = ', NF_STRERROR(ret) - call abort() - end if - - end subroutine check_ret - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: ncd_defvar -! -! !INTERFACE: - subroutine ncd_defvar(ncid, varname, xtype, & - dim1name, dim2name, dim3name, dim4name, dim5name, & - long_name, units, cell_method, missing_value, fill_value, & - imissing_value, ifill_value) -! -! !DESCRIPTION: -! Define a netcdf variable -! -! !ARGUMENTS: - implicit none - integer , intent(in) :: ncid ! input unit - character(len=*), intent(in) :: varname ! variable name - integer , intent(in) :: xtype ! external type - character(len=*), intent(in), optional :: dim1name ! dimension name - character(len=*), intent(in), optional :: dim2name ! dimension name - character(len=*), intent(in), optional :: dim3name ! dimension name - character(len=*), intent(in), optional :: dim4name ! dimension name - character(len=*), intent(in), optional :: dim5name ! dimension name - character(len=*), intent(in), optional :: long_name ! attribute - character(len=*), intent(in), optional :: units ! attribute - character(len=*), intent(in), optional :: cell_method ! attribute - real(r8) , intent(in), optional :: missing_value ! attribute for real - real(r8) , intent(in), optional :: fill_value ! attribute for real - integer , intent(in), optional :: imissing_value ! attribute for int - integer , intent(in), optional :: ifill_value ! attribute for int -! -! !REVISION HISTORY: -! -! -! !LOCAL VARIABLES: -!EOP - integer :: n ! indices - integer :: ndims ! dimension counter - integer :: dimid(5) ! dimension ids - integer :: varid ! variable id - integer :: itmp ! temporary - character(len=256) :: str ! temporary - character(len=32) :: subname='NCD_DEFVAR_REAL' ! subroutine name -!----------------------------------------------------------------------- - - if (.not. masterproc) return - - ! Determine dimension ids for variable - - dimid(:) = 0 - - if (present(dim1name)) then - call check_ret(nf_inq_dimid(ncid, dim1name, dimid(1)), subname) - end if - if (present(dim2name)) then - call check_ret(nf_inq_dimid(ncid, dim2name, dimid(2)), subname) - end if - if (present(dim3name)) then - call check_ret(nf_inq_dimid(ncid, dim3name, dimid(3)), subname) - end if - if (present(dim4name)) then - call check_ret(nf_inq_dimid(ncid, dim4name, dimid(4)), subname) - end if - if (present(dim5name)) then - call check_ret(nf_inq_dimid(ncid, dim5name, dimid(5)), subname) - end if - - ! Define variable - - if (present(dim1name)) then - ndims = 0 - do n = 1, size(dimid) - if (dimid(n) /= 0) ndims = ndims + 1 - end do - call check_ret(nf_def_var(ncid, trim(varname), xtype, ndims, dimid(1:ndims), varid), subname) - else - call check_ret(nf_def_var(ncid, varname, xtype, 0, 0, varid), subname) - end if - if (present(long_name)) then - call check_ret(nf_put_att_text(ncid, varid, 'long_name', len_trim(long_name), trim(long_name)), subname) - end if - if (present(units)) then - call check_ret(nf_put_att_text(ncid, varid, 'units', len_trim(units), trim(units)), subname) - end if - if (present(cell_method)) then - str = 'time: ' // trim(cell_method) - call check_ret(nf_put_att_text(ncid, varid, 'cell_method', len_trim(str), trim(str)), subname) - end if - if (present(fill_value)) then - call check_ret(nf_put_att_double(ncid, varid, '_FillValue', xtype, 1, fill_value), subname) - end if - if (present(missing_value)) then - call check_ret(nf_put_att_double(ncid, varid, 'missing_value', xtype, 1, missing_value), subname) - end if - if (present(ifill_value)) then - call check_ret(nf_put_att_int(ncid, varid, '_FillValue', xtype, 1, ifill_value), subname) - end if - if (present(imissing_value)) then - call check_ret(nf_put_att_int(ncid, varid, 'missing_value', xtype, 1, imissing_value), subname) - end if - - end subroutine ncd_defvar - - ! ======================================================================== - ! ncd_def_spatial_var routines: define a spatial netCDF variable (convenience wrapper to - ! ncd_defvar) - ! ======================================================================== - - !----------------------------------------------------------------------- - subroutine ncd_def_spatial_var_0lev(ncid, varname, xtype, long_name, units) - ! - ! !DESCRIPTION: - ! Define a spatial netCDF variable (convenience wrapper to ncd_defvar) - ! - ! The variable in question has ONLY spatial dimensions (no level or time dimensions) - ! - ! !USES: - use mkvarctl, only : outnc_1d - ! - ! !ARGUMENTS: - integer , intent(in) :: ncid ! input unit - character(len=*) , intent(in) :: varname ! variable name - integer , intent(in) :: xtype ! external type - character(len=*) , intent(in) :: long_name ! attribute - character(len=*) , intent(in) :: units ! attribute - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'ncd_def_spatial_var_0lev' - !----------------------------------------------------------------------- - - if (outnc_1d) then - call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & - dim1name='gridcell', & - long_name=long_name, units=units) - else - call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & - dim1name='lsmlon', dim2name='lsmlat', & - long_name=long_name, units=units) - end if - - end subroutine ncd_def_spatial_var_0lev - - !----------------------------------------------------------------------- - subroutine ncd_def_spatial_var_1lev(ncid, varname, xtype, lev1name, long_name, units) - ! - ! !DESCRIPTION: - ! Define a spatial netCDF variable (convenience wrapper to ncd_defvar) - ! - ! The variable in question has one level (or time) dimension in addition to its - ! spatial dimensions - ! - ! !USES: - use mkvarctl, only : outnc_1d - ! - ! !ARGUMENTS: - integer , intent(in) :: ncid ! input unit - character(len=*) , intent(in) :: varname ! variable name - integer , intent(in) :: xtype ! external type - character(len=*) , intent(in) :: lev1name ! name of level (or time) dimension - character(len=*) , intent(in) :: long_name ! attribute - character(len=*) , intent(in) :: units ! attribute - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'ncd_def_spatial_var_1lev' - !----------------------------------------------------------------------- - - if (outnc_1d) then - call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & - dim1name='gridcell', dim2name=lev1name, & - long_name=long_name, units=units) - else - call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & - dim1name='lsmlon', dim2name='lsmlat',dim3name=lev1name, & - long_name=long_name, units=units) - end if - - end subroutine ncd_def_spatial_var_1lev - - !----------------------------------------------------------------------- - subroutine ncd_def_spatial_var_2lev(ncid, varname, xtype, lev1name, lev2name, long_name, units) - ! - ! !DESCRIPTION: - ! Define a spatial netCDF variable (convenience wrapper to ncd_defvar) - ! - ! The variable in question has two level (or time) dimensions in addition to its - ! spatial dimensions - ! - ! !USES: - use mkvarctl, only : outnc_1d - ! - ! !ARGUMENTS: - integer , intent(in) :: ncid ! input unit - character(len=*) , intent(in) :: varname ! variable name - integer , intent(in) :: xtype ! external type - character(len=*) , intent(in) :: lev1name ! name of first level (or time) dimension - character(len=*) , intent(in) :: lev2name ! name of second level (or time) dimension - character(len=*) , intent(in) :: long_name ! attribute - character(len=*) , intent(in) :: units ! attribute - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'ncd_def_spatial_var_2lev' - !----------------------------------------------------------------------- - - if (outnc_1d) then - call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & - dim1name='gridcell', dim2name=lev1name, dim3name=lev2name, & - long_name=long_name, units=units) - else - call ncd_defvar(ncid=ncid, varname=varname, xtype=xtype, & - dim1name='lsmlon', dim2name='lsmlat', dim3name=lev1name, dim4name=lev2name, & - long_name=long_name, units=units) - end if - - end subroutine ncd_def_spatial_var_2lev - - ! ======================================================================== - ! ncd_put_time_slice routines: write a single time slice of a variable - ! ======================================================================== - - !----------------------------------------------------------------------- - subroutine ncd_put_time_slice_1d(ncid, varid, time_index, data) - ! - ! !DESCRIPTION: - ! Write a single time slice of a 1-d variable - ! - ! !USES: - ! - ! !ARGUMENTS: - integer , intent(in) :: ncid ! netCDF id - integer , intent(in) :: varid ! variable id - integer , intent(in) :: time_index ! time index in file - real(r8), intent(in) :: data(:) ! data to write (a single time slice) - ! - ! !LOCAL VARIABLES: - integer, allocatable :: beg(:) ! begin indices for each dimension - integer, allocatable :: len(:) ! length along each dimension - - character(len=*), parameter :: subname = 'ncd_put_time_slice_1d' - !----------------------------------------------------------------------- - - call get_time_slice_beg_and_len(ncid, varid, time_index, beg, len) - call check_ret(nf_put_vara_double(ncid, varid, beg, len, data), subname) - - deallocate(beg, len) - - end subroutine ncd_put_time_slice_1d - - !----------------------------------------------------------------------- - subroutine ncd_put_time_slice_2d(ncid, varid, time_index, data) - ! - ! !DESCRIPTION: - ! Write a single time slice of a 2-d variable - ! - ! !USES: - ! - ! !ARGUMENTS: - integer , intent(in) :: ncid ! netCDF id - integer , intent(in) :: varid ! variable id - integer , intent(in) :: time_index ! time index in file - real(r8), intent(in) :: data(:,:) ! data to write (a single time slice) - ! - ! !LOCAL VARIABLES: - integer, allocatable :: beg(:) ! begin indices for each dimension - integer, allocatable :: len(:) ! length along each dimension - - character(len=*), parameter :: subname = 'ncd_put_time_slice_2d' - !----------------------------------------------------------------------- - - call get_time_slice_beg_and_len(ncid, varid, time_index, beg, len) - call check_ret(nf_put_vara_double(ncid, varid, beg, len, data), subname) - - deallocate(beg, len) - - end subroutine ncd_put_time_slice_2d - - - !----------------------------------------------------------------------- - subroutine get_time_slice_beg_and_len(ncid, varid, time_index, beg, len) - ! - ! !DESCRIPTION: - ! Determine beg and len vectors for writing a time slice. - ! - ! Assumes time is the last dimension of the given variable. - ! - ! Allocates memory for beg & len. - ! - ! !USES: - ! - ! !ARGUMENTS: - integer , intent(in) :: ncid ! netcdf ID - integer , intent(in) :: varid ! variable ID - integer , intent(in) :: time_index ! time index in file - integer, allocatable, intent(out) :: beg(:) ! begin indices for each dimension - integer, allocatable, intent(out) :: len(:) ! length along each dimension - ! - ! !LOCAL VARIABLES: - integer :: n ! index - integer :: ndims ! number of dimensions - integer, allocatable :: dimids(:) ! dimension IDs - - character(len=*), parameter :: subname = 'get_time_slice_beg_and_len' - !----------------------------------------------------------------------- - - call check_ret(nf_inq_varndims(ncid, varid, ndims), subname) - allocate(beg(ndims)) - allocate(len(ndims)) - allocate(dimids(ndims)) - - call check_ret(nf_inq_vardimid(ncid, varid, dimids), subname) - beg(1:ndims-1) = 1 - do n = 1,ndims-1 - call check_ret(nf_inq_dimlen(ncid, dimids(n), len(n)), subname) - end do - len(ndims) = 1 - beg(ndims) = time_index - - deallocate(dimids) - - end subroutine get_time_slice_beg_and_len - - - - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: get_dim_lengths -! -! !INTERFACE: -subroutine get_dim_lengths(ncid, varname, ndims, dim_lengths) -! -! !DESCRIPTION: -! Returns the number of dimensions and an array containing the dimension lengths of a -! variable in an open netcdf file. -! -! Entries 1:ndims in the returned dim_lengths array contain the dimension lengths; the -! remaining entries in that vector are meaningless. The dim_lengths array must be large -! enough to hold all ndims values; if not, the code aborts (this can be ensured by passing -! in an array of length nf_max_var_dims). -! -! !USES: -! -! !ARGUMENTS: - implicit none - integer , intent(in) :: ncid ! netcdf id of an open netcdf file - character(len=*), intent(in) :: varname ! name of variable of interest - integer , intent(out):: ndims ! number of dimensions of variable - integer , intent(out):: dim_lengths(:) ! lengths of dimensions of variable -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: - integer :: varid - integer :: dimids(size(dim_lengths)) - integer :: i - character(len=*), parameter :: subname = 'get_dim_lengths' -!EOP -!------------------------------------------------------------------------------ - call check_ret(nf_inq_varid(ncid, varname, varid), subname) - call check_ret(nf_inq_varndims(ncid, varid, ndims), subname) - - if (ndims > size(dim_lengths)) then - write(6,*) trim(subname), ' ERROR: dim_lengths too small' - call abort() - end if - - call check_ret(nf_inq_vardimid(ncid, varid, dimids), subname) - - dim_lengths(:) = 0 ! pre-fill with 0 so we won't have garbage in elements past ndims - do i = 1, ndims - call check_ret(nf_inq_dimlen(ncid, dimids(i), dim_lengths(i)), subname) - end do - end subroutine get_dim_lengths - -!---------------------------------------------------------------------------- -!BOP -! -! !IROUTINE: convert_latlon -! -! !INTERFACE: - subroutine convert_latlon(ncid, varname, data) -! -! !DESCRIPTION: -! Convert a latitude or longitude variable from its units in the input file to degrees E / -! degrees N. Currently, this just handles conversions from radians to degrees. -! -! Assumes that the longitude / latitude variable has already been read from file, into -! the variable given by 'data'. ncid & varname give the file ID and variable name from -! which this variable was read (needed to obtain the variable's units). -! -! !USES: - use shr_const_mod, only : SHR_CONST_PI -! -! !ARGUMENTS: - implicit none - integer , intent(in) :: ncid ! ID of open netcdf file - character(len=*), intent(in) :: varname ! name of lat or lon variable that was read into 'data' - real(r8) , intent(inout):: data(:) ! latitude or longitude data -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - integer :: ier ! error return code - integer :: varid ! netCDF variable id - integer :: units_len ! length of units attribute on file - character(len=256) :: units ! units attribute - character(len= 32) :: subname = 'convert_latlon' -!----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, varname, varid), subname) - ier = nf_inq_attlen(ncid, varid, 'units', units_len) - - ! Only do the following processing if there is no error; if ier /= NF_NOERR, that - ! probably means there isn't a units attribute -- in that case, assume units are - ! degrees and need no conversion - if (ier == NF_NOERR) then - if (units_len > len(units)) then - write(6,*) trim(subname), ' ERROR: units variable not long enough to hold attributue' - call abort() - end if - - call check_ret(nf_get_att_text(ncid, varid, 'units', units), subname) - - if (units(1:7) == 'radians') then - ! convert from radians to degrees - data(:) = data(:) * 180._r8 / SHR_CONST_PI - end if - end if - - end subroutine convert_latlon -!------------------------------------------------------------------------------ - - -end module mkncdio diff --git a/tools/mksurfdata_map/src/mkpctPftTypeMod.F90 b/tools/mksurfdata_map/src/mkpctPftTypeMod.F90 deleted file mode 100644 index 8c2c9b7c53..0000000000 --- a/tools/mksurfdata_map/src/mkpctPftTypeMod.F90 +++ /dev/null @@ -1,626 +0,0 @@ -module mkpctPftTypeMod - - !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mkpctPftType - ! - ! !DESCRIPTION: - ! Derived type and associated methods for operating on pct_pft data - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! - !----------------------------------------------------------------------- - - !!USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - - implicit none - private - - ! !PUBLIC TYPES - public :: pct_pft_type - - type :: pct_pft_type - private - real(r8), allocatable :: pct_p2l(:) ! pct of each pft on the landunit - real(r8) :: pct_l2g ! pct of landunit on the grid cell - contains - ! Public routines: - ! Query routines: - procedure :: get_pct_p2l ! get an array holding % of each pft on the landunit - procedure :: get_pct_p2g ! get an array holding % of each pft on the gridcell - procedure :: get_pct_l2g ! get % of landunit on the grid cell - procedure :: get_first_pft_index ! get index of the first pft (lower bound of arrays) - procedure :: get_one_pct_p2g ! get % of gridcell for a single pft - ! Routines that modify the data: - procedure :: set_pct_l2g ! set % of landunit on the grid cell - procedure :: set_one_pct_p2g ! set % pft for a single pft - procedure :: merge_pfts ! merge all area from one PFT into another PFT - procedure :: remove_small_cover ! set % cover to 0 for any PFT whose grid cell coverage is less than a threshold - - ! Private routines: - procedure, private :: convert_from_p2g ! convert a p2g array into p2l and l2g - procedure, private :: check_vals ! perform a sanity check after setting values - end type pct_pft_type - - ! !PUBLIC MEMBER FUNCTIONS - public :: update_max_array ! given an array of pct_pft_type variables update the max_p2l values from pct_p2l - public :: get_pct_p2l_array ! given an array of pct_pft_type variables, return a 2-d array of pct_p2l - public :: get_pct_l2g_array ! given an array of pct_pft_type variables, return an array of pct_l2g - - interface pct_pft_type - module procedure constructor ! initialize a new pct_pft_type object - module procedure constructor_pong ! initialize a new pct_pft_type object with all PFT's on the gridcell - module procedure constructor_empty ! initialize a new pct_pft_type object for an empty landunit - end interface pct_pft_type - - ! !PRIVATE TYPES: - real(r8), parameter :: tol = 1.e-12_r8 ! tolerance for checking equality - - !EOP - -contains - - ! ======================================================================== - ! Constructors - ! ======================================================================== - - !----------------------------------------------------------------------- - function constructor_pong(pct_p2g, first_pft_index, default_pct_p2l) result(this) - ! - ! !DESCRIPTION: - ! Given the % of each pft on the grid cell, create a pct_pft_type object. - ! - ! Note that pct_p2g should just contain the pfts in this landunit. - ! - ! If all PFTs have 0 weight on the grid cell, we arbitrarily set % of each pft on the - ! landunit based on default_pct_p2l. Note that: - ! (1) size of default_pct_p2l must match size of pct_p2g - ! (2) default_pct_p2l must sum to 100% - ! - ! !ARGUMENTS: - type(pct_pft_type) :: this ! function result - - real(r8), intent(in) :: pct_p2g(:) ! % of each pft on the grid cell - integer , intent(in) :: first_pft_index ! index of the first pft (lower bound of arrays) - real(r8), intent(in) :: default_pct_p2l(:) ! default % of each pft on the landunit, used if total landunit area is 0% - ! - ! !LOCAL VARIABLES: - integer :: last_pft_index - - character(len=*), parameter :: subname = 'constructor_pong' - !----------------------------------------------------------------------- - - if (size(default_pct_p2l) /= size(pct_p2g)) then - write(6,*) subname//' ERROR: size of default_pct_p2l must match size of pct_p2g' - call abort() - end if - - last_pft_index = first_pft_index + size(pct_p2g) - 1 - allocate(this%pct_p2l(first_pft_index : last_pft_index)) - call this%convert_from_p2g(pct_p2g, default_pct_p2l) - - end function constructor_pong - - !----------------------------------------------------------------------- - function constructor(pct_p2l, pct_l2g, first_pft_index) result(this) - ! - ! !DESCRIPTION: - ! Given the % of each pft on the land cell and % of land unit on grid cell, - ! create a pct_pft_type object. - ! - ! Note that pct_p2g should just contain the pfts in this landunit. - ! - ! !ARGUMENTS: - type(pct_pft_type) :: this ! function result - - real(r8), intent(in) :: pct_p2l(:) ! % of each pft on the landunit - real(r8), intent(in) :: pct_l2g ! % of the landunit on the grid cell - integer , intent(in) :: first_pft_index ! index of the first pft (lower bound of arrays) - ! - ! !LOCAL VARIABLES: - integer :: last_pft_index - - character(len=*), parameter :: subname = 'constructor' - !----------------------------------------------------------------------- - - last_pft_index = first_pft_index + size(pct_p2l) - 1 - allocate(this%pct_p2l(first_pft_index : last_pft_index)) - this%pct_p2l = pct_p2l - this%pct_l2g = pct_l2g - - end function constructor - - !----------------------------------------------------------------------- - function constructor_empty() result(this) - ! - ! !DESCRIPTION: - ! Initialize a new pct_pft_type object for an empty landunit - that is, one that has - ! no PFTs on it, and never can (e.g., the crop landunit when we're running without - ! prognostic crops, so that the landunit is always empty). - ! - ! !ARGUMENTS: - type(pct_pft_type) :: this ! function result - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'constructor_empty' - !----------------------------------------------------------------------- - - this%pct_l2g = 0._r8 - allocate(this%pct_p2l(0)) - - end function constructor_empty - - - - ! ======================================================================== - ! Public member functions - ! ======================================================================== - - !----------------------------------------------------------------------- - function get_pct_p2l(this) result(pct_p2l) - ! - ! !DESCRIPTION: - ! Get an array holding % of each pft on the landunit - ! - ! !ARGUMENTS: - class(pct_pft_type), intent(in) :: this - real(r8) :: pct_p2l(size(this%pct_p2l)) ! function result - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'get_pct_p2l' - !----------------------------------------------------------------------- - - pct_p2l = this%pct_p2l - - end function get_pct_p2l - - !----------------------------------------------------------------------- - function get_pct_p2g(this) result(pct_p2g) - ! - ! !DESCRIPTION: - ! Get an array holding % of each pft on the gridcell - ! - ! !ARGUMENTS: - class(pct_pft_type), intent(in) :: this - real(r8) :: pct_p2g(size(this%pct_p2l)) ! function result - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'get_pct_p2g' - !----------------------------------------------------------------------- - - pct_p2g(:) = this%pct_p2l(:) * this%pct_l2g / 100._r8 - - end function get_pct_p2g - - !----------------------------------------------------------------------- - function get_pct_l2g(this) result(pct_l2g) - ! - ! !DESCRIPTION: - ! Get % of landunit on the grid cell - ! - ! !ARGUMENTS: - real(r8) :: pct_l2g ! function result - class(pct_pft_type), intent(in) :: this - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'get_pct_l2g' - !----------------------------------------------------------------------- - - pct_l2g = this%pct_l2g - - end function get_pct_l2g - - !----------------------------------------------------------------------- - function get_first_pft_index(this) result(first_pft_index) - ! - ! !DESCRIPTION: - ! Get index of the first pft (lower bound of arrays) - ! - ! !ARGUMENTS: - integer :: first_pft_index ! function result - class(pct_pft_type), intent(in) :: this - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'get_first_pft_index' - !----------------------------------------------------------------------- - - first_pft_index = lbound(this%pct_p2l, 1) - - end function get_first_pft_index - - !----------------------------------------------------------------------- - function get_one_pct_p2g(this, pft_index) result(pct_p2g) - ! - ! !DESCRIPTION: - ! Get % of gridcell for a single pft - ! - ! !ARGUMENTS: - real(r8) :: pct_p2g ! function result - class(pct_pft_type), intent(in) :: this - integer :: pft_index - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'get_one_pct_p2g' - !----------------------------------------------------------------------- - - pct_p2g = this%pct_p2l(pft_index) * this%pct_l2g / 100._r8 - - end function get_one_pct_p2g - - !----------------------------------------------------------------------- - subroutine set_pct_l2g(this, pct_l2g_new) - ! - ! !DESCRIPTION: - ! Set percent of landunit on the grid cell. Keep pct_p2l the same as before. - ! - ! !ARGUMENTS: - class(pct_pft_type), intent(inout) :: this - real(r8), intent(in) :: pct_l2g_new ! new percent of this landunit with respect to grid cell - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'set_pct_l2g' - !----------------------------------------------------------------------- - - if (pct_l2g_new < 0._r8 .or. pct_l2g_new > (100._r8 + tol)) then - write(6,*) subname//' ERROR: pct_l2g_new must be between 0 and 100%' - write(6,*) 'pct_l2g_new = ', pct_l2g_new - call abort() - end if - - this%pct_l2g = pct_l2g_new - - end subroutine set_pct_l2g - - !----------------------------------------------------------------------- - subroutine set_one_pct_p2g(this, pft_index, pct_p2g_new) - ! - ! !DESCRIPTION: - ! Set percent pft for a single pft, given its weight on the grid cell. - ! - ! The landunit percent is adjusted appropriately. In addition, the coverage of other - ! PFTs are adjusted proportionally so that the total pct_pft adds to 100%. - ! - ! If the resulting total weight on the grid cell is reduced to 0, then pct_p2l - ! remains as it was before this subroutine call. - ! - ! Note about pft_index: Note that the first element of the array has index given by - ! the first_pft_index value given to the constructor. - ! - ! !ARGUMENTS: - class(pct_pft_type), intent(inout) :: this - integer , intent(in) :: pft_index ! index of the pft to change - real(r8), intent(in) :: pct_p2g_new ! new percent of this pft, with respect to grid cell - ! - ! !LOCAL VARIABLES: - real(r8), allocatable :: pct_p2g(:) ! % of each pft on the grid cell - - character(len=*), parameter :: subname = 'set_pct_p2g' - !----------------------------------------------------------------------- - - if (pct_p2g_new < 0._r8 .or. pct_p2g_new > (100._r8 + tol)) then - write(6,*) subname//' ERROR: pct_p2g_new must be between 0 and 100%' - write(6,*) 'pct_p2g_new = ', pct_p2g_new - call abort() - end if - - allocate(pct_p2g(lbound(this%pct_p2l, 1) : ubound(this%pct_p2l, 1))) - pct_p2g(:) = this%get_pct_p2g() - pct_p2g(pft_index) = pct_p2g_new - - ! Note that by using this%pct_p2l as the default_pct_pl2 argument, we ensure that, if - ! the new p2g value brings the total % on the grid cell to 0, then we keep the - ! previous values for pct_p2l - call this%convert_from_p2g(pct_p2g, this%pct_p2l) - - deallocate(pct_p2g) - - end subroutine set_one_pct_p2g - - !----------------------------------------------------------------------- - subroutine merge_pfts(this, source, dest) - ! - ! !DESCRIPTION: - ! Merge all area from one PFT into another PFT - ! - ! !ARGUMENTS: - class(pct_pft_type), intent(inout) :: this - integer, intent(in) :: source ! index of source PFT - integer, intent(in) :: dest ! index of dest PFT - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'merge_pfts' - !----------------------------------------------------------------------- - - this%pct_p2l(dest) = this%pct_p2l(dest) + this%pct_p2l(source) - this%pct_p2l(source) = 0._r8 - - call this%check_vals(subname) - - end subroutine merge_pfts - - !----------------------------------------------------------------------- - subroutine remove_small_cover(this, too_small, nsmall) - ! - ! !DESCRIPTION: - ! Remove any small PFTs, defined as those whose grid cell coverage is below some - ! threshold. Also returns the number of small PFTs found. - ! - ! !USES: - ! - ! !ARGUMENTS: - class(pct_pft_type), intent(inout) :: this - real(r8), intent(in) :: too_small ! threshold for considering a PFT too small (% of grid cell) - integer , intent(out) :: nsmall ! number of small (but non-zero) PFTs found - ! - ! !LOCAL VARIABLES: - integer :: pft_lbound - integer :: pft_ubound - integer :: pft_index - real(r8), allocatable :: pct_p2g(:) ! % of each pft on the grid cell - logical , allocatable :: is_small(:) ! whether each PFT is considered too small (but not 0) - logical , allocatable :: is_zero(:) ! whether each PFT is exactly 0 - - character(len=*), parameter :: subname = 'remove_small_cover' - !----------------------------------------------------------------------- - - pft_lbound = lbound(this%pct_p2l, 1) - pft_ubound = ubound(this%pct_p2l, 1) - allocate(pct_p2g (pft_lbound : pft_ubound)) - allocate(is_small(pft_lbound : pft_ubound)) - allocate(is_zero (pft_lbound : pft_ubound)) - - pct_p2g(:) = this%get_pct_p2g() - is_zero(:) = (pct_p2g == 0._r8) - is_small(:) = (pct_p2g < too_small .and. .not. is_zero(:)) - - nsmall = count(is_small(:)) - - if (nsmall > 0) then - - if (all(is_zero(:) .or. is_small(:))) then - ! If all PFTs are either 0 or small, then set pct_l2g to 0, but don't touch - ! pct_p2l(:) (We do NOT set pct_p2l to all 0 in this case, because we need to - ! maintain sum(pct_p2l) = 100%) - this%pct_l2g = 0._r8 - - else - ! If there are some big PFTs, then we need to adjust pct_p2l as well as pct_l2g - ! (setting pct_p2l to 0 for the small elements and renormalizing the others) - do pft_index = pft_lbound, pft_ubound - if (is_small(pft_index)) then - call this%set_one_pct_p2g(pft_index, 0._r8) - end if - end do - end if - - call this%check_vals(subname) - end if - - deallocate(pct_p2g, is_small, is_zero) - end subroutine remove_small_cover - - ! ======================================================================== - ! Private member functions - ! ======================================================================== - - !----------------------------------------------------------------------- - subroutine convert_from_p2g(this, pct_p2g, default_pct_p2l) - ! - ! !DESCRIPTION: - ! Given a p2g array, compute the p2l array and l2g - ! - ! !ARGUMENTS: - class(pct_pft_type), intent(inout) :: this - real(r8), intent(in) :: pct_p2g(:) ! % of each pft on the grid cell - real(r8), intent(in) :: default_pct_p2l(:) ! default % of each pft on the landunit, used if total landunit area is 0% - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'convert_from_p2g' - !----------------------------------------------------------------------- - - ! Check pre-conditions - - if (size(pct_p2g) /= size(this%pct_p2l) .or. size(default_pct_p2l) /= size(this%pct_p2l)) then - write(6,*) subname//' ERROR: array size mismatch: ' - write(6,*) size(pct_p2g), size(default_pct_p2l), size(this%pct_p2l) - call abort() - end if - - if (abs(sum(default_pct_p2l) - 100._r8) > tol) then - write(6,*) subname//' ERROR: default_pct_p2l must sum to 100' - call abort() - end if - - if (any(pct_p2g < 0._r8)) then - write(6,*) subname//' ERROR: negative values found in pct_p2g array' - write(6,*) pct_p2g - call abort() - end if - - if (sum(pct_p2g) < 0._r8 .or. sum(pct_p2g) > (100._r8 + tol)) then - write(6,*) subname//' ERROR: pct_p2g must be between 0 and 100' - write(6,*) 'sum(pct_p2g) = ', sum(pct_p2g) - call abort() - end if - - ! Done checking pre-conditions - - this%pct_l2g = sum(pct_p2g) - if (this%pct_l2g > 0._r8) then - this%pct_p2l = pct_p2g / this%pct_l2g * 100._r8 - else - this%pct_p2l = default_pct_p2l - end if - - ! Check post-conditions - - call this%check_vals(subname) - - end subroutine convert_from_p2g - - - !----------------------------------------------------------------------- - subroutine check_vals(this, caller) - ! - ! !DESCRIPTION: - ! Perform a sanity check after setting values - ! - ! !ARGUMENTS: - class(pct_pft_type), intent(in) :: this - character(len=*), intent(in) :: caller ! name of the calling subroutine - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'check_vals' - !----------------------------------------------------------------------- - - if (abs(sum(this%pct_p2l) - 100._r8) > tol) then - write(6,*) subname//' ERROR from ', caller, ': pct_p2l does not sum to 100' - write(6,*) 'sum(this%pct_p2l) = ', sum(this%pct_p2l) - call abort() - end if - - if (any(this%pct_p2l < 0._r8)) then - write(6,*) subname//' ERROR from ', caller, ': negative values found in pct_p2l' - write(6,*) this%pct_p2l - call abort() - end if - - if (this%pct_l2g < 0._r8 .or. this%pct_l2g > (100._r8 + tol)) then - write(6,*) subname//' ERROR from ', caller, ': pct_l2g must be between 0 and 100' - write(6,*) 'pct_l2g = ', this%pct_l2g - call abort() - end if - - end subroutine check_vals - - ! ======================================================================== - ! Module-level routines (not member functions) - ! ======================================================================== - - !----------------------------------------------------------------------- - subroutine update_max_array(pct_pft_max_arr,pct_pft_arr) - ! - ! !DESCRIPTION: - ! Given an array of pct_pft_type variables, update all the max_p2l variables. - ! - ! Assumes that all elements of pct_pft_max_arr and pct_pft_arr have the same - ! size and lower bound for their pct_p2l array. - ! - ! !ARGUMENTS: - ! workaround for gfortran bug (58043): declare this 'type' rather than 'class': - type(pct_pft_type), intent(inout) :: pct_pft_max_arr(:) - type(pct_pft_type), intent(in) :: pct_pft_arr(:) - ! - ! !LOCAL VARIABLES: - integer :: pft_lbound - integer :: pft_ubound - integer :: arr_index - integer :: pft_index - - character(len=*), parameter :: subname = 'update_max_array' - !----------------------------------------------------------------------- - - - pft_lbound = lbound(pct_pft_arr(1)%pct_p2l, 1) - pft_ubound = ubound(pct_pft_arr(1)%pct_p2l, 1) - - do arr_index = 1, size(pct_pft_arr) - if (lbound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_lbound .or. & - ubound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_ubound) then - write(6,*) subname//' ERROR: all elements of pct_pft_arr must have' - write(6,*) 'the same size and lower bound for their pct_p2l array' - call abort() - end if - - if (pct_pft_arr(arr_index)%pct_l2g > pct_pft_max_arr(arr_index)%pct_l2g) then - pct_pft_max_arr(arr_index)%pct_l2g = pct_pft_arr(arr_index)%pct_l2g - end if - - do pft_index = pft_lbound, pft_ubound - if (pct_pft_arr(arr_index)%pct_p2l(pft_index) > pct_pft_max_arr(arr_index)%pct_p2l(pft_index)) then - pct_pft_max_arr(arr_index)%pct_p2l(pft_index) = pct_pft_arr(arr_index)%pct_p2l(pft_index) - end if - end do - end do - - end subroutine update_max_array - - !----------------------------------------------------------------------- - function get_pct_p2l_array(pct_pft_arr) result(pct_p2l) - ! - ! !DESCRIPTION: - ! Given an array of pct_pft_type variables, return a 2-d array of pct_p2l. - ! - ! Assumes that all elements of pct_pft_arr have the same size and lower bound for - ! their pct_p2l array. - ! - ! !ARGUMENTS: - real(r8), allocatable :: pct_p2l(:,:) ! function result (n_elements, n_pfts) - ! workaround for gfortran bug (58043): declare this 'type' rather than 'class': - type(pct_pft_type), intent(in) :: pct_pft_arr(:) - ! - ! !LOCAL VARIABLES: - integer :: pft_lbound - integer :: pft_ubound - integer :: arr_index - integer :: pft_index - - character(len=*), parameter :: subname = 'get_pct_p2l_array' - !----------------------------------------------------------------------- - - pft_lbound = lbound(pct_pft_arr(1)%pct_p2l, 1) - pft_ubound = ubound(pct_pft_arr(1)%pct_p2l, 1) - - allocate(pct_p2l(size(pct_pft_arr), pft_lbound:pft_ubound)) - - do arr_index = 1, size(pct_pft_arr) - if (lbound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_lbound .or. & - ubound(pct_pft_arr(arr_index)%pct_p2l, 1) /= pft_ubound) then - write(6,*) subname//' ERROR: all elements of pct_pft_arr must have' - write(6,*) 'the same size and lower bound for their pct_p2l array' - call abort() - end if - - do pft_index = pft_lbound, pft_ubound - pct_p2l(arr_index, pft_index) = pct_pft_arr(arr_index)%pct_p2l(pft_index) - end do - end do - - end function get_pct_p2l_array - - !----------------------------------------------------------------------- - function get_pct_l2g_array(pct_pft_arr) result(pct_l2g) - ! - ! !DESCRIPTION: - ! Given an array of pct_pft_type variables, return an array of pct_l2g. - ! - ! !ARGUMENTS: - real(r8), allocatable :: pct_l2g(:) ! function result - class(pct_pft_type), intent(in) :: pct_pft_arr(:) - ! - ! !LOCAL VARIABLES: - integer :: arr_index - - character(len=*), parameter :: subname = 'get_pct_l2g_array' - !----------------------------------------------------------------------- - - allocate(pct_l2g(size(pct_pft_arr))) - pct_l2g = pct_pft_arr(:)%pct_l2g - - end function get_pct_l2g_array - - -end module mkpctPftTypeMod diff --git a/tools/mksurfdata_map/src/mkpeatMod.F90 b/tools/mksurfdata_map/src/mkpeatMod.F90 deleted file mode 100644 index 8e47f5032d..0000000000 --- a/tools/mksurfdata_map/src/mkpeatMod.F90 +++ /dev/null @@ -1,149 +0,0 @@ -module mkpeatMod - -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkpeatMod -! -! !DESCRIPTION: -! make fraction peat from input peat data -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -!----------------------------------------------------------------------- -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - use mkdomainMod , only : domain_checksame - - implicit none - - private - -! !PUBLIC MEMBER FUNCTIONS: - public mkpeat ! regrid peat data -! -!EOP -!=============================================================== -contains -!=============================================================== - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkpeat -! -! !INTERFACE: -subroutine mkpeat(ldomain, mapfname, datfname, ndiag, peat_o) -! -! !DESCRIPTION: -! make peat -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_area - use mkchecksMod, only : min_bad, max_bad -! -! !ARGUMENTS: - - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: peat_o(:) ! output grid: fraction peat -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: data_i(:) ! data on input grid - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - - real(r8), parameter :: min_valid = 0._r8 ! minimum valid value - real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value - character(len=32) :: subname = 'mkpeat' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make peat .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - call domain_read( tdomain, datfname ) - - call gridmap_mapread( tgridmap, mapfname ) - - ! Obtain frac_dst - allocate(frac_dst(ldomain%ns), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write(6,*)'Open peat file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(data_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() - - ! ----------------------------------------------------------------- - ! Regrid peat - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'peatf', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, peat_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(peat_o, min_valid, 'peat') .or. & - max_bad(peat_o, max_valid, 'peat')) then - call abort() - end if - - call output_diagnostics_area(data_i, peat_o, tgridmap, "Peat", percent=.false., ndiag=ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- - - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (data_i) - deallocate (frac_dst) - deallocate (mask_r8) - - write (6,*) 'Successfully made peat' - write (6,*) - call shr_sys_flush(6) - -end subroutine mkpeat - - -end module mkpeatMod diff --git a/tools/mksurfdata_map/src/mkpftConstantsMod.F90 b/tools/mksurfdata_map/src/mkpftConstantsMod.F90 deleted file mode 100644 index 241873c339..0000000000 --- a/tools/mksurfdata_map/src/mkpftConstantsMod.F90 +++ /dev/null @@ -1,43 +0,0 @@ -module mkpftConstantsMod - !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mkpftConstants - ! - ! !DESCRIPTION: - ! Constants used by mkpft and related code - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! - !----------------------------------------------------------------------- - !!USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - - implicit none - private - - ! - ! !PUBLIC DATA MEMBERS: - ! - - integer, parameter, public :: maxpft = 78 ! maximum # of PFT - - integer, public :: num_natpft = -1 ! number of PFTs on the natural vegetation - ! landunit, NOT including bare ground - ! (includes generic crops for runs with - ! create_crop_landunit=false) - - integer, public :: num_cft ! number of CFTs on the crop landunit - integer, public :: natpft_lb ! lower bound for natural pft arrays - integer, public :: natpft_ub ! upper bound for natural pft arrays - integer, public :: cft_lb ! lower bound for cft arrays - integer, public :: cft_ub ! upper bound for cft arrays - - integer, parameter, public :: baregroundindex = 0 ! index of bare ground in a natural pft array - - ! The following is NOT set as a parameter so that it can be overridden in unit tests - integer, public :: c3cropindex = 15 - integer, public :: c3irrcropindex = 16 - -end module mkpftConstantsMod diff --git a/tools/mksurfdata_map/src/mkpftMod.F90 b/tools/mksurfdata_map/src/mkpftMod.F90 deleted file mode 100644 index 2eae1ae381..0000000000 --- a/tools/mksurfdata_map/src/mkpftMod.F90 +++ /dev/null @@ -1,1259 +0,0 @@ -module mkpftMod - -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkpft -! -! !DESCRIPTION: -! Make PFT data -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -!----------------------------------------------------------------------- -!!USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - use mkvarpar , only : noveg - use mkvarctl , only : numpft - use mkdomainMod , only : domain_checksame - use mkpftConstantsMod - - implicit none - - private ! By default make data private -! -! !PUBLIC MEMBER FUNCTIONS: -! - public mkpftInit ! Initialization - public mkpft ! Set PFT - public mkpft_parse_oride ! Parse the string with PFT fraction/index info to override - public mkpftAtt ! Write out attributes to output file on pft -! -! !PUBLIC DATA MEMBERS: -! - - ! - ! When pft_idx and pft_frc are set, they must be set together, and they will cause the - ! entire area to be covered with vegetation and zero out other landunits. - ! The sum of pft_frc must = 100%, and each pft_idx point in the array corresponds to - ! the fraction in pft_frc. Only the first few points are used until pft_frc = 0.0. - ! - integer :: m ! index - integer, public :: pft_idx(0:maxpft) = & ! PFT vegetation index to override with - (/ ( -1, m = 0, maxpft ) /) - real(r8), public :: pft_frc(0:maxpft) = & ! PFT vegetation fraction to override with - (/ ( 0.0_r8, m = 0, maxpft ) /) -! -! !PRIVATE DATA MEMBERS: -! - logical, public, protected :: use_input_pft = .false. ! Flag to override PFT with input values - logical, public, protected :: presc_cover = .false. ! Flag to prescribe vegetation coverage - integer, private :: nzero ! index of first zero fraction - - type, public :: pft_oride ! Public only for unit testing - real(r8) :: crop ! Percent covered by crops - real(r8) :: natveg ! Percent covered by natural vegetation - real(r8), allocatable :: natpft(:) ! Percent of each natural PFT within the natural veg landunit - real(r8), allocatable :: cft(:) ! Percent of each crop CFT within the crop landunit - contains - procedure, public :: InitZeroOut ! Initialize the PFT override object to zero out all vegetation - procedure, public :: InitAllPFTIndex ! Initialize the PFT override object with PFT indeces for all veg and crop types - procedure, public :: Clean ! Clean up a PFT Override object - end type pft_oride - - interface pft_oride - module procedure :: constructor ! PFT Overide object constructor - end interface pft_oride - - type(pft_oride), private :: pft_override ! Module instance of PFT override object - ! Used for both zeroing out PFT's as well - ! as setting specified PFT's over the gridcell -! -! !PRIVATE MEMBER FUNCTIONS: -! - private :: mkpft_check_oride ! Check the pft_frc and pft_idx values for correctness -!EOP -!=============================================================== -contains -!=============================================================== - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkpftInit -! -! !INTERFACE: -subroutine mkpftInit( zero_out_l, all_veg_l ) -! -! !DESCRIPTION: -! Initialize of Make PFT data -! !USES: - use mkvarpar, only : numstdpft, numstdcft -! -! !ARGUMENTS: - implicit none - logical, intent(IN) :: zero_out_l ! If veg should be zero'ed out - logical, intent(IN) :: all_veg_l ! If should zero out other fractions so that - ! all land-cover is vegetation -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - real(r8), parameter :: hndrd = 100.0_r8 ! A hundred percent - character(len=32) :: subname = 'mkpftMod::mkpftInit() ' - logical :: error_happened ! If an error was triggered so should return -!----------------------------------------------------------------------- - write (6, '(a, a, a)') "In ", trim(subname), "..." - if ( maxpft < numpft ) then - write(6,*) subname//'number PFT is > max allowed!' - call abort() - return - end if - nzero = -1 - call mkpft_check_oride( error_happened ) - if ( error_happened )then - write(6,*) subname//'Problem setting pft override settings' - return - end if - if ( zero_out_l .and. use_input_pft )then - write(6,*) subname//"trying to both zero out all PFT's as well as set them to specific values" - call abort() - return - end if - ! If zeroing out, set use_input_pft to true so the pft_override will be used - if( zero_out_l )then - nzero = 0 - pft_frc(0) = 0.0_r8 - pft_idx(0) = noveg - use_input_pft = .true. - end if - if ( use_input_pft ) then - write(6,*) 'Set PFT fraction to : ', pft_frc(0:nzero) - write(6,*) 'With PFT index : ', pft_idx(0:nzero) - end if - if ( all_veg_l .and. .not. use_input_pft )then - write(6,*) subname//'if all_veg is set to true then specified PFT indices must be provided (i.e. pft_frc and pft_idx)' - call abort() - return - end if - - if ( zero_out_l .and. all_veg_l )then - write(6,*) subname//'zeroing out vegetation and setting vegetation to 100% is a contradiction!' - call abort() - return - end if - - ! Determine number of PFTs on the natural vegetation landunit, and number of CFTs on - ! the crop landunit. - ! - ! For the sake of dynamic PFTs and dynamic landunits, it helps for the structure of the - ! surface dataset to reflect the subgrid structure that will be used by CLM. Currently - ! generic crops will always go on the crop landunit, regardless of whether or not we're - ! using the extra specific crops (so we always run CLM with create_crop_landunit=.true.). - ! When we create a surface dataset WITH the extra specific crops, all crops - ! (including the generic crops) again go on the crop landunit. - - num_natpft = numstdpft - numstdcft - num_cft = numpft - num_natpft - - ! Determine array bounds for arrays of just natural pfts and just crops. Note that - ! these are set up so that they always span 0:numpft, so that there is a 1:1 - ! correspondence between an element in a full 0:numpft array and an element with the - ! same index in either a natpft array or a cft array. - natpft_lb = noveg - natpft_ub = num_natpft - cft_lb = num_natpft+1 - cft_ub = cft_lb + num_cft - 1 - - ! Make sure the array indices have been set up properly, to ensure the 1:1 - ! correspondence mentioned above - if (cft_ub /= numpft) then - write(6,*) 'CFT_UB set up incorrectly: cft_ub, numpft = ', cft_ub, numpft - call abort() - return - end if - ! - ! Set the PFT override values if applicable - ! - pft_override = pft_oride() - presc_cover = .false. - if( zero_out_l )then - call pft_override%InitZeroOut() - presc_cover = .true. - else if ( use_input_pft ) then - call pft_override%InitAllPFTIndex() - if ( .not. all_veg_l )then - if ( pft_override%crop <= 0.0 )then - write(6,*) "Warning: PFT/CFT's are being overridden, but no crop type is being asked for" - end if - if ( pft_override%natveg <= 0.0 )then - write(6,*) "Warning: PFT/CFT's are being overridden, but no natural vegetation type is being asked for" - end if - presc_cover = .false. - else - presc_cover = .true. - end if - end if - -end subroutine mkpftInit - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkpft -! -! !INTERFACE: -subroutine mkpft(ldomain, mapfname, fpft, ndiag, & - pctlnd_o, pctnatpft_o, pctcft_o) -! -! !DESCRIPTION: -! Make PFT data -! -! This dataset consists of the %cover of the [numpft]+1 PFTs used by -! the model. The input %cover pertains to the "vegetated" portion of the -! grid cell and sums to 100. The real portion of each grid cell -! covered by each PFT is the PFT cover times the fraction of the -! grid cell that is land. This is the quantity preserved when -! area-averaging from the input (1/2 degree) grid to the models grid. -! -! Upon return from this routine, the % cover of the natural veg + crop landunits is -! generally 100% everywhere; this will be normalized later to account for special landunits. -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio - use mkpctPftTypeMod, only : pct_pft_type - use mkpftConstantsMod, only : natpft_lb, natpft_ub, num_cft, cft_lb, cft_ub -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: fpft ! input pft dataset file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: pctlnd_o(:) ! output grid:%land/gridcell - type(pct_pft_type), intent(out):: pctnatpft_o(:) ! natural PFT cover - type(pct_pft_type), intent(out):: pctcft_o(:) ! crop (CFT) cover -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - type(pct_pft_type), allocatable:: pctnatpft_i(:) ! input grid: natural PFT cover - type(pct_pft_type), allocatable:: pctcft_i(:) ! input grid: crop (CFT) cover - type(domain_type) :: tdomain ! local domain - type(gridmap_type) :: tgridmap ! local gridmap - real(r8), allocatable :: pctpft_i(:,:) ! input grid: PFT percent - real(r8), allocatable :: pctpft_o(:,:) ! output grid: PFT percent (% of grid cell) - real(r8), allocatable :: pctnatveg_i(:) ! input grid: natural veg percent (% of grid cell) - real(r8), allocatable :: pctnatveg_o(:) ! output grid: natural veg percent (% of grid cell) - real(r8), allocatable :: pctcrop_i(:) ! input grid: all crop percent (% of grid cell) - real(r8), allocatable :: pctcrop_o(:) ! output grid: all crop percent (% of grid cell) - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: pct_cft_i(:,:) ! input grid: CFT (Crop Functional Type) percent (% of landunit cell) - real(r8), allocatable :: temp_i(:,:) ! input grid: temporary 2D variable to read in - real(r8), allocatable :: pct_cft_o(:,:) ! output grid: CFT (Crop Functional Type) percent (% of landunit cell) - real(r8), allocatable :: pct_nat_pft_i(:,:) ! input grid: natural PFT percent (% of landunit cell) - real(r8), allocatable :: pct_nat_pft_o(:,:) ! output grid: natural PFT percent (% of landunit cell) - integer :: numpft_i ! num of plant types input data - integer :: natpft_i ! num of natural plant types input data - integer :: ncft_i ! num of crop types input data - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: wst_sum ! sum of %pft - real(r8), allocatable :: gpft_o(:) ! output grid: global area pfts - real(r8) :: garea_o ! output grid: global area - real(r8), allocatable :: gpft_i(:) ! input grid: global area pfts - real(r8) :: garea_i ! input grid: global area - integer :: k,n,m,ni,no,ns_i,ns_o ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ndims ! number of dimensions for a variable on the file - integer :: dimlens(3) ! dimension lengths for a variable on the file - integer :: ier ! error status - real(r8) :: relerr = 0.0001_r8 ! max error: sum overlap wts ne 1 - logical :: oldformat ! if input file is in the old format or not (based on what variables exist) - logical :: error_happened ! If an error was triggered so should return - - character(len=35) veg(0:maxpft) ! vegetation types - character(len=32) :: subname = 'mkpftMod::mkpft()' -!----------------------------------------------------------------------- - - write (6,*) - write (6, '(a, a, a)') "In ", trim(subname), "..." - write (6,*) 'Attempting to make PFTs .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Set the vegetation types - ! ----------------------------------------------------------------- - if ( numpft >= numstdpft )then - veg(0:maxpft) = (/ & - 'not vegetated ', & - 'needleleaf evergreen temperate tree', & - 'needleleaf evergreen boreal tree ', & - 'needleleaf deciduous boreal tree ', & - 'broadleaf evergreen tropical tree ', & - 'broadleaf evergreen temperate tree ', & - 'broadleaf deciduous tropical tree ', & - 'broadleaf deciduous temperate tree ', & - 'broadleaf deciduous boreal tree ', & - 'broadleaf evergreen shrub ', & - 'broadleaf deciduous temperate shrub', & - 'broadleaf deciduous boreal shrub ', & - 'c3 arctic grass ', & - 'c3 non-arctic grass ', & - 'c4 grass ', & - 'c3_crop ', & - 'c3_irrigated ', & - 'temperate_corn ', & - 'irrigated_temperate_corn ', & - 'spring_wheat ', & - 'irrigated_spring_wheat ', & - 'winter_wheat ', & - 'irrigated_winter_wheat ', & - 'temperate_soybean ', & - 'irrigated_temperate_soybean ', & - 'barley ', & - 'irrigated_barley ', & - 'winter_barley ', & - 'irrigated_winter_barley ', & - 'rye ', & - 'irrigated_rye ', & - 'winter_rye ', & - 'irrigated_winter_rye ', & - 'cassava ', & - 'irrigated_cassava ', & - 'citrus ', & - 'irrigated citrus ', & - 'cocoa ', & - 'irrigated_cocoa ', & - 'coffee ', & - 'irrigated_coffee ', & - 'cotton ', & - 'irrigated_cotton ', & - 'datepalm ', & - 'irrigated_datepalm ', & - 'foddergrass ', & - 'irrigated_foddergrass ', & - 'grapes ', & - 'irrigated_grapes ', & - 'groundnuts ', & - 'irrigated_groundnuts ', & - 'millet ', & - 'irrigated_millet ', & - 'oilpalm ', & - 'irrigated_oilpalm ', & - 'potatoes ', & - 'irrigated_potatoes ', & - 'pulses ', & - 'irrigated_pulses ', & - 'rapeseed ', & - 'irrigated_rapeseed ', & - 'rice ', & - 'irrigated_rice ', & - 'sorghum ', & - 'irrigated_sorghum ', & - 'sugarbeet ', & - 'irrigated_sugarbeet ', & - 'sugarcane ', & - 'irrigated_sugarcane ', & - 'sunflower ', & - 'irrigated_sunflower ', & - 'miscanthus ', & - 'irrigated_miscanthus ', & - 'switchgrass ', & - 'irrigated_switchgrass ', & - 'tropical_corn ', & - 'irrigated_tropical_corn ', & - 'tropical_soybean ', & - 'irrigated_tropical_soybean ' /) - end if - if ( numpft == numstdpft )then - write(6,*)'Creating surface datasets with the standard # of PFTs =', numpft - else if ( numpft > numstdpft )then - write(6,*)'Creating surface datasets with extra types for crops; total pfts =', numpft - else - write(6,*) subname//': parameter numpft is NOT set to a known value (should be 16 or more) =',numpft - call abort() - return - end if - - ns_o = ldomain%ns - - ! ----------------------------------------------------------------- - ! Read input PFT file - ! ----------------------------------------------------------------- - if ( .not. presc_cover ) then - ! Obtain input grid info, read PCT_PFT - - call domain_read(tdomain,fpft) - ns_i = tdomain%ns - - write (6,*) 'Open PFT file: ', trim(fpft) - call check_ret(nf_open(fpft, 0, ncid), subname) - - ! Check what variables exist to determine what format the file is in - call check_ret(nf_inq_varid (ncid, 'PCT_PFT', varid), subname, varexists=oldformat) - - if ( oldformat ) then - write(6,*) subname//' ERROR: PCT_PFT field on the the file so it is in the old format, which is no longer supported' - call abort() - return - end if - call check_ret(nf_inq_dimid (ncid, 'natpft', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, natpft_i), subname) - call check_ret(nf_inq_dimid (ncid, 'cft', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, ncft_i), subname) - numpft_i = natpft_i + ncft_i - - ! Check if the number of pfts on the input matches the expected number. A mismatch - ! is okay if the input raw dataset has prognostic crops and the output does not. - if (numpft_i .ne. numpft+1) then - if (numpft_i .eq. numstdpft+1) then - write(6,*) subname//' ERROR: trying to use non-crop input file' - write(6,*) 'for a surface dataset with crops.' - call abort() - return - else if (numpft_i > numstdpft+1 .and. numpft_i == maxpft+1) then - write(6,*) subname//' WARNING: using a crop input raw dataset for a non-crop output surface dataset' - else - write(6,*) subname//': parameter numpft+1= ',numpft+1, & - 'does not equal input dataset numpft= ',numpft_i - call abort() - return - end if - endif - - - ! If file is in the new format, expect the following variables: - ! PCT_NATVEG, PCT_CROP, PCT_NAT_PFT, PCT_CFT - allocate(pctnatveg_i(ns_i), & - pctnatveg_o(ns_o), & - pctcrop_i(ns_i), & - pctcrop_o(ns_o), & - frac_dst(ns_o), & - pct_cft_i(ns_i,1:num_cft), & - pct_cft_o(ns_o,1:num_cft), & - pct_nat_pft_i(ns_i,0:num_natpft), & - pct_nat_pft_o(ns_o,0:num_natpft), & - stat=ier) - if (ier/=0)then - call abort() - return - end if - - call check_ret(nf_inq_varid (ncid, 'PCT_NATVEG', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, pctnatveg_i), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_CROP', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, pctcrop_i), subname) - if ( .not. use_input_pft )then - call check_ret(nf_inq_varid (ncid, 'PCT_CFT', varid), subname) - call get_dim_lengths(ncid, 'PCT_CFT', ndims, dimlens(:) ) - if ( ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) == num_cft )then - call check_ret(nf_get_var_double (ncid, varid, pct_cft_i), subname) - else if ( ndims == 3 .and. dimlens(1)*dimlens(2) == ns_i .and. dimlens(3) > num_cft )then - ! Read in the whole array: then sum the rainfed and irrigated - ! seperately - allocate( temp_i(ns_i,dimlens(3)) ) - call check_ret(nf_get_var_double (ncid, varid, temp_i), subname) - do n = 1, num_cft - pct_cft_i(:,n) = 0.0_r8 - do m = n, dimlens(3), 2 - pct_cft_i(:,n) = pct_cft_i(:,n) + temp_i(:,m) - end do - end do - deallocate( temp_i ) - else - write(6,*) subname//': ERROR: dimensions for PCT_CROP are NOT what is expected' - call abort() - return - end if - call check_ret(nf_inq_varid (ncid, 'PCT_NAT_PFT', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, pct_nat_pft_i), subname) - end if - - call check_ret(nf_close(ncid), subname) - - ! ----------------------------------------------------------------- - ! Otherwise if vegetation is prescribed everywhere - ! ----------------------------------------------------------------- - else - ns_i = 1 - numpft_i = numpft+1 - allocate(pctnatveg_i(ns_i), & - pctnatveg_o(ns_o), & - pctcrop_i(ns_i), & - pctcrop_o(ns_o), & - pct_cft_i(ns_i,1:num_cft), & - pct_cft_o(ns_o,1:num_cft), & - pct_nat_pft_i(ns_i,0:num_natpft), & - pct_nat_pft_o(ns_o,0:num_natpft), & - stat=ier) - if (ier/=0)then - call abort() - return - end if - end if - allocate(pctpft_i(ns_i,0:(numpft_i-1)), & - pctpft_o(ns_o,0:(numpft_i-1)), & - pctnatpft_i(ns_i), & - pctcft_i(ns_i), & - stat=ier) - if (ier/=0)then - call abort() - return - end if - - ! Determine pctpft_o on output grid - - ! If total vegetation cover is prescribed from input... - if ( use_input_pft .and. presc_cover ) then - - do no = 1,ns_o - pctlnd_o(no) = 100._r8 - pctnatveg_o(no) = pft_override%natveg - pctcrop_o(no) = pft_override%crop - end do - - ! otherewise if total cover isn't prescribed read it from the datasets - else - - ! Compute pctlnd_o, pctpft_o - - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - ! Area-average percent cover on input grid [pctpft_i] to output grid - ! [pctpft_o] and correct [pctpft_o] according to land landmask - ! Note that percent cover is in terms of total grid area. - pctlnd_o(:) = frac_dst(:) * 100._r8 - - ! New format with extra variables on input - call gridmap_areaave_srcmask(tgridmap, pctnatveg_i, pctnatveg_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, pctcrop_i, pctcrop_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! - ! If specific PFT/CFT's are NOT prescribed set them from the input file - ! - if ( .not. use_input_pft )then - do m = 0, num_natpft - call gridmap_areaave_scs(tgridmap, pct_nat_pft_i(:,m), & - pct_nat_pft_o(:,m), nodata=0._r8, & - src_wt=pctnatveg_i*0.01_r8*tdomain%mask, & - dst_wt=pctnatveg_o*0.01_r8, frac_dst=frac_dst) - do no = 1,ns_o - if (pctlnd_o(no) < 1.0e-6 .or. pctnatveg_o(no) < 1.0e-6) then - if (m == 0) then - pct_nat_pft_o(no,m) = 100._r8 - else - pct_nat_pft_o(no,m) = 0._r8 - endif - end if - enddo - end do - do m = 1, num_cft - call gridmap_areaave_scs(tgridmap, pct_cft_i(:,m), pct_cft_o(:,m), & - nodata=0._r8, src_wt=pctcrop_i*0.01_r8*tdomain%mask, & - dst_wt=pctcrop_o*0.01_r8, frac_dst=frac_dst) - do no = 1,ns_o - if (pctlnd_o(no) < 1.0e-6 .or. pctcrop_o(no) < 1.0e-6) then - if (m == 1) then - pct_cft_o(no,m) = 100._r8 - else - pct_cft_o(no,m) = 0._r8 - endif - end if - enddo - end do - ! Otherwise do some error checking to make sure specific veg types are given where nat-veg and crop is assigned - else - do no = 1,ns_o - if (pctlnd_o(no) > 1.0e-6 .and. pctnatveg_o(no) > 1.0e-6) then - if ( pft_override%natveg <= 0.0_r8 )then - write(6,*) subname//': ERROR: no natural vegetation PFTs are being prescribed but there are natural '// & - 'vegetation areas: provide at least one natural veg PFT' - call abort() - return - end if - end if - if (pctlnd_o(no) > 1.0e-6 .and. pctcrop_o(no) > 1.0e-6) then - if ( pft_override%crop <= 0.0_r8 )then - write(6,*) subname//': ERROR: no crop CFTs are being prescribed but there are crop areas: provide at least one CFT' - call abort() - return - end if - end if - end do - end if - end if - - ! - ! If specific PFT/CFT's are prescribed set them directly - ! - if ( use_input_pft )then - do no = 1,ns_o - if (pctlnd_o(no) > 1.0e-6 .and. pctnatveg_o(no) > 1.0e-6) then - pct_nat_pft_o(no,noveg:num_natpft) = pft_override%natpft(noveg:num_natpft) - else - pct_nat_pft_o(no,noveg) = 100._r8 - pct_nat_pft_o(no,noveg+1:) = 0._r8 - end if - if (pctlnd_o(no) > 1.0e-6 .and. pctcrop_o(no) > 1.0e-6) then - pct_cft_o(no,1:num_cft) = pft_override%cft(1:num_cft) - else - pct_cft_o(no,1) = 100._r8 - pct_cft_o(no,2:) = 0._r8 - end if - pctpft_o(no,natpft_lb:natpft_ub) = pct_nat_pft_o(no,0:num_natpft) - pctpft_o(no,cft_lb:cft_ub) = pct_cft_o(no,1:num_cft) - end do - end if - - - ! Error check: percents should sum to 100 for land grid cells, within roundoff - ! Also correct sums so that if they differ slightly from 100, they are corrected to - ! equal 100 more exactly. - - do no = 1,ns_o - wst_sum = 0. - do m = 0, num_natpft - wst_sum = wst_sum + pct_nat_pft_o(no,m) - enddo - if (abs(wst_sum-100._r8) > relerr) then - write (6,*) subname//'error: nat pft = ', & - (pct_nat_pft_o(no,m), m = 0, num_natpft), & - ' do not sum to 100. at no = ',no,' but to ', wst_sum - call abort() - end if - - ! Correct sum so that if it differs slightly from 100, it is corrected to equal - ! 100 more exactly - do m = 1, num_natpft - pct_nat_pft_o(no,m) = pct_nat_pft_o(no,m) * 100._r8 / wst_sum - end do - - wst_sum = 0. - do m = 1, num_cft - wst_sum = wst_sum + pct_cft_o(no,m) - enddo - if (abs(wst_sum-100._r8) > relerr) then - write (6,*) subname//'error: crop cft = ', & - (pct_cft_o(no,m), m = 1, num_cft), & - ' do not sum to 100. at no = ',no,' but to ', wst_sum - call abort() - end if - - ! Correct sum so that if it differs slightly from 100, it is corrected to equal - ! 100 more exactly - do m = 1, num_cft - pct_cft_o(no,m) = pct_cft_o(no,m) * 100._r8 / wst_sum - end do - - end do - - ! Convert % pft as % of grid cell to % pft on the landunit and % of landunit on the - ! grid cell - do no = 1,ns_o - pctnatpft_o(no) = pct_pft_type( pct_nat_pft_o(no,:), pctnatveg_o(no), first_pft_index=natpft_lb ) - pctcft_o(no) = pct_pft_type( pct_cft_o(no,:), pctcrop_o(no), first_pft_index=cft_lb ) - end do - - ! ----------------------------------------------------------------- - ! Error check - ! Compare global areas on input and output grids - ! Only when you aren't prescribing the vegetation coverage everywhere - ! If use_input_pft is set this will compare the global coverage of - ! the prescribed vegetation to the coverage of PFT/CFT's on the input - ! datasets. - ! ----------------------------------------------------------------- - - if ( .not. presc_cover ) then - - ! Convert to pctpft over grid if using new format - do ni = 1, ns_i - pctnatpft_i(ni) = pct_pft_type( pct_nat_pft_i(ni,:), pctnatveg_i(ni), first_pft_index=natpft_lb ) - pctcft_i(ni) = pct_pft_type( pct_cft_i(ni,:), pctcrop_i(ni), first_pft_index=cft_lb ) - end do - - do no = 1,ns_o - pctpft_o(no,natpft_lb:natpft_ub) = pctnatpft_o(no)%get_pct_p2g() - pctpft_o(no,cft_lb:cft_ub) = pctcft_o(no)%get_pct_p2g() - end do - allocate(gpft_i(0:numpft_i-1)) - allocate(gpft_o(0:numpft_i-1)) - - ! input grid - - gpft_i(:) = 0. - garea_i = 0. - do ni = 1,ns_i - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - do m = 0, numpft_i - 1 - gpft_i(m) = gpft_i(m) + pctpft_i(ni,m)*tgridmap%area_src(ni)*& - tdomain%mask(ni)*re**2 - end do - end do - if ( allocated(pctpft_i) ) deallocate (pctpft_i) - - ! output grid - - gpft_o(:) = 0. - garea_o = 0. - do no = 1,ns_o - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - do m = 0, numpft_i - 1 - gpft_o(m) = gpft_o(m) + pctpft_o(no,m)*tgridmap%area_dst(no)*& - frac_dst(no)*re**2 - end do - end do - - ! comparison - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'PFTs Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,1001) -1001 format (1x,'plant type ',20x,' input grid area',' output grid area',/ & - 1x,33x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - do m = 0, numpft_i - 1 - write (ndiag,1002) veg(m), gpft_i(m)*1.e-06/100.,gpft_o(m)*1.e-06/100. - end do -1002 format (1x,a35,f16.3,f17.3) - call shr_sys_flush(ndiag) - - deallocate(gpft_i, gpft_o, frac_dst) - - end if - deallocate( pctnatpft_i ) - deallocate( pctcft_i ) - deallocate(pctpft_o) - - - ! Deallocate dynamic memory - - deallocate(pctnatveg_i) - deallocate(pctnatveg_o) - deallocate(pctcrop_i) - deallocate(pctcrop_o) - deallocate(pct_cft_i) - deallocate(pct_cft_o) - deallocate(pct_nat_pft_i) - deallocate(pct_nat_pft_o) - if ( .not. presc_cover ) then - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - end if - - write (6,*) 'Successfully made PFTs' - write (6,*) - - -end subroutine mkpft - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkpft_parse_oride -! -! !INTERFACE: -subroutine mkpft_parse_oride( string ) -! -! !DESCRIPTION: -! Parse the string with pft fraction and index information on it, to override -! the file with this information rather than reading from a file. -! -! !USES: - use shr_string_mod, only: shr_string_betweenTags, shr_string_countChar -! !ARGUMENTS: - character(len=256), intent(IN) :: string ! String to parse with PFT fraction - ! and index data -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - integer :: rc ! error return code - integer :: num_elms ! number of elements - character(len=256) :: substring ! string between tags - character(len=*), parameter :: frc_start = "" - character(len=*), parameter :: frc_end = "" - character(len=*), parameter :: idx_start = "" - character(len=*), parameter :: idx_end = "" - character(len=*), parameter :: subname = 'mkpft_parse_oride' - !----------------------------------------------------------------------- - - ! NOTE(bja, 2015-02) pft_frc and pft_index can be reset multiple - ! times by calls to this function. If the number of elements being - ! set is different each time, then we are working with out of date - ! information, and the sums may not sum to 100%. - pft_frc = 0.0_r8 - pft_idx = -1 - - call shr_string_betweenTags( string, frc_start, frc_end, substring, rc ) - if ( rc /= 0 )then - write(6,*) subname//'Trouble finding pft_frac start end tags' - call abort() - return - end if - num_elms = shr_string_countChar( substring, ",", rc ) - read(substring,*) pft_frc(0:num_elms) - call shr_string_betweenTags( string, idx_start, idx_end, substring, rc ) - if ( rc /= 0 )then - write(6,*) subname//'Trouble finding pft_index start end tags' - call abort() - return - end if - if ( num_elms /= shr_string_countChar( substring, ",", rc ) )then - write(6,*) subname//'number of elements different between frc and idx fields' - call abort() - return - end if - read(substring,*) pft_idx(0:num_elms) -!----------------------------------------------------------------------- - -end subroutine mkpft_parse_oride - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkpft_check_oride -! -! !INTERFACE: -subroutine mkpft_check_oride( error_happened ) -! -! !DESCRIPTION: -! Check that the pft override values are valid -! !USES: - implicit none -! !ARGUMENTS: - logical, intent(out) :: error_happened ! Result, true if there was a problem -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - integer :: i, j ! indices - real(r8) :: sumpft ! Sum of pft_frc - real(r8), parameter :: hndrd = 100.0_r8 ! A hundred percent - character(len=32) :: subname = 'mkpftMod::mkpft_check_oride() ' -!----------------------------------------------------------------------- - - error_happened = .false. - sumpft = sum(pft_frc) - if ( sumpft == 0.0 )then - ! PFT fraction is NOT used - use_input_pft = .false. - else if ( abs(sumpft - hndrd) > 1.e-6 )then - write(6, '(a, a, f15.12)') trim(subname), 'Sum of PFT fraction is NOT equal to 100% =', sumpft - write(6,*) 'Set PFT fraction to : ', pft_frc(0:nzero) - write(6,*) 'With PFT index : ', pft_idx(0:nzero) - error_happened = .true. - call abort() - return - else - use_input_pft = .true. - nzero = numpft - do i = 0, numpft - if ( pft_frc(i) == 0.0_r8 )then - nzero = i-1 - exit - end if - end do - ! PFT fraction IS used, and sum is OK, now check details - do i = 0, nzero - if ( pft_frc(i) < 0.0_r8 .or. pft_frc(i) > hndrd )then - write(6,*) subname//'PFT fraction is out of range: pft_frc=', pft_frc(i) - error_happened = .true. - call abort() - return - else if ( pft_frc(i) > 0.0_r8 .and. pft_idx(i) == -1 )then - write(6,*) subname//'PFT fraction > zero, but index NOT set: pft_idx=', pft_idx(i) - error_happened = .true. - call abort() - return - end if - ! PFT index out of range - if ( pft_idx(i) < 0 .or. pft_idx(i) > numpft )then - write(6,*) subname//'PFT index is out of range: ', pft_idx(i) - error_happened = .true. - call abort() - return - end if - ! Make sure index values NOT used twice - do j = 0, i-1 - if ( pft_idx(i) == pft_idx(j) )then - write(6,*) subname//'Same PFT index is used twice: ', pft_idx(i) - error_happened = .true. - call abort() - return - end if - end do - end do - ! Make sure the rest of the fraction is zero and index are not set as well - do i = nzero+1, numpft - if ( pft_frc(i) /= 0.0_r8 .or. pft_idx(i) /= -1 )then - write(6,*) subname//'After PFT fraction is zeroed out, fraction is non zero, or index set' - error_happened = .true. - call abort() - return - end if - end do - end if - -end subroutine mkpft_check_oride - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkpftAtt -! -! !INTERFACE: -subroutine mkpftAtt( ncid, dynlanduse, xtype ) -! -! !DESCRIPTION: -! make PFT attributes on the output file -! - use mkncdio , only : check_ret, ncd_defvar, ncd_def_spatial_var - use fileutils , only : get_filename - use mkvarctl , only : mksrf_fvegtyp, mksrf_flai - use mkvarpar - -! !ARGUMENTS: - implicit none - include 'netcdf.inc' - integer, intent(in) :: ncid ! NetCDF file ID to write out to - logical, intent(in) :: dynlanduse ! if dynamic land-use file - integer, intent(in) :: xtype ! external type to output real data as -! -! !CALLED FROM: -! subroutine mkfile in module mkfileMod -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - integer :: pftsize ! size of lsmpft dimension - integer :: natpftsize ! size of natpft dimension - integer :: dimid ! input netCDF id's - character(len=256) :: str ! global attribute string - character(len=32) :: subname = 'mkpftAtt' - - ! Define dimensions - call check_ret(nf_def_dim (ncid, 'time' , nf_unlimited, dimid), subname) - - if (.not. dynlanduse) then - pftsize = numpft + 1 - call check_ret(nf_def_dim (ncid, 'lsmpft' , pftsize , dimid), subname) - end if - - natpftsize = num_natpft + 1 - call check_ret(nf_def_dim (ncid, 'natpft' , natpftsize , dimid), subname) - - ! zero-size dimensions can cause problems, so we only include the cft dimension if num_cft > 0 - ! Note that this implies that we can only include PCT_CFT on the dataset if num_cft > 0 - if (num_cft > 0) then - call check_ret(nf_def_dim (ncid, 'cft' , num_cft , dimid), subname) - end if - - ! Add global attributes - - if (.not. dynlanduse) then - str = get_filename(mksrf_flai) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Lai_raw_data_file_name', len_trim(str), trim(str)), subname) - end if - - if ( use_input_pft ) then - str = 'TRUE' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'pft_override', len_trim(str), trim(str)), subname) - else - str = get_filename(mksrf_fvegtyp) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Vegetation_type_raw_data_filename', len_trim(str), trim(str)), subname) - end if - - ! Define variables - - ! Coordinate variable for indices of natural PFTs - call ncd_defvar(ncid=ncid, varname='natpft', xtype=nf_int, & - dim1name='natpft', long_name='indices of natural PFTs', units='index') - - ! Coordinate variable for indices of CFTs - if (num_cft > 0) then - call ncd_defvar(ncid=ncid, varname='cft', xtype=nf_int, & - dim1name='cft', long_name='indices of CFTs', units='index') - end if - - call ncd_def_spatial_var(ncid=ncid, varname='LANDFRAC_PFT', xtype=nf_double, & - long_name='land fraction from pft dataset', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PFTDATA_MASK', xtype=nf_int, & - long_name='land mask from pft dataset, indicative of real/fake points', units='unitless') - - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='PCT_NATVEG', xtype=xtype, & - long_name='total percent natural vegetation landunit', units='unitless') - end if - - ! PCT_CROP - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CROP', xtype=xtype, & - long_name='total percent crop landunit', units='unitless') - else - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CROP', xtype=xtype, & - lev1name='time', & - long_name='total percent crop landunit', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CROP_MAX', xtype=xtype, & - long_name='maximum total percent crop landunit during time period', units='unitless') - end if - - ! PCT_NAT_PFT - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='PCT_NAT_PFT', xtype=xtype, & - lev1name='natpft', & - long_name='percent plant functional type on the natural veg landunit (% of landunit)', units='unitless') - else - call ncd_def_spatial_var(ncid=ncid, varname='PCT_NAT_PFT', xtype=xtype, & - lev1name='natpft', lev2name='time', & - long_name='percent plant functional type on the natural veg landunit (% of landunit)', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='PCT_NAT_PFT_MAX', xtype=xtype, & - lev1name='natpft', & - long_name='maximum percent plant functional type during time period (% of landunit)', units='unitless') - end if - - ! PCT_CFT - if (num_cft > 0) then - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CFT', xtype=xtype, & - lev1name='cft', & - long_name='percent crop functional type on the crop landunit (% of landunit)', units='unitless') - else - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CFT', xtype=xtype, & - lev1name='cft', lev2name='time', & - long_name='percent crop functional type on the crop landunit (% of landunit)', units='unitless') - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CFT_MAX', xtype=xtype, & - lev1name='cft', & - long_name='maximum percent crop functional type during time period (% of landunit)', units='unitless') - end if - end if - - ! LAI,SAI,HTOP,HBOT - if (.not. dynlanduse) then - call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_LAI', xtype=xtype, & - lev1name='lsmpft', lev2name='time', & - long_name='monthly leaf area index', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_SAI', xtype=xtype, & - lev1name='lsmpft', lev2name='time', & - long_name='monthly stem area index', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_HEIGHT_TOP', xtype=xtype, & - lev1name='lsmpft', lev2name='time', & - long_name='monthly height top', units='meters') - - call ncd_def_spatial_var(ncid=ncid, varname='MONTHLY_HEIGHT_BOT', xtype=xtype, & - lev1name='lsmpft', lev2name='time', & - long_name='monthly height bottom', units='meters') - end if - - ! OTHER - if (dynlanduse) then - call ncd_defvar(ncid=ncid, varname='YEAR', xtype=nf_int, & - dim1name='time', & - long_name='Year of PFT data', units='unitless') - call ncd_defvar(ncid=ncid, varname='time', xtype=nf_int, & - dim1name='time', & - long_name='year', units='unitless') - call ncd_defvar(ncid=ncid, varname='input_pftdata_filename', xtype=nf_char, & - dim1name='nchar', & - dim2name='time', & - long_name='Input filepath for PFT values for this year', units='unitless') - else - call ncd_defvar(ncid=ncid, varname='time', xtype=nf_int, & - dim1name='time', & - long_name='Calendar month', units='month') - end if - -end subroutine mkpftAtt - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: constructor -! -! !INTERFACE: -function constructor( ) result(this) -! -! !DESCRIPTION: -! Construct a new PFT override object -! -! !ARGUMENTS: - implicit none - type(pft_oride) :: this -!EOP - character(len=32) :: subname = 'mkpftMod::constructor() ' - - this%crop = -1.0_r8 - this%natveg = -1.0_r8 - if ( num_natpft < 0 )then - write(6,*) subname//'num_natpft is NOT set = ', num_natpft - call abort() - return - end if - if ( num_cft < 0 )then - write(6,*) subname//'num_cft is NOT set = ', num_cft - call abort() - return - end if - allocate( this%natpft(noveg:num_natpft) ) - allocate( this%cft(1:num_cft) ) - this%natpft(:) = -1.0_r8 - this%cft(:) = -1.0_r8 - call this%InitZeroOut() -end function constructor - - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: InitZeroOut -! -! !INTERFACE: -subroutine InitZeroOut( this ) -! -! !DESCRIPTION: -! Initialize a pft_oride object with vegetation that's zeroed out -! -! !ARGUMENTS: - implicit none - class(pft_oride), intent(inout) :: this -!EOP - this%crop = 0.0_r8 - this%natveg = 0.0_r8 - - this%natpft = 0.0_r8 - this%natpft(noveg) = 100.0_r8 - this%cft = 0.0_r8 - this%cft(1) = 100.0_r8 -end subroutine InitZeroOut - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: InitZeroOut -! -! !INTERFACE: -subroutine InitAllPFTIndex( this ) -! -! !DESCRIPTION: -! Initialize a pft_oride object with vegetation that's zeroed out -! -! !ARGUMENTS: - implicit none - class(pft_oride), intent(inout) :: this -!EOP - integer :: m, i ! Indices - real(r8) :: croptot ! Total of crop - real(r8) :: natvegtot ! Total of natural vegetation - character(len=32) :: subname = 'mkpftMod::coInitAllPFTIndex() ' - - croptot = 0.0_r8 - natvegtot = 0.0_r8 - this%natpft = 0.0_r8 - this%cft = 0.0_r8 - do m = noveg, nzero - i = pft_idx(m) - if ( (i < noveg) .or. (i > numpft) )then - write(6,*) subname//'PFT index is out of valid range' - call abort() - return - else if ( i <= num_natpft )then - this%natpft(i) = pft_frc(m) - natvegtot = natvegtot + pft_frc(m) - else - this%cft(i-num_natpft) = pft_frc(m) - croptot = croptot + pft_frc(m) - end if - end do - this%crop = croptot - this%natveg = natvegtot - ! Renormalize - if ( natvegtot > 0.0_r8 )then - this%natpft = 100.0_r8 * this%natpft / natvegtot - else - this%natpft(noveg) = 100.0_r8 - end if - if (croptot > 0.0_r8 )then - this%cft = 100.0_r8 * this%cft / croptot - else - this%cft(1) = 100.0_r8 - end if - -end subroutine InitAllPFTIndex - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: clean -! -! !INTERFACE: -subroutine Clean( this ) -! -! !DESCRIPTION: -! Clean up a PFT Oride object -! -! !ARGUMENTS: - implicit none - class(pft_oride), intent(inout) :: this -!EOP - this%crop = -1.0_r8 - this%natveg = -1.0_r8 - deallocate( this%natpft ) - deallocate( this%cft ) - -end subroutine Clean - -!----------------------------------------------------------------------- - -end module mkpftMod diff --git a/tools/mksurfdata_map/src/mkpftUtilsMod.F90 b/tools/mksurfdata_map/src/mkpftUtilsMod.F90 deleted file mode 100644 index 4a9ea12f97..0000000000 --- a/tools/mksurfdata_map/src/mkpftUtilsMod.F90 +++ /dev/null @@ -1,257 +0,0 @@ -module mkpftUtilsMod - - !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mkpftUtils - ! - ! !DESCRIPTION: - ! Lower-level utilities used in making PFT data. - ! - ! These are separated out from mkpftMod mainly as an aid to testing. - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! - !----------------------------------------------------------------------- - !!USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - - implicit none - private - - ! - ! !PUBLIC MEMBER FUNCTIONS: - ! - public :: convert_from_p2g ! Convert a p2g array into pct_pft_type objects - public :: adjust_total_veg_area ! Adjust the total vegetated area (natural veg & crop) to a new specified total - - ! - ! !PRIVATE MEMBER FUNCTIONS: - ! - - private :: get_default_natpft ! Get the default natural pft breakdown, for a 0-area natural veg. landunit - private :: get_default_cft ! Get the default cft breakdown, for a 0-area crop landunit - - interface convert_from_p2g - module procedure convert_from_p2g_default - module procedure convert_from_p2g_missing_crops - end interface convert_from_p2g - - !EOP - !=============================================================== -contains - !=============================================================== - - !----------------------------------------------------------------------- - subroutine convert_from_p2g_default(pct_p2g, pctnatpft, pctcft) - ! - ! !DESCRIPTION: - ! Given the % of each pft on the grid cell, create pct_pft_type objects that give % of - ! each pft on the landunit and % of each landunit on the grid cell. - ! - ! !USES: - use mkpctPftTypeMod , only : pct_pft_type - use mkpftConstantsMod, only : natpft_lb, natpft_ub, num_cft, cft_lb, cft_ub - ! - ! !ARGUMENTS: - real(r8), intent(in) :: pct_p2g(natpft_lb:) ! % of each pft on the grid cell (includes crops as well as natural veg types) - type(pct_pft_type), intent(out) :: pctnatpft ! natural PFT cover - type(pct_pft_type), intent(out) :: pctcft ! crop (CFT) COVER - ! - ! !LOCAL VARIABLES: - real(r8), allocatable :: default_natpft(:) ! default p2l for natural PFTs, for grid cells where the current size of the natural veg landunit is 0 - real(r8), allocatable :: default_cft(:) ! default p2l for CFTs, for grid cells where the current size of the crop landunit is 0 - - character(len=*), parameter :: subname = 'convert_from_p2g_default' - !----------------------------------------------------------------------- - - if (ubound(pct_p2g, 1) /= cft_ub) then - write(6,*) subname, ' ERROR: upper bound of pct_p2g should be cft_ub' - write(6,*) 'ubound(pct_p2g), cft_ub = ', ubound(pct_p2g), cft_ub - call abort() - end if - - allocate(default_natpft(natpft_lb:natpft_ub)) - default_natpft = get_default_natpft() - pctnatpft = pct_pft_type(pct_p2g(natpft_lb:natpft_ub), natpft_lb, default_natpft) - deallocate(default_natpft) - - if (num_cft > 0) then - allocate(default_cft(cft_lb:cft_ub)) - default_cft = get_default_cft() - pctcft = pct_pft_type(pct_p2g(cft_lb:cft_ub), cft_lb, default_cft) - deallocate(default_cft) - else - ! create an empty placeholder, with 0 area on the grid cell - pctcft = pct_pft_type() - end if - - end subroutine convert_from_p2g_default - - !----------------------------------------------------------------------- - subroutine convert_from_p2g_missing_crops(pct_p2g, pctcft_saved, pctnatpft, pctcft) - ! - ! !DESCRIPTION: - ! Given the % of each pft on the grid cell, create pct_pft_type objects that give % - ! of each pft on the landunit and % of each landunit on the grid cell. - ! - ! This version of the routine assumes that pct_p2g only includes the standard PFTs - - ! not prognostic crops. It takes the relative crop cover from pctcft_saved, and uses - ! the % cover of the generic c3 crop in pct_p2g to specify the total crop landunit - ! area. - ! - ! Typically, pct_p2g will have an upper bound of numstdpft; however, this is not - ! assumed. Any upper bound is fine as long as the upper bound is greater than - ! natpft_ub and includes c3cropindex. - ! - ! Assumptions: - ! - We are running with prognostic crops (i.e., NOT an empty crop landunit - although - ! it's fine for the crop landunit area to be 0%) - ! - In pct_p2g, the only non-zero areas should be: - ! - Areas of PFTs on the natural veg landunit - ! - The area of the generic c3 crop - ! - ! !USES: - use mkpctPftTypeMod , only : pct_pft_type - use mkpftConstantsMod , only : c3cropindex, natpft_lb, natpft_ub, num_cft - ! - ! !ARGUMENTS: - real(r8), intent(in) :: pct_p2g(natpft_lb:) ! % of each pft on the grid cell (includes crops as well as natural veg types) - type(pct_pft_type), intent(in) :: pctcft_saved ! saved crop cover information, used to specify the relative cover of each crop - type(pct_pft_type), intent(out) :: pctnatpft ! natural PFT cover - type(pct_pft_type), intent(out) :: pctcft ! crop (CFT) COVER - ! - ! !LOCAL VARIABLES: - real(r8), allocatable :: default_natpft(:) ! default p2l for natural PFTs, for grid cells where the current size of the natural veg landunit is 0 - integer :: pft_index - real(r8) :: crop_area ! area of the crop landunit on the grid cell - - character(len=*), parameter :: subname = 'convert_from_p2g_missing_crops' - !----------------------------------------------------------------------- - - ! Error checking on inputs - - if (num_cft == 0) then - write(6,*) subname, ' ERROR: this routine should only be called when running with prognostic crops' - write(6,*) '(i.e., with num_cft > 0)' - call abort() - end if - - do pft_index = natpft_ub + 1, ubound(pct_p2g, 1) - if (pft_index /= c3cropindex .and. pct_p2g(pft_index) > 0._r8) then - write(6,*) subname, ' ERROR: in pct_p2g, the only non-zero areas should be:' - write(6,*) ' - areas of PFTs on the natural veg landunit' - write(6,*) ' - the area of the generic c3 crop' - write(6,*) '(we do not currently handle the case where the transient input dataset' - write(6,*) 'has non-zero areas for both pft 15 and pft 16)' - write(6,*) 'pft_index, area = ', pft_index, pct_p2g(pft_index) - call abort() - end if - end do - - ! Done error checking on inputs - - allocate(default_natpft(natpft_lb:natpft_ub)) - default_natpft = get_default_natpft() - pctnatpft = pct_pft_type(pct_p2g(natpft_lb:natpft_ub), natpft_lb, default_natpft) - deallocate(default_natpft) - - pctcft = pctcft_saved - crop_area = pct_p2g(c3cropindex) - call pctcft%set_pct_l2g(crop_area) - - end subroutine convert_from_p2g_missing_crops - - !----------------------------------------------------------------------- - function get_default_natpft() result(default_natpft) - ! - ! !DESCRIPTION: - ! Get the default natural pft breakdown, for a 0-area natural veg. landunit. - ! - ! Currently we use the same default everywhere. In the future, we could change this - ! to compute default_natpft based on some function of location (e.g., different - ! values for high latitudes than low latitudes, etc.). - ! - ! !USES: - use mkpftConstantsMod, only : baregroundindex, natpft_lb, natpft_ub - ! - ! !ARGUMENTS: - real(r8), allocatable :: default_natpft(:) ! function result - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'get_default_natpft' - !----------------------------------------------------------------------- - - allocate(default_natpft(natpft_lb:natpft_ub)) - default_natpft(:) = 0._r8 - default_natpft(baregroundindex) = 100._r8 - - end function get_default_natpft - - !----------------------------------------------------------------------- - function get_default_cft() result(default_cft) - ! - ! !DESCRIPTION: - ! Get the default cft breakdown, for a 0-area crop landunit. - ! - ! !USES: - use mkpftConstantsMod, only : c3cropindex, cft_lb, cft_ub - ! - ! !ARGUMENTS: - real(r8), allocatable :: default_cft(:) ! function result - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'get_default_cft' - !----------------------------------------------------------------------- - - allocate(default_cft(cft_lb:cft_ub)) - default_cft(:) = 0._r8 - default_cft(c3cropindex) = 100._r8 - - end function get_default_cft - - - !----------------------------------------------------------------------- - subroutine adjust_total_veg_area(new_total_pct, pctnatpft, pctcft) - ! - ! !DESCRIPTION: - ! Adjust the total vegetated area on the grid cell (natural veg & crop) to a new - ! specified total. - ! - ! If the old areas are 0%, then all the new area goes into pctnatpft. - ! - ! !USES: - use mkpctPftTypeMod, only : pct_pft_type - ! - ! !ARGUMENTS: - real(r8), intent(in) :: new_total_pct ! new total % of natural veg + crop landunits - class(pct_pft_type), intent(inout) :: pctnatpft ! natural veg cover information - class(pct_pft_type), intent(inout) :: pctcft ! crop cover information - ! - ! !LOCAL VARIABLES: - real(r8) :: natpft_l2g ! grid cell % cover of nat. veg. - real(r8) :: cft_l2g ! grid cell % cover of crop - real(r8) :: old_total ! old total % cover of natural veg + crop landunits - - character(len=*), parameter :: subname = 'adjust_total_veg_area' - !----------------------------------------------------------------------- - - natpft_l2g = pctnatpft%get_pct_l2g() - cft_l2g = pctcft%get_pct_l2g() - old_total = natpft_l2g + cft_l2g - if (old_total > 0._r8) then - call pctnatpft%set_pct_l2g(natpft_l2g * new_total_pct / old_total) - call pctcft%set_pct_l2g(cft_l2g * new_total_pct / old_total) - else - call pctnatpft%set_pct_l2g(new_total_pct) - end if - - end subroutine adjust_total_veg_area - - -end module mkpftUtilsMod - - diff --git a/tools/mksurfdata_map/src/mksoilMod.F90 b/tools/mksurfdata_map/src/mksoilMod.F90 deleted file mode 100644 index d7cad23e0d..0000000000 --- a/tools/mksurfdata_map/src/mksoilMod.F90 +++ /dev/null @@ -1,1237 +0,0 @@ -module mksoilMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mksoilMod -! -! !DESCRIPTION: -! Make soil data (texture, color and organic) -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -!----------------------------------------------------------------------- -!!USES: - use shr_kind_mod, only : r8 => shr_kind_r8, r4=>shr_kind_r4 - use shr_sys_mod , only : shr_sys_flush - use mkdomainMod , only : domain_checksame - use mksoilUtilsMod, only : mkrank, dominant_soil_color - implicit none - - SAVE - private ! By default make data private -! -! !PUBLIC MEMBER FUNCTIONS: -! - public mksoilInit ! Soil Initialization - - public mksoilAtt ! Add attributes to output file - - public mksoiltex ! Set soil texture - public mkorganic ! Set organic soil - public mksoilcol ! Set soil color - public mkfmax ! Make percent fmax -! -! !PUBLIC DATA MEMBERS: -! - real(r8), public, parameter :: unset = -999.99_r8 ! Flag to signify soil texture override not set - real(r8), public :: soil_sand = unset ! soil texture sand % to override with - real(r8), public :: soil_clay = unset ! soil texture clay % to override with - real(r8), public :: soil_fmax = unset ! soil max saturation frac to override with - integer , parameter :: unsetcol = -999 ! flag to indicate soil color NOT set - integer , public :: soil_color= unsetcol ! soil color to override with -! -! !PRIVATE DATA MEMBERS: -! -! !PRIVATE MEMBER FUNCTIONS: - private :: mksoiltexInit ! Soil texture Initialization - private :: mksoilcolInit ! Soil color Initialization - private :: mksoilfmaxInit ! Soil fmax Initialization - -!EOP -!=============================================================== -contains -!=============================================================== - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoilInit -! -! !INTERFACE: -subroutine mksoilInit( ) -! -! !DESCRIPTION: -! Initialize the different soil types -! !USES: -! -! !ARGUMENTS: - implicit none -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - character(len=32) :: subname = 'mksoilInit' -!----------------------------------------------------------------------- - call mksoiltexInit() - call mksoilcolInit() - call mksoilfmaxInit() - -end subroutine mksoilInit - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoiltexInit -! -! !INTERFACE: -subroutine mksoiltexInit( ) -! -! !DESCRIPTION: -! Initialize of make soil texture -! !USES: -! -! !ARGUMENTS: - implicit none -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - real(r8) :: sumtex - character(len=32) :: subname = 'mksoiltexInit' -!----------------------------------------------------------------------- - if ( soil_clay /= unset )then - write(6,*) 'Replace soil clay % for all points with: ', soil_clay - if ( soil_sand == unset )then - write (6,*) subname//':error: soil_clay set, but NOT soil_sand' - call abort() - end if - end if - if ( soil_sand /= unset )then - write(6,*) 'Replace soil sand % for all points with: ', soil_sand - if ( soil_clay == unset )then - write (6,*) subname//':error: soil_sand set, but NOT soil_clay' - call abort() - end if - sumtex = soil_sand + soil_clay - if ( sumtex < 0.0_r8 .or. sumtex > 100.0_r8 )then - write (6,*) subname//':error: soil_sand and soil_clay out of bounds: sand, clay = ', & - soil_sand, soil_clay - call abort() - end if - end if - -end subroutine mksoiltexInit - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoiltex -! -! !INTERFACE: -subroutine mksoiltex(ldomain, mapfname, datfname, ndiag, sand_o, clay_o) -! -! !DESCRIPTION: -! make %sand and %clay from IGBP soil data, which includes -! igbp soil 'mapunits' and their corresponding textures -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: sand_o(:,:) ! % sand (output grid) - real(r8) , intent(out):: clay_o(:,:) ! % clay (output grid) -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - character(len=38) :: typ ! soil texture based on ... - integer :: nlay ! number of soil layers - integer :: mapunitmax ! max value of igbp soil mapunits - integer :: mapunittemp ! temporary igbp soil mapunit - integer :: maxovr - integer , allocatable :: novr(:) - integer , allocatable :: kmap(:,:) - real(r8), allocatable :: kwgt(:,:) - integer , allocatable :: kmax(:) - real(r8), allocatable :: wst(:) - real(r8), allocatable :: sand_i(:,:) ! input grid: percent sand - real(r8), allocatable :: clay_i(:,:) ! input grid: percent clay - real(r8), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer, parameter :: num=2 ! set soil mapunit number - integer :: wsti(num) ! index to 1st and 2nd largest wst - integer, parameter :: nlsm=4 ! number of soil textures - character(len=38) :: soil(0:nlsm) ! name of each soil texture - real(r8) :: gast_i(0:nlsm) ! global area, by texture type - real(r8) :: gast_o(0:nlsm) ! global area, by texture type - real(r8) :: wt ! map overlap weight - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - integer :: l,k,n,m,ni,no,ns_i,ns_o ! indices - integer :: k1,k2 ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - integer :: miss = 99999 ! missing data indicator - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - logical :: found ! temporary - integer :: kmap_max ! maximum overlap weights - integer, parameter :: kmap_max_min = 90 ! kmap_max mininum value - integer, parameter :: km_mx_ns_prod = 160000 ! product of kmap_max*ns_o to keep constant - character(len=32) :: subname = 'mksoiltex' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make %sand and %clay .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Define the model surface types: 0 to nlsm - ! ----------------------------------------------------------------- - - soil(0) = 'no soil: ocean, glacier, lake, no data' - soil(1) = 'clays ' - soil(2) = 'sands ' - soil(3) = 'loams ' - soil(4) = 'silts ' - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - ns_o = ldomain%ns - - write (6,*) 'Open soil texture file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_dimid (ncid, 'number_of_layers', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, nlay), subname) - - call check_ret(nf_inq_dimid (ncid, 'max_value_mapunit', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, mapunitmax), subname) - - allocate(sand_i(mapunitmax,nlay), & - clay_i(mapunitmax,nlay), & - mapunit_i(ns_i), stat=ier) - if (ier/=0) call abort() - - call check_ret(nf_inq_varid (ncid, 'MAPUNITS', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, mapunit_i), subname) - - call check_ret(nf_inq_varid (ncid, 'PCT_SAND', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, sand_i), subname) - - call check_ret(nf_inq_varid (ncid, 'PCT_CLAY', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, clay_i), subname) - - call check_ret(nf_close(ncid), subname) - - ! Compute local fields _o - if (soil_sand==unset .and. soil_clay==unset) then - - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! kmap_max are the maximum number of mapunits that will consider on - ! any output gridcell - this is set currently above and can be changed - ! kmap(:) are the mapunit values on the input grid - ! kwgt(:) are the weights on the input grid - - allocate(novr(ns_o)) - novr(:) = 0 - do n = 1,tgridmap%ns - ni = tgridmap%src_indx(n) - if (tdomain%mask(ni) > 0) then - no = tgridmap%dst_indx(n) - novr(no) = novr(no) + 1 - end if - end do - maxovr = maxval(novr(:)) - kmap_max = min(maxovr,max(kmap_max_min,km_mx_ns_prod/ns_o)) - deallocate(novr) - - write(6,*)'kmap_max= ',kmap_max,' maxovr= ',maxovr,' ns_o= ',ns_o,' size= ',(kmap_max+1)*ns_o - - allocate(kmap(0:kmap_max,ns_o), stat=ier) - if (ier/=0) call abort() - allocate(kwgt(0:kmap_max,ns_o), stat=ier) - if (ier/=0) call abort() - allocate(kmax(ns_o), stat=ier) - if (ier/=0) call abort() - allocate(wst(0:kmap_max), stat=ier) - if (ier/=0) call abort() - - kwgt(:,:) = 0. - kmap(:,:) = 0 - kmax(:) = 0 - - do n = 1,tgridmap%ns - ni = tgridmap%src_indx(n) - no = tgridmap%dst_indx(n) - wt = tgridmap%wovr(n) * tdomain%mask(ni) - if (wt > 0._r8) then - k = mapunit_i(ni) - found = .false. - do l = 0,kmax(no) - if (k == kmap(l,no)) then - kwgt(l,no) = kwgt(l,no) + wt - found = .true. - exit - end if - end do - if (.not. found) then - kmax(no) = kmax(no) + 1 - if (kmax(no) > kmap_max) then - write(6,*)'kmax is > kmap_max= ',kmax(no), 'kmap_max = ', & - kmap_max,' for no = ',no - write(6,*)'reset kmap_max in mksoilMod to a greater value' - call abort() - end if - kmap(kmax(no),no) = k - kwgt(kmax(no),no) = wt - end if - end if - enddo - - end if - - do no = 1,ns_o - - if (soil_sand==unset .and. soil_clay==unset) then - wst(:) = 0. - wst(0:kmax(no)) = kwgt(0:kmax(no),no) - - ! Rank non-zero weights by soil mapunit. - ! k1 is the most extensive mapunit. - ! k2 is the second most extensive mapunit. - - if (maxval(wst(:)) > 0) then - call mkrank (kmax(no)+1, wst(0:kmax(no)), miss, wsti, num) - k1 = kmap(wsti(1),no) - if (wsti(2) == miss) then - k2 = miss - else - k2 = kmap(wsti(2),no) - end if - else - k1 = 0 - k2 = 0 - end if - - end if - - ! Set soil texture as follows: - ! a. Use dominant igbp soil mapunit based on area of overlap unless - ! 'no data' is dominant - ! b. In this case use second most dominant mapunit if it has data - ! c. If this has no data or if there isn't a second most dominant - ! mapunit, use loam for soil texture - - if (soil_sand/=unset .and. soil_clay/=unset) then !---soil texture is input - do l = 1, nlay - sand_o(no,l) = soil_sand - clay_o(no,l) = soil_clay - end do - else if (k1 /= 0) then !---not 'no data' - do l = 1, nlay - sand_o(no,l) = sand_i(k1,l) - clay_o(no,l) = clay_i(k1,l) - end do - else !---if (k1 == 0) then - if (k2 == 0 .or. k2 == miss) then !---no data - do l = 1, nlay - sand_o(no,l) = 43. !---use loam - clay_o(no,l) = 18. - end do - else !---if (k2 /= 0 and /= miss) - do l = 1, nlay - sand_o(no,l) = sand_i(k2,l) - clay_o(no,l) = clay_i(k2,l) - end do - end if !---end of k2 if-block - end if !---end of k1 if-block - - enddo - - if (soil_sand==unset .and. soil_clay==unset) then - - ! Global sum of output field - - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global area of each soil type on input and output grids - ! ----------------------------------------------------------------- - - ! input grid: global areas by texture class - - gast_i(:) = 0. - do l = 1, nlay - do ni = 1,ns_i - mapunittemp = nint(mapunit_i(ni)) - if (mapunittemp==0) then - typ = 'no soil: ocean, glacier, lake, no data' - else if (clay_i(mapunittemp,l) >= 40.) then - typ = 'clays' - else if (sand_i(mapunittemp,l) >= 50.) then - typ = 'sands' - else if (clay_i(mapunittemp,l)+sand_i(mapunittemp,l) < 50.) then - if (tdomain%mask(ni) /= 0.) then - typ = 'silts' - else !if (tdomain%mask(ni) == 0.) then no data - typ = 'no soil: ocean, glacier, lake, no data' - end if - else - typ = 'loams' - end if - do m = 0, nlsm - if (typ == soil(m)) go to 101 - end do - write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunittemp,l), & - ' clay = ',clay_i(mapunittemp,l), & - ' not assigned to soil type for input grid lon,lat,layer = ',ni,l - call abort() -101 continue - gast_i(m) = gast_i(m) + tgridmap%area_src(ni)*tdomain%mask(ni)*re**2 - end do - end do - - ! output grid: global areas by texture class - - gast_o(:) = 0. - do l = 1, nlay - do no = 1,ns_o - if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then - typ = 'no soil: ocean, glacier, lake, no data' - else if (clay_o(no,l) >= 40.) then - typ = 'clays' - else if (sand_o(no,l) >= 50.) then - typ = 'sands' - else if (clay_o(no,l)+sand_o(no,l) < 50.) then - typ = 'silts' - else - typ = 'loams' - end if - do m = 0, nlsm - if (typ == soil(m)) go to 102 - end do - write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & - ' clay = ',clay_o(no,l), & - ' not assigned to soil type for output grid lon,lat,layer = ',no,l - call abort() -102 continue - gast_o(m) = gast_o(m) + tgridmap%area_dst(no)*frac_dst(no)*re**2 - end do - end do - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',l=1,70) - write (ndiag,*) 'Soil Texture Output' - write (ndiag,'(1x,70a1)') ('=',l=1,70) - write (ndiag,*) - - write (ndiag,*) 'The following table of soil texture classes is for comparison only.' - write (ndiag,*) 'The actual data is continuous %sand, %silt and %clay not textural classes' - write (ndiag,*) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',l=1,70) - write (ndiag,1001) -1001 format (1x,'soil texture class',17x,' input grid area output grid area',/ & - 1x,33x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',l=1,70) - write (ndiag,*) - - do l = 0, nlsm - write (ndiag,1002) soil(l),gast_i(l)*1.e-6,gast_o(l)*1.e-6 -1002 format (1x,a38,f16.3,f17.3) - end do - - end if - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - if (soil_sand==unset .and. soil_clay==unset) then - call gridmap_clean(tgridmap) - deallocate (kmap, kwgt, kmax, wst) - deallocate (sand_i,clay_i,mapunit_i) - deallocate (frac_dst) - deallocate (mask_r8) - end if - - - write (6,*) 'Successfully made %sand and %clay' - write (6,*) - call shr_sys_flush(6) - -end subroutine mksoiltex - -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoilcolInit -! -! !INTERFACE: -subroutine mksoilcolInit( ) -! -! !DESCRIPTION: -! Initialize of make soil color -! !USES: -! -! !ARGUMENTS: - implicit none -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - real(r8) :: sumtex - character(len=32) :: subname = 'mksoilcolInit' -!----------------------------------------------------------------------- - - ! Error check soil_color if it is set - if ( soil_color /= unsetcol )then - if ( soil_color < 0 .or. soil_color > 20 )then - write(6,*)'soil_color is out of range = ', soil_color - call abort() - end if - write(6,*) 'Replace soil color for all points with: ', soil_color - end if -end subroutine mksoilcolInit - - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoilcol -! -! !INTERFACE: -subroutine mksoilcol(ldomain, mapfname, datfname, ndiag, & - soil_color_o, nsoicol) -! -! !DESCRIPTION: -! make %sand and %clay from IGBP soil data, which includes -! igbp soil 'mapunits' and their corresponding textures -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - integer , intent(out):: soil_color_o(:) ! soil color classes - integer , intent(out):: nsoicol ! number of soil colors -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: gast_i(:) ! global area, by surface type - real(r8), allocatable :: gast_o(:) ! global area, by surface type - integer , allocatable :: soil_color_i(:) ! input grid: BATS soil color - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - character(len=35), allocatable :: col(:) ! name of each color - integer :: k,l,m,ni,no,ns_i,ns_o ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mksoilcol' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make soil color classes .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ns_o = ldomain%ns - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - allocate(soil_color_i(ns_i), stat=ier) - if (ier/=0) call abort() - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() - - write (6,*) 'Open soil color file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'SOIL_COLOR', varid), subname) - call check_ret(nf_get_var_int (ncid, varid, soil_color_i), subname) - call check_ret(nf_close(ncid), subname) - - nsoicol = maxval(soil_color_i) - write(6,*)'nsoicol = ',nsoicol - - allocate(gast_i(0:nsoicol),gast_o(0:nsoicol),col(0:nsoicol)) - - ! ----------------------------------------------------------------- - ! Define the model color classes: 0 to nsoicol - ! ----------------------------------------------------------------- - - if (nsoicol == 20) then - col(0) = 'no soil ' - col(1) = 'class 1: light ' - col(2) = 'class 2: ' - col(3) = 'class 3: ' - col(4) = 'class 4: ' - col(5) = 'class 5: ' - col(6) = 'class 6: ' - col(7) = 'class 7: ' - col(8) = 'class 8: ' - col(9) = 'class 9: ' - col(10) = 'class 10: ' - col(11) = 'class 11: ' - col(12) = 'class 12: ' - col(13) = 'class 13: ' - col(14) = 'class 14: ' - col(15) = 'class 15: ' - col(16) = 'class 16: ' - col(17) = 'class 17: ' - col(18) = 'class 18: ' - col(19) = 'class 19: ' - col(20) = 'class 20: dark ' - else if (nsoicol == 8) then - col(0) = 'no soil ' - col(1) = 'class 1: light ' - col(2) = 'class 2: ' - col(3) = 'class 3: ' - col(4) = 'class 4: ' - col(5) = 'class 5: ' - col(6) = 'class 6: ' - col(7) = 'class 7: ' - col(8) = 'class 8: dark ' - else - write(6,*)'nsoicol value of ',nsoicol,' is not currently supported' - call abort() - end if - - ! Error check soil_color if it is set - if ( soil_color /= unsetcol )then - if ( soil_color > nsoicol )then - write(6,*)'soil_color is out of range = ', soil_color - call abort() - end if - - do no = 1,ns_o - soil_color_o(no) = soil_color - end do - - else - - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine dominant soil color for each output cell - - call dominant_soil_color( & - tgridmap = tgridmap, & - mask_i = tdomain%mask, & - soil_color_i = soil_color_i, & - nsoicol = nsoicol, & - soil_color_o = soil_color_o) - - ! Global sum of output field - - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global area of each soil color on input and output grids - ! ----------------------------------------------------------------- - - gast_i(:) = 0. - do ni = 1,ns_i - k = soil_color_i(ni) - gast_i(k) = gast_i(k) + tgridmap%area_src(ni)*tdomain%mask(ni)*re**2 - end do - - gast_o(:) = 0. - do no = 1,ns_o - k = soil_color_o(no) - gast_o(k) = gast_o(k) + tgridmap%area_dst(no)*frac_dst(no)*re**2 - end do - - ! area comparison - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Soil Color Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,1001) -1001 format (1x,'soil color type',20x,' input grid area output grid area',/ & - 1x,33x,' 10**6 km**2',' 10**6 km**2') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - - do k = 0, nsoicol - write (ndiag,1002) col(k),gast_i(k)*1.e-6,gast_o(k)*1.e-6 -1002 format (1x,a35,f16.3,f17.3) - end do - - end if - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - if ( soil_color == unsetcol )then - call gridmap_clean(tgridmap) - end if - deallocate (soil_color_i,gast_i,gast_o,col, frac_dst, mask_r8) - - write (6,*) 'Successfully made soil color classes' - write (6,*) - call shr_sys_flush(6) - -end subroutine mksoilcol - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkorganic -! -! !INTERFACE: -subroutine mkorganic(ldomain, mapfname, datfname, ndiag, organic_o) -! -! !DESCRIPTION: -! make organic matter dataset -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: organic_o(:,:) ! output grid: -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! -! Author: David Lawrence -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: organic_i(:,:) ! input grid: total column organic matter - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: gomlev_i ! input grid: global organic on lev - real(r8) :: garea_i ! input grid: global area - real(r8) :: gomlev_o ! output grid: global organic on lev - real(r8) :: garea_o ! output grid: global area - integer :: k,n,m,ni,no,ns_i ! indices - integer :: lev ! level index - integer :: nlay ! number of soil layers - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mkorganic' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make organic matter dataset .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - - write (6,*) 'Open soil organic file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - call check_ret(nf_inq_dimid (ncid, 'number_of_layers', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, nlay), subname) - - allocate(organic_i(ns_i,nlay),stat=ier) - if (ier/=0) call abort() - allocate(frac_dst(ldomain%ns),stat=ier) - if (ier/=0) call abort() - - if (nlay /= nlevsoi) then - write(6,*)'nlay, nlevsoi= ',nlay,nlevsoi,' do not match' - call abort() - end if - - call check_ret(nf_inq_varid (ncid, 'ORGANIC', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, organic_i), subname) - - call check_ret(nf_close(ncid), subname) - - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. - - call gridmap_mapread(tgridmap, mapfname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - do lev = 1,nlay - call gridmap_areaave_srcmask(tgridmap, organic_i(:,lev), organic_o(:,lev), nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - end do - - do lev = 1,nlevsoi - - ! Check for conservation - - do no = 1,ldomain%ns - if ((organic_o(no,lev)) > 130.000001_r8) then - write (6,*) 'MKORGANIC error: organic = ',organic_o(no,lev), & - ' greater than 130.000001 for column, row = ',no - call shr_sys_flush(6) - call abort() - end if - enddo - -! ! Diagnostic output - - ! TODO: there is nothing being written out here currently - all zeroes - ! So for now these are commented out -!!$ write (ndiag,*) -!!$ write (ndiag,'(1x,70a1)') ('.',k=1,70) -!!$ write (ndiag,2001) -!!$2001 format (1x,'surface type input grid area output grid area'/ & -!!$ 1x,' 10**6 km**2 10**6 km**2 ') -!!$ write (ndiag,'(1x,70a1)') ('.',k=1,70) -!!$ write (ndiag,*) -!!$ write (ndiag,2002) gomlev_i*1.e-06,gomlev_o*1.e-06 -!!$ write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 -!!$2002 format (1x,'organic ',f14.3,f17.3) -!!$2004 format (1x,'all surface ',f14.3,f17.3) -!!$ - call shr_sys_flush(ndiag) - - write (6,*) 'Successfully made organic matter, level = ', lev - call shr_sys_flush(6) - - end do ! lev - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (organic_i) - deallocate (frac_dst) - - write (6,*) 'Successfully made organic matter' - call shr_sys_flush(6) - write(6,*) - -end subroutine mkorganic - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoilfmaxInit -! -! !INTERFACE: -subroutine mksoilfmaxInit( ) -! -! !DESCRIPTION: -! Initialize of make soil fmax -! !USES: -! -! !ARGUMENTS: - implicit none -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - real(r8) :: sumtex - character(len=32) :: subname = 'mksoilfmaxInit' -!----------------------------------------------------------------------- - - ! Error check soil_fmax if it is set - if ( soil_fmax /= unset )then - if ( soil_fmax < 0.0 .or. soil_fmax > 1.0 )then - write(6,*)'soil_fmax is out of range = ', soil_fmax - call abort() - end if - write(6,*) 'Replace soil fmax for all points with: ', soil_fmax - end if - -end subroutine mksoilfmaxInit - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkfmax -! -! !INTERFACE: -subroutine mkfmax(ldomain, mapfname, datfname, ndiag, fmax_o) -! -! !DESCRIPTION: -! make percent fmax -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: fmax_o(:) ! output grid: %fmax -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Revised: Nan Rosenbloom - used mkglacier.F90 as template. -! Original Author: Mariana Vertenstein -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: fmax_i(:) ! input grid: percent fmax - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - real(r8) :: gfmax_i ! input grid: global fmax - real(r8) :: garea_i ! input grid: global area - real(r8) :: gfmax_o ! output grid: global fmax - real(r8) :: garea_o ! output grid: global area - integer :: k,n,m,ni,no,ns_i,ns_o ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mkfmax' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make %fmax .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - ns_o = ldomain%ns - allocate(fmax_i(ns_i), stat=ier) - if (ier/=0) call abort() - allocate(frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() - - write (6,*) 'Open soil fmax file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'FMAX', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, fmax_i), subname) - call check_ret(nf_close(ncid), subname) - - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. - - call gridmap_mapread(tgridmap, mapfname ) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine fmax_o on output grid - - ! In points with no data, use globalAvg - ! (WJS (3-11-13): use real(.365783,r8) rather than .365783_r8 to maintain bfb results - ! with old code) - call gridmap_areaave_srcmask(tgridmap, fmax_i, fmax_o, nodata=real(.365783,r8), mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check for conservation - - do no = 1, ns_o - if ((fmax_o(no)) > 1.000001_r8) then - write (6,*) 'MKFMAX error: fmax = ',fmax_o(no), & - ' greater than 1.000001 for column, row = ',no - call shr_sys_flush(6) - call abort() - end if - enddo - - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - - gfmax_i = 0. - garea_i = 0. - do ni = 1,ns_i - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - gfmax_i = gfmax_i + fmax_i(ni)*(tgridmap%area_src(ni)/100.)* & - tdomain%mask(ni)*re**2 - end do - - gfmax_o = 0. - garea_o = 0. - do no = 1,ns_o - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - gfmax_o = gfmax_o + fmax_o(no)*(tgridmap%area_dst(no)/100.) * & - frac_dst(no)*re**2 - if ((frac_dst(no) < 0.0) .or. (frac_dst(no) > 1.0001)) then - write(6,*) "ERROR:: frac_dst out of range: ", frac_dst(no),no - call abort() - end if - end do - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - write (ndiag,*) 'Maximum Fractional Saturated Area Output' - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) -2001 format (1x,'surface type input grid area output grid area'/ & - 1x,' 10**6 km**2 10**6 km**2 ') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2002) gfmax_i*1.e-06,gfmax_o*1.e-06 - write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 -2002 format (1x,'fmax ',f14.3,f17.3) -2004 format (1x,'all surface ',f14.3,f17.3) - - write (6,*) 'Successfully made %fmax' - write (6,*) - call shr_sys_flush(6) - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (fmax_i) - deallocate (frac_dst) - deallocate (mask_r8) - -end subroutine mkfmax - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoilAtt -! -! !INTERFACE: -subroutine mksoilAtt( ncid, dynlanduse, xtype ) -! -! !DESCRIPTION: -! add atttributes to output file regarding the soil module -! -! !USES: - use fileutils , only : get_filename - use mkncdio , only : check_ret, ncd_defvar, ncd_def_spatial_var - use mkvarpar - use mkvarctl - -! !ARGUMENTS: - implicit none - include 'netcdf.inc' - integer, intent(in) :: ncid ! NetCDF file ID to write out to - logical, intent(in) :: dynlanduse ! if dynamic land-use file - integer, intent(in) :: xtype ! external type to output real data as -! -! !CALLED FROM: -! subroutine mkfile in module mkfileMod -! -! !REVISION HISTORY: -! Original Author: Erik Kluzek -! -! -! !LOCAL VARIABLES: -!EOP - integer :: dimid ! temporary - character(len=256) :: str ! global attribute string - character(len=32) :: subname = 'mksoilAtt' -!----------------------------------------------------------------------- - - if (.not. dynlanduse) then - - ! Define dimensions unique to soil - - call check_ret(nf_def_dim (ncid, 'nlevsoi', & - nlevsoi , dimid), subname) - - ! Add global attributes to file - - if ( soil_clay /= unset .and. soil_sand /= unset )then - str = 'TRUE' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'soil_clay_override', len_trim(str), trim(str)), subname) - str = 'TRUE' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'soil_sand_override', len_trim(str), trim(str)), subname) - else - str = get_filename(mksrf_fsoitex) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Soil_texture_raw_data_file_name', len_trim(str), trim(str)), subname) - end if - if ( soil_color /= unsetcol )then - str = 'TRUE' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'soil_color_override', len_trim(str), trim(str)), subname) - else - str = get_filename(mksrf_fsoicol) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Soil_color_raw_data_file_name', len_trim(str), trim(str)), subname) - end if - if ( soil_fmax /= unset )then - str = 'TRUE' - call check_ret(nf_put_att_text (ncid, NF_GLOBAL, & - 'soil_fmax_override', len_trim(str), trim(str)), subname) - else - str = get_filename(mksrf_fmax) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Fmax_raw_data_file_name', len_trim(str), trim(str)), subname) - end if - str = get_filename(mksrf_forganic) - call check_ret(nf_put_att_text(ncid, NF_GLOBAL, & - 'Organic_matter_raw_data_file_name', len_trim(str), trim(str)), subname) - - ! Define variables - - call ncd_defvar(ncid=ncid, varname='mxsoil_color', xtype=nf_int, & - long_name='maximum numbers of soil colors', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='SOIL_COLOR', xtype=nf_int, & - long_name='soil color', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_SAND', xtype=xtype, & - lev1name='nlevsoi', & - long_name='percent sand', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='PCT_CLAY', xtype=xtype, & - lev1name='nlevsoi', & - long_name='percent clay', units='unitless') - - call ncd_def_spatial_var(ncid=ncid, varname='ORGANIC', xtype=xtype, & - lev1name='nlevsoi', & - long_name='organic matter density at soil levels', & - units='kg/m3 (assumed carbon content 0.58 gC per gOM)') - - call ncd_def_spatial_var(ncid=ncid, varname='FMAX', xtype=xtype, & - long_name='maximum fractional saturated area', units='unitless') - - end if - -end subroutine mksoilAtt - -!----------------------------------------------------------------------- - -end module mksoilMod diff --git a/tools/mksurfdata_map/src/mksoilUtilsMod.F90 b/tools/mksurfdata_map/src/mksoilUtilsMod.F90 deleted file mode 100644 index 122cfd45d5..0000000000 --- a/tools/mksurfdata_map/src/mksoilUtilsMod.F90 +++ /dev/null @@ -1,224 +0,0 @@ -module mksoilUtilsMod - - !----------------------------------------------------------------------- - !BOP - ! - ! !MODULE: mksoilUtils - ! - ! !DESCRIPTION: - ! Lower-level utilities used in making soil data. - ! - ! These are separated out from mksoilMod mainly as an aid to testing. - ! - ! !REVISION HISTORY: - ! Author: Bill Sacks - ! - !----------------------------------------------------------------------- - !!USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkgridmapMod, only : gridmap_type - - implicit none - private - - ! - ! !PUBLIC MEMBER FUNCTIONS: - ! - public :: dominant_soil_color - public :: mkrank - - ! - ! !PRIVATE MEMBER FUNCTIONS: - ! - - !EOP - !=============================================================== -contains - !=============================================================== - - !----------------------------------------------------------------------- - subroutine dominant_soil_color(tgridmap, mask_i, soil_color_i, nsoicol, soil_color_o) - ! - ! !DESCRIPTION: - ! Determine the dominant soil color in each output cell - ! - ! !ARGUMENTS: - type(gridmap_type) , intent(in) :: tgridmap - integer , intent(in) :: mask_i(:) ! input grid: land mask (1 = land, 0 = ocean) - integer , intent(in) :: soil_color_i(:) ! input grid: BATS soil color - integer , intent(in) :: nsoicol ! number of soil colors - integer , intent(out) :: soil_color_o(:) ! output grid: soil color classes - ! - ! !LOCAL VARIABLES: - integer, parameter :: num = 2 ! set soil mapunit number - integer :: wsti(num) ! index to 1st and 2nd largest wst - integer :: k, n, ni, no, ns_i, ns_o - real(r8) :: wt ! map overlap weight - real(r8), allocatable :: wst(:,:) ! overlap weights, by surface type - logical :: has_color ! whether this grid cell has non-zero color - integer, parameter :: miss = 99999 ! missing data indicator - - character(len=*), parameter :: subname = 'dominant_soil_color' - !----------------------------------------------------------------------- - - ns_i = size(mask_i) - if (size(soil_color_i) /= ns_i) then - write(6,*) subname, ' ERROR: size of soil_color_i should match size of mask_i' - write(6,*) 'size(mask_i), size(soil_color_i) = ', & - size(mask_i), size(soil_color_i) - call abort() - end if - - ! find area of overlap for each soil color for each no - - ns_o = size(soil_color_o) - allocate(wst(0:nsoicol,ns_o)) - wst(0:nsoicol,:) = 0 - - ! TODO: need to do a loop to determine - ! the maximum number of over lap cells throughout the grid - ! first get an array that is novr(ns_o) and fill this in - then set - ! maxovr - to max(novr) - then allocate the array wst to be size of - ! maxovr,ns_o or 0:nsoilcol,ns_o - - do n = 1,tgridmap%ns - ni = tgridmap%src_indx(n) - no = tgridmap%dst_indx(n) - wt = tgridmap%wovr(n) * mask_i(ni) - k = soil_color_i(ni) * mask_i(ni) - wst(k,no) = wst(k,no) + wt - enddo - - soil_color_o(:) = 0 - do no = 1,ns_o - - ! If the output cell has any non-zero-colored inputs, then set the weight of - ! zero-colored inputs to 0, to ensure that the zero-color is NOT dominant. - if (any(wst(1:nsoicol,no) > 0.)) then - has_color = .true. - wst(0,no) = 0.0 - else - has_color = .false. - end if - - ! Rank non-zero weights by color type. wsti(1) is the most extensive - ! color type. - - if (has_color) then - call mkrank (nsoicol, wst(0:nsoicol,no), miss, wsti, num) - soil_color_o(no) = wsti(1) - end if - - ! If land but no color, set color to 15 (in older dataset generic - ! soil color 4) - - if (nsoicol == 8) then - if (soil_color_o(no)==0) then - soil_color_o(no) = 4 - end if - else if (nsoicol == 20) then - if (soil_color_o(no)==0) then - soil_color_o(no) = 15 - end if - else - write(6,*) 'MKSOILCOL error: unhandled nsoicol: ', nsoicol - call abort() - end if - - ! Error checks - - if (soil_color_o(no) < 0 .or. soil_color_o(no) > nsoicol) then - write (6,*) 'MKSOILCOL error: land model soil color = ', & - soil_color_o(no),' is not valid for lon,lat = ',no - call abort() - end if - - end do - - deallocate (wst) - - end subroutine dominant_soil_color - - - !----------------------------------------------------------------------- - !BOP - ! - ! !ROUTINE: mkrank - ! - ! !INTERFACE: - subroutine mkrank (n, a, miss, iv, num) - ! - ! !DESCRIPTION: - ! Return indices of largest [num] values in array [a]. - ! - ! !ARGUMENTS: - integer , intent(in) :: n !array length - real(r8), intent(in) :: a(0:n) !array to be ranked - integer , intent(in) :: miss !missing data value - integer , intent(in) :: num !number of largest values requested - integer , intent(out):: iv(num) !index to [num] largest values in array [a] - ! - ! !REVISION HISTORY: - ! Author: Gordon Bonan - ! - ! !LOCAL VARIABLES: - !EOP - real(r8) a_max !maximum value in array - integer i !array index - real(r8) delmax !tolerance for finding if larger value - integer m !do loop index - integer k !do loop index - logical exclude !true if data value has already been chosen - !----------------------------------------------------------------------- - - delmax = 1.e-06 - - ! Find index of largest non-zero number - - iv(1) = miss - a_max = -9999. - - do i = 0, n - if (a(i)>0. .and. (a(i)-a_max)>delmax) then - a_max = a(i) - iv(1) = i - end if - end do - - ! iv(1) = miss indicates no values > 0. this is an error - - if (iv(1) == miss) then - write (6,*) 'MKRANK error: iv(1) = missing' - call abort() - end if - - ! Find indices of the next [num]-1 largest non-zero number. - ! iv(m) = miss if there are no more values > 0 - - do m = 2, num - iv(m) = miss - a_max = -9999. - do i = 0, n - - ! exclude if data value has already been chosen - - exclude = .false. - do k = 1, m-1 - if (i == iv(k)) exclude = .true. - end do - - ! if not already chosen, see if it is the largest of - ! the remaining values - - if (.not. exclude) then - if (a(i)>0. .and. (a(i)-a_max)>delmax) then - a_max = a(i) - iv(m) = i - end if - end if - end do - end do - - end subroutine mkrank - -end module mksoilUtilsMod diff --git a/tools/mksurfdata_map/src/mksoildepthMod.F90 b/tools/mksurfdata_map/src/mksoildepthMod.F90 deleted file mode 100644 index c69cf375a4..0000000000 --- a/tools/mksurfdata_map/src/mksoildepthMod.F90 +++ /dev/null @@ -1,172 +0,0 @@ -module mksoildepthMod - -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mksoildepthMod -! -! !DESCRIPTION: -! make fraction soildepth from input soildepth data -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -!----------------------------------------------------------------------- -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - use mkdomainMod , only : domain_checksame - - implicit none - - private - -! !PUBLIC MEMBER FUNCTIONS: - public mksoildepth ! regrid soildepth data -! -!EOP -!=============================================================== -contains -!=============================================================== - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mksoildepth -! -! !INTERFACE: -subroutine mksoildepth(ldomain, mapfname, datfname, ndiag, soildepth_o) -! -! !DESCRIPTION: -! make soildepth -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_area - use mkchecksMod, only : min_bad, max_bad -! -! !ARGUMENTS: - - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(out):: soildepth_o(:) ! output grid: fraction soildepth -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Sam Levis and Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: data_i(:) ! data on input grid - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - - real(r8), parameter :: min_valid = 0._r8 ! minimum valid value - real(r8), parameter :: max_valid = 100.000001_r8 ! maximum valid value - character(len=32) :: subname = 'mksoildepth' - character(len=32) :: varname - integer :: varnum -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make soildepth .....' - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - call domain_read( tdomain, datfname ) - - call gridmap_mapread( tgridmap, mapfname ) - - ! Obtain frac_dst - allocate(frac_dst(ldomain%ns), stat=ier) - if (ier/=0) call abort() - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write(6,*)'Open soildepth file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(data_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() - - ! ----------------------------------------------------------------- - ! Regrid soildepth - ! ----------------------------------------------------------------- - - varnum = 1 - select case (varnum) - case(1) - varname = 'Avg_Depth_Median' - case(2) - varname = 'Avg_Depth_Mean' - case(3) - varname = 'Upland_Valley_Depth_Median' - case(4) - varname = 'Upland_Valley_Depth_Mean' - case(5) - varname = 'Upland_Hillslope_Depth_Median' - case(6) - varname = 'Upland_Hillslope_Depth_Mean' - case(7) - varname = 'Lowland_Depth_Mean' - case(8) - varname = 'Lowland_Depth_Mean' - end select - -! call check_ret(nf_inq_varid (ncid, 'Avg_Depth_Median', varid), subname) - call check_ret(nf_inq_varid (ncid, varname, varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areaave_srcmask(tgridmap, data_i, soildepth_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check validity of output data - if (min_bad(soildepth_o, min_valid, 'soildepth') .or. & - max_bad(soildepth_o, max_valid, 'soildepth')) then - call abort() - end if - - call output_diagnostics_area(data_i, soildepth_o, tgridmap, "Soildepth", percent=.false., ndiag=ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- - - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (data_i) - deallocate (frac_dst) - deallocate (mask_r8) - - write (6,*) 'Successfully made soildepth' - write (6,*) - call shr_sys_flush(6) - -end subroutine mksoildepth - - -end module mksoildepthMod diff --git a/tools/mksurfdata_map/src/mksurfdat.F90 b/tools/mksurfdata_map/src/mksurfdat.F90 deleted file mode 100644 index aa965f097d..0000000000 --- a/tools/mksurfdata_map/src/mksurfdat.F90 +++ /dev/null @@ -1,1630 +0,0 @@ -program mksurfdat - -!----------------------------------------------------------------------- -!BOP -! -! !PROGRAM: mksurfdat -! -! !DESCRIPTION: -! Creates land model surface dataset from original "raw" data files. -! Surface dataset contains model grid, pfts, inland water, glacier, -! soil texture, soil color, LAI and SAI, urban fraction, and urban -! parameters. -! -! !USES: - use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 - use fileutils , only : opnfil, getavu - use mklaiMod , only : mklai - use mkpctPftTypeMod , only : pct_pft_type, get_pct_p2l_array, get_pct_l2g_array, update_max_array - use mkpftConstantsMod , only : natpft_lb, natpft_ub, cft_lb, cft_ub, num_cft - use mkpftMod , only : pft_idx, pft_frc, mkpft, mkpftInit, mkpft_parse_oride - use mksoilMod , only : soil_sand, soil_clay, mksoiltex, mksoilInit, & - soil_color, mksoilcol, mkorganic, & - soil_fmax, mkfmax - use mkvocefMod , only : mkvocef - use mklanwatMod , only : mklakwat, mkwetlnd, mklakparams - use mkglacierregionMod , only : mkglacierregion - use mkglcmecMod , only : nglcec, mkglcmec, mkglcmecInit, mkglacier - use mkharvestMod , only : mkharvest, mkharvest_init, mkharvest_fieldname - use mkharvestMod , only : mkharvest_numtypes, mkharvest_parse_oride - use mkharvestMod , only : harvestDataType - use mkurbanparCommonMod, only : mkelev - use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, numurbl - use mkutilsMod , only : normalize_classes_by_gcell - use mkfileMod , only : mkfile - use mkvarpar , only : nlevsoi, elev_thresh, numstdpft - use mkvarctl - use nanMod , only : nan, bigint - use mkncdio , only : check_ret, ncd_put_time_slice - use mkdomainMod , only : domain_type, domain_read_map, domain_read - use mkdomainMod , only : domain_write, is_domain_0to360_longs - use mkgdpMod , only : mkgdp - use mkpeatMod , only : mkpeat - use mksoildepthMod , only : mksoildepth - use mkagfirepkmonthMod , only : mkagfirepkmon - use mktopostatsMod , only : mktopostats - use mkVICparamsMod , only : mkVICparams -! -! !ARGUMENTS: - implicit none - - include 'netcdf.inc' -! -! !REVISION HISTORY: -! Authors: Gordon Bonan, Sam Levis and Mariana Vertenstein -! Revised: Nan Rosenbloom to add fmax processing. -! 3/18/08: David Lawrence added organic matter processing -! 1/22/09: Keith Oleson added urban parameter processing -! 2/11/13: Sam Levis added abm, peat, and gdp processing for new fire model -! -! -! !LOCAL VARIABLES: -!EOP - integer :: nsoicol ! number of model color classes - integer :: k,m,n ! indices - integer :: ni,nj,ns_o ! indices - integer :: ier ! error status - integer :: ndiag,nfdyn ! unit numbers - integer :: ncid ! netCDF id - integer :: omode ! netCDF output mode - integer :: varid ! netCDF variable id - integer :: ret ! netCDF return status - integer :: ntim ! time sample for dynamic land use - integer :: year ! year for dynamic land use - integer :: year2 ! year for dynamic land use for harvest file - logical :: all_veg ! if gridcell will be 100% vegetated land-cover - real(r8) :: suma ! sum for error check - character(len=256) :: fgrddat ! grid data file - character(len=256) :: fsurdat ! output surface data file name (if blank, do not output a surface dataset) - character(len=256) :: fsurlog ! output surface log file name - character(len=256) :: fdyndat ! dynamic landuse data file name - character(len=256) :: fname ! generic filename - character(len=256) :: fhrvname ! generic harvest filename - character(len=256) :: string ! string read in - integer :: t1 ! timer - real(r8),parameter :: p5 = 0.5_r8 ! constant - real(r8),parameter :: p25 = 0.25_r8 ! constant - - real(r8), allocatable :: landfrac_pft(:) ! PFT data: % land per gridcell - real(r8), allocatable :: pctlnd_pft(:) ! PFT data: % of gridcell for PFTs - real(r8), allocatable :: pctlnd_pft_dyn(:) ! PFT data: % of gridcell for dyn landuse PFTs - integer , allocatable :: pftdata_mask(:) ! mask indicating real or fake land type - type(pct_pft_type), allocatable :: pctnatpft(:) ! % of grid cell that is nat veg, and breakdown into PFTs - type(pct_pft_type), allocatable :: pctnatpft_max(:) ! % of grid cell maximum PFTs of the time series - type(pct_pft_type), allocatable :: pctcft(:) ! % of grid cell that is crop, and breakdown into CFTs - type(pct_pft_type), allocatable :: pctcft_max(:) ! % of grid cell maximum CFTs of the time series - real(r8) :: harvest_initval ! initial value for harvest variables - real(r8), pointer :: harvest1D(:) ! harvest 1D data: normalized harvesting - real(r8), pointer :: harvest2D(:,:) ! harvest 1D data: normalized harvesting - real(r8), allocatable :: pctgla(:) ! percent of grid cell that is glacier - real(r8), allocatable :: pctglc_gic(:) ! percent of grid cell that is gic (% of glc landunit) - real(r8), allocatable :: pctglc_icesheet(:) ! percent of grid cell that is ice sheet (% of glc landunit) - real(r8), allocatable :: pctglcmec(:,:) ! glacier_mec pct coverage in each class (% of landunit) - real(r8), allocatable :: topoglcmec(:,:) ! glacier_mec sfc elevation in each gridcell and class - real(r8), allocatable :: pctglcmec_gic(:,:) ! GIC pct coverage in each class (% of landunit) - real(r8), allocatable :: pctglcmec_icesheet(:,:) ! icesheet pct coverage in each class (% of landunit) - real(r8), allocatable :: elevclass(:) ! glacier_mec elevation classes - integer, allocatable :: glacier_region(:) ! glacier region ID - real(r8), allocatable :: pctlak(:) ! percent of grid cell that is lake - real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland - real(r8), allocatable :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) - real(r8), allocatable :: urbn_classes(:,:) ! percent cover of each urban class, as % of total urban area - real(r8), allocatable :: urbn_classes_g(:,:)! percent cover of each urban class, as % of grid cell - real(r8), allocatable :: elev(:) ! glc elevation (m) - real(r8), allocatable :: fmax(:) ! fractional saturated area - integer , allocatable :: soicol(:) ! soil color - real(r8), allocatable :: pctsand(:,:) ! soil texture: percent sand - real(r8), allocatable :: pctclay(:,:) ! soil texture: percent clay - real(r8), allocatable :: ef1_btr(:) ! Isoprene emission factor for broadleaf - real(r8), allocatable :: ef1_fet(:) ! Isoprene emission factor for fine/everg - real(r8), allocatable :: ef1_fdt(:) ! Isoprene emission factor for fine/dec - real(r8), allocatable :: ef1_shr(:) ! Isoprene emission factor for shrubs - real(r8), allocatable :: ef1_grs(:) ! Isoprene emission factor for grasses - real(r8), allocatable :: ef1_crp(:) ! Isoprene emission factor for crops - real(r8), allocatable :: organic(:,:) ! organic matter density (kg/m3) - real(r8), allocatable :: gdp(:) ! GDP (x1000 1995 US$/capita) - real(r8), allocatable :: fpeat(:) ! peatland fraction of gridcell - real(r8), allocatable :: soildepth(:) ! soil depth (m) - integer , allocatable :: agfirepkmon(:) ! agricultural fire peak month - integer , allocatable :: urban_region(:) ! urban region ID - real(r8), allocatable :: topo_stddev(:) ! standard deviation of elevation (m) - real(r8), allocatable :: slope(:) ! topographic slope (degrees) - real(r8), allocatable :: vic_binfl(:) ! VIC b parameter (unitless) - real(r8), allocatable :: vic_ws(:) ! VIC Ws parameter (unitless) - real(r8), allocatable :: vic_dsmax(:) ! VIC Dsmax parameter (mm/day) - real(r8), allocatable :: vic_ds(:) ! VIC Ds parameter (unitless) - real(r8), allocatable :: lakedepth(:) ! lake depth (m) - - real(r8) :: std_elev = -999.99_r8 ! Standard deviation of elevation (m) to use for entire grid - - integer, allocatable :: harvind1D(:) ! Indices of 1D harvest fields - integer, allocatable :: harvind2D(:) ! Indices of 2D harvest fields - - ! NOTE(bja, 2015-01) added to work around a ?bug? causing 1x1_urbanc_alpha to abort. See - !/glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 - logical :: urban_skip_abort_on_invalid_data_check - - type(domain_type) :: ldomain - - character(len=32) :: subname = 'mksrfdat' ! program name - type(harvestDataType) :: harvdata - - namelist /clmexp/ & - mksrf_fgrid, & - mksrf_gridtype, & - mksrf_fvegtyp, & - mksrf_fhrvtyp, & - mksrf_fsoitex, & - mksrf_forganic, & - mksrf_fsoicol, & - mksrf_fvocef, & - mksrf_flakwat, & - mksrf_fwetlnd, & - mksrf_fglacier, & - mksrf_fglacierregion, & - mksrf_furbtopo, & - mksrf_fmax, & - mksrf_furban, & - mksrf_flai, & - mksrf_fdynuse, & - mksrf_fgdp, & - mksrf_fpeat, & - mksrf_fsoildepth, & - mksrf_fabm, & - mksrf_ftopostats, & - mksrf_fvic, & - nglcec, & - numpft, & - soil_color, & - soil_sand, & - soil_fmax, & - soil_clay, & - pft_idx, & - all_veg, & - pft_frc, & - all_urban, & - no_inlandwet, & - map_fpft, & - map_flakwat, & - map_fwetlnd, & - map_fglacier, & - map_fglacierregion, & - map_fsoitex, & - map_fsoicol, & - map_furban, & - map_furbtopo, & - map_fmax, & - map_forganic, & - map_fvocef, & - map_flai, & - map_fharvest, & - map_fgdp, & - map_fpeat, & - map_fsoildepth, & - map_fabm, & - map_ftopostats, & - map_fvic, & - gitdescribe, & - outnc_large_files, & - outnc_double, & - outnc_dims, & - outnc_vic, & - outnc_3dglc, & - fsurdat, & - fdyndat, & - fsurlog, & - std_elev, & - urban_skip_abort_on_invalid_data_check - -!----------------------------------------------------------------------- - - ! ====================================================================== - ! Read input namelist - ! ====================================== - ! Must specify settings for the output grid: - ! ====================================== - ! mksrf_fgrid -- Grid dataset - ! ====================================== - ! Must specify settings for input high resolution datafiles - ! ====================================== - ! mksrf_fglacier - Glacier dataset - ! mksrf_fglacierregion - Glacier region ID dataset - ! mksrf_flai ----- Leaf Area Index dataset - ! mksrf_flakwat -- Lake water dataset - ! mksrf_fwetlnd -- Wetland water dataset - ! mksrf_forganic - Organic soil carbon dataset - ! mksrf_fmax ----- Max fractional saturated area dataset - ! mksrf_fsoicol -- Soil color dataset - ! mksrf_fsoitex -- Soil texture dataset - ! mksrf_furbtopo-- Topography dataset (for limiting urban areas) - ! mksrf_furban --- Urban dataset - ! mksrf_fvegtyp -- PFT vegetation type dataset - ! mksrf_fhrvtyp -- harvest type dataset - ! mksrf_fvocef -- Volatile Organic Compund Emission Factor dataset - ! mksrf_fgdp ----- GDP dataset - ! mksrf_fpeat ---- Peatland dataset - ! mksrf_fsoildepth Soil depth dataset - ! mksrf_fabm ----- Agricultural fire peak month dataset - ! mksrf_ftopostats Topography statistics dataset - ! mksrf_fvic ----- VIC parameters dataset - ! ====================================== - ! Must specify mapping file for the different datafiles above - ! ====================================== - ! map_fpft -------- Mapping for mksrf_fvegtyp - ! map_flakwat ----- Mapping for mksrf_flakwat - ! map_fwetlnd ----- Mapping for mksrf_fwetlnd - ! map_fglacier ---- Mapping for mksrf_fglacier - ! map_fglacierregion - Mapping for mksrf_fglacierregion - ! map_fsoitex ----- Mapping for mksrf_fsoitex - ! map_fsoicol ----- Mapping for mksrf_fsoicol - ! map_furban ------ Mapping for mksrf_furban - ! map_furbtopo ---- Mapping for mksrf_furbtopo - ! map_fmax -------- Mapping for mksrf_fmax - ! map_forganic ---- Mapping for mksrf_forganic - ! map_fvocef ------ Mapping for mksrf_fvocef - ! map_flai -------- Mapping for mksrf_flai - ! map_fharvest ---- Mapping for mksrf_flai harvesting - ! map_fgdp -------- Mapping for mksrf_fgdp - ! map_fpeat ------- Mapping for mksrf_fpeat - ! map_fsoildepth -- Mapping for mksrf_fsoildepth - ! map_fabm -------- Mapping for mksrf_fabm - ! map_ftopostats -- Mapping for mksrf_ftopostats - ! map_fvic -------- Mapping for mksrf_fvic - ! ====================================== - ! Optionally specify setting for: - ! ====================================== - ! mksrf_fdynuse ----- ASCII text file that lists each year of pft files to use - ! mksrf_gridtype ---- Type of grid (default is 'global') - ! outnc_double ------ If output should be in double precision - ! outnc_large_files - If output should be in NetCDF large file format - ! outnc_vic --------- Output fields needed for VIC - ! outnc_3dglc ------- Output 3D glacier fields (normally only needed for comparasion) - ! nglcec ------------ If you want to change the number of Glacier elevation classes - ! gitdescribe ------- Description of this version from git - ! ====================================== - ! Optional settings to change values for entire area - ! ====================================== - ! all_urban --------- If entire area is urban - ! all_veg ----------- If entire area is to be vegetated (pft_idx and pft_frc then required) - ! no_inlandwet ------ If wetland should be set to 0% over land - ! soil_color -------- If you want to change the soil_color to this value everywhere - ! soil_clay --------- If you want to change the soil_clay % to this value everywhere - ! soil_fmax --------- If you want to change the soil_fmax to this value everywhere - ! soil_sand --------- If you want to change the soil_sand % to this value everywhere - ! pft_idx ----------- If you want to change to 100% veg covered with given PFT indices - ! pft_frc ----------- Fractions that correspond to the pft_idx above - ! ================== - ! numpft (if different than default of 16) - ! ====================================== - ! Optional settings to work around urban bug? - ! ====================================== - ! urban_skip_abort_on_invalid_data_check - ! ====================================================================== - - write(6,*) 'Attempting to initialize control settings .....' - - mksrf_gridtype = 'global' - outnc_large_files = .false. - outnc_double = .true. - outnc_vic = .false. - outnc_3dglc = .false. - all_urban = .false. - all_veg = .false. - no_inlandwet = .true. - - ! default value for bug work around - urban_skip_abort_on_invalid_data_check = .false. - - read(5, clmexp, iostat=ier) - if (ier /= 0) then - write(6,*)'error: namelist input resulted in error code ',ier - call abort() - endif - - write (6,*) 'Attempting to create surface boundary data .....' - write (6,'(72a1)') ("-",n=1,60) - - ! ---------------------------------------------------------------------- - ! Error check namelist input - ! ---------------------------------------------------------------------- - - if (urban_skip_abort_on_invalid_data_check) then - write(6, *) "WARNING: aborting on invalid data check in urban has been disabled!" - write(6, *) "WARNING: urban data may be invalid!" - end if - - if (mksrf_fgrid /= ' ')then - fgrddat = mksrf_fgrid - write(6,*)'mksrf_fgrid = ',mksrf_fgrid - else - write (6,*)'must specify mksrf_fgrid' - call abort() - endif - - if (trim(mksrf_gridtype) == 'global' .or. & - trim(mksrf_gridtype) == 'regional') then - write(6,*)'mksrf_gridtype = ',trim(mksrf_gridtype) - else - write(6,*)'mksrf_gridtype = ',trim(mksrf_gridtype) - write (6,*)'illegal mksrf_gridtype, must be global or regional ' - call abort() - endif - if ( outnc_large_files )then - write(6,*)'Output file in NetCDF 64-bit large_files format' - end if - if ( outnc_double )then - write(6,*)'Output ALL data in file as 64-bit' - end if - if ( outnc_vic )then - write(6,*)'Output VIC fields' - end if - if ( outnc_3dglc )then - write(6,*)'Output optional 3D glacier fields (mostly used for verification of the glacier model)' - end if - if ( outnc_3dglc )then - write(6,*)'Output optional 3D glacier fields (mostly used for verification of the glacier model)' - end if - if ( all_urban )then - write(6,*) 'Output ALL data in file as 100% urban' - end if - if ( no_inlandwet )then - write(6,*) 'Set wetland to 0% over land' - end if - if (nglcec <= 0) then - write(6,*) 'nglcec must be at least 1' - call abort() - end if - - ! - ! Call module initialization routines - ! - call mksoilInit( ) - call mkpftInit( zero_out_l=all_urban, all_veg_l=all_veg ) - allocate ( elevclass(nglcec+1) ) - call mkglcmecInit (elevclass) - call mkurbanInit (mksrf_furban) - - if ( all_veg )then - write(6,*) 'Output ALL data in file as 100% vegetated' - end if - - ! ---------------------------------------------------------------------- - ! Determine land model grid, fractional land and land mask - ! ---------------------------------------------------------------------- - - write(6,*)'calling domain_read' - if ( .not. domain_read_map(ldomain, fgrddat) )then - call domain_read(ldomain, fgrddat) - end if - write(6,*)'finished domain_read' - - ! Invalidate mask and frac for ldomain - - !ldomain%mask = bigint - !ldomain%frac = nan - - ! Determine if will have 1d output - - if (ldomain%ni /= -9999 .and. ldomain%nj /= -9999) then - write(6,*)'fsurdat is 2d lat/lon grid' - write(6,*)'nlon= ',ldomain%ni,' nlat= ',ldomain%nj - if (outnc_dims == 1) then - write(6,*)' writing output file in 1d gridcell format' - end if - else - write(6,*)'fsurdat is 1d gridcell grid' - outnc_dims = 1 - end if - - outnc_1d = .false. - if ((ldomain%ni == -9999 .and. ldomain%nj == -9999) .or. outnc_dims==1) then - outnc_1d = .true. - write(6,*)'output file will be 1d' - end if - - ! Make sure ldomain is on a 0 to 360 grid as that's a requirement for CESM - if ( .not. is_domain_0to360_longs( ldomain ) )then - write(6,*)' Output domain must be on a 0 to 360 longitude grid rather than a -180 to 180 grid as it is required for CESM' - call abort() - end if - ! ---------------------------------------------------------------------- - ! Allocate and initialize dynamic memory - ! ---------------------------------------------------------------------- - - ns_o = ldomain%ns - allocate ( landfrac_pft(ns_o) , & - pctlnd_pft(ns_o) , & - pftdata_mask(ns_o) , & - pctnatpft(ns_o) , & - pctnatpft_max(ns_o) , & - pctcft(ns_o) , & - pctcft_max(ns_o) , & - pctgla(ns_o) , & - pctlak(ns_o) , & - pctwet(ns_o) , & - pcturb(ns_o) , & - urban_region(ns_o) , & - urbn_classes(ns_o,numurbl) , & - urbn_classes_g(ns_o,numurbl) , & - pctsand(ns_o,nlevsoi) , & - pctclay(ns_o,nlevsoi) , & - soicol(ns_o) , & - gdp(ns_o) , & - fpeat(ns_o) , & - soildepth(ns_o) , & - agfirepkmon(ns_o) , & - topo_stddev(ns_o) , & - slope(ns_o) , & - vic_binfl(ns_o) , & - vic_ws(ns_o) , & - vic_dsmax(ns_o) , & - vic_ds(ns_o) , & - lakedepth(ns_o) , & - glacier_region(ns_o) ) - landfrac_pft(:) = spval - pctlnd_pft(:) = spval - pftdata_mask(:) = -999 - pctgla(:) = spval - pctlak(:) = spval - pctwet(:) = spval - pcturb(:) = spval - urban_region(:) = -999 - urbn_classes(:,:) = spval - urbn_classes_g(:,:) = spval - pctsand(:,:) = spval - pctclay(:,:) = spval - soicol(:) = -999 - gdp(:) = spval - fpeat(:) = spval - soildepth(:) = spval - agfirepkmon(:) = -999 - topo_stddev(:) = spval - slope(:) = spval - vic_binfl(:) = spval - vic_ws(:) = spval - vic_dsmax(:) = spval - vic_ds(:) = spval - lakedepth(:) = spval - glacier_region(:) = -999 - - ! ---------------------------------------------------------------------- - ! Open diagnostic output log file - ! ---------------------------------------------------------------------- - - if (fsurlog == ' ') then - write(6,*)' must specify fsurlog in namelist' - call abort() - else - ndiag = getavu(); call opnfil (fsurlog, ndiag, 'f') - end if - - if (urban_skip_abort_on_invalid_data_check) then - write(ndiag, *) "WARNING: aborting on invalid data check in urban has been disabled!" - write(ndiag, *) "WARNING: urban data may be invalid!" - end if - - if (mksrf_fgrid /= ' ')then - write (ndiag,*)'using fractional land data from file= ', & - trim(mksrf_fgrid),' to create the surface dataset' - endif - - if (trim(mksrf_gridtype) == 'global' .or. & - trim(mksrf_gridtype) == 'regional') then - write(6,*)'mksrf_gridtype = ',trim(mksrf_gridtype) - endif - - write(ndiag,*) 'PFTs from: ',trim(mksrf_fvegtyp) - write(ndiag,*) 'harvest from: ',trim(mksrf_fhrvtyp) - write(ndiag,*) 'fmax from: ',trim(mksrf_fmax) - write(ndiag,*) 'glaciers from: ',trim(mksrf_fglacier) - write(ndiag,*) ' with: ', nglcec, ' glacier elevation classes' - write(ndiag,*) 'glacier region ID from: ',trim(mksrf_fglacierregion) - write(ndiag,*) 'urban topography from: ',trim(mksrf_furbtopo) - write(ndiag,*) 'urban from: ',trim(mksrf_furban) - write(ndiag,*) 'inland lake from: ',trim(mksrf_flakwat) - write(ndiag,*) 'inland wetland from: ',trim(mksrf_fwetlnd) - write(ndiag,*) 'soil texture from: ',trim(mksrf_fsoitex) - write(ndiag,*) 'soil organic from: ',trim(mksrf_forganic) - write(ndiag,*) 'soil color from: ',trim(mksrf_fsoicol) - write(ndiag,*) 'VOC emission factors from: ',trim(mksrf_fvocef) - write(ndiag,*) 'gdp from: ',trim(mksrf_fgdp) - write(ndiag,*) 'peat from: ',trim(mksrf_fpeat) - write(ndiag,*) 'soil depth from: ',trim(mksrf_fsoildepth) - write(ndiag,*) 'abm from: ',trim(mksrf_fabm) - write(ndiag,*) 'topography statistics from: ',trim(mksrf_ftopostats) - write(ndiag,*) 'VIC parameters from: ',trim(mksrf_fvic) - write(ndiag,*)' mapping for pft ',trim(map_fpft) - write(ndiag,*)' mapping for lake water ',trim(map_flakwat) - write(ndiag,*)' mapping for wetland ',trim(map_fwetlnd) - write(ndiag,*)' mapping for glacier ',trim(map_fglacier) - write(ndiag,*)' mapping for glacier region ',trim(map_fglacierregion) - write(ndiag,*)' mapping for soil texture ',trim(map_fsoitex) - write(ndiag,*)' mapping for soil color ',trim(map_fsoicol) - write(ndiag,*)' mapping for soil organic ',trim(map_forganic) - write(ndiag,*)' mapping for urban ',trim(map_furban) - write(ndiag,*)' mapping for fmax ',trim(map_fmax) - write(ndiag,*)' mapping for VOC pct emis ',trim(map_fvocef) - write(ndiag,*)' mapping for harvest ',trim(map_fharvest) - write(ndiag,*)' mapping for lai/sai ',trim(map_flai) - write(ndiag,*)' mapping for urb topography ',trim(map_furbtopo) - write(ndiag,*)' mapping for GDP ',trim(map_fgdp) - write(ndiag,*)' mapping for peatlands ',trim(map_fpeat) - write(ndiag,*)' mapping for soil depth ',trim(map_fsoildepth) - write(ndiag,*)' mapping for ag fire pk month ',trim(map_fabm) - write(ndiag,*)' mapping for topography stats ',trim(map_ftopostats) - write(ndiag,*)' mapping for VIC parameters ',trim(map_fvic) - - if (mksrf_fdynuse /= ' ') then - write(6,*)'mksrf_fdynuse = ',trim(mksrf_fdynuse) - end if - - ! ---------------------------------------------------------------------- - ! Make surface dataset fields - ! ---------------------------------------------------------------------- - - ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] - - call mkpft(ldomain, mapfname=map_fpft, fpft=mksrf_fvegtyp, & - ndiag=ndiag, pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft) - - ! Create harvesting data at model resolution - if (all_veg) then - ! In this case, we don't call mkharvest, so we want the harvest variables to be - ! initialized reasonably. - harvest_initval = 0._r8 - else - harvest_initval = spval - end if - call mkharvest_init( ns_o, harvest_initval, harvdata, mksrf_fhrvtyp ) - if ( .not. all_veg )then - - call mkharvest( ldomain, mapfname=map_fharvest, datfname=mksrf_fhrvtyp, & - ndiag=ndiag, harvdata=harvdata ) - end if - - ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] - - call mklakwat (ldomain, mapfname=map_flakwat, datfname=mksrf_flakwat, & - ndiag=ndiag, zero_out=all_urban.or.all_veg, lake_o=pctlak) - - call mkwetlnd (ldomain, mapfname=map_fwetlnd, datfname=mksrf_fwetlnd, & - ndiag=ndiag, zero_out=all_urban.or.all_veg.or.no_inlandwet, swmp_o=pctwet) - - ! Make glacier fraction [pctgla] from [fglacier] dataset - - call mkglacier (ldomain, mapfname=map_fglacier, datfname=mksrf_fglacier, & - ndiag=ndiag, zero_out=all_urban.or.all_veg, glac_o=pctgla) - - ! Make glacier region ID [glacier_region] from [fglacierregion] dataset - - call mkglacierregion (ldomain, mapfname=map_fglacierregion, & - datfname=mksrf_fglacierregion, ndiag=ndiag, & - glacier_region_o = glacier_region) - - ! Make soil texture [pctsand, pctclay] [fsoitex] - - call mksoiltex (ldomain, mapfname=map_fsoitex, datfname=mksrf_fsoitex, & - ndiag=ndiag, sand_o=pctsand, clay_o=pctclay) - ! Make soil color classes [soicol] [fsoicol] - - call mksoilcol (ldomain, mapfname=map_fsoicol, datfname=mksrf_fsoicol, & - ndiag=ndiag, soil_color_o=soicol, nsoicol=nsoicol) - - ! Make fmax [fmax] from [fmax] dataset - - allocate(fmax(ns_o)) - fmax(:) = spval - call mkfmax (ldomain, mapfname=map_fmax, datfname=mksrf_fmax, & - ndiag=ndiag, fmax_o=fmax) - - ! Make GDP data [gdp] from [gdp] - - call mkgdp (ldomain, mapfname=map_fgdp, datfname=mksrf_fgdp, & - ndiag=ndiag, gdp_o=gdp) - - ! Make peat data [fpeat] from [peatf] - - call mkpeat (ldomain, mapfname=map_fpeat, datfname=mksrf_fpeat, & - ndiag=ndiag, peat_o=fpeat) - - ! Make soil depth data [soildepth] from [soildepthf] - - call mksoildepth (ldomain, mapfname=map_fsoildepth, datfname=mksrf_fsoildepth, & - ndiag=ndiag, soildepth_o=soildepth) - - ! Make agricultural fire peak month data [abm] from [abm] - - call mkagfirepkmon (ldomain, mapfname=map_fabm, datfname=mksrf_fabm, & - ndiag=ndiag, agfirepkmon_o=agfirepkmon) - - ! Make urban fraction [pcturb] from [furban] dataset - - call mkurban (ldomain, mapfname=map_furban, datfname=mksrf_furban, & - ndiag=ndiag, zero_out=all_veg, urbn_o=pcturb, urbn_classes_o=urbn_classes, & - region_o=urban_region) - - ! Make elevation [elev] from [ftopo, ffrac] dataset - ! Used only to screen pcturb - ! Screen pcturb by elevation threshold from elev dataset - - if ( .not. all_urban .and. .not. all_veg )then - allocate(elev(ns_o)) - elev(:) = spval - ! NOTE(wjs, 2016-01-15) This uses the 'TOPO_ICE' variable for historical reasons - ! (this same dataset used to be used for glacier-related purposes as well). - ! TODO(wjs, 2016-01-15) A better solution for this urban screening would probably - ! be to modify the raw urban data; in that case, I believe we could remove - ! furbtopo. - call mkelev (ldomain, mapfname=map_furbtopo, datfname=mksrf_furbtopo, & - varname='TOPO_ICE', ndiag=ndiag, elev_o=elev) - - where (elev .gt. elev_thresh) - pcturb = 0._r8 - end where - deallocate(elev) - end if - - ! Compute topography statistics [topo_stddev, slope] from [ftopostats] - call mktopostats (ldomain, mapfname=map_ftopostats, datfname=mksrf_ftopostats, & - ndiag=ndiag, topo_stddev_o=topo_stddev, slope_o=slope, std_elev=std_elev) - - ! Make VIC parameters [binfl, ws, dsmax, ds] from [fvic] - if ( outnc_vic )then - call mkVICparams (ldomain, mapfname=map_fvic, datfname=mksrf_fvic, ndiag=ndiag, & - binfl_o=vic_binfl, ws_o=vic_ws, dsmax_o=vic_dsmax, ds_o=vic_ds) - end if - - ! Make lake depth [lakedepth] from [flakwat] - call mklakparams (ldomain, mapfname=map_flakwat, datfname=mksrf_flakwat, ndiag=ndiag, & - lakedepth_o=lakedepth) - - ! Make organic matter density [organic] [forganic] - allocate (organic(ns_o,nlevsoi)) - organic(:,:) = spval - call mkorganic (ldomain, mapfname=map_forganic, datfname=mksrf_forganic, & - ndiag=ndiag, organic_o=organic) - - ! Make VOC emission factors for isoprene & - ! [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] - - allocate ( ef1_btr(ns_o) , & - ef1_fet(ns_o) , & - ef1_fdt(ns_o) , & - ef1_shr(ns_o) , & - ef1_grs(ns_o) , & - ef1_crp(ns_o) ) - ef1_btr(:) = 0._r8 - ef1_fet(:) = 0._r8 - ef1_fdt(:) = 0._r8 - ef1_shr(:) = 0._r8 - ef1_grs(:) = 0._r8 - ef1_crp(:) = 0._r8 - - call mkvocef (ldomain, mapfname=map_fvocef, datfname=mksrf_fvocef, ndiag=ndiag, & - ef_btr_o=ef1_btr, ef_fet_o=ef1_fet, ef_fdt_o=ef1_fdt, & - ef_shr_o=ef1_shr, ef_grs_o=ef1_grs, ef_crp_o=ef1_crp) - - ! Do landuse changes such as for the poles, etc. - - call change_landuse( ldomain, dynpft=.false. ) - - do n = 1,ns_o - - ! Truncate all percentage fields on output grid. This is needed to - ! insure that wt is zero (not a very small number such as - ! 1e-16) where it really should be zero - - do k = 1,nlevsoi - pctsand(n,k) = float(nint(pctsand(n,k))) - pctclay(n,k) = float(nint(pctclay(n,k))) - end do - pctlak(n) = float(nint(pctlak(n))) - pctwet(n) = float(nint(pctwet(n))) - pctgla(n) = float(nint(pctgla(n))) - - ! Assume wetland, glacier and/or lake when dataset landmask implies ocean - ! (assume medium soil color (15) and loamy texture). - ! Also set pftdata_mask here - - if (pctlnd_pft(n) < 1.e-6_r8) then - pftdata_mask(n) = 0 - soicol(n) = 15 - if (pctgla(n) < 1.e-6_r8) then - pctwet(n) = 100._r8 - pctlak(n) - pctgla(n) = 0._r8 - else - pctwet(n) = max(100._r8 - pctgla(n) - pctlak(n), 0.0_r8) - end if - pcturb(n) = 0._r8 - call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) - pctsand(n,:) = 43._r8 - pctclay(n,:) = 18._r8 - organic(n,:) = 0._r8 - else - pftdata_mask(n) = 1 - end if - - ! Make sure sum of land cover types does not exceed 100. If it does, - ! subtract excess from most dominant land cover. - - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - if (suma > 250._r4) then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb and pctgla is greater than 250%' - write (6,*)'n,pctlak,pctwet,pcturb,pctgla= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n) - call abort() - else if (suma > 100._r4) then - pctlak(n) = pctlak(n) * 100._r8/suma - pctwet(n) = pctwet(n) * 100._r8/suma - pcturb(n) = pcturb(n) * 100._r8/suma - pctgla(n) = pctgla(n) * 100._r8/suma - end if - - end do - - call normalizencheck_landuse(ldomain) - - ! Write out sum of PFT's - - do k = natpft_lb,natpft_ub - suma = 0._r8 - do n = 1,ns_o - suma = suma + pctnatpft(n)%get_one_pct_p2g(k) - enddo - write(6,*) 'sum over domain of pft ',k,suma - enddo - write(6,*) - - do k = cft_lb,cft_ub - suma = 0._r8 - do n = 1,ns_o - suma = suma + pctcft(n)%get_one_pct_p2g(k) - enddo - write(6,*) 'sum over domain of cft ',k,suma - enddo - write(6,*) - - ! Make final values of percent urban by class - ! This call needs to occur after all corrections are made to pcturb - - call normalize_classes_by_gcell(urbn_classes, pcturb, urbn_classes_g) - - - ! Make glacier multiple elevation classes [pctglcmec,topoglcmec] from [fglacier] dataset - ! This call needs to occur after pctgla has been adjusted for the final time - - allocate (pctglcmec(ns_o,nglcec), & - topoglcmec(ns_o,nglcec) ) - if ( outnc_3dglc )then - allocate( & - pctglcmec_gic(ns_o,nglcec), & - pctglcmec_icesheet(ns_o,nglcec)) - allocate (pctglc_gic(ns_o)) - allocate (pctglc_icesheet(ns_o)) - end if - - pctglcmec(:,:) = spval - topoglcmec(:,:) = spval - - if ( outnc_3dglc )then - call mkglcmec (ldomain, mapfname=map_fglacier, & - datfname_fglacier=mksrf_fglacier, ndiag=ndiag, & - pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec, & - pctglcmec_gic_o=pctglcmec_gic, pctglcmec_icesheet_o=pctglcmec_icesheet, & - pctglc_gic_o=pctglc_gic, pctglc_icesheet_o=pctglc_icesheet) - else - call mkglcmec (ldomain, mapfname=map_fglacier, & - datfname_fglacier=mksrf_fglacier, ndiag=ndiag, & - pctglcmec_o=pctglcmec, topoglcmec_o=topoglcmec ) - end if - - ! Determine fractional land from pft dataset - - do n = 1,ns_o - landfrac_pft(n) = pctlnd_pft(n)/100._r8 - end do - - ! ---------------------------------------------------------------------- - ! Create surface dataset - ! ---------------------------------------------------------------------- - - ! Create netCDF surface dataset. - - ! If fsurdat is blank, then we do not write a surface dataset - but we may still - ! write a dynamic landuse file. This is useful if we are creating many datasets at - ! once, and don't want duplicate surface datasets. - ! - ! TODO(wjs, 2016-01-26) Ideally, we would also avoid doing the processing of - ! variables that are just needed by the surface dataset (not by the dynamic landuse - ! file). However, this would require some analysis of the above code, to determine - ! which processing is needed (directly or indirectly) in order to create a dynamic - ! landuse file. - - if (fsurdat /= ' ') then - - call mkfile(ldomain, trim(fsurdat), harvdata, dynlanduse = .false.) - - call domain_write(ldomain, fsurdat) - - call check_ret(nf_open(trim(fsurdat), nf_write, ncid), subname) - call check_ret(nf_set_fill (ncid, nf_nofill, omode), subname) - - ! Write fields OTHER THAN lai, sai, heights, and urban parameters to netcdf surface dataset - - call check_ret(nf_inq_varid(ncid, 'natpft', varid), subname) - call check_ret(nf_put_var_int(ncid, varid, (/(n,n=natpft_lb,natpft_ub)/)), subname) - - if (num_cft > 0) then - call check_ret(nf_inq_varid(ncid, 'cft', varid), subname) - call check_ret(nf_put_var_int(ncid, varid, (/(n,n=cft_lb,cft_ub)/)), subname) - end if - - call check_ret(nf_inq_varid(ncid, 'PFTDATA_MASK', varid), subname) - call check_ret(nf_put_var_int(ncid, varid, pftdata_mask), subname) - - call check_ret(nf_inq_varid(ncid, 'LANDFRAC_PFT', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, landfrac_pft), subname) - - call check_ret(nf_inq_varid(ncid, 'mxsoil_color', varid), subname) - call check_ret(nf_put_var_int(ncid, varid, nsoicol), subname) - - call check_ret(nf_inq_varid(ncid, 'SOIL_COLOR', varid), subname) - call check_ret(nf_put_var_int(ncid, varid, soicol), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_SAND', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pctsand), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_CLAY', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pctclay), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_WETLAND', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pctwet), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_LAKE', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pctlak), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_GLACIER', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pctgla), subname) - - call check_ret(nf_inq_varid(ncid, 'GLACIER_REGION', varid), subname) - call check_ret(nf_put_var_int(ncid, varid, glacier_region), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_GLC_MEC', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pctglcmec), subname) - - call check_ret(nf_inq_varid(ncid, 'GLC_MEC', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, elevclass), subname) - - call check_ret(nf_inq_varid(ncid, 'TOPO_GLC_MEC', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, topoglcmec), subname) - - if ( outnc_3dglc )then - call check_ret(nf_inq_varid(ncid, 'PCT_GLC_MEC_GIC', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pctglcmec_gic), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_GLC_MEC_ICESHEET', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pctglcmec_icesheet), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_GLC_GIC', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pctglc_gic), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_GLC_ICESHEET', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pctglc_icesheet), subname) - end if - - if ( outnc_3dglc )then - call check_ret(nf_inq_varid(ncid, 'PCT_GLC_MEC_GIC', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pctglcmec_gic), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_GLC_MEC_ICESHEET', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pctglcmec_icesheet), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_GLC_GIC', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pctglc_gic), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_GLC_ICESHEET', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, pctglc_icesheet), subname) - end if - - call check_ret(nf_inq_varid(ncid, 'PCT_URBAN', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, urbn_classes_g), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_NATVEG', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, get_pct_l2g_array(pctnatpft)), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_CROP', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, get_pct_l2g_array(pctcft)), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_NAT_PFT', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, get_pct_p2l_array(pctnatpft)), subname) - - if (num_cft > 0) then - call check_ret(nf_inq_varid(ncid, 'PCT_CFT', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, get_pct_p2l_array(pctcft)), subname) - end if - - call harvdata%getFieldsIdx( harvind1D, harvind2D ) - do k = 1, harvdata%num1Dfields() - call check_ret(nf_inq_varid(ncid, trim(mkharvest_fieldname(harvind1D(k),constant=.true.)), varid), subname) - harvest1D => harvdata%get1DFieldPtr( harvind1D(k), output=.true. ) - call check_ret(nf_put_var_double(ncid, varid, harvest1D), subname) - end do - do k = 1, harvdata%num2Dfields() - call check_ret(nf_inq_varid(ncid, trim(mkharvest_fieldname(harvind2D(k),constant=.true.)), varid), subname) - harvest2D => harvdata%get2DFieldPtr( harvind2D(k), output=.true. ) - call check_ret(nf_put_var_double(ncid, varid, harvest2D), subname) - end do - deallocate( harvind1D, harvind2D ) - - call check_ret(nf_inq_varid(ncid, 'FMAX', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, fmax), subname) - - call check_ret(nf_inq_varid(ncid, 'gdp', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, gdp), subname) - - call check_ret(nf_inq_varid(ncid, 'peatf', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, fpeat), subname) - - - ! call check_ret(nf_inq_varid(ncid, 'Avg_Depth_Median', varid), subname) - call check_ret(nf_inq_varid(ncid, 'zbedrock', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, soildepth), subname) - - call check_ret(nf_inq_varid(ncid, 'abm', varid), subname) - call check_ret(nf_put_var_int(ncid, varid, agfirepkmon), subname) - - call check_ret(nf_inq_varid(ncid, 'SLOPE', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, slope), subname) - - call check_ret(nf_inq_varid(ncid, 'STD_ELEV', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, topo_stddev), subname) - - if ( outnc_vic )then - call check_ret(nf_inq_varid(ncid, 'binfl', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, vic_binfl), subname) - - call check_ret(nf_inq_varid(ncid, 'Ws', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, vic_ws), subname) - - call check_ret(nf_inq_varid(ncid, 'Dsmax', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, vic_dsmax), subname) - - call check_ret(nf_inq_varid(ncid, 'Ds', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, vic_ds), subname) - end if - - call check_ret(nf_inq_varid(ncid, 'LAKEDEPTH', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, lakedepth), subname) - - call check_ret(nf_inq_varid(ncid, 'EF1_BTR', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, ef1_btr), subname) - - call check_ret(nf_inq_varid(ncid, 'EF1_FET', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, ef1_fet), subname) - - call check_ret(nf_inq_varid(ncid, 'EF1_FDT', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, ef1_fdt), subname) - - call check_ret(nf_inq_varid(ncid, 'EF1_SHR', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, ef1_shr), subname) - - call check_ret(nf_inq_varid(ncid, 'EF1_GRS', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, ef1_grs), subname) - - call check_ret(nf_inq_varid(ncid, 'EF1_CRP', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, ef1_crp), subname) - - call check_ret(nf_inq_varid(ncid, 'ORGANIC', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, organic), subname) - - call check_ret(nf_inq_varid(ncid, 'URBAN_REGION_ID', varid), subname) - call check_ret(nf_put_var_int(ncid, varid, urban_region), subname) - - ! Synchronize the disk copy of a netCDF dataset with in-memory buffers - - call check_ret(nf_sync(ncid), subname) - - ! ---------------------------------------------------------------------- - ! Make Urban Parameters from raw input data and write to surface dataset - ! Write to netcdf file is done inside mkurbanpar routine - ! ---------------------------------------------------------------------- - - write(6,*)'calling mkurbanpar' - call mkurbanpar(datfname=mksrf_furban, ncido=ncid, region_o=urban_region, & - urbn_classes_gcell_o=urbn_classes_g, & - urban_skip_abort_on_invalid_data_check=urban_skip_abort_on_invalid_data_check) - - ! ---------------------------------------------------------------------- - ! Make LAI and SAI from 1/2 degree data and write to surface dataset - ! Write to netcdf file is done inside mklai routine - ! ---------------------------------------------------------------------- - - write(6,*)'calling mklai' - call mklai(ldomain, mapfname=map_flai, datfname=mksrf_flai, & - ndiag=ndiag, ncido=ncid ) - - ! Close surface dataset - - call check_ret(nf_close(ncid), subname) - - write (6,'(72a1)') ("-",n=1,60) - write (6,*)' land model surface data set successfully created for ', & - 'grid of size ',ns_o - - else ! fsurdat == ' ' - - write (6,*) 'fsurdat is blank: skipping writing surface dataset' - - end if ! if (fsurdat /= ' ') - - ! Deallocate arrays NOT needed for dynamic-pft section of code - - deallocate ( organic ) - deallocate ( ef1_btr, ef1_fet, ef1_fdt, ef1_shr, ef1_grs, ef1_crp ) - deallocate ( pctglcmec, topoglcmec) - if ( outnc_3dglc ) deallocate ( pctglc_gic, pctglc_icesheet) - deallocate ( elevclass ) - deallocate ( fmax ) - deallocate ( pctsand, pctclay ) - deallocate ( soicol ) - deallocate ( gdp, fpeat, agfirepkmon ) - deallocate ( soildepth ) - deallocate ( topo_stddev, slope ) - deallocate ( vic_binfl, vic_ws, vic_dsmax, vic_ds ) - deallocate ( lakedepth ) - deallocate ( glacier_region ) - - call harvdata%clean() - - ! ---------------------------------------------------------------------- - ! Create dynamic land use dataset if appropriate - ! ---------------------------------------------------------------------- - - if (mksrf_fdynuse /= ' ') then - - write(6,*)'creating dynamic land use dataset' - - allocate(pctlnd_pft_dyn(ns_o)) - call mkharvest_init( ns_o, spval, harvdata, mksrf_fhrvtyp ) - - if (fdyndat == ' ') then - write(6,*)' must specify fdyndat in namelist if mksrf_fdynuse is not blank' - call abort() - end if - - ! Define dimensions and global attributes - - call mkfile(ldomain, fdyndat, harvdata, dynlanduse=.true.) - - ! Write fields other pft to dynamic land use dataset - - call domain_write(ldomain, fdyndat) - - call check_ret(nf_open(trim(fdyndat), nf_write, ncid), subname) - call check_ret(nf_set_fill (ncid, nf_nofill, omode), subname) - - call check_ret(nf_inq_varid(ncid, 'natpft', varid), subname) - call check_ret(nf_put_var_int(ncid, varid, (/(n,n=natpft_lb,natpft_ub)/)), subname) - - if (num_cft > 0) then - call check_ret(nf_inq_varid(ncid, 'cft', varid), subname) - call check_ret(nf_put_var_int(ncid, varid, (/(n,n=cft_lb,cft_ub)/)), subname) - end if - - call check_ret(nf_inq_varid(ncid, 'PFTDATA_MASK', varid), subname) - call check_ret(nf_put_var_int(ncid, varid, pftdata_mask), subname) - - call check_ret(nf_inq_varid(ncid, 'LANDFRAC_PFT', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, landfrac_pft), subname) - - ! Synchronize the disk copy of a netCDF dataset with in-memory buffers - - call check_ret(nf_sync(ncid), subname) - - ! Read in each dynamic pft landuse dataset - - nfdyn = getavu(); call opnfil (mksrf_fdynuse, nfdyn, 'f') - - pctnatpft_max = pctnatpft - pctcft_max = pctcft - - ntim = 0 - do - ! Read input pft data - - read(nfdyn, '(A195,1x,I4)', iostat=ier) string, year - if (ier /= 0) exit - ! - ! If pft fraction override is set, than intrepret string as PFT and harvesting override values - ! - if ( all_veg )then - fname = ' ' - fhrvname = ' ' - call mkpft_parse_oride(string) - call mkharvest_parse_oride(string) - write(6, '(a, i4, a)') 'PFT and harvesting values for year ', year, ' :' - write(6, '(a, a)') ' ', trim(string) - ! - ! Otherwise intrepret string as a filename with PFT and harvesting values in it - ! - else - fname = string - write(6,*)'input pft dynamic dataset for year ', year, ' is : ', trim(fname) - read(nfdyn, '(A195,1x,I4)', iostat=ier) fhrvname, year2 - if ( year2 /= year ) then - write(6,*) subname, ' error: year for harvest not equal to year for PFT files' - call abort() - end if - end if - ntim = ntim + 1 - - ! Create pctpft data at model resolution - - call mkpft(ldomain, mapfname=map_fpft, fpft=fname, & - ndiag=ndiag, pctlnd_o=pctlnd_pft_dyn, pctnatpft_o=pctnatpft, pctcft_o=pctcft ) - - ! Create harvesting data at model resolution - - call mkharvest( ldomain, mapfname=map_fharvest, datfname=fhrvname, & - ndiag=ndiag, harvdata=harvdata ) - - ! Consistency check on input land fraction - - do n = 1,ns_o - if (pctlnd_pft_dyn(n) /= pctlnd_pft(n)) then - write(6,*) subname,' error: pctlnd_pft for dynamics data = ',& - pctlnd_pft_dyn(n), ' not equal to pctlnd_pft for surface data = ',& - pctlnd_pft(n),' at n= ',n - if ( trim(fname) == ' ' )then - write(6,*) ' PFT string = ', string - else - write(6,*) ' PFT file = ', fname - end if - call abort() - end if - end do - - call change_landuse(ldomain, dynpft=.true.) - - call normalizencheck_landuse(ldomain) - - call update_max_array(pctnatpft_max,pctnatpft) - call update_max_array(pctcft_max,pctcft) - - ! Output time-varying data for current year - - call check_ret(nf_inq_varid(ncid, 'PCT_NAT_PFT', varid), subname) - call ncd_put_time_slice(ncid, varid, ntim, get_pct_p2l_array(pctnatpft)) - - call check_ret(nf_inq_varid(ncid, 'PCT_CROP', varid), subname) - call ncd_put_time_slice(ncid, varid, ntim, get_pct_l2g_array(pctcft)) - - if (num_cft > 0) then - call check_ret(nf_inq_varid(ncid, 'PCT_CFT', varid), subname) - call ncd_put_time_slice(ncid, varid, ntim, get_pct_p2l_array(pctcft)) - end if - - call harvdata%getFieldsIdx( harvind1D, harvind2D ) - do k = 1, harvdata%num1Dfields() - call check_ret(nf_inq_varid(ncid, trim(mkharvest_fieldname(harvind1D(k),constant=.false.)), varid), subname) - harvest1D => harvdata%get1DFieldPtr( harvind1D(k), output=.true. ) - call ncd_put_time_slice(ncid, varid, ntim, harvest1D) - end do - do k = 1, harvdata%num2Dfields() - call check_ret(nf_inq_varid(ncid, trim(mkharvest_fieldname(harvind2D(k),constant=.false.)), varid), subname) - harvest2D => harvdata%get2DFieldPtr( harvind2D(k), output=.true. ) - call ncd_put_time_slice(ncid, varid, ntim, harvest2D) - end do - deallocate( harvind1D, harvind2D ) - - call check_ret(nf_inq_varid(ncid, 'YEAR', varid), subname) - call check_ret(nf_put_vara_int(ncid, varid, ntim, 1, year), subname) - - call check_ret(nf_inq_varid(ncid, 'time', varid), subname) - call check_ret(nf_put_vara_int(ncid, varid, ntim, 1, year), subname) - - call check_ret(nf_inq_varid(ncid, 'input_pftdata_filename', varid), subname) - call check_ret(nf_put_vara_text(ncid, varid, (/ 1, ntim /), (/ len_trim(string), 1 /), trim(string) ), subname) - - ! Synchronize the disk copy of a netCDF dataset with in-memory buffers - - call check_ret(nf_sync(ncid), subname) - - end do ! end of read loop - - call check_ret(nf_inq_varid(ncid, 'PCT_NAT_PFT_MAX', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, get_pct_p2l_array(pctnatpft_max)), subname) - - call check_ret(nf_inq_varid(ncid, 'PCT_CROP_MAX', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, get_pct_l2g_array(pctcft_max)), subname) - - if (num_cft > 0) then - call check_ret(nf_inq_varid(ncid, 'PCT_CFT_MAX', varid), subname) - call check_ret(nf_put_var_double(ncid, varid, get_pct_p2l_array(pctcft_max)), subname) - end if - - call check_ret(nf_close(ncid), subname) - - end if ! end of if-create dynamic landust dataset - - ! ---------------------------------------------------------------------- - ! Close diagnostic dataset - ! ---------------------------------------------------------------------- - - close (ndiag) - write (6,*) - write (6,*) 'Surface data output file = ',trim(fsurdat) - write (6,*) ' This file contains the land model surface data' - write (6,*) 'Diagnostic log file = ',trim(fsurlog) - write (6,*) ' See this file for a summary of the dataset' - write (6,*) - - write (6,*) 'Successfully created surface dataset' - -!----------------------------------------------------------------------- -contains -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: change_landuse -! -! !INTERFACE: -subroutine change_landuse( ldomain, dynpft ) -! -! !DESCRIPTION: -! -! Do landuse changes such as for the poles, etc. -! -! !USES: - implicit none -! -! !ARGUMENTS: - type(domain_type) :: ldomain - logical, intent(in) :: dynpft ! if part of the dynpft section of code - -! -! !REVISION HISTORY: -! 9/10/09: Erik Kluzek spin off subroutine from original embedded code -! -!EOP -! -! !LOCAL VARIABLES: - integer :: n,ns_o ! indices - character(len=32) :: subname = 'change_landuse' ! subroutine name -!----------------------------------------------------------------------- - - ns_o = ldomain%ns - do n = 1,ns_o - - ! If have pole points on grid - set south pole to glacier - ! north pole is assumed as non-land - - if (abs((ldomain%latc(n) - 90._r8)) < 1.e-6_r8) then - pctlak(n) = 0._r8 - pctwet(n) = 0._r8 - pcturb(n) = 0._r8 - pctgla(n) = 100._r8 - call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) - if ( .not. dynpft )then - organic(n,:) = 0._r8 - ef1_btr(n) = 0._r8 - ef1_fet(n) = 0._r8 - ef1_fdt(n) = 0._r8 - ef1_shr(n) = 0._r8 - ef1_grs(n) = 0._r8 - ef1_crp(n) = 0._r8 - end if - end if - - end do - -end subroutine change_landuse - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: normalizencheck_landuse -! -! !INTERFACE: -subroutine normalizencheck_landuse(ldomain) -! -! !DESCRIPTION: -! -! Normalize land use and make sure things add up to 100% as well as -! checking that things are as they should be. -! -! Precondition: pctlak + pctwet + pcturb + pctgla <= 100 (within roundoff) -! -! !USES: - use mkpftConstantsMod , only : baregroundindex - use mkpftUtilsMod , only : adjust_total_veg_area - implicit none -! !ARGUMENTS: - type(domain_type) :: ldomain -! -! !REVISION HISTORY: -! 9/10/09: Erik Kluzek spin off subroutine from original embedded code -! -!EOP -! -! !LOCAL VARIABLES: - integer :: m,k,n,ns_o ! indices - integer :: nsmall ! number of small PFT values for a single check - integer :: nsmall_tot ! total number of small PFT values in all grid cells - real(r8) :: suma ! sum for error check - real(r8) :: suma2 ! another sum for error check - real(r8) :: new_total_veg_pct ! new % veg (% of grid cell, total of natural veg & crop) - real(r8) :: bare_pct_p2g ! % of bare soil, as % of grid cell - real(r8) :: bare_urb_diff ! difference between bare soil and urban % - real(r8) :: pcturb_excess ! excess urban % not accounted for by bare soil - real(r8) :: sum8, sum8a ! sum for error check - real(r4) :: sum4a ! sum for error check - real(r8), parameter :: tol_loose = 1.e-4_r8 ! tolerance for some 'loose' error checks - real(r8), parameter :: toosmallPFT = 1.e-10_r8 ! tolerance for PFT's to ignore - character(len=32) :: subname = 'normalizencheck_landuse' ! subroutine name -!----------------------------------------------------------------------- - - ! ------------------------------------------------------------------------ - ! Normalize vegetated area so that vegetated + special area is 100% - ! ------------------------------------------------------------------------ - - ns_o = ldomain%ns - do n = 1,ns_o - - ! Check preconditions - if ( pctlak(n) < 0.0_r8 )then - write(6,*) subname, ' ERROR: pctlak is negative!' - write(6,*) 'n, pctlak = ', n, pctlak(n) - call abort() - end if - if ( pctwet(n) < 0.0_r8 )then - write(6,*) subname, ' ERROR: pctwet is negative!' - write(6,*) 'n, pctwet = ', n, pctwet(n) - call abort() - end if - if ( pcturb(n) < 0.0_r8 )then - write(6,*) subname, ' ERROR: pcturb is negative!' - write(6,*) 'n, pcturb = ', n, pcturb(n) - call abort() - end if - if ( pctgla(n) < 0.0_r8 )then - write(6,*) subname, ' ERROR: pctgla is negative!' - write(6,*) 'n, pctgla = ', n, pctgla(n) - call abort() - end if - - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - if (suma > (100._r8 + tol_loose)) then - write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla must be' - write(6,*) '<= 100% before calling this subroutine' - write(6,*) 'n, pctlak, pctwet, pcturb, pctgla = ', & - n, pctlak(n), pctwet(n), pcturb(n), pctgla(n) - call abort() - end if - - ! First normalize vegetated (natural veg + crop) cover so that the total of - ! (vegetated + (special excluding urban)) is 100%. We'll deal with urban later. - ! - ! Note that, in practice, the total area of natural veg + crop is typically 100% - ! going into this routine. However, the following code does NOT rely on this, and - ! will work properly regardless of the initial area of natural veg + crop (even if - ! that initial area is 0%). - - suma = pctlak(n)+pctwet(n)+pctgla(n) - new_total_veg_pct = 100._r8 - suma - ! correct for rounding error: - new_total_veg_pct = max(new_total_veg_pct, 0._r8) - - call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) - - ! Make sure we did the above rescaling correctly - - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - if (abs(suma - 100._r8) > tol_loose) then - write(6,*) subname, ' ERROR in rescaling veg based on (special excluding urban' - write(6,*) 'suma = ', suma - call abort() - end if - - ! Now decrease the vegetated area to account for urban area. Urban needs to be - ! handled specially because we replace bare soil preferentially with urban, rather - ! than rescaling all PFTs equally. - - if (pcturb(n) > 0._r8) then - - ! Replace bare soil preferentially with urban - bare_pct_p2g = pctnatpft(n)%get_one_pct_p2g(baregroundindex) - bare_urb_diff = bare_pct_p2g - pcturb(n) - bare_pct_p2g = max(0._r8, bare_urb_diff) - call pctnatpft(n)%set_one_pct_p2g(baregroundindex, bare_pct_p2g) - pcturb_excess = abs(min(0._r8,bare_urb_diff)) - - ! For any urban not accounted for by bare soil, replace other PFTs - ! proportionally - if (pcturb_excess > 0._r8) then - ! Note that, in this case, we will have already reduced bare ground to 0% - - new_total_veg_pct = pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - pcturb_excess - if (new_total_veg_pct < 0._r8) then - if (abs(new_total_veg_pct) < tol_loose) then - ! only slightly less than 0; correct it - new_total_veg_pct = 0._r8 - else - write(6,*) subname, ' ERROR: trying to replace veg with urban,' - write(6,*) 'but pcturb_excess exceeds current vegetation percent' - call abort() - end if - end if - - call adjust_total_veg_area(new_total_veg_pct, pctnatpft=pctnatpft(n), pctcft=pctcft(n)) - end if - - end if ! pcturb(n) > 0 - - ! Confirm that we have done the rescaling correctly: now the sum of all landunits - ! should be 100% - suma = pctlak(n)+pctwet(n)+pctgla(n)+pcturb(n) - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - if (abs(suma - 100._r8) > tol_loose) then - write(6,*) subname, ' ERROR: landunits do not sum to 100%' - write(6,*) 'n, suma, pctlak, pctwet, pctgla, pcturb, pctnatveg, pctcrop = ' - write(6,*) n, suma, pctlak(n), pctwet(n), pctgla(n), pcturb(n), & - pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() - call abort() - end if - - end do - - ! ------------------------------------------------------------------------ - ! Do other corrections and error checks - ! ------------------------------------------------------------------------ - - nsmall_tot = 0 - - do n = 1,ns_o - - ! If the coverage of any PFT or CFT is too small at the gridcell level, set its - ! % cover to 0, then renormalize everything else as needed - call pctnatpft(n)%remove_small_cover(toosmallPFT, nsmall) - nsmall_tot = nsmall_tot + nsmall - call pctcft(n)%remove_small_cover(toosmallPFT, nsmall) - nsmall_tot = nsmall_tot + nsmall - - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - if ( abs(suma - 100.0_r8) > 2.0*epsilon(suma) )then - pctlak(n) = pctlak(n) * 100._r8/suma - pctwet(n) = pctwet(n) * 100._r8/suma - pcturb(n) = pcturb(n) * 100._r8/suma - pctgla(n) = pctgla(n) * 100._r8/suma - call pctnatpft(n)%set_pct_l2g(pctnatpft(n)%get_pct_l2g() * 100._r8/suma) - call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8/suma) - end if - - ! Roundoff error fix - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - suma2 = pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - if ( (suma < 100._r8 .and. suma > (100._r8 - 1.e-6_r8)) .or. & - (suma2 > 0.0_r8 .and. suma2 < 1.e-6_r8) ) then - write (6,*) 'Special land units near 100%, but not quite for n,suma =',n,suma - write (6,*) 'Adjusting special land units to 100%' - if (pctlak(n) >= 25._r8) then - pctlak(n) = 100._r8 - (pctwet(n) + pcturb(n) + pctgla(n)) - else if (pctwet(n) >= 25._r8) then - pctwet(n) = 100._r8 - (pctlak(n) + pcturb(n) + pctgla(n)) - else if (pcturb(n) >= 25._r8) then - pcturb(n) = 100._r8 - (pctlak(n) + pctwet(n) + pctgla(n)) - else if (pctgla(n) >= 25._r8) then - pctgla(n) = 100._r8 - (pctlak(n) + pctwet(n) + pcturb(n)) - else - write (6,*) subname, 'Error: sum of special land units nearly 100% but none is >= 25% at ', & - 'n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),pctnatveg(n),pctcrop(n),suma = ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& - pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(),suma - call abort() - end if - call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) - end if - if ( any(pctnatpft(n)%get_pct_p2g() > 0.0_r8 .and. pctnatpft(n)%get_pct_p2g() < toosmallPFT ) .or. & - any(pctcft(n)%get_pct_p2g() > 0.0_r8 .and. pctcft(n)%get_pct_p2g() < toosmallPFT )) then - write (6,*) 'pctnatpft or pctcft is small at n=', n - write (6,*) 'pctnatpft%pct_p2l = ', pctnatpft(n)%get_pct_p2l() - write (6,*) 'pctcft%pct_p2l = ', pctcft(n)%get_pct_p2l() - write (6,*) 'pctnatpft%pct_l2g = ', pctnatpft(n)%get_pct_l2g() - write (6,*) 'pctcft%pct_l2g = ', pctcft(n)%get_pct_l2g() - call abort() - end if - - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) - if (suma < 100._r8-epsilon(suma) .and. suma > (100._r8 - 4._r8*epsilon(suma))) then - write (6,*) subname, 'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& - pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() - call abort() - end if - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() - if ( abs(suma-100._r8) > 1.e-10_r8) then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb, pctgla, pctnatveg and pctcrop is NOT equal to 100' - write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,sum= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& - pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), suma - call abort() - end if - - end do - - ! Check that when pctnatveg+pctcrop identically zero, sum of special landunits is identically 100% - - if ( .not. outnc_double )then - do n = 1,ns_o - sum8 = real(pctlak(n),r4) - sum8 = sum8 + real(pctwet(n),r4) - sum8 = sum8 + real(pcturb(n),r4) - sum8 = sum8 + real(pctgla(n),r4) - sum4a = real(pctnatpft(n)%get_pct_l2g(),r4) - sum4a = sum4a + real(pctcft(n)%get_pct_l2g(),r4) - if ( sum4a==0.0_r4 .and. sum8 < 100._r4-2._r4*epsilon(sum4a) )then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 - write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n), & - pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g() - call abort() - end if - end do - else - do n = 1,ns_o - sum8 = pctlak(n) - sum8 = sum8 + pctwet(n) - sum8 = sum8 + pcturb(n) - sum8 = sum8 + pctgla(n) - sum8a = pctnatpft(n)%get_pct_l2g() - sum8a = sum8a + pctcft(n)%get_pct_l2g() - if ( sum8a==0._r8 .and. sum8 < (100._r8-4._r8*epsilon(sum8)) )then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & - 'pcturb, pctgla is < 100% when pctnatveg+pctcrop==0 sum = ', sum8 - write (6,*) 'Total error, error/epsilon = ',100._r8-sum8, ((100._r8-sum8)/epsilon(sum8)) - write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,epsilon= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& - pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), epsilon(sum8) - call abort() - end if - end do - end if - - ! Make sure that there is no vegetation outside the pft mask - do n = 1,ns_o - if (pftdata_mask(n) == 0 .and. (pctnatpft(n)%get_pct_l2g() > 0 .or. pctcft(n)%get_pct_l2g() > 0)) then - write (6,*)'vegetation found outside the pft mask at n=',n - write (6,*)'pctnatveg,pctcrop=', pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() - call abort() - end if - end do - - ! Make sure that sums at the landunit level all add to 100% - ! (Note that we don't check pctglcmec here, because it isn't computed at the point - ! that this subroutine is called -- but the check of sum(pctglcmec) is done in - ! mkglcmecMod) - ! (Also note that we don't need to check pctnatpft or pctcft, because a similar check - ! is done internally by the pct_pft_type routines.) - do n = 1,ns_o - if (abs(sum(urbn_classes(n,:)) - 100._r8) > 1.e-12_r8) then - write(6,*) 'sum(urbn_classes(n,:)) != 100: ', n, sum(urbn_classes(n,:)) - call abort() - end if - end do - - if ( nsmall_tot > 0 )then - write (6,*)'number of small pft = ', nsmall_tot - end if - -end subroutine normalizencheck_landuse - -end program mksurfdat diff --git a/tools/mksurfdata_map/src/mktopostatsMod.F90 b/tools/mksurfdata_map/src/mktopostatsMod.F90 deleted file mode 100644 index 7e102d9bcf..0000000000 --- a/tools/mksurfdata_map/src/mktopostatsMod.F90 +++ /dev/null @@ -1,183 +0,0 @@ -module mktopostatsMod - -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mktopostatsMod -! -! !DESCRIPTION: -! make various topography statistics -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -!----------------------------------------------------------------------- -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - use mkdomainMod , only : domain_checksame - - implicit none - - private - -! !PUBLIC MEMBER FUNCTIONS: - public mktopostats ! make topo stddev & mean slope -! -!EOP -!=============================================================== -contains -!=============================================================== - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mktopostats -! -! !INTERFACE: -subroutine mktopostats(ldomain, mapfname, datfname, ndiag, topo_stddev_o, slope_o, std_elev) -! -! !DESCRIPTION: -! make various topography statistics -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_continuous, output_diagnostics_continuous_outonly - use mkchecksMod, only : min_bad, max_bad -! -! !ARGUMENTS: - - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - real(r8) , intent(in) :: std_elev ! standard deviation of elevation (m) to use when not using input file - real(r8) , intent(out):: topo_stddev_o(:) ! output grid: standard deviation of elevation (m) - real(r8) , intent(out):: slope_o(:) ! output grid: slope (degrees) -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: data_i(:) ! data on input grid - integer :: ncid,varid ! input netCDF id's - integer :: ier ! error status - logical :: bypass_reading ! If should bypass reading dataset and just use a global value - - real(r8), parameter :: min_valid_topo_stddev = 0._r8 - - real(r8), parameter :: min_valid_slope = 0._r8 - real(r8), parameter :: max_valid_slope = 90._r8 - - character(len=32) :: subname = 'mktopostats' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make Topography statistics.....' - if ( std_elev >= 0.0_r8 )then - bypass_reading = .true. - write (6,*) ' By pass the reading and just use global values' - else - bypass_reading = .false. - end if - call shr_sys_flush(6) - - ! ----------------------------------------------------------------- - ! Read domain and mapping information, check for consistency - ! ----------------------------------------------------------------- - - if ( .not. bypass_reading )then - call domain_read(tdomain,datfname) - - call gridmap_mapread(tgridmap, mapfname ) - - call gridmap_check( tgridmap, tgridmap%frac_src, tgridmap%frac_dst, subname ) - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! ----------------------------------------------------------------- - ! Open input file, allocate memory for input data - ! ----------------------------------------------------------------- - - write(6,*)'Open Topography file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - - allocate(data_i(tdomain%ns), stat=ier) - if (ier/=0) call abort() - - ! ----------------------------------------------------------------- - ! Make topography standard deviation - ! ----------------------------------------------------------------- - - call check_ret(nf_inq_varid (ncid, 'ELEVATION', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - call gridmap_areastddev(tgridmap, data_i, topo_stddev_o, nodata=0._r8) - - call output_diagnostics_continuous_outonly(topo_stddev_o, tgridmap, "Topo Std Dev", "m", ndiag) - else - write (6,*) ' Set std deviation of topography to ', std_elev - topo_stddev_o = std_elev - end if - - ! Check validity of output data - if (min_bad(topo_stddev_o, min_valid_topo_stddev, 'topo_stddev')) then - call abort() - end if - - - ! ----------------------------------------------------------------- - ! Regrid slope - ! ----------------------------------------------------------------- - - if ( .not. bypass_reading )then - call check_ret(nf_inq_varid (ncid, 'SLOPE', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, data_i), subname) - - ! Subr. gridmap_areaave_no_srcmask should NOT be used in general. We have - ! kept it to support the rare raw data files for which we have masking on - ! the mapping file and, therefore, we do not explicitly pass the src_mask - ! as an argument. In general, users are advised to use subroutine - ! gridmap_areaave_srcmask. - call gridmap_areaave_no_srcmask(tgridmap, data_i, slope_o, nodata=0._r8) - - call output_diagnostics_continuous(data_i, slope_o, tgridmap, "Slope", "degrees", ndiag, tdomain%mask, tgridmap%frac_dst) - else - write (6,*) ' Set slope of topography to ', 0.0_r8 - slope_o = 0.0_r8 - end if - ! Check validity of output data - if (min_bad(slope_o, min_valid_slope, 'slope') .or. & - max_bad(slope_o, max_valid_slope, 'slope')) then - call abort() - end if - - - ! ----------------------------------------------------------------- - ! Close files and deallocate dynamic memory - ! ----------------------------------------------------------------- - - if ( .not. bypass_reading )then - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (data_i) - end if - - write (6,*) 'Successfully made Topography statistics' - write (6,*) - call shr_sys_flush(6) - -end subroutine mktopostats - - -end module mktopostatsMod diff --git a/tools/mksurfdata_map/src/mkurbanparCommonMod.F90 b/tools/mksurfdata_map/src/mkurbanparCommonMod.F90 deleted file mode 100644 index ab738ea03c..0000000000 --- a/tools/mksurfdata_map/src/mkurbanparCommonMod.F90 +++ /dev/null @@ -1,365 +0,0 @@ -module mkurbanparCommonMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkurbanparCommon -! -! !DESCRIPTION: -! Common routines for making urban parameter data, independent of the method used for -! making the urban parameters (e.g., averages, dominant type, etc.) -! -! (WJS 4-18-12: In the past, this contained routines shared between mkurbanparDomMod and -! mkurbanparAvgMod; now there is just a single module, mkurbanparMod, but I am keeping the -! separate mkurbanparCommonMod in case a similar split comes back in the future. However, -! if such a split seems unlikely in the future, these routines could be moved back into -! mkurbanparMod.) -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -!----------------------------------------------------------------------- -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - implicit none - - private - -! !PUBLIC MEMBER FUNCTIONS: - public :: mkurban_pct ! Make output urban %, given input urban % - public :: mkurban_pct_diagnostics ! print diagnostics related to pct urban - public :: mkelev ! Get elevation to reduce urban for high elevation areas -! -! !PUBLIC DATA MEMBERS: -! - real(r8), parameter :: MIN_DENS = 0.1_r8 ! minimum urban density (% of grid cell) - below this value, urban % is set to 0 - - public :: MIN_DENS -! -!EOP - -contains - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkurban_pct -! -! !INTERFACE: -subroutine mkurban_pct(ldomain, tdomain, tgridmap, urbn_i, urbn_o, frac_dst) -! -! !DESCRIPTION: -! make percent urban on output grid, given percent urban on input grid -! -! This assumes that we're neither using all_urban or zero_out -! -! -! !USES: - use mkdomainMod , only : domain_type, domain_checksame - use mkgridmapMod - use mkvarctl , only : mksrf_gridtype -! -! !ARGUMENTS: - implicit none - type(domain_type) , intent(in) :: ldomain - type(domain_type) , intent(in) :: tdomain ! local domain - type(gridmap_type), intent(in) :: tgridmap ! local gridmap - real(r8) , intent(in) :: urbn_i(:) ! input grid: percent urban - real(r8) , intent(in) :: frac_dst(:) ! output fractions - real(r8) , intent(out):: urbn_o(:) ! output grid: percent urban -! -! !REVISION HISTORY: -! Author: Bill Sacks -! (Moved from mkurbanparMod Feb, 2012) -! -! -! !LOCAL VARIABLES: -!EOP - integer :: ier ! error status - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldi ! global sum of dummy input fld - real(r8) :: sum_fldo ! global sum of dummy output fld - integer :: ni,no ! indices - real(r8) :: relerr = 0.00001_r8 ! max error: sum overlap wts ne 1 - character(len=*), parameter :: subname = 'mkurban_pct' -!----------------------------------------------------------------------- - - ! Error checks for array size consistencies - - if (size(urbn_i) /= tdomain%ns .or. & - size(urbn_o) /= ldomain%ns) then - write(6,*) subname//' ERROR: array size inconsistencies' - write(6,*) 'size(urbn_i) = ', size(urbn_i) - write(6,*) 'tdomain%ns = ', tdomain%ns - write(6,*) 'size(urbn_o) = ', size(urbn_o) - write(6,*) 'ldomain%ns = ', ldomain%ns - call abort() - end if - if (size(frac_dst) /= ldomain%ns) then - write(6,*) subname//' ERROR: array size inconsistencies' - write(6,*) 'size(frac_dst) = ', size(frac_dst) - write(6,*) 'ldomain%ns = ', ldomain%ns - call abort() - end if - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Determine urbn_o on ouput grid: - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. - - call gridmap_areaave_srcmask(tgridmap, urbn_i, urbn_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check for conservation - - do no = 1, ldomain%ns - if ((urbn_o(no)) > 100.000001_r8) then - write (6,*) 'MKURBAN error: urban = ',urbn_o(no), & - ' greater than 100.000001 for column, row = ',no - call abort() - end if - enddo - - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - - allocate(mask_r8(tdomain%ns), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - ! (Error check2 in mkurban_pct_diagnostics, which should be called separately) - - deallocate (mask_r8) - -end subroutine mkurban_pct -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkurban_pct_diagnostics -! -! !INTERFACE: -subroutine mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, urbn_i, urbn_o, ndiag, dens_class, frac_dst) -! -! !DESCRIPTION: -! print diagnostics related to pct urban -! -! This is intended to be called after mkurban_pct, but is split out into a separate -! routine so that modifications to urbn_o can be made in between the two calls (e.g., -! setting urbn_o to 0 wherever it is less than a certain threshold; the rules for doing -! this can't always be applied inline in mkurban_pct). -! -! !USES: - use mkdomainMod , only : domain_type - use mkgridmapMod, only : gridmap_type - use mkvarpar -! -! !ARGUMENTS: - implicit none - type(domain_type) , intent(in) :: ldomain - type(domain_type) , intent(in) :: tdomain ! local domain - type(gridmap_type), intent(in) :: tgridmap ! local gridmap - real(r8) , intent(in) :: urbn_i(:) ! input grid: percent urban - real(r8) , intent(in) :: urbn_o(:) ! output grid: percent urban - real(r8) , intent(in) :: frac_dst(:) ! output fractions - integer , intent(in) :: ndiag ! unit number for diag out - - integer , intent(in), optional :: dens_class ! density class -! -! !REVISION HISTORY: -! Author: Bill Sacks -! (Moved from mkurbanparMod Feb, 2012) -! -! -! !LOCAL VARIABLES: -!EOP - real(r8) :: gurbn_i ! input grid: global urbn - real(r8) :: garea_i ! input grid: global area - real(r8) :: gurbn_o ! output grid: global urbn - real(r8) :: garea_o ! output grid: global area - integer :: ni,no,k ! indices - character(len=*), parameter :: subname = 'mkurban_pct_diagnostics' -!----------------------------------------------------------------------- - - ! Error check inputs - if (size(frac_dst) /= ldomain%ns) then - write(6,*) subname//' ERROR: array size inconsistencies' - write(6,*) 'size(frac_dst) = ', size(frac_dst) - write(6,*) 'ldomain%ns = ', ldomain%ns - call abort() - end if - - ! ----------------------------------------------------------------- - ! Error check2 - ! Compare global areas on input and output grids - ! ----------------------------------------------------------------- - - ! Input grid - - gurbn_i = 0._r8 - garea_i = 0._r8 - - do ni = 1, tdomain%ns - garea_i = garea_i + tgridmap%area_src(ni)*re**2 - gurbn_i = gurbn_i + urbn_i(ni)*(tgridmap%area_src(ni)/100._r8)*& - tdomain%mask(ni)*re**2 - end do - - ! Output grid - - gurbn_o = 0._r8 - garea_o = 0._r8 - - do no = 1, ldomain%ns - garea_o = garea_o + tgridmap%area_dst(no)*re**2 - gurbn_o = gurbn_o + urbn_o(no)* (tgridmap%area_dst(no)/100._r8)*& - frac_dst(no)*re**2 - end do - - ! Diagnostic output - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('=',k=1,70) - if (present(dens_class)) then - write (ndiag,'(1x,a,i0)') 'Urban Output -- class ', dens_class - else - write (ndiag,'(1x,a)') 'Urban Output' - end if - write (ndiag,'(1x,70a1)') ('=',k=1,70) - - write (ndiag,*) - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,2001) -2001 format (1x,'surface type input grid area output grid area'/ & - 1x,' 10**6 km**2 10**6 km**2 ') - write (ndiag,'(1x,70a1)') ('.',k=1,70) - write (ndiag,*) - write (ndiag,2003) gurbn_i*1.e-06,gurbn_o*1.e-06 - write (ndiag,2004) garea_i*1.e-06,garea_o*1.e-06 -2002 format (1x,'urban ',f14.3,f17.3) -2003 format (1x,'urban ',f14.3,f22.8) -2004 format (1x,'all surface ',f14.3,f17.3) - -end subroutine mkurban_pct_diagnostics -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkelev -! -! !INTERFACE: -subroutine mkelev(ldomain, mapfname, datfname, varname, ndiag, elev_o) -! -! !DESCRIPTION: -! Make elevation data -! -! !USES: - use mkdomainMod , only : domain_type, domain_clean, domain_read, domain_checksame - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_continuous -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - character(len=*) , intent(in) :: varname ! topo variable name - real(r8) , intent(out):: elev_o(:) ! output elevation data -! -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Keith Oleson -! -! -! !LOCAL VARIABLES: -!EOP - type(domain_type) :: tdomain ! local domain - type(gridmap_type) :: tgridmap ! local gridmap - - real(r8), allocatable :: elev_i(:) ! canyon_height to width ratio in - real(r8), allocatable :: frac_dst(:) ! output fractions - integer :: ns_i,ns_o ! indices - integer :: k,l,n,m,ni ! indices - integer :: ncidi,dimid,varid ! input netCDF id's - integer :: ier ! error status - character(len=256) :: name ! name of attribute - character(len=256) :: unit ! units of attribute - character(len= 32) :: subname = 'mkelev' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make elevation .....' - call shr_sys_flush(6) - - ns_o = ldomain%ns - - ! ----------------------------------------------------------------- - ! Read input file - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - - ns_i = tdomain%ns - allocate(elev_i(ns_i), stat=ier) - allocate(frac_dst(ns_o), stat=ier) - if (ier /= 0) then - write(6,*)'mkelev allocation error'; call abort() - end if - - write (6,*) 'Open elevation file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncidi), subname) - call check_ret(nf_inq_varid (ncidi, trim(varname), varid), subname) - call check_ret(nf_get_var_double (ncidi, varid, elev_i), subname) - call check_ret(nf_close(ncidi), subname) - - ! Read topo elev dataset with unit mask everywhere - - call gridmap_mapread(tgridmap, mapfname) - - ! Error checks for domain and map consistencies - ! Note that the topo dataset has no landmask - so a unit landmask is assumed - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Determine elev_o on output grid - - elev_o(:) = 0. - - call gridmap_areaave_srcmask(tgridmap, elev_i, elev_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - call output_diagnostics_continuous(elev_i, elev_o, tgridmap, "Urban elev variable", "m", ndiag, tdomain%mask, frac_dst) - - - ! Deallocate dynamic memory - - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (elev_i) - deallocate (frac_dst) - - write (6,*) 'Successfully made elevation' - write (6,*) - call shr_sys_flush(6) - -end subroutine mkelev - -!----------------------------------------------------------------------- - -end module mkurbanparCommonMod diff --git a/tools/mksurfdata_map/src/mkurbanparMod.F90 b/tools/mksurfdata_map/src/mkurbanparMod.F90 deleted file mode 100644 index 49ce95dd07..0000000000 --- a/tools/mksurfdata_map/src/mkurbanparMod.F90 +++ /dev/null @@ -1,759 +0,0 @@ -module mkurbanparMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkurbanpar -! -! !DESCRIPTION: -! Make Urban Parameter data -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -!----------------------------------------------------------------------- -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - use mkvarctl, only : ispval - implicit none - - private - -! !PUBLIC MEMBER FUNCTIONS: - public :: mkurbanInit - public :: mkurban - public :: mkurbanpar - - ! The following could be private, but because there are associated test routines in a - ! separate module, it needs to be public - public :: normalize_urbn_by_tot - -! !PUBLIC DATA MEMBERS: - integer :: numurbl ! number of urban classes - integer :: nlevurb = ispval ! number of urban layers - - public :: numurbl - public :: nlevurb - -! !PRIVATE DATA MEMBERS: - ! flag to indicate nodata for index variables in output file: - integer, parameter :: index_nodata = 0 - character(len=*), parameter :: modname = 'mkurbanparMod' - - private :: index_nodata - private :: modname - -!EOP - -contains - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkurbanInit -! -! !INTERFACE: -subroutine mkurbanInit(datfname) -! -! !DESCRIPTION: -! Initialize variables needed for urban -! -! !USES: - use mkncdio -! -! !ARGUMENTS: - implicit none - character(len=*), intent(in) :: datfname ! input data file name (same as file used in mkurban) -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: - integer :: ncid,dimid ! input netCDF id's - - character(len=*), parameter :: subname = 'mkurbanInit' -!EOP -!----------------------------------------------------------------------- - - ! Set numurbl - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_dimid (ncid, 'density_class', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, numurbl), subname) - call check_ret(nf_inq_dimid (ncid, 'nlevurb', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, nlevurb), subname) - call check_ret(nf_close(ncid), subname) - -end subroutine mkurbanInit -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkurban -! -! !INTERFACE: -subroutine mkurban(ldomain, mapfname, datfname, ndiag, zero_out, & - urbn_o, urbn_classes_o, region_o) -! -! !DESCRIPTION: -! make total percent urban, breakdown into urban classes, and region ID on the output grid -! -! urbn_classes_o(n, i) gives the percent of the urban area in grid cell n that is in class #i. -! This is normalized so that sum(urbn_classes_o(n,:)) = 100 for all n, even for grid -! cells where urbn_o(n) = 0 (in the case where urbn_o(n) = 0, we come up with an -! arbitrary assignment of urban into the different classes). -! -! See comments under the normalize_urbn_by_tot subroutine for how urbn_classes_o is -! determined when the total % urban is 0, according to the input data. Note that this -! also applies when all_urban=.true., for points that have 0 urban according to the input -! data. -! -! TODO (WJS 6-12-14): I think this could be rewritten slightly to take advantage of the -! new mkpctPftTypeMod (which should then be renamed to something more general; or maybe -! better, in terms of maintaining helpful abstractions, there could be a new type to -! handle urban, and both that and pct_pft_type could be build on a single set of shared -! code - either as a single base class or through a "has-a" mechanism). This would allow -! us to combine urbn_o and urbn_classes_o into a single derived type variable. I think -! this would also replace the use of normalize_classes_by_gcell, and maybe some other -! urban-specific code. -! -! !USES: - use mkdomainMod , only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkindexmapMod, only : get_dominant_indices - use mkurbanparCommonMod, only : mkurban_pct, mkurban_pct_diagnostics, MIN_DENS - use mkutilsMod , only : normalize_classes_by_gcell - use mkvarctl , only : all_urban - use mkvarpar - use mkncdio - use mkdiagnosticsMod, only : output_diagnostics_index -! -! !ARGUMENTS: - implicit none - type(domain_type), intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diag out - logical , intent(in) :: zero_out ! if should zero urban out - real(r8) , intent(out):: urbn_o(:) ! output grid: total % urban - real(r8) , intent(out):: urbn_classes_o(:,:) ! output grid: breakdown of total urban into each class - ! (dimensions: (ldomain%ns, numurbl)) - integer , intent(out):: region_o(:) ! output grid: region ID -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - type(domain_type) :: tdomain ! local domain - type(gridmap_type) :: tgridmap ! local gridmap - real(r8), allocatable :: urbn_classes_gcell_i(:,:) ! input grid: percent urban in each density class - ! (% of total grid cell area) - real(r8), allocatable :: urbn_classes_gcell_o(:,:) ! output grid: percent urban in each density class - real(r8), allocatable :: frac_dst(:) ! output fractions - ! (% of total grid cell area) - integer , allocatable :: region_i(:) ! input grid: region ID - integer :: ni,no,ns,k ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: dimlen ! netCDF dimension length - integer :: max_region ! maximum region index - integer :: ier ! error status - - character(len=*), parameter :: subname = 'mkurban' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make %urban .....' - - ! Obtain input grid info, read local fields - - call gridmap_mapread(tgridmap, mapfname) - call domain_read(tdomain, datfname) - - ns = tdomain%ns - - allocate(urbn_classes_gcell_i(ns, numurbl), & - urbn_classes_gcell_o(ldomain%ns, numurbl), & - frac_dst(ldomain%ns), & - stat=ier) - if (ier/=0) call abort() - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - write (6,*) 'Open urban file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'PCT_URBAN', varid), subname) - call check_ret(nf_get_var_double (ncid, varid, urbn_classes_gcell_i), subname) - - ! Determine % urban by density class on the output grid - do k = 1, numurbl - call mkurban_pct(ldomain, tdomain, tgridmap, urbn_classes_gcell_i(:,k), urbn_classes_gcell_o(:,k), frac_dst) - end do - - ! Determine total % urban - do no = 1, ldomain%ns - urbn_o(no) = sum(urbn_classes_gcell_o(no,:)) - end do - - call normalize_urbn_by_tot(urbn_classes_gcell_o, urbn_o, urbn_classes_o) - - ! Handle special cases - - ! Note that, for all these adjustments of total urban %, we do not change anything - ! about the breakdown into the different urban classes. In particular: when urbn_o is - ! set to 0 for a point, the breakdown into the different urban classes is maintained - ! as it was before. - if (all_urban) then - urbn_o(:) = 100._r8 - else if (zero_out) then - urbn_o(:) = 0._r8 - else - ! Set points to 0% if they fall below a given threshold - do no = 1, ldomain%ns - if (urbn_o(no) < MIN_DENS) then - urbn_o(no) = 0._r8 - end if - end do - end if - - ! Print diagnostics - ! First, recompute urbn_classes_gcell_o, based on any changes we have made to urbn_o - ! while handling special cases - call normalize_classes_by_gcell(urbn_classes_o, urbn_o, urbn_classes_gcell_o) - do k = 1, numurbl - call mkurban_pct_diagnostics(ldomain, tdomain, tgridmap, & - urbn_classes_gcell_i(:,k), urbn_classes_gcell_o(:,k), & - ndiag, dens_class=k, frac_dst=frac_dst) - end do - - write (6,*) 'Successfully made %urban' - - - write(6,*) 'Attempting to make urban region .....' - - ! Read in region field - ! Note: we do this here, rather than with the rest of the reads above, because we - ! expect the input urban fields to be large, so we're just reading the fields as - ! they're needed to try to avoid unnecessary memory paging - - allocate(region_i(ns), stat=ier) - if (ier/=0) call abort() - call check_ret(nf_inq_varid (ncid, 'REGION_ID', varid), subname) - call check_ret(nf_get_var_int (ncid, varid, region_i), subname) - - ! Determine max region value, and make sure it doesn't exceed bounds of the lookup tables. - ! - ! (Note: this check assumes that region_i=1 refers to region(1), region_i=2 refers to - ! region(2), etc. The alternative would be to use a coordinate variable associated with - ! the region dimension of the lookup table, which could result in an arbitrary mapping - ! between region values and the indices of the lookup table; however, this use of - ! coordinate variables currently isn't supported by lookup_2d_netcdf [as of 2-8-12].) - - max_region = maxval(region_i) - call check_ret(nf_inq_dimid (ncid, 'region', dimid), subname) - call check_ret(nf_inq_dimlen (ncid, dimid, dimlen), subname) - if (max_region > dimlen) then - write(6,*) modname//':'//subname// & - ' ERROR: max region value exceeds length of region dimension' - write(6,*) 'max region value : ', max_region - write(6,*) 'length of region dimension: ', dimlen - call abort() - end if - - ! Determine dominant region for each output cell - - call get_dominant_indices(tgridmap, region_i, region_o, 1, max_region, index_nodata, mask_src=tdomain%mask) - - write (6,*) 'Successfully made urban region' - write (6,*) - - ! Output diagnostics - - call output_diagnostics_index(region_i, region_o, tgridmap, 'Urban Region ID', & - 1, max_region, ndiag, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Deallocate dynamic memory & other clean up - - call check_ret(nf_close(ncid), subname) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - deallocate (urbn_classes_gcell_i, urbn_classes_gcell_o, region_i, frac_dst) - -end subroutine mkurban -!----------------------------------------------------------------------- - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: normalize_urbn_by_tot -! -! !INTERFACE: -subroutine normalize_urbn_by_tot(classes_pct_gcell, sums, classes_pct_tot) -! -! !DESCRIPTION: -! Normalizes urban class areas to produce % cover of each class, as % of total urban area -! -! Specifically: Given (1) an array specifying the % cover of each urban class, as a % of -! the total grid cell area ('classes_pct_gcell'), and (2) a vector giving the total urban -! area in each grid cell, expressed as % of the grid cell area: Returns an array -! ('classes_pct_tot') of the same dimensionality as classes_pct_gcell, where the values -! now give % cover of each class as a % of the total urban area. -! -! Assumes that sums(n) = sum(classes_pct_gcell(n,:)) -! -! When sums(n) = 0, the creation of classes_pct_tot(n,:) is ambiguous. Here we use the -! rule that all area is assigned to the medium-density class, defined by parameter MD. -! -! The returned array satisfies sum(classes_pct_tot(n,:))==100 for all n (within rounding error) -! -! !USES: -! -! !ARGUMENTS: - implicit none - real(r8), intent(in) :: classes_pct_gcell(:,:) ! % cover of classes as % of grid cell - real(r8), intent(in) :: sums(:) ! totals, as % of grid cell - real(r8), intent(out):: classes_pct_tot(:,:) ! % cover of classes as % of total -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - integer :: n ! index - integer :: n_max ! number of points - integer :: nclasses ! number of classes - real(r8) :: suma ! sum for error check - - ! index of medium-density class, which is where we assign urban areas when the total - ! urban area is 0 - integer, parameter :: MD = 3 - - ! relative error tolerance for error check - real(r8), parameter :: relerr = 1.e-10_r8 - - character(len=*), parameter :: subname = 'normalize_urbn_by_tot' -!----------------------------------------------------------------------- - - ! Error-check inputs - - n_max = size(sums) - if (size(classes_pct_tot, 1) /= n_max .or. & - size(classes_pct_gcell, 1) /= n_max) then - write(6,*) subname//' ERROR: array size mismatch' - write(6,*) 'size(sums) = ', n_max - write(6,*) 'size(classes_pct_tot, 1) = ', size(classes_pct_tot, 1) - write(6,*) 'size(classes_pct_gcell, 1) = ', size(classes_pct_gcell, 1) - call abort() - end if - - if (size(classes_pct_tot, 2) /= size(classes_pct_gcell, 2)) then - write(6,*) subname//' ERROR: array size mismatch' - write(6,*) 'size(classes_pct_tot, 2) = ', size(classes_pct_tot, 2) - write(6,*) 'size(classes_pct_gcell, 2) = ', size(classes_pct_gcell, 2) - call abort() - end if - - nclasses = size(classes_pct_gcell, 2) - if (MD > nclasses) then - write(6,*) subname//' ERROR: MD exceeds nclasses' - write(6,*) 'MD = ', MD - write(6,*) 'nclasses = ', nclasses - call abort() - end if - - ! Do the work - - do n = 1, n_max - if (sums(n) > 0._r8) then - classes_pct_tot(n,:) = classes_pct_gcell(n,:)/sums(n) * 100._r8 - else - ! Creation of classes_pct_tot is ambiguous. Apply the rule that all area is - ! assigned to the medium-density class. - classes_pct_tot(n,:) = 0._r8 - classes_pct_tot(n,MD) = 100._r8 - end if - end do - - ! Error-check output: Make sure sum(classes_pct_tot(n,:)) = 100 for all n - - do n = 1, n_max - suma = sum(classes_pct_tot(n,:)) - if (abs(suma/100._r8 - 1._r8) > relerr) then - write(6,*) subname//' ERROR: sum does not equal 100 at point ', n - write(6,*) 'suma = ', suma - call abort() - end if - end do - -end subroutine normalize_urbn_by_tot -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkurbanpar -! -! !INTERFACE: -subroutine mkurbanpar(datfname, ncido, region_o, urbn_classes_gcell_o, urban_skip_abort_on_invalid_data_check) -! -! !DESCRIPTION: -! Make Urban Parameter data -! -! Note that, in a grid cell with region_o==r, parameter values are filled from region r -! for ALL density classes. Thus, the parameter variables have a numurbl dimension along -! with their other dimensions. -! -! Note that we will have a 'nodata' value (given by the fill_val value associated with -! each parameter) wherever (1) we have a nodata value for region_o, or (2) the parameter -! has nodata for the given region/density combination in the input lookup table. -! -! !USES: - use mkdomainMod , only : domain_type, domain_clean, domain_read - use mkindexmapMod, only : dim_slice_type, lookup_2d_netcdf - use mkvarpar - use mkncdio -! -! !ARGUMENTS: - implicit none - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ncido ! output netcdf file id - integer , intent(in) :: region_o(:) ! output grid: region ID (length: ns_o) - real(r8) , intent(in) :: urbn_classes_gcell_o(:,:) ! output grid: percent urban in each density class - ! (% of total grid cell area) (dimensions: ns_o, numurbl) - logical , intent(in) :: urban_skip_abort_on_invalid_data_check - -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - ! Type to store information about each urban parameter - type param - character(len=32) :: name ! name in input & output files - real(r8) :: fill_val ! value to put where we have no data in output - logical :: check_invalid ! should we check whether there are any invalid data in the output? - end type param - - real(r8), allocatable :: data_scalar_o(:,:) ! output array for parameters with no extra dimensions - real(r8), allocatable :: data_rad_o(:,:,:,:) ! output array for parameters dimensioned by numrad & numsolar - real(r8), allocatable :: data_levurb_o(:,:,:) ! output array for parameters dimensioned by nlevurb - integer , allocatable :: unity_dens_o(:,:) ! artificial density indices - integer :: nlevurb_i ! input grid: number of urban vertical levels - integer :: numsolar_i ! input grid: number of solar type (DIR/DIF) - integer :: numrad_i ! input grid: number of solar bands (VIS/NIR) - integer :: m,n,no,ns_o,p,k ! indices - integer :: ncidi,dimid,varid ! netCDF id's - integer :: ier ! error status - character(len=nf_max_name) :: varname ! variable name - - ! information on extra dimensions for lookup tables greater than 2-d: - type(dim_slice_type), allocatable :: extra_dims(:) - - ! suffix for variables dimensioned by numsolar, for each value of numsolar: - character(len=8), parameter :: solar_suffix(numsolar) = (/'_DIR', '_DIF'/) - - ! value to put where we have no data in output variables, for real-valued parameters - real(r8), parameter :: fill_val_real = 0._r8 - - ! To add a new urban parameter, simply add an element to one of the below lists - ! (params_scalar, params_rad or params_levurb) - - ! Urban parameters with no extra dimensions - type(param), parameter :: params_scalar(13) = & - (/ param('CANYON_HWR', fill_val_real, .true.), & - param('EM_IMPROAD', fill_val_real, .true.), & - param('EM_PERROAD', fill_val_real, .true.), & - param('EM_ROOF', fill_val_real, .true.), & - param('EM_WALL', fill_val_real, .true.), & - param('HT_ROOF', fill_val_real, .true.), & - param('THICK_ROOF', fill_val_real, .true.), & - param('THICK_WALL', fill_val_real, .true.), & - param('T_BUILDING_MIN', fill_val_real, .true.), & - param('WIND_HGT_CANYON', fill_val_real, .true.), & - param('WTLUNIT_ROOF', fill_val_real, .true.), & - param('WTROAD_PERV', fill_val_real, .true.), & - - ! Note that NLEV_IMPROAD is written as an integer, meaning that type conversion occurs - ! by truncation. Thus we expect the values in the NLEV_IMPROAD lookup table to be exact; - ! e.g., if a value were 1.99999 rather than 2.0000, it would be written as 1 instead of 2 - ! Also note: we use fill_val=-1 rather than 0, because 0 appears in the lookup table - param('NLEV_IMPROAD', -1, .true.) /) - - ! Urban parameters dimensioned by numrad & numsolar - type(param), parameter :: params_rad(4) = & - (/ param('ALB_IMPROAD', fill_val_real, .true.), & - param('ALB_PERROAD', fill_val_real, .true.), & - param('ALB_ROOF', fill_val_real, .true.), & - param('ALB_WALL', fill_val_real, .true.) /) - - ! Urban parameters dimensioned by nlevurb - type(param), parameter :: params_levurb(6) = & - (/ param('TK_ROOF', fill_val_real, .true.), & - param('TK_WALL', fill_val_real, .true.), & - param('CV_ROOF', fill_val_real, .true.), & - param('CV_WALL', fill_val_real, .true.), & - - ! Impervious road thermal conductivity and heat capacity have varying levels of - ! data. Thus, we expect to find some missing values in the lookup table -- we - ! do not want to treat that as an error -- thus, we set check_invalid=.false. - param('CV_IMPROAD', fill_val_real, .false.), & - param('TK_IMPROAD', fill_val_real, .false.) /) - - - character(len=*), parameter :: subname = 'mkurbanpar' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make Urban Parameters .....' - call shr_sys_flush(6) - - ! Determine & error-check array sizes - ns_o = size(region_o) - if (size(urbn_classes_gcell_o, 1) /= ns_o) then - write(6,*) modname//':'//subname//' ERROR: array size mismatch' - write(6,*) 'size(region_o) = ', size(region_o) - write(6,*) 'size(urbn_classes_gcell_o, 1) = ', size(urbn_classes_gcell_o, 1) - call abort() - end if - if (size(urbn_classes_gcell_o, 2) /= numurbl) then - write(6,*) modname//':'//subname//' ERROR: array size mismatch' - write(6,*) 'size(urbn_classes_gcell_o, 2) = ', size(urbn_classes_gcell_o, 2) - write(6,*) 'numurbl = ', numurbl - end if - - - ! Read dimensions from input file - - write (6,*) 'Open urban parameter file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncidi), subname) - call check_ret(nf_inq_dimid(ncidi, 'nlevurb', dimid), subname) - call check_ret(nf_inq_dimlen(ncidi, dimid, nlevurb_i), subname) - call check_ret(nf_inq_dimid(ncidi, 'numsolar', dimid), subname) - call check_ret(nf_inq_dimlen(ncidi, dimid, numsolar_i), subname) - call check_ret(nf_inq_dimid(ncidi, 'numrad', dimid), subname) - call check_ret(nf_inq_dimlen(ncidi, dimid, numrad_i), subname) - - if (nlevurb_i /= nlevurb) then - write(6,*)'MKURBANPAR: parameter nlevurb= ',nlevurb, & - 'does not equal input dataset nlevurb= ',nlevurb_i - call abort() - endif - if (numsolar_i /= numsolar) then - write(6,*)'MKURBANPAR: parameter numsolar= ',numsolar, & - 'does not equal input dataset numsolar= ',numsolar_i - call abort() - endif - if (numrad_i /= numrad) then - write(6,*)'MKURBANPAR: parameter numrad= ',numrad, & - 'does not equal input dataset numrad= ',numrad_i - call abort() - endif - - ! Create an array that will hold the density indices - ! In a given grid cell, we output parameter values for all density classes, for the - ! region of that grid cell. In order to do this while still using the lookup_2d - ! routine, we create a dummy unity_dens_o array that contains the density values - ! passed to the lookup routine. - - allocate(unity_dens_o(ns_o, numurbl)) - do k = 1, numurbl - unity_dens_o(:,k) = k - end do - - ! Handle urban parameters with no extra dimensions - - allocate(data_scalar_o(ns_o, numurbl), stat=ier) - if (ier /= 0) then - write(6,*)'mkurbanpar allocation error'; call abort() - end if - - do p = 1, size(params_scalar) - call lookup_and_check_err(params_scalar(p)%name, params_scalar(p)%fill_val, & - params_scalar(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & - data_scalar_o, 0) - - call check_ret(nf_inq_varid(ncido, params_scalar(p)%name, varid), subname) - ! In the following, note that type conversion occurs if we're writing to a variable of type - ! other than double; e.g., for an integer, conversion occurs by truncation! - call check_ret(nf_put_var_double(ncido, varid, data_scalar_o), subname) - end do - - deallocate(data_scalar_o) - - ! Handle urban parameters dimensioned by numrad & numsolar - - allocate(data_rad_o(ns_o, numurbl, numrad, numsolar), stat=ier) - if (ier /= 0) then - write(6,*)'mkurbanpar allocation error'; call abort() - end if - - allocate(extra_dims(2)) - extra_dims(1)%name = 'numrad' - extra_dims(2)%name = 'numsolar' - - do p = 1, size(params_rad) - do m = 1,numsolar - extra_dims(2)%val = m - do n = 1,numrad - extra_dims(1)%val = n - - call lookup_and_check_err(params_rad(p)%name, params_rad(p)%fill_val, & - params_rad(p)%check_invalid, urban_skip_abort_on_invalid_data_check, & - data_rad_o(:,:,n,m), & - 2, extra_dims) - end do - end do - - ! Special handling of numsolar: rather than outputting variables with a numsolar - ! dimension, we output separate variables for each value of numsolar - do m = 1,numsolar - if (len_trim(params_rad(p)%name) + len_trim(solar_suffix(m)) > len(varname)) then - write(6,*) 'variable name exceeds length of varname' - write(6,*) trim(params_rad(p)%name)//trim(solar_suffix(m)) - call abort() - end if - varname = trim(params_rad(p)%name)//trim(solar_suffix(m)) - call check_ret(nf_inq_varid(ncido, varname, varid), subname) - ! In the following, note that type conversion occurs if we're writing to a variable of type - ! other than double; e.g., for an integer, conversion occurs by truncation! - call check_ret(nf_put_var_double(ncido, varid, data_rad_o(:,:,:,m)), subname) - end do - end do - - deallocate(data_rad_o) - deallocate(extra_dims) - - ! Handle urban parameters dimensioned by nlevurb - - allocate(data_levurb_o(ns_o, numurbl, nlevurb), stat=ier) - if (ier /= 0) then - write(6,*)'mkurbanpar allocation error'; call abort() - end if - - allocate(extra_dims(1)) - extra_dims(1)%name = 'nlevurb' - - do p = 1, size(params_levurb) - do n = 1,nlevurb - extra_dims(1)%val = n - - call lookup_and_check_err(params_levurb(p)%name, params_levurb(p)%fill_val, & - params_levurb(p)%check_invalid, & - urban_skip_abort_on_invalid_data_check, data_levurb_o(:,:,n), & - 1, extra_dims) - end do - - call check_ret(nf_inq_varid(ncido, params_levurb(p)%name, varid), subname) - ! In the following, note that type conversion occurs if we're writing to a variable of type - ! other than double; e.g., for an integer, conversion occurs by truncation! - call check_ret(nf_put_var_double(ncido, varid, data_levurb_o), subname) - end do - - deallocate(data_levurb_o) - deallocate(extra_dims) - - - call check_ret(nf_close(ncidi), subname) - call check_ret(nf_sync(ncido), subname) - - write (6,*) 'Successfully made Urban Parameters' - write (6,*) - call shr_sys_flush(6) - - deallocate(unity_dens_o) - -contains -!------------------------------------------------------------------------------ - subroutine lookup_and_check_err(varname, fill_val, check_invalid, & - urban_skip_abort_on_invalid_data_check, data, n_extra_dims, extra_dims) - - ! Wrapper to lookup_2d_netcdf: Loops over each density class, calling lookup_2d_netcdf - ! with that density class and filling the appropriate slice of the data array. Also - ! checks for any errors, aborting if there were any. - ! - ! Note that the lookup_2d_netcdf routine is designed to work with a single value of - ! each of the indices. However, we want to fill parameter values for ALL density - ! classes. This is why we loop over density class in this routine. - ! - ! Note: inherits a number of variables from the parent routine - - use mkindexmapMod, only : lookup_2d_netcdf - - implicit none - character(len=*), intent(in) :: varname ! name of lookup table - real(r8) , intent(in) :: fill_val ! value to put where we have no data in output variables - logical , intent(in) :: check_invalid ! should we check whether there are any invalid data in the output? - logical , intent(in) :: urban_skip_abort_on_invalid_data_check - - real(r8) , intent(out):: data(:,:) ! output from lookup_2d_netcdf - integer , intent(in) :: n_extra_dims ! number of extra dimensions in the lookup table - - ! slice to use if lookup table variable has more than 2 dimensions: - type(dim_slice_type), intent(in), optional :: extra_dims(:) - - ! Local variables: - - integer :: k,n ! indices - integer :: ierr ! error return code - - - do k = 1, numurbl - ! In the following, note that unity_dens_o(:,k) has been constructed so that - ! unity_dens_o(:,k)==k everywhere. Thus, we fill data(:,k) with the parameter - ! values corresponding to density class k. - ! Also note: We use invalid_okay=.true. because we fill all density classes, - ! some of which may have invalid entries. Because doing so disables some error - ! checking, we do our own error checking after the call. - call lookup_2d_netcdf(ncidi, varname, .true., & - 'density_class', 'region', n_extra_dims, & - unity_dens_o(:,k), region_o, fill_val, data(:,k), ierr, & - extra_dims=extra_dims, nodata=index_nodata, & - invalid_okay=.true.) - - if (ierr /= 0) then - write(6,*) modname//':'//subname//' ERROR in lookup_2d_netcdf for ', & - trim(varname), ' class', k, ': err=', ierr - call abort() - end if - - if (check_invalid) then - ! Make sure we have valid parameter values wherever we have non-zero urban cover - do n = 1, ns_o - ! This check assumes that fill_val doesn't appear in any of the valid entries - ! of the lookup table - if (urbn_classes_gcell_o(n,k) > 0. .and. data(n,k) == fill_val) then - write(6,*) modname//':'//subname//' ERROR: fill value found in output where urban cover > 0' - write(6,*) 'var: ', trim(varname) - write(6,*) 'class: ', k - write(6,*) 'n: ', n - write(6,*) 'region: ', region_o(n) - write(6,*) 'urbn_classes_gcell_o(n,k): ', urbn_classes_gcell_o(n,k) - if (.not. urban_skip_abort_on_invalid_data_check) then - ! NOTE(bja, 2015-01) added to work around a ?bug? noted in - ! /glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 - call abort() - end if - end if - end do - end if - - end do - - end subroutine lookup_and_check_err - -end subroutine mkurbanpar -!------------------------------------------------------------------------------ - -end module mkurbanparMod diff --git a/tools/mksurfdata_map/src/mkutilsMod.F90 b/tools/mksurfdata_map/src/mkutilsMod.F90 deleted file mode 100644 index 43e779745b..0000000000 --- a/tools/mksurfdata_map/src/mkutilsMod.F90 +++ /dev/null @@ -1,197 +0,0 @@ -module mkutilsMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkutils -! -! !DESCRIPTION: -! General-purpose utilities for mksurfdata_map -! -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - - implicit none - private -! -! !PUBLIC MEMBER FUNCTIONS: - public :: normalize_classes_by_gcell ! renormalize array so values are given as % of total grid cell area - public :: slightly_below - public :: slightly_above -! -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -!EOP -!------------------------------------------------------------------------------ -contains - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: normalize_classes_by_gcell -! -! !INTERFACE: -subroutine normalize_classes_by_gcell(classes_pct_tot, sums, classes_pct_gcell) -! -! !DESCRIPTION: -! Renormalizes an array (gcell x class) so that values are given as % of total grid cell area -! -! Specifically: Given (1) an array specifying the % cover of different classes, as a % of -! some total ('classes_pct_tot'), and (2) a vector giving these totals ('sums'), expressed -! as % of grid cell area: Returns an array ('classes_pct_gcell') of the same -! dimensionality as classes_pct_tot, where the values now give the % cover of each class -! as a % of total grid cell area. -! -! The size of 'sums' should match the size of the first dimension in 'classes_pct_tot' and -! 'classes_pct_gcell' -! -! For example, if classes_pct_tot(n,i) gives the % of the urban area in grid cell n that is -! in urban class #i, and sums(n) gives the % of grid cell n that is urban, then -! classes_pct_gcell(n,i) will give the % of the total area of grid cell n that is in urban -! class #i. -! -! !USES: -! -! !ARGUMENTS: - implicit none - real(r8), intent(in) :: classes_pct_tot(:,:) ! % cover of classes as % of total - real(r8), intent(in) :: sums(:) ! totals, as % of grid cell - real(r8), intent(out):: classes_pct_gcell(:,:) ! % cover of classes as % of grid cell -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - integer :: n, n_max - - character(len=*), parameter :: subname = "normalize_classes_by_gcell" -!------------------------------------------------------------------------------ - - ! Error-check inputs - - n_max = size(sums) - if (size(classes_pct_tot, 1) /= n_max .or. & - size(classes_pct_gcell, 1) /= n_max) then - write(6,*) subname//' ERROR: array size mismatch' - write(6,*) 'size(sums) = ', n_max - write(6,*) 'size(classes_pct_tot, 1) = ', size(classes_pct_tot, 1) - write(6,*) 'size(classes_pct_gcell, 1) = ', size(classes_pct_gcell, 1) - call abort() - end if - - if (size(classes_pct_tot, 2) /= size(classes_pct_gcell, 2)) then - write(6,*) subname//' ERROR: array size mismatch' - write(6,*) 'size(classes_pct_tot, 2) = ', size(classes_pct_tot, 2) - write(6,*) 'size(classes_pct_gcell, 2) = ', size(classes_pct_gcell, 2) - call abort() - end if - - ! Do the work - - do n = 1, n_max - classes_pct_gcell(n,:) = classes_pct_tot(n,:) * (sums(n)/100._r8) - end do -end subroutine normalize_classes_by_gcell -!------------------------------------------------------------------------------ - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: slightly_below -! -! !INTERFACE: -logical function slightly_below(a, b, eps) -! -! !DESCRIPTION: -! Returns true if a is slightly below b; false if a is significantly below b or if a is -! greater than or equal to b -! -! !USES: -! -! !ARGUMENTS: - implicit none - real(r8), intent(in) :: a - real(r8), intent(in) :: b - - ! if provided, eps gives the relative error allowed for checking the "slightly" - ! condition; if not provided, the tolerance defaults to the value given by eps_default - real(r8), intent(in), optional :: eps -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - real(r8) :: l_eps - real(r8), parameter :: eps_default = 1.e-15_r8 ! default relative error tolerance -!------------------------------------------------------------------------------ - - if (present(eps)) then - l_eps = eps - else - l_eps = eps_default - end if - - if (a < b .and. (b - a)/b < l_eps) then - slightly_below = .true. - else - slightly_below = .false. - end if - -end function slightly_below -!------------------------------------------------------------------------------ - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: slightly_above -! -! !INTERFACE: -logical function slightly_above(a, b, eps) -! -! !DESCRIPTION: -! Returns true if a is slightly above b; false if a is significantly above b or if a is -! less than or equal to b -! -! !USES: -! -! !ARGUMENTS: - implicit none - real(r8), intent(in) :: a - real(r8), intent(in) :: b - - ! if provided, eps gives the relative error allowed for checking the "slightly" - ! condition; if not provided, the tolerance defaults to the value given by eps_default - real(r8), intent(in), optional :: eps -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - real(r8) :: l_eps - real(r8), parameter :: eps_default = 1.e-15_r8 ! default relative error tolerance -!------------------------------------------------------------------------------ - - if (present(eps)) then - l_eps = eps - else - l_eps = eps_default - end if - - if (a > b .and. (a - b)/b < l_eps) then - slightly_above = .true. - else - slightly_above = .false. - end if - -end function slightly_above -!------------------------------------------------------------------------------ - -end module mkutilsMod diff --git a/tools/mksurfdata_map/src/mkvarctl.F90 b/tools/mksurfdata_map/src/mkvarctl.F90 deleted file mode 100644 index 864291ae07..0000000000 --- a/tools/mksurfdata_map/src/mkvarctl.F90 +++ /dev/null @@ -1,90 +0,0 @@ -module mkvarctl - -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkvarctl -! -! !DESCRIPTION: -! Module containing control variables -! -! !USES: - use shr_kind_mod, only: r8 => shr_kind_r8 -! -! !PUBLIC TYPES: - implicit none - private - save -! - real(r8), public, parameter :: spval = 1.e36 ! special value - integer, public, parameter :: ispval = -9999 ! special value - - logical, public :: outnc_large_files ! output files in 64-bit format for large files - logical, public :: outnc_double ! output ALL data in files as 64-bit - integer, public :: outnc_dims = 2 ! only applicable to lat/lon grids - logical, public :: outnc_1d ! true => output file is 1d - logical, public :: outnc_vic ! true => output VIC fields - logical, public :: outnc_3dglc ! true => output 3D glacier fields - - character(len= 32), public :: mksrf_gridnm = ' ' ! name of grid to use on output file - character(len=256), public :: mksrf_fgrid = ' ' ! land grid file name to use - character(len=256), public :: mksrf_gridtype = ' ' ! land gridtype, global or reg - character(len=256), public :: mksrf_fvegtyp = ' ' ! vegetation data file name - character(len=256), public :: mksrf_fhrvtyp = ' ' ! harvest data file name - character(len=256), public :: mksrf_fsoitex = ' ' ! soil texture data file name - character(len=256), public :: mksrf_forganic = ' ' ! organic matter data file name - character(len=256), public :: mksrf_fsoicol = ' ' ! soil color data file name - character(len=256), public :: mksrf_fabm = ' ' ! ag fire peak month and - character(len=256), public :: mksrf_fpeat = ' ' ! peatlands and - character(len=256), public :: mksrf_fsoildepth = ' ' ! soil depth file name - character(len=256), public :: mksrf_fgdp = ' ' ! gdp data file names - character(len=256), public :: mksrf_flakwat = ' ' ! inland lake data file name - character(len=256), public :: mksrf_fwetlnd = ' ' ! inland wetlands data file name - character(len=256), public :: mksrf_furban = ' ' ! urban data file name - character(len=256), public :: mksrf_fglacier = ' ' ! glacier data file name - character(len=256), public :: mksrf_fglacierregion = ' ' ! glacier region data file name - character(len=256), public :: mksrf_furbtopo = ' ' ! urban topography data file name - character(len=256), public :: mksrf_fmax = ' ' ! fmax data file name - character(len=256), public :: mksrf_flai = ' ' ! lai data filename - character(len=256), public :: mksrf_fdynuse = ' ' ! ascii file containing names of dynamic land use files - character(len=256), public :: mksrf_fvocef = ' ' ! VOC Emission Factor data file name - character(len=256), public :: mksrf_ftopostats = ' ' ! topography statistics data file name - character(len=256), public :: mksrf_fvic = ' ' ! VIC parameters data file name - - integer , public :: numpft = 16 ! number of plant types - - character(len=256), public :: map_fpft = ' ' ! Mapping file for PFT - character(len=256), public :: map_flakwat = ' ' ! Mapping file for lake water - character(len=256), public :: map_fwetlnd = ' ' ! Mapping file for wetland water - character(len=256), public :: map_fglacier = ' ' ! Mapping file for glacier - character(len=256), public :: map_fglacierregion = ' ' ! Mapping file for glacier region - character(len=256), public :: map_fsoitex = ' ' ! Mapping file for soil texture - character(len=256), public :: map_fsoicol = ' ' ! Mapping file for soil color - character(len=256), public :: map_fabm = ' ' ! Mapping file: ag fire... - character(len=256), public :: map_fpeat = ' ' ! Mapping file: peatlands - character(len=256), public :: map_fsoildepth = ' ' ! Mapping file: soil depth - character(len=256), public :: map_fgdp = ' ' ! Mapping file: gdp - character(len=256), public :: map_furban = ' ' ! Mapping file for urban - character(len=256), public :: map_furbtopo = ' ' ! Mapping file for urban topography - character(len=256), public :: map_fmax = ' ' ! Mapping file for soil frac max - character(len=256), public :: map_forganic = ' ' ! Mapping file for organic soil - character(len=256), public :: map_fvocef = ' ' ! Mapping file for VOC emission factors - character(len=256), public :: map_flai = ' ' ! Mapping file for LAI - character(len=256), public :: map_fharvest = ' ' ! Mapping file for harvesting - character(len=256), public :: map_ftopostats = ' ' ! Mapping file for topography statistics - character(len=256), public :: map_fvic = ' ' ! Mapping file for VIC parameters - character(len=80) , public :: gitdescribe = ' ' ! Description of model version from git -! -! Variables to override data read in with -! (all_urban is mostly for single-point mode, but could be used for sensitivity studies) -! - logical, public :: all_urban ! output ALL data as 100% covered in urban - logical, public :: no_inlandwet ! set wetland to 0% over land; wetland will only be used for ocean points -! -! !REVISION HISTORY: -! Created by Mariana Vertenstein 11/04 -! -!EOP -!----------------------------------------------------------------------- - -end module mkvarctl diff --git a/tools/mksurfdata_map/src/mkvarpar.F90 b/tools/mksurfdata_map/src/mkvarpar.F90 deleted file mode 100644 index a8a01d2da2..0000000000 --- a/tools/mksurfdata_map/src/mkvarpar.F90 +++ /dev/null @@ -1,32 +0,0 @@ -module mkvarpar - -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: clm_varpar -! -! !DESCRIPTION: -! Module containing CLM parameters -! -! !USES: - use shr_kind_mod, only: r8 => shr_kind_r8 - use shr_const_mod, only: SHR_CONST_REARTH -! -! !PUBLIC TYPES: - implicit none - save -! - integer, parameter :: nlevsoi = 10 ! number of soil layers - integer, parameter :: numstdpft = 16! number of standard PFT types - integer, parameter :: numstdcft = 2 ! of the number of standard PFT types, how many are crop (CFT) - integer, parameter :: noveg = 0 ! value for non-vegetated pft - integer, parameter :: numsolar = 2 ! number of solar types (Direct,Diffuse) - integer, parameter :: numrad = 2 ! number of solar bands (VIS,NIR) - real(r8),parameter :: elev_thresh = 2600._r8 ! elevation threshold for screening urban areas - real(r8),parameter :: re = SHR_CONST_REARTH*0.001 - -! -!EOP -!----------------------------------------------------------------------- - -end module mkvarpar diff --git a/tools/mksurfdata_map/src/mkvocefMod.F90 b/tools/mksurfdata_map/src/mkvocefMod.F90 deleted file mode 100644 index 03d9dddd3f..0000000000 --- a/tools/mksurfdata_map/src/mkvocefMod.F90 +++ /dev/null @@ -1,209 +0,0 @@ -module mkvocefMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkvocMod -! -! !DESCRIPTION: -! Make VOC percentage emissions for surface dataset -! -! !REVISION HISTORY: -! Author: Erik Kluzek -! -!----------------------------------------------------------------------- -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use shr_sys_mod , only : shr_sys_flush - use mkdomainMod , only : domain_checksame - - implicit none - private - -! !PUBLIC MEMBER FUNCTIONS: - public :: mkvocef ! Get the percentage emissions for VOC for different - ! land cover types -!EOP - -contains - -!----------------------------------------------------------------------- -!BOP -! -! !IROUTINE: mkvocef -! -! !INTERFACE: -subroutine mkvocef(ldomain, mapfname, datfname, ndiag, & - ef_btr_o, ef_fet_o, ef_fdt_o, ef_shr_o, ef_grs_o, ef_crp_o) -! -! !DESCRIPTION: -! make volatile organic coumpunds (VOC) emission factors. -! -! !USES: - use mkdomainMod, only : domain_type, domain_clean, domain_read - use mkgridmapMod - use mkvarpar - use mkvarctl - use mkncdio -! -! !ARGUMENTS: - implicit none - type(domain_type) , intent(in) :: ldomain - character(len=*) , intent(in) :: mapfname ! input mapping file name - character(len=*) , intent(in) :: datfname ! input data file name - integer , intent(in) :: ndiag ! unit number for diagnostic output - real(r8) , intent(out):: ef_btr_o(:) ! output grid: EFs for broadleaf trees - real(r8) , intent(out):: ef_fet_o(:) ! output grid: EFs for fineleaf evergreen - real(r8) , intent(out):: ef_fdt_o(:) ! output grid: EFs for fineleaf deciduous - real(r8) , intent(out):: ef_shr_o(:) ! output grid: EFs for shrubs - real(r8) , intent(out):: ef_grs_o(:) ! output grid: EFs for grasses - real(r8) , intent(out):: ef_crp_o(:) ! output grid: EFs for crops -! -! !CALLED FROM: -! subroutine mksrfdat in module mksrfdatMod -! -! !REVISION HISTORY: -! Author: Colette L. Heald -! 17 Jul 2007 F Vitt -- updated to pftintdat06_clm3_5_05 and corrected indexing of ef_*_i arrarys -! -!EOP -! -! !LOCAL VARIABLES: - type(gridmap_type) :: tgridmap - type(domain_type) :: tdomain ! local domain - real(r8), allocatable :: ef_btr_i(:) ! input grid: EFs for broadleaf trees - real(r8), allocatable :: ef_fet_i(:) ! input grid: EFs for fineleaf evergreen - real(r8), allocatable :: ef_fdt_i(:) ! input grid: EFs for fineleaf deciduous - real(r8), allocatable :: ef_shr_i(:) ! input grid: EFs for shrubs - real(r8), allocatable :: ef_grs_i(:) ! input grid: EFs for grasses - real(r8), allocatable :: ef_crp_i(:) ! input grid: EFs for crops - real(r8), allocatable :: frac_dst(:) ! output fractions - real(r8), allocatable :: mask_r8(:) ! float of tdomain%mask - real(r8) :: sum_fldo ! global sum of dummy input fld - real(r8) :: sum_fldi ! global sum of dummy input fld - integer :: k,n,no,ni,ns_o,ns_i ! indices - integer :: ncid,dimid,varid ! input netCDF id's - integer :: ier ! error status - real(r8) :: relerr = 0.00001_r8 ! max error: sum overlap wts ne 1 - character(len=32) :: subname = 'mkvocef' -!----------------------------------------------------------------------- - - write (6,*) 'Attempting to make VOC emission factors .....' - call shr_sys_flush(6) - - ns_o = ldomain%ns - - ! ----------------------------------------------------------------- - ! Read input Emission Factors - ! ----------------------------------------------------------------- - - ! Obtain input grid info, read local fields - - call domain_read(tdomain,datfname) - ns_i = tdomain%ns - allocate(ef_btr_i(ns_i), ef_fet_i(ns_i), ef_fdt_i(ns_i), & - ef_shr_i(ns_i), ef_grs_i(ns_i), ef_crp_i(ns_i), & - frac_dst(ns_o), stat=ier) - if (ier/=0) call abort() - - write (6,*) 'Open VOC file: ', trim(datfname) - call check_ret(nf_open(datfname, 0, ncid), subname) - call check_ret(nf_inq_varid (ncid, 'ef_btr', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_btr_i), subname) - call check_ret(nf_inq_varid (ncid, 'ef_fet', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_fet_i), subname) - call check_ret(nf_inq_varid (ncid, 'ef_fdt', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_fdt_i), subname) - call check_ret(nf_inq_varid (ncid, 'ef_shr', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_shr_i), subname) - call check_ret(nf_inq_varid (ncid, 'ef_grs', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_grs_i), subname) - call check_ret(nf_inq_varid (ncid, 'ef_crp', varid), subname) - call check_ret(nf_get_var_double(ncid, varid, ef_crp_i), subname) - call check_ret(nf_close(ncid), subname) - - ! Area-average percent cover on input grid to output grid - ! and correct according to land landmask - ! Note that percent cover is in terms of total grid area. - - call gridmap_mapread(tgridmap, mapfname ) - - ! Error checks for domain and map consistencies - - call domain_checksame( tdomain, ldomain, tgridmap ) - - ! Obtain frac_dst - call gridmap_calc_frac_dst(tgridmap, tdomain%mask, frac_dst) - - ! Do mapping from input to output grid - - call gridmap_areaave_srcmask(tgridmap, ef_btr_i, ef_btr_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, ef_fet_i, ef_fet_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, ef_fdt_i, ef_fdt_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, ef_shr_i, ef_shr_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, ef_grs_i, ef_grs_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - call gridmap_areaave_srcmask(tgridmap, ef_crp_i, ef_crp_o, nodata=0._r8, mask_src=tdomain%mask, frac_dst=frac_dst) - - ! Check for conservation - - do no = 1, ns_o - if ( ef_btr_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF btr = ',ef_btr_o(no), & - ' is negative for no = ',no - call abort() - end if - if ( ef_fet_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF fet = ',ef_fet_o(no), & - ' is negative for no = ',no - call abort() - end if - if ( ef_fdt_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF fdt = ',ef_fdt_o(no), & - ' is negative for no = ',no - call abort() - end if - if ( ef_shr_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF shr = ',ef_shr_o(no), & - ' is negative for no = ',no - call abort() - end if - if ( ef_grs_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF grs = ',ef_grs_o(no), & - ' is negative for no = ',no - call abort() - end if - if ( ef_crp_o(no) < 0._r8 ) then - write (6,*) 'MKVOCEF error: EF crp = ',ef_crp_o(no), & - ' is negative for no = ',no - call abort() - end if - enddo - - ! ----------------------------------------------------------------- - ! Error check1 - ! Compare global sum fld_o to global sum fld_i. - ! ----------------------------------------------------------------- - - ! Global sum of output field -- must multiply by fraction of - ! output grid that is land as determined by input grid - - allocate(mask_r8(ns_i), stat=ier) - if (ier/=0) call abort() - mask_r8 = tdomain%mask - call gridmap_check( tgridmap, mask_r8, frac_dst, subname ) - - write (6,*) 'Successfully made VOC Emission Factors' - write (6,*) - call shr_sys_flush(6) - - ! Deallocate dynamic memory - - deallocate ( ef_btr_i, ef_fet_i, ef_fdt_i, & - ef_shr_i, ef_grs_i, ef_crp_i, frac_dst, mask_r8 ) - call domain_clean(tdomain) - call gridmap_clean(tgridmap) - -end subroutine mkvocef - -!----------------------------------------------------------------------- - -end module mkvocefMod diff --git a/tools/mksurfdata_map/src/nanMod.F90 b/tools/mksurfdata_map/src/nanMod.F90 deleted file mode 100644 index 0cbeeea112..0000000000 --- a/tools/mksurfdata_map/src/nanMod.F90 +++ /dev/null @@ -1,41 +0,0 @@ -module nanMod - -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: nanMod -! -! !DESCRIPTION: -! Set parameters for the floating point flags "inf" Infinity -! and "nan" not-a-number. As well as "bigint" the point -! at which integers start to overflow. These values are used -! to initialize arrays with as a way to detect if arrays -! are being used before being set. -! Note that bigint is the largest possible 32-bit integer. -! -! !USES: - use shr_kind_mod, only: r8 => shr_kind_r8 -! -! !PUBLIC TYPES: - implicit none - save -#ifdef __PGI -! quiet nan for portland group compilers - real(r8), parameter :: inf = O'0777600000000000000000' - real(r8), parameter :: nan = O'0777700000000000000000' - integer, parameter :: bigint = O'17777777777' -#else -! signaling nan otherwise - real(r8), parameter :: inf = O'0777600000000000000000' - real(r8), parameter :: nan = O'0777610000000000000000' - integer, parameter :: bigint = O'17777777777' -#endif -! -! !REVISION HISTORY: -! Created by Mariana Vertenstein based on cam module created by -! CCM core group -! -!EOP -!----------------------------------------------------------------------- - -end module nanMod diff --git a/tools/mksurfdata_map/src/shr_const_mod.F90 b/tools/mksurfdata_map/src/shr_const_mod.F90 deleted file mode 100644 index 07d194e71e..0000000000 --- a/tools/mksurfdata_map/src/shr_const_mod.F90 +++ /dev/null @@ -1,58 +0,0 @@ -!=============================================================================== - -MODULE shr_const_mod - - use shr_kind_mod - - integer(SHR_KIND_IN),parameter,private :: R8 = SHR_KIND_R8 ! rename for local readability only - - !---------------------------------------------------------------------------- - ! physical constants (all data public) - !---------------------------------------------------------------------------- - public - - real(R8),parameter :: SHR_CONST_PI = 3.14159265358979323846_R8 ! pi - real(R8),parameter :: SHR_CONST_CDAY = 86400.0_R8 ! sec in calendar day ~ sec - real(R8),parameter :: SHR_CONST_SDAY = 86164.0_R8 ! sec in siderial day ~ sec - real(R8),parameter :: SHR_CONST_OMEGA = 2.0_R8*SHR_CONST_PI/SHR_CONST_SDAY ! earth rot ~ rad/sec - real(R8),parameter :: SHR_CONST_REARTH = 6.37122e6_R8 ! radius of earth ~ m - real(R8),parameter :: SHR_CONST_G = 9.80616_R8 ! acceleration of gravity ~ m/s^2 - - real(R8),parameter :: SHR_CONST_STEBOL = 5.67e-8_R8 ! Stefan-Boltzmann constant ~ W/m^2/K^4 - real(R8),parameter :: SHR_CONST_BOLTZ = 1.38065e-23_R8 ! Boltzmann's constant ~ J/K/molecule - real(R8),parameter :: SHR_CONST_AVOGAD = 6.02214e26_R8 ! Avogadro's number ~ molecules/kmole - real(R8),parameter :: SHR_CONST_RGAS = SHR_CONST_AVOGAD*SHR_CONST_BOLTZ ! Universal gas constant ~ J/K/kmole - real(R8),parameter :: SHR_CONST_MWDAIR = 28.966_R8 ! molecular weight dry air ~ kg/kmole - real(R8),parameter :: SHR_CONST_MWWV = 18.016_R8 ! molecular weight water vapor - real(R8),parameter :: SHR_CONST_RDAIR = SHR_CONST_RGAS/SHR_CONST_MWDAIR ! Dry air gas constant ~ J/K/kg - real(R8),parameter :: SHR_CONST_RWV = SHR_CONST_RGAS/SHR_CONST_MWWV ! Water vapor gas constant ~ J/K/kg - real(R8),parameter :: SHR_CONST_ZVIR = (SHR_CONST_RWV/SHR_CONST_RDAIR)-1.0_R8 ! RWV/RDAIR - 1.0 - real(R8),parameter :: SHR_CONST_KARMAN = 0.4_R8 ! Von Karman constant - real(R8),parameter :: SHR_CONST_PSTD = 101325.0_R8 ! standard pressure ~ pascals - real(R8),parameter :: SHR_CONST_PDB = 0.0112372_R8 ! ratio of 13C/12C in Pee Dee Belemnite (C isotope standard) - - real(R8),parameter :: SHR_CONST_TKTRIP = 273.16_R8 ! triple point of fresh water ~ K - real(R8),parameter :: SHR_CONST_TKFRZ = 273.15_R8 ! freezing T of fresh water ~ K - real(R8),parameter :: SHR_CONST_TKFRZSW = SHR_CONST_TKFRZ - 1.8_R8 ! freezing T of salt water ~ K - - real(R8),parameter :: SHR_CONST_RHODAIR = & ! density of dry air at STP ~ kg/m^3 - SHR_CONST_PSTD/(SHR_CONST_RDAIR*SHR_CONST_TKFRZ) - real(R8),parameter :: SHR_CONST_RHOFW = 1.000e3_R8 ! density of fresh water ~ kg/m^3 - real(R8),parameter :: SHR_CONST_RHOSW = 1.026e3_R8 ! density of sea water ~ kg/m^3 - real(R8),parameter :: SHR_CONST_RHOICE = 0.917e3_R8 ! density of ice ~ kg/m^3 - real(R8),parameter :: SHR_CONST_CPDAIR = 1.00464e3_R8 ! specific heat of dry air ~ J/kg/K - real(R8),parameter :: SHR_CONST_CPWV = 1.810e3_R8 ! specific heat of water vap ~ J/kg/K - real(R8),parameter :: SHR_CONST_CPVIR = (SHR_CONST_CPWV/SHR_CONST_CPDAIR)-1.0_R8 ! CPWV/CPDAIR - 1.0 - real(R8),parameter :: SHR_CONST_CPFW = 4.188e3_R8 ! specific heat of fresh h2o ~ J/kg/K - real(R8),parameter :: SHR_CONST_CPSW = 3.996e3_R8 ! specific heat of sea h2o ~ J/kg/K - real(R8),parameter :: SHR_CONST_CPICE = 2.11727e3_R8 ! specific heat of fresh ice ~ J/kg/K - real(R8),parameter :: SHR_CONST_LATICE = 3.337e5_R8 ! latent heat of fusion ~ J/kg - real(R8),parameter :: SHR_CONST_LATVAP = 2.501e6_R8 ! latent heat of evaporation ~ J/kg - real(R8),parameter :: SHR_CONST_LATSUB = & ! latent heat of sublimation ~ J/kg - SHR_CONST_LATICE + SHR_CONST_LATVAP - real(R8),parameter :: SHR_CONST_OCN_REF_SAL = 34.7_R8 ! ocn ref salinity (psu) - real(R8),parameter :: SHR_CONST_ICE_REF_SAL = 4.0_R8 ! ice ref salinity (psu) - - real(R8),parameter :: SHR_CONST_SPVAL = 1.0e30_R8 ! special missing value - -END MODULE shr_const_mod diff --git a/tools/mksurfdata_map/src/shr_file_mod.F90 b/tools/mksurfdata_map/src/shr_file_mod.F90 deleted file mode 100644 index a5e8d1987d..0000000000 --- a/tools/mksurfdata_map/src/shr_file_mod.F90 +++ /dev/null @@ -1,1023 +0,0 @@ -!BOP =========================================================================== -! -! !MODULE: shr_file_mod.F90 --- Module to handle various file utilily functions. -! -! !DESCRIPTION: -! -! Miscilaneous methods to handle file and directory utilities as well as FORTRAN -! unit control. Also put/get local files into/from archival location -! -! File utilites used with CCSM Message passing: -! -! shr_file_stdio is the main example here, it changes the working directory, -! changes stdin and stdout to a given filename. -! -! This is needed because some implementations of MPI with MPMD so that -! each executable can run in a different working directory and redirect -! output to different files. -! -! File name archival convention, eg. -! call shr_file_put(rcode,"foo","mss:/USER/foo",rtpd=3650) -! is extensible -- the existence of the option file name prefix, eg. "mss:", -! and optional arguments, eg. rtpd-3650 can be used to access site-specific -! storage devices. Based on CCM (atmosphere) getfile & putfile routines, but -! intended to be a more extensible, shared code. -! -! !REVISION HISTORY: -! 2006-05-08 E. Kluzek, Add in shr_file_mod and getUnit, freeUnif methods. -! 2000-??-?? B. Kauffman, original version circa 2000 -! -! !INTERFACE: ------------------------------------------------------------------ - -MODULE shr_file_mod - -! !USES: - - use shr_kind_mod ! defines kinds - use shr_sys_mod ! system calls - use shr_log_mod, only: s_loglev => shr_log_Level - use shr_log_mod, only: s_logunit => shr_log_Unit - - IMPLICIT none - - PRIVATE ! By default everything is private to this module - -! !PUBLIC TYPES: - - ! no public types - -! !PUBLIC MEMBER FUNCTIONS: - - public :: shr_file_put ! Put a file to an archive location - public :: shr_file_get ! Get a file from an archive location - public :: shr_file_queryPrefix ! Get prefix type for a filename - public :: shr_file_getUnit ! Get a logical unit for reading or writing - public :: shr_file_freeUnit ! Free a logical unit - public :: shr_file_stdio ! change dir and stdin and stdout - public :: shr_file_chDir ! change current working directory - public :: shr_file_dirio ! change stdin and stdout - public :: shr_file_chStdIn ! change stdin (attach to a file) - public :: shr_file_chStdOut ! change stdout (attach to a file) - public :: shr_file_setIO ! open a log file from namelist - public :: shr_file_setLogUnit ! Reset the log unit number - public :: shr_file_setLogLevel ! Reset the logging debug level - public :: shr_file_getLogUnit ! Get the log unit number - public :: shr_file_getLogLevel ! Get the logging debug level - -! !PUBLIC DATA MEMBERS: - - ! Integer flags for recognized prefixes on file get/put operations - integer(SHR_KIND_IN), parameter, public :: shr_file_noPrefix = 0 ! no recognized prefix - integer(SHR_KIND_IN), parameter, public :: shr_file_nullPrefix = 1 ! null: - integer(SHR_KIND_IN), parameter, public :: shr_file_cpPrefix = 2 ! cp: - integer(SHR_KIND_IN), parameter, public :: shr_file_mssPrefix = 3 ! mss: - integer(SHR_KIND_IN), parameter, public :: shr_file_hpssPrefix = 4 ! hpss: - -!EOP - !--- unit numbers, users can ask for unit numbers from 0 to min, but getUnit - !--- won't give a unit below min, users cannot ask for unit number above max - !--- for backward compatability. - !--- eventually, recommend min as hard lower limit (tcraig, 9/2007) - integer(SHR_KIND_IN),parameter :: shr_file_minUnit = 10 ! Min unit number to give - integer(SHR_KIND_IN),parameter :: shr_file_maxUnit = 99 ! Max unit number to give - logical, save :: UnitTag(0:shr_file_maxUnit) = .false. ! Logical units in use - -!=============================================================================== -CONTAINS -!=============================================================================== - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_put -- Put a file to an archival location. -! -! !DESCRIPTION: -! a generic, extensible put-local-file-into-archive routine -! USAGE: -! call shr_file_put(rcode,"foo","/home/user/foo") -! if ( rcode /= 0 ) call shr_sys_abort( "error copying foo" ) -! call shr_file_put(rcode,"foo","cp:/home/user/foo",remove=.true.) -! if ( rcode /= 0 ) call shr_sys_abort( "error copying foo" ) -! call shr_file_put(rcode,"foo","mss:/USER/foo",rtpd=3650) -! if ( rcode /= 0 ) call shr_sys_abort( "error archiving foo to MSS" ) -! -! !INTERFACE: ------------------------------------------------------------------ - -SUBROUTINE shr_file_put(rcode,loc_fn,rem_fn,passwd,rtpd,async,remove) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - integer(SHR_KIND_IN),intent(out) :: rcode ! return code (non-zero -- error) - character(*), intent(in) :: loc_fn ! local filename - character(*), intent(in) :: rem_fn ! remote filename - character(*), intent(in),optional :: passwd ! password - integer(SHR_KIND_IN),intent(in),optional :: rtpd ! MSS retention period - logical, intent(in),optional :: async ! true <=> asynchronous put - logical, intent(in),optional :: remove ! true <=> rm after put - -!EOP - - !----- local ----- - integer(SHR_KIND_IN) :: rtpd2 ! MSS retention period - logical :: remove2 ! true <=> rm after put - logical :: async2 ! true <=> asynchronous put - character(SHR_KIND_CL) :: passwd2 ! password - character(SHR_KIND_CL) :: rfn ! rem_fn without the destination prefix - character(SHR_KIND_CL) :: cmd ! command sent to system call - integer(SHR_KIND_IN) :: prefix ! remote file prefix type - - !----- formats ----- - character(*),parameter :: subName = '(shr_file_put) ' - character(*),parameter :: F00 = "('(shr_file_put) ',4a)" - character(*),parameter :: F01 = "('(shr_file_put) ',a,i3,2a)" - character(*),parameter :: F02 = "(a,i4)" - -!------------------------------------------------------------------------------- -! Notes: -! - On some machines the system call will not return a valid error code -! - when things are sent asynchronously, there probably won't be a error code -! returned. -!------------------------------------------------------------------------------- - - remove2 =.false. ; if ( PRESENT(remove )) remove2 = remove - async2 =.true. ; if ( PRESENT(async )) async2 = async - passwd2 = " " ; if ( PRESENT(passwd )) passwd2 = passwd - rtpd2 = 365 ; if ( PRESENT(rtpd )) rtpd2 = rtpd - rcode = 0 - - if ( trim(rem_fn) == trim(loc_fn) ) then - !------------------------------------------------------ - ! (remote file name) == (local file name) => do nothing - !------------------------------------------------------ - cmd = 'do nothing: remote file = local file = '//trim(loc_fn) - rcode = 0 - else if ( prefix == shr_file_cpPrefix .or. prefix == shr_file_noPrefix )then - !------------------------------------------------------ - ! put via unix cp - !------------------------------------------------------ - rfn = rem_fn - if ( rem_fn(1:3) == "cp:") rfn = rem_fn(4:len_trim(rem_fn)) -#if defined(CATAMOUNT) - call shr_jlcp(trim(loc_fn),len_trim(loc_fn),trim(rfn),len_trim(rfn),rcode) - if (remove2) call unlink(trim(loc_fn)) - if (async2 .and. s_loglev > 0) write(s_logunit,F00) 'Error: asynchronous copy not supported.' - cmd = 'shr_jlcp -f '//trim(loc_fn)//' '//trim(rfn) - rcode = 0 -#else - cmd = '/bin/cp -f '//trim(loc_fn)//' '//trim(rfn) - if (remove2) cmd = trim(cmd)//' && /bin/rm -f '//trim(loc_fn) - if (async2 ) cmd = trim(cmd)//' & ' - call shr_sys_system(trim(cmd),rcode) -#endif - else if ( prefix == shr_file_mssPrefix )then - !------------------------------------------------------ - ! put onto NCAR's MSS - !------------------------------------------------------ - if (rtpd2 > 9999) rtpd2 = 9999 - write(cmd,F02) '/usr/local/bin/msrcp -period ',rtpd2 - if (async2 .and. (.not. remove2) ) cmd = trim(cmd)//' -async ' - if (len_trim(passwd2) > 0 ) cmd = trim(cmd)//' -wpwd '//trim(passwd) - cmd = trim(cmd)//' '//trim(loc_fn)//' '//trim(rem_fn) - if (remove2) cmd = trim(cmd)//' && /bin/rm -f '//trim(loc_fn) - if (async2 .and. remove2 ) cmd = trim(cmd)//' & ' - call shr_sys_system(trim(cmd),rcode) - else if ( prefix == shr_file_hpssPrefix )then - !------------------------------------------------------ - ! put onto LANL's hpss - !------------------------------------------------------ - rcode = -1 - cmd = 'rem_fn='//trim(rem_fn)//' loc_fn='//trim(loc_fn) - write(s_logunit,F00) 'ERROR: hpss option not yet implemented' - call shr_sys_abort( subName//'ERROR: hpss option not yet implemented' ) - else if ( prefix == shr_file_nullPrefix )then - ! do nothing - cmd = "null prefix => no file archival, do nothing" - rcode = 0 - end if - - if (s_loglev > 0) write(s_logunit,F01) 'rcode =',rcode,' cmd = ', trim(cmd) - -END SUBROUTINE shr_file_put - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_get -- Get a file from archival location. -! -! !DESCRIPTION: -! a generic, extensible get-local-file-from-archive routine -! -! USAGE: -! call shr_file_get(rcode,"foo","/home/user/foo") -! if ( rcode /= 0 ) call shr_sys_abort( "error getting file foo" ) -! call shr_file_get(rcode,"foo","cp:/home/user/foo",remove=.true.) -! if ( rcode /= 0 ) call shr_sys_abort( "error getting file foo" ) -! call shr_file_get(rcode,"foo","mss:/USER/foo",clobber=.true.) -! if ( rcode /= 0 ) call shr_sys_abort( "error getting file foo from MSS" ) -! -! !INTERFACE: ------------------------------------------------------------------ - -SUBROUTINE shr_file_get(rcode,loc_fn,rem_fn,passwd,async,clobber) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - integer(SHR_KIND_IN),intent(out) :: rcode ! return code (non-zero means error) - character(*) ,intent(in) :: loc_fn ! local filename - character(*) ,intent(in) :: rem_fn ! remote filename - character(*) ,intent(in),optional :: passwd ! password - logical ,intent(in),optional :: async ! true <=> asynchronous get - logical ,intent(in),optional :: clobber ! true <=> clobber existing file - -!EOP - - !----- local ----- - logical :: async2 ! true <=> asynchronous get - logical :: clobber2 ! true <=> clobber existing file - logical :: exists ! true <=> local file a ready exists - character(SHR_KIND_CL) :: passwd2 ! password - character(SHR_KIND_CL) :: rfn ! rem_fn without the destination prefix - character(SHR_KIND_CL) :: cmd ! command sent to system call - integer(SHR_KIND_IN) :: prefix ! remote file prefix type - - !----- formats ----- - character(*),parameter :: subName = '(shr_file_get) ' - character(*),parameter :: F00 = "('(shr_file_get) ',4a)" - character(*),parameter :: F01 = "('(shr_file_get) ',a,i3,2a)" - -!------------------------------------------------------------------------------- -! Notes: -! - On some machines the system call will not return a valid error code -! - When things are sent asynchronously, there probably won't be a error code -! returned. -!------------------------------------------------------------------------------- - - passwd2 = " " ; if (PRESENT(passwd )) passwd2 = passwd - async2 = .false. ; if (PRESENT(async )) async2 = async - clobber2 = .false. ; if (PRESENT(clobber)) clobber2 = clobber - rcode = 0 - - inquire(file=trim(loc_fn),exist=exists) - prefix = shr_file_queryPrefix( rem_fn ) - - if ( exists .and. .not. clobber2 ) then - !------------------------------------------------------ - ! (file exists) and (don't clobber) => do nothing - !------------------------------------------------------ - cmd = 'do nothing: file exists & no-clobber for '//trim(loc_fn) - rcode = 0 - else if ( trim(rem_fn) == trim(loc_fn) ) then - !------------------------------------------------------ - ! (remote file name) == (local file name) => do nothing - !------------------------------------------------------ - cmd = 'do nothing: remote file = local file for '//trim(loc_fn) - rcode = 0 - else if ( prefix == shr_file_cpPrefix .or. prefix == shr_file_noPrefix )then - !------------------------------------------------------ - ! get via unix cp - !------------------------------------------------------ - rfn = rem_fn ! remove prefix from this temp file name - if (rem_fn(1:3) == "cp:") rfn = rem_fn(4:len_trim(rem_fn)) -#if defined(CATAMOUNT) - call shr_jlcp(trim(rfn),len(trim(rfn)),trim(loc_fn),len(trim(loc_fn)),rcode) - if (async2.and.s_loglev>0) write(s_logunit,F00) 'Error: asynchronous copy not supported.' - cmd = 'shr_jlcp -f '//trim(rfn)//' '//trim(loc_fn) - rcode = 0 -#else - cmd = '/bin/cp -f '//trim(rfn)//' '//trim(loc_fn) - if (async2) cmd = trim(cmd)//' & ' - call shr_sys_system(trim(cmd),rcode) -#endif - else if ( prefix == shr_file_mssPrefix )then - !------------------------------------------------------ - ! get from NCAR's MSS - !------------------------------------------------------ - cmd = '/usr/local/bin/msrcp ' - if (async2) cmd = trim(cmd)//' -async ' - cmd = trim(cmd)//' '//trim(rem_fn)//' '//trim(loc_fn) - call shr_sys_system(trim(cmd),rcode) - else if ( prefix == shr_file_hpssPrefix )then - !------------------------------------------------------ - ! get from LANL's hpss - !------------------------------------------------------ - rcode = -1 - cmd = 'rem_fn='//trim(rem_fn)//' loc_fn='//trim(loc_fn) - write(s_logunit,F00) 'ERROR: hpss option not yet implemented' - call shr_sys_abort( subName//'ERROR: hpss option not yet implemented' ) - else if ( prefix == shr_file_nullPrefix )then - ! do nothing - cmd = "null prefix => no file retrieval, do nothing" - rcode = 0 - end if - - if (s_loglev > 0) write(s_logunit,F01) 'rcode =',rcode,' cmd = ', trim(cmd) - -END SUBROUTINE shr_file_get - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_queryPrefix -- Get the prefix type from a filepath. -! -! !DESCRIPTION: -! -! !INTERFACE: ------------------------------------------------------------------ - -integer(SHR_KIND_IN) FUNCTION shr_file_queryPrefix( filepath, prefix ) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*), intent(in) :: filepath ! Input filepath - character(*), intent(out), optional :: prefix ! Output prefix description - -!EOP - - !----- local ----- - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - if ( filepath(1:5) == "null:" )then - shr_file_queryPrefix = shr_file_nullPrefix - if ( present(prefix) ) prefix = "null:" - else if( filepath(1:3) == "cp:" )then - shr_file_queryPrefix = shr_file_cpPrefix - if ( present(prefix) ) prefix = "cp:" - else if( filepath(1:4) == "mss:" )then - shr_file_queryPrefix = shr_file_mssPrefix - if ( present(prefix) ) prefix = "mss:" - else if( filepath(1:5) == "hpss:" )then - shr_file_queryPrefix = shr_file_hpssPrefix - if ( present(prefix) ) prefix = "hpss:" - else - shr_file_queryPrefix = shr_file_noPrefix - if ( present(prefix) ) prefix = "" - end if - -END FUNCTION shr_file_queryPrefix - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_getUnit -- Get a free FORTRAN unit number -! -! !DESCRIPTION: Get the next free FORTRAN unit number. -! -! !REVISION HISTORY: -! 2005-Dec-14 - E. Kluzek - creation -! -! !INTERFACE: ------------------------------------------------------------------ - -INTEGER FUNCTION shr_file_getUnit ( unit ) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - integer(SHR_KIND_IN),intent(in),optional :: unit ! desired unit number - -!EOP - - !----- local ----- - integer(SHR_KIND_IN) :: n ! loop index - logical :: opened ! If unit opened or not - - !----- formats ----- - character(*),parameter :: subName = '(shr_file_getUnit) ' - character(*),parameter :: F00 = "('(shr_file_getUnit) ',A,I4,A)" - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - if (present (unit)) then - inquire( unit, opened=opened ) - if (unit < 0 .or. unit > shr_file_maxUnit) then - write(s_logunit,F00) 'invalid unit number request:', unit - call shr_sys_abort( 'ERROR: bad input unit number' ) - else if (opened .or. UnitTag(unit) .or. unit == 0 .or. unit == 5 & - .or. unit == 6) then - write(s_logunit,F00) 'unit number ', unit, ' is already in use' - call shr_sys_abort( 'ERROR: Input unit number already in use' ) - else - shr_file_getUnit = unit - UnitTag (unit) = .true. - return - end if - - else - ! --- Choose first available unit other than 0, 5, or 6 ------ - do n=shr_file_maxUnit, shr_file_minUnit, -1 - inquire( n, opened=opened ) - if (n == 5 .or. n == 6 .or. opened) then - cycle - end if - if ( .not. UnitTag(n) ) then - shr_file_getUnit = n - UnitTag(n) = .true. - return - end if - end do - end if - - call shr_sys_abort( subName//': Error: no available units found' ) - -END FUNCTION shr_file_getUnit - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_freeUnit -- Free up a FORTRAN unit number -! -! !DESCRIPTION: Free up the given unit number -! -! !REVISION HISTORY: -! 2005-Dec-14 - E. Kluzek - creation -! -! !INTERFACE: ------------------------------------------------------------------ - -SUBROUTINE shr_file_freeUnit ( unit) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - integer(SHR_KIND_IN),intent(in) :: unit ! unit number to be freed - -!EOP - - !----- local ----- - - !----- formats ----- - character(*), parameter :: subName = '(shr_file_freeUnit) ' - character(*), parameter :: F00 = "('(shr_file_freeUnit) ',A,I4,A)" - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - if (unit < 0 .or. unit > shr_file_maxUnit) then - if (s_loglev > 0) write(s_logunit,F00) 'invalid unit number request:', unit - else if (unit == 0 .or. unit == 5 .or. unit == 6) then - call shr_sys_abort( subName//': Error: units 0, 5, and 6 must not be freed' ) - else if (UnitTag(unit)) then - UnitTag (unit) = .false. - else - if (s_loglev > 0) write(s_logunit,F00) 'unit ', unit, ' was not in use' - end if - - return - -END SUBROUTINE shr_file_freeUnit - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_stdio -- Change working directory, and redirect stdin/stdout -! -! !DESCRIPTION: -! 1) change the cwd (current working directory) and -! 2) redirect stdin & stdout (units 5 & 6) to named files, -! where the desired cwd & files are specified by namelist file. -! -! Normally this is done to work around limitations in the execution syntax -! of common MPI implementations. For example, SGI's mpirun syntax is not -! flexible enough to allow MPMD models to select different execution -! directories or to redirect stdin & stdout on the command line. -! Such functionality is highly desireable for CCSM purposes. -! ie. mpirun can't handle this: -! unix> cd /usr/tmp/jdoe/csm/case01/atm ; atm < atm.parm > atm.log & -! unix> cd /usr/tmp/jdoe/csm/case01/cpl ; cpl < cpl.parm > cpl.log & -! etc. -! -! ASSUMPTIONS: -! o if the cwd, stdin, or stdout are to be changed, there must be a namelist -! file in the cwd named _stdio.nml where is provided via -! subroutine dummy argument. -! -! !INTERFACE: ------------------------------------------------------------------ - -SUBROUTINE shr_file_stdio(model) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*),intent(in) :: model ! used to construct env varible name - -!EOP - - !--- formats --- - character(*),parameter :: subName = '(shr_file_stdio) ' - character(*),parameter :: F00 = "('(shr_file_stdio) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - call shr_file_chdir (model) ! changes cwd - call shr_file_chStdOut(model) ! open units 5 & 6 to named files - call shr_file_chStdIn (model) ! open units 5 & 6 to named files - -END SUBROUTINE shr_file_stdio - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_chdir -- Change working directory. -! -! !DESCRIPTION: -! change the cwd (current working directory), see shr_file_stdio for notes -! -! !INTERFACE: ------------------------------------------------------------------ - -SUBROUTINE shr_file_chdir(model, rcodeOut) - -! !USES: - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(in) :: model ! used to construct env varible name - integer(SHR_KIND_IN),intent(out),optional :: rcodeOut ! Return error code - -!EOP - - !--- local --- - character(SHR_KIND_CL) :: dir ! directory to cd to - integer (SHR_KIND_IN) :: rcode ! Return error code - character(SHR_KIND_CL) :: filename ! namelist file to read - - !--- formats --- - character(*),parameter :: subName = '(shr_file_chdir) ' - character(*),parameter :: F00 = "('(shr_file_chdir) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - call shr_file_stdioReadNL( model, filename, dirOut=dir, rcodeOut=rcode ) - if (dir /= "nochange") then - call shr_sys_chdir(dir ,rcode) - if (s_loglev > 0) write(s_logunit,F00) "read ",trim(filename),", changed cwd to ",trim(dir) - else - if (s_loglev > 0) write(s_logunit,F00) "read ",trim(filename),", cwd has *not* been changed" - rcode = 1 - endif - if ( present(rcodeOut) ) rcodeOut = rcode - -END SUBROUTINE shr_file_chdir - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_dirio --- Change stdin and stdout. -! -! !DESCRIPTION: -! change the stdin & stdout (units 5 & 6), see shr_file_stdio for notes -! -! !INTERFACE: ------------------------------------------------------------------ - -SUBROUTINE shr_file_dirio(model) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*),intent(in) :: model ! used to construct env varible name - -!EOP - - !--- local --- - - !--- formats --- - character(*),parameter :: subName = '(shr_file_dirio) ' - -!------------------------------------------------------------------------------- -! Notes: -! -!------------------------------------------------------------------------------- - - call shr_file_chStdIn (model) - call shr_file_chStdOut(model) - -END SUBROUTINE shr_file_dirio - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_chStdIn -- Change stdin -! -! !DESCRIPTION: -! change the stdin (unit 5), see shr_file_stdio for notes -! -! !INTERFACE: ------------------------------------------------------------------ - -SUBROUTINE shr_file_chStdIn( model, NLFilename, rcodeOut ) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(in) :: model ! used to construct env var name - character(SHR_KIND_CL),intent(out),optional :: NLFilename ! open unit 5 to this - integer (SHR_KIND_IN),intent(out),optional :: rcodeOut ! return code - -!EOP - - !--- local --- - character(SHR_KIND_CL) :: stdin ! open unit 5 to this file - character(SHR_KIND_CL) :: nlfile ! Namelist filename for model to read from - character(SHR_KIND_CL) :: filename ! namelist file to read - integer (SHR_KIND_IN) :: rcode ! return code - - !--- formats --- - character(*),parameter :: subName = '(shr_file_chStdIn) ' - character(*),parameter :: F00 = "('(shr_file_chStdIn) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - call shr_file_stdioReadNL( model, filename, stdinOut=stdin, & - nlfileOut=nlfile, rcodeOut=rcode ) - if (stdin /= "nochange") then - open(unit=5,file=stdin ,status='UNKNOWN',iostat=rcode) - if ( rcode /= 0 )then - if (s_loglev > 0) & - write(s_logunit,F00) "read ",trim(filename),': error opening file as unit 5:', & - trim(nlfile) - else - if (s_loglev > 0) & - write(s_logunit,F00) "read ",trim(filename),': unit 5 connected to ', & - trim(stdin) - end if - else - if (s_loglev > 0) write(s_logunit,F00) "read ",trim(filename), & - ': unit 5 has *not* been redirected' - endif - if ( len_trim(nlfile) > 0) then - if (s_loglev > 0) write(s_logunit,F00) "read ",trim(filename), & - ': read namelist from file:',trim(nlfile) - if ( .not. present(NLFilename) )then - if (s_loglev > 0) write(s_logunit,F00) "error: namelist filename NOT present" - rcode = 7 - end if - else - if (s_loglev > 0) write(s_logunit,F00) "read ",trim(filename),", " - if ( present(NLFilename) )then - if (s_loglev > 0) write(s_logunit,F00) "error: namelist filename present, but null" - rcode = 8 - end if - endif - if ( present(NLFilename) ) NLFilename = nlfile - if ( present(rcodeOut) ) rcodeOut = rcode - -END SUBROUTINE shr_file_chStdIn - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_stdout -- Change stdout -! -! !DESCRIPTION: -! change the stdout (unit 6), see shr_file_stdio for notes -! -! !INTERFACE: ------------------------------------------------------------------ - -SUBROUTINE shr_file_chStdOut(model,rcodeOut) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - !--- arguments --- - character(*) ,intent(in) :: model ! used to construct env varible name - integer(SHR_KIND_IN),intent(out),optional :: rcodeOut ! Return error code -!EOP - - !--- local --- - character(SHR_KIND_CL) :: filename ! namelist file to read - character(SHR_KIND_CL) :: stdout ! open unit 6 to this file - integer (SHR_KIND_IN) :: rcode ! return code - - !--- formats --- - character(*),parameter :: subName = '(shr_file_chStdOut) ' - character(*),parameter :: F00 = "('(shr_file_chStdOut) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - call shr_file_stdioReadNL( model, filename, stdoutOut=stdout, & - rcodeOut=rcode ) - if (stdout /= "nochange") then - close(6) - open(unit=6,file=stdout,position='APPEND') - if (s_loglev > 0) write(s_logunit,F00) "read ",trim(filename), & - ': unit 6 connected to ',trim(stdout) - call shr_sys_flush(s_logunit) - else - if (s_loglev > 0) write(s_logunit,F00) "read ",trim(filename), & - ': unit 6 has *not* been redirected' - rcode = 1 - endif - - if ( present(rcodeOut) ) rcodeOut = rcode - -END SUBROUTINE shr_file_chStdOut - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_stdioReadNL -- read in stdio namelist -! -! !DESCRIPTION: -! Read in the stdio namelist for any given model type. Return any of the -! needed input namelist variables as optional arguments. Return "nochange" in -! dir, stdin, or stdout if shouldn't change. -! -! !INTERFACE: ------------------------------------------------------------------ - -SUBROUTINE shr_file_stdioReadNL( model, filename, dirOut, stdinOut, stdoutOut, & - NLFileOut, rcodeOut ) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(in) :: model ! used to construct env varible name - character(SHR_KIND_CL),intent(out) :: filename ! nml file to read from unit 5 - character(SHR_KIND_CL),intent(out),optional :: NLFileOut ! open unit 6 to this file - character(SHR_KIND_CL),intent(out),optional :: dirOut ! directory to cd to - character(SHR_KIND_CL),intent(out),optional :: stdinOut ! open unit 5 to this file - character(SHR_KIND_CL),intent(out),optional :: stdoutOut ! open unit 6 to this file - integer (SHR_KIND_IN),intent(out),optional :: rcodeOut ! return code - -!EOP - - !--- local --- - logical :: exists ! true iff file exists - character(SHR_KIND_CL) :: dir ! directory to cd to - character(SHR_KIND_CL) :: stdin ! open unit 5 to this file - character(SHR_KIND_CL) :: stdout ! open unit 6 to this file - character(SHR_KIND_CL) :: NLFile ! namelist file to read seperately - integer (SHR_KIND_IN) :: rcode ! return code - integer (SHR_KIND_IN) :: unit ! Unit to read from - - namelist / stdio / dir,stdin,stdout,NLFile - - !--- formats --- - character(*),parameter :: subName = '(shr_file_stdioReadNL) ' - character(*),parameter :: F00 = "('(shr_file_stdioReadNL) ',4a)" - character(*),parameter :: F01 = "('(shr_file_stdioReadNL) ',2a,i6)" - -!------------------------------------------------------------------------------- -! Notes: -! -!------------------------------------------------------------------------------- - - rcode = 0 - dir = "nochange" - stdin = "nochange" - stdout = "nochange" - NLFile = " " - - filename = trim(model)//"_stdio.nml" ! eg. file="cpl_stdio.nml" - inquire(file=filename,exist=exists) - - if (.not. exists) then - if (s_loglev > 0) write(s_logunit,F00) "file ",trim(filename),& - & " doesn't exist, can not read stdio namelist from it" - rcode = 9 - else - unit = shr_file_getUnit() - open (unit,file=filename,action="READ") - read (unit,nml=stdio,iostat=rcode) - close(unit) - call shr_file_freeUnit( unit ) - if (rcode /= 0) then - write(s_logunit,F01) 'ERROR: reading ',trim(filename),': iostat=',rcode - call shr_sys_abort(subName//" ERROR reading "//trim(filename) ) - end if - endif - if ( len_trim(NLFile) > 0 .and. trim(stdin) /= "nochange" )then - write(s_logunit,F00) "Error: input namelist:" - write(s_logunit,nml=stdio) - call shr_sys_abort(subName//" ERROR trying to both redirect AND "// & - "open namelist filename" ) - end if - if ( present(NLFileOut) ) NLFileOut = NLFile - if ( present(dirOut) ) dirOut = dir - if ( present(stdinOut) ) stdinOut = stdin - if ( present(stdoutOut) ) stdoutOut = stdout - if ( present(rcodeOut) ) rcodeOut = rcode - -END SUBROUTINE shr_file_stdioReadNL - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_setIO -- read in stdio namelist -! -! !DESCRIPTION: -! This opens a namelist file specified as an argument and then opens -! a log file associated with the unit argument. This may be extended -! in the future. -! -! !INTERFACE: ------------------------------------------------------------------ - -SUBROUTINE shr_file_setIO( nmlfile, funit) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(len=*) ,intent(in) :: nmlfile ! namelist filename - integer(SHR_KIND_IN),intent(in) :: funit ! unit number for log file - -!EOP - - !--- local --- - logical :: exists ! true if file exists - character(SHR_KIND_CL) :: diri ! directory to cd to - character(SHR_KIND_CL) :: diro ! directory to cd to - character(SHR_KIND_CL) :: logfile ! open unit 6 to this file - integer(SHR_KIND_IN) :: unit ! unit number - integer(SHR_KIND_IN) :: rcode ! error code - - namelist / modelio / diri,diro,logfile - - !--- formats --- - character(*),parameter :: subName = '(shr_file_setIO) ' - character(*),parameter :: F00 = "('(shr_file_setIO) ',4a)" - character(*),parameter :: F01 = "('(shr_file_setIO) ',2a,i6)" - -!------------------------------------------------------------------------------- -! Notes: -! -!------------------------------------------------------------------------------- - - diri = "." - diro = "." - logfile = "" - - inquire(file=nmlfile,exist=exists) - - if (.not. exists) then - if (s_loglev > 0) write(s_logunit,F00) "file ",trim(nmlfile)," non existant" - return - else - unit = shr_file_getUnit() - open (unit,file=nmlfile,action="READ") - read (unit,nml=modelio,iostat=rcode) - close(unit) - call shr_file_freeUnit( unit ) - if (rcode /= 0) then - write(s_logunit,F01) 'ERROR: reading ',trim(nmlfile),': iostat=',rcode - call shr_sys_abort(subName//" ERROR reading "//trim(nmlfile) ) - end if - endif - - if (len_trim(logfile) > 0) then - open(funit,file=trim(diro)//"/"//trim(logfile)) - else - if (s_loglev > 0) write(s_logunit,F00) "logfile not opened" - endif - -END SUBROUTINE shr_file_setIO - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_setLogUnit -- Set the Log I/O Unit number -! -! !INTERFACE: ------------------------------------------------------------------ - -SUBROUTINE shr_file_setLogUnit(unit) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - integer(SHR_KIND_IN),intent(in) :: unit ! new unit number - -!EOP - - !--- formats --- - character(*),parameter :: subName = '(shr_file_setLogUnit) ' - character(*),parameter :: F00 = "('(shr_file_setLogUnit) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: Caller must be sure it's a valid unit number -!------------------------------------------------------------------------------- - - if (s_loglev > 1 .and. s_logunit-unit /= 0) then - write(s_logunit,*) subName,': reset log unit number from/to ',s_logunit, unit - write( unit,*) subName,': reset log unit number from/to ',s_logunit, unit - endif - - s_logunit = unit - -END SUBROUTINE shr_file_setLogUnit - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_setLogLevel -- Set the Log I/O Unit number -! -! !INTERFACE: ------------------------------------------------------------------ - -SUBROUTINE shr_file_setLogLevel(newlevel) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - integer(SHR_KIND_IN),intent(in) :: newlevel ! new log level - -!EOP - - !--- formats --- - character(*),parameter :: subName = '(shr_file_setLogLevel) ' - character(*),parameter :: F00 = "('(shr_file_setLogLevel) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - if (s_loglev+newlevel > 2 .and. s_loglev-newlevel /= 0) & - write(s_logunit,*) subName,': reset log level from/to ',s_loglev, newlevel - - s_loglev = newlevel - -END SUBROUTINE shr_file_setLogLevel - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_getLogUnit -- Set the Log I/O Unit number -! -! !INTERFACE: ------------------------------------------------------------------ - -SUBROUTINE shr_file_getLogUnit(unit) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - integer(SHR_KIND_IN),intent(out) :: unit ! new unit number - -!EOP - - !--- formats --- - character(*),parameter :: subName = '(shr_file_getLogUnit) ' - character(*),parameter :: F00 = "('(shr_file_getLogUnit) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - unit = s_logunit - -END SUBROUTINE shr_file_getLogUnit - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_file_getLogLevel -- Set the Log I/O Unit number -! -! !INTERFACE: ------------------------------------------------------------------ - -SUBROUTINE shr_file_getLogLevel(curlevel) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - integer(SHR_KIND_IN),intent(out) :: curlevel ! new log level - -!EOP - - !--- formats --- - character(*),parameter :: subName = '(shr_file_getLogLevel) ' - character(*),parameter :: F00 = "('(shr_file_getLogLevel) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - curlevel = s_loglev - -END SUBROUTINE shr_file_getLogLevel - -!=============================================================================== -!=============================================================================== - -END MODULE shr_file_mod diff --git a/tools/mksurfdata_map/src/shr_kind_mod.F90 b/tools/mksurfdata_map/src/shr_kind_mod.F90 deleted file mode 100644 index d1219223da..0000000000 --- a/tools/mksurfdata_map/src/shr_kind_mod.F90 +++ /dev/null @@ -1,19 +0,0 @@ -!=============================================================================== - -MODULE shr_kind_mod - - !---------------------------------------------------------------------------- - ! precision/kind constants add data public - !---------------------------------------------------------------------------- - public - integer,parameter :: SHR_KIND_R8 = selected_real_kind(12) ! 8 byte real - integer,parameter :: SHR_KIND_R4 = selected_real_kind( 6) ! 4 byte real - integer,parameter :: SHR_KIND_RN = kind(1.0) ! native real - integer,parameter :: SHR_KIND_I8 = selected_int_kind (13) ! 8 byte integer - integer,parameter :: SHR_KIND_I4 = selected_int_kind ( 6) ! 4 byte integer - integer,parameter :: SHR_KIND_IN = kind(1) ! native integer - integer,parameter :: SHR_KIND_CS = 80 ! short char - integer,parameter :: SHR_KIND_CL = 256 ! long char - integer,parameter :: SHR_KIND_CX = 512 ! extra-long char - -END MODULE shr_kind_mod diff --git a/tools/mksurfdata_map/src/shr_log_mod.F90 b/tools/mksurfdata_map/src/shr_log_mod.F90 deleted file mode 100644 index 244314a8de..0000000000 --- a/tools/mksurfdata_map/src/shr_log_mod.F90 +++ /dev/null @@ -1,13 +0,0 @@ -MODULE shr_log_mod - - use shr_kind_mod - - !---------------------------------------------------------------------------- - ! low-level shared variables for logging, these may not be parameters - !---------------------------------------------------------------------------- - public - - integer(SHR_KIND_IN) :: shr_log_Level = 1 - integer(SHR_KIND_IN) :: shr_log_Unit = 6 - -END MODULE shr_log_mod diff --git a/tools/mksurfdata_map/src/shr_string_mod.F90 b/tools/mksurfdata_map/src/shr_string_mod.F90 deleted file mode 100644 index 44697ceaee..0000000000 --- a/tools/mksurfdata_map/src/shr_string_mod.F90 +++ /dev/null @@ -1,1753 +0,0 @@ -!=============================================================================== -!BOP =========================================================================== -! -! !MODULE: shr_string_mod -- string and list methods -! -! !DESCRIPTION: -! General string and specific list method. A list is a single string -! that is delimited by a character forming multiple fields, ie, -! character(len=*) :: mylist = "t:s:u1:v1:u2:v2:taux:tauy" -! The delimiter is called listDel in this module, is default ":", -! but can be set by a call to shr_string_listSetDel. -! -! !REVISION HISTORY: -! 2005-Apr-28 - T. Craig - first version -! -! !INTERFACE: ------------------------------------------------------------------ - -module shr_string_mod - -! !USES: - - use shr_kind_mod ! F90 kinds - use shr_sys_mod ! shared system calls - use shr_timer_mod, only : shr_timer_get, shr_timer_start, shr_timer_stop - use shr_log_mod, only : s_loglev => shr_log_Level - use shr_log_mod, only : s_logunit => shr_log_Unit - - implicit none - private - -! !PUBLIC TYPES: - - ! no public types - -! !PUBLIC MEMBER FUNCTIONS: - - public :: shr_string_countChar ! Count number of char in string, fn - public :: shr_string_toUpper ! Convert string to upper-case - public :: shr_string_toLower ! Convert string to lower-case - public :: shr_string_getParentDir ! For a pathname get the parent directory name - public :: shr_string_lastIndex ! Index of last substr in str - public :: shr_string_endIndex ! Index of end of substr in str - public :: shr_string_leftAlign ! remove leading white space - public :: shr_string_alphanum ! remove all non alpha-numeric characters - public :: shr_string_betweenTags ! get the substring between the two tags - public :: shr_string_parseCFtunit ! parse CF time units - public :: shr_string_clean ! Set string to all white space - - public :: shr_string_listIsValid ! test for a valid "list" - public :: shr_string_listGetNum ! Get number of fields in list, fn - public :: shr_string_listGetIndex ! Get index of field - public :: shr_string_listGetIndexF ! function version of listGetIndex - public :: shr_string_listGetName ! get k-th field name - public :: shr_string_listIntersect ! get intersection of two field lists - public :: shr_string_listUnion ! get union of two field lists - public :: shr_string_listMerge ! merge two lists to form third - public :: shr_string_listAppend ! append list at end of another - public :: shr_string_listPrepend ! prepend list in front of another - public :: shr_string_listSetDel ! Set field delimeter in lists - public :: shr_string_listGetDel ! Get field delimeter in lists - - public :: shr_string_setAbort ! set local abort flag - public :: shr_string_setDebug ! set local debug flag - -! !PUBLIC DATA MEMBERS: - - ! no public data members - -!EOP - - character(len=1) ,save :: listDel = ":" ! note single exec implications - character(len=2) ,save :: listDel2 = "::" ! note single exec implications - logical ,save :: doabort = .true. - integer(SHR_KIND_IN),save :: debug = 0 - -!=============================================================================== -contains -!=============================================================================== - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_countChar -- Count number of occurances of a character -! -! !DESCRIPTION: -! count number of occurances of a single character in a string -! \newline -! n = shr\_string\_countChar(string,character) -! -! !REVISION HISTORY: -! 2005-Feb-28 - First version from dshr_bundle -! -! !INTERFACE: ------------------------------------------------------------------ - -integer function shr_string_countChar(str,char,rc) - - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(in) :: str ! string to search - character(1) ,intent(in) :: char ! char to search for - integer(SHR_KIND_IN),intent(out),optional :: rc ! return code - -!EOP - - !----- local ----- - integer(SHR_KIND_IN) :: count ! counts occurances of char - integer(SHR_KIND_IN) :: n ! generic index - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_countChar) " - character(*),parameter :: F00 = "('(shr_string_countChar) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - count = 0 - do n = 1, len_trim(str) - if (str(n:n) == char) count = count + 1 - end do - shr_string_countChar = count - - if (present(rc)) rc = 0 - - if (debug>1) call shr_timer_stop (t01) - -end function shr_string_countChar - -!=============================================================================== -!BOP =========================================================================== -! !IROUTINE: shr_string_toUpper -- Convert string to upper case -! -! !DESCRIPTION: -! Convert the input string to upper-case. -! Use achar and iachar intrinsics to ensure use of ascii collating sequence. -! -! !REVISION HISTORY: -! 2005-Dec-20 - Move CAM version over to shared code. -! -! !INTERFACE: ------------------------------------------------------------------ - -function shr_string_toUpper(str) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - character(len=*), intent(in) :: str ! String to convert to upper case - character(len=len(str)) :: shr_string_toUpper - - !----- local ----- - integer(SHR_KIND_IN) :: i ! Index - integer(SHR_KIND_IN) :: aseq ! ascii collating sequence - integer(SHR_KIND_IN) :: LowerToUpper ! integer to convert case - character(len=1) :: ctmp ! Character temporary - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_toUpper) " - character(*),parameter :: F00 = "('(shr_string_toUpper) ',4a)" - -!------------------------------------------------------------------------------- -! -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - LowerToUpper = iachar("A") - iachar("a") - - do i = 1, len(str) - ctmp = str(i:i) - aseq = iachar(ctmp) - if ( aseq >= iachar("a") .and. aseq <= iachar("z") ) & - ctmp = achar(aseq + LowertoUpper) - shr_string_toUpper(i:i) = ctmp - end do - - if (debug>1) call shr_timer_stop (t01) - -end function shr_string_toUpper - -!=============================================================================== -!BOP =========================================================================== -! !IROUTINE: shr_string_toLower -- Convert string to lower case -! -! !DESCRIPTION: -! Convert the input string to lower-case. -! Use achar and iachar intrinsics to ensure use of ascii collating sequence. -! -! !REVISION HISTORY: -! 2006-Apr-20 - Creation -! -! !INTERFACE: ------------------------------------------------------------------ -function shr_string_toLower(str) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - character(len=*), intent(in) :: str ! String to convert to lower case - character(len=len(str)) :: shr_string_toLower - - !----- local ----- - integer(SHR_KIND_IN) :: i ! Index - integer(SHR_KIND_IN) :: aseq ! ascii collating sequence - integer(SHR_KIND_IN) :: UpperToLower ! integer to convert case - character(len=1) :: ctmp ! Character temporary - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_toLower) " - character(*),parameter :: F00 = "('(shr_string_toLower) ',4a)" - -!------------------------------------------------------------------------------- -! -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - UpperToLower = iachar("a") - iachar("A") - - do i = 1, len(str) - ctmp = str(i:i) - aseq = iachar(ctmp) - if ( aseq >= iachar("A") .and. aseq <= iachar("Z") ) & - ctmp = achar(aseq + UpperToLower) - shr_string_toLower(i:i) = ctmp - end do - - if (debug>1) call shr_timer_stop (t01) - -end function shr_string_toLower - -!=============================================================================== -!BOP =========================================================================== -! !IROUTINE: shr_string_getParentDir -- For pathname get the parent directory name -! -! !DESCRIPTION: -! Get the parent directory name for a pathname. -! -! !REVISION HISTORY: -! 2006-May-09 - Creation -! -! !INTERFACE: ------------------------------------------------------------------ - -function shr_string_getParentDir(str) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - character(len=*), intent(in) :: str ! String to convert to lower case - character(len=len(str)) :: shr_string_getParentDir - - !----- local ----- - integer(SHR_KIND_IN) :: i ! Index - integer(SHR_KIND_IN) :: nlen ! Length of string - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_getParentDir) " - character(*),parameter :: F00 = "('(shr_string_getParentDir) ',4a)" - -!------------------------------------------------------------------------------- -! -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - nlen = len_trim(str) - if ( str(nlen:nlen) == "/" ) nlen = nlen - 1 - i = index( str(1:nlen), "/", back=.true. ) - if ( i == 0 )then - shr_string_getParentDir = str - else - shr_string_getParentDir = str(1:i-1) - end if - - if (debug>1) call shr_timer_stop (t01) - -end function shr_string_getParentDir - -!=============================================================================== -!BOP =========================================================================== -! -! -! !IROUTINE: shr_string_lastIndex -- Get index of last substr within string -! -! !DESCRIPTION: -! Get index of last substr within string -! \newline -! n = shr\_string\_lastIndex(string,substring) -! -! !REVISION HISTORY: -! 2005-Feb-28 - First version from dshr_domain -! -! !INTERFACE: ------------------------------------------------------------------ - -integer function shr_string_lastIndex(string,substr,rc) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(in) :: string ! string to search - character(*) ,intent(in) :: substr ! sub-string to search for - integer(SHR_KIND_IN),intent(out),optional :: rc ! return code - -!EOP - - !--- local --- - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_lastIndex) " - character(*),parameter :: F00 = "('(shr_string_lastIndex) ',4a)" - -!------------------------------------------------------------------------------- -! Note: -! - "new" F90 back option to index function makes this home-grown solution obsolete -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - shr_string_lastIndex = index(string,substr,.true.) - - if (present(rc)) rc = 0 - - if (debug>1) call shr_timer_stop (t01) - -end function shr_string_lastIndex - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_endIndex -- Get the ending index of substr within string -! -! !DESCRIPTION: -! Get the ending index of substr within string -! \newline -! n = shr\_string\_endIndex(string,substring) -! -! !REVISION HISTORY: -! 2005-May-10 - B. Kauffman, first version. -! -! !INTERFACE: ------------------------------------------------------------------ - -integer function shr_string_endIndex(string,substr,rc) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(in) :: string ! string to search - character(*) ,intent(in) :: substr ! sub-string to search for - integer(SHR_KIND_IN),intent(out),optional :: rc ! return code - -!EOP - - !--- local --- - integer(SHR_KIND_IN) :: i ! generic index - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_endIndex) " - character(*),parameter :: F00 = "('(shr_string_endIndex) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -! * returns zero if substring not found, uses len_trim() intrinsic -! * very similar to: i = index(str,substr,back=.true.) -! * do we need this function? -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - i = index(trim(string),trim(substr)) - if ( i == 0 ) then - shr_string_endIndex = 0 ! substr is not in string - else - shr_string_endIndex = i + len_trim(substr) - 1 - end if - -! ------------------------------------------------------------------- -! i = index(trim(string),trim(substr),back=.true.) -! if (i == len(string)+1) i = 0 -! shr_string_endIndex = i -! ------------------------------------------------------------------- - - if (present(rc)) rc = 0 - - if (debug>1) call shr_timer_stop (t01) - -end function shr_string_endIndex - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_leftAlign -- remove leading white space -! -! !DESCRIPTION: -! Remove leading white space -! \newline -! call shr\_string\_leftAlign(string) -! -! !REVISION HISTORY: -! 2005-Apr-28 - B. Kauffman - First version -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_leftAlign(str,rc) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(inout) :: str - integer(SHR_KIND_IN),intent(out) ,optional :: rc ! return code - -!EOP - - !----- local ---- - integer(SHR_KIND_IN) :: rCode ! return code - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_leftAlign) " - character(*),parameter :: F00 = "('(shr_string_leftAlign) ',4a)" - -!------------------------------------------------------------------------------- -! note: -! * ?? this routine isn't needed, use the intrisic adjustL instead ?? -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - -! ------------------------------------------------------------------- -! --- I used this until I discovered the intrinsic function below - BK -! do while (len_trim(str) > 0 ) -! if (str(1:1) /= ' ') exit -! str = str(2:len_trim(str)) -! end do -! rCode = 0 -! !! (len_trim(str) == 0 ) rCode = 1 ! ?? appropriate ?? -! ------------------------------------------------------------------- - - str = adjustL(str) - if (present(rc)) rc = 0 - - if (debug>1) call shr_timer_stop (t01) - -end subroutine shr_string_leftAlign - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_alphanum -- remove non alpha numeric characters -! -! !DESCRIPTION: -! Remove all non alpha numeric characters from string -! \newline -! call shr\_string\_alphanum(string) -! -! !REVISION HISTORY: -! 2005-Aug-01 - T. Craig - First version -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_alphanum(str,rc) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(inout) :: str - integer(SHR_KIND_IN),intent(out) ,optional :: rc ! return code - -!EOP - - !----- local ---- - integer(SHR_KIND_IN) :: rCode ! return code - integer(SHR_KIND_IN) :: n,icnt ! counters - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_alphaNum) " - character(*),parameter :: F00 = "('(shr_string_alphaNum) ',4a)" - -!------------------------------------------------------------------------------- -! -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - icnt = 0 - do n=1,len_trim(str) - if ((str(n:n) >= 'a' .and. str(n:n) <= 'z') .or. & - (str(n:n) >= 'A' .and. str(n:n) <= 'Z') .or. & - (str(n:n) >= '0' .and. str(n:n) <= '9')) then - icnt = icnt + 1 - str(icnt:icnt) = str(n:n) - endif - enddo - do n=icnt+1,len(str) - str(n:n) = ' ' - enddo - - if (present(rc)) rc = 0 - - if (debug>1) call shr_timer_stop (t01) - -end subroutine shr_string_alphanum - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_betweenTags -- Get the substring between the two tags. -! -! !DESCRIPTION: -! Get the substring found between the start and end tags. -! \newline -! call shr\_string\_betweenTags(string,startTag,endTag,substring,rc) -! -! !REVISION HISTORY: -! 2005-May-11 - B. Kauffman, first version -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_betweenTags(string,startTag,endTag,substr,rc) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(in) :: string ! string to search - character(*) ,intent(in) :: startTag ! start tag - character(*) ,intent(in) :: endTag ! end tag - character(*) ,intent(out) :: substr ! sub-string between tags - integer(SHR_KIND_IN),intent(out),optional :: rc ! retrun code - -!EOP - - !--- local --- - integer(SHR_KIND_IN) :: iStart ! substring start index - integer(SHR_KIND_IN) :: iEnd ! substring end index - integer(SHR_KIND_IN) :: rCode ! return code - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_betweenTags) " - character(*),parameter :: F00 = "('(shr_string_betweenTags) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -! * assumes the leading/trailing white space is not part of start & end tags -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - iStart = shr_string_endIndex(string,trim(adjustL(startTag))) ! end of start tag - iEnd = index(string,trim(adjustL(endTag ))) ! start of end tag - - rCode = 0 - substr = "" - - if (iStart < 1) then - if (s_loglev > 0) then - write(s_logunit,F00) "ERROR: can't find start tag in string" - write(s_logunit,F00) "ERROR: start tag = ",trim(startTag) - write(s_logunit,F00) "ERROR: string = ",trim(string) - endif - rCode = 1 - else if (iEnd < 1) then - if (s_loglev > 0) then - write(s_logunit,F00) "ERROR: can't find end tag in string" - write(s_logunit,F00) "ERROR: end tag = ",trim( endTag) - write(s_logunit,F00) "ERROR: string = ",trim(string) - endif - rCode = 2 - else if ( iEnd <= iStart) then - if (s_loglev > 0) then - write(s_logunit,F00) "ERROR: start tag not before end tag" - write(s_logunit,F00) "ERROR: start tag = ",trim(startTag) - write(s_logunit,F00) "ERROR: end tag = ",trim( endTag) - write(s_logunit,F00) "ERROR: string = ",trim(string) - endif - rCode = 3 - else if ( iStart+1 == iEnd ) then - substr = "" - if (s_loglev > 0) write(s_logunit,F00) "WARNING: zero-length substring found in ",trim(string) - else - substr = string(iStart+1:iEnd-1) - if (len_trim(substr) == 0 .and. s_loglev > 0) & - & write(s_logunit,F00) "WARNING: white-space substring found in ",trim(string) - end if - - if (present(rc)) rc = rCode - - if (debug>1) call shr_timer_stop (t01) - -end subroutine shr_string_betweenTags - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_parseCFtunit -- Parse CF time unit -! -! !DESCRIPTION: -! Parse CF time unit into a delta string name and a base time in yyyymmdd -! and seconds (nearest integer actually). -! \newline -! call shr\_string\_parseCFtunit(string,substring) -! \newline -! Input string is like "days since 0001-06-15 15:20:45.5 -6:00" -! - recognizes "days", "hours", "minutes", "seconds" -! - must have at least yyyy-mm-dd, hh:mm:ss.s is optional -! - expects a "since" in the string -! - ignores time zone part -! -! !REVISION HISTORY: -! 2005-May-15 - T. Craig - first version -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_parseCFtunit(string,unit,bdate,bsec,rc) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(in) :: string ! string to search - character(*) ,intent(out) :: unit ! delta time unit - integer(SHR_KIND_IN),intent(out) :: bdate ! base date yyyymmdd - real(SHR_KIND_R8) ,intent(out) :: bsec ! base seconds - integer(SHR_KIND_IN),intent(out),optional :: rc ! return code - -!EOP - - !--- local --- - integer(SHR_KIND_IN) :: i,i1,i2 ! generic index - character(SHR_KIND_CL) :: tbase ! baseline time - character(SHR_KIND_CL) :: lstr ! local string - integer(SHR_KIND_IN) :: yr,mo,da,hr,min ! time stuff - real(SHR_KIND_R8) :: sec ! time stuff - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_parseCFtunit) " - character(*),parameter :: F00 = "('(shr_string_parseCFtunit) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -! o assume length of CF-1.0 time attribute char string < SHR_KIND_CL -! This is a reasonable assumption. -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - unit = 'none' - bdate = 0 - bsec = 0.0_SHR_KIND_R8 - - i = shr_string_lastIndex(string,'days ') - if (i > 0) unit = 'days' - i = shr_string_lastIndex(string,'hours ') - if (i > 0) unit = 'hours' - i = shr_string_lastIndex(string,'minutes ') - if (i > 0) unit = 'minutes' - i = shr_string_lastIndex(string,'seconds ') - if (i > 0) unit = 'seconds' - - if (trim(unit) == 'none') then - write(s_logunit,F00) ' ERROR time unit unknown' - call shr_string_abort(subName//' time unit unknown') - endif - - i = shr_string_lastIndex(string,' since ') - if (i < 1) then - write(s_logunit,F00) ' ERROR since does not appear in unit attribute for time ' - call shr_string_abort(subName//' no since in attr name') - endif - tbase = trim(string(i+6:)) - call shr_string_leftAlign(tbase) - - if (debug > 0 .and. s_logunit > 0) then - write(s_logunit,*) trim(subName)//' '//'unit '//trim(unit) - write(s_logunit,*) trim(subName)//' '//'tbase '//trim(tbase) - endif - - yr=0; mo=0; da=0; hr=0; min=0; sec=0 - i1 = 1 - - i2 = index(tbase,'-') - 1 - lstr = tbase(i1:i2) - read(lstr,*,ERR=200,END=200) yr - tbase = tbase(i2+2:) - call shr_string_leftAlign(tbase) - - i2 = index(tbase,'-') - 1 - lstr = tbase(i1:i2) - read(lstr,*,ERR=200,END=200) mo - tbase = tbase(i2+2:) - call shr_string_leftAlign(tbase) - - i2 = index(tbase,' ') - 1 - lstr = tbase(i1:i2) - read(lstr,*,ERR=200,END=200) da - tbase = tbase(i2+2:) - call shr_string_leftAlign(tbase) - - i2 = index(tbase,':') - 1 - lstr = tbase(i1:i2) - read(lstr,*,ERR=200,END=100) hr - tbase = tbase(i2+2:) - call shr_string_leftAlign(tbase) - - i2 = index(tbase,':') - 1 - lstr = tbase(i1:i2) - read(lstr,*,ERR=200,END=100) min - tbase = tbase(i2+2:) - call shr_string_leftAlign(tbase) - - i2 = index(tbase,' ') - 1 - lstr = tbase(i1:i2) - read(lstr,*,ERR=200,END=100) sec - -100 continue - - if (debug > 0 .and. s_loglev > 0) write(s_logunit,*) trim(subName),'ymdhms:',yr,mo,da,hr,min,sec - - bdate = abs(yr)*10000 + mo*100 + da - if (yr < 0) bdate = -bdate - bsec = real(hr*3600 + min*60,SHR_KIND_R8) + sec - - if (present(rc)) rc = 0 - - if (debug>1) call shr_timer_stop (t01) - return - -200 continue - write(s_logunit,F00) 'ERROR 200 on char num read ' - call shr_string_abort(subName//' ERROR on char num read') - if (debug>1) call shr_timer_stop (t01) - return - -end subroutine shr_string_parseCFtunit - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_clean -- Clean a string, set it to "blank" -! -! !DESCRIPTION: -! Clean a string, set it to blank -! \newline -! call shr\_string\_clean(string,rc) -! -! !REVISION HISTORY: -! 2005-May-05 - T. Craig -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_clean(string,rc) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(inout) :: string ! list/string - integer(SHR_KIND_IN),optional,intent(out) :: rc ! return code - -!EOP - - !----- local ----- - integer(SHR_KIND_IN) :: n ! counter - integer(SHR_KIND_IN) :: rCode ! return code - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_clean) " - character(*),parameter :: F00 = "('(shr_string_clean) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - rCode = 0 - string = ' ' - if (present(rc)) rc = rCode - if (debug>1) call shr_timer_stop (t01) - -end subroutine shr_string_clean - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_listIsValid -- determine whether string is a valid list -! -! !DESCRIPTION: -! Determine whether string is a valid list -! \newline -! logical_var = shr\_string\_listIsValid(list,rc) -! -! !REVISION HISTORY: -! 2005-May-05 - B. Kauffman -! -! !INTERFACE: ------------------------------------------------------------------ - -logical function shr_string_listIsValid(list,rc) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(in) :: list ! list/string - integer(SHR_KIND_IN),optional,intent(out) :: rc ! return code - -!EOP - - !----- local ----- - integer (SHR_KIND_IN) :: nChar ! lenth of list - integer (SHR_KIND_IN) :: rCode ! return code - integer (SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_listIsValid) " - character(*),parameter :: F00 = "('(shr_string_listIsValid) ',4a)" - -!------------------------------------------------------------------------------- -! check that the list conforms to the list format -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - rCode = 0 - shr_string_listIsValid = .true. - - nChar = len_trim(list) - if (nChar < 1) then ! list is an empty string - rCode = 1 - else if ( list(1:1) == listDel ) then ! first char is delimiter - rCode = 2 - else if (list(nChar:nChar) == listDel ) then ! last char is delimiter - rCode = 3 - else if (index(trim(list)," " ) > 0) then ! white-space in a field name - rCode = 4 - else if (index(trim(list),listDel2) > 0) then ! found zero length field - rCode = 5 - end if - - if (rCode /= 0) then - shr_string_listIsValid = .false. - if (s_loglev > 0) write(s_logunit,F00) "WARNING: invalid list = ",trim(list) - endif - - if (present(rc)) rc = rCode - if (debug>1) call shr_timer_stop (t01) - -end function shr_string_listIsValid - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_listGetName -- Get name of k-th field in list -! -! !DESCRIPTION: -! Get name of k-th field in list -! \newline -! call shr\_string\_listGetName(list,k,name,rc) -! -! !REVISION HISTORY: -! 2005-May-05 - B. Kauffman -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_listGetName(list,k,name,rc) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(in) :: list ! list/string - integer(SHR_KIND_IN) ,intent(in) :: k ! index of field - character(*) ,intent(out) :: name ! k-th name in list - integer(SHR_KIND_IN),optional,intent(out) :: rc ! return code - -!EOP - - !----- local ----- - integer(SHR_KIND_IN) :: i,j,n ! generic indecies - integer(SHR_KIND_IN) :: kFlds ! number of fields in list - integer(SHR_KIND_IN) :: i0,i1 ! name = list(i0:i1) - integer(SHR_KIND_IN) :: rCode ! return code - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_listGetName) " - character(*),parameter :: F00 = "('(shr_string_listGetName) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - rCode = 0 - - !--- check that this is a valid list --- - if (.not. shr_string_listIsValid(list,rCode) ) then - write(s_logunit,F00) "ERROR: invalid list = ",trim(list) - call shr_string_abort(subName//" ERROR: invalid list = "//trim(list)) - end if - - !--- check that this is a valid index --- - kFlds = shr_string_listGetNum(list) - if (k<1 .or. kFlds1) call shr_timer_stop (t01) - -end subroutine shr_string_listGetName - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_listIntersect -- Get intersection of two field lists -! -! !DESCRIPTION: -! Get intersection of two fields lists, write into third list -! \newline -! call shr\_string\_listIntersect(list1,list2,listout) -! -! !REVISION HISTORY: -! 2005-May-05 - T. Craig -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_listIntersect(list1,list2,listout,rc) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(in) :: list1 ! list/string - character(*) ,intent(in) :: list2 ! list/string - character(*) ,intent(out) :: listout ! list/string - integer(SHR_KIND_IN),optional,intent(out) :: rc ! return code - -!EOP - - !----- local ----- - integer(SHR_KIND_IN) :: nf,n1,n2 ! counters - character(SHR_KIND_CS) :: name ! field name - integer(SHR_KIND_IN) :: rCode ! return code - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_listIntersect) " - character(*),parameter :: F00 = "('(shr_string_listIntersect) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - rCode = 0 - - nf = shr_string_listGetNum(list1) - call shr_string_clean(listout) - do n1 = 1,nf - call shr_string_listGetName(list1,n1,name,rCode) - n2 = shr_string_listGetIndexF(list2,name) - if (n2 > 0) then - call shr_string_listAppend(listout,name) - endif - enddo - - if (present(rc)) rc = rCode - if (debug>1) call shr_timer_stop (t01) - -end subroutine shr_string_listIntersect - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_listUnion -- Get union of two field lists -! -! !DESCRIPTION: -! Get union of two fields lists, write into third list -! \newline -! call shr\_string\_listUnion(list1,list2,listout) -! -! !REVISION HISTORY: -! 2005-May-05 - T. Craig -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_listUnion(list1,list2,listout,rc) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(in) :: list1 ! list/string - character(*) ,intent(in) :: list2 ! list/string - character(*) ,intent(out) :: listout ! list/string - integer(SHR_KIND_IN),optional,intent(out) :: rc ! return code - -!EOP - - !----- local ----- - integer(SHR_KIND_IN) :: nf,n1,n2 ! counters - character(SHR_KIND_CS) :: name ! field name - integer(SHR_KIND_IN) :: rCode ! return code - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_listUnion) " - character(*),parameter :: F00 = "('(shr_string_listUnion) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - rCode = 0 - - call shr_string_clean(listout) - - nf = shr_string_listGetNum(list1) - do n1 = 1,nf - call shr_string_listGetName(list1,n1,name,rCode) - n2 = shr_string_listGetIndexF(listout,name) - if (n2 < 1) then - call shr_string_listAppend(listout,name) - endif - enddo - - nf = shr_string_listGetNum(list2) - do n1 = 1,nf - call shr_string_listGetName(list2,n1,name,rCode) - n2 = shr_string_listGetIndexF(listout,name) - if (n2 < 1) then - call shr_string_listAppend(listout,name) - endif - enddo - - if (present(rc)) rc = rCode - if (debug>1) call shr_timer_stop (t01) - -end subroutine shr_string_listUnion - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_listMerge -- Merge lists two list to third -! -! !DESCRIPTION: -! Merge two list to third -! \newline -! call shr\_string\_listMerge(list1,list2,listout) -! call shr\_string\_listMerge(list1,list2,list1) -! -! !REVISION HISTORY: -! 2005-May-05 - T. Craig -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_listMerge(list1,list2,listout,rc) - - implicit none -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(in) :: list1 ! list/string - character(*) ,intent(in) :: list2 ! list/string - character(*) ,intent(out) :: listout ! list/string - integer(SHR_KIND_IN),optional,intent(out) :: rc ! return code - -!EOP - - !----- local ----- - character(SHR_KIND_CX) :: l1,l2 ! local char strings - integer(SHR_KIND_IN) :: rCode ! return code - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_listMerge) " - character(*),parameter :: F00 = "('(shr_string_listMerge) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -! - no input or output string should be longer than SHR_KIND_CX -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - rCode = 0 - - !--- make sure temp strings are large enough --- - if ( (len(l1) < len_trim(list1)) .or. (len(l2) < len_trim(list2))) then - call shr_string_abort(subName//'ERROR: temp string not large enough') - end if - - call shr_string_clean(l1) - call shr_string_clean(l2) - call shr_string_clean(listout) - l1 = trim(list1) - l2 = trim(list2) - call shr_string_leftAlign(l1,rCode) - call shr_string_leftAlign(l2,rCode) - if (len_trim(l1)+len_trim(l2)+1 > len(listout)) & - call shr_string_abort(subName//'ERROR: output list string not large enough') - if (len_trim(l1) == 0) then - listout = trim(l2) - else - listout = trim(l1)//":"//trim(l2) - endif - - if (present(rc)) rc = rCode - if (debug>1) call shr_timer_stop (t01) - -end subroutine shr_string_listMerge - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_listAppend -- Append one list to another -! -! !DESCRIPTION: -! Append one list to another -! \newline -! call shr\_string\_listAppend(list,listadd) -! -! !REVISION HISTORY: -! 2005-May-05 - T. Craig -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_listAppend(list,listadd,rc) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(inout) :: list ! list/string - character(*) ,intent(in) :: listadd ! list/string - integer(SHR_KIND_IN),optional,intent(out) :: rc ! return code - -!EOP - - !----- local ----- - character(SHR_KIND_CX) :: l1 ! local string - integer(SHR_KIND_IN) :: rCode ! return code - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_listAppend) " - character(*),parameter :: F00 = "('(shr_string_listAppend) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -! - no input or output string should be longer than SHR_KIND_CX -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - rCode = 0 - - !--- make sure temp string is large enough --- - if (len(l1) < len_trim(listAdd)) then - call shr_string_abort(subName//'ERROR: temp string not large enough') - end if - - call shr_string_clean(l1) - l1 = trim(listadd) - call shr_string_leftAlign(l1,rCode) - if (len_trim(list)+len_trim(l1)+1 > len(list)) & - call shr_string_abort(subName//'ERROR: output list string not large enough') - if (len_trim(list) == 0) then - list = trim(l1) - else - list = trim(list)//":"//trim(l1) - endif - - if (present(rc)) rc = rCode - if (debug>1) call shr_timer_stop (t01) - -end subroutine shr_string_listAppend - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_listPrepend -- Prepend one list to another -! -! !DESCRIPTION: -! Prepend one list to another -! \newline -! call shr\_string\_listPrepend(listadd,list) -! \newline -! results in listadd:list -! -! !REVISION HISTORY: -! 2005-May-05 - T. Craig -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_listPrepend(listadd,list,rc) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(in) :: listadd ! list/string - character(*) ,intent(inout) :: list ! list/string - integer(SHR_KIND_IN),optional,intent(out) :: rc ! return code - -!EOP - - !----- local ----- - character(SHR_KIND_CX) :: l1 ! local string - integer(SHR_KIND_IN) :: rCode ! return code - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_listPrepend) " - character(*),parameter :: F00 = "('(shr_string_listPrepend) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -! - no input or output string should be longer than SHR_KIND_CX -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - rCode = 0 - - !--- make sure temp string is large enough --- - if (len(l1) < len_trim(listAdd)) then - call shr_string_abort(subName//'ERROR: temp string not large enough') - end if - - call shr_string_clean(l1) - l1 = trim(listadd) - call shr_string_leftAlign(l1,rCode) - call shr_string_leftAlign(list,rCode) - if (len_trim(list)+len_trim(l1)+1 > len(list)) & - call shr_string_abort(subName//'ERROR: output list string not large enough') - if (len_trim(l1) == 0) then - list = trim(list) - else - list = trim(l1)//":"//trim(list) - endif - - if (present(rc)) rc = rCode - if (debug>1) call shr_timer_stop (t01) - -end subroutine shr_string_listPrepend - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_listGetIndexF -- Get index of field in string -! -! !DESCRIPTION: -! Get index of field in string -! \newline -! k = shr\_string\_listGetIndex(str,"taux") -! -! !REVISION HISTORY: -! 2005-Feb-28 - B. Kauffman and J. Schramm - first version -! -! !INTERFACE: ------------------------------------------------------------------ - -integer function shr_string_listGetIndexF(string,fldStr) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*),intent(in) :: string ! string - character(*),intent(in) :: fldStr ! name of field - -!EOP - - !----- local ----- - integer(SHR_KIND_IN) :: k ! local index variable - integer(SHR_KIND_IN) :: rc ! error code - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_listGetIndexF) " - character(*),parameter :: F00 = "('(shr_string_listGetIndexF) ',4a)" - -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - call shr_string_listGetIndex(string,fldStr,k,print=.false.,rc=rc) - shr_string_listGetIndexF = k - - if (debug>1) call shr_timer_stop (t01) - -end function shr_string_listGetIndexF - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_listGetIndex -- Get index of field in string -! -! !DESCRIPTION: -! Get index of field in string -! \newline -! call shr\_string\_listGetIndex(str,"taux",k,rc) -! -! !REVISION HISTORY: -! 2005-Feb-28 - B. Kauffman and J. Schramm - first version -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_listGetIndex(string,fldStr,kFld,print,rc) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*) ,intent(in) :: string ! string - character(*) ,intent(in) :: fldStr ! name of field - integer(SHR_KIND_IN),intent(out) :: kFld ! index of field - logical ,intent(in) ,optional :: print ! print switch - integer(SHR_KIND_IN),intent(out),optional :: rc ! return code - -!EOP - - !----- local ----- - integer(SHR_KIND_IN) :: n ! index for colon position - integer(SHR_KIND_IN) :: k ! index for field name position - integer(SHR_KIND_IN) :: nFields ! number of fields in a string - integer(SHR_KIND_IN) :: i0,i1 ! fldStr == string(i0,i1) ?? - integer(SHR_KIND_IN) :: j0,j1 ! fldStr == string(j0,j1) ?? - logical :: found ! T => field found in fieldNames - logical :: lprint ! local print flag - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_listGetIndex) " - character(*),parameter :: F00 = "('(shr_string_listGetIndex) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -! - searching from both ends of the list at the same time seems to be 20% faster -! but I'm not sure why (B. Kauffman, Feb 2007) -! - I commented out sanity check to a little gain speed (B. Kauffman, Mar 2007) -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - if (present(rc)) rc = 0 - - lprint = .false. - if (present(print)) lprint = print - - !--- confirm proper size of input data --- - if (len_trim(fldStr) < 1) then - if (lprint) write(s_logunit,F00) "ERROR: input field name has 0 length" - call shr_string_abort(subName//"invalid field name") - end if - - !--- search for field name in string's list of fields --- - found = .false. - kFld = 0 - i0 = 1 ! ?? fldStr == string(i0:i1) ?? - i1 = -1 - j0 = -1 ! ?? fldStr == string(j0:j1) ?? - j1 = len_trim(string) - nFields = shr_string_listGetNum(string) - do k = 1,nFields - !-------------------------------------------------------- - ! search from end of list to end of list - !-------------------------------------------------------- - !--- get end index of of field number k --- - n = index(string(i0:len_trim(string)),listDel) - if (n > 0) then - i1 = i0 + n - 2 ! *not* the last field name in fieldNames - else - i1 = len_trim(string) ! this is the last field name in fieldNames - endif - !--- sanity check --- - ! if ((k 0)) then - ! call shr_string_abort(subName//"ERROR: wrong string%nf ?") - ! end if - !--- is it a match? --- - if (trim(fldStr) == string(i0:i1)) then - found = .true. - kFld = k - exit - endif - i0 = i1 + 2 ! start index for next iteration - !-------------------------------------------------------- - ! search from end of list to start of list - !-------------------------------------------------------- - !--- get start index of field number (nFields + 1 - k ) --- - n = index(string(1:j1),listDel,back=.true.) - j0 = n + 1 ! n==0 => the first field name in fieldNames - !--- sanity check --- - ! if ((k 0)) then - ! call shr_string_abort(subName//"ERROR: wrong string%nf ?") - ! end if - !--- is it a match? --- - if (trim(fldStr) == string(j0:j1)) then - found = .true. - kFld = nFields + 1 - k - exit - endif - j1 = j0 - 2 ! end index for next iteration - !-------------------------------------------------------- - ! exit if all field names have been checked - !-------------------------------------------------------- - if (2*k >= nFields) exit - end do - - !--- not finding a field is not a fatal error --- - if (.not. found) then - kFld = 0 - if (lprint .and. s_loglev > 0) write(s_logunit,F00) "FYI: field ",trim(fldStr)," not found in list ",trim(string) - if (present(rc)) rc = 1 - end if - - if (debug>1) call shr_timer_stop (t01) - -end subroutine shr_string_listGetIndex - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_listGetNum -- get number of fields in a string list -! -! !DESCRIPTION: -! return number of fields in string list -! -! !REVISION HISTORY: -! 2005-Apr-28 - T. Craig - First version -! -! !INTERFACE: ------------------------------------------------------------------ - -integer function shr_string_listGetNum(str) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*),intent(in) :: str ! string to search - -!EOP - - !----- local ----- - integer(SHR_KIND_IN) :: count ! counts occurances of char - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !----- formats ----- - character(*),parameter :: subName = "(shr_string_listGetNum) " - character(*),parameter :: F00 = "('(shr_string_listGetNum) ',4a)" - -!------------------------------------------------------------------------------- -! Notes: -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - shr_string_listGetNum = 0 - - if (len_trim(str) > 0) then - count = shr_string_countChar(str,listDel) - shr_string_listGetNum = count + 1 - endif - - if (debug>1) call shr_timer_stop (t01) - -end function shr_string_listGetNum - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_listSetDel -- Set list delimeter character -! -! !DESCRIPTION: -! Set field delimeter character in lists -! \newline -! call shr\_string\_listSetDel(":") -! -! !REVISION HISTORY: -! 2005-Apr-30 - T. Craig - first prototype -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_listSetDel(cflag) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(len=1),intent(in) :: cflag - -!EOP - - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !--- formats --- - character(*),parameter :: subName = "(shr_string_listSetDel) " - character(*),parameter :: F00 = "('(shr_string_listSetDel) ',a) " - -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - if (debug > 0 .and. s_loglev > 0) write(s_logunit,F00) 'changing listDel from '//trim(listDel)//' to '//trim(cflag) - listDel = trim(cflag) - listDel2 = listDel//listDel - - if (debug>1) call shr_timer_stop (t01) - -end subroutine shr_string_listSetDel - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_listGetDel -- Get list delimeter character -! -! !DESCRIPTION: -! Get field delimeter character in lists -! \newline -! call shr\_string\_listGetDel(del) -! -! !REVISION HISTORY: -! 2005-May-15 - T. Craig - first prototype -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_listGetDel(del) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*),intent(out) :: del - -!EOP - - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !--- formats --- - character(*),parameter :: subName = "(shr_string_listGetDel) " - character(*),parameter :: F00 = "('(shr_string_listGetDel) ',a) " - -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - del = trim(listDel) - - if (debug>1) call shr_timer_stop (t01) - -end subroutine shr_string_listGetDel - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_setAbort -- Set local shr_string abort flag -! -! !DESCRIPTION: -! Set local shr_string abort flag, true = abort, false = print and continue -! \newline -! call shr\_string\_setAbort(.false.) -! -! !REVISION HISTORY: -! 2005-Apr-30 - T. Craig - first prototype -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_setAbort(flag) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - logical,intent(in) :: flag - -!EOP - - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !--- formats --- - character(*),parameter :: subName = "(shr_string_setAbort) " - character(*),parameter :: F00 = "('(shr_string_setAbort) ',a) " - -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - if (debug > 0 .and. s_loglev > 0) then - if (flag) then - write(s_logunit,F00) 'setting abort to true' - else - write(s_logunit,F00) 'setting abort to false' - endif - endif - - doabort = flag - - if (debug>1) call shr_timer_stop (t01) - -end subroutine shr_string_setAbort - -!=============================================================================== -!BOP =========================================================================== -! -! !IROUTINE: shr_string_setDebug -- Set local shr_string debug level -! -! !DESCRIPTION: -! Set local shr_string debug level, 0 = production -! \newline -! call shr\_string\_setDebug(2) -! -! !REVISION HISTORY: -! 2005-Apr-30 - T. Craig - first prototype -! -! !INTERFACE: ------------------------------------------------------------------ - -subroutine shr_string_setDebug(iFlag) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - integer(SHR_KIND_IN),intent(in) :: iFlag ! requested debug level - -!EOP - - !--- local --- - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !--- formats --- - character(*),parameter :: subName = "(shr_string_setDebug) " - character(*),parameter :: F00 = "('(shr_string_setDebug) ',a) " - character(*),parameter :: F01 = "('(shr_string_setDebug) ',a,i3,a,i3) " - -!------------------------------------------------------------------------------- -! NTOE: write statement can be expensive if called many times. -!------------------------------------------------------------------------------- - - if (iFlag>1 .and. t01<1) call shr_timer_get(t01,subName) - if (iFlag>1) call shr_timer_start(t01) - -! if (s_loglev > 0) write(s_logunit,F01) 'changing debug level from ',debug,' to ',iflag - debug = iFlag - - if (iFlag>1) call shr_timer_stop (t01) - -end subroutine shr_string_setDebug - -!=============================================================================== -!=============================================================================== - -subroutine shr_string_abort(string) - - implicit none - -! !INPUT/OUTPUT PARAMETERS: - - character(*),optional,intent(in) :: string - -!EOP - - integer(SHR_KIND_IN) :: t01 = 0 ! timer - - !--- local --- - character(SHR_KIND_CX) :: lstring - character(*),parameter :: subName = "(shr_string_abort)" - character(*),parameter :: F00 = "('(shr_string_abort) ',a)" - -!------------------------------------------------------------------------------- -! NOTE: -! - no input or output string should be longer than SHR_KIND_CX -!------------------------------------------------------------------------------- - - if (debug>1 .and. t01<1) call shr_timer_get(t01,subName) - if (debug>1) call shr_timer_start(t01) - - lstring = '' - if (present(string)) lstring = string - - if (doabort) then - call shr_sys_abort(trim(lstring)) - else - write(s_logunit,F00) ' no abort:'//trim(lstring) - endif - - if (debug>1) call shr_timer_stop (t01) - -end subroutine shr_string_abort - -!=============================================================================== -!=============================================================================== - -end module shr_string_mod diff --git a/tools/mksurfdata_map/src/shr_sys_mod.F90 b/tools/mksurfdata_map/src/shr_sys_mod.F90 deleted file mode 100644 index 8c51b711cc..0000000000 --- a/tools/mksurfdata_map/src/shr_sys_mod.F90 +++ /dev/null @@ -1,352 +0,0 @@ -!=============================================================================== - -MODULE shr_sys_mod - - use shr_kind_mod ! defines real & integer kinds - use shr_log_mod, only: s_loglev => shr_log_Level - use shr_log_mod, only: s_logunit => shr_log_Unit - - implicit none - -! PUBLIC: Public interfaces - - private - - public :: shr_sys_system ! make a system call - public :: shr_sys_chdir ! change current working dir - public :: shr_sys_getenv ! get an environment variable - public :: shr_sys_abort ! abort a program - public :: shr_sys_irtc ! returns real-time clock tick - public :: shr_sys_sleep ! have program sleep for a while - public :: shr_sys_flush ! flush an i/o buffer - -!=============================================================================== -CONTAINS -!=============================================================================== - -!=============================================================================== -!=============================================================================== - -SUBROUTINE shr_sys_system(str,rcode) - - IMPLICIT none - - !----- arguments --- - character(*) ,intent(in) :: str ! system/shell command string - integer(SHR_KIND_IN),intent(out) :: rcode ! function return error code - - !----- functions ----- -#if (defined CRAY) || (defined UNICOSMP) - integer(SHR_KIND_IN),external :: ishell ! function to envoke shell command -#endif -#if (defined OSF1 || defined SUNOS || (defined LINUX && !defined __GFORTRAN__ && !defined CATAMOUNT)) - integer(SHR_KIND_IN),external :: system ! function to envoke shell command -#endif - - !----- local ----- -#if (defined CATAMOUNT) - character(2*SHR_KIND_CL) :: file1 ! one or two filenames - character( SHR_KIND_CL) :: file2 ! 2nd file name - integer(SHR_KIND_IN) :: iloc ! index/location within a string -#endif - - !----- formats ----- - character(*),parameter :: subName = '(shr_sys_system) ' - character(*),parameter :: F00 = "('(shr_sys_system) ',4a)" - -!------------------------------------------------------------------------------- -! PURPOSE: an architecture independant system call -! NOTE: -! - for Catamount (Cray, pheonix at ORNL) there is no system call -- workarounds -! exist only for simple "rm" and "cp" commands -!------------------------------------------------------------------------------- - - -#if (defined CRAY) || (defined UNICOSMP) - - rcode=ishell(str) - -#elif (defined IRIX64 || defined NEC_SX) - - rcode = 0 - call system(str) - -#elif (defined AIX) - - call system(str,rcode) - -#elif (defined OSF1 || defined SUNOS || defined __GFORTRAN__ || (defined LINUX && !defined CATAMOUNT)) - - rcode = system(str) - -#elif (defined CATAMOUNT) - if (str(1:3) == 'rm ') then - call unlink(str(4:)) - if (s_loglev > 0) write(s_logunit,F00) 'CATAMOUNT unlink ',trim(str(4:)) - rcode = 0 - elseif (str(1:3) == 'mv ') then - file1 = str(4:) - iloc = index(file1,' ') + 3 - if (iloc < 6) then - if (s_loglev > 0) write(s_logunit,*) 'CATAMOUNT mv error ',trim(str),iloc - rcode = -1 - else - file1 = str(4:iloc) - file2 = str(iloc+1:) - call rename(trim(file1),trim(file2)) - if (s_loglev > 0) write(s_logunit,F00) 'CATAMOUNT rename ',trim(file1)," ",trim(file2) - rcode = 0 - endif - else - rcode = -1 - endif - -#else - - write(s_logunit,F00) 'ERROR: no implementation of system call for this architecture' - call shr_sys_abort(subName//'no implementation of system call for this architecture') - -#endif - -END SUBROUTINE shr_sys_system - -!=============================================================================== -!=============================================================================== - -SUBROUTINE shr_sys_chdir(path, rcode) - - IMPLICIT none - - !----- arguments ----- - character(*) ,intent(in) :: path ! chdir to this dir - integer(SHR_KIND_IN),intent(out) :: rcode ! return code - - !----- local ----- - integer(SHR_KIND_IN) :: lenpath ! length of path -#if (defined AIX || defined OSF1 || defined SUNOS || (defined LINUX && !defined __GFORTRAN__) || defined NEC_SX) - integer(SHR_KIND_IN),external :: chdir ! AIX system call -#endif - - !----- formats ----- - character(*),parameter :: subName = '(shr_sys_chdir) ' - character(*),parameter :: F00 = "('(shr_sys_chdir) ',4a)" - -!------------------------------------------------------------------------------- -! PURPOSE: an architecture independant system call -!------------------------------------------------------------------------------- - - lenpath=len_trim(path) - -#if (defined IRIX64 || defined CRAY || defined UNICOSMP) - - call pxfchdir(path, lenpath, rcode) - -#elif (defined AIX) - - rcode = chdir(%ref(path(1:lenpath)//'\0')) - -#elif (defined OSF1 || defined SUNOS || defined LINUX || defined NEC_SX) - - rcode=chdir(path(1:lenpath)) - -#else - - write(s_logunit,F00) 'ERROR: no implementation of chdir for this architecture' - call shr_sys_abort(subname//'no implementation of chdir for this machine') - -#endif - -END SUBROUTINE shr_sys_chdir - -!=============================================================================== -!=============================================================================== - -SUBROUTINE shr_sys_getenv(name, val, rcode) - - IMPLICIT none - - !----- arguments ----- - character(*) ,intent(in) :: name ! env var name - character(*) ,intent(out) :: val ! env var value - integer(SHR_KIND_IN),intent(out) :: rcode ! return code - - !----- local ----- - integer(SHR_KIND_IN) :: lenname ! length of env var name - integer(SHR_KIND_IN) :: lenval ! length of env var value - character(SHR_KIND_CL) :: tmpval ! temporary env var value - - !----- formats ----- - character(*),parameter :: subName = '(shr_sys_getenv) ' - character(*),parameter :: F00 = "('(shr_sys_getenv) ',4a)" - -!------------------------------------------------------------------------------- -! PURPOSE: an architecture independant system call -!------------------------------------------------------------------------------- - - lenname=len_trim(name) - -#if (defined IRIX64 || defined CRAY || defined UNICOSMP) - - call pxfgetenv(name, lenname, val, lenval, rcode) - -#elif (defined AIX || defined OSF1 || defined SUNOS || defined LINUX || defined NEC_SX) - - call getenv(trim(name),tmpval) - val=trim(tmpval) - rcode = 0 - if (len_trim(val) == 0 ) rcode = 1 - if (len_trim(val) > SHR_KIND_CL) rcode = 2 - -#else - - write(s_logunit,F00) 'ERROR: no implementation of getenv for this architecture' - call shr_sys_abort(subname//'no implementation of getenv for this machine') - -#endif - -END SUBROUTINE shr_sys_getenv - -!=============================================================================== -!=============================================================================== - -SUBROUTINE shr_sys_abort(string,rc) - - IMPLICIT none - - character(*) ,optional :: string ! error message string - integer(SHR_KIND_IN),optional :: rc ! error code - - !----- formats ----- - character(*),parameter :: subName = '(shr_sys_abort) ' - character(*),parameter :: F00 = "('(shr_sys_abort) ',4a)" - -!------------------------------------------------------------------------------- -! PURPOSE: consistent stopping mechanism -!------------------------------------------------------------------------------- - - call shr_sys_flush(s_logunit) - if (len_trim(string) > 0) write(s_logunit,F00) 'ERROR: '//trim(string) - write(s_logunit,F00) 'WARNING: stopping' - call shr_sys_flush(s_logunit) - call abort() - stop - -END SUBROUTINE shr_sys_abort - -!=============================================================================== -!=============================================================================== - -integer(SHR_KIND_I8) FUNCTION shr_sys_irtc( rate ) - - IMPLICIT none - - !----- arguments ----- - integer(SHR_KIND_I8), optional :: rate - - !----- local ----- - integer(SHR_KIND_IN) :: count - integer(SHR_KIND_IN) :: count_rate - integer(SHR_KIND_IN) :: count_max - integer(SHR_KIND_IN),save :: last_count = -1 - integer(SHR_KIND_I8),save :: count_offset = 0 - - !----- formats ----- - character(*),parameter :: subName = '(shr_sys_irtc) ' - character(*),parameter :: F00 = "('(shr_sys_irtc) ',4a)" - -!------------------------------------------------------------------------------- -! emulates Cray/SGI irtc function (returns clock tick since last reboot) -!------------------------------------------------------------------------------- - - call system_clock(count=count,count_rate=count_rate, count_max=count_max) - if ( present(rate) ) rate = count_rate - shr_sys_irtc = count - - !--- adjust for clock wrap-around --- - if ( last_count /= -1 ) then - if ( count < last_count ) count_offset = count_offset + count_max - end if - shr_sys_irtc = shr_sys_irtc + count_offset - last_count = count - -END FUNCTION shr_sys_irtc - -!=============================================================================== -!=============================================================================== - -SUBROUTINE shr_sys_sleep(sec) - - IMPLICIT none - - !----- arguments ----- - real (SHR_KIND_R8),intent(in) :: sec ! number of seconds to sleep - - !----- local ----- - integer(SHR_KIND_IN) :: isec ! integer number of seconds - integer(SHR_KIND_IN) :: rcode ! return code - character(90) :: str ! system call string - - !----- formats ----- - character(*),parameter :: subName = '(shr_sys_sleep) ' - character(*),parameter :: F00 = "('(shr_sys_sleep) ',4a)" - character(*),parameter :: F10 = "('sleep ',i8 )" - -!------------------------------------------------------------------------------- -! PURPOSE: Sleep for approximately sec seconds -!------------------------------------------------------------------------------- - - isec = nint(sec) - - if (isec < 0) then - if (s_loglev > 0) write(s_logunit,F00) 'ERROR: seconds must be > 0, sec=',sec - else if (isec == 0) then - ! Don't consider this an error and don't call system sleep - else -#if defined(CATAMOUNT) - call sleep(isec) -#else - write(str,FMT=F10) isec - call shr_sys_system( str, rcode ) -#endif - endif - -END SUBROUTINE shr_sys_sleep - -!=============================================================================== -!=============================================================================== - -SUBROUTINE shr_sys_flush(unit) - - IMPLICIT none - - !----- arguments ----- - integer(SHR_KIND_IN) :: unit ! flush output buffer for this unit - - !----- formats ----- - character(*),parameter :: subName = '(shr_sys_flush) ' - character(*),parameter :: F00 = "('(shr_sys_flush) ',4a)" - -!------------------------------------------------------------------------------- -! PURPOSE: an architecture independant system call -!------------------------------------------------------------------------------- - -#if (defined IRIX64 || defined CRAY || defined OSF1 || defined SUNOS || defined LINUX || defined NEC_SX || defined UNICOSMP) - - call flush(unit) - -#elif (defined AIX) - - call flush_(unit) - -#else - - if (s_loglev > 0) write(s_logunit,F00) 'WARNING: no implementation of flush for this architecture' - -#endif - -END SUBROUTINE shr_sys_flush - -!=============================================================================== -!=============================================================================== - -END MODULE shr_sys_mod diff --git a/tools/mksurfdata_map/src/shr_timer_mod.F90 b/tools/mksurfdata_map/src/shr_timer_mod.F90 deleted file mode 100644 index c9d728ca4a..0000000000 --- a/tools/mksurfdata_map/src/shr_timer_mod.F90 +++ /dev/null @@ -1,425 +0,0 @@ -!=============================================================================== - -module shr_timer_mod - - !---------------------------------------------------------------------------- - ! - ! routines that support multiple CPU timers via F90 intrinsics - ! - ! Note: - ! o if an operation is requested on an invalid timer number n - ! then nothing is done in a routine - ! o if more than max_timers are requested, - ! then timer n=max_timers is "overloaded" and becomes invalid/undefined - ! - ! * cpp if-defs were introduced in 2005 to work-around a bug in the ORNL Cray - ! X1 F90 intrinsic system_clock() function -- ideally this Cray bug would be - ! fixed and cpp if-defs would be unnecessary and removed. - ! - ! !REVISION HISTORY: - ! 2005-??-?? - added workaround for Cray F90 bug, mods by Cray/ORNL - ! 2000-??-?? - 1st version by B. Kauffman - !---------------------------------------------------------------------------- - - use shr_kind_mod - use shr_log_mod, only: s_loglev => shr_log_Level - use shr_log_mod, only: s_logunit => shr_log_Unit - - implicit none - - private ! restricted access - - public :: shr_timer_init - public :: shr_timer_get - public :: shr_timer_start - public :: shr_timer_stop - public :: shr_timer_print - public :: shr_timer_print_all - public :: shr_timer_check - public :: shr_timer_check_all - public :: shr_timer_zero - public :: shr_timer_zero_all - public :: shr_timer_free - public :: shr_timer_free_all - public :: shr_timer_sleep - - integer(SHR_KIND_IN),parameter :: stat_free = 0 ! timer status constants - integer(SHR_KIND_IN),parameter :: stat_inuse = 1 - integer(SHR_KIND_IN),parameter :: stat_started = 2 - integer(SHR_KIND_IN),parameter :: stat_stopped = 3 - integer(SHR_KIND_IN),parameter :: max_timers = 200 ! max number of timers - - integer(SHR_KIND_IN) :: status (max_timers) ! status of each timer - !---------------------------------------------------------------------------- - ! the following ifdef circumvents a bug in the X1 system_clock function - !---------------------------------------------------------------------------- -#if (defined UNICOSMP) - integer(kind=8) :: cycles1(max_timers) ! cycle number at timer start - integer(kind=8) :: cycles2(max_timers) ! cycle number at timer stop -#else - integer(SHR_KIND_IN) :: cycles1(max_timers) ! cycle number at timer start - integer(SHR_KIND_IN) :: cycles2(max_timers) ! cycle number at timer stop -#endif - integer(SHR_KIND_IN) :: cycles_max = -1 ! max cycles before wrapping - character (len=80) :: name (max_timers) ! name assigned to each timer - real (SHR_KIND_R8) :: dt (max_timers) ! accumulated time - integer(SHR_KIND_IN) :: calls (max_timers) ! # of samples in accumulation - real (SHR_KIND_R8) :: clock_rate ! clock_rate: seconds per cycle - - save - -!=============================================================================== - contains -!=============================================================================== - -subroutine shr_timer_init - - !----- local ----- - integer(SHR_KIND_IN) :: cycles ! count rate return by system clock -#if (defined UNICOSMP) - integer(kind=8) :: irtc_rate -#endif - - !----- i/o formats ----- - character(len=*),parameter :: F00 = "('(shr_timer_init) ',a,i5)" - -!------------------------------------------------------------------------------- -! This routine initializes: -! 1) values in all timer array locations -! 2) machine parameters necessary for computing cpu time from F90 intrinsics. -! F90 intrinsic: system_clock(count_rate=cycles, count_max=cycles_max) -!------------------------------------------------------------------------------- - - call shr_timer_free_all - -#if (defined UNICOSMP) - cycles = irtc_rate() -#else - call system_clock(count_rate=cycles, count_max=cycles_max) -#endif - - if (cycles /= 0) then - clock_rate = 1.0_SHR_KIND_R8/real(cycles,SHR_KIND_R8) - else - clock_rate = 0._SHR_KIND_R8 - if (s_loglev > 0) write(s_logunit,F00) 'ERROR: no system clock available' - endif - -end subroutine shr_timer_init - -!=============================================================================== - -subroutine shr_timer_get(n, str) - - !----- arguments ----- - integer(SHR_KIND_IN),intent(out) :: n ! timer number - character (*) ,intent( in) :: str ! text string with timer name - - !----- i/o formats ----- - character(len=*),parameter :: F00 = "('(shr_timer_get) ',a,i5)" - -!----------------------------------------------------------------------- -! search for next free timer -!----------------------------------------------------------------------- - - do n=1,max_timers - if (status(n) == stat_free) then - status(n) = stat_inuse - name (n) = str - calls (n) = 0 - return - endif - end do - - n=max_timers - name (n) = "" - if (s_loglev > 0) write(s_logunit,F00) 'ERROR: exceeded maximum number of timers' - -end subroutine shr_timer_get - -!=============================================================================== - -subroutine shr_timer_start(n) - - !----- arguments ----- - integer(SHR_KIND_IN), intent(in) :: n ! timer number - - !----- local ----- -#if (defined UNICOSMP) - integer(kind=8) :: irtc -#endif - - !----- i/o formats ----- - character(len=*),parameter :: F00 = "('(shr_timer_start) ',a,i5)" - -!----------------------------------------------------------------------- -! This routine starts a given timer. -!----------------------------------------------------------------------- - - if ( n>0 .and. n<=max_timers) then - if (status(n) == stat_started) call shr_timer_stop(n) - - status(n) = stat_started -#if (defined UNICOSMP) - cycles1(n) = irtc() -#else - call system_clock(count=cycles1(n)) -#endif - else - if (s_loglev > 0) write(s_logunit,F00) 'ERROR: invalid timer number: ',n - end if - -end subroutine shr_timer_start - -!=============================================================================== - -subroutine shr_timer_stop(n) - - !----- arguments ----- - integer(SHR_KIND_IN), intent(in) :: n ! timer number - - !----- local ----- - real (SHR_KIND_R8) :: elapse ! elapsed time returned by system counter -#if (defined UNICOSMP) - integer(kind=8) :: irtc -#endif - - !----- i/o formats ----- - character(len=*),parameter :: F00 = "('(shr_timer_stop) ',a,i5)" - -!------------------------------------------------------------------------------- -! This routine stops a given timer, checks for cycle wrapping, computes the -! elapsed time, and accumulates the elapsed time in the dt(n) array -!------------------------------------------------------------------------------- - - if ( n>0 .and. n<=max_timers) then - if ( status(n) == stat_started) then -#if (defined UNICOSMP) - cycles2(n) = irtc() -#else - call system_clock(count=cycles2(n)) -#endif - if (cycles2(n) >= cycles1(n)) then - dt(n) = dt(n) + clock_rate*(cycles2(n) - cycles1(n)) - else - dt(n) = dt(n) + clock_rate*(cycles_max + cycles2(n) - cycles1(n)) - endif - calls (n) = calls(n) + 1 - status(n) = stat_stopped - end if - else - if (s_loglev > 0) write(s_logunit,F00) 'ERROR: invalid timer number: ',n - end if - -end subroutine shr_timer_stop - -!=============================================================================== - -subroutine shr_timer_print(n) - - !----- arguments ----- - integer(SHR_KIND_IN), intent(in) :: n ! timer number - - !----- i/o formats ----- - character(len=*),parameter :: F00 = "('(shr_timer_print) ',a,i5)" - character(len=*),parameter :: F01 = "('(shr_timer_print) timer',i3,& - & ':',i8,' calls,',f10.3,'s, id: ',a)" -!------------------------------------------------------------------------------- -! prints the accumulated time for a given timer -!------------------------------------------------------------------------------- - - if ( n>0 .and. n<=max_timers) then - if (status(n) == stat_started) then - call shr_timer_stop(n) - if (s_loglev > 0) write(s_logunit,F01) n,calls(n),dt(n),trim(name(n)) - call shr_timer_start(n) - else - if (s_loglev > 0) write(s_logunit,F01) n,calls(n),dt(n),trim(name(n)) - endif - else - if (s_loglev > 0) write(s_logunit,F00) 'ERROR: invalid timer number: ',n - end if - -end subroutine shr_timer_print - -!=============================================================================== - -subroutine shr_timer_print_all - - !----- local ----- - integer(SHR_KIND_IN) :: n - - !----- i/o formats ----- - character(len=*),parameter :: F00 = "('(shr_timer_print_all) ',a,i5)" - -!------------------------------------------------------------------------------- -! prints accumulated time for all timers in use -!------------------------------------------------------------------------------- - - if (s_loglev > 0) write(s_logunit,F00) 'print all timing info:' - - do n=1,max_timers - if (status(n) /= stat_free) call shr_timer_print(n) - end do - -end subroutine shr_timer_print_all - -!=============================================================================== - -subroutine shr_timer_zero(n) - - !----- arguments ----- - integer(SHR_KIND_IN), intent(in) :: n ! timer number - - !----- i/o formats ----- - character(len=*),parameter :: F00 = "('(shr_timer_zero) ',a,i5)" - -!------------------------------------------------------------------------------- -! This routine resets a given timer. -!------------------------------------------------------------------------------- - - if ( n>0 .and. n<=max_timers) then - dt(n) = 0.0_SHR_KIND_R8 - calls(n) = 0 - else - if (s_loglev > 0) write(s_logunit,F00) 'ERROR: invalid timer number: ',n - end if - -end subroutine shr_timer_zero - -!=============================================================================== - -subroutine shr_timer_zero_all - - !----- i/o formats ----- - character(len=*),parameter :: F00 = "('(shr_timer_zero_all) ',a,i5)" - -!------------------------------------------------------------------------------- -! This routine resets all timers. -!------------------------------------------------------------------------------- - - dt = 0.0_SHR_KIND_R8 - calls = 0 - -end subroutine shr_timer_zero_all - -!=============================================================================== - -subroutine shr_timer_check(n) - - !----- arguments ----- - integer(SHR_KIND_IN), intent(in) :: n ! timer number - - !----- i/o formats ----- - character(len=*),parameter :: F00 = "('(shr_timer_check) ',a,i5)" - -!------------------------------------------------------------------------------- -! This routine checks a given timer. This is primarily used to -! periodically accumulate time in the timer to prevent timer cycles -! from wrapping around max_cycles. -!------------------------------------------------------------------------------- - - if ( n>0 .and. n<=max_timers) then - if (status(n) == stat_started) then - call shr_timer_stop (n) - call shr_timer_start(n) - endif - else - if (s_loglev > 0) write(s_logunit,F00) 'ERROR: invalid timer number: ',n - end if - -end subroutine shr_timer_check - -!=============================================================================== - -subroutine shr_timer_check_all - - !----- local ----- - integer(SHR_KIND_IN) :: n - - !----- i/o formats ----- - character(len=*),parameter :: F00 = "('(shr_timer_check_all) ',a,i5)" - -!------------------------------------------------------------------------------- -! Call shr_timer_check for all timers in use -!------------------------------------------------------------------------------- - - do n=1,max_timers - if (status(n) == stat_started) then - call shr_timer_stop (n) - call shr_timer_start(n) - endif - end do - -end subroutine shr_timer_check_all - -!=============================================================================== - -subroutine shr_timer_free(n) - - !----- arguments ----- - integer(SHR_KIND_IN),intent(in) :: n ! timer number - - !----- i/o formats ----- - character(len=*),parameter :: F00 = "('(shr_timer_free) ',a,i5)" - -!----------------------------------------------------------------------- -! initialize/free all timer array values -!----------------------------------------------------------------------- - - if ( n>0 .and. n<=max_timers) then - status (n) = stat_free - name (n) = "" - dt (n) = 0.0_SHR_KIND_R8 - cycles1(n) = 0 - cycles2(n) = 0 - else - if (s_loglev > 0) write(s_logunit,F00) 'ERROR: invalid timer number: ',n - end if - -end subroutine shr_timer_free - -!=============================================================================== - -subroutine shr_timer_free_all - - !----- local ----- - integer(SHR_KIND_IN) :: n - - !----- i/o formats ----- - character(len=*),parameter :: F00 = "('(shr_timer_free_all) ',a,i5)" - -!------------------------------------------------------------------------------- -! initialize/free all timer array values -!------------------------------------------------------------------------------- - - do n=1,max_timers - call shr_timer_free(n) - end do - -end subroutine shr_timer_free_all - -!=============================================================================== - -subroutine shr_timer_sleep(sec) - - use shr_sys_mod ! share system calls (namely, shr_sys_sleep) - - !----- local ----- - real (SHR_KIND_R8),intent(in) :: sec ! number of seconds to sleep - -!------------------------------------------------------------------------------- -! Sleep for approximately sec seconds -! -! Note: sleep is typically a system call, hence it is implemented in -! shr_sys_mod, although it probably would only be used in a timing -! context, which is why there is a shr_timer_* wrapper provided here. -!------------------------------------------------------------------------------- - - call shr_sys_sleep(sec) - -end subroutine shr_timer_sleep - -!=============================================================================== -end module shr_timer_mod -!=============================================================================== diff --git a/tools/mksurfdata_map/src/test/CMakeLists.txt b/tools/mksurfdata_map/src/test/CMakeLists.txt deleted file mode 100644 index 78dee7b2b1..0000000000 --- a/tools/mksurfdata_map/src/test/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -add_subdirectory(mkpctPftType_test) -add_subdirectory(mkpftUtils_test) -add_subdirectory(mkpftmod_test) -add_subdirectory(mkgridmap_test) -add_subdirectory(mkindexmap_test) -add_subdirectory(mksoilUtils_test) -add_subdirectory(mkdomain_test) diff --git a/tools/mksurfdata_map/src/test/mkdomain_test/CMakeLists.txt b/tools/mksurfdata_map/src/test/mkdomain_test/CMakeLists.txt deleted file mode 100644 index 401ce6a6f6..0000000000 --- a/tools/mksurfdata_map/src/test/mkdomain_test/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -set (pfunit_sources - test_mkdomain.pf) - -create_pFUnit_test(mkdomainMod test_mkdomain_exe - "${pfunit_sources}" "") - -target_link_libraries(test_mkdomain_exe mksurfdat) diff --git a/tools/mksurfdata_map/src/test/mkdomain_test/test_mkdomain.pf b/tools/mksurfdata_map/src/test/mkdomain_test/test_mkdomain.pf deleted file mode 100644 index c54e299356..0000000000 --- a/tools/mksurfdata_map/src/test/mkdomain_test/test_mkdomain.pf +++ /dev/null @@ -1,93 +0,0 @@ -module test_mkdomain - - ! Tests of mkdomainMod - - use pfunit_mod - - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkgridmapMod, only : gridmap_type, for_test_create_gridmap - use mkdomainMod - - implicit none - save - - @TestCase - type, extends(TestCase) :: TestMkDomain - type(domain_type) :: ldomain - contains - procedure :: setUp - procedure :: tearDown - end type TestMkDomain - - integer, parameter :: ns = 2 - -contains - - subroutine setUp(this) - class(TestMkDomain), intent(inout) :: this - - call for_test_create_domain(this%ldomain) - end subroutine setUp - - subroutine tearDown(this) - class(TestMkDomain), intent(inout) :: this - - call domain_clean(this%ldomain) - - end subroutine tearDown - - @Test - subroutine test_runmkdomain(this) - class(TestMkDomain), intent(inout) :: this - - call domain_check( this%ldomain ) - - end subroutine test_runmkdomain - - @Test - subroutine test_is_neglong_domain_0to360(this) - class(TestMkDomain), intent(inout) :: this - - logical :: result - - result = is_domain_0to360_longs( this%ldomain ) - @assertFalse( result ) - end subroutine test_is_neglong_domain_0to360 - - @Test - subroutine test_is_posto360_domain_0to360(this) - class(TestMkDomain), intent(inout) :: this - - logical :: result - - this%ldomain%lonc(1) = 0.0_r8 - this%ldomain%lonc(2) = 360.0_r8 - result = is_domain_0to360_longs( this%ldomain ) - @assertTrue( result ) - end subroutine test_is_posto360_domain_0to360 - - @Test - subroutine test_is_posto180_domain_0to360(this) - class(TestMkDomain), intent(inout) :: this - - logical :: result - - this%ldomain%lonc(1) = 0.0_r8 - this%ldomain%lonc(2) = 180.0_r8 - result = is_domain_0to360_longs( this%ldomain ) - @assertTrue( result ) - end subroutine test_is_posto180_domain_0to360 - - @Test - subroutine test_is_ge180pos_domain_0to360(this) - class(TestMkDomain), intent(inout) :: this - - logical :: result - - this%ldomain%lonc(1) = 180.0_r8 - this%ldomain%lonc(2) = 200.0_r8 - result = is_domain_0to360_longs( this%ldomain ) - @assertTrue( result ) - end subroutine test_is_ge180pos_domain_0to360 - -end module test_mkdomain diff --git a/tools/mksurfdata_map/src/test/mkgridmap_test/CMakeLists.txt b/tools/mksurfdata_map/src/test/mkgridmap_test/CMakeLists.txt deleted file mode 100644 index 85d936fd33..0000000000 --- a/tools/mksurfdata_map/src/test/mkgridmap_test/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -create_pFUnit_test(mkgridmap test_mkgridmap_exe - "test_mkgridmap.pf" "") - -target_link_libraries(test_mkgridmap_exe mksurfdat) \ No newline at end of file diff --git a/tools/mksurfdata_map/src/test/mkgridmap_test/test_mkgridmap.pf b/tools/mksurfdata_map/src/test/mkgridmap_test/test_mkgridmap.pf deleted file mode 100644 index c8eda9d007..0000000000 --- a/tools/mksurfdata_map/src/test/mkgridmap_test/test_mkgridmap.pf +++ /dev/null @@ -1,106 +0,0 @@ -module test_mkgridmap - - ! Tests of mkgridmapMod - - use pfunit_mod - use mkgridmapMod - use shr_kind_mod , only : r8 => shr_kind_r8 - - implicit none - - @TestCase - type, extends(TestCase) :: TestMkGridmap - type(gridmap_type) :: gridmap - contains - procedure :: setUp - procedure :: tearDown - end type TestMkGridmap - - real(r8), parameter :: tol = 1.e-13_r8 - -contains - - subroutine setUp(this) - class(TestMkGridmap), intent(inout) :: this - end subroutine setUp - - subroutine tearDown(this) - class(TestMkGridmap), intent(inout) :: this - - call gridmap_clean(this%gridmap) - end subroutine tearDown - - ! ------------------------------------------------------------------------ - ! Tests of for_test_create_gridmap - ! ------------------------------------------------------------------------ - - @Test - subroutine forTestCreateGridmap_defaultArgs(this) - class(TestMkGridmap), intent(inout) :: this - call for_test_create_gridmap(this%gridmap, na=2, nb=3, ns=4, & - src_indx = [11,11,12,12], & - dst_indx = [21,22,22,23], & - wovr = [1._r8, 0.5_r8, 0.5_r8, 1._r8]) - - @assertEqual(2, this%gridmap%na) - @assertEqual(3, this%gridmap%nb) - @assertEqual(4, this%gridmap%ns) - @assertEqual([11,11,12,12], this%gridmap%src_indx) - @assertEqual([21,22,22,23], this%gridmap%dst_indx) - @assertEqual([1._r8, 0.5_r8, 0.5_r8, 1._r8], this%gridmap%wovr) - @assertEqual([1._r8, 1._r8], this%gridmap%frac_src) - @assertEqual([1._r8, 1._r8, 1._r8], this%gridmap%frac_dst) - - ! Don't bother asserting area, xc, yc, because the default values of those shouldn't - ! matter too much. - end subroutine forTestCreateGridmap_defaultArgs - - @Test - subroutine forTestCreateGridmap_explicitArgs(this) - class(TestMkGridmap), intent(inout) :: this - integer, parameter :: na = 2 - integer, parameter :: nb = 3 - integer, parameter :: ns = 4 - integer, parameter :: src_indx(ns) = [11,11,12,12] - integer, parameter :: dst_indx(ns) = [21,22,22,23] - real(r8), parameter :: wovr(ns) = [1._r8, 0.5_r8, 0.5_r8, 1._r8] - real(r8), parameter :: frac_src(na) = [0.1_r8, 0.0_r8] - real(r8), parameter :: frac_dst(nb) = [0.0_r8, 0.1_r8, 0.1_r8] - real(r8), parameter :: area_src(na) = [0.11_r8, 0.12_r8] - real(r8), parameter :: area_dst(nb) = [0.13_r8, 0.14_r8, 0.15_r8] - real(r8), parameter :: xc_src(na) = [1.1_r8, 1.2_r8] - real(r8), parameter :: xc_dst(nb) = [2.1_r8, 2.2_r8, 2.3_r8] - real(r8), parameter :: yc_src(na) = [3.1_r8, 3.2_r8] - real(r8), parameter :: yc_dst(nb) = [4.1_r8, 4.2_r8, 4.3_r8] - - call for_test_create_gridmap(this%gridmap, na=na, nb=nb, ns=ns, & - src_indx = src_indx, & - dst_indx = dst_indx, & - wovr = wovr, & - frac_src = frac_src, & - frac_dst = frac_dst, & - area_src = area_src, & - area_dst = area_dst, & - xc_src = xc_src, & - xc_dst = xc_dst, & - yc_src = yc_src, & - yc_dst = yc_dst) - - @assertEqual(na, this%gridmap%na) - @assertEqual(nb, this%gridmap%nb) - @assertEqual(ns, this%gridmap%ns) - @assertEqual(src_indx, this%gridmap%src_indx) - @assertEqual(dst_indx, this%gridmap%dst_indx) - @assertEqual(wovr, this%gridmap%wovr) - @assertEqual(frac_src, this%gridmap%frac_src) - @assertEqual(frac_dst, this%gridmap%frac_dst) - @assertEqual(yc_src, this%gridmap%yc_src) - @assertEqual(yc_dst, this%gridmap%yc_dst) - @assertEqual(xc_src, this%gridmap%xc_src) - @assertEqual(xc_dst, this%gridmap%xc_dst) - @assertEqual(area_src, this%gridmap%area_src) - @assertEqual(area_dst, this%gridmap%area_dst) - - end subroutine forTestCreateGridmap_explicitArgs - -end module test_mkgridmap diff --git a/tools/mksurfdata_map/src/test/mkindexmap_test/CMakeLists.txt b/tools/mksurfdata_map/src/test/mkindexmap_test/CMakeLists.txt deleted file mode 100644 index 044d3e4f89..0000000000 --- a/tools/mksurfdata_map/src/test/mkindexmap_test/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -create_pFUnit_test(mkindexmap test_mkindexmap_exe - "test_mkindexmap.pf" "") - -target_link_libraries(test_mkindexmap_exe mksurfdat) \ No newline at end of file diff --git a/tools/mksurfdata_map/src/test/mkindexmap_test/test_mkindexmap.pf b/tools/mksurfdata_map/src/test/mkindexmap_test/test_mkindexmap.pf deleted file mode 100644 index 98e9590478..0000000000 --- a/tools/mksurfdata_map/src/test/mkindexmap_test/test_mkindexmap.pf +++ /dev/null @@ -1,258 +0,0 @@ -module test_mkindexmap - - ! Tests of mkindexmapMod - - use pfunit_mod - use mkindexmapMod - use mkgridmapMod, only : gridmap_type, for_test_create_gridmap, gridmap_clean - use shr_kind_mod , only : r8 => shr_kind_r8 - - implicit none - - @TestCase - type, extends(TestCase) :: TestMkIndexMap - type(gridmap_type) :: gridmap - contains - procedure :: setUp - procedure :: tearDown - procedure :: createGridmap - procedure :: createGridmap3src1dst - end type TestMkIndexMap - - real(r8), parameter :: tol = 1.e-13_r8 - - integer, parameter :: NODATA_VAL = -999 - -contains - - ! ------------------------------------------------------------------------ - ! Helper routines - ! ------------------------------------------------------------------------ - - - subroutine setUp(this) - class(TestMkIndexMap), intent(inout) :: this - end subroutine setUp - - subroutine tearDown(this) - class(TestMkIndexMap), intent(inout) :: this - call gridmap_clean(this%gridmap) - end subroutine tearDown - - !----------------------------------------------------------------------- - subroutine createGridmap(this, src_indx, dst_indx, wovr, & - na_in, nb_in) - ! - ! !DESCRIPTION: - ! Create this%gridmap - ! - ! !ARGUMENTS: - class(TestMkIndexMap), intent(inout) :: this - - ! The following arrays should all be the same size: - integer, intent(in) :: src_indx(:) - integer, intent(in) :: dst_indx(:) - real(r8), intent(in) :: wovr(:) ! overlap weights - - ! If not present, na is set to max(src_indx) and nb to max(dst_indx) - integer, intent(in), optional :: na_in - integer, intent(in), optional :: nb_in - - ! - ! !LOCAL VARIABLES: - integer :: na - integer :: nb - integer :: ns - - character(len=*), parameter :: subname = 'createGridmap' - !----------------------------------------------------------------------- - - ns = size(wovr) - @assertEqual(ns, size(src_indx)) - @assertEqual(ns, size(dst_indx)) - - if (present(na_in)) then - na = na_in - else - na = maxval(src_indx) - end if - - if (present(nb_in)) then - nb = nb_in - else - nb = maxval(dst_indx) - end if - - call for_test_create_gridmap(this%gridmap, na=na, nb=nb, ns=ns, & - src_indx=src_indx, dst_indx=dst_indx, wovr=wovr) - - end subroutine createGridmap - - !----------------------------------------------------------------------- - subroutine createGridmap3src1dst(this) - ! - ! !DESCRIPTION: - ! Creates a gridmap with 3 src points and 1 dst point. - ! - ! Overlap weights are 0.25, 0.5, 0.25 - ! - ! !ARGUMENTS: - class(TestMkIndexMap), intent(inout) :: this - ! - ! !LOCAL VARIABLES: - - character(len=*), parameter :: subname = 'createGridmap3src1dst' - !----------------------------------------------------------------------- - - call this%createGridmap( & - src_indx = [1, 2, 3], & - dst_indx = [1, 1, 1], & - wovr = [0.25_r8, 0.5_r8, 0.25_r8]) - end subroutine createGridmap3src1dst - - - ! ------------------------------------------------------------------------ - ! Tests of get_max_indices - ! ------------------------------------------------------------------------ - - @Test - subroutine getMaxIndices_maxFirst(this) - class(TestMkIndexMap), intent(inout) :: this - integer :: dst_array(1) - - call this%createGridmap3src1dst() - - call get_max_indices(& - gridmap = this%gridmap, & - src_array = [13, 12, 11], & - dst_array = dst_array, & - nodata = NODATA_VAL, & - mask_src = [1, 1, 1]) - - @assertEqual([13], dst_array) - end subroutine getMaxIndices_maxFirst - - @Test - subroutine getMaxIndices_maxMiddle(this) - class(TestMkIndexMap), intent(inout) :: this - integer :: dst_array(1) - - call this%createGridmap3src1dst() - - call get_max_indices(& - gridmap = this%gridmap, & - src_array = [12, 13, 11], & - dst_array = dst_array, & - nodata = NODATA_VAL, & - mask_src = [1, 1, 1]) - - @assertEqual([13], dst_array) - end subroutine getMaxIndices_maxMiddle - - @Test - subroutine getMaxIndices_maxLast(this) - class(TestMkIndexMap), intent(inout) :: this - integer :: dst_array(1) - - call this%createGridmap3src1dst() - - call get_max_indices(& - gridmap = this%gridmap, & - src_array = [11, 12, 13], & - dst_array = dst_array, & - nodata = NODATA_VAL, & - mask_src = [1, 1, 1]) - - @assertEqual([13], dst_array) - end subroutine getMaxIndices_maxLast - - @Test - subroutine getMaxIndices_noData(this) - class(TestMkIndexMap), intent(inout) :: this - integer :: dst_array(2) - - ! 2 destination points, but all source points map to dest #1 (nothing maps to dest #2) - call this%createGridmap( & - src_indx = [1,2,3], & - dst_indx = [1,1,1], & - wovr = [0.25_r8, 0.5_r8, 0.25_r8], & - nb_in = 2) - - call get_max_indices(& - gridmap = this%gridmap, & - src_array = [11, 12, 13], & - dst_array = dst_array, & - nodata = NODATA_VAL, & - mask_src = [1, 1, 1]) - - @assertEqual([13, NODATA_VAL], dst_array) - end subroutine getMaxIndices_noData - - @Test - subroutine getMaxIndices_noOverlap(this) - class(TestMkIndexMap), intent(inout) :: this - integer :: dst_array(2) - - ! 2 destination points, and the matrix has an overlap with dest #2, but the overlap - ! weight is 0. (I'm not sure this can happen in practice, but I'm also not sure that - ! it can't happen.) - call this%createGridmap( & - src_indx = [1,2,3,3], & - dst_indx = [1,1,1,2], & - wovr = [0.25_r8, 0.5_r8, 0.25_r8, 0._r8]) - - call get_max_indices(& - gridmap = this%gridmap, & - src_array = [11, 12, 13], & - dst_array = dst_array, & - nodata = NODATA_VAL, & - mask_src = [1, 1, 1]) - - @assertEqual([13, NODATA_VAL], dst_array) - end subroutine getMaxIndices_noOverlap - - @Test - subroutine getMaxIndices_bigValNoOverlap(this) - class(TestMkIndexMap), intent(inout) :: this - integer :: dst_array(1) - - ! Overlap weight is 0 for a point with a big value. (I'm not sure this can happen in - ! practice, but I'm also not sure that it can't happen.) - call this%createGridmap( & - src_indx = [1,2,3], & - dst_indx = [1,1,1], & - wovr = [0.5_r8, 0.5_r8, 0._r8]) - - call get_max_indices(& - gridmap = this%gridmap, & - src_array = [11, 12, 13], & - dst_array = dst_array, & - nodata = NODATA_VAL, & - mask_src = [1, 1, 1]) - - @assertEqual([12], dst_array) - end subroutine getMaxIndices_bigValNoOverlap - - @Test - subroutine getMaxIndices_multipleDests(this) - ! Make sure that the source/dest indexing is working right by having multiple source - ! & dest points - class(TestMkIndexMap), intent(inout) :: this - integer :: dst_array(2) - - call this%createGridmap( & - src_indx = [1,2,3,4], & - dst_indx = [1,1,2,2], & - wovr = [0.5_r8, 0.5_r8, 0.5_r8, 0.5_r8]) - - call get_max_indices(& - gridmap = this%gridmap, & - src_array = [11,12,22,21], & - dst_array = dst_array, & - nodata = NODATA_VAL, & - mask_src = [1, 1, 1, 1]) - - @assertEqual([12,22], dst_array) - end subroutine getMaxIndices_multipleDests - -end module test_mkindexmap diff --git a/tools/mksurfdata_map/src/test/mkpctPftType_test/CMakeLists.txt b/tools/mksurfdata_map/src/test/mkpctPftType_test/CMakeLists.txt deleted file mode 100644 index 8fd784c672..0000000000 --- a/tools/mksurfdata_map/src/test/mkpctPftType_test/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -create_pFUnit_test(mkpctPftType test_mkpctPftType_exe - "test_mkpctPftType.pf" "") - -target_link_libraries(test_mkpctPftType_exe mksurfdat) \ No newline at end of file diff --git a/tools/mksurfdata_map/src/test/mkpctPftType_test/test_mkpctPftType.pf b/tools/mksurfdata_map/src/test/mkpctPftType_test/test_mkpctPftType.pf deleted file mode 100644 index 47e7e90f48..0000000000 --- a/tools/mksurfdata_map/src/test/mkpctPftType_test/test_mkpctPftType.pf +++ /dev/null @@ -1,253 +0,0 @@ -module test_mkpctPftType - - ! Tests of pct_pft_type - - use pfunit_mod - - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkpctPftTypeMod - - implicit none - save - - real(r8), parameter :: tol = 1.e-12_r8 - -contains - - @Test - subroutine test_constructor_nonzero() - ! Tests constructor with non-zero area - type(pct_pft_type) :: pct_pft - - pct_pft = pct_pft_type([5._r8, 20._r8, 25._r8], 11, [0._r8, 100._r8, 0._r8]) - - @assertEqual([10._r8, 40._r8, 50._r8], pct_pft%get_pct_p2l(), tolerance=tol) - @assertEqual(50._r8, pct_pft%get_pct_l2g(), tolerance=tol) - @assertEqual(11, pct_pft%get_first_pft_index()) - - end subroutine test_constructor_nonzero - - @Test - subroutine test_constructor_zero() - ! Tests constructor with zero area - type(pct_pft_type) :: pct_pft - real(r8) :: default_pct_p2l(3) - - default_pct_p2l = [0._r8, 100._r8, 0._r8] - - pct_pft = pct_pft_type([0._r8, 0._r8, 0._r8], 11, default_pct_p2l) - @assertEqual(default_pct_p2l, pct_pft%get_pct_p2l()) - @assertEqual(0._r8, pct_pft%get_pct_l2g()) - end subroutine test_constructor_zero - - @Test - subroutine test_constructor_empty() - ! Tests version of constructor with an empty landunit - type(pct_pft_type) :: pct_pft - - pct_pft = pct_pft_type() - @assertEqual(0._r8, pct_pft%get_pct_l2g()) - end subroutine test_constructor_empty - - @Test - subroutine test_assignment() - ! Tests assignment of one object to another - ! - ! Currently there is no defined assignment operator, so the point of this is to - ! ensure that intrinsic assignment works properly, particularly with respect to - ! maintaining the correct lower bound (get_first_pft_index). - type(pct_pft_type) :: source, dest - - source = pct_pft_type([5._r8, 20._r8, 25._r8], 11, [0._r8, 100._r8, 0._r8]) - dest = source - - @assertEqual([10._r8, 40._r8, 50._r8], dest%get_pct_p2l(), tolerance=tol) - @assertEqual(50._r8, dest%get_pct_l2g(), tolerance=tol) - @assertEqual(11, dest%get_first_pft_index()) - end subroutine test_assignment - - @Test - subroutine test_get_pct_p2g() - ! Test the get_pct_p2g routine - type(pct_pft_type) :: pct_pft - - pct_pft = pct_pft_type([5._r8, 20._r8, 25._r8], 11, [0._r8, 100._r8, 0._r8]) - - @assertEqual([5._r8, 20._r8, 25._r8], pct_pft%get_pct_p2g()) - end subroutine test_get_pct_p2g - - @Test - subroutine test_get_one_pct_p2g() - ! Test the get_one_pct_p2g routine - type(pct_pft_type) :: pct_pft - - pct_pft = pct_pft_type([5._r8, 20._r8, 25._r8], 11, [0._r8, 100._r8, 0._r8]) - - @assertEqual(20._r8, pct_pft%get_one_pct_p2g(12)) - end subroutine test_get_one_pct_p2g - - - @Test - subroutine test_set_pct_l2g() - ! Test the set_pct_l2g routine - type(pct_pft_type) :: pct_pft - - pct_pft = pct_pft_type([5._r8, 20._r8, 25._r8], 11, [0._r8, 100._r8, 0._r8]) - - call pct_pft%set_pct_l2g(60._r8) - @assertEqual([10._r8, 40._r8, 50._r8], pct_pft%get_pct_p2l(), tolerance=tol) - @assertEqual(60._r8, pct_pft%get_pct_l2g(), tolerance=tol) - end subroutine test_set_pct_l2g - - - @Test - subroutine test_set_one_pct_p2g() - ! Test the set_one_pct_p2g routine - type(pct_pft_type) :: pct_pft - - pct_pft = pct_pft_type([5._r8, 20._r8, 25._r8], 11, [0._r8, 100._r8, 0._r8]) - - call pct_pft%set_one_pct_p2g(12, 10._r8) - @assertEqual(40._r8, pct_pft%get_pct_l2g(), tolerance=tol) - @assertEqual([12.5_r8, 25._r8, 62.5_r8], pct_pft%get_pct_p2l(), tolerance=tol) - - end subroutine test_set_one_pct_p2g - - @Test - subroutine test_set_one_pct_p2g_to_zero() - ! Test the set_one_pct_p2g routine, when we go to a total area of 0 - type(pct_pft_type) :: pct_pft - - pct_pft = pct_pft_type([20._r8, 0._r8, 0._r8], 11, [0._r8, 100._r8, 0._r8]) - - call pct_pft%set_one_pct_p2g(11, 0._r8) - @assertEqual(0._r8, pct_pft%get_pct_l2g()) - ! note that pct_p2l stays at its original value - @assertEqual([100._r8, 0._r8, 0._r8], pct_pft%get_pct_p2l(), tolerance=tol) - - end subroutine test_set_one_pct_p2g_to_zero - - @Test - subroutine test_set_one_pct_p2g_from_zero() - ! Test the set_one_pct_p2g routine, when we start from a total area of 0 - type(pct_pft_type) :: pct_pft - - pct_pft = pct_pft_type([0._r8, 0._r8, 0._r8], 11, [0._r8, 100._r8, 0._r8]) - - call pct_pft%set_one_pct_p2g(13, 5._r8) - @assertEqual(5._r8, pct_pft%get_pct_l2g()) - @assertEqual([0._r8, 0._r8, 100._r8], pct_pft%get_pct_p2l(), tolerance=tol) - - end subroutine test_set_one_pct_p2g_from_zero - - @Test - subroutine test_merge_pfts() - ! Test the merge_pfts routine - type(pct_pft_type) :: pct_pft - - pct_pft = pct_pft_type([5._r8, 20._r8, 25._r8], 11, [0._r8, 100._r8, 0._r8]) - - call pct_pft%merge_pfts(source=12, dest=13) - @assertEqual(50._r8, pct_pft%get_pct_l2g()) - @assertEqual([10._r8, 0._r8, 90._r8], pct_pft%get_pct_p2l(), tolerance=tol) - end subroutine test_merge_pfts - - @Test - subroutine test_remove_small_cover_no_small() - ! Test the remove_small_cover routine with no small pfts - type(pct_pft_type) :: pct_pft, pct_pft_orig - integer :: nsmall - - pct_pft = pct_pft_type([5._r8, 20._r8, 0._r8], 11, [0._r8, 100._r8, 0._r8]) - pct_pft_orig = pct_pft - - call pct_pft%remove_small_cover(1._r8, nsmall) - @assertEqual(pct_pft_orig%get_pct_l2g(), pct_pft%get_pct_l2g()) - @assertEqual(pct_pft_orig%get_pct_p2l(), pct_pft%get_pct_p2l()) - @assertEqual(0, nsmall) - end subroutine test_remove_small_cover_no_small - - @Test - subroutine test_remove_small_cover_all_small() - ! Test the remove_small_cover routine with all small (or zero) pfts - type(pct_pft_type) :: pct_pft, pct_pft_orig - integer :: nsmall - - pct_pft = pct_pft_type([5._r8, 20._r8, 0._r8], 11, [0._r8, 100._r8, 0._r8]) - pct_pft_orig = pct_pft - - call pct_pft%remove_small_cover(30._r8, nsmall) - @assertEqual(0._r8, pct_pft%get_pct_l2g()) - @assertEqual(pct_pft_orig%get_pct_p2l(), pct_pft%get_pct_p2l()) - @assertEqual(2, nsmall) - end subroutine test_remove_small_cover_all_small - - @Test - subroutine test_remove_small_cover_some_small() - ! Test the remove_small_cover routine with some (but not all) small pfts - type(pct_pft_type) :: pct_pft - integer :: nsmall - - pct_pft = pct_pft_type([5._r8, 20._r8, 0._r8, 25._r8], 11, [0._r8, 100._r8, 0._r8, 0._r8]) - - call pct_pft%remove_small_cover(10._r8, nsmall) - @assertEqual(45._r8, pct_pft%get_pct_l2g()) - @assertEqual([0._r8, 20._r8, 0._r8, 25._r8]/45._r8 * 100._r8, pct_pft%get_pct_p2l(), tolerance=tol) - @assertEqual(1, nsmall) - end subroutine test_remove_small_cover_some_small - - @Test - subroutine test_remove_small_cover_zero_area() - ! Test the remove_small_cover routine with a starting area of 0 - type(pct_pft_type) :: pct_pft - integer :: nsmall - - pct_pft = pct_pft_type([0._r8, 0._r8, 0._r8], 11, [0._r8, 100._r8, 0._r8]) - - call pct_pft%remove_small_cover(1._r8, nsmall) - @assertEqual(0._r8, pct_pft%get_pct_l2g()) - @assertEqual([0._r8, 100._r8, 0._r8], pct_pft%get_pct_p2l()) - @assertEqual(0, nsmall) - end subroutine test_remove_small_cover_zero_area - - @Test - subroutine test_remove_small_cover_no_landunit() - ! Test the remove_small_cover routine when there are no pfts on this landunit - type(pct_pft_type) :: pct_pft - integer :: nsmall - - pct_pft = pct_pft_type() - call pct_pft%remove_small_cover(1._r8, nsmall) - @assertEqual(0._r8, pct_pft%get_pct_l2g()) - @assertEqual(0, nsmall) - end subroutine test_remove_small_cover_no_landunit - - @Test - subroutine test_get_pct_p2l_array() - ! Test the get_pct_p2l_array routine - type(pct_pft_type) :: pct_pft(2) - real(r8) :: expected(2, 3) - - pct_pft(1) = pct_pft_type([10._r8, 40._r8, 50._r8], 11, [0._r8, 100._r8, 0._r8]) - pct_pft(2) = pct_pft_type([5._r8, 30._r8, 65._r8], 11, [0._r8, 100._r8, 0._r8]) - - expected(1,:) = [10._r8, 40._r8, 50._r8] - expected(2,:) = [5._r8, 30._r8, 65._r8] - - @assertEqual(expected, get_pct_p2l_array(pct_pft)) - - end subroutine test_get_pct_p2l_array - - @Test - subroutine test_get_pct_l2g_array() - ! Test the get_pct_l2g_array routine - type(pct_pft_type) :: pct_pft(2) - - pct_pft(1) = pct_pft_type([5._r8, 25._r8, 20._r8], 11, [0._r8, 100._r8, 0._r8]) - pct_pft(2) = pct_pft_type([1._r8, 2._r8, 3._r8], 11, [0._r8, 100._r8, 0._r8]) - - @assertEqual([50._r8, 6._r8], get_pct_l2g_array(pct_pft), tolerance=tol) - - end subroutine test_get_pct_l2g_array - -end module test_mkpctPftType diff --git a/tools/mksurfdata_map/src/test/mkpftUtils_test/CMakeLists.txt b/tools/mksurfdata_map/src/test/mkpftUtils_test/CMakeLists.txt deleted file mode 100644 index 33dd01bcd9..0000000000 --- a/tools/mksurfdata_map/src/test/mkpftUtils_test/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -set (pfunit_sources - test_adjust_total_veg_area.pf - test_convert_from_p2g.pf) - -create_pFUnit_test(mkpftUtils test_mkpftUtils_exe - "${pfunit_sources}" "") - -target_link_libraries(test_mkpftUtils_exe mksurfdat) \ No newline at end of file diff --git a/tools/mksurfdata_map/src/test/mkpftUtils_test/test_adjust_total_veg_area.pf b/tools/mksurfdata_map/src/test/mkpftUtils_test/test_adjust_total_veg_area.pf deleted file mode 100644 index 345c1a7370..0000000000 --- a/tools/mksurfdata_map/src/test/mkpftUtils_test/test_adjust_total_veg_area.pf +++ /dev/null @@ -1,59 +0,0 @@ -module test_adjust_total_veg_area - - ! Tests of mkpftUtilsMod: adjust_total_veg_area - - use pfunit_mod - - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkpctPftTypeMod, only : pct_pft_type - use mkpftUtilsMod, only : adjust_total_veg_area - - implicit none - save - - real(r8), parameter :: tol = 1.e-12_r8 - -contains - - @Test - subroutine test_standard_case() - type(pct_pft_type) :: pctnatpft, pctcft - - pctnatpft = pct_pft_type([5._r8, 10._r8], 1, [100._r8, 0._r8]) - pctcft = pct_pft_type([10._r8, 20._r8], 3, [100._r8, 0._r8]) - - call adjust_total_veg_area(90._r8, pctnatpft, pctcft) - - @assertEqual(30._r8, pctnatpft%get_pct_l2g()) - @assertEqual(60._r8, pctcft%get_pct_l2g()) - end subroutine test_standard_case - - @Test - subroutine test_initial_total_zero() - ! When the old areas are 0, all area should go into natural veg - type(pct_pft_type) :: pctnatpft, pctcft - - pctnatpft = pct_pft_type([0._r8, 0._r8], 1, [100._r8, 0._r8]) - pctcft = pct_pft_type([0._r8, 0._r8], 3, [100._r8, 0._r8]) - - call adjust_total_veg_area(90._r8, pctnatpft, pctcft) - - @assertEqual(90._r8, pctnatpft%get_pct_l2g()) - @assertEqual(0._r8, pctcft%get_pct_l2g()) - end subroutine test_initial_total_zero - - @Test - subroutine test_initial_one_zero() - ! Test a case where this is initially a 0 - make sure it stays 0 - type(pct_pft_type) :: pctnatpft, pctcft - - pctnatpft = pct_pft_type([0._r8, 0._r8], 1, [100._r8, 0._r8]) - pctcft = pct_pft_type([10._r8, 20._r8], 3, [100._r8, 0._r8]) - - call adjust_total_veg_area(90._r8, pctnatpft, pctcft) - - @assertEqual(0._r8, pctnatpft%get_pct_l2g()) - @assertEqual(90._r8, pctcft%get_pct_l2g()) - end subroutine test_initial_one_zero - -end module test_adjust_total_veg_area diff --git a/tools/mksurfdata_map/src/test/mkpftUtils_test/test_convert_from_p2g.pf b/tools/mksurfdata_map/src/test/mkpftUtils_test/test_convert_from_p2g.pf deleted file mode 100644 index 53548e4e6c..0000000000 --- a/tools/mksurfdata_map/src/test/mkpftUtils_test/test_convert_from_p2g.pf +++ /dev/null @@ -1,151 +0,0 @@ -module test_convert_from_p2g - - ! Tests of mkpftUtilsMod: convert_from_p2g - - use pfunit_mod - - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkpctPftTypeMod, only : pct_pft_type - use mkpftUtilsMod, only : convert_from_p2g - use mkpftConstantsMod, only : natpft_lb, natpft_ub, num_cft, cft_lb, cft_ub, c3cropindex - - implicit none - save - - real(r8), parameter :: tol = 1.e-12_r8 - -contains - - subroutine setup() - ! Perform setup for most tests - - natpft_lb = 0 - natpft_ub = 2 - cft_lb = 3 - cft_ub = 4 - num_cft = 2 - - c3cropindex = 3 - - end subroutine setup - - - ! ------------------------------------------------------------------------ - ! Tests of convert_from_p2g_default - ! ------------------------------------------------------------------------ - - @Test - subroutine test_standard() - ! Standard case: some nat pft, some crop - type(pct_pft_type) :: pctnatpft, pctcft - - call setup - - call convert_from_p2g([1._r8, 2._r8, 3._r8, 4._r8, 5._r8], pctnatpft, pctcft) - - @assertEqual(6._r8, pctnatpft%get_pct_l2g(), tolerance=tol) - @assertEqual([1._r8, 2._r8, 3._r8]/6._r8 * 100._r8, pctnatpft%get_pct_p2l(), tolerance=tol) - @assertEqual(9._r8, pctcft%get_pct_l2g(), tolerance=tol) - @assertEqual([4._r8, 5._r8]/9._r8 * 100._r8, pctcft%get_pct_p2l(), tolerance=tol) - end subroutine test_standard - - @Test - subroutine test_natpft0() - ! natpft all 0 (percents should be at their default) - type(pct_pft_type) :: pctnatpft, pctcft - - call setup - - call convert_from_p2g([0._r8, 0._r8, 0._r8, 4._r8, 5._r8], pctnatpft, pctcft) - - @assertEqual(0._r8, pctnatpft%get_pct_l2g()) - @assertEqual([100._r8, 0._r8, 0._r8], pctnatpft%get_pct_p2l()) - @assertEqual(9._r8, pctcft%get_pct_l2g(), tolerance=tol) - @assertEqual([4._r8, 5._r8]/9._r8 * 100._r8, pctcft%get_pct_p2l(), tolerance=tol) - end subroutine test_natpft0 - - @Test - subroutine test_cft0() - ! cft landunit present, but all 0 (percents should be at their default) - type(pct_pft_type) :: pctnatpft, pctcft - - call setup - - call convert_from_p2g([1._r8, 2._r8, 3._r8, 0._r8, 0._r8], pctnatpft, pctcft) - @assertEqual(6._r8, pctnatpft%get_pct_l2g(), tolerance=tol) - @assertEqual([1._r8, 2._r8, 3._r8]/6._r8 * 100._r8, pctnatpft%get_pct_p2l(), tolerance=tol) - @assertEqual(0._r8, pctcft%get_pct_l2g(), tolerance=tol) - @assertEqual([100._r8, 0._r8], pctcft%get_pct_p2l(), tolerance=tol) - end subroutine test_cft0 - - @Test - subroutine test_no_cft_landunit() - ! no cft landunit - type(pct_pft_type) :: pctnatpft, pctcft - - call setup - - cft_lb = 3 - cft_ub = 2 - num_cft = 0 - - call convert_from_p2g([1._r8, 2._r8, 3._r8], pctnatpft, pctcft) - @assertEqual(6._r8, pctnatpft%get_pct_l2g(), tolerance=tol) - @assertEqual([1._r8, 2._r8, 3._r8]/6._r8 * 100._r8, pctnatpft%get_pct_p2l(), tolerance=tol) - @assertEqual(0._r8, pctcft%get_pct_l2g(), tolerance=tol) - - end subroutine test_no_cft_landunit - - ! ------------------------------------------------------------------------ - ! Tests of convert_from_p2g_missing_crops - ! ------------------------------------------------------------------------ - - @Test - subroutine test_missing_crops() - type(pct_pft_type) :: pctnatpft, pctcft_saved, pctcft - - call setup - ! add an extra cft to make sure it's okay for the pct_p2g input to not contain the - ! same number of elements as the cft landunit - cft_ub = 5 - num_cft = 3 - pctcft_saved = pct_pft_type([10._r8, 15._r8, 20._r8], cft_lb, [100._r8, 0._r8, 0._r8]) - - call convert_from_p2g([1._r8, 2._r8, 3._r8, 4._r8, 0._r8], pctcft_saved, pctnatpft, pctcft) - @assertEqual(6._r8, pctnatpft%get_pct_l2g(), tolerance=tol) - @assertEqual([1._r8, 2._r8, 3._r8]/6._r8 * 100._r8, pctnatpft%get_pct_p2l(), tolerance=tol) - @assertEqual(4._r8, pctcft%get_pct_l2g(), tolerance=tol) - @assertEqual([10._r8, 15._r8, 20._r8]/45._r8 * 100._r8, pctcft%get_pct_p2l(), tolerance=tol) - - end subroutine test_missing_crops - - @Test - subroutine test_missing_crops_natpft0() - ! Make sure the setting of the natpft default works correctly for the missing_crops - ! version of the subroutine - type(pct_pft_type) :: pctnatpft, pctcft_saved, pctcft - - call setup - pctcft_saved = pct_pft_type([10._r8, 15._r8], cft_lb, [100._r8, 0._r8]) - - call convert_from_p2g([0._r8, 0._r8, 0._r8, 4._r8, 0._r8], pctcft_saved, pctnatpft, pctcft) - @assertEqual(0._r8, pctnatpft%get_pct_l2g()) - @assertEqual([100._r8, 0._r8, 0._r8], pctnatpft%get_pct_p2l()) - @assertEqual(4._r8, pctcft%get_pct_l2g(), tolerance=tol) - @assertEqual([10._r8, 15._r8]/25._r8 * 100._r8, pctcft%get_pct_p2l(), tolerance=tol) - end subroutine test_missing_crops_natpft0 - - @Test - subroutine test_missing_crops_cft0() - ! Make sure the cft cover is as expected when the cft landunit area goes to 0 - type(pct_pft_type) :: pctnatpft, pctcft_saved, pctcft - - call setup - pctcft_saved = pct_pft_type([10._r8, 15._r8], cft_lb, [100._r8, 0._r8]) - - call convert_from_p2g([1._r8, 2._r8, 3._r8, 0._r8, 0._r8], pctcft_saved, pctnatpft, pctcft) - @assertEqual(0._r8, pctcft%get_pct_l2g(), tolerance=tol) - @assertEqual([10._r8, 15._r8]/25._r8 * 100._r8, pctcft%get_pct_p2l(), tolerance=tol) - end subroutine test_missing_crops_cft0 - -end module test_convert_from_p2g diff --git a/tools/mksurfdata_map/src/test/mkpftmod_test/CMakeLists.txt b/tools/mksurfdata_map/src/test/mkpftmod_test/CMakeLists.txt deleted file mode 100644 index 8fcb75145f..0000000000 --- a/tools/mksurfdata_map/src/test/mkpftmod_test/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -set (pfunit_sources - test_pftrun.pf - test_pft_oride.pf - test_pftInit.pf) - -create_pFUnit_test(mkpftMod test_mkpft_exe - "${pfunit_sources}" "") - -target_link_libraries(test_mkpft_exe mksurfdat) diff --git a/tools/mksurfdata_map/src/test/mkpftmod_test/test_pftInit.pf b/tools/mksurfdata_map/src/test/mkpftmod_test/test_pftInit.pf deleted file mode 100644 index 1ddb143961..0000000000 --- a/tools/mksurfdata_map/src/test/mkpftmod_test/test_pftInit.pf +++ /dev/null @@ -1,297 +0,0 @@ -module test_pftInit - - ! Tests of mkpftMod: pft_override functions - - use pfunit_mod - - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkpftMod - use mkvarctl, only: numpft - use mkvarpar, only: numstdpft, noveg - use mkpftConstantsMod, only: maxpft, c3cropindex - - implicit none - save - - @TestCase - type, extends(TestCase) :: TestMkPFT - contains - procedure :: setUp - procedure :: tearDown - end type TestMkPFT - -contains - - subroutine setUp(this) - class(TestMkPFT), intent(inout) :: this - numpft = numstdpft - pft_idx(0:maxpft) = -1 - pft_frc(0:maxpft) = 0.0_r8 - end subroutine setUp - - subroutine tearDown(this) - class(TestMkPFT), intent(inout) :: this - - end subroutine tearDown - - @Test - subroutine test_runmkpftInit(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .false. - all_veg_l = .false. - call mkpftInit( zero_out_l, all_veg_l ) - @assertFalse( use_input_pft ) - @assertFalse( presc_cover ) - - end subroutine test_runmkpftInit - - @Test - subroutine test_runmkpftInitZero(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .true. - all_veg_l = .false. - call mkpftInit( zero_out_l, all_veg_l ) - @assertTrue( use_input_pft ) - @assertTrue( presc_cover ) - @assertEqual( pft_idx(0), noveg ) - @assertEqual( pft_frc(0), 0.0_r8 ) - - end subroutine test_runmkpftInitZero - - @Test - subroutine test_runmkpftInitPftORide(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .false. - pft_idx(0) = 1 - pft_frc(0) = 100._r8 - all_veg_l = .true. - call mkpftInit( zero_out_l, all_veg_l ) - @assertTrue( use_input_pft ) - @assertTrue( presc_cover ) - - end subroutine test_runmkpftInitPftORide - - - @Test - subroutine test_runmkpftInitPftORideButNOTAllVeg(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .false. - pft_idx(0:1) = (/ 1, c3cropindex /) - pft_frc(0:1) = (/ 50._r8, 50.0_r8 /) - all_veg_l = .true. - call mkpftInit( zero_out_l, all_veg_l ) - @assertTrue( use_input_pft ) - @assertTrue( presc_cover ) - - end subroutine test_runmkpftInitPftORideButNOTAllVeg - - - @Test - subroutine test_runmkpftInitPftORideCrop(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .false. - numpft = maxpft - pft_idx(0) = 17 - pft_frc(0) = 100._r8 - all_veg_l = .true. - call mkpftInit( zero_out_l, all_veg_l ) - @assertTrue( use_input_pft ) - @assertTrue( presc_cover ) - - end subroutine test_runmkpftInitPftORideCrop - - - @Test - subroutine test_runmkpftInitPftORideAll(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - integer :: i - - zero_out_l = .false. - numpft = numstdpft - do i = 0, numpft - pft_idx(i) = i - pft_frc(i) = 1.0_r8 - end do - pft_frc(numpft) = 100._r8 - sum(pft_frc(0:numpft-1)) - @assertEqual( 100.0_r8, sum(pft_frc) ) - all_veg_l = .true. - call mkpftInit( zero_out_l, all_veg_l ) - @assertTrue( use_input_pft ) - @assertTrue( presc_cover ) - - end subroutine test_runmkpftInitPftORideAll - - @Test - subroutine test_runmkpftInitPFTOrideWarnNoCrop(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .false. - numpft = maxpft - pft_idx(0) = 1 - pft_frc(0) = 100._r8 - all_veg_l = .true. - call mkpftInit( zero_out_l, all_veg_l ) - @assertTrue( use_input_pft ) - @assertTrue( presc_cover ) - - end subroutine test_runmkpftInitPFTOrideWarnNoCrop - - @Test - subroutine test_runmkpftInitPFTOrideWarnNoNatVeg(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .false. - numpft = maxpft - pft_idx(0) = c3cropindex - pft_frc(0) = 100._r8 - all_veg_l = .true. - call mkpftInit( zero_out_l, all_veg_l ) - @assertTrue( use_input_pft ) - @assertTrue( presc_cover ) - - end subroutine test_runmkpftInitPFTOrideWarnNoNatVeg - - @Test - subroutine test_runmkpftInitBadZeroNInput(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .true. - numpft = maxpft - pft_idx(0) = numstdpft+1 - pft_frc(0) = 100._r8 - all_veg_l = .true. - call mkpftInit( zero_out_l, all_veg_l ) - @assertExceptionRaised( "ABORTED:" ) - - end subroutine test_runmkpftInitBadZeroNInput - - @Test - subroutine test_runmkpftInitBadAllVeg(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .false. - all_veg_l = .true. - call mkpftInit( zero_out_l, all_veg_l ) - @assertExceptionRaised( "ABORTED:" ) - - end subroutine test_runmkpftInitBadAllVeg - - @Test - subroutine test_runmkpftInitBadNotSum(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .false. - all_veg_l = .true. - numpft = maxpft - pft_idx(0) = numstdpft+1 - pft_frc(0) = 99._r8 - call mkpftInit( zero_out_l, all_veg_l ) - @assertExceptionRaised( "ABORTED:" ) - - end subroutine test_runmkpftInitBadNotSum - - @Test - subroutine test_runmkpftInitBadPFTOutRange(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .false. - all_veg_l = .true. - numpft = numstdpft - pft_idx(0) = numstdpft+1 - pft_frc(0) = 100._r8 - call mkpftInit( zero_out_l, all_veg_l ) - @assertExceptionRaised( "ABORTED:" ) - - end subroutine test_runmkpftInitBadPFTOutRange - - @Test - subroutine test_runmkpftInitBadPFTBadVals(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .false. - all_veg_l = .true. - numpft = maxpft - pft_idx(0:1) = (/ numstdpft+1, numstdpft+2 /) - pft_frc(0:1) = (/ 101._r8, -1._r8 /) - call mkpftInit( zero_out_l, all_veg_l ) - @assertExceptionRaised( "ABORTED:" ) - - end subroutine test_runmkpftInitBadPFTBadVals - - @Test - subroutine test_runmkpftInitBadnumpft(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .false. - all_veg_l = .true. - numpft = 79 - call mkpftInit( zero_out_l, all_veg_l ) - @assertExceptionRaised( "ABORTED:" ) - - end subroutine test_runmkpftInitBadnumpft - - @Test - subroutine test_runmkpftInitBadFrcNotIdx(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .false. - all_veg_l = .true. - numpft = maxpft - pft_idx(0) = numstdpft+1 - pft_frc(0:1) = (/ 99._r8, 1._r8 /) - call mkpftInit( zero_out_l, all_veg_l ) - @assertExceptionRaised( "ABORTED:" ) - - end subroutine test_runmkpftInitBadFrcNotIdx - - @Test - subroutine test_runmkpftInitBadIdxTwice(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .false. - all_veg_l = .true. - numpft = maxpft - pft_idx(0:1) = (/ 17, 17 /) - pft_frc(0:1) = (/ 99._r8, 1._r8 /) - call mkpftInit( zero_out_l, all_veg_l ) - @assertExceptionRaised( "ABORTED:" ) - - end subroutine test_runmkpftInitBadIdxTwice - - @Test - subroutine test_runmkpftInitBadFrcAfterZero(this) - class(TestMkPFT), intent(inout) :: this - logical :: zero_out_l, all_veg_l - - zero_out_l = .false. - numpft = maxpft - all_veg_l = .true. - pft_idx(0:2) = (/ 17, -1, 18 /) - pft_frc(0:2) = (/ 99._r8, 0.0_r8, 1._r8 /) - call mkpftInit( zero_out_l, all_veg_l ) - @assertExceptionRaised( "ABORTED:" ) - end subroutine test_runmkpftInitBadFrcAfterZero - - -end module test_pftInit diff --git a/tools/mksurfdata_map/src/test/mkpftmod_test/test_pft_oride.pf b/tools/mksurfdata_map/src/test/mkpftmod_test/test_pft_oride.pf deleted file mode 100644 index 97cfc66d1e..0000000000 --- a/tools/mksurfdata_map/src/test/mkpftmod_test/test_pft_oride.pf +++ /dev/null @@ -1,127 +0,0 @@ -module test_pft_oride - - ! Tests of mkpftMod: pft_override functions - - use pfunit_mod - - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkpftMod - use mkvarctl, only : numpft - use mkvarpar, only : numstdpft - use mkpftConstantsMod, only : c3cropindex, c3irrcropindex - - implicit none - save - - @TestCase - type, extends(TestCase) :: TestPFTORide - type(pft_oride) :: pftoverride - contains - procedure :: setUp - procedure :: tearDown - end type TestPFTORide - - logical :: zero_out, all_veg_l - -contains - - subroutine setUp(this) - class(TestPFTORide), intent(inout) :: this - - pft_idx(:) = -1 - pft_frc(:) = 0.0_r8 - zero_out = .false. - numpft = numstdpft - all_veg_l = .false. - call mkpftInit( zero_out, all_veg_l ) - this%pftoverride = pft_oride( ) - end subroutine setUp - - subroutine tearDown(this) - class(TestPFTORide), intent(inout) :: this - - call this%pftoverride%Clean() - - end subroutine tearDown - - @Test - subroutine test_runmkpftZero(this) - class(TestPFTORide), intent(inout) :: this - - zero_out = .true. - all_veg_l = .false. - call mkpftInit( zero_out, all_veg_l ) - call this%pftoverride%InitZeroOut() - @assertEqual( 0.0_r8, this%pftoverride%crop ) - @assertEqual( 0.0_r8, this%pftoverride%natveg ) - @assertEqual( 100.0_r8, sum(this%pftoverride%cft)) - @assertEqual( 100.0_r8, sum(this%pftoverride%natpft)) - - end subroutine test_runmkpftZero - - @Test - subroutine test_runSetpft(this) - class(TestPFTORide), intent(inout) :: this - integer, parameter :: pftidx = 1 - - pft_idx(0) = pftidx - pft_frc(0) = 100.0_r8 - zero_out = .false. - all_veg_l = .true. - call mkpftInit( zero_out, all_veg_l ) - call this%pftoverride%InitAllPFTIndex() - @assertEqual( 0.0_r8, this%pftoverride%crop ) - @assertEqual( 100.0_r8, this%pftoverride%natveg ) - @assertEqual( 100.0_r8, sum(this%pftoverride%cft) ) - @assertEqual( 100.0_r8, sum(this%pftoverride%natpft) ) - @assertEqual( 100.0_r8, this%pftoverride%natpft(pftidx) ) - - end subroutine test_runSetpft - - @Test - subroutine test_runSetCrop(this) - class(TestPFTORide), intent(inout) :: this - integer :: cftidx - - cftidx = c3cropindex - pft_idx(0) = cftidx - pft_frc(0) = 100.0_r8 - zero_out = .false. - all_veg_l = .true. - call mkpftInit( zero_out, all_veg_l ) - call this%pftoverride%InitAllPFTIndex() - @assertEqual( 100.0_r8, this%pftoverride%crop ) - @assertEqual( 0.0_r8, this%pftoverride%natveg ) - @assertEqual( 100.0_r8, sum(this%pftoverride%cft) ) - @assertEqual( 100.0_r8, sum(this%pftoverride%natpft) ) - @assertEqual( 100.0_r8, this%pftoverride%cft(numpft-cftidx) ) - - end subroutine test_runSetCrop - - @Test - subroutine test_runSetMix(this) - class(TestPFTORide), intent(inout) :: this - integer :: cftidx, cftidx2, pftidx2 - integer, parameter :: pftidx = 1 - - zero_out = .false. - pftidx2 = c3cropindex-1 - cftidx = c3cropindex - cftidx2 = c3irrcropindex - pft_idx(0:3) = (/ pftidx, pftidx2, cftidx, cftidx2 /) - pft_frc(0:3) = (/ 25.0_r8, 25.0_r8, 25.0_r8, 25.0_r8 /) - all_veg_l = .true. - call mkpftInit( zero_out, all_veg_l ) - call this%pftoverride%InitAllPFTIndex() - @assertEqual( 50.0_r8, this%pftoverride%crop ) - @assertEqual( 50.0_r8, this%pftoverride%natveg ) - @assertEqual( 100.0_r8, sum(this%pftoverride%cft) ) - @assertEqual( 100.0_r8, sum(this%pftoverride%natpft) ) - @assertEqual( 50.0_r8, this%pftoverride%natpft(pftidx) ) - @assertEqual( 50.0_r8, this%pftoverride%natpft(pftidx2) ) - @assertEqual( 50.0_r8, this%pftoverride%cft(1) ) - @assertEqual( 50.0_r8, this%pftoverride%cft(2) ) - - end subroutine test_runSetMix - -end module test_pft_oride diff --git a/tools/mksurfdata_map/src/test/mkpftmod_test/test_pftrun.pf b/tools/mksurfdata_map/src/test/mkpftmod_test/test_pftrun.pf deleted file mode 100644 index 389748764b..0000000000 --- a/tools/mksurfdata_map/src/test/mkpftmod_test/test_pftrun.pf +++ /dev/null @@ -1,204 +0,0 @@ -module test_pftrun - - ! Tests of mkpftMod: pft_override functions - - use pfunit_mod - - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkpftMod - use mkvarctl, only: numpft - use mkvarpar, only: numstdpft - use mkpftConstantsMod, only: maxpft, c3cropindex, c3irrcropindex - use mkpctPftTypeMod , only : pct_pft_type - use mkdomainMod , only : domain_type, for_test_create_domain, domain_clean - - implicit none - save - - @TestCase - type, extends(TestCase) :: TestMkPFTRun - character(len=12) :: mapfname - character(len=12) :: fpft - type(domain_type) :: ldomain - integer :: ndiag - real(r8), allocatable :: expected(:) - real(r8) :: expected_cft(2) - real(r8) :: expected_pft(0:14) - type(pct_pft_type), allocatable :: pctnatpft(:) ! % of grid cell that is nat veg, and breakdown into PFTs - real(r8), allocatable :: pctlnd_pft(:) ! PFT data: % of gridcell for PFTs - type(pct_pft_type), allocatable :: pctcft(:) ! % of grid cell that is crop, and breakdown into CFTs - contains - procedure :: setUp - procedure :: tearDown - end type TestMkPFTRun - -contains - - subroutine setUp(this) - class(TestMkPFTRun), intent(inout) :: this - integer :: ns_o - - numpft = numstdpft - pft_idx(0:maxpft) = -1 - pft_frc(0:maxpft) = 0.0_r8 - this%ndiag = 6 - this%mapfname = "none" - this%fpft = "none" - call for_test_create_domain( this%ldomain ) - ns_o = this%ldomain%ns - allocate( this%pctnatpft(ns_o) ) - allocate( this%pctlnd_pft(ns_o) ) - allocate( this%pctcft(ns_o) ) - allocate( this%expected(ns_o) ) - this%expected = 0.0_r8 - this%expected_cft = 0.0_r8 - this%expected_pft = 0.0_r8 - end subroutine setUp - - subroutine tearDown(this) - class(TestMkPFTRun), intent(inout) :: this - - deallocate( this%pctnatpft ) - deallocate( this%pctlnd_pft ) - deallocate( this%pctcft ) - deallocate( this%expected ) - call domain_clean( this%ldomain ) - - end subroutine tearDown - - @Test - subroutine test_runmkpftZero(this) - class(TestMkPFTRun), intent(inout) :: this - logical :: zero_out, all_veg_l - integer :: n - - zero_out = .true. - all_veg_l = .false. - call mkpftInit( zero_out, all_veg_l ) - @assertTrue( use_input_pft ) - @assertTrue( presc_cover ) - call mkpft(this%ldomain, this%mapfname, this%fpft, this%ndiag, & - pctlnd_o=this%pctlnd_pft, pctnatpft_o=this%pctnatpft, pctcft_o=this%pctcft) - this%expected = 100.0_r8 - @assertEqual( this%expected, this%pctlnd_pft ) - do n = 1, this%ldomain%ns - @assertEqual( this%pctnatpft(n)%get_pct_l2g(), 0.0_r8 ) - @assertEqual( this%pctcft(n)%get_pct_l2g(), 0.0_r8 ) - this%expected_pft = 0.0_r8 - this%expected_pft(0) = 100.0_r8 - this%expected_cft = 0.0_r8 - this%expected_cft(1) = 100.0_r8 - @assertEqual( this%pctnatpft(n)%get_pct_p2l(), this%expected_pft ) - @assertEqual( this%pctcft(n)%get_pct_p2l(), this%expected_cft ) - end do - - end subroutine test_runmkpftZero - - @Test - subroutine test_runmkpftPftORide(this) - class(TestMkPFTRun), intent(inout) :: this - logical :: zero_out, all_veg_l - integer :: n - integer, parameter :: pftidx = 1 - - zero_out = .false. - all_veg_l = .true. - pft_idx(0) = pftidx - pft_frc(0) = 100._r8 - call mkpftInit( zero_out, all_veg_l ) - @assertTrue( use_input_pft ) - @assertTrue( presc_cover ) - call mkpft(this%ldomain, this%mapfname, this%fpft, this%ndiag, & - pctlnd_o=this%pctlnd_pft, pctnatpft_o=this%pctnatpft, pctcft_o=this%pctcft) - this%expected = 100.0_r8 - @assertEqual( this%expected, this%pctlnd_pft ) - do n = 1, this%ldomain%ns - @assertEqual( this%pctnatpft(n)%get_pct_l2g(), 100.0_r8 ) - @assertEqual( this%pctcft(n)%get_pct_l2g(), 0.0_r8 ) - this%expected_pft = 0.0_r8 - this%expected_pft(pftidx) = 100.0_r8 - this%expected_cft = 0.0_r8 - this%expected_cft(1) = 100.0_r8 - @assertEqual( this%pctnatpft(n)%get_pct_p2l(), this%expected_pft ) - @assertEqual( this%pctcft(n)%get_pct_p2l(), this%expected_cft ) - end do - - end subroutine test_runmkpftPftORide - - - @Test - subroutine test_runmkpftPftORideWCrop(this) - use mkvarpar, only: numstdpft, numstdcft - class(TestMkPFTRun), intent(inout) :: this - logical :: zero_out, all_veg_l - integer :: n - integer :: cftidx - integer, parameter :: pftidx = 1 - - cftidx = c3cropindex - zero_out = .false. - all_veg_l = .true. - @assertLessThan( pftidx, numstdpft-numstdcft+1 ) - @assertGreaterThan( cftidx, numstdpft-numstdcft ) - pft_idx(0:1) = (/ pftidx, cftidx /) - pft_frc(0:1) = (/ 50.0_r8, 50.0_r8 /) - call mkpftInit( zero_out, all_veg_l ) - @assertTrue( use_input_pft ) - @assertTrue( presc_cover ) - call mkpft(this%ldomain, this%mapfname, this%fpft, this%ndiag, & - pctlnd_o=this%pctlnd_pft, pctnatpft_o=this%pctnatpft, pctcft_o=this%pctcft) - this%expected = 100.0_r8 - @assertEqual( this%expected, this%pctlnd_pft ) - do n = 1, this%ldomain%ns - @assertEqual( this%pctnatpft(n)%get_pct_l2g(), 50.0_r8 ) - @assertEqual( this%pctcft(n)%get_pct_l2g(), 50.0_r8 ) - this%expected_pft = 0.0_r8 - this%expected_pft(pftidx) = 100.0_r8 - this%expected_cft = 0.0_r8 - this%expected_cft(numstdpft-cftidx) = 100.0_r8 - @assertEqual( this%pctnatpft(n)%get_pct_p2l(), this%expected_pft ) - @assertEqual( this%pctcft(n)%get_pct_p2l(), this%expected_cft ) - end do - - end subroutine test_runmkpftPftORideWCrop - - @Test - subroutine test_runmkpft4PftORideWCrop(this) - use mkvarpar, only: numstdpft, numstdcft - class(TestMkPFTRun), intent(inout) :: this - logical :: zero_out, all_veg_l - integer :: n - integer :: cftidx, cftidx2 - integer, parameter :: pftidx = 1, pftidx2 = 2 - - cftidx = c3cropindex - cftidx2 = c3irrcropindex - zero_out = .false. - all_veg_l = .true. - @assertLessThan( pftidx, numstdpft-numstdcft+1 ) - @assertLessThan( pftidx2, numstdpft-numstdcft+1 ) - @assertGreaterThan( cftidx, numstdpft-numstdcft ) - @assertGreaterThan( cftidx2, numstdpft-numstdcft ) - pft_idx(0:3) = (/ pftidx, pftidx2, cftidx, cftidx2 /) - pft_frc(0:3) = (/ 25.0_r8, 25.0_r8, 25.0_r8, 25.0_r8 /) - call mkpftInit( zero_out, all_veg_l ) - @assertTrue( use_input_pft ) - @assertTrue( presc_cover ) - call mkpft(this%ldomain, this%mapfname, this%fpft, this%ndiag, & - pctlnd_o=this%pctlnd_pft, pctnatpft_o=this%pctnatpft, pctcft_o=this%pctcft) - this%expected = 100.0_r8 - @assertEqual( this%expected, this%pctlnd_pft ) - do n = 1, this%ldomain%ns - @assertEqual( this%pctnatpft(n)%get_pct_l2g(), 50.0_r8 ) - @assertEqual( this%pctcft(n)%get_pct_l2g(), 50.0_r8 ) - this%expected_pft = 0.0_r8 - this%expected_pft(pftidx) = 50.0_r8 - this%expected_pft(pftidx2) = 50.0_r8 - this%expected_cft = 50.0_r8 - @assertEqual( this%pctnatpft(n)%get_pct_p2l(), this%expected_pft ) - @assertEqual( this%pctcft(n)%get_pct_p2l(), this%expected_cft ) - end do - - end subroutine test_runmkpft4PftORideWCrop - -end module test_pftrun diff --git a/tools/mksurfdata_map/src/test/mksoilUtils_test/CMakeLists.txt b/tools/mksurfdata_map/src/test/mksoilUtils_test/CMakeLists.txt deleted file mode 100644 index 4d94b8114b..0000000000 --- a/tools/mksurfdata_map/src/test/mksoilUtils_test/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -set (pfunit_sources - test_dominant_soil_color.pf) - -create_pFUnit_test(mksoilUtils test_mksoilUtils_exe - "${pfunit_sources}" "") - -target_link_libraries(test_mksoilUtils_exe mksurfdat) \ No newline at end of file diff --git a/tools/mksurfdata_map/src/test/mksoilUtils_test/test_dominant_soil_color.pf b/tools/mksurfdata_map/src/test/mksoilUtils_test/test_dominant_soil_color.pf deleted file mode 100644 index b506549d87..0000000000 --- a/tools/mksurfdata_map/src/test/mksoilUtils_test/test_dominant_soil_color.pf +++ /dev/null @@ -1,140 +0,0 @@ -module test_dominant_soil_color - - ! Tests of mksoilUtilsMod: dominant_soil_color - - use pfunit_mod - use mksoilUtilsMod - use shr_kind_mod , only : r8 => shr_kind_r8 - use mkgridmapMod, only : gridmap_type, gridmap_clean, for_test_create_gridmap - - implicit none - - @TestCase - type, extends(TestCase) :: tdsc - type(gridmap_type) :: gridmap - contains - procedure :: setUp - procedure :: tearDown - procedure :: createGridmap1dst - end type tdsc - - real(r8), parameter :: tol = 1.e-13_r8 - -contains - - subroutine setUp(this) - class(tdsc), intent(inout) :: this - end subroutine setUp - - subroutine tearDown(this) - class(tdsc), intent(inout) :: this - call gridmap_clean(this%gridmap) - end subroutine tearDown - - subroutine createGridmap1dst(this, wovr) - ! Create this%gridmap with a single destination point - class(tdsc), intent(inout) :: this - real(r8), intent(in) :: wovr(:) ! overlap weights - - integer :: i - integer :: npts - integer :: src_indx(size(wovr)) - integer :: dst_indx(size(wovr)) - - dst_indx(:) = 1 - npts = size(wovr) - src_indx(:) = [(i, i = 1, npts)] - - call for_test_create_gridmap(this%gridmap, na = npts, nb = 1, ns = npts, & - src_indx = src_indx, dst_indx = dst_indx, wovr = wovr) - end subroutine createGridmap1dst - - @Test - subroutine equalWeights(this) - ! Four inputs with equal weight; two of one class, one of each of two other classes - class(tdsc), intent(inout) :: this - integer :: mask_i(4) - integer :: soil_color_i(4) - integer :: soil_color_o(1) - - call this%createGridmap1dst([0.25_r8, 0.25_r8, 0.25_r8, 0.25_r8]) - mask_i(:) = 1 - soil_color_i(:) = [1, 2, 2, 3] - - call dominant_soil_color(this%gridmap, mask_i, soil_color_i, 20, soil_color_o) - - @assertEqual(2, soil_color_o(1)) - end subroutine equalWeights - - @Test - subroutine inequalWeights(this) - ! Four inputs with inequal weight - class(tdsc), intent(inout) :: this - integer :: mask_i(4) - integer :: soil_color_i(4) - integer :: soil_color_o(1) - - call this%createGridmap1dst([0.5_r8, 0.2_r8, 0.2_r8, 0.1_r8]) - mask_i(:) = 1 - soil_color_i(:) = [3, 1, 1, 2] - - call dominant_soil_color(this%gridmap, mask_i, soil_color_i, 20, soil_color_o) - - @assertEqual(3, soil_color_o(1)) - end subroutine inequalWeights - - @Test - subroutine noColor(this) - ! No color in input - class(tdsc), intent(inout) :: this - integer :: mask_i(4) - integer :: soil_color_i(4) - integer :: soil_color_o(1) - - call this%createGridmap1dst([0.25_r8, 0.25_r8, 0.25_r8, 0.25_r8]) - ! Some points are inside the mask with color = 0, other points are outside the mask - mask_i(:) = [1, 0, 0, 1] - soil_color_i(:) = [0, 1, 1, 0] - - call dominant_soil_color(this%gridmap, mask_i, soil_color_i, 20, soil_color_o) - - @assertEqual(15, soil_color_o(1)) - end subroutine noColor - - @Test - subroutine noColorInFirstPoints(this) - ! No color in the first points, but a color in the last point - class(tdsc), intent(inout) :: this - integer :: mask_i(4) - integer :: soil_color_i(4) - integer :: soil_color_o(1) - - call this%createGridmap1dst([0.25_r8, 0.25_r8, 0.25_r8, 0.25_r8]) - ! Some points are inside the mask with color = 0, other points are outside the mask - mask_i(:) = 1 - soil_color_i(:) = [0, 0, 0, 1] - - call dominant_soil_color(this%gridmap, mask_i, soil_color_i, 20, soil_color_o) - - @assertEqual(1, soil_color_o(1)) - end subroutine noColorInFirstPoints - - @Test - subroutine noColorInLastPoints(this) - ! No color in the last points, but a color in the first point - class(tdsc), intent(inout) :: this - integer :: mask_i(4) - integer :: soil_color_i(4) - integer :: soil_color_o(1) - - call this%createGridmap1dst([0.25_r8, 0.25_r8, 0.25_r8, 0.25_r8]) - ! Some points are inside the mask with color = 0, other points are outside the mask - mask_i(:) = 1 - soil_color_i(:) = [1, 0, 0, 0] - - call dominant_soil_color(this%gridmap, mask_i, soil_color_i, 20, soil_color_o) - - @assertEqual(1, soil_color_o(1)) - end subroutine noColorInLastPoints - -end module test_dominant_soil_color diff --git a/tools/mksurfdata_map/src/unit_test_stubs/abort.F90 b/tools/mksurfdata_map/src/unit_test_stubs/abort.F90 deleted file mode 100644 index aa1d8b76c2..0000000000 --- a/tools/mksurfdata_map/src/unit_test_stubs/abort.F90 +++ /dev/null @@ -1,25 +0,0 @@ -subroutine abort() - ! Replacement for abort that throws a pfunit exception rather than aborting - ! - ! This can be used to test expected errors (i.e., failure testing). - ! - ! If this occurs within a pFUnit-based test: - ! - ! - If you have code like: - ! - ! @assertExceptionRaised("ABORTED:") - ! - ! - If you don't have - ! - ! @assertExceptionRaised - ! - ! or - ! - ! call assertExceptionRaised - ! - ! then this will result in the given pFUnit test failing. - use pfunit_mod, only : throw - implicit none - - call throw("ABORTED:") -end subroutine abort diff --git a/tools/mksurfdata_map/src/unit_test_stubs/mkncdio.F90 b/tools/mksurfdata_map/src/unit_test_stubs/mkncdio.F90 deleted file mode 100644 index 1bf6a8afdf..0000000000 --- a/tools/mksurfdata_map/src/unit_test_stubs/mkncdio.F90 +++ /dev/null @@ -1,223 +0,0 @@ -module mkncdio - ! Stub of mkncdio for unit testing. This is enough to get other modules to compile, but - ! it doesn't do anything useful. - - use shr_kind_mod, only : r8 => shr_kind_r8 - - implicit none - private - - public :: nf_open - public :: nf_close - public :: nf_strerror - public :: nf_inq_dimid - public :: nf_inq_dimname - public :: nf_inq_dimlen - public :: nf_inq_varid - public :: nf_inq_varndims - public :: nf_inq_vardimid - public :: nf_get_var_double - public :: nf_get_var_int - public :: nf_get_vara_double - public :: nf_get_att_double - public :: ncd_defvar - public :: ncd_def_spatial_var - - public :: get_dim_lengths - - public :: check_ret - public :: convert_latlon - - interface nf_get_var_double - module procedure nf_get_var_double_1d - module procedure nf_get_var_double_2d - end interface nf_get_var_double - - interface nf_get_vara_double - module procedure nf_get_vara_double_2d - end interface nf_get_vara_double - - integer, parameter, public :: nf_nowrite = 0 - integer, parameter, public :: nf_noerr = 0 - integer, parameter, public :: nf_max_name = 64 - -contains - -!----------------------------------------------------------------------- - subroutine ncd_defvar(ncid, varname, xtype, & - dim1name, dim2name, & - long_name, units ) -! - implicit none - integer , intent(in) :: ncid ! input unit - character(len=*), intent(in) :: varname ! variable name - integer , intent(in) :: xtype ! external type - character(len=*), intent(in), optional :: dim1name ! dimension name - character(len=*), intent(in), optional :: dim2name ! dimension name - character(len=*), intent(in), optional :: long_name ! attribute - character(len=*), intent(in), optional :: units ! attribute -! - end subroutine ncd_defvar - - !----------------------------------------------------------------------- - subroutine ncd_def_spatial_var(ncid, varname, xtype, long_name, units, lev1name, lev2name) - integer , intent(in) :: ncid ! input unit - character(len=*) , intent(in) :: varname ! variable name - integer , intent(in) :: xtype ! external type - character(len=*) , intent(in) :: long_name ! attribute - character(len=*) , intent(in) :: units ! attribute - character(len=*) , optional, intent(in) :: lev1name ! name of first level (or time) dimension - character(len=*) , optional, intent(in) :: lev2name ! name of second level (or time) dimension - end subroutine ncd_def_spatial_var - - subroutine get_dim_lengths(ncid, varname, ndims, dim_lengths) - integer , intent(in) :: ncid ! netcdf id of an open netcdf file - character(len=*), intent(in) :: varname ! name of variable of interest - integer , intent(out):: ndims ! number of dimensions of variable - integer , intent(out):: dim_lengths(:) ! lengths of dimensions of variable - - dim_lengths = 0 - end subroutine get_dim_lengths - - integer function nf_open(filename, mode, ncid) - character(len=*), intent(in) :: filename - integer, intent(in) :: mode - integer, intent(out) :: ncid - - ncid = 0 - nf_open = 0 - end function nf_open - - integer function nf_close(ncid) - integer, intent(in) :: ncid - - nf_close = 0 - end function nf_close - - function nf_strerror(rcode) - character(len=16) :: nf_strerror - integer, intent(in) :: rcode - - nf_strerror = 'N/A' - end function nf_strerror - - integer function nf_inq_dimid(ncid, dimname, did) - integer, intent(in) :: ncid - character(len=*), intent(in) :: dimname - integer, intent(out) :: did - - did = 0 - nf_inq_dimid = 0 - end function nf_inq_dimid - - integer function nf_inq_dimname(ncid, dimid, dimname) - integer, intent(in) :: ncid - integer, intent(in) :: dimid - character(len=*), intent(out) :: dimname - - dimname = 'none' - nf_inq_dimname = 0 - end function nf_inq_dimname - - integer function nf_inq_dimlen(ncid, did, dimlen) - integer, intent(in) :: ncid - integer, intent(in) :: did - integer, intent(out) :: dimlen - - dimlen = 0 - nf_inq_dimlen = 0 - end function nf_inq_dimlen - - integer function nf_inq_varid(ncid, varname, vid) - integer, intent(in) :: ncid - character(len=*), intent(in) :: varname - integer, intent(out) :: vid - - vid = 0 - nf_inq_varid = 0 - end function nf_inq_varid - - integer function nf_inq_varndims(ncid, varid, ndims) - integer, intent(in) :: ncid - integer, intent(in) :: varid - integer, intent(out) :: ndims - - ndims = 0 - nf_inq_varndims = 0 - end function nf_inq_varndims - - integer function nf_inq_vardimid(ncid, varid, dimids) - integer, intent(in) :: ncid - integer, intent(in) :: varid - integer, intent(out) :: dimids(:) - - dimids(:) = 0 - nf_inq_vardimid = 0 - end function nf_inq_vardimid - - integer function nf_get_var_double_1d(ncid, vid, data) - integer, intent(in) :: ncid - integer, intent(in) :: vid - real(r8), intent(out) :: data(:) - - data(:) = 0._r8 - nf_get_var_double_1d = 0 - end function nf_get_var_double_1d - - integer function nf_get_var_double_2d(ncid, vid, data) - integer, intent(in) :: ncid - integer, intent(in) :: vid - real(r8), intent(out) :: data(:,:) - - data(:,:) = 0._r8 - nf_get_var_double_2d = 0 - end function nf_get_var_double_2d - - integer function nf_get_var_int(ncid, vid, data) - integer, intent(in) :: ncid - integer, intent(in) :: vid - integer, intent(out) :: data(:) - - data(:) = 0 - nf_get_var_int = 0 - end function nf_get_var_int - - integer function nf_get_vara_double_2d(ncid, varid, starts, counts, data) - integer, intent(in) :: ncid - integer, intent(in) :: varid - integer, intent(in) :: starts(:) - integer, intent(in) :: counts(:) - real(r8), intent(out) :: data(:,:) - - data(:,:) = 0._r8 - nf_get_vara_double_2d = 0 - end function nf_get_vara_double_2d - - integer function nf_get_att_double(ncid, varid, attname, attval) - integer, intent(in) :: ncid - integer, intent(in) :: varid - character(len=*), intent(in) :: attname - real(r8), intent(out) :: attval - - attval = 0._r8 - nf_get_att_double = 0 - end function nf_get_att_double - - subroutine check_ret(ret, calling, varexists) - integer, intent(in) :: ret - character(len=*), intent(in) :: calling - logical, intent(out), optional :: varexists - - if (present(varexists)) then - varexists = .true. - end if - end subroutine check_ret - - subroutine convert_latlon(ncid, varname, data) - integer, intent(in) :: ncid - character(len=*), intent(in) :: varname - real(r8), intent(inout) :: data(:) - - end subroutine convert_latlon - -end module mkncdio diff --git a/tools/mksurfdata_map/unit_testers/Filepath b/tools/mksurfdata_map/unit_testers/Filepath deleted file mode 100644 index f5228276ec..0000000000 --- a/tools/mksurfdata_map/unit_testers/Filepath +++ /dev/null @@ -1,2 +0,0 @@ -. -../src diff --git a/tools/mksurfdata_map/unit_testers/Makefile b/tools/mksurfdata_map/unit_testers/Makefile deleted file mode 100644 index 7260c828d8..0000000000 --- a/tools/mksurfdata_map/unit_testers/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# Makefile for mksurfdata_map unit testing - -EXENAME = ../test_mksurfdata_map - -# Set optimization off by default -ifeq ($(OPT),$(null)) - OPT := FALSE -endif - -include ../src/Makefile.common \ No newline at end of file diff --git a/tools/mksurfdata_map/unit_testers/README b/tools/mksurfdata_map/unit_testers/README deleted file mode 100644 index 8620c3cc6d..0000000000 --- a/tools/mksurfdata_map/unit_testers/README +++ /dev/null @@ -1,6 +0,0 @@ -This directory contains source code for building unit tests for -mksurfdata_map - -test_mod.F90 was copied from -https://svn-ccsm-models.cgd.ucar.edu/csm_share/trunk/unit_testers/test_mod.F90 - diff --git a/tools/mksurfdata_map/unit_testers/Srcfiles b/tools/mksurfdata_map/unit_testers/Srcfiles deleted file mode 100644 index 3ee42a79bb..0000000000 --- a/tools/mksurfdata_map/unit_testers/Srcfiles +++ /dev/null @@ -1,32 +0,0 @@ -test_mksurfdata_map.F90 -test_mkdomainMod.F90 -test_mkindexmapMod.F90 -test_mkgridmapMod.F90 -test_mkchecksMod.F90 -test_mkurbanparMod.F90 -test_mkutilsMod.F90 -test_mkharvest.F90 -test_mkncdio.F90 -test_mod.F90 -mkindexmapMod.F90 -mkchecksMod.F90 -mkharvestMod.F90 -mkurbanparMod.F90 -mkdiagnosticsMod.F90 -mkurbanparCommonMod.F90 -mkutilsMod.F90 -mkdomainMod.F90 -mkvarpar.F90 -mkgridmapMod.F90 -mkncdio.F90 -mkvarctl.F90 -nanMod.F90 -fileutils.F90 -shr_const_mod.F90 -shr_kind_mod.F90 -shr_sys_mod.F90 -shr_log_mod.F90 -shr_string_mod.F90 -shr_timer_mod.F90 -shr_file_mod.F90 - diff --git a/tools/mksurfdata_map/unit_testers/test_mkchecksMod.F90 b/tools/mksurfdata_map/unit_testers/test_mkchecksMod.F90 deleted file mode 100644 index edec7643e5..0000000000 --- a/tools/mksurfdata_map/unit_testers/test_mkchecksMod.F90 +++ /dev/null @@ -1,101 +0,0 @@ -module test_mkchecksMod -! Module for testing mkchecksMod - - use mkchecksMod - use test_mod - use shr_kind_mod, only : r8 => shr_kind_r8 - - implicit none - private - - public :: test_min_bad - public :: test_max_bad - - character(len=*), parameter :: modname = 'test_mkchecksMod' - -contains - -!------------------------------------------------------------------------------ - subroutine test_min_bad - - implicit none - - character(len=128) :: testname - logical :: test_result - - character(len=*), parameter :: subname = 'test_min_bad' - - ! Tests for r8 - - testname = 'r8 - pass' - test_result = min_bad((/1._r8,2._r8,3._r8/), 0._r8, 'testvar') - call test_is(test_result .eqv. .false., modname//' -- '//subname//' -- '//trim(testname)) - - testname = 'r8 - pass on border' - test_result = min_bad((/1._r8,2._r8,3._r8/), 1._r8, 'testvar') - call test_is(test_result .eqv. .false., modname//' -- '//subname//' -- '//trim(testname)) - - ! Note that we expect output to stdout from the following test that indicates an error - testname = 'r8 - fail' - test_result = min_bad((/1._r8,2._r8,3._r8/), 1.5_r8, 'testvar') - call test_is(test_result .eqv. .true., modname//' -- '//subname//' -- '//trim(testname)) - - ! Tests for int - - testname = 'int - pass' - test_result = min_bad((/1,2,3/), 0, 'testvar') - call test_is(test_result .eqv. .false., modname//' -- '//subname//' -- '//trim(testname)) - - testname = 'int - pass on border' - test_result = min_bad((/1,2,3/), 1, 'testvar') - call test_is(test_result .eqv. .false., modname//' -- '//subname//' -- '//trim(testname)) - - ! Note that we expect output to stdout from the following test that indicates an error - testname = 'int - fail' - test_result = min_bad((/1,2,3/), 2, 'testvar') - call test_is(test_result .eqv. .true., modname//' -- '//subname//' -- '//trim(testname)) - - end subroutine test_min_bad - -!------------------------------------------------------------------------------ - subroutine test_max_bad - - implicit none - - character(len=128) :: testname - logical :: test_result - - character(len=*), parameter :: subname = 'test_max_bad' - - ! Tests for r8 - - testname = 'r8 - pass' - test_result = max_bad((/1._r8,2._r8,3._r8/), 4._r8, 'testvar') - call test_is(test_result .eqv. .false., modname//' -- '//subname//' -- '//trim(testname)) - - testname = 'r8 - pass on border' - test_result = max_bad((/1._r8,2._r8,3._r8/), 3._r8, 'testvar') - call test_is(test_result .eqv. .false., modname//' -- '//subname//' -- '//trim(testname)) - - ! Note that we expect output to stdout from the following test that indicates an error - testname = 'r8 - fail' - test_result = max_bad((/1._r8,2._r8,3._r8/), 2.5_r8, 'testvar') - call test_is(test_result .eqv. .true., modname//' -- '//subname//' -- '//trim(testname)) - - ! Tests for int - - testname = 'int - pass' - test_result = max_bad((/1,2,3/), 4, 'testvar') - call test_is(test_result .eqv. .false., modname//' -- '//subname//' -- '//trim(testname)) - - testname = 'int - pass on border' - test_result = max_bad((/1,2,3/), 3, 'testvar') - call test_is(test_result .eqv. .false., modname//' -- '//subname//' -- '//trim(testname)) - - ! Note that we expect output to stdout from the following test that indicates an error - testname = 'int - fail' - test_result = max_bad((/1,2,3/), 2, 'testvar') - call test_is(test_result .eqv. .true., modname//' -- '//subname//' -- '//trim(testname)) - - end subroutine test_max_bad -end module test_mkchecksMod diff --git a/tools/mksurfdata_map/unit_testers/test_mkdomainMod.F90 b/tools/mksurfdata_map/unit_testers/test_mkdomainMod.F90 deleted file mode 100644 index 56a37e7f28..0000000000 --- a/tools/mksurfdata_map/unit_testers/test_mkdomainMod.F90 +++ /dev/null @@ -1,95 +0,0 @@ -module test_mkdomainMod -! Module for testing mkindexmapMod - - use mkdomainMod - use test_mod - use shr_kind_mod, only : r8 => shr_kind_r8 - - implicit none - private - - public :: test_domain_read_dims - - character(len=*), parameter :: modname = 'test_mkdomainMod' - -contains - -!------------------------------------------------------------------------------ - subroutine test_domain_read_dims - - use mkncdio - - implicit none - - type(domain_type) :: domain - integer :: ncid - character(len=128) :: testname - - integer :: ni_t, nj_t, ns_t - logical :: is_2d_t - - character(len=*), parameter :: subname = 'test_domain_read_dims' - - testname = 'lon' - call check_ret(nf_open('unit_testers/inputs/test_domain_read_dims__lon.nc', 0, ncid), subname) - ni_t = 2 - nj_t = 3 - ns_t = 6 - is_2d_t = .true. - call domain_read_dims(domain, ncid) - call check_results_2d - - testname = 'lsmlon' - call check_ret(nf_open('unit_testers/inputs/test_domain_read_dims__lsmlon.nc', 0, ncid), subname) - ni_t = 3 - nj_t = 4 - ns_t = 12 - is_2d_t = .true. - call domain_read_dims(domain, ncid) - call check_results_2d - - ! When we have both 'lon' and 'ni', should use 'ni' - testname = 'lon_and_ni' - call check_ret(nf_open('unit_testers/inputs/test_domain_read_dims__lon_and_ni.nc', 0, ncid), subname) - ni_t = 4 - nj_t = 5 - ns_t = 20 - is_2d_t = .true. - call domain_read_dims(domain, ncid) - call check_results_2d - - ! test 1-d - testname = 'num_pixels' - call check_ret(nf_open('unit_testers/inputs/test_domain_read_dims__num_pixels.nc', 0, ncid), subname) - ns_t = 17 - is_2d_t = .false. - call domain_read_dims(domain, ncid) - call check_results_1d - - ! When we have both 2-d and 1-d info, should use 2-d info - testname = 'lon_and_num_pixels' - call check_ret(nf_open('unit_testers/inputs/test_domain_read_dims__lon_and_num_pixels.nc', 0, ncid), subname) - ni_t = 2 - nj_t = 3 - ns_t = 6 - is_2d_t = .true. - call domain_read_dims(domain, ncid) - call check_results_2d - - contains - subroutine check_results_1d - call test_is(domain%ns, ns_t, modname//' -- '//subname//' -- '//trim(testname)//' -- ns') - call test_is((domain%is_2d .eqv. is_2d_t), modname//' -- '//subname//' -- '//trim(testname)//' -- is_2d') - end subroutine check_results_1d - - subroutine check_results_2d - call test_is(domain%ns, ns_t, modname//' -- '//subname//' -- '//trim(testname)//' -- ns') - call test_is(domain%ni, ni_t, modname//' -- '//subname//' -- '//trim(testname)//' -- ni') - call test_is(domain%nj, nj_t, modname//' -- '//subname//' -- '//trim(testname)//' -- nj') - call test_is((domain%is_2d .eqv. is_2d_t), modname//' -- '//subname//' -- '//trim(testname)//' -- is_2d') - end subroutine check_results_2d - end subroutine test_domain_read_dims -end module test_mkdomainMod - - - diff --git a/tools/mksurfdata_map/unit_testers/test_mkgridmapMod.F90 b/tools/mksurfdata_map/unit_testers/test_mkgridmapMod.F90 deleted file mode 100644 index 77fb3ffd9a..0000000000 --- a/tools/mksurfdata_map/unit_testers/test_mkgridmapMod.F90 +++ /dev/null @@ -1,476 +0,0 @@ -module test_mkgridmapMod - ! Module for testing mkgridmapMod - - use mkgridmapMod - use test_mod - use shr_kind_mod, only : r8 => shr_kind_r8 - - implicit none - private - - public :: test_gridmap_areastddev - public :: test_gridmap_areaave_no_srcmask - public :: test_gridmap_areaave_srcmask - - character(len=*), parameter :: modname = 'test_mkgridmapMod' - -contains - - !------------------------------------------------------------------------------ - subroutine test_gridmap_areaave_no_srcmask - - implicit none - - type(gridmap_type) :: gridmap - character(len=128) :: testname - - real(r8), allocatable :: src_array(:) - real(r8), allocatable :: dst_array(:) - real(r8), allocatable :: dst_array_t(:) - - real(r8), parameter :: nodata = -1._r8 - real(r8), parameter :: eps = 1.e-13_r8 - - character(len=*), parameter :: subname = 'test_gridmap_areaave_no_srcmask' - - ! Note about the gridmaps for the tests here: - ! For most tests here, the test arrays are: (1) simple case, (2) the main case to - ! test, (3) simple case. Thus, the main case in question is #2 of 3, and we're always - ! basically just testing one scenario in each call to the subroutine (rather than - ! doing a bunch of tests at once, which could make setting up the test arrays more - ! error-prone). - - ! Set up a gridmap with 0 weight of overlap on dest #2 - gridmap%na = 4 - gridmap%nb = 3 - gridmap%ns = 4 - allocate(gridmap%src_indx(gridmap%ns), & - gridmap%dst_indx(gridmap%ns), & - gridmap%wovr (gridmap%ns), & - gridmap%frac_dst(gridmap%nb)) - gridmap%src_indx = (/1,2,3,4/) - gridmap%dst_indx = (/1,1,3,3/) - gridmap%wovr = (/0.75_r8,0.25_r8, & ! weights of sources 1:2 on dest 1 - 0.25_r8,0.75_r8/) ! weights of sources 3:4 on test 3 - gridmap%frac_dst = (/1.0, 0.0, 1.0/) - gridmap%set = 'gridmap_IsSet' - allocate(src_array (gridmap%na), & - dst_array (gridmap%nb), & - dst_array_t(gridmap%nb)) - testname = 'no overlap' - src_array = (/0.1_r8,0.2_r8,0.3_r8,0.4_r8/) - dst_array_t = (/0.125_r8, nodata, 0.375_r8/) - call gridmap_areaave_no_srcmask(gridmap, src_array, dst_array, nodata) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - deallocate(gridmap%src_indx, gridmap%dst_indx, gridmap%wovr, gridmap%frac_dst) - deallocate(src_array, dst_array, dst_array_t) - - ! Set up a gridmap with a single point overlapping dest #2 - gridmap%na = 5 - gridmap%nb = 3 - gridmap%ns = 5 - allocate(gridmap%src_indx(gridmap%ns), & - gridmap%dst_indx(gridmap%ns), & - gridmap%wovr (gridmap%ns), & - gridmap%frac_dst(gridmap%nb)) - gridmap%src_indx = (/1,2,3,4,5/) - gridmap%dst_indx = (/1,1,2,3,3/) - gridmap%wovr = (/0.75_r8,0.25_r8, & ! weights of sources 1:2 on dest 1 - 1.0_r8, & ! weight of source 3 on dest 2 - 0.25_r8,0.75_r8/) ! weights of sources 4:5 on test 3 - gridmap%frac_dst = (/1.0, 1.0, 1.0/) - gridmap%set = 'gridmap_IsSet' - allocate(src_array (gridmap%na), & - dst_array (gridmap%nb), & - dst_array_t(gridmap%nb)) - testname = 'single overlap' - src_array = (/0.1_r8,0.2_r8,0.5_r8,0.3_r8,0.4_r8/) - dst_array_t = (/0.125_r8, 0.5_r8, 0.375_r8/) - call gridmap_areaave_no_srcmask(gridmap, src_array, dst_array, nodata) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - - ! Now change the overlap point to have weight=0 - testname = 'single overlap with 0 weight' - gridmap%wovr(3) = 0.0_r8 - gridmap%frac_dst(2) = 0.0_r8 - dst_array_t(2) = nodata - call gridmap_areaave_no_srcmask(gridmap, src_array, dst_array, nodata) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - - deallocate(gridmap%src_indx, gridmap%dst_indx, gridmap%wovr, gridmap%frac_dst) - deallocate(src_array, dst_array, dst_array_t) - - ! Set up a gridmap for the remaining tests - ! This gridmap will have 3 src cells, 9 dest cells, and: - ! src 1: just overlaps with dst 1 - ! src 2: overlaps with dst 1 & dst 2 - ! src 3..7: just overlaps with dst 2 - ! src 8: overlaps with dst 2 & dst 3 - ! src 9: just overlaps with dst 3 - gridmap%na = 9 - gridmap%nb = 3 - gridmap%ns = 11 - allocate(gridmap%src_indx(gridmap%ns), & - gridmap%dst_indx(gridmap%ns), & - gridmap%wovr (gridmap%ns), & - gridmap%frac_dst(gridmap%nb)) - gridmap%src_indx = (/1,2,2,3,4,5,6,7,8,8,9/) - gridmap%dst_indx = (/1,1,2,2,2,2,2,2,2,3,3/) - gridmap%wovr = (/0.75_r8,0.25_r8, & ! weights of sources 1:2 on dest 1 - 0.05_r8,0.05_r8,0.1_r8,0.3_r8,0.2_r8,0.15_r8,0.15_r8, & ! weights of sources 2:8 on dest 2 - 0.25_r8,0.75_r8/) ! weights of sources 8:9 on test 3 - gridmap%frac_dst = (/1.0_r8, 1.0_r8, 1.0_r8/) - gridmap%set = 'gridmap_IsSet' - allocate(src_array (gridmap%na), & - dst_array (gridmap%nb), & - dst_array_t(gridmap%nb)) - - - testname='multiple overlaps, all the same value' - src_array = (/0.1_r8, 0.5_r8, 0.5_r8, 0.5_r8, 0.5_r8, 0.5_r8, 0.5_r8, 0.5_r8, 0.6_r8/) - dst_array_t = (/0.2_r8, 0.5_r8, 0.575_r8/) - call gridmap_areaave_no_srcmask(gridmap, src_array, dst_array, nodata) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - - testname='multiple overlaps, different values' - src_array = (/0.1_r8, 0.2_r8, 0.3_r8, 0.7_r8, 0.5_r8, 1.5_r8, 0.5_r8, 1.7_r8, 1.8_r8/) - dst_array_t = (/0.125_r8, 0.875_r8, 1.775_r8/) - call gridmap_areaave_no_srcmask(gridmap, src_array, dst_array, nodata) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - - ! dividing the weights by 2 shouldn't affect the mean - testname='weights divided by 2' - gridmap%wovr(:) = gridmap%wovr(:) / 2.0_r8 - gridmap%frac_dst(:) = gridmap%frac_dst(:) / 2.0_r8 - src_array = (/0.1_r8, 0.2_r8, 0.3_r8, 0.7_r8, 0.5_r8, 1.5_r8, 0.5_r8, 1.7_r8, 1.8_r8/) - dst_array_t = (/0.125_r8, 0.875_r8, 1.775_r8/) - call gridmap_areaave_no_srcmask(gridmap, src_array, dst_array, nodata) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - ! restore wovr & frac_dst - gridmap%wovr(:) = gridmap%wovr(:) * 2.0_r8 - gridmap%frac_dst(:) = gridmap%frac_dst(:) * 2.0_r8 - - ! using frac_dst > 1 should be okay - testname='frac_dst > 1' - gridmap%wovr(:) = gridmap%wovr(:) * 2.0_r8 - gridmap%frac_dst(:) = gridmap%frac_dst(:) * 2.0_r8 - src_array = (/0.1_r8, 0.2_r8, 0.3_r8, 0.7_r8, 0.5_r8, 1.5_r8, 0.5_r8, 1.7_r8, 1.8_r8/) - dst_array_t = (/0.125_r8, 0.875_r8, 1.775_r8/) - call gridmap_areaave_no_srcmask(gridmap, src_array, dst_array, nodata) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - ! restore wovr & frac_dst - gridmap%wovr(:) = gridmap%wovr(:) / 2.0_r8 - gridmap%frac_dst(:) = gridmap%frac_dst(:) / 2.0_r8 - - deallocate(src_array, dst_array, dst_array_t) - - end subroutine test_gridmap_areaave_no_srcmask - - !------------------------------------------------------------------------------ - subroutine test_gridmap_areaave_srcmask - - implicit none - - type(gridmap_type) :: gridmap - character(len=128) :: testname - - real(r8), allocatable :: src_array(:) - integer , allocatable :: mask_src(:) - real(r8), allocatable :: dst_array(:) - real(r8), allocatable :: dst_array_t(:) - - real(r8), parameter :: nodata = -1._r8 - real(r8), parameter :: eps = 1.e-13_r8 - - character(len=*), parameter :: subname = 'test_gridmap_areaave_srcmask' - - ! Note about the gridmaps for the tests here: - ! For most tests here, the test arrays are: (1) simple case, (2) the main case to - ! test, (3) simple case. Thus, the main case in question is #2 of 3, and we're always - ! basically just testing one scenario in each call to the subroutine (rather than - ! doing a bunch of tests at once, which could make setting up the test arrays more - ! error-prone). - - ! Set up a gridmap with 0 weight of overlap on dest #2 - gridmap%na = 4 - gridmap%nb = 3 - gridmap%ns = 4 - allocate(gridmap%src_indx(gridmap%ns), & - gridmap%dst_indx(gridmap%ns), & - gridmap%wovr (gridmap%ns), & - gridmap%frac_dst(gridmap%nb)) - gridmap%src_indx = (/1,2,3,4/) - gridmap%dst_indx = (/1,1,3,3/) - gridmap%wovr = (/0.75_r8,0.25_r8, & ! weights of sources 1:2 on dest 1 - 0.25_r8,0.75_r8/) ! weights of sources 3:4 on test 3 - gridmap%frac_dst = (/1.0, 0.0, 1.0/) - gridmap%set = 'gridmap_IsSet' - allocate(src_array (gridmap%na), & - mask_src (gridmap%na), & - dst_array (gridmap%nb), & - dst_array_t(gridmap%nb)) - testname = 'no overlap' - src_array = (/0.1_r8,0.2_r8,0.3_r8,0.4_r8/) - mask_src(:) = 1 - dst_array_t = (/0.125_r8, nodata, 0.375_r8/) - call gridmap_areaave_srcmask(gridmap, src_array, dst_array, nodata, mask_src=mask_src, frac_dst=gridmap%frac_dst) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - deallocate(gridmap%src_indx, gridmap%dst_indx, gridmap%wovr, gridmap%frac_dst) - deallocate(src_array, mask_src, dst_array, dst_array_t) - - ! Set up a gridmap with a single point overlapping dest #2 - gridmap%na = 5 - gridmap%nb = 3 - gridmap%ns = 5 - allocate(gridmap%src_indx(gridmap%ns), & - gridmap%dst_indx(gridmap%ns), & - gridmap%wovr (gridmap%ns), & - gridmap%frac_dst(gridmap%nb)) - gridmap%src_indx = (/1,2,3,4,5/) - gridmap%dst_indx = (/1,1,2,3,3/) - gridmap%wovr = (/0.75_r8,0.25_r8, & ! weights of sources 1:2 on dest 1 - 1.0_r8, & ! weight of source 3 on dest 2 - 0.25_r8,0.75_r8/) ! weights of sources 4:5 on test 3 - gridmap%frac_dst = (/1.0, 1.0, 1.0/) - gridmap%set = 'gridmap_IsSet' - allocate(src_array (gridmap%na), & - mask_src (gridmap%na), & - dst_array (gridmap%nb), & - dst_array_t(gridmap%nb)) - testname = 'single overlap' - src_array = (/0.1_r8,0.2_r8,0.5_r8,0.3_r8,0.4_r8/) - mask_src(:) = 1.0_r8 - dst_array_t = (/0.125_r8, 0.5_r8, 0.375_r8/) - call gridmap_areaave_srcmask(gridmap, src_array, dst_array, nodata, mask_src=mask_src, frac_dst=gridmap%frac_dst) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - - ! Now change the overlap point to have src_mask=0 - testname = 'single overlap with 0 src_mask' - mask_src(3) = 0.0_r8 - dst_array_t(2) = nodata - call gridmap_areaave_srcmask(gridmap, src_array, dst_array, nodata, mask_src=mask_src, frac_dst=gridmap%frac_dst) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - - deallocate(gridmap%src_indx, gridmap%dst_indx, gridmap%wovr, gridmap%frac_dst) - deallocate(src_array, mask_src, dst_array, dst_array_t) - - ! Set up a gridmap for the remaining tests - ! This gridmap will have 3 src cells, 9 dest cells, and: - ! src 1: just overlaps with dst 1 - ! src 2: overlaps with dst 1 & dst 2 - ! src 3..7: just overlaps with dst 2 - ! src 8: overlaps with dst 2 & dst 3 - ! src 9: just overlaps with dst 3 - gridmap%na = 9 - gridmap%nb = 3 - gridmap%ns = 11 - allocate(gridmap%src_indx(gridmap%ns), & - gridmap%dst_indx(gridmap%ns), & - gridmap%wovr (gridmap%ns), & - gridmap%frac_dst(gridmap%nb)) - gridmap%src_indx = (/1,2,2,3,4,5,6,7,8,8,9/) - gridmap%dst_indx = (/1,1,2,2,2,2,2,2,2,3,3/) - gridmap%wovr = (/0.75_r8,0.25_r8, & ! weights of sources 1:2 on dest 1 - 0.05_r8,0.05_r8,0.1_r8,0.3_r8,0.2_r8,0.15_r8,0.15_r8, & ! weights of sources 2:8 on dest 2 - 0.25_r8,0.75_r8/) ! weights of sources 8:9 on test 3 - gridmap%frac_dst = (/1.0_r8, 1.0_r8, 1.0_r8/) - gridmap%set = 'gridmap_IsSet' - allocate(src_array (gridmap%na), & - mask_src (gridmap%na), & - dst_array (gridmap%nb), & - dst_array_t(gridmap%nb)) - - - testname='multiple overlaps, all the same value' - src_array = (/0.1_r8, 0.5_r8, 0.5_r8, 0.5_r8, 0.5_r8, 0.5_r8, 0.5_r8, 0.5_r8, 0.6_r8/) - mask_src(:) = 1.0_r8 - dst_array_t = (/0.2_r8, 0.5_r8, 0.575_r8/) - call gridmap_areaave_srcmask(gridmap, src_array, dst_array, nodata, mask_src=mask_src, frac_dst=gridmap%frac_dst) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - - testname='multiple overlaps, different values' - src_array = (/0.1_r8, 0.2_r8, 0.3_r8, 0.7_r8, 0.5_r8, 1.5_r8, 0.5_r8, 1.7_r8, 1.8_r8/) - mask_src(:) = 1.0_r8 - dst_array_t = (/0.125_r8, 0.875_r8, 1.775_r8/) - call gridmap_areaave_srcmask(gridmap, src_array, dst_array, nodata, mask_src=mask_src, frac_dst=gridmap%frac_dst) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - - testname='multiple overlaps, different values, srcmask' - src_array = (/0.1_r8, 0.2_r8, 0.3_r8, 0.7_r8, 0.5_r8, 1.5_r8, 0.5_r8, 1.7_r8, 1.8_r8/) - mask_src(:) = (/1.0_r8, 1.0_r8, 0.0_r8, 0.5_r8, 1.0_r8, 0.5_r8, 0.0_r8, 1.0_r8, 1.0_r8/) - dst_array_t = (/0.125_r8, 0.923076923076923_r8, 1.775_r8/) - call gridmap_areaave_srcmask(gridmap, src_array, dst_array, nodata, mask_src=mask_src, frac_dst=gridmap%frac_dst) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - - ! dividing the weights by 2 and dividing mask_src by a constant shouldn't affect the mean - testname='weights divided by 2' - gridmap%wovr(:) = gridmap%wovr(:) / 2.0_r8 - gridmap%frac_dst(:) = gridmap%frac_dst(:) / 2.0_r8 - src_array = (/0.1_r8, 0.2_r8, 0.3_r8, 0.7_r8, 0.5_r8, 1.5_r8, 0.5_r8, 1.7_r8, 1.8_r8/) - mask_src(:) = 0.25_r8 - dst_array_t = (/0.125_r8, 0.875_r8, 1.775_r8/) - call gridmap_areaave_srcmask(gridmap, src_array, dst_array, nodata, mask_src=mask_src, frac_dst=gridmap%frac_dst) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - ! restore wovr & frac_dst - gridmap%wovr(:) = gridmap%wovr(:) * 2.0_r8 - gridmap%frac_dst(:) = gridmap%frac_dst(:) * 2.0_r8 - - ! using frac_dst > 1 should be okay - testname='frac_dst > 1' - gridmap%wovr(:) = gridmap%wovr(:) * 2.0_r8 - gridmap%frac_dst(:) = gridmap%frac_dst(:) * 2.0_r8 - src_array = (/0.1_r8, 0.2_r8, 0.3_r8, 0.7_r8, 0.5_r8, 1.5_r8, 0.5_r8, 1.7_r8, 1.8_r8/) - mask_src(:) = 0.25_r8 - dst_array_t = (/0.125_r8, 0.875_r8, 1.775_r8/) - call gridmap_areaave_srcmask(gridmap, src_array, dst_array, nodata, mask_src=mask_src, frac_dst=gridmap%frac_dst) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - ! restore wovr & frac_dst - gridmap%wovr(:) = gridmap%wovr(:) / 2.0_r8 - gridmap%frac_dst(:) = gridmap%frac_dst(:) / 2.0_r8 - - - deallocate(src_array, mask_src, dst_array, dst_array_t) - - end subroutine test_gridmap_areaave_srcmask - - !------------------------------------------------------------------------------ - subroutine test_gridmap_areastddev - - implicit none - - type(gridmap_type) :: gridmap - character(len=128) :: testname - - real(r8), allocatable :: src_array(:) - real(r8), allocatable :: dst_array(:) - real(r8), allocatable :: dst_array_t(:) - - real(r8), parameter :: nodata = -1._r8 - real(r8), parameter :: eps = 1.e-13_r8 - - character(len=*), parameter :: subname = 'test_gridmap_areastddev' - - ! Note about the gridmaps for the tests here: - ! For most tests here, the test arrays are: (1) simple case, (2) the main case to - ! test, (3) simple case. Thus, the main case in question is #2 of 3, and we're always - ! basically just testing one scenario in each call to the subroutine (rather than - ! doing a bunch of tests at once, which could make setting up the test arrays more - ! error-prone). - - ! Set up a gridmap with 0 weight of overlap on dest #2 - gridmap%na = 4 - gridmap%nb = 3 - gridmap%ns = 4 - allocate(gridmap%src_indx(gridmap%ns), & - gridmap%dst_indx(gridmap%ns), & - gridmap%wovr (gridmap%ns), & - gridmap%frac_dst(gridmap%nb)) - gridmap%src_indx = (/1,2,3,4/) - gridmap%dst_indx = (/1,1,3,3/) - gridmap%wovr = (/0.75_r8,0.25_r8, & ! weights of sources 1:2 on dest 1 - 0.25_r8,0.75_r8/) ! weights of sources 3:4 on test 3 - gridmap%frac_dst = (/1.0, 0.0, 1.0/) - gridmap%set = 'gridmap_IsSet' - allocate(src_array (gridmap%na), & - dst_array (gridmap%nb), & - dst_array_t(gridmap%nb)) - testname = 'no overlap' - src_array = (/0.1_r8,0.2_r8,0.3_r8,0.4_r8/) - dst_array_t = (/0.04330127018922193_r8, nodata, 0.04330127018922195_r8/) - call gridmap_areastddev(gridmap, src_array, dst_array, nodata) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - deallocate(gridmap%src_indx, gridmap%dst_indx, gridmap%wovr, gridmap%frac_dst) - deallocate(src_array, dst_array, dst_array_t) - - ! Set up a gridmap with a single point overlapping dest #2 - gridmap%na = 5 - gridmap%nb = 3 - gridmap%ns = 5 - allocate(gridmap%src_indx(gridmap%ns), & - gridmap%dst_indx(gridmap%ns), & - gridmap%wovr (gridmap%ns), & - gridmap%frac_dst(gridmap%nb)) - gridmap%src_indx = (/1,2,3,4,5/) - gridmap%dst_indx = (/1,1,2,3,3/) - gridmap%wovr = (/0.75_r8,0.25_r8, & ! weights of sources 1:2 on dest 1 - 1.0_r8, & ! weight of source 3 on dest 2 - 0.25_r8,0.75_r8/) ! weights of sources 4:5 on test 3 - gridmap%frac_dst = (/1.0, 1.0, 1.0/) - gridmap%set = 'gridmap_IsSet' - allocate(src_array (gridmap%na), & - dst_array (gridmap%nb), & - dst_array_t(gridmap%nb)) - testname = 'single overlap' - src_array = (/0.1_r8,0.2_r8,0.5_r8,0.3_r8,0.4_r8/) - dst_array_t = (/0.04330127018922193_r8, 0.0_r8, 0.04330127018922195_r8/) - call gridmap_areastddev(gridmap, src_array, dst_array, nodata) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - deallocate(gridmap%src_indx, gridmap%dst_indx, gridmap%wovr, gridmap%frac_dst) - deallocate(src_array, dst_array, dst_array_t) - - ! Set up a gridmap for the remaining tests - ! This gridmap will have 3 src cells, 9 dest cells, and: - ! src 1: just overlaps with dst 1 - ! src 2: overlaps with dst 1 & dst 2 - ! src 3..7: just overlaps with dst 2 - ! src 8: overlaps with dst 2 & dst 3 - ! src 9: just overlaps with dst 3 - gridmap%na = 9 - gridmap%nb = 3 - gridmap%ns = 11 - allocate(gridmap%src_indx(gridmap%ns), & - gridmap%dst_indx(gridmap%ns), & - gridmap%wovr (gridmap%ns), & - gridmap%frac_dst(gridmap%nb)) - gridmap%src_indx = (/1,2,2,3,4,5,6,7,8,8,9/) - gridmap%dst_indx = (/1,1,2,2,2,2,2,2,2,3,3/) - gridmap%wovr = (/0.75_r8,0.25_r8, & ! weights of sources 1:2 on dest 1 - 0.05_r8,0.05_r8,0.1_r8,0.3_r8,0.2_r8,0.15_r8,0.15_r8, & ! weights of sources 2:8 on dest 2 - 0.25_r8,0.75_r8/) ! weights of sources 8:9 on test 3 - gridmap%frac_dst = (/1.0_r8, 1.0_r8, 1.0_r8/) - gridmap%set = 'gridmap_IsSet' - allocate(src_array (gridmap%na), & - dst_array (gridmap%nb), & - dst_array_t(gridmap%nb)) - - - testname='multiple overlaps, all the same value' - src_array = (/0.1_r8, 0.5_r8, 0.5_r8, 0.5_r8, 0.5_r8, 0.5_r8, 0.5_r8, 0.5_r8, 0.6_r8/) - dst_array_t = (/0.1732050807568877_r8, 0.0_r8, 0.04330127018922193_r8/) - call gridmap_areastddev(gridmap, src_array, dst_array, nodata) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - - testname='multiple overlaps, different values' - src_array = (/0.1_r8, 0.2_r8, 0.3_r8, 0.7_r8, 0.5_r8, 1.5_r8, 0.5_r8, 1.7_r8, 1.8_r8/) - dst_array_t = (/0.04330127018922193_r8, 0.5346727971385864_r8, 0.04330127018922197_r8/) - call gridmap_areastddev(gridmap, src_array, dst_array, nodata) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - - ! dividing the weights by 2 shouldn't affect the standard deviation - testname='weights divided by 2' - gridmap%wovr(:) = gridmap%wovr(:) / 2.0_r8 - gridmap%frac_dst(:) = gridmap%frac_dst(:) / 2.0_r8 - src_array = (/0.1_r8, 0.2_r8, 0.3_r8, 0.7_r8, 0.5_r8, 1.5_r8, 0.5_r8, 1.7_r8, 1.8_r8/) - dst_array_t = (/0.04330127018922193_r8, 0.5346727971385864_r8, 0.04330127018922197_r8/) - call gridmap_areastddev(gridmap, src_array, dst_array, nodata) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - ! restore wovr & frac_dst - gridmap%wovr(:) = gridmap%wovr(:) * 2.0_r8 - gridmap%frac_dst(:) = gridmap%frac_dst(:) * 2.0_r8 - - ! using frac_dst > 1 should be okay - testname='frac_dst > 1' - gridmap%wovr(:) = gridmap%wovr(:) * 2.0_r8 - gridmap%frac_dst(:) = gridmap%frac_dst(:) * 2.0_r8 - src_array = (/0.1_r8, 0.2_r8, 0.3_r8, 0.7_r8, 0.5_r8, 1.5_r8, 0.5_r8, 1.7_r8, 1.8_r8/) - dst_array_t = (/0.04330127018922193_r8, 0.5346727971385864_r8, 0.04330127018922197_r8/) - call gridmap_areastddev(gridmap, src_array, dst_array, nodata) - call test_close(dst_array, dst_array_t, eps, modname//' -- '//subname//' -- '//trim(testname)) - ! restore wovr & frac_dst - gridmap%wovr(:) = gridmap%wovr(:) / 2.0_r8 - gridmap%frac_dst(:) = gridmap%frac_dst(:) / 2.0_r8 - - deallocate(src_array, dst_array, dst_array_t) - - end subroutine test_gridmap_areastddev -end module test_mkgridmapMod diff --git a/tools/mksurfdata_map/unit_testers/test_mkharvest.F90 b/tools/mksurfdata_map/unit_testers/test_mkharvest.F90 deleted file mode 100644 index 421af9d620..0000000000 --- a/tools/mksurfdata_map/unit_testers/test_mkharvest.F90 +++ /dev/null @@ -1,316 +0,0 @@ -module test_mkharvest -! Module for testing harvest - - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkharvestMod - use test_mod - - implicit none - private - - public :: test_harvest_init - public :: test_harvest_init_old - public :: test_harvest_data - public :: test_harvest_data_all1D - - character(len=*), parameter :: modname = 'test_harvest' - - character(len=128) :: testname - character(len=128) :: test_prefix - integer, parameter :: ns_o = 4 - -contains - -!------------------------------------------------------------------------------ - subroutine test_harvest_init - - use mkncdio - implicit none - - integer :: ncid - type(harvestDataType) :: harvdata - character(len=128) :: varname - integer :: varid - logical :: varexists - integer :: ifld - character(len=*), parameter :: constfieldname(9) = (/ & - 'CONST_HARVEST_VH1 ', & - 'CONST_HARVEST_VH2 ', & - 'CONST_HARVEST_SH1 ', & - 'CONST_HARVEST_SH2 ', & - 'CONST_HARVEST_SH3 ', & - 'CONST_GRAZING ', & - 'CONST_FERTNITRO_CFT ', & - 'UNREPRESENTED_PFT_LULCC', & - 'UNREPRESENTED_CFT_LULCC' & - /) - character(len=*), parameter :: units(9) = (/ & - 'gC/m2/yr', & - 'gC/m2/yr', & - 'gC/m2/yr', & - 'gC/m2/yr', & - 'gC/m2/yr', & - 'gC/m2/yr', & - 'gN/m2/yr', & - 'unitless', & - 'unitless' & - /) - character(len=*), parameter :: fieldname(9) = (/ & - 'HARVEST_VH1 ', & - 'HARVEST_VH2 ', & - 'HARVEST_SH1 ', & - 'HARVEST_SH2 ', & - 'HARVEST_SH3 ', & - 'GRAZING ', & - 'FERTNITRO_CFT', & - 'PFT_LULCC ', & - 'CFT_LULCC ' & - /) - character(len=*), parameter :: longname(9) = (/ & - 'harvest from primary forest ', & - 'harvest from primary non-forest ', & - 'harvest from secondary mature-forest ', & - 'harvest from secondary young-forest ', & - 'harvest from secondary non-forest ', & - 'grazing of herbacous pfts ', & - 'constant background nitrogen fertilizer for each crop ', & - 'constant background unrepresented PFT LULCC transitions ', & - 'constant background unrepresented crop LULCC transitions' & - /) - character(len=256) :: string - character(len=*), parameter :: filename = 'unit_testers/inputs/harvestfields.nc' - - character(len=*), parameter :: subname = 'test_harvest_init' - integer :: nfields - - testname = 'check harvest_init' - test_prefix = modname//' -- '//subname//' -- '//trim(testname)//' -- ' - ! Open netcdf file that will be used for most tests - call check_ret(nf_open(filename, 0, ncid), subname) - varname = 'GRAZING' - call check_ret(nf_inq_varid(ncid, varname, varid), subname, varexists=varexists) - call test_is(varexists, trim(test_prefix)//'existing var') - call test_is( .not.mkharvest_fieldInBounds( 3 ), trim(test_prefix)//'allfieldsoutofboundsbeforeinit') - - call mkharvest_init( ns_o, 0.0_r8, harvdata, filename ) - call test_is( .not.mkharvest_fieldInBounds( 0 ), trim(test_prefix)//'0 out of bounds') - nfields = mkharvest_numtypes() - call test_is( .not.mkharvest_fieldInBounds( nfields+1), trim(test_prefix)//'10 out of bounds') - - ! make sure can now do getter functions - - do ifld = 1, mkharvest_numtypes() - call test_is(mkharvest_fieldname(ifld,constant=.true.), constfieldname(ifld), trim(test_prefix)//'bad const fieldname') - call test_is(mkharvest_fieldname(ifld), fieldname(ifld), trim(test_prefix)//trim(testname)//'bad fieldname') - call test_is(mkharvest_units(ifld), units(ifld), trim(test_prefix)//'bad units') - call test_is(mkharvest_longname(ifld), longname(ifld), trim(test_prefix)//'bad longname') - end do - call harvdata%clean() - - end subroutine test_harvest_init - - subroutine test_harvest_data_all1D() - implicit none - type(harvestDataType) :: harvdata - integer :: dim2nd(9) - integer :: dsizes(2), nfields, ifld, n, doutsizes(2) - integer :: dims1D(1), dims2D(2) - character(len=*), parameter :: subname = 'test_harvest_data' - character(len=*), parameter :: filename = 'unit_testers/inputs/harvestfields.nc' - integer, parameter :: indices1D(9) = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /) - integer, parameter :: indices2D(1) = (/ -1 /) - real(r8), pointer :: data1D(:) - integer, allocatable :: ind1D(:), ind2D(:) - integer, parameter :: ns_i = 15, ns_o = 10 - - testname = 'check harvest_data_all1D' - test_prefix = modname//' -- '//subname//' -- '//trim(testname)//' -- ' - dim2nd = 0 - call mkharvest_init( ns_o, 0.0_r8, harvdata, filename ) - call harvdata%clean() - call harvdata%init( dim2nd, ns_i, ns_o, 0.0_r8 ) - do ifld = 1, mkharvest_numtypes() - call test_is(harvdata%isField1D(ifld), trim(test_prefix)//'field is 1D' ) - call test_is(.not.harvdata%isField2D(ifld), trim(test_prefix)//'field not 2D' ) - end do - nfields = mkharvest_numtypes() - call test_is(harvdata%num1DFields(),nfields,trim(test_prefix)//'num 1D fields') - call test_is(harvdata%num2DFields(),0,trim(test_prefix)//'num 2D fields') - call harvdata%getFieldsIdx( ind1D, ind2D ) - call test_is(ind1D,indices1D,trim(test_prefix)//'1D fields indices') - call test_is(ind2D,indices2D,trim(test_prefix)//'2D fields indices') - dsizes(1) = ns_i - doutsizes(1) = ns_o - do n = 1, harvdata%num1DFields() - call test_is(harvdata%isField1D(indices1D(n)), trim(test_prefix)//'verify field is 1D' ) - data1D => harvdata%get1DFieldPtr( indices1D(n) ) - dims1D = shape(data1D) - call test_is(dims1D,dsizes(:),trim(test_prefix)//'1D field dims') - ! Set data - data1D(:) = real( n, r8 ) - data1D => null() - ! Output data - data1D => harvdata%get1DFieldPtr( indices1D(n), output=.true. ) - dims1D = shape(data1D) - call test_is(dims1D,doutsizes(:),trim(test_prefix)//'1D Output field dims') - ! Set data - data1D(:) = real( n*100, r8 ) - data1D => null() - end do - ! Check that data is set from setting above - do n = 1, harvdata%num1DFields() - data1D => harvdata%get1DFieldPtr( indices1D(n) ) - call test_is(data1D(1),real( n, r8 ), trim(test_prefix)//'field ') - data1D => null() - ! output data - data1D => harvdata%get1DFieldPtr( indices1D(n), output=.true. ) - call test_is(data1D(1),real( n*100, r8 ), trim(test_prefix)//'field ') - data1D => null() - end do - call harvdata%clean() - end subroutine test_harvest_data_all1D - -!------------------------------------------------------------------------------ - - subroutine test_harvest_data() - implicit none - type(harvestDataType) :: harvdata - integer :: dsizes(2), nfields, ifld, n, doutsizes(2) - integer :: dims1D(1), dims2D(2) - character(len=*), parameter :: subname = 'test_harvest_data' - character(len=*), parameter :: filename = 'unit_testers/inputs/harvestfields.nc' - integer, parameter :: indices1D(6) = (/ 1, 2, 3, 4, 5, 6 /) - integer, parameter :: indices2D(3) = (/ 7, 8, 9 /) - integer, parameter :: dim2nd(3) = (/ 64, 15, 64 /) - character(len=10) :: dimnames(3) = (/ "cft", "natpft", "cft" /) - real(r8), pointer :: data1D(:) - real(r8), pointer :: data2D(:,:) - integer, allocatable :: ind1D(:), ind2D(:) - integer, parameter :: ns_i = 4, ns_o = 20 - - testname = 'check harvest_data' - test_prefix = modname//' -- '//subname//' -- '//trim(testname)//' -- ' - call mkharvest_init( ns_o, 0.0_r8, harvdata, filename ) - call harvdata%getFieldsIdx( ind1D, ind2D ) - call test_is(ind1D,indices1D,trim(test_prefix)//'1D fields indices') - call test_is(ind2D,indices2D,trim(test_prefix)//'2D fields indices') - call test_is(harvdata%num1DFields(),size(indices1D),trim(test_prefix)//'num 1D fields') - call test_is(harvdata%num2DFields(),size(indices2D),trim(test_prefix)//'num 2D fields') - do n = 1, harvdata%num1DFields() - ifld = ind1D(n) - call test_is(harvdata%isField1D(ifld), trim(test_prefix)//'field is 1D' ) - call test_is(.not.harvdata%isField2D(ifld), trim(test_prefix)//'field not 2D' ) - end do - do n = 1, harvdata%num2DFields() - ifld = ind2D(n) - call test_is(.not.harvdata%isField1D(ifld), trim(test_prefix)//'field is not 1D' ) - call test_is(harvdata%isField2D(ifld), trim(test_prefix)//'field is 2D' ) - end do - dsizes(1) = ns_i - doutsizes(1) = ns_o - do n = 1, harvdata%num1DFields() - call test_is(harvdata%isField1D(indices1D(n)), trim(test_prefix)//'verify field is 1D' ) - data1D => harvdata%get1DFieldPtr( indices1D(n) ) - dims1D = shape(data1D) - call test_is(dims1D,dsizes(:),trim(test_prefix)//'1D field dims') - call test_is(harvdata%getFieldsDim(indices1D(n)),"none",trim(test_prefix)//'1D field dimname') - data1D => null() - end do - do n = 1, harvdata%num2DFields() - dsizes(2) = dim2nd(n) - call test_is(harvdata%isField2D(indices2D(n)), trim(test_prefix)//'verify field is 2D' ) - data2D => harvdata%get2DFieldPtr( indices2D(n) ) - dims2D = shape(data2D) - call test_is(dims2D,dsizes(:),trim(test_prefix)//'2D field dims') - call test_is(harvdata%getFieldsDim(indices2D(n)),dimnames(n),trim(test_prefix)//'1D field dimname') - data2D => null() - end do - call harvdata%clean() - end subroutine test_harvest_data - - -!------------------------------------------------------------------------------ - subroutine test_harvest_init_old - - use mkncdio - implicit none - - type(harvestDataType) :: harvdata - character(len=128) :: testname - integer :: ncid - character(len=128) :: varname - integer :: varid - logical :: varexists - integer, parameter :: ns_o = 4 - integer :: ifld - - character(len=*), parameter :: filename = 'unit_testers/inputs/harvestfieldsold.nc' - - character(len=*), parameter :: subname = 'test_harvest_init' - character(len=*), parameter :: constfieldname(9) = (/ & - 'CONST_HARVEST_VH1 ', & - 'CONST_HARVEST_VH2 ', & - 'CONST_HARVEST_SH1 ', & - 'CONST_HARVEST_SH2 ', & - 'CONST_HARVEST_SH3 ', & - 'CONST_GRAZING ', & - 'CONST_FERTNITRO_CFT ', & - 'UNREPRESENTED_PFT_LULCC', & - 'UNREPRESENTED_CFT_LULCC' & - /) - character(len=*), parameter :: units(9) = (/ & - 'unitless ', & - 'unitless ', & - 'unitless ', & - 'unitless ', & - 'unitless ', & - 'unitless ', & - 'not_read_in', & - 'not_read_in', & - 'not_read_in' & - /) - character(len=*), parameter :: fieldname(9) = (/ & - 'HARVEST_VH1 ', & - 'HARVEST_VH2 ', & - 'HARVEST_SH1 ', & - 'HARVEST_SH2 ', & - 'HARVEST_SH3 ', & - 'GRAZING ', & - 'FERTNITRO_CFT', & - 'PFT_LULCC ', & - 'CFT_LULCC ' & - /) - character(len=*), parameter :: longname(9) = (/ & - 'harvest from primary forest ', & - 'harvest from primary non-forest ', & - 'harvest from secondary mature-forest', & - 'harvest from secondary young-forest ', & - 'harvest from secondary non-forest ', & - 'grazing of herbacous pfts ', & - 'FERTNITRO_CFT (zeroed out) ', & - 'PFT_LULCC (zeroed out) ', & - 'CFT_LULCC (zeroed out) ' & - /) - character(len=256) :: string - testname = 'check harvest_init_old' - ! Open netcdf file that will be used for most tests - call check_ret(nf_open(filename, 0, ncid), subname) - varname = 'GRAZING' - call check_ret(nf_inq_varid(ncid, varname, varid), subname, varexists=varexists) - call test_is(varexists, modname//' -- '//subname//' -- '//trim(testname)//' -- existing var') - - call mkharvest_init( ns_o, 0.0_r8, harvdata, filename ) - - ! make sure can now do getter functions - - do ifld = 1, mkharvest_numtypes() - call test_is(mkharvest_fieldname(ifld,constant=.true.), constfieldname(ifld), modname//' -- '//subname//' -- '//trim(testname)//' -- bad const fieldname') - call test_is(mkharvest_fieldname(ifld), fieldname(ifld), modname//' -- '//subname//' -- '//trim(testname)//' -- bad fieldname') - call test_is(mkharvest_units(ifld), units(ifld), modname//' -- '//subname//' -- '//trim(testname)//' -- bad units') - call test_is(mkharvest_longname(ifld), longname(ifld), modname//' -- '//subname//' -- '//trim(testname)//' -- bad longname') - end do - call harvdata%clean() - - end subroutine test_harvest_init_old - -end module test_mkharvest diff --git a/tools/mksurfdata_map/unit_testers/test_mkindexmapMod.F90 b/tools/mksurfdata_map/unit_testers/test_mkindexmapMod.F90 deleted file mode 100644 index 709d6dac0c..0000000000 --- a/tools/mksurfdata_map/unit_testers/test_mkindexmapMod.F90 +++ /dev/null @@ -1,573 +0,0 @@ -module test_mkindexmapMod -! Module for testing mkindexmapMod - - use mkindexmapMod - use test_mod - use shr_kind_mod, only : r8 => shr_kind_r8 - - implicit none - private - - public :: test_get_dominant_indices - public :: test_lookup_2d - public :: test_lookup_2d_netcdf - public :: test_which_max - - character(len=*), parameter :: modname = 'test_mkindexmapMod' - -contains - -!------------------------------------------------------------------------------ - subroutine test_get_dominant_indices - - use mkgridmapMod, only : gridmap_type - - implicit none - - type(gridmap_type) :: gridmap - character(len=128) :: testname - - integer, allocatable :: src_array(:) - integer, allocatable :: mask_src(:) - integer, allocatable :: dst_array(:) - integer, allocatable :: dst_array_t(:) - logical, allocatable :: filter(:) - integer :: minval, maxval, nodata - - character(len=*), parameter :: subname = 'test_get_dominant_indices' - - ! Set up a gridmap that will be used for most tests, and allocate corresponding - ! arrays: - ! Note that, for most tests here, the test arrays are: (1) simple case, (2) the main - ! case to test, (3) simple case. Thus, the main case in question is #2 of 3, and - ! we're always basically just testing one scenario in each call to the subroutine - ! (rather than doing a bunch of tests at once, which could make setting up the test - ! arrays more error-prone). - - ! This gridmap will have 3 src cells, 9 dest cells, and: - ! src 1: just overlaps with dst 1 - ! src 2: overlaps with dst 1 & dst 2 - ! src 3..7: just overlaps with dst 2 - ! src 8: overlaps with dst 2 & dst 3 - ! src 9: just overlaps with dst 3 - ! Note: I'm not setting some things that aren't used in get_dominant_indices - gridmap%na = 9 - gridmap%nb = 3 - gridmap%ns = 11 - allocate(gridmap%src_indx(gridmap%ns), & - gridmap%dst_indx(gridmap%ns), & - gridmap%wovr (gridmap%ns)) - gridmap%src_indx = (/1,2,2,3,4,5,6,7,8,8,9/) - gridmap%dst_indx = (/1,1,2,2,2,2,2,2,2,3,3/) - gridmap%wovr = (/0.75,0.25, & ! weights of sources 1:2 on dest 1 - 0.1,0.1,0.1,0.3,0.2,0.2,0.2, & ! weights of sources 2:8 on dest 2 - 0.25,0.75/) ! weights of sources 8:9 on test 3 - allocate(src_array (gridmap%na), & - mask_src (gridmap%na), & - dst_array (gridmap%nb), & - dst_array_t(gridmap%nb), & - filter (gridmap%ns)) - - testname = 'basic test, all unique' - src_array = (/1, 2, 3, 4, 5, 6, 7, 8, 9/) - mask_src(:) = 1 ! same for all the tests - minval = 1 - maxval = 9 - nodata = -1 - ! dst 2 takes its value from src 5 because it has the largest weight: - dst_array_t = (/1, 5, 9/) - call get_dominant_indices(gridmap, src_array, dst_array, minval, maxval, nodata, mask_src=mask_src) - call test_is(dst_array, dst_array_t, modname//' -- '//subname//' -- '//trim(testname)) - - testname = 'basic test, some duplicates' - src_array = (/1, 2, 3, 3, 4, 2, 2, 1, 1/) - minval = 1 - maxval = 4 - nodata = -1 - dst_array_t = (/1, 2, 1/) - call get_dominant_indices(gridmap, src_array, dst_array, minval, maxval, nodata, mask_src=mask_src) - call test_is(dst_array, dst_array_t, modname//' -- '//subname//' -- '//trim(testname)) - - testname = 'minval not 1' - src_array = (/3, 4, 5, 5, 6, 4, 4, 3, 3/) - minval = 3 - maxval = 6 - nodata = -1 - dst_array_t = (/3, 4, 3/) - call get_dominant_indices(gridmap, src_array, dst_array, minval, maxval, nodata, mask_src=mask_src) - call test_is(dst_array, dst_array_t, modname//' -- '//subname//' -- '//trim(testname)) - - testname = 'single non-zero source value' - src_array = (/1, 0, 0, 0, 0, 2, 0, 0, 1/) - minval = 1 - maxval = 2 - nodata = -1 - dst_array_t = (/1, 2, 1/) - call get_dominant_indices(gridmap, src_array, dst_array, minval, maxval, nodata, mask_src=mask_src) - call test_is(dst_array, dst_array_t, modname//' -- '//subname//' -- '//trim(testname)) - - testname = 'single value within given min-max range' - src_array = (/1, 0, 9, 9, 0, 2, 9, 9, 1/) - minval = 1 - maxval = 2 - nodata = -1 - dst_array_t = (/1, 2, 1/) - call get_dominant_indices(gridmap, src_array, dst_array, minval, maxval, nodata, mask_src=mask_src) - call test_is(dst_array, dst_array_t, modname//' -- '//subname//' -- '//trim(testname)) - - testname = 'no valid values' - src_array = (/1, 0, 9, 9, 0, 0, 9, 9, 1/) - minval = 1 - maxval = 2 - nodata = -1 - dst_array_t = (/1, nodata, 1/) - call get_dominant_indices(gridmap, src_array, dst_array, minval, maxval, nodata, mask_src=mask_src) - call test_is(dst_array, dst_array_t, modname//' -- '//subname//' -- '//trim(testname)) - - testname = 'some filters false' - src_array = (/1, 2, 3, 3, 4, 2, 2, 1, 1/) - minval = 1 - maxval = 4 - nodata = -1 - filter = (/.true., .true., & - .false., .true., .true., .true., .false., .true., .true., & - .true., .true./) - dst_array_t = (/1, 4, 1/) - call get_dominant_indices(gridmap, src_array, dst_array, minval, maxval, nodata, filter=filter, mask_src=mask_src) - call test_is(dst_array, dst_array_t, modname//' -- '//subname//' -- '//trim(testname)) - - testname = 'all filters false' - src_array = (/1, 2, 3, 3, 4, 2, 2, 1, 1/) - minval = 1 - maxval = 4 - nodata = -1 - filter = (/.true., .true., & - .false., .false., .false., .false., .false., .false., .false., & - .true., .true./) - dst_array_t = (/1, nodata, 1/) - call get_dominant_indices(gridmap, src_array, dst_array, minval, maxval, nodata, filter=filter, mask_src=mask_src) - call test_is(dst_array, dst_array_t, modname//' -- '//subname//' -- '//trim(testname)) - - ! Modify gridmap weights for the following test - gridmap%wovr = (/0.75,0.25, & ! weights of sources 1:2 on dest 1 - 0.0,0.0,0.0,0.0,0.0,0.0,0.0, & ! weights of sources 2:8 on dest 2 - 0.25,0.75/) ! weights of sources 8:9 on test 3 - testname='all weights 0' - src_array = (/1, 1, 1, 1, 1, 1, 1, 1, 1/) - minval = 1 - maxval = 2 - nodata = -1 - dst_array_t = (/1, nodata, 1/) - call get_dominant_indices(gridmap, src_array, dst_array, minval, maxval, nodata, mask_src=mask_src) - call test_is(dst_array, dst_array_t, modname//' -- '//subname//' -- '//trim(testname)) - - ! Make a new gridmap for the following test; - ! this involves more output cells and a more complex mapping from src to dst - ! This gridmap will have: - ! dst 1: from src 1, 4, 7 - ! dst 2: from src 2, 4, 6 - ! dst 3: from src 1 - ! dst 4: no overlapping src cells - ! dst 5: from src 5, 7, 8 - ! note that src 3 & 9 do not overlap with any dst - deallocate(gridmap%src_indx, gridmap%dst_indx, gridmap%wovr, & - src_array, dst_array, dst_array_t, filter) - gridmap%na = 9 - gridmap%nb = 5 - gridmap%ns = 10 - allocate(gridmap%src_indx(gridmap%ns), & - gridmap%dst_indx(gridmap%ns), & - gridmap%wovr (gridmap%ns)) - gridmap%src_indx = (/1, 2, 4, 4, 7, 6, 1, 5, 7, 8/) - gridmap%dst_indx = (/1, 2, 1, 2, 1, 2, 3, 5, 5, 5/) - gridmap%wovr = (/1, 1, 2, 2, 1, 3, 1, 2, 2, 3/) - allocate(src_array (gridmap%na), & - dst_array (gridmap%nb), & - dst_array_t(gridmap%nb), & - filter (gridmap%ns)) - - testname = 'more complex gridmap' - ! src index: 1 2 3 4 5 6 7 8 9 - src_array = (/1, 2, 3, 1, 5, 6, 5, 8, 9/) - minval = 1 - maxval = 9 - nodata = -1 - dst_array_t = (/1, 6, 1, nodata, 5/) - call get_dominant_indices(gridmap, src_array, dst_array, minval, maxval, nodata, mask_src=mask_src) - call test_is(dst_array, dst_array_t, modname//' -- '//subname//' -- '//trim(testname)) - - deallocate(gridmap%src_indx, gridmap%dst_indx, gridmap%wovr, & - src_array, dst_array_t, filter) - - end subroutine test_get_dominant_indices -!------------------------------------------------------------------------------ - -!------------------------------------------------------------------------------ - subroutine test_lookup_2d - - implicit none - - character(len=128) :: testname - real(r8), allocatable :: lookup_table(:,:) - logical , allocatable :: valid_entries(:,:) - integer , allocatable :: index1(:), index2(:) - real(r8), allocatable :: data(:), data_t(:) - real(r8) :: fill_val - integer :: nodata - integer :: ierr, ierr_t - - character(len=*), parameter :: subname = 'test_lookup_2d' - - ! Create lookup table for use in most tests - allocate(lookup_table(2,3), valid_entries(2,3)) - lookup_table(1,:) = (/11.,12.,13./) - lookup_table(2,:) = (/21.,22.,23./) - - testname = 'basic test; no nodata or valid_entries' - allocate(index1(5), index2(5), data(5), data_t(5)) - index1 = (/1,2,1,2,2/) - index2 = (/1,2,3,2,3/) - fill_val = -1. - data_t = (/11., 22., 13., 22., 23./) - ierr_t = 0 - call lookup_2d(index1, index2, lookup_table, fill_val, data, ierr) - call check_results - deallocate(index1, index2, data, data_t) - - testname = 'basic test but with index out of range' - allocate(index1(5), index2(5), data(5), data_t(5)) - index1 = (/1,2,3,2,2/) - index2 = (/1,2,1,2,4/) - fill_val = -1. - data_t = (/11._r8, 22._r8, fill_val, 22._r8, fill_val/) - ierr_t = 2 - call lookup_2d(index1, index2, lookup_table, fill_val, data, ierr) - call check_results - deallocate(index1, index2, data, data_t) - - testname = 'basic test but with nodata present, and a nodata value in input' - allocate(index1(5), index2(5), data(5), data_t(5)) - nodata = -1 - index1 = (/nodata,2,1,2,nodata/) - index2 = (/1,2,3,nodata,nodata/) - fill_val = -1. - data_t = (/fill_val, 22._r8, 13._r8, fill_val, fill_val/) - ierr_t = 0 - call lookup_2d(index1, index2, lookup_table, fill_val, data, ierr, nodata=nodata) - call check_results - deallocate(index1, index2, data, data_t) - - testname = 'valid_entries' - allocate(index1(5), index2(5), data(5), data_t(5)) - index1 = (/1,1,2,2,1/) - index2 = (/1,2,1,2,3/) - valid_entries(1,:) = (/.false.,.false.,.true./) - valid_entries(2,:) = (/.true. ,.true. ,.true./) - fill_val = -1. - data_t = (/fill_val, fill_val, 21._r8, 22._r8, 13._r8/) - ierr_t = 1 - call lookup_2d(index1, index2, lookup_table, fill_val, data, ierr, valid_entries=valid_entries) - call check_results - - testname = 'valid_entries, invalid_okay' - ! Note: this test reuses some setup from the previous test - ierr_t = 0 - call lookup_2d(index1, index2, lookup_table, fill_val, data, ierr, & - valid_entries=valid_entries, invalid_okay=.true.) - call check_results - deallocate(index1, index2, data, data_t) - - - testname = 'valid_entries, together with index out of range' - ! in addition to checking both valid_entries and index out of range, this also - ! makes sure that we get the appropriate ierr value when we have both errors - ! (because we encounter the valid_entries error first) - allocate(index1(5), index2(5), data(5), data_t(5)) - index1 = (/1,1,3,2,2/) - index2 = (/1,2,1,1,0/) - valid_entries(1,:) = (/.false.,.false.,.true./) - valid_entries(2,:) = (/.true. ,.true. ,.true./) - fill_val = -1. - data_t = (/fill_val, fill_val, fill_val, 21._r8, fill_val/) - ierr_t = 1 - call lookup_2d(index1, index2, lookup_table, fill_val, data, ierr, valid_entries=valid_entries) - call check_results - deallocate(index1, index2, data, data_t) - - - deallocate(lookup_table, valid_entries) - - contains - subroutine check_results - call test_is(data, data_t, modname//' -- '//subname//' -- '//trim(testname)//' -- data') - call test_is(ierr, ierr_t, modname//' -- '//subname//' -- '//trim(testname)//' -- ierr') - end subroutine check_results - - end subroutine test_lookup_2d -!------------------------------------------------------------------------------ - -!------------------------------------------------------------------------------ - subroutine test_lookup_2d_netcdf - - use mkncdio - - implicit none - - character(len=128) :: testname - character(len=64) :: tablename - character(len=4) :: dimname1, dimname2 - logical :: invalid_lookup - integer :: n_extra_dims - integer , allocatable :: index1(:), index2(:) - real(r8), allocatable :: data(:), data_t(:) - real(r8) :: fill_val - integer :: nodata - integer :: ierr, ierr_t - type(dim_slice_type), allocatable :: extra_dims(:) - - integer :: ncid - character(len=*), parameter :: filename = 'unit_testers/inputs/test_lookup_2d_netcdf.nc' - - ! flags to enable tests that we don't usually want to run, because they result in - ! an abort, but we may occasionally want to run to make sure this error-handling is - ! working properly - logical, parameter :: test_abort1 = .false. - logical, parameter :: test_abort2 = .false. - logical, parameter :: test_abort3 = .false. - - character(len=*), parameter :: subname = 'test_lookup_2d_netcdf' - - ! Open netcdf file that will be used for most tests: - ! Note that this file was created such that lookup4d(i,j,k,l) = 1000*i+100*j+10*k+l, - ! and similarly for the other variables - ! Also, lookup2d(1,2) is missing (i.e., equal to the _FillVal) - call check_ret(nf_open(filename, 0, ncid), subname) - - testname = '2-d lookup table with _FillValue resulting in valid_entries false somewhere' - allocate(index1(5), index2(5), data(5), data_t(5)) - tablename = 'lookup2d' - invalid_lookup = .true. - dimname1 = 'dim1' - dimname2 = 'dim2' - n_extra_dims = 0 - index1 = (/1,2,1,2,2/) - index2 = (/1,2,2,1,3/) - fill_val = -1. - ! Note that the third value is fill_val because lookup2d(1,2) is missing (i.e., - ! equal to the _FillVal in the netcdf file) - data_t = (/11._r8, 22._r8, fill_val, 21._r8, 23._r8/) - ierr_t = 1 - call lookup_2d_netcdf(ncid, tablename, invalid_lookup, dimname1, dimname2, & - n_extra_dims, index1, index2, fill_val, data, ierr) - call check_results - - testname = '2-d lookup table with _FillValue resulting in valid_entries false somewhere, invalid_okay' - ! Note: this test reuses some setup from the previous test - ierr_t = 0 - call lookup_2d_netcdf(ncid, tablename, invalid_lookup, dimname1, dimname2, & - n_extra_dims, index1, index2, fill_val, data, ierr, invalid_okay=.true.) - call check_results - deallocate(index1, index2, data, data_t) - - testname = '3-d lookup table with no _FillValue; nodata in index arrays' - allocate(index1(5), index2(5), data(5), data_t(5)) - tablename = 'lookup3d' - invalid_lookup = .false. - dimname1 = 'dim1' - dimname2 = 'dim2' - n_extra_dims = 1 - allocate(extra_dims(n_extra_dims)) - extra_dims(1) = dim_slice_type('dim3', 2) - nodata = -999 - index1 = (/nodata,2,1,2,2/) - index2 = (/1,2,2,1,nodata/) - fill_val = -1. - data_t = (/fill_val, 222._r8, 122._r8, 212._r8, fill_val/) - ierr_t = 0 - call lookup_2d_netcdf(ncid, tablename, invalid_lookup, dimname1, dimname2, & - n_extra_dims, index1, index2, fill_val, data, ierr, extra_dims=extra_dims, & - nodata=nodata) - call check_results - deallocate(index1, index2, data, data_t, extra_dims) - - testname = '4-d lookup table' - allocate(index1(5), index2(5), data(5), data_t(5)) - tablename = 'lookup4d' - invalid_lookup = .true. - dimname1 = 'dim1' - dimname2 = 'dim2' - n_extra_dims = 2 - allocate(extra_dims(n_extra_dims)) - extra_dims(1) = dim_slice_type('dim3', 4) - extra_dims(2) = dim_slice_type('dim4', 5) - index1 = (/1,2,1,2,2/) - index2 = (/1,2,2,1,3/) - fill_val = -1. - data_t = (/1145., 2245., 1245., 2145., 2345./) - ierr_t = 0 - call lookup_2d_netcdf(ncid, tablename, invalid_lookup, dimname1, dimname2, & - n_extra_dims, index1, index2, fill_val, data, ierr, extra_dims=extra_dims) - call check_results - deallocate(index1, index2, data, data_t, extra_dims) - - ! The following tests should result in the code aborting with an error message. - ! - ! We don't usually want to run these tests, because they result in the code - ! aborting, but we may want to run them occasionally to make sure this - ! error-handling is working correctly. - - if (test_abort1) then - testname = '2-d lookup table with incorrect dimname for dimension 2' - allocate(index1(5), index2(5), data(5), data_t(5)) - tablename = 'lookup2d' - invalid_lookup = .true. - dimname1 = 'dim1' - dimname2 = 'bad2' ! this differs from the value in the file - n_extra_dims = 0 - index1 = (/1,2,1,2,2/) - index2 = (/1,2,2,1,3/) - fill_val = -1. - ! Note that the third value is fill_val because lookup2d(1,2) is missing (i.e., - ! equal to the _FillVal in the netcdf file) - data_t = (/11._r8, 22._r8, fill_val, 21._r8, 23._r8/) - ierr_t = 1 - call lookup_2d_netcdf(ncid, tablename, invalid_lookup, dimname1, dimname2, & - n_extra_dims, index1, index2, fill_val, data, ierr) - deallocate(index1, index2, data, data_t) - end if - - if (test_abort2) then - testname = '3-d lookup table with incorrect dimname for dimension 3' - allocate(index1(5), index2(5), data(5), data_t(5)) - tablename = 'lookup3d' - invalid_lookup = .false. - dimname1 = 'dim1' - dimname2 = 'dim2' - n_extra_dims = 1 - allocate(extra_dims(n_extra_dims)) - extra_dims(1) = dim_slice_type('bad3', 2) ! this name differs from the value in the file - nodata = -999 - index1 = (/nodata,2,1,2,2/) - index2 = (/1,2,2,1,nodata/) - fill_val = -1. - data_t = (/fill_val, 222._r8, 122._r8, 212._r8, fill_val/) - ierr_t = 0 - call lookup_2d_netcdf(ncid, tablename, invalid_lookup, dimname1, dimname2, & - n_extra_dims, index1, index2, fill_val, data, ierr, extra_dims=extra_dims, & - nodata=nodata) - deallocate(index1, index2, data, data_t, extra_dims) - end if - - if (test_abort3) then - testname = '3-d lookup table, trying to access too large index for dimension 3' - allocate(index1(5), index2(5), data(5), data_t(5)) - tablename = 'lookup3d' - invalid_lookup = .false. - dimname1 = 'dim1' - dimname2 = 'dim2' - n_extra_dims = 1 - allocate(extra_dims(n_extra_dims)) - extra_dims(1) = dim_slice_type('dim3', 5) ! this index is out of bounds - nodata = -999 - index1 = (/nodata,2,1,2,2/) - index2 = (/1,2,2,1,nodata/) - fill_val = -1. - data_t = (/fill_val, 222._r8, 122._r8, 212._r8, fill_val/) - ierr_t = 0 - call lookup_2d_netcdf(ncid, tablename, invalid_lookup, dimname1, dimname2, & - n_extra_dims, index1, index2, fill_val, data, ierr, extra_dims=extra_dims, & - nodata=nodata) - deallocate(index1, index2, data, data_t, extra_dims) - end if - - call check_ret(nf_close(ncid), subname) - - contains - subroutine check_results - call test_is(data, data_t, modname//' -- '//subname//' -- '//trim(testname)//' -- data') - call test_is(ierr, ierr_t, modname//' -- '//subname//' -- '//trim(testname)//' -- ierr') - end subroutine check_results - - end subroutine test_lookup_2d_netcdf -!------------------------------------------------------------------------------ - -!------------------------------------------------------------------------------ - subroutine test_which_max - - implicit none - - real(r8), dimension(:), allocatable :: arr - - character(len=128) :: testname - - real(r8) :: maxval, maxval_t - integer :: maxindex, maxindex_t - - character(len=*), parameter :: subname = 'test_which_max' - - - testname = 'length-1 array' - allocate(arr(1)) - arr = (/3.0/) - maxval_t = 3.0 - maxindex_t = 1 - call which_max(arr, maxval, maxindex) - call check_results - deallocate(arr) - - testname = 'max @ 1' - allocate(arr(5)) - arr = (/5.0, 2.0, 3.0, 2.5, 1.5/) - maxval_t = 5.0 - maxindex_t = 1 - call which_max(arr, maxval, maxindex) - call check_results - deallocate(arr) - - testname = 'max in middle' - allocate(arr(5)) - arr = (/1.0, 2.0, 3.0, 2.5, 1.5/) - maxval_t = 3.0 - maxindex_t = 3 - call which_max(arr, maxval, maxindex) - call check_results - deallocate(arr) - - testname = 'max at end' - allocate(arr(5)) - arr = (/1.0, 2.0, 3.0, 2.5, 8.0/) - maxval_t = 8.0 - maxindex_t = 5 - call which_max(arr, maxval, maxindex) - call check_results - deallocate(arr) - - testname = 'multiple tied max values' - allocate(arr(5)) - arr = (/1.0, 3.0, 3.0, 2.5, 1.5/) - maxval_t = 3.0 - maxindex_t = 2 - call which_max(arr, maxval, maxindex) - call check_results - deallocate(arr) - - testname = 'max in middle, with lbound present' - allocate(arr(3:7)) - arr = (/1.0, 3.0, 10.0, 2.5, 8.0/) - maxval_t = 10.0 - maxindex_t = 5 - call which_max(arr, maxval, maxindex, lbound=3) - call check_results - deallocate(arr) - - contains - subroutine check_results - call test_is(maxval, maxval_t, modname//' -- '//subname//' -- '//trim(testname)//' -- maxval') - call test_is(maxindex, maxindex_t, modname//' -- '//subname//' -- '//trim(testname)//' -- maxindex') - end subroutine check_results - - end subroutine test_which_max -!------------------------------------------------------------------------------ - -end module test_mkindexmapMod - diff --git a/tools/mksurfdata_map/unit_testers/test_mkncdio.F90 b/tools/mksurfdata_map/unit_testers/test_mkncdio.F90 deleted file mode 100644 index b96dc47071..0000000000 --- a/tools/mksurfdata_map/unit_testers/test_mkncdio.F90 +++ /dev/null @@ -1,82 +0,0 @@ -module test_mkncdio -! Module for testing mkncdio - - use mkncdio - use test_mod - - implicit none - private - - public :: test_get_dim_lengths - public :: test_get_nonexisting_var - - character(len=*), parameter :: modname = 'test_mkncdio' - -contains - -!------------------------------------------------------------------------------ - subroutine test_get_dim_lengths - - implicit none - - character(len=128) :: testname - integer :: ncid - character(len=128) :: varname - integer :: ndims, ndims_t - integer :: dim_lengths(nf_max_var_dims), dim_lengths_t(nf_max_var_dims) - - character(len=*), parameter :: filename = 'unit_testers/inputs/test_lookup_2d_netcdf.nc' - - character(len=*), parameter :: subname = 'test_get_dim_lengths' - - ! Open netcdf file that will be used for most tests - call check_ret(nf_open(filename, 0, ncid), subname) - - testname = '3d variable' - varname = 'lookup3d' - ndims_t = 3 - dim_lengths_t = 0 - dim_lengths_t(1) = 2 - dim_lengths_t(2) = 3 - dim_lengths_t(3) = 4 - call get_dim_lengths(ncid, varname, ndims, dim_lengths) - call check_results - - call check_ret(nf_close(ncid), subname) - - contains - subroutine check_results - call test_is(ndims, ndims_t, modname//' -- '//subname//' -- '//trim(testname)//' -- ndims') - call test_is(dim_lengths(1:ndims), dim_lengths_t(1:ndims_t), & - modname//' -- '//subname//' -- '//trim(testname)//' -- dim_lengths') - end subroutine check_results - - end subroutine test_get_dim_lengths - -!------------------------------------------------------------------------------ - subroutine test_get_nonexisting_var - - implicit none - - character(len=128) :: testname - integer :: ncid - character(len=128) :: varname - integer :: varid - logical :: varexists - - character(len=*), parameter :: filename = 'unit_testers/inputs/test_lookup_2d_netcdf.nc' - - character(len=*), parameter :: subname = 'test_get_nonexiting_var' - - testname = 'check if variables exist' - varname = 'lookup3d' - ! Open netcdf file that will be used for most tests - call check_ret(nf_open(filename, 0, ncid), subname) - call check_ret(nf_inq_varid(ncid, "zztop", varid), subname, varexists=varexists) - call test_is(.not.varexists, modname//' -- '//subname//' -- '//trim(testname)//' -- non existing var') - call check_ret(nf_inq_varid(ncid, varname, varid), subname, varexists=varexists) - call test_is(varexists, modname//' -- '//subname//' -- '//trim(testname)//' -- existing var') - - end subroutine test_get_nonexisting_var - -end module test_mkncdio diff --git a/tools/mksurfdata_map/unit_testers/test_mksurfdata_map.F90 b/tools/mksurfdata_map/unit_testers/test_mksurfdata_map.F90 deleted file mode 100644 index cb5f7f9b72..0000000000 --- a/tools/mksurfdata_map/unit_testers/test_mksurfdata_map.F90 +++ /dev/null @@ -1,52 +0,0 @@ -! Run unit tests for mksurfdata_map -program mksurfdata_map_unit_tester - use test_mkdomainMod - use test_mkutilsMod - use test_mkgridmapMod - use test_mkindexmapMod - use test_mkchecksMod - use test_mkurbanparMod - use test_mkncdio - use test_mkharvest - use test_mod, only : test_init, test_final - - call test_init - - ! Test mkdomainMod - call test_domain_read_dims - - ! Test mkutilsMod - call test_slightly_below - call test_slightly_above - - ! Test mkgridmapMod - call test_gridmap_areaave_no_srcmask - call test_gridmap_areaave_srcmask - call test_gridmap_areastddev - - ! Test mkindexmapMod - call test_get_dominant_indices - call test_lookup_2d - call test_lookup_2d_netcdf - call test_which_max - - ! Test mkchecksMod - call test_min_bad - call test_max_bad - - ! Test mkurbanparMod - call test_normalize_urbn_by_tot - - ! Test mkharvestMod - call test_harvest_init - call test_harvest_init_old - call test_harvest_data_all1D - call test_harvest_data - - ! Test mkncdio - call test_get_dim_lengths - call test_get_nonexisting_var - - call test_final - -end program mksurfdata_map_unit_tester diff --git a/tools/mksurfdata_map/unit_testers/test_mkurbanparMod.F90 b/tools/mksurfdata_map/unit_testers/test_mkurbanparMod.F90 deleted file mode 100644 index 30168eb97c..0000000000 --- a/tools/mksurfdata_map/unit_testers/test_mkurbanparMod.F90 +++ /dev/null @@ -1,75 +0,0 @@ -module test_mkurbanparMod -! Module for testing mkurbanparMod - - use mkurbanparMod - use test_mod - use shr_kind_mod, only : r8 => shr_kind_r8 - - implicit none - private - - public :: test_normalize_urbn_by_tot - - character(len=*), parameter :: modname = 'test_mkurbanparMod' - -contains - -!------------------------------------------------------------------------------ - subroutine test_normalize_urbn_by_tot - - use mkutilsMod, only : normalize_classes_by_gcell - - implicit none - - character(len=128) :: testname - - real(r8), allocatable :: classes_pct_gcell_t(:,:) - real(r8), allocatable :: classes_pct_gcell(:,:) - real(r8), allocatable :: classes_pct_tot(:,:) - real(r8), allocatable :: sums(:) - - integer :: n,nmax,nclass,totsize - - real(r8), parameter :: eps = 1.e-13_r8 - - character(len=*), parameter :: subname = 'test_normalize_urbn_by_tot' - - - ! This test does a basic check of both normalize_urbn_by_tot and - ! normalize_classes_by_gcell, by ensuring that when the two are called in - ! succession, the result is the same as the initial values - ! (Note that it doesn't directly check the intermediate values -- i.e. the output - ! produced by normalize_urbn_by_tot) - testname = 'normalize_urbn_by_tot then normalize_classes_by_gcell' - nmax = 7 - nclass = 3 - totsize = nmax*nclass - allocate(classes_pct_gcell_t(nmax,nclass), & - classes_pct_gcell (nmax,nclass), & - classes_pct_tot (nmax,nclass), & - sums (nmax)) - - ! The following values are designed to test a number of things, including summing - ! to 100, summing to 0, some values 0 for a given n, and no values being 0 for a - ! given n - classes_pct_gcell_t(:,1) = (/ 0., 5., 0., 0., 10., 0., 10./) - classes_pct_gcell_t(:,2) = (/ 0., 0., 0., 100., 30., 15., 50./) - classes_pct_gcell_t(:,3) = (/100., 30., 0., 0., 20., 0., 40./) - - do n = 1, nmax - sums(n) = sum(classes_pct_gcell_t(n,:)) - end do - - call normalize_urbn_by_tot(classes_pct_gcell_t, sums, classes_pct_tot) - call normalize_classes_by_gcell(classes_pct_tot, sums, classes_pct_gcell) - call test_close(reshape(classes_pct_gcell, (/totsize/)), & - reshape(classes_pct_gcell_t, (/totsize/)), & - eps, modname//' -- '//subname//' -- '//trim(testname), rel_diff=.true.) - - deallocate(classes_pct_gcell_t, classes_pct_gcell, classes_pct_tot, sums) - - - end subroutine test_normalize_urbn_by_tot -!------------------------------------------------------------------------------ - -end module test_mkurbanparMod diff --git a/tools/mksurfdata_map/unit_testers/test_mkutilsMod.F90 b/tools/mksurfdata_map/unit_testers/test_mkutilsMod.F90 deleted file mode 100644 index 53b5b1b8c3..0000000000 --- a/tools/mksurfdata_map/unit_testers/test_mkutilsMod.F90 +++ /dev/null @@ -1,112 +0,0 @@ -module test_mkutilsMod -! Module for testing mkutilsMod - - use mkutilsMod - use test_mod - use shr_kind_mod, only : r8 => shr_kind_r8 - - implicit none - private - - public :: test_slightly_below - public :: test_slightly_above - - character(len=*), parameter :: modname = 'test_mkutilsMod' - -contains - -!------------------------------------------------------------------------------ - subroutine test_slightly_below - - implicit none - - character(len=128) :: testname - - logical :: retval - real(r8) :: a - real(r8) :: b - - character(len=*), parameter :: subname = 'test_slightly_below' - - testname='basic-true' - b = 3.0 - a = 3.0 - b*epsilon(b) - retval = slightly_below(a,b) - call test_is((retval .eqv. .true.), modname//' -- '//subname//' -- '//trim(testname)) - - testname='far below' - b = 3.0 - a = 2.0 - retval = slightly_below(a,b) - call test_is((retval .eqv. .false.), modname//' -- '//subname//' -- '//trim(testname)) - - testname='equal' - b = 3.0 - a = 3.0 - retval = slightly_below(a,b) - call test_is((retval .eqv. .false.), modname//' -- '//subname//' -- '//trim(testname)) - - testname='above' - b = 3.0 - a = 3.0 + epsilon(b) - retval = slightly_below(a,b) - call test_is((retval .eqv. .false.), modname//' -- '//subname//' -- '//trim(testname)) - - testname='change epsilon to allow far below' - b = 3.0 - a = 2.0 - retval = slightly_below(a,b,eps=0.75_r8) - call test_is((retval .eqv. .true.), modname//' -- '//subname//' -- '//trim(testname)) - - end subroutine test_slightly_below -!------------------------------------------------------------------------------ - -!------------------------------------------------------------------------------ - subroutine test_slightly_above - - implicit none - - character(len=128) :: testname - - logical :: retval - real(r8) :: a - real(r8) :: b - - character(len=*), parameter :: subname = 'test_slightly_above' - - testname='basic-true' - b = 3.0 - a = 3.0 + b*epsilon(b) - retval = slightly_above(a,b) - call test_is((retval .eqv. .true.), modname//' -- '//subname//' -- '//trim(testname)) - - testname='far above' - b = 3.0 - a = 4.0 - retval = slightly_above(a,b) - call test_is((retval .eqv. .false.), modname//' -- '//subname//' -- '//trim(testname)) - - testname='equal' - b = 3.0 - a = 3.0 - retval = slightly_above(a,b) - call test_is((retval .eqv. .false.), modname//' -- '//subname//' -- '//trim(testname)) - - testname='below' - b = 3.0 - a = 3.0 - epsilon(b) - retval = slightly_above(a,b) - call test_is((retval .eqv. .false.), modname//' -- '//subname//' -- '//trim(testname)) - - testname='change epsilon to allow far above' - b = 3.0 - a = 4.0 - retval = slightly_above(a,b,eps=0.75_r8) - call test_is((retval .eqv. .true.), modname//' -- '//subname//' -- '//trim(testname)) - - end subroutine test_slightly_above -!------------------------------------------------------------------------------ - -end module test_mkutilsMod - - diff --git a/tools/mksurfdata_map/unit_testers/test_mod.F90 b/tools/mksurfdata_map/unit_testers/test_mod.F90 deleted file mode 100644 index 967eee1c89..0000000000 --- a/tools/mksurfdata_map/unit_testers/test_mod.F90 +++ /dev/null @@ -1,339 +0,0 @@ -module test_mod - -use shr_kind_mod, only : SHR_KIND_R8 -use shr_sys_mod, only : shr_sys_abort - -implicit none - -public test_init -public test_is -public test_close -public test_final - -integer, save :: ntests = 0 -integer, save :: npass = 0 -integer, save :: num_expected = 0 -logical, save :: num_expected_given = .false. -character(*), parameter :: formatTest = '(A4, " ", i5.5, " - ", A)' -character(*), parameter :: formatArrayMatch = & - '(" (all ", i5, " values match)")' -character(*), parameter :: formatArray2DMatch = & - '(" (all ", i5, "x", i5, " values match)")' -character(*), parameter :: formatArrayMisMatch = & - '(" (only ", i5, " values of ", i5, " values match)")' -character(*), parameter :: formatArray2DMisMatch = & - '(" (only ", i5, " values of ", i5, "x", i5, " values match)")' -character(*), parameter :: formatRArrayClose = & - '(" (all ", i5, " values are within", 1pe9.1e2, " )")' -character(*), parameter :: formatRArrayNotClose = & - '(" (only ", i5, " values of ", i5, " values are within", 1pe9.1e2, " max diff= ", 1pe9.1e2, ")")' -character(*), parameter :: formatRClose = & - '(" ( value within", 1pe9.1e2, " )")' -character(*), parameter :: formatRNotClose = & - '(" ( value within", 1pe9.1e2, " diff= ", 1pe9.1e2, ")")' - -interface test_is - module procedure test_is_logical - module procedure test_is_logical1D - module procedure test_is_string - module procedure test_is_integer - module procedure test_is_integer1D - module procedure test_is_real1D - module procedure test_is_real2D - module procedure test_is_realScalar -end interface test_is - -interface test_close - module procedure test_close_real1D - module procedure test_close_realScalar -end interface test_close - -private test_is_logical -private test_is_string -private test_is_integer -private test_is_integer1D -private test_is_real1D -private test_is_realScalar -private test_close_real1D - -contains - - -subroutine test_init( num_expected_tests ) - integer, intent(IN), optional :: num_expected_tests - - if ( present(num_expected_tests) ) then - num_expected = num_expected_tests - num_expected_given = .true. - write(*,formatTest) "1...", num_expected, "expected tests" - write(*,*) - end if - -end subroutine test_init - -subroutine test_is_logical( pass, description ) - - implicit none - - logical, intent(IN) :: pass ! If matches or not - character(*), intent(IN) :: description ! description of test - - character(4) :: status - - ntests = ntests + 1 - if ( pass )then - npass = npass + 1 - status = "PASS" - else - status = "FAIL" - end if - write(*,formatTest) status, ntests, trim(description) - -end subroutine test_is_logical - -subroutine test_is_logical1D( value, expected, description ) - - implicit none - - logical, intent(IN) :: value(:) ! test value - logical, intent(IN) :: expected(:) ! expected value - character(*), intent(IN) :: description ! description of test - - logical :: pass - integer :: nsize, nmatch - character(256) :: descrip - - nsize = size(value) - if ( all(value .eqv. expected) )then - pass = .true. - write(descrip,formatArrayMatch) nsize - else - nmatch = count(value .eqv. expected) - write(descrip,formatArrayMisMatch) nmatch, nsize - pass = .false. - end if - call test_is_logical( pass, trim(description)//trim(descrip) ) - -end subroutine test_is_logical1D - - -subroutine test_is_string( value, expected, description ) - - implicit none - - character(len=*), intent(IN) :: value - character(len=*), intent(IN) :: expected - character(len=*), intent(IN) :: description ! description of test - - - logical :: pass ! If matches or not - - character(4) :: status - - if ( trim(value) == trim(expected) )then - pass = .true. - else - pass = .false. - end if - ntests = ntests + 1 - if ( pass )then - npass = npass + 1 - status = "PASS" - else - status = "FAIL" - end if - write(*,formatTest) status, ntests, trim(description) - -end subroutine test_is_string - -subroutine test_is_integer( value, expected, description ) - integer, intent(IN) :: value ! test value - integer, intent(IN) :: expected ! expected value - character(*), intent(IN) :: description ! description of test - - logical :: pass - - if ( value == expected )then - pass = .true. - else - pass = .false. - end if - call test_is_logical( pass, description ) - -end subroutine test_is_integer - -subroutine test_is_integer1D( value, expected, description ) - integer, intent(IN) :: value(:) ! test value - integer, intent(IN) :: expected(:) ! expected value - character(*), intent(IN) :: description ! description of test - - logical :: pass - integer :: nsize, nmatch - character(256) :: descrip - - nsize = size(value) - if ( all(value == expected) )then - pass = .true. - write(descrip,formatArrayMatch) nsize - else - nmatch = count(value == expected) - write(descrip,formatArrayMisMatch) nmatch, nsize - pass = .false. - end if - call test_is_logical( pass, trim(description)//trim(descrip) ) - -end subroutine test_is_integer1D - -subroutine test_is_real1D( value, expected, description ) - real(SHR_KIND_R8), intent(IN) :: value(:) ! test value - real(SHR_KIND_R8), intent(IN) :: expected(:) ! expected value - character(*), intent(IN) :: description ! description of test - - logical :: pass - integer :: nsize, nmatch - character(256) :: descrip - - nsize = size(value) - if ( all(value == expected) )then - pass = .true. - write(descrip,formatArrayMatch) nsize - else - nmatch = count(value == expected) - write(descrip,formatArrayMisMatch) nmatch, nsize - pass = .false. - end if - call test_is_logical( pass, trim(description)//trim(descrip) ) - -end subroutine test_is_real1D - -subroutine test_is_real2D( value, expected, description ) - real(SHR_KIND_R8), intent(IN) :: value(:,:) ! test value - real(SHR_KIND_R8), intent(IN) :: expected(:,:) ! expected value - character(*), intent(IN) :: description ! description of test - - logical :: pass - integer :: nsize1, nsize2, nmatch - character(256) :: descrip - - nsize1 = size(value,1) - nsize2 = size(value,2) - if ( all(value == expected) )then - pass = .true. - write(descrip,formatArray2DMatch) nsize1, nsize2 - else - nmatch = count(value == expected) - write(descrip,formatArray2DMisMatch) nmatch, nsize1, nsize2 - pass = .false. - end if - call test_is_logical( pass, trim(description)//trim(descrip) ) - -end subroutine test_is_real2D - -subroutine test_is_realScalar( value, expected, description ) - real(SHR_KIND_R8), intent(IN) :: value ! test value - real(SHR_KIND_R8), intent(IN) :: expected ! expected value - character(*), intent(IN) :: description ! description of test - - logical :: pass - - if ( value == expected )then - pass = .true. - else - pass = .false. - end if - call test_is_logical( pass, description ) - -end subroutine test_is_realScalar - -subroutine test_close_real1D( value, expected, eps, description, rel_diff ) - real(SHR_KIND_R8), intent(IN) :: value(:) ! test value - real(SHR_KIND_R8), intent(IN) :: expected(:) ! expected value - real(SHR_KIND_R8), intent(IN) :: eps ! epsilon -- how close to be within - character(*), intent(IN) :: description ! description of test - logical, optional, intent(IN) :: rel_diff ! if should do relative difference or not - - logical :: pass, lreldiff - integer :: nsize, nmatch, i, n0(1), nf(1) - real(SHR_KIND_R8) :: within, diff - character(256) :: descrip - - lreldiff = .false. - if ( present(rel_diff) ) lreldiff = rel_diff - nsize = size(value) - if ( nsize /= size(expected) )then - call shr_sys_abort( "size of value and expected array is different" ) - end if - if ( any(lbound(value) /= lbound(expected)) )then - call shr_sys_abort( "lower bound of value and expected array is different" ) - end if - nmatch = 0 - n0 = lbound(value) - nf = ubound(value) - within = abs(value(n0(1)) - expected(n0(1))) - if ( lreldiff .and. within > 0.0_SHR_KIND_R8 ) within = within / max( abs(value(n0(1))), abs(expected(n0(1))) ) - do i = n0(1), nf(1) - diff = abs(value(i) - expected(i)) - if ( lreldiff .and. diff > 0.0_SHR_KIND_R8 ) diff = diff / max(abs(value(i)),abs(expected(i)) ) - within = max( within, diff ) - if ( diff <= eps ) nmatch = nmatch + 1 - end do - if( nmatch == nsize )then - write(descrip,formatRArrayClose) nsize, eps - pass = .true. - else - write(descrip,formatRArrayNotClose) nmatch, nsize, eps, within - pass = .false. - end if - call test_is_logical( pass, trim(description)//trim(descrip) ) - -end subroutine test_close_real1D - -subroutine test_close_realScalar( value, expected, eps, description ) - real(SHR_KIND_R8), intent(IN) :: value ! test value - real(SHR_KIND_R8), intent(IN) :: expected ! expected value - real(SHR_KIND_R8), intent(IN) :: eps ! epsilon -- how close to be within - character(*), intent(IN) :: description ! description of test - - logical :: pass - real(SHR_KIND_R8) :: diff - character(256) :: descrip - - diff = abs(value - expected) - if ( diff <= eps ) then - write(descrip,formatRClose) eps - pass = .true. - else - write(descrip,formatRNotClose) eps, diff - pass = .false. - end if - call test_is_logical( pass, trim(description)//trim(descrip) ) - -end subroutine test_close_realScalar - -subroutine test_final( PassStatus ) - - logical, intent(OUT), optional :: PassStatus - - character(4) :: status - character(50) :: desc - - write(*,*) - status = "PASS" - if ( present(PassStatus) ) PassStatus = .true. - desc = "All expected tests ran successfully" - if ( num_expected_given .and. ntests /= num_expected )then - status = "FAIL" - desc = "Different number of tests than expected" - if ( present(PassStatus) ) PassStatus = .false. - end if - if ( npass /= ntests )then - status = "FAIL" - if ( present(PassStatus) ) PassStatus = .false. - write(desc,'(A,i3,A)') "Not all tests passed (", & - ntests-npass, " tests failed)" - end if - write(*,formatTest) status, ntests, "tests run -- "//desc - -end subroutine test_final - -end module test_mod From 474cd9502c8d0e45237f4554a6e049cc9fc05110 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 21 Apr 2022 13:27:08 -0600 Subject: [PATCH 140/614] moved soiltexnewMod.F90 to soiltexMod.F90 --- tools/mksurfdata_esmf/src/CMakeLists.txt | 1 - tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 370 ++++++++-------- tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 | 409 ------------------ tools/mksurfdata_esmf/src/mksurfdata.F90 | 8 +- 4 files changed, 190 insertions(+), 598 deletions(-) delete mode 100644 tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 26c3853338..597dadaf9e 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -40,7 +40,6 @@ set(SRCFILES mkagfirepkmonthMod.F90 mksoilcolMod.F90 mksoilfmaxMod.F90 mksoiltexMod.F90 - mksoiltexnewMod.F90 mksoildepthMod.F90 mktopostatsMod.F90 mkurbanparMod.F90 diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 04e68c60d0..0d6810df8b 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -33,25 +33,26 @@ module mksoiltexMod contains !================================================================================= - subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc) + subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o, pctlnd_pft_o, rc) ! ! make %sand and %clay from IGBP soil data, which includes ! igbp soil 'mapunits' and their corresponding textures ! ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh + character(len=*) , intent(in) :: file_mesh_i ! input mesh/grid file name + character(len=*) , intent(in) :: file_mapunit_i ! input mapunit file name + character(len=*) , intent(in) :: file_lookup_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh type(file_desc_t) , intent(inout) :: pioid_o real(r8) , intent(in) :: pctlnd_pft_o(:) ! PFT data: % of gridcell for PFTs integer , intent(out) :: rc ! local variables type(ESMF_RouteHandle) :: routehandle + type(ESMF_Grid) :: grid_i type(ESMF_Mesh) :: mesh_i type(ESMF_Field) :: field_i type(ESMF_Field) :: field_o - type(ESMF_Field) :: field_dstfrac type(file_desc_t) :: pioid_i type(var_desc_t) :: pio_varid integer :: pio_vartype @@ -59,27 +60,28 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc integer :: ni,no integer :: ns_i, ns_o integer :: k,l,m,n - integer :: nlay ! number of soil layers + integer :: nlay ! number of soil layers + integer :: n_scid integer , allocatable :: mask_i(:) - real(r4), allocatable :: rmask_i(:) - real(r8), allocatable :: frac_o(:) - real(r4), allocatable :: sand_i(:,:) ! input grid: percent sand - real(r4), allocatable :: clay_i(:,:) ! input grid: percent clay - real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits - real(r8), allocatable :: sand_o(:,:) ! % sand (output grid) - real(r8), allocatable :: clay_o(:,:) ! % clay (output grid) - integer , allocatable :: mapunit_o(:) real(r4), pointer :: dataptr(:) - real(r8), pointer :: dataptr_r8(:) - real(r4) :: sumtex - integer :: mapunit ! temporary igbp soil mapunit - integer, allocatable :: soil_i(:) - integer, allocatable :: soil_o(:) - integer :: rcode, ier ! error status + integer :: mapunit ! temporary igbp soil mapunit + integer, allocatable :: sand_i(:,:,:) ! input grid: percent sand + integer, allocatable :: clay_i(:,:,:) ! input grid: percent clay + real(r4), allocatable :: sand_o(:,:) ! % sand (output grid) + real(r4), allocatable :: clay_o(:,:) ! % clay (output grid) + integer :: n_mapunits + integer :: lookup_index + integer :: SCID + real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits + integer , allocatable :: mapunit_o(:) ! output grid: igbp soil mapunits + integer , allocatable :: MapUnits(:) + integer , allocatable :: mapunit_lookup(:) + type(var_desc_t) :: pio_varid_sand + type(var_desc_t) :: pio_varid_clay + integer :: starts(3) ! starting indices for reading lookup table + integer :: counts(3) ! dimension counts for reading lookup table integer :: srcTermProcessing_Value = 0 - integer, parameter :: nlsm=4 ! number of soil textures - character(len=38) :: soil(0:nlsm) ! name of each soil texture - character(len=38) :: typ ! soil texture based on ... + integer :: rcode, ier ! error status character(len=*), parameter :: subname = 'mksoiltex' !----------------------------------------------------------------------- @@ -88,8 +90,9 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to make %sand and %clay .....' - write(ndiag,'(a)') ' Input file is '//trim(file_data_i) - write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) + write(ndiag,'(a)') ' Input mapunit file is '//trim(file_mapunit_i) + write(ndiag,'(a)') ' Input lookup table file is '//trim(file_lookup_i) + write(ndiag,'(a)') ' Input mesh/grid file is '//trim(file_mesh_i) end if ! Determine ns_o and allocate output data @@ -99,228 +102,232 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc allocate(sand_o(ns_o,nlevsoi)) ; sand_o(:,:) = spval allocate(clay_o(ns_o,nlevsoi)) ; clay_o(:,:) = spval - ! Open input data file - call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_data_i)) - rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) - - ! Read in input mesh - call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) - mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + !--------------------------------- + ! Determine mapunits on output grid + !--------------------------------- + + ! Determine input mesh + if (trim(file_mesh_i) == trim(file_mapunit_i)) then + ! input format is GRIDSPEC and read in grid and then create mesh + if (root_task) write(ndiag,*)"reading grid_i and then creating mesh_i in "//trim(subname) + call ESMF_VMLogMemInfo("Before create read in grid_i in "//trim(subname)) + grid_i = ESMF_GridCreate(filename=trim(file_mesh_i), & + fileformat=ESMF_FILEFORMAT_GRIDSPEC, addCornerStagger=.true., addmask=.true., varname='MU', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) + mesh_i = esmf_meshcreate(grid_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + else + ! Read in mesh directly + if (root_task) write(ndiag,*)"reading mesh_i directly in "//trim(subname) + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if - ! Determine ns_i + ! Determine ns_i (use the distgrid to the number of elements) call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Get the landmask from the file and reset the mesh mask based on that - allocate(rmask_i(ns_i), stat=ier) + ! Read in mapunit data + if (root_task) write(ndiag,*)"Reading in mapunit data in "//trim(subname) + call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_mapunit_i)) + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_mapunit_i), pio_nowrite) + allocate(mapunit_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid_i, 'MU', mesh_i, mapunit_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) + call pio_closefile(pioid_i) + + ! Set mesh mask to zero where the mapunit values are 0 + if (root_task) write(ndiag,*)"Setting mask in mesh where mapunit data is 0 "//trim(subname) allocate(mask_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return do ni = 1,ns_i - if (rmask_i(ni) > 0._r4) then - mask_i(ni) = 1 - else + if (mapunit_i(ni) == 0.) then mask_i(ni) = 0 end if end do call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Read in mapunit data - allocate(mapunit_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid_i, 'MAPUNITS', mesh_i, mapunit_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - - ! Set mapunit values to zero where the input mask is 0 - do ni = 1,ns_i - mapunit_i(ni) = mapunit_i(ni) * mask_i(ni) - end do - - ! Determine mapunit_value_max (set it as a module variable so that it can be - ! accessible to gen_dominant_mapunit) - rcode = pio_inq_dimid (pioid_i, 'max_value_mapunit', dimid) - rcode = pio_inq_dimlen (pioid_i, dimid, mapunit_value_max) - ! Create ESMF fields that will be used below field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - field_dstfrac = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle + if (root_task) write(ndiag,*)" before route handle creation "//trim(subname) call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & - ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & - dstFracField= field_dstfrac, rc=rc) + ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - - ! Determin frac_o - call ESMF_FieldGet(field_dstfrac, farrayptr=dataptr_r8, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(frac_o(ns_o)) - frac_o(:) = dataptr_r8(:) + if (root_task) write(ndiag,*)" after route handle creation "//trim(subname) ! Create a dynamic mask object ! The dynamic mask object further holds a pointer to the routine that will be called in order to ! handle dynamically masked elements - in this case its DynMaskProc (see below) + if (root_task) write(ndiag,*)" before call to dynamic mask set creation "//trim(subname) call ESMF_DynamicMaskSetR4R8R4(dynamicMask, dynamicMaskRoutine=get_dominant_mapunit, & handleAllElements=.true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (root_task) write(ndiag,*)" after call to dynamic mask set creation "//trim(subname) - ! Determine dominant soil color in the field regrid call below + ! Determine values in field_i call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) dataptr(:) = real(mapunit_i(:), kind=r4) + + ! Determine mapunit_value_max (set it as a module variable so that it can be + ! accessible to gen_dominant_mapunit) - this is needed in the dynamic mask routine + mapunit_value_max = maxval(dataptr) + + ! Determine values in field_o call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:) = 0._r4 + ! Determine mapunit_o call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, dynamicMask=dynamicMask, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do no = 1,ns_o mapunit_o(no) = int(dataptr(no)) end do - ! Get dimensions from input file and allocate memory for sand_i and clay_i - rcode = pio_inq_dimid (pioid_i, 'number_of_layers', dimid) + do no = 1,ns_o + if (mapunit_o(no) > mapunit_value_max) then + write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) + ! call shr_sys_abort("mapunit_o is out of bounds") + end if + end do + + ! Write out mapunit_o + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out mapunits " + call mkfile_output(pioid_o, mesh_o, 'mapunits', mapunit_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') + call pio_syncfile(pioid_o) + + !--------------------------------- + ! Determine %sand and %clay on output grid - using above mapunits + !--------------------------------- + + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_lookup_i), pio_nowrite) + + rcode = pio_inq_dimid (pioid_i, 'MapUnit', dimid) + rcode = pio_inq_dimlen (pioid_i, dimid, n_mapunits) + + rcode = pio_inq_dimid (pioid_i, 'soil_layer', dimid) rcode = pio_inq_dimlen (pioid_i, dimid, nlay) - allocate(sand_i(mapunit_value_max,nlay), stat=ier) + + rcode = pio_inq_dimid (pioid_i, 'SCID', dimid) + rcode = pio_inq_dimlen (pioid_i, dimid, n_scid) + + ! Read In MapUnits from the input file + allocate(MapUnits(n_mapunits), stat=ier) + rcode = pio_inq_varid(pioid_i, 'MapUnit', pio_varid) + rcode = pio_get_var(pioid_i, pio_varid, MapUnits) + + ! Determine the mapunit lookup index from the value of the MapUnit variable + mapunit_value_max = maxval(MapUnits) + allocate(mapunit_lookup(mapunit_value_max)) + mapunit_lookup(:) = -999 + do n = 1,size(MapUnits) + mapunit_lookup(MapUnits(n)) = n + end do + + allocate(sand_i(nlay,n_scid,n_mapunits)) if (ier/=0) call shr_sys_abort() - allocate(clay_i(mapunit_value_max,nlay), stat=ier) + allocate(clay_i(nlay,n_scid,n_mapunits)) if (ier/=0) call shr_sys_abort() - ! read in sand_i and clay_i (they will read in total on all processors) - rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid) - rcode = pio_get_var(pioid_i, pio_varid, sand_i) - rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid) - rcode = pio_get_var(pioid_i, pio_varid, clay_i) + ! Get dimensions from input file and allocate memory for sand_i and clay_i + rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid_sand) + rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid_clay) - ! Set soil texture as follows: - ! a. Use dominant igbp soil mapunit based on area of overlap unless 'no data' is dominant - ! b. If this has no data, use loam for soil texture + rcode = pio_get_var(pioid_i, pio_varid_sand, sand_i) + rcode = pio_get_var(pioid_i, pio_varid_clay, clay_i) do no = 1,ns_o - if (mapunit_o(no) > 0) then - ! valid value is obtained - if (mapunit_o(no) > mapunit_value_max) then - write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) - ! call shr_sys_abort("mapunit_o is out of bounds") - end if - do l = 1, nlay - sand_o(no,l) = sand_i(mapunit_o(no),l) - clay_o(no,l) = clay_i(mapunit_o(no),l) - end do + + if (pctlnd_pft_o(no) < 1.e-6_r8 .or. mapunit_o(no) == 0) then + + ! Adjust sand and clay be loam if pctlnd_pft is < 1.e-6 or mapunit is 0 + sand_o(no,:) = 43._r4 + clay_o(no,:) = 18._r4 + else - ! use loam - do l = 1, nlay - sand_o(no,l) = 43. - clay_o(no,l) = 18. - end do - end if - end do - ! Define the model surface types: 0:4 - soil(0) = 'no soil: ocean, glacier, lake, no data' - soil(1) = 'clays ' - soil(2) = 'sands ' - soil(3) = 'loams ' - soil(4) = 'silts ' - - ! input grid: determine soil_i for global area comparison - allocate(soil_i(ns_i)) - do l = 1, nlay - do ni = 1,ns_i - mapunit = nint(mapunit_i(ni)) - if (mapunit==0) then - typ = 'no soil: ocean, glacier, lake, no data' - else if (clay_i(mapunit,l) >= 40.) then - typ = 'clays' - else if (sand_i(mapunit,l) >= 50.) then - typ = 'sands' - else if (clay_i(mapunit,l)+sand_i(mapunit,l) < 50.) then - if (rmask_i(ni) /= 0.) then - typ = 'silts' + ! Determine lookup_index + lookup_index = mapunit_lookup(mapunit_o(no)) + + ! Determine the top soil layer sand_o and clay_o + ! If its less than 0 search within the SCID array for the first index + ! that gives a pct sand that is greater than or equal to 0 + ! Then determine the other soil layers sand_o + sand_o(no,1) = float(sand_i(1,1,lookup_index)) + if (sand_o(no,1) < 0.) then + do l = 2,n_scid + if (float(sand_i(1,l,lookup_index)) >= 0.) then + sand_o(no,1) = float(sand_i(1,l,lookup_index)) + exit + end if + end do + end if + if (sand_o(no,1) < 0.) then + if (int(sand_o(no,1)) == -4) then + write(6,'(a,i8)')'WARNING: changing sand_o from -4 to 99% at no = ',no + sand_o(no,:) = 99._r4 else - typ = 'no soil: ocean, glacier, lake, no data' + write(6,'(a,i8,a,i8)')'WARNING: changing sand_o from ',int(sand_o(no,1)),' to 43 at no = ',no + sand_o(no,:) = 43._r4 end if - else - typ = 'loams' end if - do m = 0, nlsm - if (typ == soil(m)) go to 101 + do l = 2,nlay + sand_o(no,l) = float(sand_i(l,1,lookup_index)) + if (sand_o(no,l) < 0. .and. l > 1) then + sand_o(no,l) = sand_o(no,l-1) + end if end do - write (6,*) 'MKSOILTEX error: sand = ',sand_i(mapunit,l), & - ' clay = ',clay_i(mapunit,l),' not assigned to soil type for input grid lon,lat,layer = ',ni,l - call shr_sys_abort() -101 continue - soil_i(ni) = m ! allocate memory for this - end do - end do - ! output grid: determine soil_o for global area comparison - allocate(soil_o(ns_o)) - do l = 1, nlay - do no = 1,ns_o - if (clay_o(no,l)==0. .and. sand_o(no,l)==0.) then - typ = 'no soil: ocean, glacier, lake, no data' - else if (clay_o(no,l) >= 40.) then - typ = 'clays' - else if (sand_o(no,l) >= 50.) then - typ = 'sands' - else if (clay_o(no,l)+sand_o(no,l) < 50.) then - typ = 'silts' - else - typ = 'loams' + ! If its less than 0 search within the SCID array for the first index + ! that gives a pct clay that is greater than or equal to 0 + ! Now determine the other soil layers clay_o + clay_o(no,1) = float(clay_i(1,1,lookup_index)) + if (clay_o(no,1) < 0.) then + do l = 2,n_scid + if (float(clay_i(1,l,lookup_index)) >= 0.) then + clay_o(no,1) = float(clay_i(1,l,lookup_index)) + exit + end if + end do end if - do m = 0, nlsm - if (typ == soil(m)) go to 102 + if (clay_o(no,1) < 0.) then + if (int(clay_o(no,1)) == -4) then + write(6,'(a,i8)')'WARNING: changing clay_o from -4 to 1% at no = ',no + clay_o(no,:) = 1._r4 + else + write(6,'(a,i8,a,i8)')'WARNING: changing clay_o from ',int(clay_o(no,1)),' to 18 at no = ',no + clay_o(no,:) = 18._r4 + end if + end if + if (clay_o(no,1) < 0.) then + write(6,*)'ERROR: at no, lookup_index = ',no,lookup_index + call shr_sys_abort('could not find a value >= 0 for clay_i') + end if + do l = 2,nlay + clay_o(no,l) = float(clay_i(l,1,lookup_index)) + if (clay_o(no,l) < 0. .and. l > 1) then + clay_o(no,l) = clay_o(no,l-1) + end if end do - write (6,*) 'MKSOILTEX error: sand = ',sand_o(no,l), & - ' clay = ',clay_o(no,l), ' not assigned to soil type for output grid lon,lat,layer = ',no,l - call shr_sys_abort() -102 continue - soil_o(no) = m - end do - end do - ! Compare global areas - if (root_task) then - write (ndiag,'(a)') 'The following table of soil texture classes is for comparison only.' - write (ndiag,'(a)') 'The actual data is continuous %sand, %silt and %clay not textural classes' - end if - call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & - 0, nlsm, soil_i, soil_o, 'soil texture class', ndiag, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Adjust pct sand and pct clay to be nearest integers and to be loam if pctlnd_pft is < 1.e-6 - ! Truncate all percentage fields on output grid. This is needed to insure that wt is zero - ! (not a very small number such as 1e-16) where it really should be zero - do no = 1,ns_o - do k = 1,nlevsoi - sand_o(no,k) = float(nint(sand_o(no,k))) - clay_o(no,k) = float(nint(clay_o(no,k))) - end do - if (pctlnd_pft_o(no) < 1.e-6_r8) then - sand_o(no,:) = 43._r8 - clay_o(no,:) = 18._r8 end if - end do - ! Write out fields - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" - call mkfile_output(pioid_o, mesh_o, 'mapunits', mapunit_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') + end do if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) @@ -329,6 +336,7 @@ subroutine mksoiltex(file_mesh_i, file_data_i, mesh_o, pioid_o, pctlnd_pft_o, rc if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) ! Release memory diff --git a/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 deleted file mode 100644 index f44cbb181f..0000000000 --- a/tools/mksurfdata_esmf/src/mksoiltexnewMod.F90 +++ /dev/null @@ -1,409 +0,0 @@ -module mksoiltexnewMod - - !----------------------------------------------------------------------- - ! Make soil data (texture) - !----------------------------------------------------------------------- - - use ESMF - use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4=>shr_kind_r4 - use shr_sys_mod , only : shr_sys_abort - use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths - use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkutilsMod , only : chkerr - use mkdiagnosticsMod , only : output_diagnostics_index - use mkfileMod , only : mkfile_output - use mkvarctl , only : root_task, ndiag, spval - use mkvarctl , only : unsetsoil - use mkvarpar , only : nlevsoi - - implicit none - private ! By default make data private - - public :: mksoiltexnew ! Set soil texture - - integer :: mapunit_value_max - integer :: num_soil_textures - type(ESMF_DynamicMask) :: dynamicMask - - character(len=*) , parameter :: u_FILE_u = & - __FILE__ - -!================================================================================= -contains -!================================================================================= - - subroutine mksoiltexnew(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o, pctlnd_pft_o, rc) - ! - ! make %sand and %clay from IGBP soil data, which includes - ! igbp soil 'mapunits' and their corresponding textures - ! - ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh/grid file name - character(len=*) , intent(in) :: file_mapunit_i ! input mapunit file name - character(len=*) , intent(in) :: file_lookup_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh - type(file_desc_t) , intent(inout) :: pioid_o - real(r8) , intent(in) :: pctlnd_pft_o(:) ! PFT data: % of gridcell for PFTs - integer , intent(out) :: rc - - ! local variables - type(ESMF_RouteHandle) :: routehandle - type(ESMF_Grid) :: grid_i - type(ESMF_Mesh) :: mesh_i - type(ESMF_Field) :: field_i - type(ESMF_Field) :: field_o - type(file_desc_t) :: pioid_i - type(var_desc_t) :: pio_varid - integer :: pio_vartype - integer :: dimid - integer :: ni,no - integer :: ns_i, ns_o - integer :: k,l,m,n - integer :: nlay ! number of soil layers - integer :: n_scid - integer , allocatable :: mask_i(:) - real(r4), pointer :: dataptr(:) - integer :: mapunit ! temporary igbp soil mapunit - integer, allocatable :: sand_i(:,:,:) ! input grid: percent sand - integer, allocatable :: clay_i(:,:,:) ! input grid: percent clay - real(r4), allocatable :: sand_o(:,:) ! % sand (output grid) - real(r4), allocatable :: clay_o(:,:) ! % clay (output grid) - integer :: n_mapunits - integer :: lookup_index - integer :: SCID - real(r4), allocatable :: mapunit_i(:) ! input grid: igbp soil mapunits - integer , allocatable :: mapunit_o(:) ! output grid: igbp soil mapunits - integer , allocatable :: MapUnits(:) - integer , allocatable :: mapunit_lookup(:) - type(var_desc_t) :: pio_varid_sand - type(var_desc_t) :: pio_varid_clay - integer :: starts(3) ! starting indices for reading lookup table - integer :: counts(3) ! dimension counts for reading lookup table - integer :: srcTermProcessing_Value = 0 - integer :: rcode, ier ! error status - character(len=*), parameter :: subname = 'mksoiltexnew' - !----------------------------------------------------------------------- - - if (root_task) then - write(ndiag,*) - write(ndiag,'(1x,80a1)') ('=',k=1,80) - write(ndiag,*) - write(ndiag,'(a)') 'Attempting to make %sand and %clay .....' - write(ndiag,'(a)') ' Input mapunit file is '//trim(file_mapunit_i) - write(ndiag,'(a)') ' Input lookup table file is '//trim(file_lookup_i) - write(ndiag,'(a)') ' Input mesh/grid file is '//trim(file_mesh_i) - end if - - ! Determine ns_o and allocate output data - call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(mapunit_o(ns_o)) ; mapunit_o(:) = 0 - allocate(sand_o(ns_o,nlevsoi)) ; sand_o(:,:) = spval - allocate(clay_o(ns_o,nlevsoi)) ; clay_o(:,:) = spval - - !--------------------------------- - ! Determine mapunits on output grid - !--------------------------------- - - ! Determine input mesh - if (trim(file_mesh_i) == trim(file_mapunit_i)) then - ! input format is GRIDSPEC and read in grid and then create mesh - if (root_task) write(ndiag,*)"reading grid_i and then creating mesh_i in "//trim(subname) - call ESMF_VMLogMemInfo("Before create read in grid_i in "//trim(subname)) - grid_i = ESMF_GridCreate(filename=trim(file_mesh_i), & - fileformat=ESMF_FILEFORMAT_GRIDSPEC, addCornerStagger=.true., addmask=.true., varname='MU', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) - mesh_i = esmf_meshcreate(grid_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - else - ! Read in mesh directly - if (root_task) write(ndiag,*)"reading mesh_i directly in "//trim(subname) - mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - ! Determine ns_i (use the distgrid to the number of elements) - call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Read in mapunit data - if (root_task) write(ndiag,*)"Reading in mapunit data in "//trim(subname) - call ESMF_VMLogMemInfo("Before pio_openfile for "//trim(file_mapunit_i)) - rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_mapunit_i), pio_nowrite) - allocate(mapunit_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid_i, 'MU', mesh_i, mapunit_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - call pio_closefile(pioid_i) - - ! Set mesh mask to zero where the mapunit values are 0 - if (root_task) write(ndiag,*)"Setting mask in mesh where mapunit data is 0 "//trim(subname) - allocate(mask_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - do ni = 1,ns_i - if (mapunit_i(ni) == 0.) then - mask_i(ni) = 0 - end if - end do - call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Create ESMF fields that will be used below - field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R4, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Create a route handle - if (root_task) write(ndiag,*)" before route handle creation "//trim(subname) - call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, srcTermProcessing=srcTermProcessing_Value, & - ignoreDegenerate=.true., unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - if (root_task) write(ndiag,*)" after route handle creation "//trim(subname) - - ! Create a dynamic mask object - ! The dynamic mask object further holds a pointer to the routine that will be called in order to - ! handle dynamically masked elements - in this case its DynMaskProc (see below) - if (root_task) write(ndiag,*)" before call to dynamic mask set creation "//trim(subname) - call ESMF_DynamicMaskSetR4R8R4(dynamicMask, dynamicMaskRoutine=get_dominant_mapunit, & - handleAllElements=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (root_task) write(ndiag,*)" after call to dynamic mask set creation "//trim(subname) - - ! Determine values in field_i - call ESMF_FieldGet(field_i, farrayptr=dataptr, rc=rc) - dataptr(:) = real(mapunit_i(:), kind=r4) - - ! Determine mapunit_value_max (set it as a module variable so that it can be - ! accessible to gen_dominant_mapunit) - this is needed in the dynamic mask routine - mapunit_value_max = maxval(dataptr) - - ! Determine values in field_o - call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr(:) = 0._r4 - - ! Determine mapunit_o - call ESMF_FieldRegrid(field_i, field_o, routehandle=routehandle, dynamicMask=dynamicMask, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_o, farrayptr=dataptr, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do no = 1,ns_o - mapunit_o(no) = int(dataptr(no)) - end do - - do no = 1,ns_o - if (mapunit_o(no) > mapunit_value_max) then - write(6,*)'mapunit_o is out of bounds ',mapunit_o(no) - ! call shr_sys_abort("mapunit_o is out of bounds") - end if - end do - - ! Write out mapunit_o - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out mapunits " - call mkfile_output(pioid_o, mesh_o, 'mapunits', mapunit_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') - call pio_syncfile(pioid_o) - - !--------------------------------- - ! Determine %sand and %clay on output grid - using above mapunits - !--------------------------------- - - rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_lookup_i), pio_nowrite) - - rcode = pio_inq_dimid (pioid_i, 'MapUnit', dimid) - rcode = pio_inq_dimlen (pioid_i, dimid, n_mapunits) - - rcode = pio_inq_dimid (pioid_i, 'soil_layer', dimid) - rcode = pio_inq_dimlen (pioid_i, dimid, nlay) - - rcode = pio_inq_dimid (pioid_i, 'SCID', dimid) - rcode = pio_inq_dimlen (pioid_i, dimid, n_scid) - - ! Read In MapUnits from the input file - allocate(MapUnits(n_mapunits), stat=ier) - rcode = pio_inq_varid(pioid_i, 'MapUnit', pio_varid) - rcode = pio_get_var(pioid_i, pio_varid, MapUnits) - - ! Determine the mapunit lookup index from the value of the MapUnit variable - mapunit_value_max = maxval(MapUnits) - allocate(mapunit_lookup(mapunit_value_max)) - mapunit_lookup(:) = -999 - do n = 1,size(MapUnits) - mapunit_lookup(MapUnits(n)) = n - end do - - allocate(sand_i(nlay,n_scid,n_mapunits)) - if (ier/=0) call shr_sys_abort() - allocate(clay_i(nlay,n_scid,n_mapunits)) - if (ier/=0) call shr_sys_abort() - - ! Get dimensions from input file and allocate memory for sand_i and clay_i - rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid_sand) - rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid_clay) - - rcode = pio_get_var(pioid_i, pio_varid_sand, sand_i) - rcode = pio_get_var(pioid_i, pio_varid_clay, clay_i) - - do no = 1,ns_o - - if (pctlnd_pft_o(no) < 1.e-6_r8 .or. mapunit_o(no) == 0) then - - ! Adjust sand and clay be loam if pctlnd_pft is < 1.e-6 or mapunit is 0 - sand_o(no,:) = 43._r4 - clay_o(no,:) = 18._r4 - - else - - ! Determine lookup_index - lookup_index = mapunit_lookup(mapunit_o(no)) - - ! Determine the top soil layer sand_o and clay_o - ! If its less than 0 search within the SCID array for the first index - ! that gives a pct sand that is greater than or equal to 0 - ! Then determine the other soil layers sand_o - sand_o(no,1) = float(sand_i(1,1,lookup_index)) - if (sand_o(no,1) < 0.) then - do l = 2,n_scid - if (float(sand_i(1,l,lookup_index)) >= 0.) then - sand_o(no,1) = float(sand_i(1,l,lookup_index)) - exit - end if - end do - end if - if (sand_o(no,1) < 0.) then - if (int(sand_o(no,1)) == -4) then - write(6,'(a,i8)')'WARNING: changing sand_o from -4 to 99% at no = ',no - sand_o(no,:) = 99._r4 - else - write(6,'(a,i8,a,i8)')'WARNING: changing sand_o from ',int(sand_o(no,1)),' to 43 at no = ',no - sand_o(no,:) = 43._r4 - end if - end if - do l = 2,nlay - sand_o(no,l) = float(sand_i(l,1,lookup_index)) - if (sand_o(no,l) < 0. .and. l > 1) then - sand_o(no,l) = sand_o(no,l-1) - end if - end do - - ! If its less than 0 search within the SCID array for the first index - ! that gives a pct clay that is greater than or equal to 0 - ! Now determine the other soil layers clay_o - clay_o(no,1) = float(clay_i(1,1,lookup_index)) - if (clay_o(no,1) < 0.) then - do l = 2,n_scid - if (float(clay_i(1,l,lookup_index)) >= 0.) then - clay_o(no,1) = float(clay_i(1,l,lookup_index)) - exit - end if - end do - end if - if (clay_o(no,1) < 0.) then - if (int(clay_o(no,1)) == -4) then - write(6,'(a,i8)')'WARNING: changing clay_o from -4 to 1% at no = ',no - clay_o(no,:) = 1._r4 - else - write(6,'(a,i8,a,i8)')'WARNING: changing clay_o from ',int(clay_o(no,1)),' to 18 at no = ',no - clay_o(no,:) = 18._r4 - end if - end if - if (clay_o(no,1) < 0.) then - write(6,*)'ERROR: at no, lookup_index = ',no,lookup_index - call shr_sys_abort('could not find a value >= 0 for clay_i') - end if - do l = 2,nlay - clay_o(no,l) = float(clay_i(l,1,lookup_index)) - if (clay_o(no,l) < 0. .and. l > 1) then - clay_o(no,l) = clay_o(no,l-1) - end if - end do - - end if - - end do - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" - call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" - call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - - call pio_syncfile(pioid_o) - - ! Release memory - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) - - if (root_task) then - write (ndiag,'(a)') 'Successfully made %sand and %clay' - end if - - end subroutine mksoiltexnew - - !================================================================================================ - subroutine get_dominant_mapunit(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, rc) - - use ESMF, only : ESMF_RC_ARG_BAD - - ! input/output arguments - type(ESMF_DynamicMaskElementR4R8R4) , pointer :: dynamicMaskList(:) - real(ESMF_KIND_R4) , intent(in), optional :: dynamicSrcMaskValue - real(ESMF_KIND_R4) , intent(in), optional :: dynamicDstMaskValue - integer , intent(out) :: rc - - ! local variables - integer :: ni, no, n - real(ESMF_KIND_R4) :: wts_o(0:mapunit_value_max) - integer :: maxindex(1) - real(ESMF_KIND_R4) :: maxvalue - character(len=*), parameter :: subname = 'mksoiltex' - !--------------------------------------------------------------- - - rc = ESMF_SUCCESS - - if (associated(dynamicMaskList)) then - do no = 1, size(dynamicMaskList) - dynamicMaskList(no)%dstElement = 0.d0 - wts_o(:) = 0.d0 - do ni = 1, size(dynamicMaskList(no)%factor) - if (dynamicMaskList(no)%srcElement(ni) > 0.d0) then - do n = 0,mapunit_value_max - if (dynamicMaskList(no)%srcElement(ni) == n) then - wts_o(n) = wts_o(n) + dynamicMaskList(no)%factor(ni) - end if - enddo - end if - end do - - ! Determine the most dominant index of wts_o - maxvalue = -999._r4 - maxindex = -999 - do n = 0,mapunit_value_max - if (wts_o(n) > maxvalue) then - maxindex(1) = n - maxvalue = wts_o(n) - end if - end do - if (maxindex(1) > mapunit_value_max) then - write(6,*)'mapunit_o is out of bounds ',maxindex(1) - call shr_sys_abort(subname//" mapunit_o is out of bounds") - end if - dynamicMaskList(no)%dstElement = real(maxindex(1), kind=r4) - end do - end if - - end subroutine get_dominant_mapunit - -end module mksoiltexnewMod diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 4dd8bd9f56..395d04d161 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -103,7 +103,6 @@ program mksurfdata use mkglcmecMod , only : mkglcmecInit, mkglcmec, mkglacier use mkglacierregionMod , only : mkglacierregion use mksoiltexMod , only : mksoiltex - use mksoiltexnewMod , only : mksoiltexnew use mksoilfmaxMod , only : mksoilfmax use mksoildepthMod , only : mksoildepth use mksoilcolMod , only : mksoilcol @@ -192,7 +191,6 @@ program mksurfdata character(len=CL) :: fname character(len=*), parameter :: subname = 'mksrfdata' ! program name - ! TODO: temporary for new soil texture data character(len=CL) :: mksrf_fsoitex_mapunit character(len=CL) :: mksrf_fsoitex_lookup @@ -452,10 +450,6 @@ program mksurfdata ! Make soil texture [pctsand, pctclay] ! ----------------------------------- if (fsurdat /= ' ') then - ! mapunits, PCT_SAND and PCT_CLAY are written out in the subroutine - ! call mksoiltex( mksrf_fsoitex_mesh, mksrf_fsoitex, mesh_model, pioid, pctlnd_pft, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') - ! --- for a 3 second input mapunit --- ! mksrf_fsoitex_mapunit = & ! '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v5_grid.nc' @@ -467,7 +461,7 @@ program mksurfdata mksrf_fsoitex_lookup = & '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v1_lookup2.nc' - call mksoiltexnew( mksrf_fsoitex_mesh, file_mapunit_i=mksrf_fsoitex_mapunit, file_lookup_i=mksrf_fsoitex_lookup, & + call mksoiltex( mksrf_fsoitex_mesh, file_mapunit_i=mksrf_fsoitex_mapunit, file_lookup_i=mksrf_fsoitex_lookup, & mesh_o=mesh_model, pioid_o=pioid, pctlnd_pft_o=pctlnd_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') end if From d4d7078c4aac704e7b8d557338f57cf655a8503a Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sun, 24 Apr 2022 21:49:24 -0600 Subject: [PATCH 141/614] Remove the mksurfdata_map tests --- test/tools/README.testnames | 2 +- test/tools/input_tests_master | 37 ------------------- test/tools/nl_files/mksrfdt_10x15_1850 | 1 - .../nl_files/mksrfdt_10x15_crp_1850-2000 | 1 - test/tools/nl_files/mksrfdt_1x1_brazil_1850 | 1 - .../nl_files/mksrfdt_1x1_brazil_1850-2000 | 1 - .../nl_files/mksrfdt_1x1_numaIA_crp_2000 | 1 - .../mksrfdt_1x1_numaIA_crp_SSP5-8.5_1850-2100 | 1 - .../nl_files/mksrfdt_1x1_vancouverCAN_2000 | 1 - .../nl_files/mksrfdt_5x5_amazon_hirespft_2005 | 1 - test/tools/nl_files/mksrfdt_T31_crpglc_2000 | 1 - test/tools/nl_files/mksrfdt_f09_PtVg | 1 - test/tools/tests_posttag_dav_mpi | 2 - test/tools/tests_posttag_hobart_nompi | 3 -- test/tools/tests_posttag_izumi_nompi | 3 -- test/tools/tests_posttag_nompi_regression | 10 ----- test/tools/tests_pretag_cheyenne_nompi | 12 ------ 17 files changed, 1 insertion(+), 78 deletions(-) delete mode 100644 test/tools/nl_files/mksrfdt_10x15_1850 delete mode 100644 test/tools/nl_files/mksrfdt_10x15_crp_1850-2000 delete mode 100644 test/tools/nl_files/mksrfdt_1x1_brazil_1850 delete mode 100644 test/tools/nl_files/mksrfdt_1x1_brazil_1850-2000 delete mode 100644 test/tools/nl_files/mksrfdt_1x1_numaIA_crp_2000 delete mode 100644 test/tools/nl_files/mksrfdt_1x1_numaIA_crp_SSP5-8.5_1850-2100 delete mode 100644 test/tools/nl_files/mksrfdt_1x1_vancouverCAN_2000 delete mode 100644 test/tools/nl_files/mksrfdt_5x5_amazon_hirespft_2005 delete mode 100644 test/tools/nl_files/mksrfdt_T31_crpglc_2000 delete mode 100644 test/tools/nl_files/mksrfdt_f09_PtVg delete mode 100644 test/tools/tests_posttag_dav_mpi delete mode 100644 test/tools/tests_posttag_izumi_nompi diff --git a/test/tools/README.testnames b/test/tools/README.testnames index 11d9e23d4c..4dd51ee050 100644 --- a/test/tools/README.testnames +++ b/test/tools/README.testnames @@ -28,7 +28,7 @@ c -- mkprocdata_map d -- mkmapgrids e -- unused f -- unused -g -- mksurfdata_map +g -- unused h -- unused i -- tools scripts diff --git a/test/tools/input_tests_master b/test/tools/input_tests_master index f3e46d50b5..b162266115 100644 --- a/test/tools/input_tests_master +++ b/test/tools/input_tests_master @@ -3,36 +3,6 @@ smc#4 TSMscript_tools.sh mkprocdata_map mkprocdata_map_wrap mkprocdata_ne30_to_f19_I2000^tools__ds blc#4 TBLscript_tools.sh mkprocdata_map mkprocdata_map_wrap mkprocdata_ne30_to_f19_I2000^tools__ds -smg54 TSMtools.sh mksurfdata_map tools__s namelist -blg54 TBLtools.sh mksurfdata_map tools__s namelist - -smi24 TSMscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_T31_crpglc_2000^tools__ds -bli24 TBLscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_T31_crpglc_2000^tools__ds - -smi04 TSMscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_f09_PtVg^tools__ds -bli04 TBLscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_f09_PtVg^tools__ds - -smi53 TSMscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_10x15_1850^tools__o -bli53 TBLscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_10x15_1850^tools__o -smi54 TSMscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_10x15_1850^tools__ds -bli54 TBLscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_10x15_1850^tools__ds -smi57 TSMscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_10x15_1850^tools__do -bli57 TBLscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_10x15_1850^tools__do -smi58 TSMscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_10x15_crp_1850-2000^tools__do -bli58 TBLscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_10x15_crp_1850-2000^tools__do - -smi64 TSMscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_5x5_amazon_hirespft_2005^tools__ds -bli64 TBLscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_5x5_amazon_hirespft_2005^tools__ds - -smi74 TSMscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_1x1_brazil_1850-2000^tools__ds -bli74 TBLscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_1x1_brazil_1850-2000^tools__ds -smi78 TSMscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_1x1_brazil_1850^tools__ds -bli78 TBLscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_1x1_brazil_1850^tools__ds -smiT4 TSMscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_1x1_numaIA_crp_2000^tools__ds -bliT4 TBLscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_1x1_numaIA_crp_2000^tools__ds -smiT2 TSMscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_1x1_numaIA_crp_SSP5-8.5_1850-2100^tools__s -bliT2 TBLscript_tools.sh mksurfdata_map mksurfdata.pl mksrfdt_1x1_numaIA_crp_SSP5-8.5_1850-2100^tools__s - sm0a1 TSMscript_tools.sh site_and_regional run_neon.py run_neon_OSBS bl0a1 TBLscript_tools.sh site_and_regional run_neon.py run_neon_OSBS @@ -49,10 +19,3 @@ blbd1 TBLscript_tools.sh site_and_regional subset_data subset_data_region1 smaa2 TSMscript_tools.sh site_and_regional modify_singlept_site_neon.py modify_data_YELL blaa2 TBLscript_tools.sh site_and_regional modify_singlept_site_neon.py modify_data_YELL - -smi#2 TSMscript_tools.sh mkmapdata mkmapdata.sh mkmapdata_ne30np4 -bli#2 TBLscript_tools.sh mkmapdata mkmapdata.sh mkmapdata_ne30np4 -smi59 TSMscript_tools.sh mkmapdata mkmapdata.sh mkmapdata_if10 -bli59 TBLscript_tools.sh mkmapdata mkmapdata.sh mkmapdata_if10 -smi79 TSMscript_tools.sh mkmapdata mkmapdata.sh mkmapdata_i1x1_brazil -bli79 TBLscript_tools.sh mkmapdata mkmapdata.sh mkmapdata_i1x1_brazil diff --git a/test/tools/nl_files/mksrfdt_10x15_1850 b/test/tools/nl_files/mksrfdt_10x15_1850 deleted file mode 100644 index cdbb7c13dc..0000000000 --- a/test/tools/nl_files/mksrfdt_10x15_1850 +++ /dev/null @@ -1 +0,0 @@ --l CSMDATA -vic -r 10x15 -no-crop -y 1850 -exedir EXEDIR diff --git a/test/tools/nl_files/mksrfdt_10x15_crp_1850-2000 b/test/tools/nl_files/mksrfdt_10x15_crp_1850-2000 deleted file mode 100644 index b42c1deb04..0000000000 --- a/test/tools/nl_files/mksrfdt_10x15_crp_1850-2000 +++ /dev/null @@ -1 +0,0 @@ --l CSMDATA -r 10x15 -y 1850-2000 -exedir EXEDIR diff --git a/test/tools/nl_files/mksrfdt_1x1_brazil_1850 b/test/tools/nl_files/mksrfdt_1x1_brazil_1850 deleted file mode 100644 index 2330bd082e..0000000000 --- a/test/tools/nl_files/mksrfdt_1x1_brazil_1850 +++ /dev/null @@ -1 +0,0 @@ --l CSMDATA -r 1x1_brazil -y 1850-2000 -exedir EXEDIR diff --git a/test/tools/nl_files/mksrfdt_1x1_brazil_1850-2000 b/test/tools/nl_files/mksrfdt_1x1_brazil_1850-2000 deleted file mode 100644 index 2330bd082e..0000000000 --- a/test/tools/nl_files/mksrfdt_1x1_brazil_1850-2000 +++ /dev/null @@ -1 +0,0 @@ --l CSMDATA -r 1x1_brazil -y 1850-2000 -exedir EXEDIR diff --git a/test/tools/nl_files/mksrfdt_1x1_numaIA_crp_2000 b/test/tools/nl_files/mksrfdt_1x1_numaIA_crp_2000 deleted file mode 100644 index 03304f81eb..0000000000 --- a/test/tools/nl_files/mksrfdt_1x1_numaIA_crp_2000 +++ /dev/null @@ -1 +0,0 @@ --l CSMDATA -r 1x1_numaIA -y 2000 -exedir EXEDIR diff --git a/test/tools/nl_files/mksrfdt_1x1_numaIA_crp_SSP5-8.5_1850-2100 b/test/tools/nl_files/mksrfdt_1x1_numaIA_crp_SSP5-8.5_1850-2100 deleted file mode 100644 index ed83434075..0000000000 --- a/test/tools/nl_files/mksrfdt_1x1_numaIA_crp_SSP5-8.5_1850-2100 +++ /dev/null @@ -1 +0,0 @@ --l CSMDATA -r 1x1_numaIA -y 1850-2100 -ssp_rcp SSP5-8.5 -exedir EXEDIR diff --git a/test/tools/nl_files/mksrfdt_1x1_vancouverCAN_2000 b/test/tools/nl_files/mksrfdt_1x1_vancouverCAN_2000 deleted file mode 100644 index a446e82fcd..0000000000 --- a/test/tools/nl_files/mksrfdt_1x1_vancouverCAN_2000 +++ /dev/null @@ -1 +0,0 @@ --l CSMDATA -r 1x1_vancouverCAN -no-crop -y 2000 -exedir EXEDIR diff --git a/test/tools/nl_files/mksrfdt_5x5_amazon_hirespft_2005 b/test/tools/nl_files/mksrfdt_5x5_amazon_hirespft_2005 deleted file mode 100644 index 47a5391c84..0000000000 --- a/test/tools/nl_files/mksrfdt_5x5_amazon_hirespft_2005 +++ /dev/null @@ -1 +0,0 @@ --l CSMDATA -r 5x5_amazon -y 2005 -hirespft -exedir EXEDIR diff --git a/test/tools/nl_files/mksrfdt_T31_crpglc_2000 b/test/tools/nl_files/mksrfdt_T31_crpglc_2000 deleted file mode 100644 index ac8ceed1a8..0000000000 --- a/test/tools/nl_files/mksrfdt_T31_crpglc_2000 +++ /dev/null @@ -1 +0,0 @@ --l CSMDATA -r 48x96 -y 2000 -glc_nec 10 -exedir EXEDIR diff --git a/test/tools/nl_files/mksrfdt_f09_PtVg b/test/tools/nl_files/mksrfdt_f09_PtVg deleted file mode 100644 index 61c2d8325e..0000000000 --- a/test/tools/nl_files/mksrfdt_f09_PtVg +++ /dev/null @@ -1 +0,0 @@ --l CSMDATA -r 0.9x1.25 -no-crop -y PtVg -exedir EXEDIR diff --git a/test/tools/tests_posttag_dav_mpi b/test/tools/tests_posttag_dav_mpi deleted file mode 100644 index ef42215791..0000000000 --- a/test/tools/tests_posttag_dav_mpi +++ /dev/null @@ -1,2 +0,0 @@ -smi#2 bli#2 -smi59 bli59 diff --git a/test/tools/tests_posttag_hobart_nompi b/test/tools/tests_posttag_hobart_nompi index 9f07863e4d..c185428868 100644 --- a/test/tools/tests_posttag_hobart_nompi +++ b/test/tools/tests_posttag_hobart_nompi @@ -1,4 +1 @@ smc#4 blc#4 -smi54 bli54 -smi57 bli57 -smiT4 bliT4 diff --git a/test/tools/tests_posttag_izumi_nompi b/test/tools/tests_posttag_izumi_nompi deleted file mode 100644 index 62687a7e3d..0000000000 --- a/test/tools/tests_posttag_izumi_nompi +++ /dev/null @@ -1,3 +0,0 @@ -smi54 bli54 -smi57 bli57 -smiT4 bliT4 diff --git a/test/tools/tests_posttag_nompi_regression b/test/tools/tests_posttag_nompi_regression index 1395aebe11..c185428868 100644 --- a/test/tools/tests_posttag_nompi_regression +++ b/test/tools/tests_posttag_nompi_regression @@ -1,11 +1 @@ smc#4 blc#4 -smg54 blg54 -smi24 bli24 -smi53 bli53 -smi54 bli54 -smi57 bli57 -smi58 bli58 -smi74 bli74 -smi78 bli78 -smiT4 bliT4 -smiT2 bliT2 diff --git a/test/tools/tests_pretag_cheyenne_nompi b/test/tools/tests_pretag_cheyenne_nompi index 19e96594bf..e92ffaaaad 100644 --- a/test/tools/tests_pretag_cheyenne_nompi +++ b/test/tools/tests_pretag_cheyenne_nompi @@ -1,15 +1,3 @@ -smi79 bli79 smc#4 blc#4 -smg54 blg54 smba1 blba1 smbd1 blbd1 -smi04 bli04 -smi24 bli24 -smi53 bli53 -smi64 bli64 -smi54 bli54 -smi57 bli57 -smi58 bli58 -smi74 bli74 -smiT4 bliT4 -smiT2 bliT2 From 64d2829f9f3da2c1b59400647b677622a1e69492 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sun, 24 Apr 2022 21:52:10 -0600 Subject: [PATCH 142/614] Remove mention of mksurfdata_map in README files, also remove mkmapdata and toolchain/gen_mksurf_namelist as they are deprecated with mksurfdata_esmf --- .gitignore | 7 +- README | 6 +- tools/README | 138 +++---- tools/mkmapdata/README | 90 ----- tools/mkmapdata/createXMLEntries.pl | 116 ------ tools/mkmapdata/mkmapdata.sh | 578 ---------------------------- tools/mkmapdata/mvNimport.sh | 75 ---- tools/mkmapdata/regridbatch.sh | 102 ----- tools/mkmapdata/regridgeyser.sh | 87 ----- tools/mkmapdata/rmdups.ncl | 131 ------- tools/toolchain/gen_mksurf_namelist | 77 ---- 11 files changed, 50 insertions(+), 1357 deletions(-) delete mode 100644 tools/mkmapdata/README delete mode 100755 tools/mkmapdata/createXMLEntries.pl delete mode 100755 tools/mkmapdata/mkmapdata.sh delete mode 100755 tools/mkmapdata/mvNimport.sh delete mode 100755 tools/mkmapdata/regridbatch.sh delete mode 100755 tools/mkmapdata/regridgeyser.sh delete mode 100644 tools/mkmapdata/rmdups.ncl delete mode 100755 tools/toolchain/gen_mksurf_namelist diff --git a/.gitignore b/.gitignore index 005ad3dbfb..2538083cf1 100644 --- a/.gitignore +++ b/.gitignore @@ -91,18 +91,15 @@ ctsm.input_data_list.previous /tools/mksurfdata_esmf/mksurfdata_in /tools/mksurfdata_esmf/bld /tools/mksurfdata_esmf/src +/tools/mksurfdata_esmf/surfdata_*.nc +/tools/mksurfdata_esmf/landuse.timeseries_*.nc # mksurfdata unit tests unit_test_build # Tools executables -/tools/mksurfdata_map/mksurfdata_map /tools/mkprocdata_map/mkprocdata_map -# mksurfdata output files -/tools/mksurfdata_map/surfdata_*.nc -/tools/mksurfdata_map/landuse.timeseries_*.nc - # mkmapdata output files /tools/mkmapdata/PET*.RegridWeightGen.Log /tools/mkmapdata/regrid.*.out diff --git a/README b/README index 7e81aecd9a..c50a6eabd8 100644 --- a/README +++ b/README @@ -52,6 +52,7 @@ Directory structure only for a CTSM checkout: components -------- Other active sub-components needed for CTSM to run (river routing and land-ice models) libraries --------- CESM libraries: MCT (Model Coupling Toolkit) and PIO share ------------- CESM shared code +ccs_config -------- CIME configure files (for grids, compsets, and machines) for CESM cime/scripts --------------- cesm/cime driver scripts @@ -132,13 +133,12 @@ cime_config/usermods_dirs -------- Directories of sets of user-modification subd test/tools/test_driver.sh -- Script for general software testing of CTSM's offline tools. -tools/mksurfdata_map ---------- Directory to build program to create surface dataset +tools/mksurfdata_esmf --------- Directory to build program to create surface dataset at any resolution. -tools/mkdatadomain ------------ Directory to build program to create datm7 or docn7 - domain files from clm files. tools/mkprocdata_map ---------- Process history data from unstructed grids to a gridded format. tools/mkmapgrids -------------- NCL script to create a SCRIP grid file for a regular lat/lon grid +tools/modify_fsurdat ---------- Script to modify existing surface datasets in standard ways tools/ncl_scripts ------------ Directory of NCL and perl scripts to do various tasks. Most notably to plot perturbation error growth testing and to extract regional information from diff --git a/tools/README b/tools/README index e71016486e..8bd1950151 100644 --- a/tools/README +++ b/tools/README @@ -8,8 +8,7 @@ I. General directory structure: $CTSMROOT/tools mksurfdata_esmf -- Create surface datasets. - mkmapgrids ------- Create regular lat/lon SCRIP grid files needed by mkmapdata - mkmapdata -------- Create SCRIP mapping data from SCRIP grid files (uses ESMF) + mkmapgrids ------- Create regular lat/lon SCRIP grid files mkprocdata_map --- Convert output unstructured grids into a 2D format that can be plotted easily ncl_scripts ------ NCL post or pre processing scripts. @@ -19,6 +18,8 @@ I. General directory structure: standard process as well as subsetting existing datasets and overwriting some aspects for a specific case. + modify_fsurdat --- Modifies surface datasets according to some simple patterns + contrib ---------- Miscellaneous tools for pre or post processing of CTSM. Typically these are contributed by anyone who has something they think might be helpful to the community. They may not @@ -30,7 +31,7 @@ I. General directory structure: II. Notes on building/running for each of the above tools: - Each tool that has FORTRAN source code (mksurfdata_map and mkprocdata_map) has the following files: + mkprocdata_map has the following files to facilitate building the FORTRAN code: README ------- Specific help for using the specific tool and help on specific files in that directory. @@ -42,21 +43,6 @@ II. Notes on building/running for each of the above tools: src/Srcfiles ----- List of source files that are needed. src/Mkdepends ---- Dependency generator program - mkmapdata, mkmapgrids and ncl_scripts only contain scripts so don't have the above build files. - - Most tools have copies of files from other directories -- see the README.filecopies - file for more information on this. - - Tools may also have files with the directory name followed by namelist to provide sample namelists. - - .namelist ------ Namelist to create a global file. - - These files are also used by the test scripts to test the tools (see the - README.testing) file. - - NOTE: Be sure to change the path of the datasets references by these namelists to - point to where you have exported your CESM inputdata datasets. - To build: cd @@ -88,6 +74,26 @@ II. Notes on building/running for each of the above tools: run normally as above + mksurfdata_esmf has a cime configure and CMake based build using the following files: + + CMakeLists.txt -- Tells CMake how to build the source code + Makefile -------- GNU makefile to link the program together + + mkmapgrids, site_and_regional, and ncl_scripts only contain scripts so don't have the above build files. + + Some tools have copies of files from other directories -- see the README.filecopies + file for more information on this. + + Tools may also have files with the directory name followed by namelist to provide sample namelists. + + .namelist ------ Namelist to create a global file. + + These files are also used by the test scripts to test the tools (see the + README.testing) file. + + NOTE: Be sure to change the path of the datasets references by these namelists to + point to where you have exported your CESM inputdata datasets. + III. Process sequence to create input datasets needed to run CTSM 1.) Create SCRIP grid files (if needed) @@ -163,31 +169,10 @@ III. Process sequence to create input datasets needed to run CTSM http://www.cesm.ucar.edu/models/cesm1.0/clm/models/lnd/clm/doc/UsersGuide/book1.html - If you don't do this step, you'll need to specify the file to mkmapdata + If you don't do this step, you'll need to specify the file to mksurfdata_esmf in step (3) using the "-f" option. - 4.) Create mapping files for use by mksurfdata_map with mkmapdata - (See mkmapdata/README for more help on doing this) - - - this step uses the results of (1) that were entered into the XML database - by step (3). If you don't enter datasets in, you need to specify the - SCRIP grid file using the "-f" option to mkmapdata.sh. - - Example: to generate all necessary mapping files for the ne30np4 grid - - cd mkmapdata - ./mkmapdata.sh -r ne30np4 - - 5.) Add mapping file(s) created in step (4) into XML database in CTSM (optional) - - See notes on doing this in step (3) above. - Edit ../bld/namelist_files/namelist_defaults_clm.xml to incorporate new - mapping files. - - If you don't do this step, you'll need to specify the grid resolution name - and file creation dates to mksurfdata_map in step (5) below. - - 6.) Convert map of ocean to atm for use by DATM and CTSM with gen_domain + 4.) Convert map of ocean to atm for use by DATM and CTSM with gen_domain (See $CIMEROOT/tools/mapping/README for more help on doing this) - gen_domain uses the map from step (2) (or previously created CESM maps) @@ -208,72 +193,39 @@ III. Process sequence to create input datasets needed to run CTSM file for CTSM. Output domain files will be named according to the input OCN/LND gridnames. - 7.) Create surface datasets with mksurfdata_map - (See mksurfdata_map/README for more help on doing this) + 5.) Create surface datasets with mksurfdata_esmf on cheyenne + (See mksurfdata_esmf/README for more help on doing this) + + - gen_mksurfdata_build.sh to build + - gen_mksurfdata_namelist.py to build the namelist + - gen_mksurfdata_jobscript_single.py to build a batch script to run on cheyenne + - Submit the batch script just created above - - Run mksurfdata_map/mksurfdata.pl - - This step uses the results of step (4) entered into the XML database - in step (5). + - This step uses the results of step (3) entered into the XML database + in step (4). - If datasets were NOT entered into the XML database, set the resolution - to "usrspec" and use the "-usr_gname", and "-usr_gdate" options. + by entering the mesh file using the options: --model-mesh --model-mesh-nx --model-mesh-ny - Example: for 0.9x1.25 resolution + Example: for 0.9x1.25 resolution fro 1850 - cd mksurfdata_map/src - gmake - cd .. - ./mksurfdata.pl -r 0.9x1.25 + cd mksurfdata_esmf + ./gen_mksurfdata_build.sh + ./gen_mksurfdata_namelist.py --res 0.9x1.25 --start-year 1850 --end-year 1850 + ./gen_mksurfdata_jobscript_single.py --number-of-nodes 24 --tasks-per-node 12 --namelist-file target.namelist + qsub mksurfdata_jobscript_single NOTE that surface dataset will be used by default for fatmgrid - and it will contain the lat,lon,edges and area values for the atm grid - ASSUMING that the atm and land grid are the same - 8.) Add new files to XML data or using user_nl_clm (optional) + 6.) Add new files to XML data or using user_nl_clm (optional) See notes on doing this in step (3) above. -IV. Example of creating single-point datasets without entering into XML database. - - Here we apply the process described in III. for a single-point dataset - where we don't enter the datasets into the XML database (thus skipping - steps 3, 5 and 8), but use the needed command line options to specify where the - files are. This also skips step (2) since step 1 creates the needed mapping file. - - 0.) Set name of grid to use and the creation date to be used later... - setenv GRIDNAME 1x1_boulderCO - setenv CDATE `date +%y%m%d` - 1.) SCRIP grid and atm to ocn mapping file - cd site_and_regional - ./mknoocnmap.pl -p 40,255 -n $GRIDNAME - # Set pointer to MAPFILE that will be used in step (6) - setenv MAPFILE `pwd`/map_${GRIDNAME}_noocean_to_${GRIDNAME}_nomask_aave_da_${CDATE}.nc - cd ../.. - 2.) skip - 3.) skip - 4.) Mapping files needed for mksurfdata_map - cd mkmapdata - setenv GRIDFILE ../mkmapgrids/SCRIPgrid_${GRIDNAME}_nomask_${CDATE}.nc - ./mkmapdata.sh -r $GRIDNAME -f $GRIDFILE -t regional - cd ../.. - 5.) skip - 6.) Generate domain file for datm and CTSM - cd $CIMEROOT/tools/mapping/gen_domain_files/src - gmake - cd .. - setenv OCNDOM domain.ocn_noocean.nc - setenv ATMDOM domain.lnd.{$GRIDNAME}_noocean.nc - ./gen_domain -m $MAPFILE -o $OCNDOM -l $ATMDOM - 7.) Create surface dataset for CTSM - cd mksurfdata_map/src - gmake - cd .. - ./mksurfdata.pl -r usrspec -usr_gname $GRIDNAME -usr_gdate $CDATE - 8.) skip - -V. Notes on which input datasets are needed for CTSM +IV. Notes on which input datasets are needed for CTSM global or regional/single-point grids - need fsurdata and fatmlndfrc - fsurdata ---- from mksurfdata_map in step (III.7) + fsurdata ---- from mksurfdata_esmf in step (III.7) fatmlndfrc -- use the domain.lnd file from gen_domain in step (III.6) diff --git a/tools/mkmapdata/README b/tools/mkmapdata/README deleted file mode 100644 index 77d89717ad..0000000000 --- a/tools/mkmapdata/README +++ /dev/null @@ -1,90 +0,0 @@ -$CTSMROOT/tools/mkmapdata/README Jun/08/2018 - -The routines in this directory create a mapping dataset from -SCRIP grid files to map from one grid to another. These mapping files -are used by either CLM or mksurfdata_map to regrid from one resolution -to another. - -We have generally moved to "nomask" grid and mapping files. These "nomask" -files typically contain mask and frac equal to 1 everywhere. During remapping -we now apply the source masks found in the raw datasets and ignore the -masks found in the mapping files. Exception: we continue to use a masked -grid file and mapping file to regrid the 1-km topography. - -The script uses ESMF and requires that ESMF be built and the path -for ESMF binary files (using the program ESMF_RegridWeightGen) -be given as input to the script. You need to build at least -two versions, one with mpiuni and one with mpi. Both versions -also need to be built with NetCDF rather than the default -IO version. - -Currently uses: ESMF7.1.0r - -Do the following for help with the different options to the script... - - ./mkmapdata.sh -help - -The following steps provide a method to create the executable -and generate the grid map dataset: - -0) Background tasks you only have to do once - - a.) Export the input SCRIP grid files for the resolutions you'll need - - Most of these files are on the Subversion inputdata server at... - - https://svn-ccsm-inputdata.cgd.ucar.edu/trunk/inputdata/lnd/clm2/mappingdata/grids/ - - Supported machines also have a copy on the CESM DIN_LOC_ROOT location - for that machine. - - b.) Obtain and build the versions of ESMF required for this script - -The version needs to support ESMF_RegridWeightGen and support the -options passed to it in the mkmapdata.sh script. As such it needs -to be built with NetCDF. You also need to build at least one -version with mpiuni and one with an mpi library. You also need -a version that supports the options: --netcdf4, --64bit_offset -and --src_type UGRID. - - http://www.earthsystemmodeling.org/ - -You may need more than one version to do everything above. On cheyenne -we use ESMF7.1.0r. - -The version of NetCDF used with ESMF needs to be version 4.1 or higher -and compiled with the NetCDF4 file format enabled (with HDF5 compression). -That will enable the --netcdf4 and --64bit_offset options to be used. - -1) cd to this directory - -2) Create map dataset(s) - Option A.) Use mkmapdata.sh directly - run script(e.g.): (see header of mkmapdata.sh for other environment that can be set) - - Example for standard resolutions - ./mkmapdata.sh -r 10x15 - Example for non-standard resolutions where you provide an input SCRIP grid file. - ./mkmapdata.sh -f - - Option B.) Alternatively, run regridbatch.sh to run mkmapdata.sh for a bunch of - different resolutions. - - Option C.) Alternatively, run mknoocnmap.pl to create a single-point/regional - map for an area without ocean (in the site_and_regional directory parallel to this one. - - ../site_and_regional/mknoocnmap.pl -help # for help on this script - -3) move (and rename if appropriate) generated map datasets - to $DIN_LOC_ROOT/lnd/clm/mappingdata/maps, etc. - - -Important files: - - regridbatch.sh ------- Script to run mkmapdata.sh for many resolutions on cheyenne - regriddav.sh --------- Script to run mkmapdata.sh for many resolutions on the DAV cluster (Casper) - mvNimport.sh --------- Script to copy and import mapping files in for many resolutions - mkmapdata.sh --------- Script to create mapping datasets for a given resolution - - rmdups.ncl ----------- NCL script to remove duplicate mapping points - diff --git a/tools/mkmapdata/createXMLEntries.pl b/tools/mkmapdata/createXMLEntries.pl deleted file mode 100755 index c65e6888f7..0000000000 --- a/tools/mkmapdata/createXMLEntries.pl +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env perl - -# Creates a file giving XML entries for all the mapping files in the -# current directory (mapping_entries.txt). Also creates another file -# giving commands to move these files to the inputdata space -# (mv_cmds.sh). -# -# Should be run with no arguments. -# -# See also bld/namelist_files/createMapEntry.pl, and mvNimport.sh in -# the current directory for scripts that share some of the -# functionality of this script. - -# Bill Sacks -# March, 2013 - -use strict; - -# ---------------------------------------------------------------------- -# FUNCTIONS -# ---------------------------------------------------------------------- - -# Given a map filename, returns a hash giving the resolutions and -# masks implicit in that filename. -# Inputs: -# - filename -# Output: -# - hash containing: -# - filename -# - from_res -# - from_mask -# - to_res -# - to_mask -# Or does a bare return if the filename doesn't match the expected pattern -sub get_resolutions_and_masks { - my $filename = shift; - - # The following match assumes that the destination mask is - # "nomask". This match will tolerate underscores in the - # destination grid (e.g., 5x5_amazon), but be careful about - # underscores in the source grid or source mask! - if ($filename =~ m/^map_(.*)_(.*)_to_(.*)_nomask/) { - my $from_res=$1; - my $from_mask=$2; - my $to_res=$3; - my $to_mask="nomask"; - - my %info = (filename => $filename, - from_res => $from_res, - from_mask => $from_mask, - to_res => $to_res, - to_mask => $to_mask); - - return %info; - } - else { - return; - } -} - - -# ---------------------------------------------------------------------- -# PARAMETERS DEFINED HERE -# ---------------------------------------------------------------------- - -my $CSMDATA = "/glade/p/cesm/cseg/inputdata"; -my $maps_dir = "lnd/clm2/mappingdata/maps"; # directory where mapping files are stored within the inputdata directory - -# ---------------------------------------------------------------------- -# BEGIN MAIN PROGRAM -# ---------------------------------------------------------------------- - -my @files = glob "map*.nc"; - -# Make a hash containing all of the files at each destination resolution. -# The keys of the hash are destination resolutions; the values are -# references to arrays of hash references, where these low-level -# hashes are the return values of get_resolutions_and_masks. -my %dest_resols; -foreach my $file (@files) { - my %info = get_resolutions_and_masks($file); - if (%info) { - my $to_res = $info{'to_res'}; - push @{$dest_resols{$to_res}}, \%info; - } - else { - warn "WARNING: $file doesn't match expected mapping filename pattern; skipping\n"; - } -} - -open MAP_ENTRIES, ">", "mapping_entries.txt"; -open MV_CMDS, ">", "mv_cmds.sh"; - -# Output xml entries (and mv commands) grouped by destination resolution -foreach my $to_res (sort keys %dest_resols) { - my $full_maps_dir = "$maps_dir/$to_res"; - - foreach my $info_ref (@{$dest_resols{$to_res}}) { - my $filename = ${$info_ref}{'filename'}; - my $from_res = ${$info_ref}{'from_res'}; - my $from_mask = ${$info_ref}{'from_mask'}; - my $to_res = ${$info_ref}{'to_res'}; - my $to_mask = ${$info_ref}{'to_mask'}; - - print MV_CMDS "mv $filename $CSMDATA/$full_maps_dir/$filename\n"; - print MAP_ENTRIES "$full_maps_dir/$filename\n"; - } - - # Print blank line between destination grids - print MAP_ENTRIES "\n"; -} - -system "chmod", "755", "mv_cmds.sh"; -close MAP_ENTRIES; -close MV_CMDS; diff --git a/tools/mkmapdata/mkmapdata.sh b/tools/mkmapdata/mkmapdata.sh deleted file mode 100755 index 531ca5a60f..0000000000 --- a/tools/mkmapdata/mkmapdata.sh +++ /dev/null @@ -1,578 +0,0 @@ -#!/bin/bash -#---------------------------------------------------------------------- -# -# mkmapdata.sh -# -# Create needed mapping files for mksurfdata_map and CLM. -# -# Example to run for an output resolution of 4x5 -# -# mkmapdata.sh -r 4x5 -# -# valid arguments: -# -f Input grid filename -# -t Output type, supported values are [regional, global] -# -r Output resolution -# -b use batch mode (not default) -# -i High resolution mode (Only used with -f) -# -l list mapping files required (so can use check_input_data to get them) -# -d debug usage -- display mkmapdata that will be run but don't execute them -# -v verbose usage -- log more information on what is happening -# -h displays this help message -# -# You can also set the following env variables: -# -# ESMFBIN_PATH - Path to ESMF binaries -# CSMDATA ------ Path to CESM input data -# MPIEXEC ------ Name of mpirun executable -# REGRID_PROC -- Number of MPI processors to use -# -#---------------------------------------------------------------------- -echo $0 -dir=${0%/*} -if [ "$dir" = "$0" ];then - dir="." -fi -outfilelist="clm.input_data_list" -default_res="10x15" - -#---------------------------------------------------------------------- -# SET SOME DEFAULTS -- if not set via env variables outside - -case $hostname in - - ##cheyenne - cheyenne* | r* ) - if [ -z "$CSMDATA" ]; then - CSMDATA=/glade/p/cesm/cseg/inputdata - fi - ;; - - ##hobart/izumi/thorodin - hobart* | izumi* | thorodin* ) - if [ -z "$CSMDATA" ]; then - CSMDATA=/fs/cgd/csm/inputdata - fi - ;; - -esac - -#---------------------------------------------------------------------- -# Usage subroutine -usage() { - echo "" - echo "**********************" - echo "usage:" - echo "./mkmapdata.sh" - echo "" - echo "valid arguments: " - echo "[-f|--gridfile ] " - echo " Full pathname of model SCRIP grid file to use " - echo " This variable should be set if this is not a supported grid" - echo " This variable will override the automatic generation of the" - echo " filename generated from the -res argument " - echo " the filename is generated ASSUMING that this is a supported " - echo " grid that has entries in the file namelist_defaults_ctsm.xml" - echo " the -r|--res argument MUST be specied if this argument is specified" - echo "[-r|--res ]" - echo " Model output resolution (default is $default_res)" - echo "[-t|--gridtype ]" - echo " Model output grid type" - echo " supported values are [regional,global], (default is global)" - echo "[-b|--batch]" - echo " Toggles batch mode usage (and run with mpi). If you want to run in batch mode" - echo " you need to have a separate batch script for a supported machine" - echo " that calls this script interactively - you cannot submit this" - echo " script directly to the batch system" - echo "[-i|--hires]" - echo " Output maps are high resolution and large file support should be used" - echo "[-l|--list]" - echo " List mapping files required (use check_input_data to get them)" - echo " also writes data to $outfilelist" - echo "[-d|--debug]" - echo " Toggles debug-only (don't actually run mkmapdata just echo what would happen)" - echo "[-h|--help] " - echo " Displays this help message" - echo "[-v|--verbose]" - echo " Toggle verbose usage -- log more information on what is happening " - echo "[--fast]" - echo " Toggle fast maps only -- only create the maps that can be done quickly " - echo "" - echo " You can also set the following env variables:" - echo " ESMFBIN_PATH - Path to ESMF binaries " - echo " (default is determined by machine running on)" - echo " CSMDATA ------ Path to CESM input data" - echo " (default is $CSMDATA)" - echo " MPIEXEC ------ Name of mpirun executable" - echo " (default is determined by machine running on)" - echo " REGRID_PROC -- Number of MPI processors to use" - echo " (default is $REGRID_PROC)" - echo "" - echo "**defaults can be determined on the machines: cheyenne or casper" - echo "" - echo "**pass environment variables by preceding above commands " - echo " with 'env var1=setting var2=setting '" - echo "**********************" -} -#---------------------------------------------------------------------- -# runcmd subroutine -#---------------------------------------------------------------------- - -runcmd() { - cmd=$@ - if [ -z "$cmd" ]; then - echo "No command given to the runcmd function" - exit 3 - fi - if [ "$verbose" = "YES" ]; then - echo "$cmd" - fi - if [ "$debug" != "YES" ]; then - ${cmd} - rc=$? - else - rc=0 - fi - if [ $rc != 0 ]; then - echo "Error status returned from mkmapdata script" - exit 4 -undo - fi - return 0 -} - -#---------------------------------------------------------------------- -# Process input arguments -#---------------------------------------------------------------------- - -interactive="YES" -debug="no" -res="default" -type="global" -phys="clm4_5" -verbose="no" -list="no" -outgrid="" -gridfile="default" -fast="no" -netcdfout="none" - -while [ $# -gt 0 ]; do - case $1 in - -v|-V) - verbose="YES" - ;; - -b|--batch) - interactive="NO" - ;; - -d|--debug) - debug="YES" - ;; - --fast) - fast="YES" - ;; - -i|--hires) - netcdfout="64bit_offset" - ;; - -l|--list) - debug="YES" - list="YES" - ;; - -r|--res) - res=$2 - shift - ;; - -f|--gridfile) - gridfile=$2 - shift - ;; - -t|--gridtype) - type=$2 - shift - ;; - -h|--help ) - usage - exit 0 - ;; - * ) - echo "ERROR:: invalid argument sent in: $2" - usage - exit 1 - ;; - esac - shift -done - -echo "Script to create mapping files required by mksurfdata_map" - -#---------------------------------------------------------------------- -# Determine output scrip grid file -#---------------------------------------------------------------------- - -# Set general query command used below -QUERY="$dir/../../bld/queryDefaultNamelist.pl -silent -namelist clmexp " -QUERY="$QUERY -justvalue -options sim_year=2000 -csmdata $CSMDATA" -echo "query command is $QUERY" - -echo "" -DST_EXTRA_ARGS="" -if [ "$gridfile" != "default" ]; then - GRIDFILE=$gridfile - echo "Using user specified scrip grid file: $GRIDFILE" - if [ "$res" = "default" ]; then - echo "When user specified grid file is given you MUST set the resolution (as the name of your grid)\n"; - exit 1 - fi - - # For now, maked the assumption about user-specified grids -- - # that they are SCRIP format. In the future we may want to - # provide a command-line options to allow the user to - # override that default. - DST_LRGFIL=$netcdfout - DST_TYPE="SCRIP" -else - if [ "$res" = "default" ]; then - res=$default_res - fi - - QUERYARGS="-res $res -options lmask=nomask" - - # Find the output grid file for this resolution using the XML database - QUERYFIL="$QUERY -var scripgriddata $QUERYARGS -onlyfiles" - if [ "$verbose" = "YES" ]; then - echo $QUERYFIL - fi - GRIDFILE=`$QUERYFIL` - echo "Using default scrip grid file: $GRIDFILE" - - # Determine extra information about the destination grid file - DST_LRGFIL=`$QUERY -var scripgriddata_lrgfile_needed $QUERYARGS` - DST_TYPE=`$QUERY -var scripgriddata_type $QUERYARGS` - if [ "$DST_TYPE" = "UGRID" ]; then - # For UGRID, we need extra information: the meshname variable - dst_meshname=`$QUERY -var scripgriddata_meshname $QUERYARGS` - DST_EXTRA_ARGS="$DST_EXTRA_ARGS --dst_meshname $dst_meshname" - fi -fi - -if [ "$type" = "global" ] && [ `echo "$res" | grep -c "1x1_"` = 1 ]; then - echo "This is a regional resolution and yet it is being run as global, set type with '-t' option\n"; - exit 1 -fi -if [ "$type" = "global" ] && [ `echo "$res" | grep -c "5x5_"` = 1 ]; then - echo "This is a regional resolution and yet it is being run as global, set type with '-t' option\n"; - exit 1 -fi -echo "Output grid resolution is $res" -if [ -z "$GRIDFILE" ]; then - echo "Output grid file was NOT found for this resolution: $res\n"; - exit 1 -fi - -if [ "$list" = "YES" ]; then - echo "outgrid = $GRIDFILE" - echo "outgrid = $GRIDFILE" > $outfilelist -elif [ ! -f "$GRIDFILE" ]; then - echo "Input SCRIP grid file does NOT exist: $GRIDFILE\n"; - echo "Make sure CSMDATA environment variable is set correctly" - exit 1 -fi - -#---------------------------------------------------------------------- -# Determine all input grid files and output file names -#---------------------------------------------------------------------- - -if [ "$phys" = "clm4_5" ]; then - grids=( \ - "0.5x0.5_nomask" \ - "0.25x0.25_nomask" \ - "0.125x0.125_nomask" \ - "3x3min_nomask" \ - "5x5min_nomask" \ - "10x10min_nomask" \ - "0.9x1.25_nomask" \ - "1km-merge-10min_HYDRO1K-merge-nomask" \ - ) - -else - echo "ERROR: Unknown value for phys: $phys" - exit 1 -fi - -# Set timestamp for names below -# The flag `-d "-0 days"` can serve as a time saver as follows: -# If the script aborted without creating all of the map_ files and -# the user resubmits to create the remaining files on the next day, -# the user could change -0 to -1 to prevent the script from -# duplicating files already generated the day before. -# -CDATE="c"`date -d "-0 days" +%y%m%d` - -# Set name of each output mapping file -# First determine the name of the input scrip grid file -# for each of the above grids -declare -i nfile=1 -for gridmask in ${grids[*]} -do - grid=${gridmask%_*} - lmask=${gridmask#*_} - - QUERYARGS="-res $grid -options lmask=$lmask,glc_nec=10 " - - QUERYFIL="$QUERY -var scripgriddata $QUERYARGS -onlyfiles" - if [ "$verbose" = "YES" ]; then - echo $QUERYFIL - fi - INGRID[nfile]=`$QUERYFIL` - if [ "$list" = "YES" ]; then - echo "ingrid = ${INGRID[nfile]}" - echo "ingrid = ${INGRID[nfile]}" >> $outfilelist - fi - - OUTFILE[nfile]=map_${grid}_${lmask}_to_${res}_nomask_aave_da_$CDATE.nc - - # Determine extra information about the source grid file - SRC_EXTRA_ARGS[nfile]="" - SRC_LRGFIL[nfile]=`$QUERY -var scripgriddata_lrgfile_needed $QUERYARGS` - SRC_TYPE[nfile]=`$QUERY -var scripgriddata_type $QUERYARGS` - if [ "${SRC_TYPE[nfile]}" = "UGRID" ]; then - # For UGRID, we need extra information: the meshname variable - src_meshname=`$QUERY -var scripgriddata_meshname $QUERYARGS` - SRC_EXTRA_ARGS[nfile]="${SRC_EXTRA_ARGS[nfile]} --src_meshname $src_meshname" - fi - - nfile=nfile+1 -done - -#---------------------------------------------------------------------- -# Determine supported machine specific stuff -#---------------------------------------------------------------------- - -hostname=`hostname` -if [ -n "$NERSC_HOST" ]; then - hostname=$NERSC_HOST -fi -echo "Hostname = $hostname" -case $hostname in - ##cheyenne - cheyenne* | r* ) - . /glade/u/apps/ch/opt/lmod/8.1.7/lmod/lmod/init/bash - if [ -z "$REGRID_PROC" ]; then - REGRID_PROC=36 - fi - if [ interactive = "YES" ]; then - REGRID_PROC=1 - fi - if [ "$verbose" = "YES" ]; then - echo "Number of processors to regrid with = $REGRID_PROC" - fi - esmfvers=8.2.0b13 - intelvers=19.1.1 - module purge - module load intel/$intelvers -# module load esmf_libs -# module load esmf_libs/$esmfvers - module load nco - - if [[ $REGRID_PROC > 1 ]]; then - mpi=mpt - module load mpt/2.22 - else - mpi=mpiuni - fi -# module load esmf-${esmfvers}-ncdfio-${mpi}-O - module use /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/$intelvers - module load esmf-${esmfvers}-ncdfio-${mpi}-g - if [ -z "$ESMFBIN_PATH" ]; then - ESMFBIN_PATH=`grep ESMF_APPSDIR $ESMFMKFILE | awk -F= '{print $2}'` - fi - if [ -z "$MPIEXEC" ]; then - MPIEXEC="mpiexec_mpt -np $REGRID_PROC" - fi - if [ "$verbose" = "YES" ]; then - echo "list of modules" - module list - fi - ;; - - ## DAV - pronghorn* | casper* ) - . /glade/u/apps/ch/opt/lmod/7.2.1/lmod/lmod/init/bash - if [ -z "$REGRID_PROC" ]; then - REGRID_PROC=8 - fi - if [ interactive = "YES" ]; then - REGRID_PROC=1 - fi - echo "REGRID_PROC=$REGRID_PROC" - esmfvers=7.1.0r - intelvers=17.0.1 - module purge - module load intel/$intelvers - if [ $? != 0 ]; then - echo "Error doing module load: intel/$intelvers" - exit 1 - fi - module load nco - module load netcdf - module load ncarcompilers - - module load esmflibs/$esmfvers - if [ $? != 0 ]; then - echo "Error doing module load: esmflibs/$esmfvers" - exit 1 - fi - - if [[ $REGRID_PROC > 1 ]]; then - mpi=mpi - echo "MPI option is NOT currently available" - exit 1 - else - mpi=uni - fi - module load esmf-${esmfvers}-ncdfio-${mpi}-O - if [ $? != 0 ]; then - echo "Error doing module load: esmf-${esmfvers}-ncdfio-${mpi}-O" - exit 1 - fi - if [ -z "$ESMFBIN_PATH" ]; then - ESMFBIN_PATH=`grep ESMF_APPSDIR $ESMFMKFILE | awk -F= '{print $2}'` - fi - echo "ESMFMKFILE: $ESMFMKFILE" - echo "LD_LIBRARY_PATH: $LD_LIBRARY_PATH" - - if [ -z "$MPIEXEC" ]; then - MPIEXEC="mpiexec -n $REGRID_PROC" - fi - ;; - - ##no other machine currently supported - *) - echo "Machine $hostname NOT recognized" - ;; - -esac - -# Error checks -if [ ! -d "$ESMFBIN_PATH" ]; then - echo "Path to ESMF binary directory does NOT exist: $ESMFBIN_PATH" - echo "Set the environment variable: ESMFBIN_PATH" - exit 1 -fi - -#---------------------------------------------------------------------- -# Generate the mapping files needed for surface dataset generation -#---------------------------------------------------------------------- - -# Resolve interactive or batch mode command -# NOTE - if you want to run in batch mode - you need to have a separate -# batch file that calls this script interactively - you cannot submit -# this script to the batch system - -if [ "$interactive" = "NO" ]; then - echo "Running in batch mode using MPI" - if [ -z "$MPIEXEC" ]; then - echo "Name of MPI exec to use was NOT set" - echo "Set the environment variable: MPIEXEC" - exit 1 - fi - if [ ! -x `which ${MPIEXEC%% *}` ]; then - echo "The MPIEXEC pathname given is NOT an executable: ${MPIEXEC%% *}" - echo "Set the environment variable: MPIEXEC or run in interactive mode without MPI" - exit 1 - fi - mpirun=$MPIEXEC - echo "Running in batch mode" -else - mpirun="" -fi - -ESMF_REGRID="$ESMFBIN_PATH/ESMF_RegridWeightGen" -if [ ! -x "$ESMF_REGRID" ]; then - echo "ESMF_RegridWeightGen does NOT exist in ESMF binary directory: $ESMFBIN_PATH\n" - echo "Upgrade to a newer version of ESMF with this utility included" - echo "Set the environment variable: ESMFBIN_PATH" - exit 1 -fi - -# Remove previous log files -rm PET*.Log - -# -# Now run the mapping for each file, checking that input files exist -# and then afterwards that the output mapping file exists -# -declare -i nfile=1 -until ((nfile>${#INGRID[*]})); do - echo "Creating mapping file: ${OUTFILE[nfile]}" - echo "From input grid: ${INGRID[nfile]}" - echo "For output grid: $GRIDFILE" - echo " " - if [ -z "${INGRID[nfile]}" ] || [ -z "$GRIDFILE" ] || [ -z "${OUTFILE[nfile]}" ]; then - echo "Either input or output grid or output mapping file is NOT set" - exit 3 - fi - if [ ! -f "${INGRID[nfile]}" ]; then - echo "Input grid file does NOT exist: ${INGRID[nfile]}" - if [ ! "$list" = "YES" ]; then - exit 2 - fi - fi - if [ ! -f "$GRIDFILE" ]; then - echo "Output grid file does NOT exist: $GRIDFILE" - exit 3 - fi - - # Determine what (if any) large file support is needed. Use the - # most extreme large file support needed by either the source file - # or the destination file. - if [ "$DST_LRGFIL" = "netcdf4" ] || [ "${SRC_LRGFIL[nfile]}" = "netcdf4" ]; then - lrgfil="--netcdf4" - elif [ "$DST_LRGFIL" = "64bit_offset" ] || [ "${SRC_LRGFIL[nfile]}" = "64bit_offset" ]; then - lrgfil="--64bit_offset" - elif [ "$DST_LRGFIL" = "none" ] && [ "${SRC_LRGFIL[nfile]}" = "none" ]; then - lrgfil="" - else - echo "Unknown LRGFIL type:" - echo "DST_LRGFIL = $DST_LRGFIL" - echo "SRC_LRGFIL = ${SRC_LRGFIL[nfile]}" - exit 4 - fi - - # Skip if file already exists - if [ -f "${OUTFILE[nfile]}" ]; then - echo "Skipping creation of ${OUTFILE[nfile]} as already exists" - # Skip if large file and Fast mode is on - elif [ "$fast" = "YES" ] && [ "${SRC_LRGFIL[nfile]}" = "netcdf4" ]; then - echo "Skipping creation of ${OUTFILE[nfile]} as fast mode is on so skipping large files in NetCDF4 format" - else - - cmd="$mpirun $ESMF_REGRID --ignore_unmapped -s ${INGRID[nfile]} " - cmd="$cmd -d $GRIDFILE -m conserve -w ${OUTFILE[nfile]}" - if [ $type = "regional" ]; then - cmd="$cmd --dst_regional" - fi - - cmd="$cmd --src_type ${SRC_TYPE[nfile]} ${SRC_EXTRA_ARGS[nfile]} --dst_type $DST_TYPE $DST_EXTRA_ARGS" - cmd="$cmd $lrgfil" - - runcmd $cmd - - if [ "$debug" != "YES" ] && [ ! -f "${OUTFILE[nfile]}" ]; then - echo "Output mapping file was NOT created: ${OUTFILE[nfile]}" - exit 6 - fi - # add some metadata to the file - HOST=`hostname` - history="$ESMF_REGRID" - runcmd "ncatted -a history,global,a,c,"$history" ${OUTFILE[nfile]}" - runcmd "ncatted -a hostname,global,a,c,$HOST -h ${OUTFILE[nfile]}" - runcmd "ncatted -a logname,global,a,c,$LOGNAME -h ${OUTFILE[nfile]}" - fi - - nfile=nfile+1 -done - -echo "Successfully created needed mapping files for $res" - -exit 0 diff --git a/tools/mkmapdata/mvNimport.sh b/tools/mkmapdata/mvNimport.sh deleted file mode 100755 index 184a3fac25..0000000000 --- a/tools/mkmapdata/mvNimport.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash -# -# -# Batch script to move and import mapping files to inputdata -# for several resolutions. -# - -#---------------------------------------------------------------------- - -if [ -z "$CSMDATA" ]; then - CSMDATA=/fis/cgd/cseg/csm/inputdata -fi - -if [ ! -d "$CSMDATA" ]; then - echo "Environment variable CSMDATA is not set to a valid directory!" - exit 1 -fi - -mapdir="lnd/clm2/mappingdata/maps" -if [ ! -d "$CSMDATA/$mapdir" ]; then - echo "Environment variable CSMDATA is not set to a valid inputdata directory!" - exit 1 -fi - -if [ -z "$SVN_INP_DIR" ]; then - SVN_INP_DIR=https://svn-ccsm-inputdata.cgd.ucar.edu/trunk/inputdata -fi - -if [ $# -gt 0 ]; then - resols="" - for arg in $@; do - resols="$resols $arg" - done -else - echo "Run for all valid resolutions" - resols=`../bld/queryDefaultNamelist.pl -res list -silent` -fi -echo "Move and import mapping files for this list of resolutions: $resols" - -#---------------------------------------------------------------------- - -for res in $resols; do - echo "Move and import mapping files for: $res" - dir=$mapdir/$res - #---------------------------------------------------------------------- - files=(map_*${res}*_aave_da_c??????.nc) - if [ ${#files[*]} -lt 2 ]; then - echo "No mappingfiles found for $res" - exit 2 - else - if [ ! -d "$CSMDATA/$dir" ]; then - echo "Create mapping directory: $CSMDATA/$dir" - mkdir $CSMDATA/$dir - svn mkdir $SVN_INP_URL/$dir -m "Create mapping directory for $res" - fi - for file in ${files[*]}; do - echo "Copy and import file $file" - cp -p $file $CSMDATA/$dir - if [ $? -ne 0 ]; then - echo "Problem copying file: $file" - exit 3 - fi - chmod 0444 $CSMDATA/$dir/$file - if [ $? -ne 0 ]; then - echo "Problem chmod on file: $file" - exit 4 - fi - svn import $CSMDATA/$dir/$file $SVN_INP_DIR/$dir/$file -m "Mapping file for $res" - if [ $? -ne 0 ]; then - echo "Problem doing svn import on file: $file" - exit 4 - fi - done - fi -done diff --git a/tools/mkmapdata/regridbatch.sh b/tools/mkmapdata/regridbatch.sh deleted file mode 100755 index 8b56f2dc7d..0000000000 --- a/tools/mkmapdata/regridbatch.sh +++ /dev/null @@ -1,102 +0,0 @@ -#!/bin/bash -# -# -# Batch script to submit to create mapping files for all standard -# resolutions. If you provide a single resolution via "$RES", only -# that resolution will be used. In that case: If it is a regional or -# single point resolution, you should set '#PBS -n' to 1, and be sure -# that '-t regional' is specified in cmdargs. -# -# cheyenne specific batch commands: -#PBS -A P93300606 -#PBS -N regrid -#PBS -q regular -#PBS -l select=4:ncpus=2:mpiprocs=2:mem=109GB -#PBS -l walltime=2:00:00 -#PBS -j oe -#PBS -me -#PBS -V -#PBS -S /bin/bash - -#---------------------------------------------------------------------- -# Set parameters -#---------------------------------------------------------------------- - -#---------------------------------------------------------------------- -# Begin main script -#---------------------------------------------------------------------- - -if [ -z "$RES" ]; then - echo "Run for all valid resolutions" - resols=`../../bld/queryDefaultNamelist.pl -res list -silent` - if [ ! -z "$GRIDFILE" ]; then - echo "When GRIDFILE set RES also needs to be set for a single resolution" - exit 1 - fi -else - resols="$RES" -fi -if [ -z "$GRIDFILE" ]; then - grid="" -else - if [[ ${#resols[@]} > 1 ]]; then - echo "When GRIDFILE is specificed only one resolution can also be given (# resolutions ${#resols[@]})" - echo "Resolutions input is: $resols" - exit 1 - fi - grid="-f $GRIDFILE" -fi - -if [ -z "$MKMAPDATA_OPTIONS" ]; then - echo "Run with standard options" - options=" " -else - options="$MKMAPDATA_OPTIONS" -fi -echo "Create mapping files for this list of resolutions: $resols" - -#---------------------------------------------------------------------- - -for res in $resols; do - echo "Create mapping files for: $res" -#---------------------------------------------------------------------- - cmdargs="-r $res $grid $options" - - # For single-point and regional resolutions, tell mkmapdata that - # output type is regional - if [[ `echo "$res" | grep -c "1x1_"` -gt 0 || `echo "$res" | grep -c "5x5_"` -gt 0 ]]; then - res_type="regional" - else - res_type="global" - fi - # Assume if you are providing a gridfile that the grid is regional - if [ $grid != "" ];then - res_type="regional" - fi - - cmdargs="$cmdargs -t $res_type" - - echo "$res_type" - if [ "$res_type" = "regional" ]; then - echo "regional" - # For regional and (especially) single-point grids, we can get - # errors when trying to use multiple processors - so just use 1. - regrid_num_proc=1 - else - echo "global" - regrid_num_proc=8 - fi - - if [ ! -z "$LSFUSER" ]; then - echo "batch" - cmdargs="$cmdargs -b" - fi - if [ ! -z "$PBS_O_WORKDIR" ]; then - cd $PBS_O_WORKDIR - cmdargs="$cmdargs -b" - fi - - echo "args: $cmdargs" - echo "time env REGRID_PROC=$regrid_num_proc ./mkmapdata.sh $cmdargs\n" - time env REGRID_PROC=$regrid_num_proc ./mkmapdata.sh $cmdargs -done diff --git a/tools/mkmapdata/regridgeyser.sh b/tools/mkmapdata/regridgeyser.sh deleted file mode 100755 index 82a4615dcd..0000000000 --- a/tools/mkmapdata/regridgeyser.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/bash -# -# -# Batch script to submit to create mapping files for all standard -# resolutions. If you provide a single resolution via "$RES", only -# that resolution will be used. In that case: If it is a regional or -# single point resolution, you should set '#SBATCH -n' to 1, and be sure -# that '-t regional' is specified in cmdargs. -# -# geyser specific batch commands: -#SBATCH -J regrid # job name -#SBATCH -n 8 -#SBATCH --ntasks-per-node=8 -#SBATCH --mem=450G -#SBATCH -t 03:00:00 -#SBATCH -A P93300606 -#SBATCH -p dav -#SBATCH -e regrid.%J.out # output filename -#SBATCH -o regrid.%J.err # error filename -# -# To submit this script: -# -# sbatch regridgeyser.sh -# -## IMPORTANT NOTE: -# -# environment variables can NOT be passed into DAV -# queues. Hence, this script MUST be edited to select -# what resolution to run for. - -#---------------------------------------------------------------------- -# Set parameters -#---------------------------------------------------------------------- -export RES=1x1_brazil - -#---------------------------------------------------------------------- -# Begin main script -#---------------------------------------------------------------------- - -if [ -z "$RES" ]; then - echo "Run for all valid resolutions" - resols=`../../bld/queryDefaultNamelist.pl -res list -silent` -else - resols="$RES" -fi -echo "Create mapping files for this list of resolutions: $resols" - -#---------------------------------------------------------------------- - -for res in $resols; do - echo "Create mapping files for: $res" -#---------------------------------------------------------------------- - cmdargs="-r $res" - - # For single-point and regional resolutions, tell mkmapdata that - # output type is regional - if [[ `echo "$res" | grep -c "1x1_"` -gt 0 || `echo "$res" | grep -c "5x5_"` -gt 0 ]]; then - res_type="regional" - else - res_type="global" - fi - - cmdargs="$cmdargs -t $res_type" - - echo "$res_type" - if [ "$res_type" = "regional" ]; then - echo "regional" - # For regional and (especially) single-point grids, we can get - # errors when trying to use multiple processors - so just use 1. - # We also do NOT set batch mode in this case, because some - # machines (e.g., yellowstone) do not listen to REGRID_PROC, so to - # get a single processor, we need to run mkmapdata.sh in - # interactive mode. - regrid_num_proc=1 - else - echo "global" - regrid_num_proc=$SLURM_NTASKS - if [ ! -z "$SLURM_JOB_ACCOUNT" ]; then - echo "batch" - cmdargs="$cmdargs -b" - fi - fi - - echo "args: $cmdargs" - echo "time env REGRID_PROC=$regrid_num_proc ./mkmapdata.sh $cmdargs\n" - time env REGRID_PROC=$regrid_num_proc ./mkmapdata.sh $cmdargs -done diff --git a/tools/mkmapdata/rmdups.ncl b/tools/mkmapdata/rmdups.ncl deleted file mode 100644 index d5fff40d53..0000000000 --- a/tools/mkmapdata/rmdups.ncl +++ /dev/null @@ -1,131 +0,0 @@ -; -; Remove duplicate weights from a mapping file. -; -; Mark Taylor (converted for use by CLM mkmapdata by Erik Kluzek) -; Sep/01/2011 -; -load "$NCARG_NCARG/nclscripts/csm/gsn_code.ncl" -load "$NCARG_NCARG/nclscripts/csm/gsn_csm.ncl" -load "$NCARG_NCARG/nclscripts/csm/contributed.ncl" -begin - ; =========================================================================================================== - ; - ; IMPORTANT NOTE: EDIT THE FOLLOWING TO CUSTOMIZE or use ENV VARIABLE SETTINGS - ; Edit the following as needed - ; - ; Input mapping file to remove duplicate weights from a mapping file - ; - mapfile = getenv("MAPFILE") ; Get the mapping file - newmapfile = getenv("NEWMAPFILE") ; The new mapping file to create - logname = getenv("LOGNAME") ; Logname of user running the script - - if ( ismissing(mapfile) )then - print( "You did NOT enter an input mapping file to convert" ) - status_exit( -1 ) - end if - if ( ismissing(newmapfile) )then - sdate = systemfunc( "date +%y%m%d" ); - newmapfile = mapfile+"_c"+sdate+".nc"; - end if - ; =========================================================================================================== - - if ( systemfunc("test -f "+mapfile+"; echo $?" ) .ne. 0 )then - print( "Input file does not exist or not found: "+mapfile ); - status_exit( -1 ) - end if - print("map file: "+mapfile) - f = addfile(mapfile,"r") ; Open netCDF files. - - - n_s = dimsizes(f->col) - if ( n_s .eq. 0 )then - print( "n_s is size zero, so no overlap points just return: " ); - exit - end if - - n_b = dimsizes(f->area_b) - n_a = dimsizes(f->area_a) - print("n_s = "+n_s+" max(row)="+max(f->row)+" max(col)="+max(f->col)) - - - - row = f->row - col = f->col - - - print("checking for dups, sorting...") - hash = new( n_s, double ) - hash = col - hash= hash + row*n_b - index1d=dim_pqsort(hash,1) - row2=row(index1d) - col2=col(index1d) - S=f->S - print("zeroing out any dups...") - ndups=0 - i0=0 - do i=1,n_s-1 - if ( (col2(i) .eq. col2(i0)) .and. (row2(i) .eq. row2(i0))) then - iorig1 = index1d(i0) - iorig2 = index1d(i) - ;print("dup row: "+row2(i)+" "+row2(i0)+" "+row(iorig1)+" "+row(iorig2)) - ;print("dup col: "+col2(i)+" "+col2(i0)+" "+col(iorig1)+" "+col(iorig2)) - ;print("removing "+iorig2+" keeping "+iorig1) - S(iorig1)=S(iorig1)+S(iorig2) - S(iorig2)=0 - ndups=ndups+1 - ; dont increment i0 - else - i0=i - end if - end do - delete(row2) - delete(col2) - if ( ndups .gt. 0) then - print("ndups = "+ndups) - print("compacting S...") - ns2 = n_s-ndups - S2 = new( ns2, double) - row2= new( ns2, integer) - col2 = new( ns2, integer) - ns2=0 - do i=0,n_s-1 - if (S(i) .ne. 0) then - S2(ns2)=S(i) - row2(ns2)=row(i) - col2(ns2)=col(i) - ns2=ns2+1 - end if - end do - print("removed "+ndups+" dups") - delete(S) - delete(row) - delete(col) - S=S2 - row=row2 - col=col2 - n_s = ns2 - print("writing new netcdf file") - cmdout = systemfunc("ncks -O -x -v S,row,col "+mapfile+" "+newmapfile) - nco = addfile(newmapfile,"rw") ; Open netCDF files. - nco->S = S - nco->row = row - nco->col = col - ldate = systemfunc( "date" ); - nco@history = nco@history + ":"+ldate + ": "; - nco@history = nco@history + " Removed duplicate weights from mapping file with: rmdups.ncl " - nco@rmdups_Logname = logname; - nco@rmdups_mod_date = ldate; - nco@rmdups_version = systemfunc( "git describe" ); - - print("Successfully removed duplicate weights from mapping file" ); - - else - - print("No duplicate weights to remove from mapping file" ); - - end if - - - -end diff --git a/tools/toolchain/gen_mksurf_namelist b/tools/toolchain/gen_mksurf_namelist deleted file mode 100755 index ecd225dd19..0000000000 --- a/tools/toolchain/gen_mksurf_namelist +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python - -# 2020-11-08 Negin Sobhani - -""" -|------------------------------------------------------------------| -|--------------------- Instructions -----------------------------| -|------------------------------------------------------------------| -This is a just top-level skeleton script that calls -gen_mksurf_namelist.py. -The original code (./gen_mksurf_namelist.py) is located under -python/ctsm folder. - -This Python script is part of the simplified toolchain for creating -the surface dataset for ctsm cases. -This script should be used as the first step of the new toolchain. -It will automatically create namelist (control file) that is -needed for creating surface dataset and requisite intermediate files for -running CTSM cases. -For transient cases, it will also create a txt file that includes the -landuse files for every year. - -------------------------------------------------------------------- -Instructions for running on Cheyenne/Casper: - -load the following into your local environment: - - module load python - ncar_pylib -------------------------------------------------------------------- -To see the available options: - ./gen_mksurf_namelist.py --help - -To run the script: - ./gen_mksurf_namelist.py - -To remove NPL(ncar_pylib) from your environment on Cheyenne/Casper: - deactivate -------------------------------------------------------------------- -""" - -#TODO (NS) - -# -[x] Add default values in the help page. -# -[x] Add info for help page note for end_year -- by default is start_year -# -[ ] Possibly remove year --years and range options -# Currently comment them out. - -# -[ ] maybe a verbose option and removing debug -# -[x] --debug mode is not working... - -# -[ ] add error check for hi-res and years if they are 1850 and 2005. - -# -[x] different path for each range of years for transient cases. -# default should be picked based on the year. 1850 - 2015 --> -# /glade/p/cesm/cseg/inputdata/lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/ -# 850-1850 --> -# pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012 - -# -[ ] hirespft data only for 2005? - -# -- Import libraries -import os -import sys - -# -- add python/ctsm to path -_CTSM_PYTHON = os.path.join( - os.path.dirname(os.path.realpath(__file__)), os.pardir, os.pardir, "python" - ) -sys.path.insert(1, _CTSM_PYTHON) - -from ctsm.gen_mksurf_namelist import main - -if __name__ == "__main__": - main() - - From 016267eccfee0c80bd5f8ea06be4f3782cec315e Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 25 Apr 2022 16:08:30 -0600 Subject: [PATCH 143/614] cmake build working on cheyenne --- tools/mksurfdata_esmf/cmake/FindESMF.cmake | 130 +++++++ tools/mksurfdata_esmf/cmake/FindNetCDF.cmake | 347 ++++++++++++++++++ tools/mksurfdata_esmf/cmake/FindPnetCDF.cmake | 68 ++++ tools/mksurfdata_esmf/src/CMakeLists.txt | 38 +- 4 files changed, 561 insertions(+), 22 deletions(-) create mode 100644 tools/mksurfdata_esmf/cmake/FindESMF.cmake create mode 100644 tools/mksurfdata_esmf/cmake/FindNetCDF.cmake create mode 100644 tools/mksurfdata_esmf/cmake/FindPnetCDF.cmake diff --git a/tools/mksurfdata_esmf/cmake/FindESMF.cmake b/tools/mksurfdata_esmf/cmake/FindESMF.cmake new file mode 100644 index 0000000000..e67e45c489 --- /dev/null +++ b/tools/mksurfdata_esmf/cmake/FindESMF.cmake @@ -0,0 +1,130 @@ +# - Try to find ESMF +# +# Requires setting ESMFMKFILE to the filepath of esmf.mk. If this is NOT set, +# then ESMF_FOUND will always be FALSE. If ESMFMKFILE exists, then ESMF_FOUND=TRUE +# and all ESMF makefile variables will be set in the global scope. Optionally, +# set ESMF_MKGLOBALS to a string list to filter makefile variables. For example, +# to globally scope only ESMF_LIBSDIR and ESMF_APPSDIR variables, use this CMake +# command in CMakeLists.txt: +# +# set(ESMF_MKGLOBALS "LIBSDIR" "APPSDIR") + + +# Add the ESMFMKFILE path to the cache if defined as system env variable +if (DEFINED ENV{ESMFMKFILE} AND NOT DEFINED ESMFMKFILE) + set(ESMFMKFILE $ENV{ESMFMKFILE} CACHE FILEPATH "Path to ESMF mk file") +endif () + +# Found the mk file and ESMF exists on the system +if (EXISTS ${ESMFMKFILE}) + set(ESMF_FOUND TRUE CACHE BOOL "ESMF mk file found" FORCE) + # Did not find the ESMF mk file +else() + set(ESMF_FOUND FALSE CACHE BOOL "ESMF mk file NOT found" FORCE) + # Best to warn users that without the mk file there is no way to find ESMF + if (NOT DEFINED ESMFMKFILE) + message(FATAL_ERROR "ESMFMKFILE not defined. This is the path to esmf.mk file. \ +Without this filepath, ESMF_FOUND will always be FALSE.") + endif () +endif() + +# Only parse the mk file if it is found +if (ESMF_FOUND) + # Read the mk file + file(STRINGS "${ESMFMKFILE}" esmfmkfile_contents) + # Parse each line in the mk file + foreach(str ${esmfmkfile_contents}) + # Only consider uncommented lines + string(REGEX MATCH "^[^#]" def ${str}) + # Line is not commented + if (def) + # Extract the variable name + string(REGEX MATCH "^[^=]+" esmf_varname ${str}) + # Extract the variable's value + string(REGEX MATCH "=.+$" esmf_vardef ${str}) + # Only for variables with a defined value + if (esmf_vardef) + # Get rid of the assignment string + string(SUBSTRING ${esmf_vardef} 1 -1 esmf_vardef) + # Remove whitespace + string(STRIP ${esmf_vardef} esmf_vardef) + # A string or single-valued list + if(NOT DEFINED ESMF_MKGLOBALS) + # Set in global scope + set(${esmf_varname} ${esmf_vardef}) + # Don't display by default in GUI + mark_as_advanced(esmf_varname) + else() # Need to filter global promotion + foreach(m ${ESMF_MKGLOBALS}) + string(FIND ${esmf_varname} ${m} match) + # Found the string + if(NOT ${match} EQUAL -1) + # Promote to global scope + set(${esmf_varname} ${esmf_vardef}) + # Don't display by default in the GUI + mark_as_advanced (esmf_varname) + # No need to search for the current string filter + break() + endif() + endforeach() + endif() + endif() + endif() + endforeach() + + # Construct ESMF_VERSION from ESMF_VERSION_STRING_GIT + if(ESMF_FOUND) + # ESMF_VERSION_MAJOR and ESMF_VERSION_MINOR are defined in ESMFMKFILE + set(ESMF_VERSION 0) + set(ESMF_VERSION_PATCH ${ESMF_VERSION_REVISION}) + set(ESMF_BETA_RELEASE FALSE) + if(ESMF_VERSION_BETASNAPSHOT MATCHES "^('T')$") + set(ESMF_BETA_RELEASE TRUE) + string(REGEX REPLACE ".*beta_snapshot_*\([0-9]*\).*" "\\1" ESMF_BETA_SNAPSHOT "${ESMF_VERSION_STRING_GIT}") + endif() + set(ESMF_VERSION "${ESMF_VERSION_MAJOR}.${ESMF_VERSION_MINOR}.${ESMF_VERSION_PATCH}") + endif() + + separate_arguments(ESMF_F90COMPILEPATHS NATIVE_COMMAND ${ESMF_F90COMPILEPATHS}) + foreach (ITEM ${ESMF_F90COMPILEPATHS}) + string(REGEX REPLACE "^-I" "" ITEM "${ITEM}") + list(APPEND tmp ${ITEM}) + endforeach() + set(ESMF_F90COMPILEPATHS ${tmp}) + + add_library(esmf UNKNOWN IMPORTED) + # Look for static library, if not found try dynamic library + find_library(esmf_lib NAMES libesmf.a PATHS ${ESMF_LIBSDIR}) + if(esmf_lib MATCHES "esmf_lib-NOTFOUND") + message(STATUS "Static ESMF library not found, searching for dynamic library instead") + find_library(esmf_lib NAMES esmf_fullylinked PATHS ${ESMF_LIBSDIR}) + if(esmf_lib MATCHES "esmf_lib-NOTFOUND") + message(FATAL_ERROR "Neither the dynamic nor the static ESMF library was found") + endif() + set(ESMF_INTERFACE_LINK_LIBRARIES "") + else() + # When linking the static library, also need the ESMF linker flags; strip any leading/trailing whitespaces + string(STRIP "${ESMF_F90ESMFLINKRPATHS} ${ESMF_F90ESMFLINKPATHS} ${ESMF_F90LINKPATHS} ${ESMF_F90LINKLIBS} ${ESMF_F90LINKOPTS}" ESMF_INTERFACE_LINK_LIBRARIES) + endif() + + message(STATUS "Found ESMF library: ${esmf_lib}") + if(ESMF_BETA_RELEASE) + message(STATUS "Detected ESMF Beta snapshot ${ESMF_BETA_SNAPSHOT}") + endif() + + set_target_properties(esmf PROPERTIES + IMPORTED_LOCATION ${esmf_lib} + INTERFACE_INCLUDE_DIRECTORIES "${ESMF_F90COMPILEPATHS}" + INTERFACE_LINK_LIBRARIES "${ESMF_INTERFACE_LINK_LIBRARIES}") + +endif() + +## Finalize find_package +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args( ${CMAKE_FIND_PACKAGE_NAME} + REQUIRED_VARS ESMF_LIBSDIR + ESMF_INTERFACE_LINK_LIBRARIES + ESMF_F90COMPILEPATHS + VERSION_VAR ESMF_VERSION + HANDLE_COMPONENTS ) \ No newline at end of file diff --git a/tools/mksurfdata_esmf/cmake/FindNetCDF.cmake b/tools/mksurfdata_esmf/cmake/FindNetCDF.cmake new file mode 100644 index 0000000000..e335b95bd5 --- /dev/null +++ b/tools/mksurfdata_esmf/cmake/FindNetCDF.cmake @@ -0,0 +1,347 @@ +# (C) Copyright 2011- ECMWF. +# +# This software is licensed under the terms of the Apache Licence Version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +# In applying this licence, ECMWF does not waive the privileges and immunities +# granted to it by virtue of its status as an intergovernmental organisation nor +# does it submit to any jurisdiction. + +# Try to find NetCDF includes and library. +# Supports static and shared libaries and allows each component to be found in sepearte prefixes. +# +# This module defines +# +# - NetCDF_FOUND - System has NetCDF +# - NetCDF_INCLUDE_DIRS - the NetCDF include directories +# - NetCDF_VERSION - the version of NetCDF +# - NetCDF_CONFIG_EXECUTABLE - the netcdf-config executable if found +# - NetCDF_PARALLEL - Boolean True if NetCDF4 has parallel IO support via hdf5 and/or pnetcdf +# - NetCDF_HAS_PNETCDF - Boolean True if NetCDF4 has pnetcdf support +# +# Deprecated Defines +# - NetCDF_LIBRARIES - [Deprecated] Use NetCDF::NetCDF_ targets instead. +# +# +# Following components are available: +# +# - C - C interface to NetCDF (netcdf) +# - CXX - CXX4 interface to NetCDF (netcdf_c++4) +# - Fortran - Fortran interface to NetCDF (netcdff) +# +# For each component the following are defined: +# +# - NetCDF__FOUND - whether the component is found +# - NetCDF__LIBRARIES - the libraries for the component +# - NetCDF__LIBRARY_SHARED - Boolean is true if libraries for component are shared +# - NetCDF__INCLUDE_DIRS - the include directories for specified component +# - NetCDF::NetCDF_ - target of component to be used with target_link_libraries() +# +# The following paths will be searched in order if set in CMake (first priority) or environment (second priority) +# +# - NetCDF_ROOT - root of NetCDF installation +# - NetCDF_PATH - root of NetCDF installation +# +# The search process begins with locating NetCDF Include headers. If these are in a non-standard location, +# set one of the following CMake or environment variables to point to the location: +# +# - NetCDF_INCLUDE_DIR or NetCDF_${comp}_INCLUDE_DIR +# - NetCDF_INCLUDE_DIRS or NetCDF_${comp}_INCLUDE_DIR +# +# Notes: +# +# - Use "NetCDF::NetCDF_" targets only. NetCDF_LIBRARIES exists for backwards compatibility and should not be used. +# - These targets have all the knowledge of include directories and library search directories, and a single +# call to target_link_libraries will provide all these transitive properties to your target. Normally all that is +# needed to build and link against NetCDF is, e.g.: +# target_link_libraries(my_c_tgt PUBLIC NetCDF::NetCDF_C) +# - "NetCDF" is always the preferred naming for this package, its targets, variables, and environment variables +# - For compatibility, some variables are also set/checked using alternate names NetCDF4, NETCDF, or NETCDF4 +# - Environments relying on these older environment variable names should move to using a "NetCDF_ROOT" environment variable +# - Preferred component capitalization follows the CMake LANGUAGES variables: i.e., C, Fortran, CXX +# - For compatibility, alternate capitalizations are supported but should not be used. +# - If no components are defined, all components will be searched +# + +list( APPEND _possible_components C CXX Fortran ) + +## Include names for each component +set( NetCDF_C_INCLUDE_NAME netcdf.h ) +set( NetCDF_CXX_INCLUDE_NAME netcdf ) +set( NetCDF_Fortran_INCLUDE_NAME netcdf.mod ) + +## Library names for each component +set( NetCDF_C_LIBRARY_NAME netcdf ) +set( NetCDF_CXX_LIBRARY_NAME netcdf_c++4 ) +set( NetCDF_Fortran_LIBRARY_NAME netcdff ) + +## Enumerate search components +foreach( _comp ${_possible_components} ) + string( TOUPPER "${_comp}" _COMP ) + set( _arg_${_COMP} ${_comp} ) + set( _name_${_COMP} ${_comp} ) +endforeach() + +set( _search_components C) +foreach( _comp ${${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS} ) + string( TOUPPER "${_comp}" _COMP ) + set( _arg_${_COMP} ${_comp} ) + list( APPEND _search_components ${_name_${_COMP}} ) + if( NOT _name_${_COMP} ) + message(SEND_ERROR "Find${CMAKE_FIND_PACKAGE_NAME}: COMPONENT ${_comp} is not a valid component. Valid components: ${_possible_components}" ) + endif() +endforeach() +list( REMOVE_DUPLICATES _search_components ) + +## Search hints for finding include directories and libraries +foreach( _comp IN ITEMS "_" "_C_" "_Fortran_" "_CXX_" ) + foreach( _name IN ITEMS NetCDF4 NetCDF NETCDF4 NETCDF ) + foreach( _var IN ITEMS ROOT PATH ) + list(APPEND _search_hints ${${_name}${_comp}${_var}} $ENV{${_name}${_comp}${_var}} ) + list(APPEND _include_search_hints + ${${_name}${_comp}INCLUDE_DIR} $ENV{${_name}${_comp}INCLUDE_DIR} + ${${_name}${_comp}INCLUDE_DIRS} $ENV{${_name}${_comp}INCLUDE_DIRS} ) + endforeach() + endforeach() +endforeach() +#Old-school HPC module env variable names +foreach( _name IN ITEMS NetCDF4 NetCDF NETCDF4 NETCDF ) + foreach( _comp IN ITEMS "_C" "_Fortran" "_CXX" ) + list(APPEND _search_hints ${${_name}} $ENV{${_name}}) + list(APPEND _search_hints ${${_name}${_comp}} $ENV{${_name}${_comp}}) + endforeach() +endforeach() + +## Find headers for each component +set(NetCDF_INCLUDE_DIRS) +set(_new_search_components) +foreach( _comp IN LISTS _search_components ) + if(NOT ${PROJECT_NAME}_NetCDF_${_comp}_FOUND) + list(APPEND _new_search_components ${_comp}) + endif() + find_file(NetCDF_${_comp}_INCLUDE_FILE + NAMES ${NetCDF_${_comp}_INCLUDE_NAME} + DOC "NetCDF ${_comp} include directory" + HINTS ${_include_search_hints} ${_search_hints} + PATH_SUFFIXES include include/netcdf + ) + mark_as_advanced(NetCDF_${_comp}_INCLUDE_FILE) + message(DEBUG "NetCDF_${_comp}_INCLUDE_FILE: ${NetCDF_${_comp}_INCLUDE_FILE}") + if( NetCDF_${_comp}_INCLUDE_FILE ) + get_filename_component(NetCDF_${_comp}_INCLUDE_FILE ${NetCDF_${_comp}_INCLUDE_FILE} ABSOLUTE) + get_filename_component(NetCDF_${_comp}_INCLUDE_DIR ${NetCDF_${_comp}_INCLUDE_FILE} DIRECTORY) + list(APPEND NetCDF_INCLUDE_DIRS ${NetCDF_${_comp}_INCLUDE_DIR}) + endif() +endforeach() +if(NetCDF_INCLUDE_DIRS) + list(REMOVE_DUPLICATES NetCDF_INCLUDE_DIRS) +endif() +set(NetCDF_INCLUDE_DIRS "${NetCDF_INCLUDE_DIRS}" CACHE STRING "NetCDF Include directory paths" FORCE) + +## Find n*-config executables for search components +foreach( _comp IN LISTS _search_components ) + if( _comp MATCHES "^(C)$" ) + set(_conf "c") + elseif( _comp MATCHES "^(Fortran)$" ) + set(_conf "f") + elseif( _comp MATCHES "^(CXX)$" ) + set(_conf "cxx4") + endif() + find_program( NetCDF_${_comp}_CONFIG_EXECUTABLE + NAMES n${_conf}-config + HINTS ${NetCDF_INCLUDE_DIRS} ${_include_search_hints} ${_search_hints} + PATH_SUFFIXES bin Bin ../bin ../../bin + DOC "NetCDF n${_conf}-config helper" ) + message(DEBUG "NetCDF_${_comp}_CONFIG_EXECUTABLE: ${NetCDF_${_comp}_CONFIG_EXECUTABLE}") +endforeach() + +set(_C_libs_flag --libs) +set(_Fortran_libs_flag --flibs) +set(_CXX_libs_flag --libs) +set(_C_includes_flag --includedir) +set(_Fortran_includes_flag --includedir) +set(_CXX_includes_flag --includedir) +function(netcdf_config exec flag output_var) + set(${output_var} False PARENT_SCOPE) + if( exec ) + execute_process( COMMAND ${exec} ${flag} RESULT_VARIABLE _ret OUTPUT_VARIABLE _val) + if( _ret EQUAL 0 ) + string( STRIP ${_val} _val ) + set( ${output_var} ${_val} PARENT_SCOPE ) + endif() + endif() +endfunction() + +## Detect additional package properties +netcdf_config(${NetCDF_C_CONFIG_EXECUTABLE} --has-parallel4 _val) +if( NOT _val MATCHES "^(yes|no)$" ) + netcdf_config(${NetCDF_C_CONFIG_EXECUTABLE} --has-parallel _val) +endif() +if( _val MATCHES "^(yes)$" ) + set(NetCDF_PARALLEL TRUE CACHE STRING "NetCDF has parallel IO capability via pnetcdf or hdf5." FORCE) +else() + set(NetCDF_PARALLEL FALSE CACHE STRING "NetCDF has no parallel IO capability." FORCE) +endif() + +if(NetCDF_PARALLEL) + find_package(MPI REQUIRED) +endif() + +## Find libraries for each component +set( NetCDF_LIBRARIES ) +foreach( _comp IN LISTS _search_components ) + string( TOUPPER "${_comp}" _COMP ) + + find_library( NetCDF_${_comp}_LIBRARY + NAMES ${NetCDF_${_comp}_LIBRARY_NAME} + DOC "NetCDF ${_comp} library" + HINTS ${NetCDF_${_comp}_INCLUDE_DIRS} ${_search_hints} + PATH_SUFFIXES lib64 lib ../lib64 ../lib ../../lib64 ../../lib ) + mark_as_advanced( NetCDF_${_comp}_LIBRARY ) + get_filename_component(NetCDF_${_comp}_LIBRARY ${NetCDF_${_comp}_LIBRARY} ABSOLUTE) + set(NetCDF_${_comp}_LIBRARY ${NetCDF_${_comp}_LIBRARY} CACHE STRING "NetCDF ${_comp} library" FORCE) + message(DEBUG "NetCDF_${_comp}_LIBRARY: ${NetCDF_${_comp}_LIBRARY}") + + if( NetCDF_${_comp}_LIBRARY ) + if( NetCDF_${_comp}_LIBRARY MATCHES ".a$" ) + set( NetCDF_${_comp}_LIBRARY_SHARED FALSE ) + set( _library_type STATIC) + else() + list( APPEND NetCDF_LIBRARIES ${NetCDF_${_comp}_LIBRARY} ) + set( NetCDF_${_comp}_LIBRARY_SHARED TRUE ) + set( _library_type SHARED) + endif() + endif() + + #Use nc-config to set per-component LIBRARIES variable if possible + netcdf_config( ${NetCDF_${_comp}_CONFIG_EXECUTABLE} ${_${_comp}_libs_flag} _val ) + if( _val ) + set( NetCDF_${_comp}_LIBRARIES ${_val} ) + if(NOT NetCDF_${_comp}_LIBRARY_SHARED AND NOT NetCDF_${_comp}_FOUND) #Static targets should use nc_config to get a proper link line with all necessary static targets. + list( APPEND NetCDF_LIBRARIES ${NetCDF_${_comp}_LIBRARIES} ) + endif() + else() + set( NetCDF_${_comp}_LIBRARIES ${NetCDF_${_comp}_LIBRARY} ) + if(NOT NetCDF_${_comp}_LIBRARY_SHARED) + message(SEND_ERROR "Unable to properly find NetCDF. Found static libraries at: ${NetCDF_${_comp}_LIBRARY} but could not run nc-config: ${NetCDF_CONFIG_EXECUTABLE}") + endif() + endif() + + #Use nc-config to set per-component INCLUDE_DIRS variable if possible + netcdf_config( ${NetCDF_${_comp}_CONFIG_EXECUTABLE} ${_${_comp}_includes_flag} _val ) + if( _val ) + string( REPLACE " " ";" _val ${_val} ) + set( NetCDF_${_comp}_INCLUDE_DIRS ${_val} ) + else() + set( NetCDF_${_comp}_INCLUDE_DIRS ${NetCDF_${_comp}_INCLUDE_DIR} ) + endif() + + if( NetCDF_${_comp}_LIBRARIES AND NetCDF_${_comp}_INCLUDE_DIRS ) + set( ${CMAKE_FIND_PACKAGE_NAME}_${_arg_${_COMP}}_FOUND TRUE ) + if (NOT TARGET NetCDF::NetCDF_${_comp}) + add_library(NetCDF::NetCDF_${_comp} ${_library_type} IMPORTED) + set_target_properties(NetCDF::NetCDF_${_comp} PROPERTIES + IMPORTED_LOCATION ${NetCDF_${_comp}_LIBRARY} + INTERFACE_INCLUDE_DIRECTORIES "${NetCDF_${_comp}_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES ${NetCDF_${_comp}_LIBRARIES} ) + if( NOT _comp MATCHES "^(C)$" ) + target_link_libraries(NetCDF::NetCDF_${_comp} INTERFACE NetCDF::NetCDF_C) + endif() + if(MPI_${_comp}_FOUND) + target_link_libraries(NetCDF::NetCDF_${_comp} INTERFACE MPI::MPI_${_comp}) + endif() + endif() + endif() +endforeach() +if(NetCDF_LIBRARIES AND NetCDF_${_comp}_LIBRARY_SHARED) + list(REMOVE_DUPLICATES NetCDF_LIBRARIES) +endif() +set(NetCDF_LIBRARIES "${NetCDF_LIBRARIES}" CACHE STRING "NetCDF library targets" FORCE) + +## Find version via netcdf-config if possible +if (NetCDF_INCLUDE_DIRS) + if( NetCDF_C_CONFIG_EXECUTABLE ) + netcdf_config( ${NetCDF_C_CONFIG_EXECUTABLE} --version _vers ) + if( _vers ) + string(REGEX REPLACE ".* ((([0-9]+)\\.)+([0-9]+)).*" "\\1" NetCDF_VERSION "${_vers}" ) + endif() + else() + foreach( _dir IN LISTS NetCDF_INCLUDE_DIRS) + if( EXISTS "${_dir}/netcdf_meta.h" ) + file(STRINGS "${_dir}/netcdf_meta.h" _netcdf_version_lines + REGEX "#define[ \t]+NC_VERSION_(MAJOR|MINOR|PATCH|NOTE)") + string(REGEX REPLACE ".*NC_VERSION_MAJOR *\([0-9]*\).*" "\\1" _netcdf_version_major "${_netcdf_version_lines}") + string(REGEX REPLACE ".*NC_VERSION_MINOR *\([0-9]*\).*" "\\1" _netcdf_version_minor "${_netcdf_version_lines}") + string(REGEX REPLACE ".*NC_VERSION_PATCH *\([0-9]*\).*" "\\1" _netcdf_version_patch "${_netcdf_version_lines}") + string(REGEX REPLACE ".*NC_VERSION_NOTE *\"\([^\"]*\)\".*" "\\1" _netcdf_version_note "${_netcdf_version_lines}") + set(NetCDF_VERSION "${_netcdf_version_major}.${_netcdf_version_minor}.${_netcdf_version_patch}${_netcdf_version_note}") + unset(_netcdf_version_major) + unset(_netcdf_version_minor) + unset(_netcdf_version_patch) + unset(_netcdf_version_note) + unset(_netcdf_version_lines) + endif() + endforeach() + endif() +endif () + +## Finalize find_package +include(FindPackageHandleStandardArgs) + +if(NOT NetCDF_FOUND OR _new_search_components) + find_package_handle_standard_args( ${CMAKE_FIND_PACKAGE_NAME} + REQUIRED_VARS NetCDF_INCLUDE_DIRS NetCDF_LIBRARIES + VERSION_VAR NetCDF_VERSION + HANDLE_COMPONENTS ) +endif() + +foreach( _comp IN LISTS _search_components ) + if( NetCDF_${_comp}_FOUND ) + #Record found components to avoid duplication in NetCDF_LIBRARIES for static libraries + set(NetCDF_${_comp}_FOUND ${NetCDF_${_comp}_FOUND} CACHE BOOL "NetCDF ${_comp} Found" FORCE) + #Set a per-package, per-component found variable to communicate between multiple calls to find_package() + set(${PROJECT_NAME}_NetCDF_${_comp}_FOUND True) + endif() +endforeach() + +if( ${CMAKE_FIND_PACKAGE_NAME}_FOUND AND NOT ${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY AND _new_search_components) + message( STATUS "Find${CMAKE_FIND_PACKAGE_NAME} defines targets:" ) + message( STATUS " - NetCDF_VERSION [${NetCDF_VERSION}]") + message( STATUS " - NetCDF_PARALLEL [${NetCDF_PARALLEL}]") + foreach( _comp IN LISTS _new_search_components ) + string( TOUPPER "${_comp}" _COMP ) + message( STATUS " - NetCDF_${_comp}_CONFIG_EXECUTABLE [${NetCDF_${_comp}_CONFIG_EXECUTABLE}]") + if( ${CMAKE_FIND_PACKAGE_NAME}_${_arg_${_COMP}}_FOUND ) + get_filename_component(_root ${NetCDF_${_comp}_INCLUDE_DIR}/.. ABSOLUTE) + if( NetCDF_${_comp}_LIBRARY_SHARED ) + message( STATUS " - NetCDF::NetCDF_${_comp} [SHARED] [Root: ${_root}] Lib: ${NetCDF_${_comp}_LIBRARY} ") + else() + message( STATUS " - NetCDF::NetCDF_${_comp} [STATIC] [Root: ${_root}] Lib: ${NetCDF_${_comp}_LIBRARY} ") + endif() + endif() + endforeach() +endif() + +foreach( _prefix NetCDF NetCDF4 NETCDF NETCDF4 ${CMAKE_FIND_PACKAGE_NAME} ) + set( ${_prefix}_INCLUDE_DIRS ${NetCDF_INCLUDE_DIRS} ) + set( ${_prefix}_LIBRARIES ${NetCDF_LIBRARIES}) + set( ${_prefix}_VERSION ${NetCDF_VERSION} ) + set( ${_prefix}_FOUND ${${CMAKE_FIND_PACKAGE_NAME}_FOUND} ) + set( ${_prefix}_CONFIG_EXECUTABLE ${NetCDF_CONFIG_EXECUTABLE} ) + set( ${_prefix}_PARALLEL ${NetCDF_PARALLEL} ) + + foreach( _comp ${_search_components} ) + string( TOUPPER "${_comp}" _COMP ) + set( _arg_comp ${_arg_${_COMP}} ) + set( ${_prefix}_${_comp}_FOUND ${${CMAKE_FIND_PACKAGE_NAME}_${_arg_comp}_FOUND} ) + set( ${_prefix}_${_COMP}_FOUND ${${CMAKE_FIND_PACKAGE_NAME}_${_arg_comp}_FOUND} ) + set( ${_prefix}_${_arg_comp}_FOUND ${${CMAKE_FIND_PACKAGE_NAME}_${_arg_comp}_FOUND} ) + + set( ${_prefix}_${_comp}_LIBRARIES ${NetCDF_${_comp}_LIBRARIES} ) + set( ${_prefix}_${_COMP}_LIBRARIES ${NetCDF_${_comp}_LIBRARIES} ) + set( ${_prefix}_${_arg_comp}_LIBRARIES ${NetCDF_${_comp}_LIBRARIES} ) + + set( ${_prefix}_${_comp}_INCLUDE_DIRS ${NetCDF_${_comp}_INCLUDE_DIRS} ) + set( ${_prefix}_${_COMP}_INCLUDE_DIRS ${NetCDF_${_comp}_INCLUDE_DIRS} ) + set( ${_prefix}_${_arg_comp}_INCLUDE_DIRS ${NetCDF_${_comp}_INCLUDE_DIRS} ) + endforeach() +endforeach() \ No newline at end of file diff --git a/tools/mksurfdata_esmf/cmake/FindPnetCDF.cmake b/tools/mksurfdata_esmf/cmake/FindPnetCDF.cmake new file mode 100644 index 0000000000..b87d245cd1 --- /dev/null +++ b/tools/mksurfdata_esmf/cmake/FindPnetCDF.cmake @@ -0,0 +1,68 @@ +# - Try to find PnetCDF +# +# This can be controlled by setting the PnetCDF_PATH (or, equivalently, the +# PNETCDF environment variable), or PnetCDF__PATH CMake variables, where +# is the COMPONENT language one needs. +# +# Once done, this will define: +# +# PnetCDF__FOUND (BOOL) - system has PnetCDF +# PnetCDF__IS_SHARED (BOOL) - whether library is shared/dynamic +# PnetCDF__INCLUDE_DIR (PATH) - Location of the C header file +# PnetCDF__INCLUDE_DIRS (LIST) - the PnetCDF include directories +# PnetCDF__LIBRARY (FILE) - Path to the C library file +# PnetCDF__LIBRARIES (LIST) - link these to use PnetCDF +# +# The available COMPONENTS are: C, Fortran +# If no components are specified, it assumes only C +include (LibFind) +include (LibCheck) + +# Define PnetCDF C Component +define_package_component (PnetCDF DEFAULT + COMPONENT C + INCLUDE_NAMES pnetcdf.h + LIBRARY_NAMES pnetcdf) + +# Define PnetCDF Fortran Component +define_package_component (PnetCDF + COMPONENT Fortran + INCLUDE_NAMES pnetcdf.mod pnetcdf.inc + LIBRARY_NAMES pnetcdf) + +# Search for list of valid components requested +find_valid_components (PnetCDF) + +#============================================================================== +# SEARCH FOR VALIDATED COMPONENTS +foreach (PNCDFcomp IN LISTS PnetCDF_FIND_VALID_COMPONENTS) + + # If not found already, search... + if (NOT PnetCDF_${PNCDFcomp}_FOUND) + + # Manually add the MPI include and library dirs to search paths + # and search for the package component + if (MPI_${PNCDFcomp}_FOUND) + initialize_paths (PnetCDF_${PNCDFcomp}_PATHS + INCLUDE_DIRECTORIES ${MPI_${PNCDFcomp}_INCLUDE_PATH} + LIBRARIES ${MPI_${PNCDFcomp}_LIBRARIES}) + find_package_component(PnetCDF COMPONENT ${PNCDFcomp} + PATHS ${PnetCDF_${PNCDFcomp}_PATHS}) + else () + find_package_component(PnetCDF COMPONENT ${PNCDFcomp}) + endif () + + # Continue only if component found + if (PnetCDF_${PNCDFcomp}_FOUND) + + # Check version + check_version (PnetCDF + NAME "pnetcdf.h" + HINTS ${PnetCDF_${PNCDFcomp}_INCLUDE_DIR} + MACRO_REGEX "PNETCDF_VERSION_") + + endif () + + endif () + +endforeach () diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 597dadaf9e..be8da28083 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -1,20 +1,9 @@ cmake_minimum_required(VERSION 3.10) project(mksurfdata Fortran) -set (ESMFMKFILE /glade/work/oehmke/ESMF/scalable_mesh_from_file/lib/libg/Linux.intel.64.mpt.default/esmf.mk) - -file(STRINGS ${ESMFMKFILE} esmf_mk_text) -foreach(line ${esmf_mk_text}) - string(REGEX REPLACE "^[ ]+" "" line ${line}) # strip leading spaces - if (line MATCHES "^ESMF_*") # process only line starting with ESMF_ - string(REGEX MATCH "^ESMF_[^=]+" esmf_name ${line}) - string(REPLACE "${esmf_name}=" "" emsf_value ${line}) - set(${esmf_name} "${emsf_value}") - endif() -endforeach() -string(REPLACE "-I" "" ESMF_F90COMPILEPATHS ${ESMF_F90COMPILEPATHS}) -string(REPLACE " " ";" ESMF_F90COMPILEPATHS ${ESMF_F90COMPILEPATHS}) -message("ESMF_F90COMPILEPATHS: ${ESMF_F90COMPILEPATHS}") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") +find_package(NetCDF 4.8.1 REQUIRED Fortran) +find_package(ESMF 8.3.0 REQUIRED ) set(SRCFILES mkagfirepkmonthMod.F90 mkchecksMod.F90 @@ -52,18 +41,23 @@ set(SRCFILES mkagfirepkmonthMod.F90 shr_const_mod.F90 shr_kind_mod.F90 shr_string_mod.F90 - shr_sys_mod.F90) - -add_library(mksurfdata ${SRCFILES}) + shr_sys_mod.F90 + mksurfdata.F90) add_compile_definitions(PIO2) -message("CMAKE_CURRENT_BINARY_DIR is ${CMAKE_CURRENT_BINARY_DIR}") -message("PROJECT_BINARY_DIR is ${PROJECT_BINARY_DIR}") +add_library(pnetcdf STATIC IMPORTED) +set_property(TARGET pnetcdf PROPERTY IMPORTED_LOCATION $ENV{PNETCDF}) +add_library(pioc STATIC IMPORTED) +add_library(piof STATIC IMPORTED) +set_property(TARGET pioc PROPERTY IMPORTED_LOCATION $ENV{PIO}/lib/libpioc.a) +set_property(TARGET piof PROPERTY IMPORTED_LOCATION $ENV{PIO}/lib/libpiof.a) +add_executable(mksurfdata ${SRCFILES}) +target_link_libraries(mksurfdata PRIVATE esmf pioc piof) target_include_directories (mksurfdata PRIVATE ${ESMF_F90COMPILEPATHS}) -target_include_directories (mksurfdata PRIVATE /glade/work/jedwards/tools/pio/2.5.5/intel/19.1.1/mpt/2.22/include) -target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/pnetcdf/1.12.2/mpt/2.22/intel/19.1.1//include) -target_include_directories (mksurfdata PRIVATE /glade/u/apps/ch/opt/netcdf-mpi/4.8.1/mpt/2.22/intel/19.1.1//include) +target_include_directories (mksurfdata PRIVATE ${PIO}/include) +target_include_directories (mksurfdata PRIVATE ${PNETCDF}/include) +target_include_directories (mksurfdata PRIVATE ${NETCDF}/include) install(TARGETS mksurfdata) From 50a1c5fce0fc678ea930905c8c094822a16f6690 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 25 Apr 2022 16:12:36 -0600 Subject: [PATCH 144/614] remove unused files --- tools/mksurfdata_esmf/cmake/FindPnetCDF.cmake | 68 ------------------- tools/mksurfdata_esmf/src/Makefile | 67 ------------------ 2 files changed, 135 deletions(-) delete mode 100644 tools/mksurfdata_esmf/cmake/FindPnetCDF.cmake delete mode 100644 tools/mksurfdata_esmf/src/Makefile diff --git a/tools/mksurfdata_esmf/cmake/FindPnetCDF.cmake b/tools/mksurfdata_esmf/cmake/FindPnetCDF.cmake deleted file mode 100644 index b87d245cd1..0000000000 --- a/tools/mksurfdata_esmf/cmake/FindPnetCDF.cmake +++ /dev/null @@ -1,68 +0,0 @@ -# - Try to find PnetCDF -# -# This can be controlled by setting the PnetCDF_PATH (or, equivalently, the -# PNETCDF environment variable), or PnetCDF__PATH CMake variables, where -# is the COMPONENT language one needs. -# -# Once done, this will define: -# -# PnetCDF__FOUND (BOOL) - system has PnetCDF -# PnetCDF__IS_SHARED (BOOL) - whether library is shared/dynamic -# PnetCDF__INCLUDE_DIR (PATH) - Location of the C header file -# PnetCDF__INCLUDE_DIRS (LIST) - the PnetCDF include directories -# PnetCDF__LIBRARY (FILE) - Path to the C library file -# PnetCDF__LIBRARIES (LIST) - link these to use PnetCDF -# -# The available COMPONENTS are: C, Fortran -# If no components are specified, it assumes only C -include (LibFind) -include (LibCheck) - -# Define PnetCDF C Component -define_package_component (PnetCDF DEFAULT - COMPONENT C - INCLUDE_NAMES pnetcdf.h - LIBRARY_NAMES pnetcdf) - -# Define PnetCDF Fortran Component -define_package_component (PnetCDF - COMPONENT Fortran - INCLUDE_NAMES pnetcdf.mod pnetcdf.inc - LIBRARY_NAMES pnetcdf) - -# Search for list of valid components requested -find_valid_components (PnetCDF) - -#============================================================================== -# SEARCH FOR VALIDATED COMPONENTS -foreach (PNCDFcomp IN LISTS PnetCDF_FIND_VALID_COMPONENTS) - - # If not found already, search... - if (NOT PnetCDF_${PNCDFcomp}_FOUND) - - # Manually add the MPI include and library dirs to search paths - # and search for the package component - if (MPI_${PNCDFcomp}_FOUND) - initialize_paths (PnetCDF_${PNCDFcomp}_PATHS - INCLUDE_DIRECTORIES ${MPI_${PNCDFcomp}_INCLUDE_PATH} - LIBRARIES ${MPI_${PNCDFcomp}_LIBRARIES}) - find_package_component(PnetCDF COMPONENT ${PNCDFcomp} - PATHS ${PnetCDF_${PNCDFcomp}_PATHS}) - else () - find_package_component(PnetCDF COMPONENT ${PNCDFcomp}) - endif () - - # Continue only if component found - if (PnetCDF_${PNCDFcomp}_FOUND) - - # Check version - check_version (PnetCDF - NAME "pnetcdf.h" - HINTS ${PnetCDF_${PNCDFcomp}_INCLUDE_DIR} - MACRO_REGEX "PNETCDF_VERSION_") - - endif () - - endif () - -endforeach () diff --git a/tools/mksurfdata_esmf/src/Makefile b/tools/mksurfdata_esmf/src/Makefile deleted file mode 100644 index dc3570168d..0000000000 --- a/tools/mksurfdata_esmf/src/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -# GNU Makefile template for user ESMF application - -################################################################################ -################################################################################ -## This Makefile must be able to find the "esmf.mk" Makefile fragment in the ## -## 'include' line below. Following the ESMF User's Guide, a complete ESMF ## -## installation should ensure that a single environment variable "ESMFMKFILE" ## -## is made available on the system. This variable should point to the ## -## "esmf.mk" file. ## -## ## -## This example Makefile uses the "ESMFMKFILE" environment variable. ## -## ## -## If you notice that this Makefile cannot find variable ESMFMKFILE then ## -## please contact the person responsible for the ESMF installation on your ## -## system. ## -## As a work-around you can simply hardcode the path to "esmf.mk" in the ## -## include line below. However, doing so will render this Makefile a lot less ## -## flexible and non-portable. ## -################################################################################ - - -COMPILEPATH = -I$(MKSURFDATA_BLD) -I/glade/u/apps/ch/opt/pio/2.5.5/mpt/2.22/intel/19.1.1/include -LINKPATH = -L$(MKSURFDATA_BLD) -PIO_LINKPATH = -L/glade/work/jedwards/tools/pio/2.5.5/intel/19.1.1/mpt/2.22/lib -L/glade/u/apps/ch/opt/pnetcdf/1.12.2/mpt/2.22/intel/19.1.1//lib -L/glade/u/apps/ch/opt/netcdf/4.7.3/intel/19.0.5/lib - -ESMFMKFILE=/glade/work/oehmke/ESMF/scalable_mesh_from_file/lib/libg/Linux.intel.64.mpt.default/esmf.mk -include $(ESMFMKFILE) - -################################################################################ -################################################################################ - -.SUFFIXES: .f90 .F90 .c .C - -%.o : %.f90 - $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) $(ESMF_F90COMPILEFREENOCPP) $(COMPILEPATH) $< - -%.o : %.F90 - $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) $(ESMF_F90COMPILEFREECPP) $(ESMF_F90COMPILECPPFLAGS) $(COMPILEPATH) $< - -%.o : %.c - $(ESMF_CXXCOMPILER) -c $(ESMF_CXXCOMPILEOPTS) $(ESMF_CXXCOMPILEPATHSLOCAL) $(ESMF_CXXCOMPILEPATHS) $(ESMF_CXXCOMPILECPPFLAGS) $< - -%.o : %.C - $(ESMF_CXXCOMPILER) -c $(ESMF_CXXCOMPILEOPTS) $(ESMF_CXXCOMPILEPATHSLOCAL) $(ESMF_CXXCOMPILEPATHS) $(ESMF_CXXCOMPILECPPFLAGS) $< - -# ----------------------------------------------------------------------------- -mksurfdata: mksurfdata.o - $(ESMF_F90LINKER) -g $(LINKPATH) $(PIO_LINKPATH) $(ESMF_F90LINKOPTS) $(ESMF_F90LINKPATHS) $(ESMF_F90LINKRPATHS) -o $@ $^ $(ESMF_F90ESMFLINKLIBS) -l mksurfdata -l piof -l pnetcdf -lnetcdf - -# ----------------------------------------------------------------------------- -# ----------------------------------------------------------------------------- -.PHONY: dust clean distclean info edit -dust: - rm -f PET*.ESMF_LogFile *.nc *.stdout -clean: - rm -f esmApp *.o *.mod -distclean: dust clean - -info: - @echo ================================================================== - @echo ESMFMKFILE=$(ESMFMKFILE) - @echo ================================================================== - @cat $(ESMFMKFILE) - @echo ================================================================== - -run: - $(ESMF_INTERNAL_MPIRUN) -np 4 ./esmApp From 3496e14d594879def6dffe24e8591c3e0faadf9a Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 26 Apr 2022 16:50:19 -0600 Subject: [PATCH 145/614] builds on izumi with $PIO --- tools/mksurfdata_esmf/src/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index be8da28083..8720f3188a 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.10) project(mksurfdata Fortran) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") -find_package(NetCDF 4.8.1 REQUIRED Fortran) -find_package(ESMF 8.3.0 REQUIRED ) +find_package(NetCDF 4.7.4 REQUIRED Fortran) +find_package(ESMF 8.2.0 REQUIRED ) set(SRCFILES mkagfirepkmonthMod.F90 mkchecksMod.F90 @@ -54,9 +54,9 @@ add_library(piof STATIC IMPORTED) set_property(TARGET pioc PROPERTY IMPORTED_LOCATION $ENV{PIO}/lib/libpioc.a) set_property(TARGET piof PROPERTY IMPORTED_LOCATION $ENV{PIO}/lib/libpiof.a) add_executable(mksurfdata ${SRCFILES}) -target_link_libraries(mksurfdata PRIVATE esmf pioc piof) +target_link_libraries(mksurfdata PRIVATE esmf piof pioc) target_include_directories (mksurfdata PRIVATE ${ESMF_F90COMPILEPATHS}) -target_include_directories (mksurfdata PRIVATE ${PIO}/include) +target_include_directories (mksurfdata PRIVATE $ENV{PIO}/include) target_include_directories (mksurfdata PRIVATE ${PNETCDF}/include) target_include_directories (mksurfdata PRIVATE ${NETCDF}/include) From 3dd40425078df86da9fd562617dea58a581193c6 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 27 Apr 2022 23:05:38 -0600 Subject: [PATCH 146/614] updated README --- tools/mksurfdata_esmf/README | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index c719e0df74..fb40164865 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -15,26 +15,28 @@ Getting the code ======================= building the executable ======================= +> bash + +> module load intel +> module load python +> module load cmake +> module use /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ +> module load esmf-8.3.0b13-ncdfio-mpt-O +> module unload netcdf/4.8.1 +> module load netcdf-mpi/4.8.1 +> module load pnetcdf/1.12.2 +> module load pio/2.5.7 +> module list + > cd tools/mksurfdata_esmf > rm -rf bld # (or the contents of /bld) before rerunning CC=... > mkdir ./bld > cd bld -> module load intel # I found I need the latest version of intel -> module load python # in case need latest version of python -> module load cmake -> bash > CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src/ > make VERBOSE=1 -> export MKSURFDATA_BLD=`pwd` # needed once; execute in /bld - -# IF YOU MODIFY .F90 files, start here first, though more than once -# I have found it necessary to go back to the "rm -rf bld" step -> cd ../src -> make clean # REMEMBER to be in bash -> make VERBOSE=1 ======================= -running for a single submission: +running for a single submission: ======================= > cd ../ # to generate your target namelist: From b354d33d9257b60d419e594cc5a3fe722bde26bd Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 28 Apr 2022 10:57:06 -0600 Subject: [PATCH 147/614] Updated README --- tools/mksurfdata_esmf/README | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index fb40164865..a3f30b9a18 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -1,5 +1,5 @@ Most recent update of README: -4/6/2022 slevis +4/28/2022 slevis ================ Getting the code @@ -7,7 +7,7 @@ Getting the code > cd > git clone https://github.com/ESCOMP/CTSM.git > cd -> git checkout feature/new_mksurfdata +> git checkout ctsm5.2.mksurfdata # Save time by checking out ccs_config only > ./manage_externals/checkout_externals ccs_config @@ -15,8 +15,6 @@ Getting the code ======================= building the executable ======================= -> bash - > module load intel > module load python > module load cmake @@ -26,12 +24,14 @@ building the executable > module load netcdf-mpi/4.8.1 > module load pnetcdf/1.12.2 > module load pio/2.5.7 +> module load mpt/2.25 > module list > cd tools/mksurfdata_esmf > rm -rf bld # (or the contents of /bld) before rerunning CC=... > mkdir ./bld > cd bld +> bash > CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src/ > make VERBOSE=1 From 4dd0eb667b8b119bf304c3ba70c46052b0101f05 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 28 Apr 2022 11:18:08 -0600 Subject: [PATCH 148/614] update README --- tools/mksurfdata_esmf/README | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index c719e0df74..4bd139e2bb 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -7,7 +7,7 @@ Getting the code > cd > git clone https://github.com/ESCOMP/CTSM.git > cd -> git checkout feature/new_mksurfdata +> git checkout ctsm5.2.mksurfdata # Save time by checking out ccs_config only > ./manage_externals/checkout_externals ccs_config @@ -22,7 +22,14 @@ building the executable > module load intel # I found I need the latest version of intel > module load python # in case need latest version of python > module load cmake -> bash +> module load mpt/2.25 +> module use /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ +> module load esmf-8.3.0b13-ncdfio-mpt-O +> module unload netcdf/4.8.1 +> module load netcdf-mpi/4.8.1 +> module load pnetcdf/1.12.2 +> module load pio/2.5.7 +> bash #If you are not already using the bash shell > CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src/ > make VERBOSE=1 > export MKSURFDATA_BLD=`pwd` # needed once; execute in /bld From 47bfd6d3398fd8fe31550f33c5f7642362890791 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 28 Apr 2022 11:35:26 -0600 Subject: [PATCH 149/614] fix merge issue --- tools/mksurfdata_esmf/README | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 6e5649619a..75be0c0afa 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -15,18 +15,6 @@ Getting the code ======================= building the executable ======================= -> bash - -> module load intel -> module load python -> module load cmake -> module use /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ -> module load esmf-8.3.0b13-ncdfio-mpt-O -> module unload netcdf/4.8.1 -> module load netcdf-mpi/4.8.1 -> module load pnetcdf/1.12.2 -> module load pio/2.5.7 -> module list > cd tools/mksurfdata_esmf > rm -rf bld # (or the contents of /bld) before rerunning CC=... From a95fab7ae54685da900cc00c2b02b5fdb8a9efdc Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 28 Apr 2022 14:28:31 -0600 Subject: [PATCH 150/614] Save routehandle from non-transient call mkpft to use in transient call ...to save time when generating transient datasets --- tools/mksurfdata_esmf/src/mkpftMod.F90 | 33 ++++++++++++------ tools/mksurfdata_esmf/src/mksurfdata.F90 | 44 ++++++++++++++---------- 2 files changed, 47 insertions(+), 30 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index d4783400a9..07a7f1ab8f 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -184,7 +184,8 @@ subroutine mkpftInit( ) end subroutine mkpftInit !=============================================================== - subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft_o, rc) + subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & + pctcft_o, routehandle, rc) ! ! Make PFT data ! @@ -200,6 +201,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! use mkpctPftTypeMod, only : pct_pft_type use mkpftConstantsMod, only : natpft_lb, natpft_ub, num_cft, cft_lb, cft_ub + use mkinputMod, only : mksrf_fdynuse ! ! input/output variables character(len=*) , intent(in) :: file_mesh_i ! input mesh file name @@ -208,11 +210,11 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft real(r8) , intent(inout) :: pctlnd_o(:) ! output grid:%land/gridcell type(pct_pft_type), intent(inout) :: pctnatpft_o(:) ! natural PFT cover type(pct_pft_type), intent(inout) :: pctcft_o(:) ! crop (CFT) cover + type(ESMF_RouteHandle), intent(inout) :: routehandle integer , intent(out) :: rc ! ! local variables: - type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid integer :: dimid @@ -328,14 +330,21 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft ! ---------------------------------------- allocate(frac_o(ns_o),stat=ier) if (ier/=0) call shr_sys_abort() - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + if (.not. ESMF_RouteHandleIsCreated(routehandle)) then + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - ! ---------------------------------------- - ! Determine pctlnd_o(:) (output argument) - ! ---------------------------------------- - pctlnd_o(:) = frac_o(:) * 100._r8 + ! ---------------------------------------- + ! Determine pctlnd_o(:) (in/out argument) + ! ---------------------------------------- + pctlnd_o(:) = frac_o(:) * 100._r8 + else + ! ---------------------------------------- + ! Get frac_o back from pctlnd_o when not calling create_routehandle_r8 + ! ---------------------------------------- + frac_o(:) = pctlnd_o(:) * 0.01_r8 + end if ! ---------------------------------------- ! Determine pct_nat_pft_o(:,:) @@ -556,8 +565,10 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, pctcft end if ! Clean up memory - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + if (mksrf_fdynuse == ' ') then ! ...else we will reuse it + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + end if call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 4fb7c0ae0c..2a8607db77 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -182,6 +182,7 @@ program mksurfdata type(ESMF_Mesh) :: mesh_model type(ESMF_Field) :: field_model type(ESMF_LogKind_Flag) :: logkindflag + type(ESMF_RouteHandle) :: routehandle_pft type(ESMF_VM) :: vm integer :: rc logical :: create_esmf_pet_files = .false. @@ -370,7 +371,8 @@ program mksurfdata allocate(pftdata_mask(lsize_o)) ; pftdata_mask(:) = -999 allocate(landfrac_pft(lsize_o)) ; landfrac_pft(:) = spval call mkpft( mksrf_fvegtyp_mesh, mksrf_fvegtyp, mesh_model, & - pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) + pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft, & + routehandle=routehandle_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') ! If have pole points on grid - set south pole to glacier @@ -880,27 +882,31 @@ program mksurfdata ! Create pctpft data at model resolution from file fname ! Note that pctlnd_o below is different than the above call and returns pctlnd_pft_dyn call mkpft( mksrf_fvegtyp_mesh, fname, mesh_model, & - pctlnd_o=pctlnd_pft_dyn, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) + pctlnd_o=pctlnd_pft_dyn, pctnatpft_o=pctnatpft, pctcft_o=pctcft, & + routehandle=routehandle_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpft') call pio_syncfile(pioid) - ! Consistency check on input land fraction - ! pctlnd_pft was calculated ABOVE - do n = 1,lsize_o - if (pctlnd_pft_dyn(n) /= pctlnd_pft(n)) then - if (root_task) then - write(ndiag,*) subname,' error: pctlnd_pft for dynamics data = ',& - pctlnd_pft_dyn(n), ' not equal to pctlnd_pft for surface data = ',& - pctlnd_pft(n),' at n= ',n - if ( trim(fname) == ' ' )then - write(ndiag,*) ' PFT string = ',trim(string) - else - write(ndiag,*) ' PFT file = ', fname - end if - end if - call shr_sys_abort() - end if - end do +! ! Consistency check on input land fraction +! ! pctlnd_pft was calculated ABOVE +! ! TODO This error check serves no purpose now that mkpft calls +! ! create_routehandle_r8 only once and, therefore, doesn't update +! ! frac_o and pctlnd_o. Delete? (slevis) +! do n = 1,lsize_o +! if (pctlnd_pft_dyn(n) /= pctlnd_pft(n)) then +! if (root_task) then +! write(ndiag,*) subname,' error: pctlnd_pft for dynamics data = ',& +! pctlnd_pft_dyn(n), ' not equal to pctlnd_pft for surface data = ',& +! pctlnd_pft(n),' at n= ',n +! if ( trim(fname) == ' ' )then +! write(ndiag,*) ' PFT string = ',trim(string) +! else +! write(ndiag,*) ' PFT file = ', fname +! end if +! end if +! call shr_sys_abort() +! end if +! end do ! Create harvesting data at model resolution ! Output data is written in mkharvest From 55d5680860cce3212990766ba9955b3348ce6b7a Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 28 Apr 2022 17:20:47 -0600 Subject: [PATCH 151/614] Save routehandle from non-transient mkharvest to use in transient call --- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 14 ++++++-------- tools/mksurfdata_esmf/src/mksurfdata.F90 | 8 +++++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index efe1f725e3..8d2bbb02df 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -54,7 +54,6 @@ module mkharvestMod real(r8), parameter :: real_undef = -999.99 type(ESMF_Mesh) :: mesh_i - type(ESMF_RouteHandle) :: routehandle_r8 real(r8), allocatable :: frac_o(:) logical :: initialized = .false. @@ -65,7 +64,7 @@ module mkharvestMod contains !================================================================================= - subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, constant, ntime, rc) + subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, ntime, routehandle_r8, rc) ! ! Make harvest data for the dynamic PFT dataset. ! This dataset consists of the normalized harvest or grazing fraction (0-1) of @@ -76,7 +75,7 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, constant, ntime, character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh type(file_desc_t) , intent(inout) :: pioid_o - logical , intent(in) :: constant + type(ESMF_RouteHandle), intent(inout) :: routehandle_r8 integer, optional , intent(in) :: ntime integer , intent(out) :: rc ! return code @@ -165,7 +164,7 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, constant, ntime, ! Read in input 1d fields if they exists and map to output grid do ifld = 1,numharv varname_i = trim(harvest_fieldnames(ifld)) - if (constant) then + if (.not. present(ntime)) then ! not transient, i.e. constant varname_o = trim(harvest_const_fieldnames(ifld)) else varname_o = varname_i @@ -253,14 +252,13 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, constant, ntime, end if end do - ! If constant model, clean up the mapping - if (constant) then + if (.not. present(ntime)) then ! ...else we will reuse it deallocate(frac_o) call ESMF_RouteHandleDestroy(routehandle_r8, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() end if + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() if (root_task) then write (ndiag,'(a)') 'Successfully made harvest and grazing' diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 2a8607db77..ec6485649b 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -182,7 +182,7 @@ program mksurfdata type(ESMF_Mesh) :: mesh_model type(ESMF_Field) :: field_model type(ESMF_LogKind_Flag) :: logkindflag - type(ESMF_RouteHandle) :: routehandle_pft + type(ESMF_RouteHandle) :: routehandle_pft, routehandle_harv type(ESMF_VM) :: vm integer :: rc logical :: create_esmf_pet_files = .false. @@ -409,7 +409,8 @@ program mksurfdata ! Note that this call must come after call to mkpftInit - since num_cft is set there ! Output data is written in mkharvest if (fsurdat /= ' ') then - call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, pioid, constant=.true., rc=rc ) + call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, pioid, & + routehandle_r8=routehandle_harv, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') end if @@ -910,7 +911,8 @@ program mksurfdata ! Create harvesting data at model resolution ! Output data is written in mkharvest - call mkharvest( mksrf_fhrvtyp_mesh, fhrvname, mesh_model, pioid, constant=.false., ntime=ntim, rc=rc ) + call mkharvest( mksrf_fhrvtyp_mesh, fhrvname, mesh_model, pioid, & + ntime=ntim, routehandle_r8=routehandle_harv, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest') call pio_syncfile(pioid) From 5face42ab2aa8e118a604eeb690eecdd99ed9d1b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 28 Apr 2022 18:11:45 -0600 Subject: [PATCH 152/614] Clean-up mkpft & mkharvest to make the changes more similar --- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 8 ++------ tools/mksurfdata_esmf/src/mkpftMod.F90 | 22 +++++++++------------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index 8d2bbb02df..296377813e 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -50,12 +50,8 @@ module mkharvestMod 'UNREPRESENTED_CFT_LULCC' & /) - character(len=CL), parameter :: string_undef = 'UNSET' - real(r8), parameter :: real_undef = -999.99 - type(ESMF_Mesh) :: mesh_i real(r8), allocatable :: frac_o(:) - logical :: initialized = .false. character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -256,9 +252,9 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, ntime, routehand deallocate(frac_o) call ESMF_RouteHandleDestroy(routehandle_r8, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() end if - call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() if (root_task) then write (ndiag,'(a)') 'Successfully made harvest and grazing' diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index 07a7f1ab8f..4edf00e923 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -24,6 +24,7 @@ module mkpftMod integer :: m ! index character(len=35) :: veg(0:maxpft) ! vegetation types + real(r8), allocatable :: frac_o(:) character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -233,7 +234,6 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & real(r8), allocatable :: output_pct_cft_o(:,:) integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) - real(r8), allocatable :: frac_o(:) real(r8), allocatable :: pctnatveg_i(:) ! input natural veg percent (% of grid cell) real(r8), allocatable :: pctnatveg_o(:) ! output natural veg percent (% of grid cell) real(r8), allocatable :: pctcrop_i(:) ! input all crop percent (% of grid cell) @@ -328,24 +328,19 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & ! ---------------------------------------- ! Create a route handle between the input and output mesh and get frac_o ! ---------------------------------------- - allocate(frac_o(ns_o),stat=ier) - if (ier/=0) call shr_sys_abort() if (.not. ESMF_RouteHandleIsCreated(routehandle)) then + allocate(frac_o(ns_o),stat=ier) + if (ier/=0) call shr_sys_abort() call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - - ! ---------------------------------------- - ! Determine pctlnd_o(:) (in/out argument) - ! ---------------------------------------- - pctlnd_o(:) = frac_o(:) * 100._r8 - else - ! ---------------------------------------- - ! Get frac_o back from pctlnd_o when not calling create_routehandle_r8 - ! ---------------------------------------- - frac_o(:) = pctlnd_o(:) * 0.01_r8 end if + ! ---------------------------------------- + ! Determine pctlnd_o(:) (in/out argument) + ! ---------------------------------------- + pctlnd_o(:) = frac_o(:) * 100._r8 + ! ---------------------------------------- ! Determine pct_nat_pft_o(:,:) ! ---------------------------------------- @@ -566,6 +561,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & ! Clean up memory if (mksrf_fdynuse == ' ') then ! ...else we will reuse it + deallocate(frac_o) call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() end if From 054700a7e266e3c6fcae6296aa659cfd3307208c Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 29 Apr 2022 09:25:11 -0600 Subject: [PATCH 153/614] Save routehandle from non-transient call mklak to use in transient call --- tools/mksurfdata_esmf/README | 2 +- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 36 +++++++++++++++-------- tools/mksurfdata_esmf/src/mksurfdata.F90 | 9 ++++-- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index a3f30b9a18..2e5a8c1a42 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -23,8 +23,8 @@ building the executable > module unload netcdf/4.8.1 > module load netcdf-mpi/4.8.1 > module load pnetcdf/1.12.2 -> module load pio/2.5.7 > module load mpt/2.25 +> module load pio/2.5.7 > module list > cd tools/mksurfdata_esmf diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 426c6d2857..3e975137d9 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -24,6 +24,8 @@ module mklanwatMod public :: mkwetlnd ! make %wetland public :: update_max_array_lake ! Update the maximum lake percent + real(r8), allocatable :: frac_o_mklak(:) + character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -31,31 +33,34 @@ module mklanwatMod contains !=============================================================== - subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, fsurdat, rc, do_depth) + subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, & + fsurdat, routehandle, rc, do_depth) ! ------------------- ! make %lake and lake depth ! PCT_LAKE is written out to fsurdat in mksurfdata after adjustments are made - ! LAKE_DETH is written out to fsurdat here + ! LAKE_DEPTH is written out to fsurdat here ! ------------------- + ! uses + use mkinputMod, only: mksrf_fdynuse + ! input/output variables character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o type(file_desc_t) , intent(inout) :: pioid_o + type(ESMF_RouteHandle), intent(inout) :: routehandle real(r8) , intent(out) :: lake_o(:) ! output grid: %lake character(len=*) , intent(in) :: fsurdat integer , intent(out) :: rc logical, optional , intent(in) :: do_depth ! do the depth part of the subroutine ! local variables - type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid_i integer , allocatable :: mask_i(:) real(r8), allocatable :: rmask_i(:) - real(r8), allocatable :: frac_o(:) real(r8), allocatable :: lake_i(:) ! input grid: percent lake real(r8), allocatable :: lakedepth_i(:) ! iput grid: lake depth (m) real(r8), allocatable :: lakedepth_o(:) ! output grid: lake depth (m) @@ -117,10 +122,12 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, fsurdat, if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle between the input and output mesh - allocate(frac_o(ns_o)) - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + if (.not. ESMF_RouteHandleIsCreated(routehandle)) then + allocate(frac_o_mklak(ns_o)) + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o_mklak, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + end if ! ---------------------------------------- ! Create %lake @@ -145,7 +152,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, fsurdat, enddo ! Check global areas - call output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o, & + call output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o_mklak, & lake_i, lake_o, "pct lake", percent=.true., ndiag=ndiag, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -173,7 +180,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, fsurdat, if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regrid_rawdata for lakedepth in "//trim(subname)) do no = 1,ns_o - if (frac_o(no) == 0._r8) then + if (frac_o_mklak(no) == 0._r8) then lakedepth_o(no) = 10._r8 end if enddo @@ -191,7 +198,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, fsurdat, ! Check global areas for lake depth call output_diagnostics_continuous(mesh_i, mesh_o, & lakedepth_i, lakedepth_o, "lake depth", "m", & - ndiag=ndiag, rc=rc, mask_i=mask_i, frac_o=frac_o) + ndiag=ndiag, rc=rc, mask_i=mask_i, frac_o=frac_o_mklak) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if @@ -204,8 +211,11 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, fsurdat, call pio_closefile(pioid_i) ! Release memory - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + if (mksrf_fdynuse == ' ') then ! ...else we will reuse it + deallocate(frac_o_mklak) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + end if call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index ec6485649b..0c042498a6 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -182,7 +182,8 @@ program mksurfdata type(ESMF_Mesh) :: mesh_model type(ESMF_Field) :: field_model type(ESMF_LogKind_Flag) :: logkindflag - type(ESMF_RouteHandle) :: routehandle_pft, routehandle_harv + type(ESMF_RouteHandle) :: routehandle_pft, routehandle_harv, & + routehandle_lak type(ESMF_VM) :: vm integer :: rc logical :: create_esmf_pet_files = .false. @@ -421,7 +422,8 @@ program mksurfdata ! Need to keep pctlak and pctwet external for use below allocate ( pctlak(lsize_o)) ; pctlak(:) = spval allocate ( pctlak_max(lsize_o)) ; pctlak_max(:) = spval - call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, pctlak, pioid, fsurdat, rc=rc, do_depth=.true.) + call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, pctlak, pioid, & + fsurdat, routehandle_lak, rc=rc, do_depth=.true.) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') allocate ( pctwet(lsize_o)) ; pctwet(:) = spval @@ -917,7 +919,8 @@ program mksurfdata call pio_syncfile(pioid) ! Create pctlak data at model resolution (use original mapping file from lake data) - call mklakwat(mksrf_flakwat_mesh, flakname, mesh_model, pctlak, pioid, fsurdat, rc=rc) + call mklakwat(mksrf_flakwat_mesh, flakname, mesh_model, pctlak, pioid, & + fsurdat, routehandle_lak, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklakwat') call pio_syncfile(pioid) From 60b32dcc7ce5f8b4ec9b3cc550012e2c999a8116 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 29 Apr 2022 09:59:12 -0600 Subject: [PATCH 154/614] Save routehandle from non-transient call mkurb to use in transient call --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 8 ++++-- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 32 +++++++++++++-------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 0c042498a6..b26969d3e5 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -183,7 +183,7 @@ program mksurfdata type(ESMF_Field) :: field_model type(ESMF_LogKind_Flag) :: logkindflag type(ESMF_RouteHandle) :: routehandle_pft, routehandle_harv, & - routehandle_lak + routehandle_lak, routehandle_urb type(ESMF_VM) :: vm integer :: rc logical :: create_esmf_pet_files = .false. @@ -515,7 +515,8 @@ program mksurfdata allocate (pcturb_max(lsize_o, numurbl)) ; pcturb_max(:,:) = spval allocate (urban_classes(lsize_o,numurbl)) ; urban_classes(:,:) = spval allocate (urban_region(lsize_o)) ; urban_region(:) = -999 - call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, pcturb, urban_classes, urban_region, rc=rc) + call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, pcturb, & + urban_classes, urban_region, routehandle_urb, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing out urban region id" @@ -924,7 +925,8 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklakwat') call pio_syncfile(pioid) - call mkurban(mksrf_furban_mesh, furbname, mesh_model, pcturb, urban_classes, urban_region, rc=rc) + call mkurban(mksrf_furban_mesh, furbname, mesh_model, pcturb, & + urban_classes, urban_region, routehandle_urb, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') call pio_syncfile(pioid) ! screen pcturb using elevation diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 97a93c7721..82b7b92355 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -42,6 +42,7 @@ module mkurbanparMod ! private data members: ! flag to indicate nodata for index variables in output file: integer , parameter :: index_nodata = 0 + real(r8) , allocatable :: frac_o_mkurban(:) character(len=*), parameter :: modname = 'mkurbanparMod' private :: index_nodata @@ -81,7 +82,8 @@ subroutine mkurbanInit(datafname) end subroutine mkurbanInit !=============================================================== - subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, urban_classes_o, region_o, rc) + subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, & + urban_classes_o, region_o, routehandle, rc) ! ! make total percent urban, breakdown into urban classes, and region ID on the output grid ! @@ -102,22 +104,24 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, urban_classes_o, ! this would also replace the use of normalize_classes_by_gcell, and maybe some other ! urban-specific code. ! + ! uses + use mkinputMod, only: mksrf_fdynuse + ! ! input/output variables character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh + type(ESMF_RouteHandle), intent(inout) :: routehandle real(r8) , intent(inout) :: pcturb_o(:) ! output grid: total % urban real(r8) , intent(inout) :: urban_classes_o(:,:) ! output grid: breakdown of total urban into each class integer , intent(inout) :: region_o(:) ! output grid: region ID integer , intent(out) :: rc ! local variables: - type(ESMF_RouteHandle) :: routehandle type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) - real(r8), allocatable :: frac_o(:) real(r8), allocatable :: data_i(:,:) real(r8), allocatable :: data_o(:,:) real(r8), allocatable :: urban_classes_gcell_o(:,:) ! % putput urban in each density class (% of total grid cell area) @@ -178,10 +182,12 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, urban_classes_o, if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle between the input and output mesh - allocate(frac_o(ns_o)) - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + if (.not. ESMF_RouteHandleIsCreated(routehandle)) then + allocate(frac_o_mkurban(ns_o)) + call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o_mkurban, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + end if ! Read in input data ! - levels are the outermost dimension in pio reads @@ -312,7 +318,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, urban_classes_o, end if ! Output diagnostics - call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o, & + call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o_mkurban, & 1, max_regions, region_i, region_o, 'urban region', ndiag, rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() @@ -323,10 +329,12 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, urban_classes_o, ! Deallocate dynamic memory & other clean up ! TODO: determine what to deallocate ! deallocate (urban_classes_gcell_i, urban_classes_gcell_o, region_i) - - call ESMF_VMLogMemInfo("Before destroy operation in "//trim(subname)) - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + if (mksrf_fdynuse == ' ') then ! ...else we will reuse it + deallocate(frac_o_mkurban) + call ESMF_VMLogMemInfo("Before destroy operation in "//trim(subname)) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + end if call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_VMLogMemInfo("after destroy operation in "//trim(subname)) From 021666947a085d732fcbab98799ea5964fe2ced9 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 29 Apr 2022 11:11:20 -0600 Subject: [PATCH 155/614] Change jobscript to point to /bld instead of /src --- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py | 2 +- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index b1a98ec9e4..1396ee692c 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -224,7 +224,7 @@ def main (): output = run_cmd.stdout.decode('utf-8').strip() namelist = output.split(' ')[-1] print (f"generated namelist {namelist}") - output = f"mpiexec_mpt -p \"%g:\" -np {np} ./src/mksurfdata < {namelist}" + output = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist}" runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index 4072349cef..a35e29010b 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -88,7 +88,7 @@ def main (): np = int(tasks_per_node) * int(number_of_nodes) - output = f"mpiexec_mpt -p \"%g:\" -np {np} ./src/mksurfdata < {namelist_file}" + output = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist_file}" runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") From 306b381c9dd7b717f9d62b762cb5079c100e3239 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 29 Apr 2022 11:12:51 -0600 Subject: [PATCH 156/614] Change jobscript to point to /bld instead of /src --- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py | 2 +- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index b1a98ec9e4..1396ee692c 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -224,7 +224,7 @@ def main (): output = run_cmd.stdout.decode('utf-8').strip() namelist = output.split(' ')[-1] print (f"generated namelist {namelist}") - output = f"mpiexec_mpt -p \"%g:\" -np {np} ./src/mksurfdata < {namelist}" + output = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist}" runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index 4072349cef..a35e29010b 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -88,7 +88,7 @@ def main (): np = int(tasks_per_node) * int(number_of_nodes) - output = f"mpiexec_mpt -p \"%g:\" -np {np} ./src/mksurfdata < {namelist_file}" + output = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist_file}" runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") From 7d7fea3f81a689788df4f480990c9845244ae49d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 2 May 2022 11:53:12 -0600 Subject: [PATCH 157/614] Change routehandle from argument to module-level for saving in transient --- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 4 ++-- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 14 +++++++------- tools/mksurfdata_esmf/src/mkpftMod.F90 | 4 ++-- tools/mksurfdata_esmf/src/mksurfdata.F90 | 19 ++++++++----------- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 14 +++++++------- 5 files changed, 26 insertions(+), 29 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index 296377813e..ac5fbf69d0 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -51,6 +51,7 @@ module mkharvestMod /) type(ESMF_Mesh) :: mesh_i + type(ESMF_RouteHandle) :: routehandle_r8 real(r8), allocatable :: frac_o(:) character(len=*) , parameter :: u_FILE_u = & @@ -60,7 +61,7 @@ module mkharvestMod contains !================================================================================= - subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, ntime, routehandle_r8, rc) + subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, ntime, rc) ! ! Make harvest data for the dynamic PFT dataset. ! This dataset consists of the normalized harvest or grazing fraction (0-1) of @@ -71,7 +72,6 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, ntime, routehand character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh type(file_desc_t) , intent(inout) :: pioid_o - type(ESMF_RouteHandle), intent(inout) :: routehandle_r8 integer, optional , intent(in) :: ntime integer , intent(out) :: rc ! return code diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 3e975137d9..a01ca38515 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -25,6 +25,7 @@ module mklanwatMod public :: update_max_array_lake ! Update the maximum lake percent real(r8), allocatable :: frac_o_mklak(:) + type(ESMF_RouteHandle) :: routehandle_mklak character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -34,7 +35,7 @@ module mklanwatMod !=============================================================== subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, & - fsurdat, routehandle, rc, do_depth) + fsurdat, rc, do_depth) ! ------------------- ! make %lake and lake depth @@ -50,7 +51,6 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, & character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o type(file_desc_t) , intent(inout) :: pioid_o - type(ESMF_RouteHandle), intent(inout) :: routehandle real(r8) , intent(out) :: lake_o(:) ! output grid: %lake character(len=*) , intent(in) :: fsurdat integer , intent(out) :: rc @@ -122,9 +122,9 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, & if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle between the input and output mesh - if (.not. ESMF_RouteHandleIsCreated(routehandle)) then + if (.not. ESMF_RouteHandleIsCreated(routehandle_mklak)) then allocate(frac_o_mklak(ns_o)) - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o_mklak, rc=rc) + call create_routehandle_r8(mesh_i, mesh_o, routehandle_mklak, frac_o=frac_o_mklak, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) end if @@ -145,7 +145,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, & if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Regrid lake_i to lake_o - call regrid_rawdata(mesh_i, mesh_o, routehandle, lake_i, lake_o, rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle_mklak, lake_i, lake_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do no = 1,ns_o if (lake_o(no) < 1.) lake_o(no) = 0. @@ -176,7 +176,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, & ! regrid lakedepth_i to lakedepth_o - this also returns lakedepth_i to be used in the global sums below allocate (lakedepth_o(ns_o)); lakedepth_o(:) = spval - call regrid_rawdata(mesh_i, mesh_o, routehandle, lakedepth_i, lakedepth_o, rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle_mklak, lakedepth_i, lakedepth_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regrid_rawdata for lakedepth in "//trim(subname)) do no = 1,ns_o @@ -213,7 +213,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, & ! Release memory if (mksrf_fdynuse == ' ') then ! ...else we will reuse it deallocate(frac_o_mklak) - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + call ESMF_RouteHandleDestroy(routehandle_mklak, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() end if call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index 4edf00e923..0062940513 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -25,6 +25,7 @@ module mkpftMod character(len=35) :: veg(0:maxpft) ! vegetation types real(r8), allocatable :: frac_o(:) + type(ESMF_RouteHandle) :: routehandle character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -186,7 +187,7 @@ end subroutine mkpftInit !=============================================================== subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & - pctcft_o, routehandle, rc) + pctcft_o, rc) ! ! Make PFT data ! @@ -211,7 +212,6 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & real(r8) , intent(inout) :: pctlnd_o(:) ! output grid:%land/gridcell type(pct_pft_type), intent(inout) :: pctnatpft_o(:) ! natural PFT cover type(pct_pft_type), intent(inout) :: pctcft_o(:) ! crop (CFT) cover - type(ESMF_RouteHandle), intent(inout) :: routehandle integer , intent(out) :: rc ! diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index b26969d3e5..509e2e16a3 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -182,8 +182,6 @@ program mksurfdata type(ESMF_Mesh) :: mesh_model type(ESMF_Field) :: field_model type(ESMF_LogKind_Flag) :: logkindflag - type(ESMF_RouteHandle) :: routehandle_pft, routehandle_harv, & - routehandle_lak, routehandle_urb type(ESMF_VM) :: vm integer :: rc logical :: create_esmf_pet_files = .false. @@ -372,8 +370,7 @@ program mksurfdata allocate(pftdata_mask(lsize_o)) ; pftdata_mask(:) = -999 allocate(landfrac_pft(lsize_o)) ; landfrac_pft(:) = spval call mkpft( mksrf_fvegtyp_mesh, mksrf_fvegtyp, mesh_model, & - pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft, & - routehandle=routehandle_pft, rc=rc) + pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') ! If have pole points on grid - set south pole to glacier @@ -411,7 +408,7 @@ program mksurfdata ! Output data is written in mkharvest if (fsurdat /= ' ') then call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, pioid, & - routehandle_r8=routehandle_harv, rc=rc ) + rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') end if @@ -423,7 +420,7 @@ program mksurfdata allocate ( pctlak(lsize_o)) ; pctlak(:) = spval allocate ( pctlak_max(lsize_o)) ; pctlak_max(:) = spval call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, pctlak, pioid, & - fsurdat, routehandle_lak, rc=rc, do_depth=.true.) + fsurdat, rc=rc, do_depth=.true.) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') allocate ( pctwet(lsize_o)) ; pctwet(:) = spval @@ -516,7 +513,7 @@ program mksurfdata allocate (urban_classes(lsize_o,numurbl)) ; urban_classes(:,:) = spval allocate (urban_region(lsize_o)) ; urban_region(:) = -999 call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, pcturb, & - urban_classes, urban_region, routehandle_urb, rc=rc) + urban_classes, urban_region, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing out urban region id" @@ -887,7 +884,7 @@ program mksurfdata ! Note that pctlnd_o below is different than the above call and returns pctlnd_pft_dyn call mkpft( mksrf_fvegtyp_mesh, fname, mesh_model, & pctlnd_o=pctlnd_pft_dyn, pctnatpft_o=pctnatpft, pctcft_o=pctcft, & - routehandle=routehandle_pft, rc=rc) + rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpft') call pio_syncfile(pioid) @@ -915,18 +912,18 @@ program mksurfdata ! Create harvesting data at model resolution ! Output data is written in mkharvest call mkharvest( mksrf_fhrvtyp_mesh, fhrvname, mesh_model, pioid, & - ntime=ntim, routehandle_r8=routehandle_harv, rc=rc ) + ntime=ntim, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest') call pio_syncfile(pioid) ! Create pctlak data at model resolution (use original mapping file from lake data) call mklakwat(mksrf_flakwat_mesh, flakname, mesh_model, pctlak, pioid, & - fsurdat, routehandle_lak, rc=rc) + fsurdat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklakwat') call pio_syncfile(pioid) call mkurban(mksrf_furban_mesh, furbname, mesh_model, pcturb, & - urban_classes, urban_region, routehandle_urb, rc=rc) + urban_classes, urban_region, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') call pio_syncfile(pioid) ! screen pcturb using elevation diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 82b7b92355..b25a34a34c 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -43,6 +43,7 @@ module mkurbanparMod ! flag to indicate nodata for index variables in output file: integer , parameter :: index_nodata = 0 real(r8) , allocatable :: frac_o_mkurban(:) + type(ESMF_RouteHandle) :: routehandle_mkurban character(len=*), parameter :: modname = 'mkurbanparMod' private :: index_nodata @@ -83,7 +84,7 @@ end subroutine mkurbanInit !=============================================================== subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, & - urban_classes_o, region_o, routehandle, rc) + urban_classes_o, region_o, rc) ! ! make total percent urban, breakdown into urban classes, and region ID on the output grid ! @@ -111,7 +112,6 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, & character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh - type(ESMF_RouteHandle), intent(inout) :: routehandle real(r8) , intent(inout) :: pcturb_o(:) ! output grid: total % urban real(r8) , intent(inout) :: urban_classes_o(:,:) ! output grid: breakdown of total urban into each class integer , intent(inout) :: region_o(:) ! output grid: region ID @@ -182,9 +182,9 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, & if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle between the input and output mesh - if (.not. ESMF_RouteHandleIsCreated(routehandle)) then + if (.not. ESMF_RouteHandleIsCreated(routehandle_mkurban)) then allocate(frac_o_mkurban(ns_o)) - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o_mkurban, rc=rc) + call create_routehandle_r8(mesh_i, mesh_o, routehandle_mkurban, frac_o=frac_o_mkurban, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) end if @@ -202,7 +202,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, & call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) ! Regrid input data to model resolution - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 1, numurbl, rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle_mkurban, data_i, data_o, 1, numurbl, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regrid_data for in "//trim(subname)) @@ -300,7 +300,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, & if (allocated(data_o)) deallocate(data_o) allocate(data_o(max_regions, ns_o), stat=ier) if (ier/=0) call shr_sys_abort('error allocating data_i(max_regions, ns_o)') - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 1, nregions, rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle_mkurban, data_i, data_o, 1, nregions, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Now find dominant region in each output gridcell - this is identical to the maximum index @@ -332,7 +332,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, & if (mksrf_fdynuse == ' ') then ! ...else we will reuse it deallocate(frac_o_mkurban) call ESMF_VMLogMemInfo("Before destroy operation in "//trim(subname)) - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + call ESMF_RouteHandleDestroy(routehandle_mkurban, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() end if call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) From ca8a7a92b181c3d972b98863304c608ccd155e85 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 2 May 2022 12:00:43 -0600 Subject: [PATCH 158/614] Get build script working again --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index 645645a47f..b41d0548fb 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -1,17 +1,14 @@ #! /bin/bash -f -module load cmake - export MACH="cheyenne" export COMPILER="intel" -export OS="LINUX" -export ESMFMKFILE="/glade/work/oehmke/ESMF/scalable_mesh_from_file/lib/libg/Linux.intel.64.mpt.default/esmf.mk" +export MPILIB="mpt" cwd=`pwd` rm -rf bld mkdir bld cd bld -../../../cime/tools/configure --macros-format CMake --machine cheyenne --compiler intel --mpilib mpt +../../../cime/tools/configure --macros-format CMake --machine $MACH --compiler $COMPILER --mpilib $MPILIB ls -l source ./.env_mach_specific.sh CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src From 333fb214c2ce8de13330f500ebd59b75441227da Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 2 May 2022 13:07:26 -0600 Subject: [PATCH 159/614] Make some changes to the README and build script that Sam and I discussed --- tools/mksurfdata_esmf/README | 35 ++++--------------- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 6 +++- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 75be0c0afa..a7ef872c48 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -1,38 +1,17 @@ -Most recent update of README: -4/6/2022 slevis +For users working on cime machines you can use the build +script to build the tool for you. On other machines you'll need to do port to cime +and tell how to build for that machine. That's talked about in the cime documentation. +And you'll have to make some modifications to the build script. -================ -Getting the code -================ -> cd -> git clone https://github.com/ESCOMP/CTSM.git -> cd -> git checkout ctsm5.2.mksurfdata - -# Save time by checking out ccs_config only -> ./manage_externals/checkout_externals ccs_config +Machines that are already run CTSM or CESM have been ported to cime. So if you can run the model +on your machine you will be able to build the tool there. ======================= building the executable ======================= > cd tools/mksurfdata_esmf -> rm -rf bld # (or the contents of /bld) before rerunning CC=... -> mkdir ./bld -> cd bld -> module load intel # I found I need the latest version of intel -> module load python # in case need latest version of python -> module load cmake -> module load mpt/2.25 -> module use /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ -> module load esmf-8.3.0b13-ncdfio-mpt-O -> module unload netcdf/4.8.1 -> module load netcdf-mpi/4.8.1 -> module load pnetcdf/1.12.2 -> module load pio/2.5.7 -> bash #If you are not already using the bash shell -> CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src/ -> make VERBOSE=1 +> ./gen_mksurfdata_build.sh # For machines with a cime build ======================= running for a single submission: diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index b41d0548fb..2333ff3483 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -1,16 +1,20 @@ #! /bin/bash -f +# Define what machine to use that's been ported to cime export MACH="cheyenne" export COMPILER="intel" export MPILIB="mpt" +# Create a build directory cwd=`pwd` rm -rf bld mkdir bld cd bld +# Run the cime configure tool to figure out what modules need to be loaded ../../../cime/tools/configure --macros-format CMake --machine $MACH --compiler $COMPILER --mpilib $MPILIB -ls -l source ./.env_mach_specific.sh +# Build the cmake files CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src +# Build the actual executable make VERBOSE=1 From 2e5af3f90aac49f4fdafd239af1b367f10bb7e48 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 2 May 2022 14:25:14 -0600 Subject: [PATCH 160/614] Have the build script figure out it's cheyenne or some other machine, add error checking after each step, and print a success at the end --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index 2333ff3483..d2b09bab7a 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -1,20 +1,49 @@ #! /bin/bash -f +hostname=`hostname --short` + # Define what machine to use that's been ported to cime -export MACH="cheyenne" -export COMPILER="intel" -export MPILIB="mpt" +case $hostname in + ##cheyenne + cheyenne* | r* ) + export MACH="cheyenne" + ;; + ## Other machines + *) + export MACH="$hostname" + ;; +esac # Create a build directory +echo "cime Machine is: $MACH..." +echo "Remove the old bld directory and create a new one..." cwd=`pwd` rm -rf bld mkdir bld cd bld # Run the cime configure tool to figure out what modules need to be loaded -../../../cime/tools/configure --macros-format CMake --machine $MACH --compiler $COMPILER --mpilib $MPILIB -source ./.env_mach_specific.sh +echo "Run cime configure for machine $MACH..." +# You can specify the non-default compiler and mpi-library by adding --compiler and --mpilib settings +../../../cime/tools/configure --macros-format CMake --machine $MACH +if [ $? != 0 ]; then + echo "Error doing configure for machine name: $MACH" + exit 1 +fi +. .env_mach_specific.sh +echo "COMPILER = $COMPILER, MPILIB = $MPILIB, DEBUG = $DEBUG, OS = $OS" # Build the cmake files +echo "Do the cmake build..." CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src +if [ $? != 0 ]; then + echo "Error doing cmake for $MACH $MPILIB $COMPILER" + exit 1 +fi # Build the actual executable +echo "Build the mksurfdata_esmf build..." make VERBOSE=1 +if [ $? != 0 ]; then + echo "Error doing make for $MACH $MPILIB $COMPILER" + exit 1 +fi +echo "\n\n\nSuccessfully created mksurfdata_esmf executable for: ${MACH}_${COMPILER} for $MPILIB library" From 3ed08f8dbae5fb76a45cc6e6279fd08b86993abe Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 2 May 2022 14:51:15 -0600 Subject: [PATCH 161/614] Add a check if the build directory already exists and abort if so --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index d2b09bab7a..2471ea9c29 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -16,7 +16,10 @@ esac # Create a build directory echo "cime Machine is: $MACH..." -echo "Remove the old bld directory and create a new one..." +if [ -d "bld" ]; then + echo "An existing bld directory exists already remove it, if you want to do a clean build..." + exit 1 +fi cwd=`pwd` rm -rf bld mkdir bld From af2d5ea27d18c9fda077da8a91515321f56c22c2 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 2 May 2022 16:07:47 -0600 Subject: [PATCH 162/614] Update to ccs_config branch --- Externals.cfg | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Externals.cfg b/Externals.cfg index 239e8e9d89..986dfa92cb 100644 --- a/Externals.cfg +++ b/Externals.cfg @@ -34,9 +34,11 @@ hash = 34723c2 required = True [ccs_config] -tag = ccs_config_cesm0.0.15 +#tag = ccs_config_cesm0.0.15 +branch = update_for_mksurfdata_esmf_build protocol = git -repo_url = https://github.com/ESMCI/ccs_config_cesm.git +#repo_url = https://github.com/ESMCI/ccs_config_cesm.git +repo_url = git@github.com:ekluzek/ccs_config_cesm.git local_path = ccs_config required = True From c309d82aa13d807da89fb2e409b8f5c2957a7a41 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 2 May 2022 16:18:11 -0600 Subject: [PATCH 163/614] Add some empty lines at the end --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index 2471ea9c29..9e046a2240 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -48,5 +48,8 @@ if [ $? != 0 ]; then echo "Error doing make for $MACH $MPILIB $COMPILER" exit 1 fi -echo "\n\n\nSuccessfully created mksurfdata_esmf executable for: ${MACH}_${COMPILER} for $MPILIB library" +echo "" +echo "" +echo "" +echo "Successfully created mksurfdata_esmf executable for: ${MACH}_${COMPILER} for $MPILIB library" From f04ab5e5e3dc502e5293edfb4e178683fa5ddff0 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 2 May 2022 16:21:54 -0600 Subject: [PATCH 164/614] Point to a specific hash on the ccs_config branch --- Externals.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Externals.cfg b/Externals.cfg index 986dfa92cb..4e0998372a 100644 --- a/Externals.cfg +++ b/Externals.cfg @@ -35,7 +35,8 @@ required = True [ccs_config] #tag = ccs_config_cesm0.0.15 -branch = update_for_mksurfdata_esmf_build +#branch = update_for_mksurfdata_esmf_build +hash = e79eafcda096d20d41e7ef4921ac484215ed3d38 protocol = git #repo_url = https://github.com/ESMCI/ccs_config_cesm.git repo_url = git@github.com:ekluzek/ccs_config_cesm.git From ecb9f71eaaa33b492a41b11a518843e5b51c451d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 2 May 2022 17:09:10 -0600 Subject: [PATCH 165/614] Update ccs_config hash with changes needed to build on izumi with intel and mvapich2 --- Externals.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals.cfg b/Externals.cfg index 4e0998372a..c7cdf64fce 100644 --- a/Externals.cfg +++ b/Externals.cfg @@ -36,7 +36,7 @@ required = True [ccs_config] #tag = ccs_config_cesm0.0.15 #branch = update_for_mksurfdata_esmf_build -hash = e79eafcda096d20d41e7ef4921ac484215ed3d38 +hash = 29a06a80a5f411f3ed001d5b2cb34d2aab685cbe protocol = git #repo_url = https://github.com/ESMCI/ccs_config_cesm.git repo_url = git@github.com:ekluzek/ccs_config_cesm.git From 668bbd692c3dd9b23c4c2ee1d7bc5cd79e3d3d2f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 2 May 2022 18:52:35 -0600 Subject: [PATCH 166/614] Add handling for specifying MPILIB and COMPILER as env variables and abort if the PIO env variable is not set after configure --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index 2471ea9c29..bfe0665df9 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -27,13 +27,25 @@ cd bld # Run the cime configure tool to figure out what modules need to be loaded echo "Run cime configure for machine $MACH..." # You can specify the non-default compiler and mpi-library by adding --compiler and --mpilib settings -../../../cime/tools/configure --macros-format CMake --machine $MACH +if [ -z "$COMPILER" ] && [ -z "$MPILIB" ]; then + echo "configure for the default MPI-library and compiler..." + ../../../cime/tools/configure --macros-format CMake --machine $MACH +else + echo "configure for the specific MPILIB=$MPILIB and COMPILER=$COMPILER..." + ../../../cime/tools/configure --macros-format CMake --machine $MACH --compiler $COMPILER --mpilib $MPILIB +fi + if [ $? != 0 ]; then echo "Error doing configure for machine name: $MACH" exit 1 fi . .env_mach_specific.sh echo "COMPILER = $COMPILER, MPILIB = $MPILIB, DEBUG = $DEBUG, OS = $OS" +if [ -z "$PIO" ]; then + echo "The PIO directory for the PIO build is required and was not set in the configure" + echo "Make sure a PIO build is provided for $MACH_$COMPILER with $MPILIB in config_machines" + exit 1 +fi # Build the cmake files echo "Do the cmake build..." CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src @@ -49,4 +61,3 @@ if [ $? != 0 ]; then exit 1 fi echo "\n\n\nSuccessfully created mksurfdata_esmf executable for: ${MACH}_${COMPILER} for $MPILIB library" - From 5898e5c150a95f8bc0a1241edcdde3a359fecca4 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 2 May 2022 23:14:36 -0600 Subject: [PATCH 167/614] Add some notes on requirements and point to some web addresses for that --- tools/mksurfdata_esmf/README | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index a7ef872c48..6b85b7564d 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -1,11 +1,43 @@ +=================== +Build Requirements: +=================== + +mksurfdata_esmf is an distributed memory parallel program (using Message Passing Interface -- MPI) that utilizes +both ESMF (Earth System Modelling Framework) for regridding as well as PIO (Parallel I/O) and NetCDF output. As +such libraries must be built for the following: + +1) MPI +2) NetCDF +3) ParallelIO +4) ESMF + +These libraries need to be built such that they can all work together in the same executable. Hence, the above +order may be required in building them. + +========================================= +Use cime to manage the build requirements +========================================= + For users working on cime machines you can use the build -script to build the tool for you. On other machines you'll need to do port to cime +script to build the tool for you. On other machines you'll need to do a port to cime and tell how to build for that machine. That's talked about in the cime documentation. And you'll have to make some modifications to the build script. -Machines that are already run CTSM or CESM have been ported to cime. So if you can run the model +https://github.com/ESMCI/cime/wiki/Porting-Overview + +Machines that already run CTSM or CESM have been ported to cime. So if you can run the model on your machine you will be able to build the tool there. +To get a list of the machines that have been ported to cime: + +cd ../../cime/scripts +./query_config --machines + +NOTE: +In addition to having a port to cime, the machine also needs to have PIO built and able +to be referenced with the env variable PIO which will need to be in the porting instructions +for the machine. Currently an independent PIO library is not available on cime ported machines. + ======================= building the executable ======================= From 309a8dcb121e2ba16dfdd182e7358da021ce6934 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 2 May 2022 23:40:19 -0600 Subject: [PATCH 168/614] Add a note about the build --- tools/mksurfdata_esmf/README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 6b85b7564d..f2d61e2539 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -11,6 +11,8 @@ such libraries must be built for the following: 3) ParallelIO 4) ESMF +In addition for the build: python, bash-shell, CMake and GNU-Make are required + These libraries need to be built such that they can all work together in the same executable. Hence, the above order may be required in building them. From 15f8f7a846242ebc0736f21fb34998f6ba35a5d5 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 4 May 2022 10:11:30 -0600 Subject: [PATCH 169/614] Change .and. to .or. in if statement; also comment clean-up --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index 8e64b3db0b..cca9308916 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -14,20 +14,21 @@ case $hostname in ;; esac -# Create a build directory +# Create /bld directory echo "cime Machine is: $MACH..." if [ -d "bld" ]; then - echo "An existing bld directory exists already remove it, if you want to do a clean build..." + echo "A /bld directory exists; remove it to do a clean build..." exit 1 fi cwd=`pwd` rm -rf bld mkdir bld cd bld + # Run the cime configure tool to figure out what modules need to be loaded echo "Run cime configure for machine $MACH..." # You can specify the non-default compiler and mpi-library by adding --compiler and --mpilib settings -if [ -z "$COMPILER" ] && [ -z "$MPILIB" ]; then +if [ -z "$COMPILER" ] || [ -z "$MPILIB" ]; then echo "configure for the default MPI-library and compiler..." ../../../cime/tools/configure --macros-format CMake --machine $MACH else @@ -46,6 +47,7 @@ if [ -z "$PIO" ]; then echo "Make sure a PIO build is provided for $MACH_$COMPILER with $MPILIB in config_machines" exit 1 fi + # Build the cmake files echo "Do the cmake build..." CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src @@ -53,7 +55,8 @@ if [ $? != 0 ]; then echo "Error doing cmake for $MACH $MPILIB $COMPILER" exit 1 fi -# Build the actual executable + +# Build the executable echo "Build the mksurfdata_esmf build..." make VERBOSE=1 if [ $? != 0 ]; then From 9ca522846d65374ffd8aa6dac461bc442484f005 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 4 May 2022 18:59:56 -0600 Subject: [PATCH 170/614] Remove hardwiring of new soil texture mapunit and lookup files --- .../gen_mksurfdata_namelist.py | 4 ++++ .../gen_mksurfdata_namelist.xml | 8 +++++++- tools/mksurfdata_esmf/src/mkfileMod.F90 | 4 +++- tools/mksurfdata_esmf/src/mkinputMod.F90 | 8 ++++++-- tools/mksurfdata_esmf/src/mksurfdata.F90 | 19 +++---------------- 5 files changed, 23 insertions(+), 20 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index ae3f62e5c6..62d583f50d 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -390,6 +390,10 @@ def main (): new_key = f"{child1.tag}_urban" rawdata_files[new_key] = os.path.join(input_path, item.text) + if item.tag == 'lookup_filename': + new_key = f"{child1.tag}_lookup" + rawdata_files[new_key] = os.path.join(input_path, item.text) + # determine output mesh tree2 = ET.parse('../../ccs_config/component_grids_nuopc.xml') root = tree2.getroot() diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 5ea0b982d0..3e1aa0450f 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -50,9 +50,15 @@ - lnd/clm2/rawdata/mksrf_soitex.10level.c010119.nc + /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/soiltex_mapunits_4320x2160_c220329.nc + /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v1_lookup2.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc + + /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v5_grid.nc + /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v1_lookup2.nc + lnd/clm2/mappingdata/grids/DO_WE_HAVE_ONE? + diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 611eb42165..0eb25c2e7d 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -216,7 +216,9 @@ subroutine mkfile_define_atts(pioid, dynlanduse) str = get_filename(mksrf_fsoicol) rcode = pio_put_att(pioid, pio_global, 'soil_color_raw_data_file_name', trim(str)) str = get_filename(mksrf_fsoitex) - rcode = pio_put_att(pioid, pio_global, 'soil_texture_raw_data_file_name', trim(str)) + rcode = pio_put_att(pioid, pio_global, 'soil_texture_mapunit_raw_data_file_name', trim(str)) + str = get_filename(mksrf_fsoitex_lookup) + rcode = pio_put_att(pioid, pio_global, 'soil_texture_lookup_raw_data_file_name', trim(str)) str = get_filename(mksrf_fmax) rcode = pio_put_att(pioid, pio_global, 'fmax_raw_data_file_name', trim(str)) str = get_filename(mksrf_forganic) diff --git a/tools/mksurfdata_esmf/src/mkinputMod.F90 b/tools/mksurfdata_esmf/src/mkinputMod.F90 index 1d5c3a38a9..b35596a026 100644 --- a/tools/mksurfdata_esmf/src/mkinputMod.F90 +++ b/tools/mksurfdata_esmf/src/mkinputMod.F90 @@ -50,7 +50,8 @@ module mkinputMod character(CX) , public :: mksrf_fsoicol = ' ' ! soil color data file name character(CX) , public :: mksrf_fsoicol_mesh = ' ' ! soil color mesh file name - character(CX) , public :: mksrf_fsoitex = ' ' ! soil texture data file name + character(CX) , public :: mksrf_fsoitex = ' ' ! soil texture mapunit data file name + character(CX) , public :: mksrf_fsoitex_lookup = ' ' ! soil texture lookup data file name character(CX) , public :: mksrf_fsoitex_mesh = ' ' ! soil texture mesh file name character(CX) , public :: mksrf_fmax = ' ' ! fmax data file name @@ -136,6 +137,7 @@ subroutine read_namelist_input() mksrf_fhrvtyp, & mksrf_fhrvtyp_mesh, & mksrf_fsoitex, & + mksrf_fsoitex_lookup, & mksrf_fsoitex_mesh, & mksrf_forganic, & mksrf_forganic_mesh, & @@ -224,6 +226,7 @@ subroutine read_namelist_input() call mpi_bcast (mksrf_fhrvtyp_mesh, len(mksrf_fhrvtyp_mesh), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fsoitex, len(mksrf_fsoitex), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fsoitex_lookup, len(mksrf_fsoitex_lookup), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fsoitex_mesh, len(mksrf_fsoitex_mesh), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fmax, len(mksrf_fmax), MPI_CHARACTER, 0, mpicom, ier) @@ -347,7 +350,8 @@ subroutine write_namelist_input() write(ndiag,'(a)')' inland wetland from: '//trim(mksrf_fwetlnd) write(ndiag,'(a)')' mesh for wetland '//trim(mksrf_fwetlnd_mesh) write(ndiag,*) - write(ndiag,'(a)')' soil texture from: '//trim(mksrf_fsoitex) + write(ndiag,'(a)')' soil texture mapunits from: '//trim(mksrf_fsoitex) + write(ndiag,'(a)')' soil texture lookup from: '//trim(mksrf_fsoitex_lookup) write(ndiag,'(a)')' mesh for soil texture '//trim(mksrf_fsoitex_mesh) write(ndiag,*) write(ndiag,'(a)')' soil organic from: '//trim(mksrf_forganic) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 7ef642f13e..827591a69c 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -32,7 +32,8 @@ program mksurfdata ! mksrf_fmax_mesh - Mesh for mksrf_fmax ! mksrf_fsoicol - Soil color dataset ! mksrf_fsoicol_mesh - Mesh for mksrf_fsoicol - ! mksrf_fsoitex - Soil texture dataset + ! mksrf_fsoitex - Soil texture dataset in mapunits + ! mksrf_fsoitex_lookup - Soil texture lookup for converting mapunits to sand/silt/clay ! mksrf_fsoitex_mesh - Mesh for mksrf_fsoitex ! mksrf_furbtopo - Topography dataset (for limiting urban areas) ! mksrf_furbtopo_mesh - Mesh for mksrf_furbtopo @@ -191,9 +192,6 @@ program mksurfdata character(len=CL) :: fname character(len=*), parameter :: subname = 'mksrfdata' ! program name - character(len=CL) :: mksrf_fsoitex_mapunit - character(len=CL) :: mksrf_fsoitex_lookup - character(len=*), parameter :: u_FILE_u = & __FILE__ @@ -452,18 +450,7 @@ program mksurfdata ! Make soil texture [pctsand, pctclay] ! ----------------------------------- if (fsurdat /= ' ') then - ! --- for a 3 second input mapunit --- - ! mksrf_fsoitex_mapunit = & - ! '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v5_grid.nc' - ! --- for a 5min input mapunit--- - mksrf_fsoitex_mesh = & - '/glade/p/cesm/cseg/inputdata/lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc' - mksrf_fsoitex_mapunit = & - '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/soiltex_mapunits_4320x2160_c220329.nc' - mksrf_fsoitex_lookup = & - '/glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v1_lookup2.nc' - - call mksoiltex( mksrf_fsoitex_mesh, file_mapunit_i=mksrf_fsoitex_mapunit, file_lookup_i=mksrf_fsoitex_lookup, & + call mksoiltex( mksrf_fsoitex_mesh, file_mapunit_i=mksrf_fsoitex, file_lookup_i=mksrf_fsoitex_lookup, & mesh_o=mesh_model, pioid_o=pioid, pctlnd_pft_o=pctlnd_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') end if From efd5ca2d918382efa7f29990d6193e65b2037bcc Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 6 May 2022 13:32:37 -0600 Subject: [PATCH 171/614] Update .xml with renamed mksrf_soitex* files --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 3e1aa0450f..b3ea543dee 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -50,14 +50,14 @@ - /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/soiltex_mapunits_4320x2160_c220329.nc - /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v1_lookup2.nc + /lnd/clm2/rawdata/mksrf_soitex_mapunits_5x5min_from_wise_30sec.c220329.nc + /lnd/clm2/rawdata/mksrf_soitex.10level.wise_30sec_lookup.c220329.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc - /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v5_grid.nc - /glade/u/home/mvertens/src/ctsm.new_mksurfdata/tools/mksurfdata_esmf/wise_30sec_v1_lookup2.nc - lnd/clm2/mappingdata/grids/DO_WE_HAVE_ONE? + /lnd/clm2/rawdata/mksrf_soitex_mapunits_wise_30sec.c220330.nc + /lnd/clm2/rawdata/mksrf_soitex.10level.wise_30sec_lookup.c220329.nc + lnd/clm2/rawdata/mksrf_soitex_mapunits_wise_30sec.c220330.nc From d53d1b98b9858402df2069ea01640ac49ebc8313 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 6 May 2022 15:49:34 -0600 Subject: [PATCH 172/614] Update .xml with renamed mksrf_soitex* files after review comments --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index b3ea543dee..c9fdc57aef 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -50,14 +50,14 @@ - /lnd/clm2/rawdata/mksrf_soitex_mapunits_5x5min_from_wise_30sec.c220329.nc - /lnd/clm2/rawdata/mksrf_soitex.10level.wise_30sec_lookup.c220329.nc + lnd/clm2/rawdata/mksrf_soil_mapunits_5x5min_WISE.c220330.nc + lnd/clm2/rawdata/mksrf_soil_lookup.10level.WISE.c220330.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc - /lnd/clm2/rawdata/mksrf_soitex_mapunits_wise_30sec.c220330.nc - /lnd/clm2/rawdata/mksrf_soitex.10level.wise_30sec_lookup.c220329.nc - lnd/clm2/rawdata/mksrf_soitex_mapunits_wise_30sec.c220330.nc + lnd/clm2/rawdata/mksrf_soil_mapunits_30sec_WISE.c220330.nc + lnd/clm2/rawdata/mksrf_soil_lookup.10level.WISE.c220330.nc + lnd/clm2/rawdata/mksrf_soil_mapunits_30sec_WISE.c220330.nc From 2e7fc4817cf85fbac8a28d00aee099be8bb439d4 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 6 May 2022 16:19:35 -0600 Subject: [PATCH 173/614] Add the --hires_soitex option to gen_mksurfdata_namelist.py --- .../gen_mksurfdata_namelist.py | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 62d583f50d..aa19c8b0da 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -176,7 +176,19 @@ def get_parser(): [default: %(default)s] """, action="store_true", - dest="hres_flag", + dest="hres_pft", + default=False, + ) + parser.add_argument( + "--hires_soitex", + help=""" + If you want to use the high-resolution soil texture dataset rather + than the default lower resolution dataset. + (Low resolution is 5x5min, high resolution 30-second) + [default: %(default)s] + """, + action="store_true", + dest="hres_soitex", default=False, ) parser.add_argument( @@ -245,7 +257,8 @@ def main (): potveg = args.potveg_flag glc_nec = args.glc_nec merge_gis = args.merge_gis - if args.hres_flag: + + if args.hres_pft: if (start_year == 1850 and end_year == 1850) or \ (start_year == 2005 and end_year == 2005): hires_pft = 'on' @@ -254,6 +267,12 @@ def main (): sys.exit(5) else: hires_pft = 'off' + + if args.hres_soitex: + hires_soitex = 'on' + else: + hires_soitex = 'off' + verbose = args.verbose if force_model_mesh_file != 'none': @@ -319,6 +338,7 @@ def main (): # create attribute list for parsing xml file attribute_list = {'hires_pft':hires_pft, + 'hires_soitex':hires_soitex, 'pft_years':pft_years, 'pft_years_ssp':pft_years_ssp, 'ssp_rcp':ssp_rcp, From fdac40c6fd6056900b5151a4d93254562b675699 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 11 May 2022 18:34:43 -0600 Subject: [PATCH 174/614] Change repo_url from git@... to https:... for ccs_config This prevents the need for ssh keys in github. The absence of ssh keys can lead to permission errors. --- Externals.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals.cfg b/Externals.cfg index c7cdf64fce..342a3ac512 100644 --- a/Externals.cfg +++ b/Externals.cfg @@ -39,7 +39,7 @@ required = True hash = 29a06a80a5f411f3ed001d5b2cb34d2aab685cbe protocol = git #repo_url = https://github.com/ESMCI/ccs_config_cesm.git -repo_url = git@github.com:ekluzek/ccs_config_cesm.git +repo_url = https://github.com/ekluzek/ccs_config_cesm.git local_path = ccs_config required = True From 198beb4cfe2312b605f1751b3bef29c4335bc3be Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 12 May 2022 13:47:46 -0600 Subject: [PATCH 175/614] Enable mksurfdata_esmf build and run on casper --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 4 ++++ .../gen_mksurfdata_jobscript_single.py | 22 ++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index cca9308916..df3c5bddb1 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -8,6 +8,10 @@ case $hostname in cheyenne* | r* ) export MACH="cheyenne" ;; + ##casper + casper* ) + export MACH="casper" + ;; ## Other machines *) export MACH="$hostname" diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index a35e29010b..f5536231c9 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -43,6 +43,14 @@ def get_parser(): dest="tasks_per_node", required=True, ) + parser.add_argument( + "--machine", + help="""currently this recognizes cheyenne and casper (default cheyenne)""", + action="store", + dest="machine", + required=False, + default='cheyenne' + ) parser.add_argument( "--namelist-file", help="""input namelist file (required)""", @@ -70,6 +78,7 @@ def main (): jobscript_file = args.jobscript_file number_of_nodes = args.number_of_nodes tasks_per_node = args.tasks_per_node + machine = args.machine account = args.account # -------------------------- @@ -81,14 +90,21 @@ def main (): runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -N mksurfdata \n') runfile.write('#PBS -j oe \n') - runfile.write('#PBS -q regular \n') runfile.write('#PBS -l walltime=30:00 \n') - runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") + if machine == 'cheyenne': + runfile.write('#PBS -q regular \n') + runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") + elif machine == 'casper': + runfile.write('#PBS -q casper \n') + runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=12:mpiprocs={tasks_per_node} \n") runfile.write("\n") np = int(tasks_per_node) * int(number_of_nodes) - output = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist_file}" + if machine == 'cheyenne': + output = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist_file}" + elif machine == 'casper': + output = f"mpiexec -np {np} ./bld/mksurfdata < {namelist_file}" runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") From 58eb9997e1be9e91457abaa79a6aea2d0976fe6d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 12 May 2022 15:56:39 -0600 Subject: [PATCH 176/614] Add to the --help documentation --- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index f5536231c9..ca07abb72d 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -45,7 +45,10 @@ def get_parser(): ) parser.add_argument( "--machine", - help="""currently this recognizes cheyenne and casper (default cheyenne)""", + help="""currently this recognizes cheyenne and casper (default + cheyenne); this needs to be a cime machine, i.e. a machine + that has been ported to cime where you can build a cime model; + for details see the README in this directory""", action="store", dest="machine", required=False, From 195ae0da739ed7b275b64880395ac00ed723bca6 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 16 May 2022 14:14:49 -0600 Subject: [PATCH 177/614] Untested mods to obtain ORGANIC from the new soil dataset --- tools/mksurfdata_esmf/src/mkorganicMod.F90 | 195 --------------------- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 63 +++++-- tools/mksurfdata_esmf/src/mksurfdata.F90 | 17 +- 3 files changed, 56 insertions(+), 219 deletions(-) delete mode 100644 tools/mksurfdata_esmf/src/mkorganicMod.F90 diff --git a/tools/mksurfdata_esmf/src/mkorganicMod.F90 b/tools/mksurfdata_esmf/src/mkorganicMod.F90 deleted file mode 100644 index fce5dc0e92..0000000000 --- a/tools/mksurfdata_esmf/src/mkorganicMod.F90 +++ /dev/null @@ -1,195 +0,0 @@ -module mkorganicMod - - ! make organic matter dataset - - use ESMF - use pio - use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 - use shr_sys_mod , only : shr_sys_abort - use mkpioMod , only : mkpio_get_rawdata, mkpio_get_dimlengths - use mkpioMod , only : pio_iotype, pio_ioformat, pio_iosystem - use mkesmfMod , only : regrid_rawdata, create_routehandle_r8 - use mkutilsMod , only : chkerr - use mkvarctl , only : root_task, ndiag, spval - use mkvarpar , only : nlevsoi - use mkfileMod , only : mkfile_output - - implicit none - private - - public :: mkorganic ! Set organic soil - - character(len=*) , parameter :: u_FILE_u = & - __FILE__ - -!================================================================================= -contains -!================================================================================= - - subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, pctlnd_pft_o, lat_o, pioid_o, rc) - - ! input/output variables - character(len=*) , intent(in) :: file_mesh_i ! input mesh file name - character(len=*) , intent(in) :: file_data_i ! input data file name - type(ESMF_Mesh) , intent(in) :: mesh_o - real(r8) , intent(in) :: pctlnd_pft_o(:) - real(r8) , intent(in) :: lat_o(:) - type(file_desc_t) , intent(inout) :: pioid_o - integer , intent(out) :: rc - - ! local variables - type(ESMF_RouteHandle) :: routehandle - type(ESMF_Mesh) :: mesh_i - type(file_desc_t) :: pioid_i - type(var_desc_t) :: pio_varid - integer :: ni,no - integer :: ns_i, ns_o - integer :: nlay - integer :: n,l,k ! indices - integer :: rcode, ier ! error status - integer :: ndims - integer , allocatable :: dimlengths(:) - integer , allocatable :: mask_i(:) - real(r8), allocatable :: frac_i(:) - real(r8), allocatable :: frac_o(:) - real(r8), allocatable :: area_i(:) - real(r8), allocatable :: area_o(:) - real(r8), allocatable :: data_i(:,:) - real(r8), allocatable :: data_o(:,:) - real(r8), allocatable :: organic_o(:,:) ! output grid: %lake - character(len=*), parameter :: subname = 'mkorganic' - !----------------------------------------------------------------------- - - rc = ESMF_SUCCESS - - if (root_task) then - write(ndiag,*) - write(ndiag,'(1x,80a1)') ('=',k=1,80) - write(ndiag,*) - write(ndiag,'(a)')'Attempting to make organic mater dataset .....' - write(ndiag,'(a)') ' Input file is '//trim(file_data_i) - write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) - end if - - ! Open input data file - rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) - call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) - - ! Get dimensions of raw data. - ! - raw data is dimensions (lon,lat,lev) - ! - input read from pio has dimensions(n,lev) - ! - esmf field dataptr has dimensions (lev,n) - allocate(dimlengths(3)) - call mkpio_get_dimlengths(pioid_i, 'ORGANIC', ndims, dimlengths) - nlay = dimlengths(3) - if (nlay /= nlevsoi) then - write(6,*)'nlay, nlevsoi= ',nlay,nlevsoi,' do not match' - call shr_sys_abort() - end if - deallocate(dimlengths) - - ! Read in input mesh - call ESMF_VMLogMemInfo("Before create mesh_i in "//trim(subname)) - mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) - - ! Determine ns_i - call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Determine ns_o and allocate output data - call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate ( organic_o(ns_o,nlevsoi)); organic_o(:,:) = spval - - ! Get the landmask from the file and reset the mesh mask based on that - allocate(frac_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - allocate(mask_i(ns_i), stat=ier) - if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, frac_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do ni = 1,ns_i - if (frac_i(ni) > 0._r8) then - mask_i(ni) = 1 - else - mask_i(ni) = 0 - end if - end do - call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Create a route handle between the input and output mesh and get frac_o - allocate(frac_o(ns_o),stat=ier) - if (ier/=0) call shr_sys_abort() - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - - ! Read in input data - ! - levels are the innermost dimension for esmf fields - ! - levels are the outermost dimension in pio reads - ! Input data is read into (ns_i,nlay) array and then transferred to data_i(nlay,ns_i) - allocate(data_i(nlay,ns_i),stat=ier) - if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid_i, 'ORGANIC', mesh_i, data_i, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - - ! Regrid data_i to data_o - allocate(data_o(nlay,ns_o),stat=ier) - if (ier/=0) call shr_sys_abort() - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_i, data_o, 1, nlay, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regrid organic_i in "//trim(subname)) - - ! Set organic_o - do l = 1,nlevsoi - do no = 1,ns_o - organic_o(no,l) = data_o(l,no) - end do - end do - do l = 1,nlevsoi - do no = 1,ns_o - if ((organic_o(no,l)) > 130.000001_r8) then - write (6,*) trim(subname)//' error: organic = ',organic_o(no,l), & - ' greater than 130.000001 for n,lev ',no,l - call shr_sys_abort() - end if - enddo - end do - do no = 1,ns_o - ! If have very small values of pctlnd - set organic_o to zero - if (pctlnd_pft_o(no) < 1.e-6_r8) then - organic_o(no,:) = 0._r8 - end if - ! If have pole points on grid - set south pole to glacier and north pole is not land - if (abs((lat_o(no) - 90._r8)) < 1.e-6_r8) then - organic_o(no,:) = 0._r8 - end if - end do - - ! Write out the output data - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil organic matter density" - call mkfile_output(pioid_o, mesh_o, 'ORGANIC', organic_o, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - - ! Close the file - call pio_closefile(pioid_i) - call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) - - ! Release memory - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) - - if (root_task) then - write (ndiag,'(a)') 'Successfully made organic matter ' - end if - - end subroutine mkorganic - -end module mkorganicMod diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 0d6810df8b..7518452810 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -35,8 +35,7 @@ module mksoiltexMod subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o, pctlnd_pft_o, rc) ! - ! make %sand and %clay from IGBP soil data, which includes - ! igbp soil 'mapunits' and their corresponding textures + ! make %sand, %clay, and organic carbon content ! ! input/output variables character(len=*) , intent(in) :: file_mesh_i ! input mesh/grid file name @@ -67,8 +66,10 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o integer :: mapunit ! temporary igbp soil mapunit integer, allocatable :: sand_i(:,:,:) ! input grid: percent sand integer, allocatable :: clay_i(:,:,:) ! input grid: percent clay + integer, allocatable :: orgc_i(:,:,:) ! input grid: organic carbon content (gC kg-1) real(r4), allocatable :: sand_o(:,:) ! % sand (output grid) real(r4), allocatable :: clay_o(:,:) ! % clay (output grid) + real(r4), allocatable :: orgc_o(:,:) ! organic carbon content (gC kg-1) (output grid) integer :: n_mapunits integer :: lookup_index integer :: SCID @@ -78,6 +79,7 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o integer , allocatable :: mapunit_lookup(:) type(var_desc_t) :: pio_varid_sand type(var_desc_t) :: pio_varid_clay + type(var_desc_t) :: pio_varid_orgc integer :: starts(3) ! starting indices for reading lookup table integer :: counts(3) ! dimension counts for reading lookup table integer :: srcTermProcessing_Value = 0 @@ -89,7 +91,7 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o write(ndiag,*) write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) - write(ndiag,'(a)') 'Attempting to make %sand and %clay .....' + write(ndiag,'(a)') 'Attempting to make %sand, %clay, and orgc .....' write(ndiag,'(a)') ' Input mapunit file is '//trim(file_mapunit_i) write(ndiag,'(a)') ' Input lookup table file is '//trim(file_lookup_i) write(ndiag,'(a)') ' Input mesh/grid file is '//trim(file_mesh_i) @@ -101,6 +103,7 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o allocate(mapunit_o(ns_o)) ; mapunit_o(:) = 0 allocate(sand_o(ns_o,nlevsoi)) ; sand_o(:,:) = spval allocate(clay_o(ns_o,nlevsoi)) ; clay_o(:,:) = spval + allocate(orgc_o(ns_o,nlevsoi)) ; orgc_o(:,:) = spval !--------------------------------- ! Determine mapunits on output grid @@ -212,7 +215,7 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o call pio_syncfile(pioid_o) !--------------------------------- - ! Determine %sand and %clay on output grid - using above mapunits + ! Determine %sand, %clay, and orgc on output grid - using above mapunits !--------------------------------- rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_lookup_i), pio_nowrite) @@ -243,13 +246,18 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o if (ier/=0) call shr_sys_abort() allocate(clay_i(nlay,n_scid,n_mapunits)) if (ier/=0) call shr_sys_abort() + allocate(orgc_i(nlay,n_scid,n_mapunits)) + if (ier/=0) call shr_sys_abort() - ! Get dimensions from input file and allocate memory for sand_i and clay_i + ! Get dimensions from input file and allocate memory for sand_i, clay_i, + ! and organic carbon content rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid_sand) rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid_clay) + rcode = pio_inq_varid(pioid_i, 'ORGC', pio_varid_orgc) rcode = pio_get_var(pioid_i, pio_varid_sand, sand_i) rcode = pio_get_var(pioid_i, pio_varid_clay, clay_i) + rcode = pio_get_var(pioid_i, pio_varid_orgc, orgc_i) do no = 1,ns_o @@ -258,13 +266,14 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o ! Adjust sand and clay be loam if pctlnd_pft is < 1.e-6 or mapunit is 0 sand_o(no,:) = 43._r4 clay_o(no,:) = 18._r4 + orgc_o(no,:) = 18._r4 ! TODO slevis: value for loam here? else ! Determine lookup_index lookup_index = mapunit_lookup(mapunit_o(no)) - ! Determine the top soil layer sand_o and clay_o + ! Determine the top soil layer sand_o, clay_o, and orgc_o ! If its less than 0 search within the SCID array for the first index ! that gives a pct sand that is greater than or equal to 0 ! Then determine the other soil layers sand_o @@ -293,9 +302,7 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o end if end do - ! If its less than 0 search within the SCID array for the first index - ! that gives a pct clay that is greater than or equal to 0 - ! Now determine the other soil layers clay_o + ! Same algorithm for clay_o as for sand_o clay_o(no,1) = float(clay_i(1,1,lookup_index)) if (clay_o(no,1) < 0.) then do l = 2,n_scid @@ -325,6 +332,38 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o end if end do + ! Same algorithm for orgc_o as for sand_o + ! TODO slevis: Get conversion (units etc) from Will's and Dave's + ! discussion in issue 1303 + orgc_o(no,1) = float(orgc_i(1,1,lookup_index)) + if (orgc_o(no,1) < 0.) then + do l = 2,n_scid + if (float(orgc_i(1,l,lookup_index)) >= 0.) then + orgc_o(no,1) = float(orgc_i(1,l,lookup_index)) + exit + end if + end do + end if + if (orgc_o(no,1) < 0.) then + if (int(orgc_o(no,1)) == -4) then + write(6,'(a,i8)')'WARNING: changing orgc_o from -4 to 0 at no = ',no + orgc_o(no,:) = 0._r4 + else + write(6,'(a,i8,a,i8)')'WARNING: changing orgc_o from ',int(orgc_o(no,1)),' to 18 at no = ',no + orgc_o(no,:) = 18._r4 ! TODO slevis: Value for loam here? + end if + end if + if (orgc_o(no,1) < 0.) then + write(6,*)'ERROR: at no, lookup_index = ',no,lookup_index + call shr_sys_abort('could not find a value >= 0 for orgc_i') + end if + do l = 2,nlay + orgc_o(no,l) = float(orgc_i(l,1,lookup_index)) + if (orgc_o(no,l) < 0. .and. l > 1) then + orgc_o(no,l) = orgc_o(no,l-1) + end if + end do + end if end do @@ -337,6 +376,10 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil organic carbon content" + call mkfile_output(pioid_o, mesh_o, 'ORGANIC', orgc_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) ! Release memory @@ -347,7 +390,7 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) if (root_task) then - write (ndiag,'(a)') 'Successfully made %sand and %clay' + write (ndiag,'(a)') 'Successfully made %sand, %clay, and orgc' end if end subroutine mksoiltex diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 827591a69c..64127adae1 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -26,14 +26,12 @@ program mksurfdata ! mksrf_flakwat_mesh - Mesh for mksrf_flakwat ! mksrf_fwetlnd - Wetland water dataset ! mksrf_fwetlnd_mesh - Mesh for mksrf_fwetlnd - ! mksrf_forganic - Organic soil carbon dataset - ! mksrf_forganic_mesh - Mesh for mksrf_forganic ! mksrf_fmax - Max fractional saturated area dataset ! mksrf_fmax_mesh - Mesh for mksrf_fmax ! mksrf_fsoicol - Soil color dataset ! mksrf_fsoicol_mesh - Mesh for mksrf_fsoicol ! mksrf_fsoitex - Soil texture dataset in mapunits - ! mksrf_fsoitex_lookup - Soil texture lookup for converting mapunits to sand/silt/clay + ! mksrf_fsoitex_lookup - Soil texture lookup for converting mapunits to sand/silt/clay and organic carbon content ! mksrf_fsoitex_mesh - Mesh for mksrf_fsoitex ! mksrf_furbtopo - Topography dataset (for limiting urban areas) ! mksrf_furbtopo_mesh - Mesh for mksrf_furbtopo @@ -109,7 +107,6 @@ program mksurfdata use mksoilcolMod , only : mksoilcol use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, mkurban_topo, numurbl, update_max_array_urban use mklanwatMod , only : mklakwat, mkwetlnd, update_max_array_lake - use mkorganicMod , only : mkorganic use mkutilsMod , only : normalize_classes_by_gcell, chkerr use mkfileMod , only : mkfile_define_dims, mkfile_define_atts, mkfile_define_vars use mkfileMod , only : mkfile_output @@ -447,7 +444,7 @@ program mksurfdata end if ! ----------------------------------- - ! Make soil texture [pctsand, pctclay] + ! Make soil texture and organic carbon content [pctsand, pctclay, organic] ! ----------------------------------- if (fsurdat /= ' ') then call mksoiltex( mksrf_fsoitex_mesh, file_mapunit_i=mksrf_fsoitex, file_lookup_i=mksrf_fsoitex_lookup, & @@ -554,18 +551,10 @@ program mksurfdata if (fsurdat /= ' ') then if (outnc_vic) then call mkVICparams ( mksrf_fvic_mesh, mksrf_fvic, mesh_model, pioid, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkVICparams') end if end if - ! ----------------------------------- - ! Make organic matter density [organic] [forganic] - ! ----------------------------------- - if (fsurdat /= ' ') then - call mkorganic( mksrf_forganic_mesh, mksrf_forganic, mesh_model, pctlnd_pft, lat, pioid, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkorganic') - end if - ! ----------------------------------- ! Make VOC emission factors for isoprene [ef1_btr,ef1_fet,ef1_fdt,ef1_shr,ef1_grs,ef1_crp] ! ----------------------------------- From 0a25ee0adcc00fd740784eefd03badae766fac39 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 17 May 2022 11:06:43 -0600 Subject: [PATCH 178/614] Add . ./.env_mach_specific.sh to gen_mksurfdata_jobscript_*.py --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 2 +- .../mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py | 8 ++++++-- .../mksurfdata_esmf/gen_mksurfdata_jobscript_single.py | 10 +++++++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index df3c5bddb1..7518852af2 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -44,7 +44,7 @@ if [ $? != 0 ]; then echo "Error doing configure for machine name: $MACH" exit 1 fi -. .env_mach_specific.sh +. ./.env_mach_specific.sh echo "COMPILER = $COMPILER, MPILIB = $MPILIB, DEBUG = $DEBUG, OS = $OS" if [ -z "$PIO" ]; then echo "The PIO directory for the PIO build is required and was not set in the configure" diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 1396ee692c..7de280d453 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -224,8 +224,12 @@ def main (): output = run_cmd.stdout.decode('utf-8').strip() namelist = output.split(' ')[-1] print (f"generated namelist {namelist}") - output = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist}" - runfile.write(f"{output} \n") + # Run env_mach_specific.sh to control the machine dependent + # environment including the paths to compilers and libraries + # external to cime such as netcdf + output1 = f". ./.env_mach_specific.sh" + output2 = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist}" + runfile.write(f"{output1} \n{output2} \n") print (f"Successfully created jobscript {jobscript_file}") sys.exit(0) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index f5536231c9..e9c854961b 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -101,11 +101,15 @@ def main (): np = int(tasks_per_node) * int(number_of_nodes) + # Run env_mach_specific.sh to control the machine dependent environment + # including the paths to compilers and libraries external to cime such + # as netcdf + output1 = f". ./.env_mach_specific.sh" if machine == 'cheyenne': - output = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist_file}" + output2 = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist_file}" elif machine == 'casper': - output = f"mpiexec -np {np} ./bld/mksurfdata < {namelist_file}" - runfile.write(f"{output} \n") + output2 = f"mpiexec -np {np} ./bld/mksurfdata < {namelist_file}" + runfile.write(f"{output1} \n{output2} \n") print (f"Successfully created jobscript {jobscript_file}") sys.exit(0) From dd72733a30b50c4e860639106c6e663975bc4f55 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 17 May 2022 11:09:05 -0600 Subject: [PATCH 179/614] First successful version of new test-suite system test --- cime_config/SystemTests/mksurfdataesmf.py | 41 +++++++++++++++++++++++ cime_config/config_tests.xml | 10 ++++++ 2 files changed, 51 insertions(+) create mode 100644 cime_config/SystemTests/mksurfdataesmf.py diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py new file mode 100644 index 0000000000..5e985ad633 --- /dev/null +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -0,0 +1,41 @@ +""" +""" + +import os +import re +import subprocess +from CIME.SystemTests.system_tests_common import SystemTestsCommon +from CIME.XML.standard_module_setup import * +from CIME.SystemTests.test_utils.user_nl_utils import append_to_user_nl_files + +logger = logging.getLogger(__name__) + +class MKSURFDATAESMF(SystemTestsCommon): + + def __init__(self, case): + """ + initialize an object interface to the SMS system test + """ + SystemTestsCommon.__init__(self, case) + + # Steps for here or build phase (e.g. see ssp.py) + # 1) build executable self._build_script_path + # 2) generate namelist self._nml_script_path + # 3) generate jobscript self._job_script_path + # 4) change user_nl_clm as done in fsurdatmodify... + + def run_phase(self): + """ + Submit jobscript + Submit CTSM run that uses fsurdat just generated + """ + # Submit jobscript + # MKSURFDATAESMF_P144x1.f19_g17.I1850Clm50BgcCrop.cheyenne_intel.clm-default + # with -np 144 stopped; presumably ran out of memory + # MKSURFDATAESMF_P48x3.f19_g17.I1850Clm50BgcCrop.cheyenne_intel.clm-default + # with -np 48 (144 gave error) stopped; presumably ran out of memory + # MKSURFDATAESMF_P144x1.f10_f10_mg37.I1850Clm50BgcCrop.cheyenne_intel.clm-default + # with -np 144 worked! + subprocess.check_call("mpiexec_mpt -np 144 /glade/work/slevis/git/mksurfdata_toolchain/tools/mksurfdata_esmf/bld/mksurfdata < /glade/work/slevis/git/mksurfdata_toolchain/tools/mksurfdata_esmf/surfdata_10x15_hist_78pfts_CMIP6_1850_c220517.namelist", shell=True) + # Submit CTSM run that uses fsurdat just generated + self.run_indv() diff --git a/cime_config/config_tests.xml b/cime_config/config_tests.xml index 0307ee7ef5..d10ac7bc01 100644 --- a/cime_config/config_tests.xml +++ b/cime_config/config_tests.xml @@ -15,6 +15,16 @@ This defines various CTSM-specific system tests FALSE + + Build and run the mksurfdata_esmf tool to generate a new fsurdat; then run the CTSM with this fsurdat + 1 + FALSE + FALSE + never + $STOP_OPTION + $STOP_N + + Run the CTSM with an fsurdat generated by the fsurdat_modify tool 1 From b8fc13619017542bd9867b83d0f97947d2ab5e49 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 17 May 2022 18:01:36 -0600 Subject: [PATCH 180/614] Changes needed for gen_mksurfdata_build.sh to work with new system test --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index 7518852af2..3e79e34519 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -20,14 +20,14 @@ esac # Create /bld directory echo "cime Machine is: $MACH..." -if [ -d "bld" ]; then +cwd=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +if [ -d "$cwd/bld" ]; then echo "A /bld directory exists; remove it to do a clean build..." exit 1 fi -cwd=`pwd` -rm -rf bld -mkdir bld -cd bld +rm -rf $cwd/bld +mkdir $cwd/bld +cd $cwd/bld # Run the cime configure tool to figure out what modules need to be loaded echo "Run cime configure for machine $MACH..." From 32264cd31a9db98c802ccf769154100ad08355e9 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 17 May 2022 18:10:38 -0600 Subject: [PATCH 181/614] Fleshing out the steps to complete this system test (not done) --- cime_config/SystemTests/mksurfdataesmf.py | 72 ++++++++++++++++++----- 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 5e985ad633..8acfe1f5a6 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -1,8 +1,9 @@ """ +This test passes if mksurfdata_esmf generates an fsurdat (surface dataset) +and the CTSM completes a simulation with this fsurdat file. """ import os -import re import subprocess from CIME.SystemTests.system_tests_common import SystemTestsCommon from CIME.XML.standard_module_setup import * @@ -18,24 +19,65 @@ def __init__(self, case): """ SystemTestsCommon.__init__(self, case) - # Steps for here or build phase (e.g. see ssp.py) - # 1) build executable self._build_script_path - # 2) generate namelist self._nml_script_path - # 3) generate jobscript self._job_script_path - # 4) change user_nl_clm as done in fsurdatmodify... + # Paths and command strings + self._ctsm_root = self._case.get_value('COMP_ROOT_DIR_LND') + self._tool_path = os.path.join(self._ctsm_root, 'tools/mksurfdata_esmf') + + def build_phase(self, sharedlib_only=False, model_only=False): + """ + Build executable that will generate fsurdat + Generate namelist for generating fsurdat + SKIP Generate jobscript + Submit jobscript to generate fsurdat + Modify user_nl_clm to point to the generated fsurdat + """ + # These steps need only happen once + if not os.path.exists(os.path.join(self._get_caseroot(), + 'done_MKSURFDATAESMF_setup.txt')): + # Paths and command strings + self._rm_bld_dir = f"rm -rf {self._tool_path}/bld" + self._fsurdat_out_prefix = os.path.join(self._get_caseroot(), 'surfdata_10x15_hist_78pfts_CMIP6_1850_c220517.') + self._build_script_path = os.path.join(self._tool_path, + 'gen_mksurfdata_build.sh') + self._nml_script_path = os.path.join(self._tool_path, + 'gen_mksurfdata_namelist.py') + self._gen_mksurfdata_namelist = f"{self._nml_script_path} --res 10x15 --start-year 1850 --end-year 1850" + + # Build executable + subprocess.check_call(self._rm_bld_dir, shell=True) + subprocess.check_call(self._build_script_path, shell=True) + + # Generate namelist self._nml_script_path + # TODO Error: No such file or directory: './gen_mksurfdata_namelist.xml' ...probably need explicit path for this to work + # subprocess.check_call(self._gen_mksurfdata_namelist, shell=True) + + # Modify user_nl_clm to point to the generated fsurdat + self._modify_user_nl() + with open('done_MKSURFDATAESMF_setup.txt', 'w') as fp: + pass + + self.build_indv(sharedlib_only=sharedlib_only, model_only=model_only) def run_phase(self): """ - Submit jobscript + Submit jobscript to generate fsurdat Submit CTSM run that uses fsurdat just generated """ - # Submit jobscript - # MKSURFDATAESMF_P144x1.f19_g17.I1850Clm50BgcCrop.cheyenne_intel.clm-default - # with -np 144 stopped; presumably ran out of memory - # MKSURFDATAESMF_P48x3.f19_g17.I1850Clm50BgcCrop.cheyenne_intel.clm-default - # with -np 48 (144 gave error) stopped; presumably ran out of memory - # MKSURFDATAESMF_P144x1.f10_f10_mg37.I1850Clm50BgcCrop.cheyenne_intel.clm-default - # with -np 144 worked! - subprocess.check_call("mpiexec_mpt -np 144 /glade/work/slevis/git/mksurfdata_toolchain/tools/mksurfdata_esmf/bld/mksurfdata < /glade/work/slevis/git/mksurfdata_toolchain/tools/mksurfdata_esmf/surfdata_10x15_hist_78pfts_CMIP6_1850_c220517.namelist", shell=True) + # Paths and command strings + self._executable_path = os.path.join(self._tool_path, 'bld/mksurfdata') + # self._mpiexec_mpt_cmd = f"mpiexec_mpt -np 144 {self._executable_path} < {self._fsurdat_out_prefix}namelist" # TODO Rm nxt line when this is ready + self._mpiexec_mpt_cmd = f"mpiexec_mpt -np 144 {self._executable_path} < {self._tool_path}/surfdata_10x15_hist_78pfts_CMIP6_1850_c220517.namelist" + + # Submit jobscript to generate fsurdat + subprocess.check_call(self._mpiexec_mpt_cmd, shell=True) + # Submit CTSM run that uses fsurdat just generated self.run_indv() + + def _modify_user_nl(self): + """ + Modify user_nl_clm to point to the generated fsurdat + """ + append_to_user_nl_files(caseroot = self._get_caseroot(), + component = "clm", + contents = "fsurdat = '{}nc'".format(self._fsurdat_out_prefix)) From 575f770ed4bf4db0ae98596a62b8920088dd6a35 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 17 May 2022 18:29:36 -0600 Subject: [PATCH 182/614] Small revisions in response to ErikK's code review --- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index e9c854961b..e4e2ca36a0 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -23,7 +23,7 @@ def get_parser(): ) parser.add_argument( "--account", - help="""account number (default P93300606)""", + help="""account number (default: %(default)s)""", action="store", dest="account", required=False, @@ -45,10 +45,11 @@ def get_parser(): ) parser.add_argument( "--machine", - help="""currently this recognizes cheyenne and casper (default cheyenne)""", + help="""default: %(default)s""", action="store", dest="machine", required=False, + choices=['cheyenne', 'casper'], # TODO Plan on adding izumi here default='cheyenne' ) parser.add_argument( @@ -60,7 +61,7 @@ def get_parser(): ) parser.add_argument( "--jobscript-file", - help="""output jobscript file to be submitted on cheyenne (default is mksurfdata_jobscript_single)]""", + help="""output jobscript file to be submitted on cheyenne (default: %(default)s)""", action="store", dest="jobscript_file", required=False, From d1de496d0eb503a2c6533e1d30c015e840157249 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 17 May 2022 18:56:36 -0600 Subject: [PATCH 183/614] More updates in response to code review --- .../gen_mksurfdata_jobscript_single.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index e4e2ca36a0..ef8662b2eb 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -88,6 +88,8 @@ def main (): with open(jobscript_file, "w",encoding='utf-8') as runfile: runfile.write('#!/bin/bash \n') + runfile.write('# Edit the batch directives for your batch system \n') + runfile.write('# Below are the batch directives used on cheyenne \n') runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -N mksurfdata \n') runfile.write('#PBS -j oe \n') @@ -105,12 +107,13 @@ def main (): # Run env_mach_specific.sh to control the machine dependent environment # including the paths to compilers and libraries external to cime such # as netcdf - output1 = f". ./.env_mach_specific.sh" + runfile.write(f". ./.env_mach_specific.sh \n") + runfile.write('# Edit the mpirun command to use the MPI executable on your system and the arguments it requires \n') if machine == 'cheyenne': - output2 = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist_file}" + output = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist_file}" elif machine == 'casper': - output2 = f"mpiexec -np {np} ./bld/mksurfdata < {namelist_file}" - runfile.write(f"{output1} \n{output2} \n") + output = f"mpiexec -np {np} ./bld/mksurfdata < {namelist_file}" + runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") sys.exit(0) From a0540a4af64100ab35b9d194b594d6183b003ad5 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 18 May 2022 09:23:27 -0600 Subject: [PATCH 184/614] Further fleshing out of the steps involved in this test --- cime_config/SystemTests/mksurfdataesmf.py | 3 +-- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 10 +++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 8acfe1f5a6..28ebc2613c 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -48,8 +48,7 @@ def build_phase(self, sharedlib_only=False, model_only=False): subprocess.check_call(self._build_script_path, shell=True) # Generate namelist self._nml_script_path - # TODO Error: No such file or directory: './gen_mksurfdata_namelist.xml' ...probably need explicit path for this to work - # subprocess.check_call(self._gen_mksurfdata_namelist, shell=True) + subprocess.check_call(self._gen_mksurfdata_namelist, shell=True) # Modify user_nl_clm to point to the generated fsurdat self._modify_user_nl() diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index ae3f62e5c6..525f277376 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -329,7 +329,9 @@ def main (): rawdata_files = {} # determine input rawdata - tree1 = ET.parse('./gen_mksurfdata_namelist.xml') + tool_path = os.path.dirname(os.path.abspath(__file__)) + xml_path = os.path.join(tool_path, 'gen_mksurfdata_namelist.xml') + tree1 = ET.parse(xml_path) root = tree1.getroot() root.tag root.attrib @@ -391,7 +393,8 @@ def main (): rawdata_files[new_key] = os.path.join(input_path, item.text) # determine output mesh - tree2 = ET.parse('../../ccs_config/component_grids_nuopc.xml') + xml_path = os.path.join(tool_path, '../../ccs_config/component_grids_nuopc.xml') + tree2 = ET.parse(xml_path) root = tree2.getroot() model_mesh = "" for child1 in root: # this is domain tag @@ -490,7 +493,8 @@ def main (): fsurlog = f"surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.log" fdyndat = f"landuse.timeseries_{res}_{ssp_rcp_name}_{num_pft}_CMIP6_{start_year}-{end_year}_c{time_stamp}.nc" - gitdescribe = subprocess.check_output('git describe', shell=True).strip() + git_desc_cmd = f"git -C {tool_path} describe" + gitdescribe = subprocess.check_output(git_desc_cmd, shell=True).strip() gitdescribe = gitdescribe.decode('utf-8') # The below two overrides are only used for testing an validation From 5f02dfee28227c5973bfb0b3dc86be3e736a16ee Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 18 May 2022 10:59:31 -0600 Subject: [PATCH 185/614] Remove some hardwiring --- cime_config/SystemTests/mksurfdataesmf.py | 13 ++++++++----- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 28ebc2613c..75d4fd096f 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -5,6 +5,7 @@ import os import subprocess +from datetime import datetime from CIME.SystemTests.system_tests_common import SystemTestsCommon from CIME.XML.standard_module_setup import * from CIME.SystemTests.test_utils.user_nl_utils import append_to_user_nl_files @@ -19,9 +20,13 @@ def __init__(self, case): """ SystemTestsCommon.__init__(self, case) - # Paths and command strings + # Paths and strings self._ctsm_root = self._case.get_value('COMP_ROOT_DIR_LND') self._tool_path = os.path.join(self._ctsm_root, 'tools/mksurfdata_esmf') + _time_stamp = datetime.today().strftime("%y%m%d") + self._res = '10x15' + self._model_yr = '1850' + self._fsurdat_out_prefix = os.path.join(self._get_caseroot(), f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{_time_stamp}.') def build_phase(self, sharedlib_only=False, model_only=False): """ @@ -36,12 +41,11 @@ def build_phase(self, sharedlib_only=False, model_only=False): 'done_MKSURFDATAESMF_setup.txt')): # Paths and command strings self._rm_bld_dir = f"rm -rf {self._tool_path}/bld" - self._fsurdat_out_prefix = os.path.join(self._get_caseroot(), 'surfdata_10x15_hist_78pfts_CMIP6_1850_c220517.') self._build_script_path = os.path.join(self._tool_path, 'gen_mksurfdata_build.sh') self._nml_script_path = os.path.join(self._tool_path, 'gen_mksurfdata_namelist.py') - self._gen_mksurfdata_namelist = f"{self._nml_script_path} --res 10x15 --start-year 1850 --end-year 1850" + self._gen_mksurfdata_namelist = f'{self._nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}' # Build executable subprocess.check_call(self._rm_bld_dir, shell=True) @@ -64,8 +68,7 @@ def run_phase(self): """ # Paths and command strings self._executable_path = os.path.join(self._tool_path, 'bld/mksurfdata') - # self._mpiexec_mpt_cmd = f"mpiexec_mpt -np 144 {self._executable_path} < {self._fsurdat_out_prefix}namelist" # TODO Rm nxt line when this is ready - self._mpiexec_mpt_cmd = f"mpiexec_mpt -np 144 {self._executable_path} < {self._tool_path}/surfdata_10x15_hist_78pfts_CMIP6_1850_c220517.namelist" + self._mpiexec_mpt_cmd = f"mpiexec_mpt -np 144 {self._executable_path} < {self._fsurdat_out_prefix}namelist" # Submit jobscript to generate fsurdat subprocess.check_call(self._mpiexec_mpt_cmd, shell=True) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 525f277376..d2f0d4edf6 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -9,7 +9,7 @@ logger = logging.getLogger(__name__) -# valid options for SSP scenarios and pft years: +# valid options for SSP/RCP scenarios valid_opts = {"ssp-rcp": ["none","SSP1-2.6","SSP3-7.0","SSP5-3.4","SSP2-4.5","SSP1-1.9","SSP4-3.4","SSP4-6.0","SSP5-8.5"]} def get_parser(): @@ -52,7 +52,7 @@ def get_parser(): help=""" model resolution [default: %(default)s] To see available supported resolutions, simply invoke this command - with a --res unknown opion + with a --res unknown option """, action="store", dest="res", From 9621dd6d9873ad98b7a18af2aed39c124c91897f Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 18 May 2022 11:17:03 -0600 Subject: [PATCH 186/614] Update some comments --- cime_config/SystemTests/mksurfdataesmf.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 75d4fd096f..b554fb15cb 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -1,6 +1,10 @@ """ This test passes if mksurfdata_esmf generates an fsurdat (surface dataset) and the CTSM completes a simulation with this fsurdat file. + +We test res = '10x15' because it uses a lower-res topography file instead of +the 1-km topography raw dataset. The 1-km file causes the test to run out of +memory on cheyenne. """ import os @@ -20,11 +24,11 @@ def __init__(self, case): """ SystemTestsCommon.__init__(self, case) - # Paths and strings + # Paths and strings needed throughout self._ctsm_root = self._case.get_value('COMP_ROOT_DIR_LND') self._tool_path = os.path.join(self._ctsm_root, 'tools/mksurfdata_esmf') _time_stamp = datetime.today().strftime("%y%m%d") - self._res = '10x15' + self._res = '10x15' # see important comment in script's docstring self._model_yr = '1850' self._fsurdat_out_prefix = os.path.join(self._get_caseroot(), f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{_time_stamp}.') @@ -32,14 +36,13 @@ def build_phase(self, sharedlib_only=False, model_only=False): """ Build executable that will generate fsurdat Generate namelist for generating fsurdat - SKIP Generate jobscript - Submit jobscript to generate fsurdat + SKIP Generate jobscript that runs executable Modify user_nl_clm to point to the generated fsurdat """ # These steps need only happen once if not os.path.exists(os.path.join(self._get_caseroot(), 'done_MKSURFDATAESMF_setup.txt')): - # Paths and command strings + # Paths and strings self._rm_bld_dir = f"rm -rf {self._tool_path}/bld" self._build_script_path = os.path.join(self._tool_path, 'gen_mksurfdata_build.sh') @@ -51,7 +54,7 @@ def build_phase(self, sharedlib_only=False, model_only=False): subprocess.check_call(self._rm_bld_dir, shell=True) subprocess.check_call(self._build_script_path, shell=True) - # Generate namelist self._nml_script_path + # Generate namelist for generating fsurdat subprocess.check_call(self._gen_mksurfdata_namelist, shell=True) # Modify user_nl_clm to point to the generated fsurdat @@ -63,14 +66,14 @@ def build_phase(self, sharedlib_only=False, model_only=False): def run_phase(self): """ - Submit jobscript to generate fsurdat + Run executable to generate fsurdat Submit CTSM run that uses fsurdat just generated """ # Paths and command strings self._executable_path = os.path.join(self._tool_path, 'bld/mksurfdata') self._mpiexec_mpt_cmd = f"mpiexec_mpt -np 144 {self._executable_path} < {self._fsurdat_out_prefix}namelist" - # Submit jobscript to generate fsurdat + # Run executable to generate fsurdat subprocess.check_call(self._mpiexec_mpt_cmd, shell=True) # Submit CTSM run that uses fsurdat just generated From cd0daa1de775815111378012f6723ba43cf2ee47 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 18 May 2022 12:35:26 -0600 Subject: [PATCH 187/614] Adding flexibility of running this test from casper, though read caveat: Currently casper complains that `git -C` is not a valid option. I added -C to the `git describe` in gen_mksurfdata_namelist.py for this system test to work. --- cime_config/SystemTests/mksurfdataesmf.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index b554fb15cb..2d1dd03999 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -71,7 +71,11 @@ def run_phase(self): """ # Paths and command strings self._executable_path = os.path.join(self._tool_path, 'bld/mksurfdata') - self._mpiexec_mpt_cmd = f"mpiexec_mpt -np 144 {self._executable_path} < {self._fsurdat_out_prefix}namelist" + _machine = self._case.get_value("MACH") + if _machine == 'cheyenne': + self._mpiexec_mpt_cmd = f"mpiexec_mpt -np 144 {self._executable_path} < {self._fsurdat_out_prefix}namelist" + elif _machine == 'casper': + self._mpiexec_mpt_cmd = f"mpiexec -np 144 {self._executable_path} < {self._fsurdat_out_prefix}namelist" # Run executable to generate fsurdat subprocess.check_call(self._mpiexec_mpt_cmd, shell=True) From f1253dc80cd124023e8cc154acb995f29ccccdb3 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 18 May 2022 16:28:09 -0600 Subject: [PATCH 188/614] Added comment to the script's docstring --- cime_config/SystemTests/mksurfdataesmf.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 2d1dd03999..e9436e51f5 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -5,6 +5,10 @@ We test res = '10x15' because it uses a lower-res topography file instead of the 1-km topography raw dataset. The 1-km file causes the test to run out of memory on cheyenne. + +Currently casper complains that `git -C` is not a valid option. +I added -C to the `git describe` in gen_mksurfdata_namelist.py for this +system test to work. """ import os From 08a77d7fd9289899c087cb732337bad6247d711b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 18 May 2022 16:37:27 -0600 Subject: [PATCH 189/614] Added the new test to testlist_clm.xml --- cime_config/testdefs/testlist_clm.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index aea66ac8bc..74a3282d24 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -2369,6 +2369,23 @@ + + + + + + + + + + + + + + + + + From 250cb06e44244772236abfa0838279aae667c1ef Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 18 May 2022 17:02:44 -0600 Subject: [PATCH 190/614] Added request for mem=20GB when running mksurfdata_esmf on casper --- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index ca07abb72d..8cc1e66e4a 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -99,7 +99,7 @@ def main (): runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") elif machine == 'casper': runfile.write('#PBS -q casper \n') - runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=12:mpiprocs={tasks_per_node} \n") + runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=12:mpiprocs={tasks_per_node}:mem=20GB \n") runfile.write("\n") np = int(tasks_per_node) * int(number_of_nodes) From 31dba9604294ca698a71300363072bd48bbf039f Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 19 May 2022 10:34:42 -0600 Subject: [PATCH 191/614] Introducing ./download_input_data to /tools/mksurfdata_esmf --- python/ctsm/mksurfdata_download_input_data.py | 86 +++++++++++++++++++ tools/mksurfdata_esmf/download_input_data | 18 ++++ .../gen_mksurfdata_namelist.py | 41 ++++++--- 3 files changed, 131 insertions(+), 14 deletions(-) create mode 100644 python/ctsm/mksurfdata_download_input_data.py create mode 100755 tools/mksurfdata_esmf/download_input_data diff --git a/python/ctsm/mksurfdata_download_input_data.py b/python/ctsm/mksurfdata_download_input_data.py new file mode 100644 index 0000000000..25df41e969 --- /dev/null +++ b/python/ctsm/mksurfdata_download_input_data.py @@ -0,0 +1,86 @@ +"""Functions implementing the download_input_data command for mksurfdata""" + +import argparse +import logging +import os +import re + +from CIME.case import Case # pylint: disable=import-error + +from ctsm.ctsm_logging import setup_logging_pre_config, add_logging_args, process_logging_args + +logger = logging.getLogger(__name__) + +# ======================================================================== +# Define some constants +# ======================================================================== + +# In surfdata.namelist, file names match this pattern: +_FILENAME = r" = '/" + +# ======================================================================== +# Public functions +# ======================================================================== + +def main(): + """Main function called when download_input_data is run from the command-line + """ + setup_logging_pre_config() + args = _commandline_args() + process_logging_args(args) + + download_input_data(rundir=args.rundir) + +def download_input_data(rundir): + """Implementation of the download_input_data command + + Args: + rundir: str - path to directory containing .input_data_list file + """ + _create_input_data_list(rundir) + # TODO Remove hardwiring + case = Case(os.path.realpath('/home/slevis/cases_FATES/CZ2_acf_off')) + case.check_all_input_data( + data_list_dir=rundir, + download=True, + chksum=False) + os.remove(os.path.join(rundir, '.input_data_list')) + +# ======================================================================== +# Private functions +# ======================================================================== + +def _commandline_args(): + """Parse and return command-line arguments + """ + + description = """ +Script to download any missing input data for mksurfdata_esmf +""" + + parser = argparse.ArgumentParser( + description=description, + formatter_class=argparse.RawTextHelpFormatter) + + parser.add_argument("--rundir", default=os.getcwd(), + help="Full path of the run directory\n" + "(This directory should contain .input_data_list and surfdata.namelist,\n" + "among other files.)\n" + "(Note: it is assumed that this directory exists alongside the other\n" + "directories created by build_ctsm: 'case' and 'inputdata'.)") + + add_logging_args(parser) + + args = parser.parse_args() + + return args + +def _create_input_data_list(rundir): + with open(os.path.join(rundir, 'surfdata.namelist')) as namelist: + with open(os.path.join(rundir, '.input_data_list'), 'w') as input_data_list: + for line in namelist: + if re.search(_FILENAME, line): + # Remove quotes from filename, then output this line + line = line.replace('"', '') + line = line.replace("'", "") + input_data_list.write(line) diff --git a/tools/mksurfdata_esmf/download_input_data b/tools/mksurfdata_esmf/download_input_data new file mode 100755 index 0000000000..c7f9918247 --- /dev/null +++ b/tools/mksurfdata_esmf/download_input_data @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +"""Download input data for running mksurfdata_esmf""" + +import os +import sys + +_CTSM_PYTHON = os.path.join(os.path.dirname(os.path.realpath(__file__)), + os.pardir, + os.pardir, + 'python') +sys.path.insert(1, _CTSM_PYTHON) + +from ctsm import add_cime_to_path + +from ctsm.mksurfdata_download_input_data import main + +if __name__ == "__main__": + main() diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index ae3f62e5c6..51150fd25b 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -329,6 +329,7 @@ def main (): rawdata_files = {} # determine input rawdata + _must_run_download_input_data = False tree1 = ET.parse('./gen_mksurfdata_namelist.xml') root = tree1.getroot() root.tag @@ -372,15 +373,17 @@ def main (): rawdata_files[child1.tag] = os.path.join(input_path, item.text) if '%y' not in rawdata_files[child1.tag]: if not os.path.isfile(rawdata_files[child1.tag]): - print(f"ERROR: input data file {rawdata_files[child1.tag]} for {child1.tag} does not exist") - sys.exit(20) + print(f"WARNING: input data file {rawdata_files[child1.tag]} for {child1.tag} does not exist") + print(f"WARNING: run ./download_input_data to try to obtain missing files") + _must_run_download_input_data = True if item.tag == 'mesh_filename': new_key = f"{child1.tag}_mesh" rawdata_files[new_key] = os.path.join(input_path, item.text) if not os.path.isfile(rawdata_files[new_key]): - print(f"ERROR: input mesh file {rawdata_files[new_key]} does not exist") - sys.exit(30) + print(f"WARNING: input mesh file {rawdata_files[new_key]} does not exist") + print(f"WARNING: run ./download_input_data to try to obtain missing files") + _must_run_download_input_data = True if item.tag == 'lake_filename': new_key = f"{child1.tag}_lake" @@ -451,14 +454,17 @@ def main (): landuse_input_fnam2 = file2.replace("%y",str(year)) landuse_input_fnam3 = file3.replace("%y",str(year)) if not os.path.isfile(landuse_input_fname): - print(f"ERROR: landunit_input_fname: {landuse_input_fname} does not exist") - sys.exit(60) + print(f"WARNING: landunit_input_fname: {landuse_input_fname} does not exist") + print(f"WARNING: run ./download_input_data to try to obtain missing files") + _must_run_download_input_data = True if not os.path.isfile(landuse_input_fnam2): - print(f"ERROR: landunit_input_fnam2: {landuse_input_fnam2} does not exist") - sys.exit(60) + print(f"WARNING: landunit_input_fnam2: {landuse_input_fnam2} does not exist") + print(f"WARNING: run ./download_input_data to try to obtain missing files") + _must_run_download_input_data = True if not os.path.isfile(landuse_input_fnam3): - print(f"ERROR: landunit_input_fnam3: {landuse_input_fnam3} does not exist") - sys.exit(60) + print(f"WARNING: landunit_input_fnam3: {landuse_input_fnam3} does not exist") + print(f"WARNING: run ./download_input_data to try to obtain missing files") + _must_run_download_input_data = True # -- Each line is written twice in the original perl code: landuse_line = f"{landuse_input_fname:<196}{str(year)}\n" @@ -547,11 +553,13 @@ def main (): if '%y' in mksrf_fhrvtyp: mksrf_fhrvtyp = mksrf_fhrvtyp.replace("%y",str(start_year)) if not os.path.isfile(mksrf_fvegtyp): - print(f"ERROR: input mksrf_fvegtyp file {mksrf_fvegtyp} does not exist") - sys.exit(20) + print(f"WARNING: input mksrf_fvegtyp file {mksrf_fvegtyp} does not exist") + print(f"WARNING: run ./download_input_data to try to obtain missing files") + _must_run_download_input_data = True if not os.path.isfile(mksrf_fhrvtyp): - print(f"ERROR: input mksrf_fhrvtyp file {mksrf_fhrvtyp} does not exist") - sys.exit(20) + print(f"WARNING: input mksrf_fhrvtyp file {mksrf_fhrvtyp} does not exist") + print(f"WARNING: run ./download_input_data to try to obtain missing files") + _must_run_download_input_data = True nlfile.write( f" mksrf_fvegtyp = \'{mksrf_fvegtyp}\' \n") nlfile.write( f" mksrf_fvegtyp_mesh = \'{mksrf_fvegtyp_mesh}\' \n") nlfile.write( f" mksrf_fhrvtyp = \'{mksrf_fhrvtyp}\' \n") @@ -590,6 +598,11 @@ def main (): nlfile.write("/ \n") + if _must_run_download_input_data: + temp_nlfname = 'surfdata.namelist' + os.rename(nlfname, temp_nlfname) + nlfname = temp_nlfname + print (f"Successfully created input namelist file {nlfname}") sys.exit(0) From 128bef9f645ccee8dd5f80675ffbe0066be69cbc Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 19 May 2022 13:46:48 -0600 Subject: [PATCH 192/614] Remove "_" and "self._" from local variables --- cime_config/SystemTests/mksurfdataesmf.py | 36 +++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index e9436e51f5..6846326a60 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -29,12 +29,12 @@ def __init__(self, case): SystemTestsCommon.__init__(self, case) # Paths and strings needed throughout - self._ctsm_root = self._case.get_value('COMP_ROOT_DIR_LND') - self._tool_path = os.path.join(self._ctsm_root, 'tools/mksurfdata_esmf') - _time_stamp = datetime.today().strftime("%y%m%d") + ctsm_root = self._case.get_value('COMP_ROOT_DIR_LND') + self._tool_path = os.path.join(ctsm_root, 'tools/mksurfdata_esmf') + time_stamp = datetime.today().strftime("%y%m%d") self._res = '10x15' # see important comment in script's docstring self._model_yr = '1850' - self._fsurdat_out_prefix = os.path.join(self._get_caseroot(), f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{_time_stamp}.') + self._fsurdat_out_prefix = os.path.join(self._get_caseroot(), f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.') def build_phase(self, sharedlib_only=False, model_only=False): """ @@ -47,19 +47,19 @@ def build_phase(self, sharedlib_only=False, model_only=False): if not os.path.exists(os.path.join(self._get_caseroot(), 'done_MKSURFDATAESMF_setup.txt')): # Paths and strings - self._rm_bld_dir = f"rm -rf {self._tool_path}/bld" - self._build_script_path = os.path.join(self._tool_path, + rm_bld_dir = f"rm -rf {self._tool_path}/bld" + build_script_path = os.path.join(self._tool_path, 'gen_mksurfdata_build.sh') - self._nml_script_path = os.path.join(self._tool_path, + nml_script_path = os.path.join(self._tool_path, 'gen_mksurfdata_namelist.py') - self._gen_mksurfdata_namelist = f'{self._nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}' + gen_mksurfdata_namelist = f'{nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}' # Build executable - subprocess.check_call(self._rm_bld_dir, shell=True) - subprocess.check_call(self._build_script_path, shell=True) + subprocess.check_call(rm_bld_dir, shell=True) + subprocess.check_call(build_script_path, shell=True) # Generate namelist for generating fsurdat - subprocess.check_call(self._gen_mksurfdata_namelist, shell=True) + subprocess.check_call(gen_mksurfdata_namelist, shell=True) # Modify user_nl_clm to point to the generated fsurdat self._modify_user_nl() @@ -74,15 +74,15 @@ def run_phase(self): Submit CTSM run that uses fsurdat just generated """ # Paths and command strings - self._executable_path = os.path.join(self._tool_path, 'bld/mksurfdata') - _machine = self._case.get_value("MACH") - if _machine == 'cheyenne': - self._mpiexec_mpt_cmd = f"mpiexec_mpt -np 144 {self._executable_path} < {self._fsurdat_out_prefix}namelist" - elif _machine == 'casper': - self._mpiexec_mpt_cmd = f"mpiexec -np 144 {self._executable_path} < {self._fsurdat_out_prefix}namelist" + executable_path = os.path.join(self._tool_path, 'bld/mksurfdata') + machine = self._case.get_value("MACH") + if machine == 'cheyenne': + mpiexec_mpt_cmd = f"mpiexec_mpt -np 144 {executable_path} < {self._fsurdat_out_prefix}namelist" + elif machine == 'casper': + mpiexec_mpt_cmd = f"mpiexec -np 144 {executable_path} < {self._fsurdat_out_prefix}namelist" # Run executable to generate fsurdat - subprocess.check_call(self._mpiexec_mpt_cmd, shell=True) + subprocess.check_call(mpiexec_mpt_cmd, shell=True) # Submit CTSM run that uses fsurdat just generated self.run_indv() From 182458cf4cda6147ddd8e8e971ac6979120c1381 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 19 May 2022 14:28:51 -0600 Subject: [PATCH 193/614] Remove /tools/mksurfdata_esmf/bld directory when done using it --- cime_config/SystemTests/mksurfdataesmf.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 6846326a60..be89ed9d44 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -31,6 +31,7 @@ def __init__(self, case): # Paths and strings needed throughout ctsm_root = self._case.get_value('COMP_ROOT_DIR_LND') self._tool_path = os.path.join(ctsm_root, 'tools/mksurfdata_esmf') + self._rm_bld_dir = f"rm -rf {self._tool_path}/bld" time_stamp = datetime.today().strftime("%y%m%d") self._res = '10x15' # see important comment in script's docstring self._model_yr = '1850' @@ -47,7 +48,6 @@ def build_phase(self, sharedlib_only=False, model_only=False): if not os.path.exists(os.path.join(self._get_caseroot(), 'done_MKSURFDATAESMF_setup.txt')): # Paths and strings - rm_bld_dir = f"rm -rf {self._tool_path}/bld" build_script_path = os.path.join(self._tool_path, 'gen_mksurfdata_build.sh') nml_script_path = os.path.join(self._tool_path, @@ -55,7 +55,7 @@ def build_phase(self, sharedlib_only=False, model_only=False): gen_mksurfdata_namelist = f'{nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}' # Build executable - subprocess.check_call(rm_bld_dir, shell=True) + subprocess.check_call(self._rm_bld_dir, shell=True) subprocess.check_call(build_script_path, shell=True) # Generate namelist for generating fsurdat @@ -83,6 +83,7 @@ def run_phase(self): # Run executable to generate fsurdat subprocess.check_call(mpiexec_mpt_cmd, shell=True) + subprocess.check_call(self._rm_bld_dir, shell=True) # Submit CTSM run that uses fsurdat just generated self.run_indv() From 0134b4e272b228b698a59746369a57eb7032fc32 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 19 May 2022 16:57:22 -0600 Subject: [PATCH 194/614] Improved error messages from subprocess.check_call commands --- cime_config/SystemTests/mksurfdataesmf.py | 28 +++++++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index be89ed9d44..8f8076d274 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -12,6 +12,7 @@ """ import os +import sys import subprocess from datetime import datetime from CIME.SystemTests.system_tests_common import SystemTestsCommon @@ -36,6 +37,8 @@ def __init__(self, case): self._res = '10x15' # see important comment in script's docstring self._model_yr = '1850' self._fsurdat_out_prefix = os.path.join(self._get_caseroot(), f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.') + self._TestStatus_log_path = os.path.join(self._get_caseroot(), + 'TestStatus.log') def build_phase(self, sharedlib_only=False, model_only=False): """ @@ -55,11 +58,20 @@ def build_phase(self, sharedlib_only=False, model_only=False): gen_mksurfdata_namelist = f'{nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}' # Build executable - subprocess.check_call(self._rm_bld_dir, shell=True) - subprocess.check_call(build_script_path, shell=True) + try: + subprocess.check_call(self._rm_bld_dir, shell=True) + except subprocess.CalledProcessError as e: + sys.exit(f'{e} ERROR RUNNING {self._rm_bld_dir}. DETAILS IN {self._TestStatus_log_path}') + try: + subprocess.check_call(build_script_path, shell=True) + except subprocess.CalledProcessError as e: + sys.exit(f'{e} ERROR RUNNING {build_script_path}. DETAILS IN {self._TestStatus_log_path}') # Generate namelist for generating fsurdat - subprocess.check_call(gen_mksurfdata_namelist, shell=True) + try: + subprocess.check_call(gen_mksurfdata_namelist, shell=True) + except subprocess.CalledProcessError as e: + sys.exit(f'{e} ERROR RUNNING {gen_mksurfdata_namelist}. DETAILS IN {self._TestStatus_log_path}') # Modify user_nl_clm to point to the generated fsurdat self._modify_user_nl() @@ -82,8 +94,14 @@ def run_phase(self): mpiexec_mpt_cmd = f"mpiexec -np 144 {executable_path} < {self._fsurdat_out_prefix}namelist" # Run executable to generate fsurdat - subprocess.check_call(mpiexec_mpt_cmd, shell=True) - subprocess.check_call(self._rm_bld_dir, shell=True) + try: + subprocess.check_call(mpiexec_mpt_cmd, shell=True) + except subprocess.CalledProcessError as e: + sys.exit(f'{e} ERROR RUNNING {mpiexec_mpt_cmd}; details in {self._TestStatus_log_path}') + try: + subprocess.check_call(self._rm_bld_dir, shell=True) + except subprocess.CalledProcessError as e: + sys.exit(f'{e} ERROR RUNNING {self._rm_bld_dir}; details in {self._TestStatus_log_path}') # Submit CTSM run that uses fsurdat just generated self.run_indv() From 7a4a6779c661af5a00626b6608e20a8cae8ebfb5 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 19 May 2022 17:13:55 -0600 Subject: [PATCH 195/614] Changed request mem=20GB to 80GB when running mksurfdata_esmf on casper --- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index 8cc1e66e4a..40794499f1 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -99,7 +99,7 @@ def main (): runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") elif machine == 'casper': runfile.write('#PBS -q casper \n') - runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=12:mpiprocs={tasks_per_node}:mem=20GB \n") + runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=12:mpiprocs={tasks_per_node}:mem=80GB \n") runfile.write("\n") np = int(tasks_per_node) * int(number_of_nodes) From a5a1d667d53a76f4f68a5a47ef0a96ae7b459d29 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 20 May 2022 10:01:50 -0600 Subject: [PATCH 196/614] Keep mksurfdata /bld after it's no longer needed (reverts https://github.com/ESCOMP/CTSM/pull/1756/commits/182458cf4cda6147ddd8e8e971ac6979120c1381) --- cime_config/SystemTests/mksurfdataesmf.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 8f8076d274..63b9546cda 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -32,7 +32,6 @@ def __init__(self, case): # Paths and strings needed throughout ctsm_root = self._case.get_value('COMP_ROOT_DIR_LND') self._tool_path = os.path.join(ctsm_root, 'tools/mksurfdata_esmf') - self._rm_bld_dir = f"rm -rf {self._tool_path}/bld" time_stamp = datetime.today().strftime("%y%m%d") self._res = '10x15' # see important comment in script's docstring self._model_yr = '1850' @@ -51,6 +50,7 @@ def build_phase(self, sharedlib_only=False, model_only=False): if not os.path.exists(os.path.join(self._get_caseroot(), 'done_MKSURFDATAESMF_setup.txt')): # Paths and strings + rm_bld_dir = f"rm -rf {self._tool_path}/bld" build_script_path = os.path.join(self._tool_path, 'gen_mksurfdata_build.sh') nml_script_path = os.path.join(self._tool_path, @@ -59,9 +59,9 @@ def build_phase(self, sharedlib_only=False, model_only=False): # Build executable try: - subprocess.check_call(self._rm_bld_dir, shell=True) + subprocess.check_call(rm_bld_dir, shell=True) except subprocess.CalledProcessError as e: - sys.exit(f'{e} ERROR RUNNING {self._rm_bld_dir}. DETAILS IN {self._TestStatus_log_path}') + sys.exit(f'{e} ERROR RUNNING {rm_bld_dir}. DETAILS IN {self._TestStatus_log_path}') try: subprocess.check_call(build_script_path, shell=True) except subprocess.CalledProcessError as e: @@ -98,10 +98,6 @@ def run_phase(self): subprocess.check_call(mpiexec_mpt_cmd, shell=True) except subprocess.CalledProcessError as e: sys.exit(f'{e} ERROR RUNNING {mpiexec_mpt_cmd}; details in {self._TestStatus_log_path}') - try: - subprocess.check_call(self._rm_bld_dir, shell=True) - except subprocess.CalledProcessError as e: - sys.exit(f'{e} ERROR RUNNING {self._rm_bld_dir}; details in {self._TestStatus_log_path}') # Submit CTSM run that uses fsurdat just generated self.run_indv() From 87e9e99a7a4ba889e7501fba83a059b740367363 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 20 May 2022 13:13:55 -0600 Subject: [PATCH 197/614] Reduced if "done_file" to cover modify_user_nl; added new if to the rest Also renamed a variable --- cime_config/SystemTests/mksurfdataesmf.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 63b9546cda..e1ec5fc4f5 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -46,9 +46,12 @@ def build_phase(self, sharedlib_only=False, model_only=False): SKIP Generate jobscript that runs executable Modify user_nl_clm to point to the generated fsurdat """ - # These steps need only happen once - if not os.path.exists(os.path.join(self._get_caseroot(), - 'done_MKSURFDATAESMF_setup.txt')): + # build_phase gets called twice: + # - once with sharedlib_only = True and + # - once with model_only = True + # Call the following steps only once during the test but do not skip + # if the test stops and gets restarted. + if sharedlib_only == True: # Paths and strings rm_bld_dir = f"rm -rf {self._tool_path}/bld" build_script_path = os.path.join(self._tool_path, @@ -73,6 +76,9 @@ def build_phase(self, sharedlib_only=False, model_only=False): except subprocess.CalledProcessError as e: sys.exit(f'{e} ERROR RUNNING {gen_mksurfdata_namelist}. DETAILS IN {self._TestStatus_log_path}') + # Call this step only once even if the test stops and gets restarted. + if not os.path.exists(os.path.join(self._get_caseroot(), + 'done_MKSURFDATAESMF_setup.txt')): # Modify user_nl_clm to point to the generated fsurdat self._modify_user_nl() with open('done_MKSURFDATAESMF_setup.txt', 'w') as fp: @@ -89,15 +95,15 @@ def run_phase(self): executable_path = os.path.join(self._tool_path, 'bld/mksurfdata') machine = self._case.get_value("MACH") if machine == 'cheyenne': - mpiexec_mpt_cmd = f"mpiexec_mpt -np 144 {executable_path} < {self._fsurdat_out_prefix}namelist" + mpi_cmd = f"mpiexec_mpt -np 144 {executable_path} < {self._fsurdat_out_prefix}namelist" elif machine == 'casper': - mpiexec_mpt_cmd = f"mpiexec -np 144 {executable_path} < {self._fsurdat_out_prefix}namelist" + mpi_cmd = f"mpiexec -np 144 {executable_path} < {self._fsurdat_out_prefix}namelist" # Run executable to generate fsurdat try: - subprocess.check_call(mpiexec_mpt_cmd, shell=True) + subprocess.check_call(mpi_cmd, shell=True) except subprocess.CalledProcessError as e: - sys.exit(f'{e} ERROR RUNNING {mpiexec_mpt_cmd}; details in {self._TestStatus_log_path}') + sys.exit(f'{e} ERROR RUNNING {mpi_cmd}; details in {self._TestStatus_log_path}') # Submit CTSM run that uses fsurdat just generated self.run_indv() From c624a736324dfec6fb7ad120283ddb5a7f5610df Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 20 May 2022 15:36:38 -0600 Subject: [PATCH 198/614] Rm preexisting .namelist & .nc files before creating them - Replaced self._fsurdat_out_prefix with self._fsurdat_namelist and self._fsurdat_nc - Replaced subprocess.check_call(rm_bld_dir, shell=True) with shutil.rmtree(os.path.join(bld_dir)) --- cime_config/SystemTests/mksurfdataesmf.py | 28 ++++++++++++++--------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index e1ec5fc4f5..e00aa0fd10 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -13,6 +13,7 @@ import os import sys +import shutil import subprocess from datetime import datetime from CIME.SystemTests.system_tests_common import SystemTestsCommon @@ -35,7 +36,8 @@ def __init__(self, case): time_stamp = datetime.today().strftime("%y%m%d") self._res = '10x15' # see important comment in script's docstring self._model_yr = '1850' - self._fsurdat_out_prefix = os.path.join(self._get_caseroot(), f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.') + self._fsurdat_namelist = os.path.join(self._get_caseroot(), f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.namelist') + self._fsurdat_nc = os.path.join(self._get_caseroot(), f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.nc') self._TestStatus_log_path = os.path.join(self._get_caseroot(), 'TestStatus.log') @@ -53,24 +55,26 @@ def build_phase(self, sharedlib_only=False, model_only=False): # if the test stops and gets restarted. if sharedlib_only == True: # Paths and strings - rm_bld_dir = f"rm -rf {self._tool_path}/bld" + bld_dir = os.path.join(self._tool_path, 'bld') build_script_path = os.path.join(self._tool_path, 'gen_mksurfdata_build.sh') nml_script_path = os.path.join(self._tool_path, 'gen_mksurfdata_namelist.py') gen_mksurfdata_namelist = f'{nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}' - # Build executable + # Build executable that will generate fsurdat (first rm -rf /bld) try: - subprocess.check_call(rm_bld_dir, shell=True) - except subprocess.CalledProcessError as e: - sys.exit(f'{e} ERROR RUNNING {rm_bld_dir}. DETAILS IN {self._TestStatus_log_path}') + shutil.rmtree(os.path.join(bld_dir)) + except OSError as e: + sys.exit(f'{e} ERROR REMOVING {bld_dir}. DETAILS IN {self._TestStatus_log_path}') try: subprocess.check_call(build_script_path, shell=True) except subprocess.CalledProcessError as e: sys.exit(f'{e} ERROR RUNNING {build_script_path}. DETAILS IN {self._TestStatus_log_path}') - # Generate namelist for generating fsurdat + # Generate namelist for generating fsurdat (rm namelist if exists) + if os.path.exists(self._fsurdat_namelist): + os.remove(self._fsurdat_namelist) try: subprocess.check_call(gen_mksurfdata_namelist, shell=True) except subprocess.CalledProcessError as e: @@ -95,11 +99,13 @@ def run_phase(self): executable_path = os.path.join(self._tool_path, 'bld/mksurfdata') machine = self._case.get_value("MACH") if machine == 'cheyenne': - mpi_cmd = f"mpiexec_mpt -np 144 {executable_path} < {self._fsurdat_out_prefix}namelist" + mpi_cmd = f'mpiexec_mpt -np 144 {executable_path} < {self._fsurdat_namelist}' elif machine == 'casper': - mpi_cmd = f"mpiexec -np 144 {executable_path} < {self._fsurdat_out_prefix}namelist" + mpi_cmd = f'mpiexec -np 144 {executable_path} < {self._fsurdat_namelist}' - # Run executable to generate fsurdat + # Run executable to generate fsurdat (rm fsurdat if exists) + if os.path.exists(self._fsurdat_nc): + os.remove(self._fsurdat_nc) try: subprocess.check_call(mpi_cmd, shell=True) except subprocess.CalledProcessError as e: @@ -114,4 +120,4 @@ def _modify_user_nl(self): """ append_to_user_nl_files(caseroot = self._get_caseroot(), component = "clm", - contents = "fsurdat = '{}nc'".format(self._fsurdat_out_prefix)) + contents = "fsurdat = '{}'".format(self._fsurdat_nc)) From c1bde16db7499a5b69365e971e19cc525613df3c Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 20 May 2022 19:42:50 -0600 Subject: [PATCH 199/614] Clean-up in code & README; the code runs but ORGANIC is wrong I followed the sand/clay template for organic and values look reasonable when written to stdout, but values are wrong in the .nc file. I have no explanation at this time. --- tools/mksurfdata_esmf/README | 35 ++++++++++--------- .../gen_mksurfdata_namelist.xml | 9 +---- tools/mksurfdata_esmf/src/CMakeLists.txt | 1 - tools/mksurfdata_esmf/src/mkfileMod.F90 | 4 --- tools/mksurfdata_esmf/src/mkinputMod.F90 | 13 +------ tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 12 +++---- 6 files changed, 27 insertions(+), 47 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index f2d61e2539..b0f8c9a8cf 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -2,9 +2,10 @@ Build Requirements: =================== -mksurfdata_esmf is an distributed memory parallel program (using Message Passing Interface -- MPI) that utilizes -both ESMF (Earth System Modelling Framework) for regridding as well as PIO (Parallel I/O) and NetCDF output. As -such libraries must be built for the following: +mksurfdata_esmf is a distributed memory parallel program (using Message Passing +Interface -- MPI) that utilizes both ESMF (Earth System Modelling Framework) +for regridding as well as PIO (Parallel I/O) and NetCDF output. As +such, libraries must be built for the following: 1) MPI 2) NetCDF @@ -13,22 +14,22 @@ such libraries must be built for the following: In addition for the build: python, bash-shell, CMake and GNU-Make are required -These libraries need to be built such that they can all work together in the same executable. Hence, the above -order may be required in building them. +These libraries need to be built such that they can all work together in the +same executable. Hence, the above order may be required in building them. ========================================= Use cime to manage the build requirements ========================================= -For users working on cime machines you can use the build -script to build the tool for you. On other machines you'll need to do a port to cime -and tell how to build for that machine. That's talked about in the cime documentation. +For users working on cime machines you can use the build script to build the +tool. On other machines you'll need to do a port to cime and tell how to build +for that machine. That's talked about in the cime documentation. And you'll have to make some modifications to the build script. https://github.com/ESMCI/cime/wiki/Porting-Overview -Machines that already run CTSM or CESM have been ported to cime. So if you can run the model -on your machine you will be able to build the tool there. +Machines that already run CTSM or CESM have been ported to cime. So if you can +run the model on your machine, you will be able to build the tool there. To get a list of the machines that have been ported to cime: @@ -36,19 +37,20 @@ cd ../../cime/scripts ./query_config --machines NOTE: -In addition to having a port to cime, the machine also needs to have PIO built and able -to be referenced with the env variable PIO which will need to be in the porting instructions -for the machine. Currently an independent PIO library is not available on cime ported machines. +In addition to having a port to cime, the machine also needs to have PIO built +and able to be referenced with the env variable PIO which will need to be in +the porting instructions for the machine. Currently an independent PIO library +is not available on cime ported machines. ======================= -building the executable +Building the executable ======================= > cd tools/mksurfdata_esmf > ./gen_mksurfdata_build.sh # For machines with a cime build ======================= -running for a single submission: +Running for a single submission: ======================= > cd ../ # to generate your target namelist: @@ -60,7 +62,7 @@ running for a single submission: > qsub mksurfdata_jobscript_single ======================= -running for the generation of multiple datasets +Running for the generation of multiple datasets ======================= # Note that gen_mksurfdata_jobscript_multi.py runs ./gen_mksurfdata_namelist.py > ./gen_mksurfdata_jobscript_multi.py --help @@ -76,6 +78,7 @@ slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED ------------------------------------------------------------ REMEMBER TO compare against existing fsurdat files in /glade/p/cesmdata/cseg/inputdata/lnd/clm2/surfdata_map/release-clm5.0.18 +0) New 30-sec raw data for soil texture fails. Try requesting more mem. 1) Soil color & texture and ag fire peak month outputs too high in .log TODO? Change frac_o from always 1. 2) Pct lake has chged in the .log bc the old diagnostic omitted mask_i frac_o diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index c9fdc57aef..554812a9c6 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -20,16 +20,9 @@ - + - - - lnd/clm2/rawdata/mksrf_organic_10level_5x5min_ISRIC-WISE-NCSCD_nlev7_c120830.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc - - - diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 8720f3188a..7d845d27bf 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -19,7 +19,6 @@ set(SRCFILES mkagfirepkmonthMod.F90 mkinputMod.F90 mklaiMod.F90 mklanwatMod.F90 - mkorganicMod.F90 mkpeatMod.F90 mkpioMod.F90 mkpftMod.F90 diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 0eb25c2e7d..1c9c46ab5d 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -179,8 +179,6 @@ subroutine mkfile_define_atts(pioid, dynlanduse) rcode = pio_put_att(pioid, pio_global, 'mesh_soil_texture_file', trim(str)) str = get_filename(mksrf_fsoicol_mesh) rcode = pio_put_att(pioid, pio_global, 'mesh_soil_color_file', trim(str)) - str = get_filename(mksrf_forganic_mesh) - rcode = pio_put_att(pioid, pio_global, 'mesh_soil_organic_file', trim(str)) str = get_filename(mksrf_furban_mesh) rcode = pio_put_att(pioid, pio_global, 'mesh_urban_file', trim(str)) str = get_filename(mksrf_fmax_mesh) @@ -221,8 +219,6 @@ subroutine mkfile_define_atts(pioid, dynlanduse) rcode = pio_put_att(pioid, pio_global, 'soil_texture_lookup_raw_data_file_name', trim(str)) str = get_filename(mksrf_fmax) rcode = pio_put_att(pioid, pio_global, 'fmax_raw_data_file_name', trim(str)) - str = get_filename(mksrf_forganic) - rcode = pio_put_att(pioid, pio_global, 'organic_matter_raw_data_file_name', trim(str)) str = get_filename(mksrf_fvocef) rcode = pio_put_att(pioid, pio_global, 'VOC_EF_raw_data_file_name', trim(str)) end if diff --git a/tools/mksurfdata_esmf/src/mkinputMod.F90 b/tools/mksurfdata_esmf/src/mkinputMod.F90 index b35596a026..6133ac09e9 100644 --- a/tools/mksurfdata_esmf/src/mkinputMod.F90 +++ b/tools/mksurfdata_esmf/src/mkinputMod.F90 @@ -44,9 +44,6 @@ module mkinputMod character(CX) , public :: mksrf_fhrvtyp = ' ' ! harvest data file name character(CX) , public :: mksrf_fhrvtyp_mesh = ' ' ! harvest mesh file name - character(CX) , public :: mksrf_forganic = ' ' ! organic matter data file name - character(CX) , public :: mksrf_forganic_mesh = ' ' ! organic matter mesh file name - character(CX) , public :: mksrf_fsoicol = ' ' ! soil color data file name character(CX) , public :: mksrf_fsoicol_mesh = ' ' ! soil color mesh file name @@ -139,8 +136,6 @@ subroutine read_namelist_input() mksrf_fsoitex, & mksrf_fsoitex_lookup, & mksrf_fsoitex_mesh, & - mksrf_forganic, & - mksrf_forganic_mesh, & mksrf_fsoicol, & mksrf_fsoicol_mesh, & mksrf_fvocef, & @@ -232,9 +227,6 @@ subroutine read_namelist_input() call mpi_bcast (mksrf_fmax, len(mksrf_fmax), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fmax_mesh, len(mksrf_fmax_mesh), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_forganic, len(mksrf_forganic), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_forganic_mesh, len(mksrf_forganic_mesh), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_fsoicol, len(mksrf_fsoicol), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fsoicol_mesh, len(mksrf_fsoicol_mesh), MPI_CHARACTER, 0, mpicom, ier) @@ -351,12 +343,9 @@ subroutine write_namelist_input() write(ndiag,'(a)')' mesh for wetland '//trim(mksrf_fwetlnd_mesh) write(ndiag,*) write(ndiag,'(a)')' soil texture mapunits from: '//trim(mksrf_fsoitex) - write(ndiag,'(a)')' soil texture lookup from: '//trim(mksrf_fsoitex_lookup) + write(ndiag,'(a)')' soil texture (sand/clay, orgc) lookup: '//trim(mksrf_fsoitex_lookup) write(ndiag,'(a)')' mesh for soil texture '//trim(mksrf_fsoitex_mesh) write(ndiag,*) - write(ndiag,'(a)')' soil organic from: '//trim(mksrf_forganic) - write(ndiag,'(a)')' mesh for soil organic '//trim(mksrf_forganic_mesh) - write(ndiag,*) write(ndiag,'(a)')' soil color from: '//trim(mksrf_fsoicol) write(ndiag,'(a)')' mesh for soil color '//trim(mksrf_fsoicol_mesh) write(ndiag,*) diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 7518452810..e4ec6cd025 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -297,7 +297,7 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o end if do l = 2,nlay sand_o(no,l) = float(sand_i(l,1,lookup_index)) - if (sand_o(no,l) < 0. .and. l > 1) then + if (sand_o(no,l) < 0.) then sand_o(no,l) = sand_o(no,l-1) end if end do @@ -327,7 +327,7 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o end if do l = 2,nlay clay_o(no,l) = float(clay_i(l,1,lookup_index)) - if (clay_o(no,l) < 0. .and. l > 1) then + if (clay_o(no,l) < 0.) then clay_o(no,l) = clay_o(no,l-1) end if end do @@ -346,8 +346,8 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o end if if (orgc_o(no,1) < 0.) then if (int(orgc_o(no,1)) == -4) then - write(6,'(a,i8)')'WARNING: changing orgc_o from -4 to 0 at no = ',no - orgc_o(no,:) = 0._r4 + write(6,'(a,i8)')'WARNING: changing orgc_o from -4 to 1 at no = ',no + orgc_o(no,:) = 1._r4 else write(6,'(a,i8,a,i8)')'WARNING: changing orgc_o from ',int(orgc_o(no,1)),' to 18 at no = ',no orgc_o(no,:) = 18._r4 ! TODO slevis: Value for loam here? @@ -355,11 +355,11 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o end if if (orgc_o(no,1) < 0.) then write(6,*)'ERROR: at no, lookup_index = ',no,lookup_index - call shr_sys_abort('could not find a value >= 0 for orgc_i') + call shr_sys_abort('could not find a value >= 0 for orgc_i') end if do l = 2,nlay orgc_o(no,l) = float(orgc_i(l,1,lookup_index)) - if (orgc_o(no,l) < 0. .and. l > 1) then + if (orgc_o(no,l) < 0.) then orgc_o(no,l) = orgc_o(no,l-1) end if end do From dca62af1ab804231c6bd8963a1c15738edfd93d0 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 23 May 2022 15:56:03 -0600 Subject: [PATCH 200/614] Changes to gen_mksurfdata_build.sh (in progress) --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index 3e79e34519..6e585b44e4 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -1,5 +1,8 @@ #! /bin/bash -f +# usage subroutine + + hostname=`hostname --short` # Define what machine to use that's been ported to cime @@ -18,26 +21,32 @@ case $hostname in ;; esac +cwd=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +builddir=$cwd/bld + +# command line code +# -b to overwrite builddir +# -m to overwrite MACH + # Create /bld directory echo "cime Machine is: $MACH..." -cwd=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -if [ -d "$cwd/bld" ]; then +if [ -d "$builddir" ]; then echo "A /bld directory exists; remove it to do a clean build..." exit 1 fi -rm -rf $cwd/bld -mkdir $cwd/bld -cd $cwd/bld +rm -rf $builddir +mkdir $builddir +cd $builddir # Run the cime configure tool to figure out what modules need to be loaded echo "Run cime configure for machine $MACH..." # You can specify the non-default compiler and mpi-library by adding --compiler and --mpilib settings if [ -z "$COMPILER" ] || [ -z "$MPILIB" ]; then echo "configure for the default MPI-library and compiler..." - ../../../cime/tools/configure --macros-format CMake --machine $MACH + $cwd/../../cime/tools/configure --macros-format CMake --machine $MACH else echo "configure for the specific MPILIB=$MPILIB and COMPILER=$COMPILER..." - ../../../cime/tools/configure --macros-format CMake --machine $MACH --compiler $COMPILER --mpilib $MPILIB + $cwd/../../cime/tools/configure --macros-format CMake --machine $MACH --compiler $COMPILER --mpilib $MPILIB fi if [ $? != 0 ]; then @@ -54,7 +63,7 @@ fi # Build the cmake files echo "Do the cmake build..." -CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug ../src +CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug $cwd/src if [ $? != 0 ]; then echo "Error doing cmake for $MACH $MPILIB $COMPILER" exit 1 From 6c8ef8b490f6c39b46e776424fbfdd49fe226b7a Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 23 May 2022 16:33:21 -0600 Subject: [PATCH 201/614] Define .nc variable ORGANIC as float instead of double --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 1c9c46ab5d..eeda6794bc 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -270,7 +270,7 @@ subroutine mkfile_define_vars(pioid, dynlanduse) call mkpio_def_spatial_var(pioid=pioid, varname='mapunits', xtype=PIO_INT, & long_name='soil texture map units', units='unitless') - call mkpio_def_spatial_var(pioid=pioid, varname='ORGANIC', xtype=xtype, & + call mkpio_def_spatial_var(pioid=pioid, varname='ORGANIC', xtype=PIO_REAL, & lev1name='nlevsoi', & long_name='organic matter density at soil levels', & units='kg/m3 (assumed carbon content 0.58 gC per gOM)') From 4e8caf8f20a66fb2bd15bcdcadcd900fefde5929 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 24 May 2022 10:00:39 -0600 Subject: [PATCH 202/614] Now we may place the /bld of mksurfdata_esmf anywhere Now the new mksurfdata_esmf system test doesn't create /bld in users' .../tools/mksurfdata_esmf and instead places this build directory where the test case builds and runs. This avoids potential confusion from a test manipulating files in users' ctsm directories. --- cime_config/SystemTests/mksurfdataesmf.py | 14 ++-- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 68 +++++++++++++++---- 2 files changed, 63 insertions(+), 19 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index e00aa0fd10..06478facb9 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -33,6 +33,7 @@ def __init__(self, case): # Paths and strings needed throughout ctsm_root = self._case.get_value('COMP_ROOT_DIR_LND') self._tool_path = os.path.join(ctsm_root, 'tools/mksurfdata_esmf') + self._tool_bld = os.path.join(self._get_caseroot(), 'tool_bld') time_stamp = datetime.today().strftime("%y%m%d") self._res = '10x15' # see important comment in script's docstring self._model_yr = '1850' @@ -55,20 +56,19 @@ def build_phase(self, sharedlib_only=False, model_only=False): # if the test stops and gets restarted. if sharedlib_only == True: # Paths and strings - bld_dir = os.path.join(self._tool_path, 'bld') build_script_path = os.path.join(self._tool_path, 'gen_mksurfdata_build.sh') nml_script_path = os.path.join(self._tool_path, 'gen_mksurfdata_namelist.py') gen_mksurfdata_namelist = f'{nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}' - # Build executable that will generate fsurdat (first rm -rf /bld) + # Rm tool_bld and build executable that will generate fsurdat try: - shutil.rmtree(os.path.join(bld_dir)) - except OSError as e: - sys.exit(f'{e} ERROR REMOVING {bld_dir}. DETAILS IN {self._TestStatus_log_path}') + subprocess.check_call(f'rm -rf {self._tool_bld}', shell=True) + except subprocess.CalledProcessError as e: + sys.exit(f'{e} ERROR REMOVING {self._tool_bld}. DETAILS IN {self._TestStatus_log_path}') try: - subprocess.check_call(build_script_path, shell=True) + subprocess.check_call(f'{build_script_path} --blddir {self._tool_bld}', shell=True) except subprocess.CalledProcessError as e: sys.exit(f'{e} ERROR RUNNING {build_script_path}. DETAILS IN {self._TestStatus_log_path}') @@ -96,7 +96,7 @@ def run_phase(self): Submit CTSM run that uses fsurdat just generated """ # Paths and command strings - executable_path = os.path.join(self._tool_path, 'bld/mksurfdata') + executable_path = os.path.join(self._tool_bld, 'mksurfdata') machine = self._case.get_value("MACH") if machine == 'cheyenne': mpi_cmd = f'mpiexec_mpt -np 144 {executable_path} < {self._fsurdat_namelist}' diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index 6e585b44e4..149face85f 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -1,11 +1,36 @@ #! /bin/bash -f -# usage subroutine +#---------------------------------------------------------------------- +# Usage subroutine +usage() { + echo "" + echo "***********************************************************************" + echo "usage:" + echo "./gen_mksurfdata_build.sh" + echo "" + echo "valid arguments: " + echo "[-h|--help] " + echo " Displays this help message" + echo "[-v|--verbose] " + echo " Run in verbose mode" + echo "[-b|--blddir ] " + echo " Overwrites default, which is /bld in the same directory as ./gen_mksurfdata_build.sh" + echo "[-m|--machine ] " + echo " Overwrites default MACH" + echo "***********************************************************************" +} -hostname=`hostname --short` +# Current working directory: the location of ./gen_mksurfdata_build.sh +cwd=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +# Default settings +verbose="No" +blddir=$cwd/bld # may overwrite this default with command-line option (below) # Define what machine to use that's been ported to cime +# May overwrite this default with command-line option --machine +hostname=`hostname --short` case $hostname in ##cheyenne cheyenne* | r* ) @@ -21,22 +46,41 @@ case $hostname in ;; esac -cwd=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -builddir=$cwd/bld - -# command line code -# -b to overwrite builddir -# -m to overwrite MACH +# Parse command-line options +while [ $# -gt 0 ]; do + case $1 in + -h|--help ) + usage + exit 0 + ;; + -v|--verbose ) + verbose="Yes" + ;; + -b|--blddir ) + blddir=$2 + shift + ;; + -m|--machine ) + MACH=$2 + shift + ;; + * ) + echo "ERROR:: invalid argument sent in: $2" + usage + exit 1 + ;; + esac + shift +done # Create /bld directory echo "cime Machine is: $MACH..." -if [ -d "$builddir" ]; then +if [ -d "$blddir" ]; then echo "A /bld directory exists; remove it to do a clean build..." exit 1 fi -rm -rf $builddir -mkdir $builddir -cd $builddir +mkdir $blddir +cd $blddir # Run the cime configure tool to figure out what modules need to be loaded echo "Run cime configure for machine $MACH..." From 8c8ac64d119d98c4d4164c3d1c1ab1b7fd66ddbf Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 24 May 2022 10:28:07 -0600 Subject: [PATCH 203/614] Enable gen_mksurfdata_namelist.py to also work on casper ...despite "git -C" option unavailable on casper --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index d2f0d4edf6..7eadb606b0 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -494,7 +494,13 @@ def main (): fdyndat = f"landuse.timeseries_{res}_{ssp_rcp_name}_{num_pft}_CMIP6_{start_year}-{end_year}_c{time_stamp}.nc" git_desc_cmd = f"git -C {tool_path} describe" - gitdescribe = subprocess.check_output(git_desc_cmd, shell=True).strip() + try: + # The "git -C" option permits a system test to run this tool from + # elsewhere while running the git command from the tool_path + gitdescribe = subprocess.check_output(git_desc_cmd, shell=True).strip() + except subprocess.CalledProcessError as e: + # In case the "git -C" option is unavailable, as on casper (2022/5/24) + gitdescribe = subprocess.check_output('git describe', shell=True).strip() gitdescribe = gitdescribe.decode('utf-8') # The below two overrides are only used for testing an validation From 8b720987b7165d4ada10d84cb66c4b15d49926c7 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 24 May 2022 14:07:55 -0600 Subject: [PATCH 204/614] pylint recommendations and other clean-up --- cime_config/SystemTests/mksurfdataesmf.py | 10 +- .../gen_mksurfdata_jobscript_multi.py | 56 ++--- .../gen_mksurfdata_jobscript_single.py | 24 ++- .../gen_mksurfdata_namelist.py | 196 ++++++++++-------- 4 files changed, 160 insertions(+), 126 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 06478facb9..47ecf9bde3 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -10,10 +10,8 @@ I added -C to the `git describe` in gen_mksurfdata_namelist.py for this system test to work. """ - import os import sys -import shutil import subprocess from datetime import datetime from CIME.SystemTests.system_tests_common import SystemTestsCommon @@ -37,8 +35,10 @@ def __init__(self, case): time_stamp = datetime.today().strftime("%y%m%d") self._res = '10x15' # see important comment in script's docstring self._model_yr = '1850' - self._fsurdat_namelist = os.path.join(self._get_caseroot(), f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.namelist') - self._fsurdat_nc = os.path.join(self._get_caseroot(), f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.nc') + self._fsurdat_namelist = os.path.join(self._get_caseroot(), + f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.namelist') + self._fsurdat_nc = os.path.join(self._get_caseroot(), + f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.nc') self._TestStatus_log_path = os.path.join(self._get_caseroot(), 'TestStatus.log') @@ -54,7 +54,7 @@ def build_phase(self, sharedlib_only=False, model_only=False): # - once with model_only = True # Call the following steps only once during the test but do not skip # if the test stops and gets restarted. - if sharedlib_only == True: + if sharedlib_only: # Paths and strings build_script_path = os.path.join(self._tool_path, 'gen_mksurfdata_build.sh') diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 7de280d453..286527e527 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -1,10 +1,13 @@ #!/usr/bin/env python3 - -import sys, os, shutil -import logging -import argparse, textwrap +""" +gen_mksurfdata_jobscript_multi.py generates a jobscript for running the +mksurfdata executable to generate many fsurdat files at once. For detailed +instructions, see README. +""" +import os +import sys +import argparse import subprocess -from datetime import datetime valid_scenarios=["all", "standard", @@ -85,7 +88,8 @@ def get_parser(): ) parser.add_argument( "--jobscript-file", - help="""output jobscript file to be submitted on cheyenne (default is mksurfdata_jobscript_multi)]""", + help="""output jobscript file to be submitted on cheyenne + [default: %(default)s]""", action="store", dest="jobscript_file", required=False, @@ -106,7 +110,7 @@ def main (): account = args.account # -------------------------- - # Determine target list + # Determine target list # -------------------------- target_list = [] if scenario == 'all': @@ -119,7 +123,7 @@ def main (): "crop-global-historical", "crop-global-transient", "crop-tropics-present", - "crop-global-SSP1-2.6", + "crop-global-SSP1-2.6", "crop-global-SSP3-7.0", "crop-global-SSP5-3.4", "crop-global-SSP2-4.5", @@ -138,7 +142,7 @@ def main (): "crop-global-historical", "crop-global-transient"] elif scenario == "crop-global-future": - target_list = ["crop-global-SSP1-2.6", + target_list = ["crop-global-SSP1-2.6", "crop-global-SSP3-7.0", "crop-global-SSP5-3.4", "crop-global-SSP2-4.5", @@ -157,11 +161,11 @@ def main (): resolution_dict = { "standard_res_no_crop" : ["0.9x1.25","1.9x2.5","10x15"], "standard_res" : ['0.9x1.25','1.9x2.5','10x15','4x5','C96', - 'ne30np4','ne30np4.pg2','ne30np4.pg3','ne30np4.pg4','ne120np4.pg3', - 'ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4','ne0np4CONUS.ne30x8'], + 'ne30np4','ne30np4.pg2','ne30np4.pg3','ne30np4.pg4','ne120np4.pg3', + 'ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4', 'ne0np4CONUS.ne30x8'], "future_res" : ["0.9x1.25","1.9x2.5","10x15"], - "trans_res" : ['0.9x1.25','1.9x2.5','10x15', - 'ne30np4','ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4','ne0np4CONUS.ne30x8','ne120np4'], + "trans_res" : ['0.9x1.25','1.9x2.5','10x15','ne30np4', + 'ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4','ne0np4CONUS.ne30x8','ne120np4'], "T42_res" : ['T42'], "nldas_res" : ['0.125nldas2'], "5x5_amazon_res" : ['5x5_amazon'], @@ -208,28 +212,30 @@ def main (): runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") runfile.write("\n") - np = int(tasks_per_node) * int(number_of_nodes) + n_p = int(tasks_per_node) * int(number_of_nodes) + # Run env_mach_specific.sh to control the machine dependent + # environment including the paths to compilers and libraries + # external to cime such as netcdf + runfile.write('. ./.env_mach_specific.sh \n') for target in target_list: res_set = dataset_dict[target][1] for res in resolution_dict[res_set]: - command = os.path.join(os.getcwd(), "gen_mksurfdata_namelist.py") + command = os.path.join(os.getcwd(), + "gen_mksurfdata_namelist.py") command = command + " " + dataset_dict[target][0] + " " + res print (f"command is {command}") commands = [x for x in command.split(' ') if x] - run_cmd = subprocess.run(commands, check=True, capture_output=True) - if run_cmd.returncode != 0: - print ("Error in calling gen_mksurfdata_namelist.py") - sys.exit(1) + try: + run_cmd = subprocess.run(commands, check=True, + capture_output=True) + except subprocess.CalledProcessError as e: + sys.exit(f'{e} ERROR calling {command}') output = run_cmd.stdout.decode('utf-8').strip() namelist = output.split(' ')[-1] print (f"generated namelist {namelist}") - # Run env_mach_specific.sh to control the machine dependent - # environment including the paths to compilers and libraries - # external to cime such as netcdf - output1 = f". ./.env_mach_specific.sh" - output2 = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist}" - runfile.write(f"{output1} \n{output2} \n") + output = f"mpiexec_mpt -p \"%g:\" -np {n_p} ./bld/mksurfdata < {namelist}" + runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") sys.exit(0) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index ef8662b2eb..b485e4371c 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -1,10 +1,11 @@ #!/usr/bin/env python3 - -import sys, os, shutil -import logging -import argparse, textwrap -import subprocess -from datetime import datetime +""" +gen_mksurfdata_jobscript_single.py generates a jobscript for running the +mksurfdata executable to generate a single fsurdat file. For detailed +instructions, see README. +""" +import sys +import argparse def get_parser(): """ @@ -102,17 +103,18 @@ def main (): runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=12:mpiprocs={tasks_per_node} \n") runfile.write("\n") - np = int(tasks_per_node) * int(number_of_nodes) + n_p = int(tasks_per_node) * int(number_of_nodes) # Run env_mach_specific.sh to control the machine dependent environment # including the paths to compilers and libraries external to cime such # as netcdf - runfile.write(f". ./.env_mach_specific.sh \n") - runfile.write('# Edit the mpirun command to use the MPI executable on your system and the arguments it requires \n') + runfile.write('. ./.env_mach_specific.sh \n') + runfile.write('# Edit the mpirun command to use the MPI executable ' \ + 'on your system and the arguments it requires \n') if machine == 'cheyenne': - output = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist_file}" + output = f"mpiexec_mpt -p \"%g:\" -np {n_p} ./bld/mksurfdata < {namelist_file}" elif machine == 'casper': - output = f"mpiexec -np {np} ./bld/mksurfdata < {namelist_file}" + output = f"mpiexec -np {n_p} ./bld/mksurfdata < {namelist_file}" runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 7eadb606b0..4130071c5e 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -1,32 +1,46 @@ #!/usr/bin/env python3 - -import sys, os, shutil +""" +gen_mksurfdata_namelist.py generates a namelist for use with the mksurfdata +executable. For detailed instructions, see README. +""" +import os +import sys import xml.etree.ElementTree as ET import logging -import argparse, textwrap +import argparse +import textwrap import subprocess from datetime import datetime +_CTSM_PYTHON = os.path.join(os.path.dirname(os.path.realpath(__file__)), + os.pardir, + os.pardir, + 'python') +sys.path.insert(1, _CTSM_PYTHON) + +from ctsm.ctsm_logging import setup_logging_pre_config, add_logging_args, process_logging_args + logger = logging.getLogger(__name__) # valid options for SSP/RCP scenarios -valid_opts = {"ssp-rcp": ["none","SSP1-2.6","SSP3-7.0","SSP5-3.4","SSP2-4.5","SSP1-1.9","SSP4-3.4","SSP4-6.0","SSP5-8.5"]} +valid_opts = {'ssp-rcp': ['SSP1-2.6', 'SSP3-7.0', 'SSP5-3.4', 'SSP2-4.5', + 'SSP1-1.9', 'SSP4-3.4', 'SSP4-6.0', 'SSP5-8.5', + 'none']} def get_parser(): """ Get parser object for this script. """ + # set up logging allowing user control + setup_logging_pre_config() + parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter ) parser.print_usage = parser.print_help + add_logging_args(parser) - parser.add_argument( - '-v', '--verbose', - help="increase output verbosity", - action="store_true", - ) parser.add_argument( "--start-year", help = textwrap.dedent('''\ @@ -228,6 +242,7 @@ def get_parser(): def main (): args = get_parser().parse_args() + process_logging_args(args) start_year = args.start_year end_year = args.end_year @@ -250,30 +265,32 @@ def main (): (start_year == 2005 and end_year == 2005): hires_pft = 'on' else: - print(f"ERROR: for --hires_pft you must set both start-year & end-year to 1850 or to 2005") - sys.exit(5) + error_msg = 'ERROR: for --hires_pft you must set both start-year ' \ + 'and end-year to 1850 or to 2005' + sys.exit(error_msg) else: hires_pft = 'off' - verbose = args.verbose if force_model_mesh_file != 'none': res = force_model_mesh_nx + 'x' + force_model_mesh_ny hostname = os.getenv("HOSTNAME") logname = os.getenv("LOGNAME") - if args.verbose: - print (f"hostname is {hostname}") - print (f"logname is {logname}") + + logger.info('hostname is %s', hostname) + logger.info('logname is %s', logname) if ssp_rcp == 'none': if int(start_year) > 2015: - print(f"ERROR: if start-year is > 2015 must add an --ssp_rcp argument that is not 'none") - print(f" valid opts for ssp-rcp are {valid_opts}") - sys.exit(10) + error_msg = 'ERROR: if start-year > 2015 must add an --ssp_rcp ' \ + 'argument that is not none: valid opts for ssp-rcp ' \ + f'are {valid_opts}' + sys.exit(error_msg) elif int(end_year) > 2015: - print(f"ERROR: if end-year is > 2015 must add an --ssp-rcp argument that is not 'none") - print(f" valid opts for ssp-rcp are {valid_opts}") - sys.exit(10) + error_msg = 'ERROR: if end-year > 2015 must add an --ssp-rcp ' \ + 'argument that is not none: valid opts for ssp-rcp ' \ + f'are {valid_opts}' + sys.exit(error_msg) pft_years_ssp = "-999" @@ -297,12 +314,12 @@ def main (): pft_years = "-999" pft_years_ssp = "2016-2100" else: - print (f"start_year is {start_year} and end_year is {end_year}") - print (f"ERROR: start and end years should be between 850 and 2105 or pot_veg flag needs to be set") - sys.exit(10) + error_msg = f'ERROR: start_year is {start_year} and end_year is ' \ + f'{end_year}; start/end years should be between 850 and ' \ + ' 2105 or pot_veg flag must be set' + sys.exit(error_msg) - if verbose: - print (f"pft_years = {pft_years}") + logger.info('pft_years = %s', pft_years) # Create land-use txt file for a transient case. # Determine the run type and if a transient run create output landuse txt file @@ -310,8 +327,7 @@ def main (): run_type = "transient" else: run_type = "timeslice" - if verbose: - print(f"run_type = {run_type}") + logger.info('run_type = %s', run_type) # error check on glc_nec if (glc_nec <= 0) or (glc_nec >= 100): @@ -333,8 +349,8 @@ def main (): xml_path = os.path.join(tool_path, 'gen_mksurfdata_namelist.xml') tree1 = ET.parse(xml_path) root = tree1.getroot() - root.tag - root.attrib + logger.info('root.tag: %s', root.tag) + logger.info('root.attrib: %s', root.attrib) for child1 in root: max_match_num = -1 max_match_child = None @@ -357,15 +373,15 @@ def main (): # For years greater than 2015 - mksrf_fvegtyp_ssp must have a match if start_year <= 2015: if 'mksrf_fvegtyp_ssp' not in child1.tag: - print (f"ERROR: {child1.tag} has no matches") - sys.exit(15) + error_msg = f'ERROR: {child1.tag} has no matches' + sys.exit(error_msg) else: continue else: # For years less than 2015 - mksrf_fvegtyp must have a match if 'mksrf_fvegtyp' not in child1.tag: - print (f"ERROR: {child1.tag} has no matches") - sys.exit(15) + error_msg = f'ERROR: {child1.tag} has no matches' + sys.exit(error_msg) else: continue @@ -374,15 +390,18 @@ def main (): rawdata_files[child1.tag] = os.path.join(input_path, item.text) if '%y' not in rawdata_files[child1.tag]: if not os.path.isfile(rawdata_files[child1.tag]): - print(f"ERROR: input data file {rawdata_files[child1.tag]} for {child1.tag} does not exist") - sys.exit(20) + error_msg = 'ERROR: input data file ' \ + f'{rawdata_files[child1.tag]} for ' \ + f'{child1.tag} does not exist' + sys.exit(error_msg) if item.tag == 'mesh_filename': new_key = f"{child1.tag}_mesh" rawdata_files[new_key] = os.path.join(input_path, item.text) if not os.path.isfile(rawdata_files[new_key]): - print(f"ERROR: input mesh file {rawdata_files[new_key]} does not exist") - sys.exit(30) + error_msg = 'ERROR: input mesh file ' \ + f'{rawdata_files[new_key]} does not exist' + sys.exit(error_msg) if item.tag == 'lake_filename': new_key = f"{child1.tag}_lake" @@ -398,40 +417,40 @@ def main (): root = tree2.getroot() model_mesh = "" for child1 in root: # this is domain tag - for name, value in child1.attrib.items(): + for _, value in child1.attrib.items(): if value == res: for child2 in child1: if child2.tag == 'mesh': model_mesh = child2.text - rawdata_files["mksrf_fgrid_mesh"] = os.path.join(input_path,model_mesh.strip('$DIN_LOC_ROOT/')) + rawdata_files['mksrf_fgrid_mesh'] = \ + os.path.join(input_path, + model_mesh.strip('$DIN_LOC_ROOT/')) if child2.tag == 'nx': rawdata_files["mksrf_fgrid_mesh_nx"] = child2.text if child2.tag == 'ny': rawdata_files["mksrf_fgrid_mesh_ny"] = child2.text if force_model_mesh_file == 'none' and len(model_mesh) == 0: - print (f"ERROR: input res {res} is invalid") valid_grids = [] for child1 in root: # this is domain tag - for name, value in child1.attrib.items(): + for _, value in child1.attrib.items(): valid_grids.append(value) - print (f"valid grid values are {valid_grids}") - sys.exit(40) + error_msg = f'ERROR: invalid input res {res};' \ + f'valid grid values are {valid_grids}' + sys.exit(error_msg) # Determine num_pft if nocrop_flag: num_pft = "16" else: num_pft = "78" - if verbose: - print (f"num_pft is {num_pft}") + logger.info('num_pft is %s', num_pft) # Write out if surface dataset will be created - if verbose: - if nosurfdata_flag: - print(f"surface dataset will not be created") - else: - print(f"surface dataset will be created") + if nosurfdata_flag: + logger.info('surface dataset will not be created') + else: + logger.info('surface dataset will be created') if run_type == 'transient': if ssp_rcp == 'none': @@ -441,6 +460,7 @@ def main (): with open(landuse_fname, "w", encoding='utf-8') as landuse_file: for year in range(start_year, end_year + 1): + year_str = str(year) if year <= 2015: file1 = rawdata_files["mksrf_fvegtyp"] file2 = rawdata_files["mksrf_fvegtyp_urban"] @@ -450,28 +470,31 @@ def main (): file2 = rawdata_files["mksrf_fvegtyp_ssp_urban"] file3 = rawdata_files["mksrf_fvegtyp_ssp_lake"] - landuse_input_fname = file1.replace("%y",str(year)) - landuse_input_fnam2 = file2.replace("%y",str(year)) - landuse_input_fnam3 = file3.replace("%y",str(year)) + landuse_input_fname = file1.replace("%y", year_str) + landuse_input_fnam2 = file2.replace("%y", year_str) + landuse_input_fnam3 = file3.replace("%y", year_str) if not os.path.isfile(landuse_input_fname): - print(f"ERROR: landunit_input_fname: {landuse_input_fname} does not exist") - sys.exit(60) + error_msg = 'ERROR: landunit_input_fname: ' \ + f'{landuse_input_fname} does not exist' + sys.exit(error_msg) if not os.path.isfile(landuse_input_fnam2): - print(f"ERROR: landunit_input_fnam2: {landuse_input_fnam2} does not exist") - sys.exit(60) + error_msg = 'ERROR: landunit_input_fnam2: ' \ + f'{landuse_input_fnam2} does not exist' + sys.exit(error_msg) if not os.path.isfile(landuse_input_fnam3): - print(f"ERROR: landunit_input_fnam3: {landuse_input_fnam3} does not exist") - sys.exit(60) + error_msg = 'ERROR: landunit_input_fnam3: ' \ + f'{landuse_input_fnam3} does not exist' + sys.exit(error_msg) # -- Each line is written twice in the original perl code: - landuse_line = f"{landuse_input_fname:<196}{str(year)}\n" - landuse_lin2 = f"{landuse_input_fnam2:<196}{str(year)}\n" - landuse_lin3 = f"{landuse_input_fnam3:<196}{str(year)}\n" + landuse_line = f"{landuse_input_fname:<196}{year_str}\n" + landuse_lin2 = f"{landuse_input_fnam2:<196}{year_str}\n" + landuse_lin3 = f"{landuse_input_fnam3:<196}{year_str}\n" landuse_file.write(landuse_line) landuse_file.write(landuse_line) landuse_file.write(landuse_lin2) landuse_file.write(landuse_lin3) - logger.debug(f"year : {year}") + logger.debug('year : %s', year_str) logger.debug(landuse_line) print(f"Successfully created input landuse file {landuse_fname}") else: @@ -483,22 +506,22 @@ def main (): else: ssp_rcp_name = ssp_rcp if int(end_year) == int(start_year): - nlfname = f"surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.namelist" - fsurdat = f"surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.nc" - fsurlog = f"surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.log" - fdyndat = "" + fdyndat = '' + prefix = f'surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.' else: - nlfname = f"surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.namelist" - fsurdat = f"surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.nc" - fsurlog = f"surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.log" - fdyndat = f"landuse.timeseries_{res}_{ssp_rcp_name}_{num_pft}_CMIP6_{start_year}-{end_year}_c{time_stamp}.nc" + fdyndat = f'landuse.timeseries_{res}_{ssp_rcp_name}_{num_pft}_CMIP6_{start_year}-{end_year}_c{time_stamp}.nc' + prefix = f'surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.' + + nlfname = f'{prefix}namelist' + fsurdat = f'{prefix}nc' + fsurlog = f'{prefix}log' - git_desc_cmd = f"git -C {tool_path} describe" + git_desc_cmd = f'git -C {tool_path} describe' try: # The "git -C" option permits a system test to run this tool from # elsewhere while running the git command from the tool_path gitdescribe = subprocess.check_output(git_desc_cmd, shell=True).strip() - except subprocess.CalledProcessError as e: + except subprocess.CalledProcessError: # In case the "git -C" option is unavailable, as on casper (2022/5/24) gitdescribe = subprocess.check_output('git describe', shell=True).strip() gitdescribe = gitdescribe.decode('utf-8') @@ -507,9 +530,10 @@ def main (): # it takes a long time to generate the mapping files # from 1km to the following two resolutions since the output mesh has so few points if res == "10x15": - mksrf_ftopostats_override = os.path.join(input_path,"lnd","clm2","rawdata","surfdata_topo_10x15_c220303.nc") - if args.verbose: - print (f"will override mksrf_ftopostats with = {mksrf_ftopostats_override}") + mksrf_ftopostats_override = os.path.join(input_path, 'lnd', 'clm2', + 'rawdata', 'surfdata_topo_10x15_c220303.nc') + logger.info('will override mksrf_ftopostats with = %s', + mksrf_ftopostats_override) else: mksrf_ftopostats_override = "" @@ -528,9 +552,9 @@ def main (): mksrf_fgrid_mesh_ny = force_model_mesh_ny mksrf_fgrid_mesh = force_model_mesh_file else: - mksrf_fgrid_mesh_nx = rawdata_files["mksrf_fgrid_mesh_nx"] - mksrf_fgrid_mesh_ny = rawdata_files["mksrf_fgrid_mesh_ny"] - mksrf_fgrid_mesh = rawdata_files["mksrf_fgrid_mesh"] + mksrf_fgrid_mesh_nx = rawdata_files["mksrf_fgrid_mesh_nx"] + mksrf_fgrid_mesh_ny = rawdata_files["mksrf_fgrid_mesh_ny"] + mksrf_fgrid_mesh = rawdata_files["mksrf_fgrid_mesh"] nlfile.write( f" mksrf_fgrid_mesh = \'{mksrf_fgrid_mesh}\' \n") nlfile.write( f" mksrf_fgrid_mesh_nx = {mksrf_fgrid_mesh_nx} \n") nlfile.write( f" mksrf_fgrid_mesh_ny = {mksrf_fgrid_mesh_ny} \n") @@ -557,11 +581,13 @@ def main (): if '%y' in mksrf_fhrvtyp: mksrf_fhrvtyp = mksrf_fhrvtyp.replace("%y",str(start_year)) if not os.path.isfile(mksrf_fvegtyp): - print(f"ERROR: input mksrf_fvegtyp file {mksrf_fvegtyp} does not exist") - sys.exit(20) + error_msg = f'ERROR: input mksrf_fvegtyp file {mksrf_fvegtyp} ' \ + 'does not exist' + sys.exit(error_msg) if not os.path.isfile(mksrf_fhrvtyp): - print(f"ERROR: input mksrf_fhrvtyp file {mksrf_fhrvtyp} does not exist") - sys.exit(20) + error_msg = f'ERROR: input mksrf_fhrvtyp file {mksrf_fhrvtyp} ' \ + 'does not exist' + sys.exit(error_msg) nlfile.write( f" mksrf_fvegtyp = \'{mksrf_fvegtyp}\' \n") nlfile.write( f" mksrf_fvegtyp_mesh = \'{mksrf_fvegtyp_mesh}\' \n") nlfile.write( f" mksrf_fhrvtyp = \'{mksrf_fhrvtyp}\' \n") @@ -579,7 +605,7 @@ def main (): # output data files # ------------------- if nosurfdata_flag: - nlfile.write(f" fsurdat = \' \' \n") + nlfile.write(" fsurdat = \' \' \n") else: nlfile.write(f" fsurdat = \'{fsurdat}'\n") nlfile.write(f" fsurlog = \'{fsurlog}\' \n") From aa13a882ce9d1704792a7753dea4cde7bb8bba84 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 24 May 2022 16:15:19 -0600 Subject: [PATCH 205/614] Upd. the file paired w mksrf_topo.10min.cdf5.c220201.nc to cdf5 in .xml --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 5ea0b982d0..11077b6290 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -110,7 +110,7 @@ lnd/clm2/rawdata/mksrf_topo.10min.cdf5.c220201.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_10x10min_nomask_cdf5_c200129.nc From 13aa24bdad9c48c7ba1a60453fff20764aafa462 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 24 May 2022 17:34:54 -0600 Subject: [PATCH 206/614] nccopy -k cdf5 all files in the .xml in order to complete the .rimport Files that hadn't been done already were all mesh files. --- .../gen_mksurfdata_namelist.xml | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 11077b6290..5ff6f662f2 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -11,11 +11,11 @@ lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20220305/mksrf_lai_ctsm52_histLUH2_2005.c220305.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_lai_histclm52deg005_earthstatmirca_2005.cdf5.c220228.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc @@ -26,7 +26,7 @@ lnd/clm2/rawdata/mksrf_organic_10level_5x5min_ISRIC-WISE-NCSCD_nlev7_c120830.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_cdf5_c200129.nc @@ -40,25 +40,25 @@ lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20220305/mksrf_soilcolor_ctsm52_histLUH2_2005.c220305.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_soilcolor_histclm52deg005_earthstatmirca_2005.cdf5.c220228.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc lnd/clm2/rawdata/mksrf_soitex.10level.c010119.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_cdf5_c200129.nc lnd/clm2/rawdata/mksrf_fmax_0.125x0.125_c200220.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.125x0.125_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.125x0.125_nomask_cdf5_c200129.nc @@ -69,14 +69,14 @@ lnd/clm2/rawdata/mksrf_LakePnDepth_3x3min_simyr2004_csplk_c151015.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc lnd/clm2/rawdata/mksrf_lanwat.050425.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_cdf5_c200129.nc @@ -87,7 +87,7 @@ lnd/clm2/rawdata/mksrf_vocef_0.5x0.5_simyr2000.c110531.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_cdf5_c200129.nc @@ -98,11 +98,11 @@ lnd/clm2/rawdata/mksrf_urban_0.05x0.05_simyr2000.c220127.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/pot_veg/mksrf_urban_0.05x0.05_zerourbanpct.cdf5.c181014.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc @@ -135,11 +135,11 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000.cdf5.c120926.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000_mergeGreenland.c120921.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc @@ -157,36 +157,36 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/mksrf_gdp_0.5x0.5_AVHRR_simyr2000.c130228.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/pot_veg/mksrf_gdp_0.5x0_zerogdp.cdf5.c200413.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_cdf5_c200129.nc lnd/clm2/rawdata/mksrf_peatf_0.5x0.5_AVHRR_simyr2000.c130228.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_cdf5_c200129.nc lnd/clm2/rawdata/mksf_soilthk_5x5min_ORNL-Soil_simyr1900-2015_c170630.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_cdf5_c200129.nc lnd/clm2/rawdata/mksrf_abm_0.5x0.5_AVHRR_simyr2000.c130201.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/pot_veg/mksrf_abm_0.5x0.5_missingabm.cdf5.c200413.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_cdf5_c200129.nc @@ -197,7 +197,7 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/mksrf_topostats_1km-merge-10min_HYDRO1K-merge-nomask_simyr2000.c130402.nc - lnd/clm2/mappingdata/grids/UGRID_1km-merge-10min_HYDRO1K-merge-nomask_c130402.nc + lnd/clm2/mappingdata/grids/UGRID_1km-merge-10min_HYDRO1K-merge-nomask_cdf5_c130402.nc @@ -208,7 +208,7 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/mksrf_vic_0.9x1.25_GRDC_simyr2000.c130307.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.9x1.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.9x1.25_nomask_cdf5_c200129.nc @@ -220,37 +220,37 @@ version of the raw dataset will probably go away. /glade/p/cgd/tss/people/slevis/pot_veg/mksrf_landuse_potvegclm50_LUH2.cdf5.c181106.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.cdf5.c170629/mksrf_landuse_histclm50_LUH2_1850.cdf5.c170629.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.cdf5.c170629/mksrf_landuse_histclm50_LUH2_2000.cdf5.c170629.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.cdf5.c170629/mksrf_landuse_histclm50_LUH2_2005.cdf5.c170629.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_2005.cdf5.c190119.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_%y.c171012.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20220305/mksrf_landuse_ctsm52_histLUH2_%y.c220305.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc @@ -264,49 +264,49 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP26_%y.c220305.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP19_%y.c220305.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP2RCP45_%y.c220305.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP3RCP70_%y.c220305.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP34_%y.c220305.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP60_%y.c220305.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP5RCP85_%y.c220305.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc From b27cd5cbacf96d3be3555e9358d4586966c3dc71 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 24 May 2022 19:08:19 -0600 Subject: [PATCH 207/614] Preparations for running the mksurfdata tool on izumi --- tools/mksurfdata_esmf/README | 8 ++++++++ .../gen_mksurfdata_jobscript_single.py | 11 +++++++++-- .../mksurfdata_esmf/gen_mksurfdata_namelist.py | 17 +++++++++-------- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index f2d61e2539..6e3b771c1c 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -55,6 +55,14 @@ running for a single submission: > ./gen_mksurfdata_namelist.py --help # for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: > ./gen_mksurfdata_namelist.py --res --start-year --end-year +# IF FILES ARE MISSING FROM /inputdata, a target namelist will be generated +# but with a generic name and with warning to run ./download_input_data next. +# IF A SMALLER SET OF FILES IS STILL MISSING AFTER RUNNING ./download_input_data +# and rerunning ./gen_mksurfdata_namelist.py, then rerun +# ./gen_mksurfdata_namelist.py with --vic selected (and iteratively additional +# options if still necessary) and rerun ./download_input_data until +# ./gen_mksurfdata_namelist.py finds all files. + # to generate your target jobscript (again --help for instructions): > ./gen_mksurfdata_jobscript_single.py --number-of-nodes 24 --tasks-per-node 12 --namelist-file target.namelist > qsub mksurfdata_jobscript_single diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index 40794499f1..ecb05f6025 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -45,13 +45,14 @@ def get_parser(): ) parser.add_argument( "--machine", - help="""currently this recognizes cheyenne and casper (default + help="""currently this recognizes cheyenne, casper, izumi (default cheyenne); this needs to be a cime machine, i.e. a machine that has been ported to cime where you can build a cime model; for details see the README in this directory""", action="store", dest="machine", required=False, + choices=['cheyenne', 'casper', 'izumi'], default='cheyenne' ) parser.add_argument( @@ -90,16 +91,20 @@ def main (): with open(jobscript_file, "w",encoding='utf-8') as runfile: runfile.write('#!/bin/bash \n') - runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -N mksurfdata \n') runfile.write('#PBS -j oe \n') runfile.write('#PBS -l walltime=30:00 \n') if machine == 'cheyenne': + runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -q regular \n') runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") elif machine == 'casper': + runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -q casper \n') runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=12:mpiprocs={tasks_per_node}:mem=80GB \n") + elif machine == 'izumi': + runfile.write('#PBS -q test \n') + runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") runfile.write("\n") np = int(tasks_per_node) * int(number_of_nodes) @@ -108,6 +113,8 @@ def main (): output = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist_file}" elif machine == 'casper': output = f"mpiexec -np {np} ./bld/mksurfdata < {namelist_file}" + elif machine == 'izumi': + output = f"mpirun -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist_file}" runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 51150fd25b..28a7298339 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -129,7 +129,8 @@ def get_parser(): parser.add_argument( "--rawdata-dir", help=""" - /path/of/root/of/input/data', + /path/of/root/of/input/data + on izumi use /fs/cgd/csm/inputdata [default: %(default)s] """, action="store", @@ -374,7 +375,7 @@ def main (): if '%y' not in rawdata_files[child1.tag]: if not os.path.isfile(rawdata_files[child1.tag]): print(f"WARNING: input data file {rawdata_files[child1.tag]} for {child1.tag} does not exist") - print(f"WARNING: run ./download_input_data to try to obtain missing files") + print(f"WARNING: run ./download_input_data to try TO OBTAIN MISSING FILES") _must_run_download_input_data = True if item.tag == 'mesh_filename': @@ -382,7 +383,7 @@ def main (): rawdata_files[new_key] = os.path.join(input_path, item.text) if not os.path.isfile(rawdata_files[new_key]): print(f"WARNING: input mesh file {rawdata_files[new_key]} does not exist") - print(f"WARNING: run ./download_input_data to try to obtain missing files") + print(f"WARNING: run ./download_input_data to try TO OBTAIN MISSING FILES") _must_run_download_input_data = True if item.tag == 'lake_filename': @@ -455,15 +456,15 @@ def main (): landuse_input_fnam3 = file3.replace("%y",str(year)) if not os.path.isfile(landuse_input_fname): print(f"WARNING: landunit_input_fname: {landuse_input_fname} does not exist") - print(f"WARNING: run ./download_input_data to try to obtain missing files") + print(f"WARNING: run ./download_input_data to try TO OBTAIN MISSING FILES") _must_run_download_input_data = True if not os.path.isfile(landuse_input_fnam2): print(f"WARNING: landunit_input_fnam2: {landuse_input_fnam2} does not exist") - print(f"WARNING: run ./download_input_data to try to obtain missing files") + print(f"WARNING: run ./download_input_data to try TO OBTAIN MISSING FILES") _must_run_download_input_data = True if not os.path.isfile(landuse_input_fnam3): print(f"WARNING: landunit_input_fnam3: {landuse_input_fnam3} does not exist") - print(f"WARNING: run ./download_input_data to try to obtain missing files") + print(f"WARNING: run ./download_input_data to try TO OBTAIN MISSING FILES") _must_run_download_input_data = True # -- Each line is written twice in the original perl code: @@ -554,11 +555,11 @@ def main (): mksrf_fhrvtyp = mksrf_fhrvtyp.replace("%y",str(start_year)) if not os.path.isfile(mksrf_fvegtyp): print(f"WARNING: input mksrf_fvegtyp file {mksrf_fvegtyp} does not exist") - print(f"WARNING: run ./download_input_data to try to obtain missing files") + print(f"WARNING: run ./download_input_data to try TO OBTAIN MISSING FILES") _must_run_download_input_data = True if not os.path.isfile(mksrf_fhrvtyp): print(f"WARNING: input mksrf_fhrvtyp file {mksrf_fhrvtyp} does not exist") - print(f"WARNING: run ./download_input_data to try to obtain missing files") + print(f"WARNING: run ./download_input_data to try TO OBTAIN MISSING FILES") _must_run_download_input_data = True nlfile.write( f" mksrf_fvegtyp = \'{mksrf_fvegtyp}\' \n") nlfile.write( f" mksrf_fvegtyp_mesh = \'{mksrf_fvegtyp_mesh}\' \n") From f7c80ec25c845b65d7311816d14d581015e0776c Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 25 May 2022 13:46:08 -0600 Subject: [PATCH 208/614] Set organic to 0 when mapunit = 0 or lookup returns negative value --- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index e4ec6cd025..14fa1293be 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -263,10 +263,10 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o if (pctlnd_pft_o(no) < 1.e-6_r8 .or. mapunit_o(no) == 0) then - ! Adjust sand and clay be loam if pctlnd_pft is < 1.e-6 or mapunit is 0 + ! Set sand and clay to loam if pctlnd_pft is < 1.e-6 or mapunit is 0 sand_o(no,:) = 43._r4 clay_o(no,:) = 18._r4 - orgc_o(no,:) = 18._r4 ! TODO slevis: value for loam here? + orgc_o(no,:) = 0._r4 else @@ -349,8 +349,8 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o write(6,'(a,i8)')'WARNING: changing orgc_o from -4 to 1 at no = ',no orgc_o(no,:) = 1._r4 else - write(6,'(a,i8,a,i8)')'WARNING: changing orgc_o from ',int(orgc_o(no,1)),' to 18 at no = ',no - orgc_o(no,:) = 18._r4 ! TODO slevis: Value for loam here? + write(6,'(a,i8,a,i8)')'WARNING: changing orgc_o from ',int(orgc_o(no,1)),' to 0 at no = ',no + orgc_o(no,:) = 0._r4 end if end if if (orgc_o(no,1) < 0.) then From 480f744c2327d25de443392f891c9fae6d281a97 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 25 May 2022 17:20:01 -0600 Subject: [PATCH 209/614] Updates to gen_mksurfdata_jobscript_single.py Jobscript now runs but fails right away --- .../gen_mksurfdata_jobscript_single.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index ecb05f6025..784d58816e 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -89,7 +89,6 @@ def main (): # Write run script # -------------------------- with open(jobscript_file, "w",encoding='utf-8') as runfile: - runfile.write('#!/bin/bash \n') runfile.write('#PBS -N mksurfdata \n') runfile.write('#PBS -j oe \n') @@ -103,18 +102,26 @@ def main (): runfile.write('#PBS -q casper \n') runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=12:mpiprocs={tasks_per_node}:mem=80GB \n") elif machine == 'izumi': - runfile.write('#PBS -q test \n') - runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") + runfile.write('#PBS -q medium \n') + runfile.write(f'#PBS -l nodes={number_of_nodes}:ppn={tasks_per_node} -r n \n') + runfile.write("\n") + + tool_path = os.path.dirname(os.path.abspath(__file__)) + bld_path = os.path.join(tool_path, 'bld') + + runfile.write(f'cd {bld_path} \n') + runfile.write("\n") + runfile.write('. ./.env_mach_specific.sh \n') runfile.write("\n") np = int(tasks_per_node) * int(number_of_nodes) if machine == 'cheyenne': - output = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist_file}" + output = f"mpiexec_mpt -p \"%g:\" -np {np} ./mksurfdata < ../{namelist_file}" elif machine == 'casper': - output = f"mpiexec -np {np} ./bld/mksurfdata < {namelist_file}" + output = f"mpiexec -np {np} ./mksurfdata < ../{namelist_file}" elif machine == 'izumi': - output = f"mpirun -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist_file}" + output = f"mpirun -np {np} ./mksurfdata < ../{namelist_file}" runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") From 1fca36c633b2543d63b2884a4781e59971845855 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 26 May 2022 13:47:53 -0600 Subject: [PATCH 210/614] Error msg for when "machine" is not valid --- cime_config/SystemTests/mksurfdataesmf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 47ecf9bde3..f78c0766c6 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -102,6 +102,8 @@ def run_phase(self): mpi_cmd = f'mpiexec_mpt -np 144 {executable_path} < {self._fsurdat_namelist}' elif machine == 'casper': mpi_cmd = f'mpiexec -np 144 {executable_path} < {self._fsurdat_namelist}' + else: + sys.exit(f'machine = {machine} not recognized by this script') # Run executable to generate fsurdat (rm fsurdat if exists) if os.path.exists(self._fsurdat_nc): From 4aa4b215d0d55c14747e98c0777abde6f5292df8 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 26 May 2022 15:27:04 -0600 Subject: [PATCH 211/614] In gen_mksurfdata_jobscript_single.py cd to tool_dir instead of bld_dir This way output files (fsurdat.nc and fsurdat.log) appear in the local directory as they used to, instead of appearing in /bld --- .../gen_mksurfdata_jobscript_single.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index 784d58816e..ecc9fded3f 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -107,21 +107,20 @@ def main (): runfile.write("\n") tool_path = os.path.dirname(os.path.abspath(__file__)) - bld_path = os.path.join(tool_path, 'bld') - runfile.write(f'cd {bld_path} \n') + runfile.write(f'cd {tool_path} \n') runfile.write("\n") - runfile.write('. ./.env_mach_specific.sh \n') + runfile.write('. ./bld/.env_mach_specific.sh \n') runfile.write("\n") np = int(tasks_per_node) * int(number_of_nodes) if machine == 'cheyenne': - output = f"mpiexec_mpt -p \"%g:\" -np {np} ./mksurfdata < ../{namelist_file}" + output = f"mpiexec_mpt -p \"%g:\" -np {np} ./bld/mksurfdata < {namelist_file}" elif machine == 'casper': - output = f"mpiexec -np {np} ./mksurfdata < ../{namelist_file}" + output = f"mpiexec -np {np} ./bld/mksurfdata < {namelist_file}" elif machine == 'izumi': - output = f"mpirun -np {np} ./mksurfdata < ../{namelist_file}" + output = f"mpirun -np {np} ./bld/mksurfdata < {namelist_file}" runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") From ba8d4260437fbc3720cdd28ad810975cc18ae579 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 27 May 2022 16:23:35 -0600 Subject: [PATCH 212/614] Added to fsurdat: BULK, CFRAG, PHAQ, ORGC (and ORGANIC temporarily) --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 17 +- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 241 +++++++++++++++++---- 2 files changed, 215 insertions(+), 43 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index eeda6794bc..a38fe9c1ff 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -271,9 +271,24 @@ subroutine mkfile_define_vars(pioid, dynlanduse) long_name='soil texture map units', units='unitless') call mkpio_def_spatial_var(pioid=pioid, varname='ORGANIC', xtype=PIO_REAL, & - lev1name='nlevsoi', & + lev1name='nlevsoi', & ! TODO Rm ORGANIC before merging PR #1732 long_name='organic matter density at soil levels', & units='kg/m3 (assumed carbon content 0.58 gC per gOM)') + call mkpio_def_spatial_var(pioid=pioid, varname='ORGC', xtype=PIO_REAL, & + lev1name='nlevsoi', & + long_name='soil organic carbon', units='gC/kg soil') + + call mkpio_def_spatial_var(pioid=pioid, varname='BULK', xtype=PIO_REAL, & + lev1name='nlevsoi', & + long_name='bulk density', units='g cm-3') + + call mkpio_def_spatial_var(pioid=pioid, varname='CFRAG', xtype=PIO_REAL, & + lev1name='nlevsoi', & + long_name='coarse fragments', units='vol% > 2 mm') + + call mkpio_def_spatial_var(pioid=pioid, varname='PHAQ', xtype=PIO_REAL, & + lev1name='nlevsoi', & + long_name='pH measured in water', units='unitless') call mkpio_def_spatial_var(pioid=pioid, varname='FMAX', xtype=xtype, & long_name='maximum fractional saturated area', units='unitless') diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 14fa1293be..948c7de086 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -35,7 +35,8 @@ module mksoiltexMod subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o, pctlnd_pft_o, rc) ! - ! make %sand, %clay, and organic carbon content + ! make %sand, %clay, organic carbon content, coarse fragments, bulk density, + ! and pH measured in H2O ! ! input/output variables character(len=*) , intent(in) :: file_mesh_i ! input mesh/grid file name @@ -66,10 +67,17 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o integer :: mapunit ! temporary igbp soil mapunit integer, allocatable :: sand_i(:,:,:) ! input grid: percent sand integer, allocatable :: clay_i(:,:,:) ! input grid: percent clay - integer, allocatable :: orgc_i(:,:,:) ! input grid: organic carbon content (gC kg-1) - real(r4), allocatable :: sand_o(:,:) ! % sand (output grid) - real(r4), allocatable :: clay_o(:,:) ! % clay (output grid) - real(r4), allocatable :: orgc_o(:,:) ! organic carbon content (gC kg-1) (output grid) + integer, allocatable :: cfrag_i(:,:,:) ! input grid: coarse fragments (vol% > 2 mm) + real(r4), allocatable :: bulk_i(:,:,:) ! input grid: bulk density (g cm-3) + real(r4), allocatable :: orgc_i(:,:,:) ! input grid: organic carbon content (gC kg-1) + real(r4), allocatable :: phaq_i(:,:,:) ! input grid: soil pH measured in H2O (unitless) + real(r4), allocatable :: sand_o(:,:) ! output grid: % sand + real(r4), allocatable :: clay_o(:,:) ! output grid: % clay + real(r4), allocatable :: orgc_o(:,:) ! output grid: organic carbon content (gC kg-1) + real(r4), allocatable :: cfrag_o(:,:) ! output grid: coarse fragments (vol% > 2 mm) + real(r4), allocatable :: bulk_o(:,:) ! output grid: bulk density (g cm-3) + real(r4), allocatable :: phaq_o(:,:) ! output grid: soil pH measured in H2O (unitless) + real(r4), allocatable :: organic_o(:,:) ! output grid: organic matter (kg m-3) TODO Rm before merging PR #1732 integer :: n_mapunits integer :: lookup_index integer :: SCID @@ -80,6 +88,10 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o type(var_desc_t) :: pio_varid_sand type(var_desc_t) :: pio_varid_clay type(var_desc_t) :: pio_varid_orgc + type(var_desc_t) :: pio_varid_cfrag + type(var_desc_t) :: pio_varid_bulk + type(var_desc_t) :: pio_varid_phaq + type(var_desc_t) :: pio_varid_organic ! TODO Rm bef merging PR #1732 integer :: starts(3) ! starting indices for reading lookup table integer :: counts(3) ! dimension counts for reading lookup table integer :: srcTermProcessing_Value = 0 @@ -91,7 +103,7 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o write(ndiag,*) write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) - write(ndiag,'(a)') 'Attempting to make %sand, %clay, and orgc .....' + write(ndiag,'(a)') 'Attempting to make %sand, %clay, orgc, cfrag, bulk, phaq .....' write(ndiag,'(a)') ' Input mapunit file is '//trim(file_mapunit_i) write(ndiag,'(a)') ' Input lookup table file is '//trim(file_lookup_i) write(ndiag,'(a)') ' Input mesh/grid file is '//trim(file_mesh_i) @@ -104,6 +116,10 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o allocate(sand_o(ns_o,nlevsoi)) ; sand_o(:,:) = spval allocate(clay_o(ns_o,nlevsoi)) ; clay_o(:,:) = spval allocate(orgc_o(ns_o,nlevsoi)) ; orgc_o(:,:) = spval + allocate(cfrag_o(ns_o,nlevsoi)) ; cfrag_o(:,:) = spval + allocate(bulk_o(ns_o,nlevsoi)) ; bulk_o(:,:) = spval + allocate(phaq_o(ns_o,nlevsoi)) ; phaq_o(:,:) = spval + allocate(organic_o(ns_o,nlevsoi)) ; organic_o(:,:) = spval ! TODO Rm bef merging PR #1732 !--------------------------------- ! Determine mapunits on output grid @@ -211,11 +227,12 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o ! Write out mapunit_o if (root_task) write(ndiag, '(a)') trim(subname)//" writing out mapunits " call mkfile_output(pioid_o, mesh_o, 'mapunits', mapunit_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for mapunits') + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error calling mkfile_output for mapunits') call pio_syncfile(pioid_o) !--------------------------------- - ! Determine %sand, %clay, and orgc on output grid - using above mapunits + ! Determine %sand, %clay, orgc, cfrag, bulk, phaq on output grid using + ! mapunits !--------------------------------- rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_lookup_i), pio_nowrite) @@ -231,6 +248,7 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o ! Read In MapUnits from the input file allocate(MapUnits(n_mapunits), stat=ier) + if (ier/=0) call shr_sys_abort() rcode = pio_inq_varid(pioid_i, 'MapUnit', pio_varid) rcode = pio_get_var(pioid_i, pio_varid, MapUnits) @@ -242,22 +260,34 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o mapunit_lookup(MapUnits(n)) = n end do - allocate(sand_i(nlay,n_scid,n_mapunits)) + allocate(sand_i(nlay,n_scid,n_mapunits), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(clay_i(nlay,n_scid,n_mapunits), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(orgc_i(nlay,n_scid,n_mapunits), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(cfrag_i(nlay,n_scid,n_mapunits), stat=ier) if (ier/=0) call shr_sys_abort() - allocate(clay_i(nlay,n_scid,n_mapunits)) + allocate(bulk_i(nlay,n_scid,n_mapunits), stat=ier) if (ier/=0) call shr_sys_abort() - allocate(orgc_i(nlay,n_scid,n_mapunits)) + allocate(phaq_i(nlay,n_scid,n_mapunits), stat=ier) if (ier/=0) call shr_sys_abort() ! Get dimensions from input file and allocate memory for sand_i, clay_i, - ! and organic carbon content + ! organic carbon content, coarse fragments, bulk density, pH measured in H2O rcode = pio_inq_varid(pioid_i, 'PCT_SAND', pio_varid_sand) rcode = pio_inq_varid(pioid_i, 'PCT_CLAY', pio_varid_clay) rcode = pio_inq_varid(pioid_i, 'ORGC', pio_varid_orgc) + rcode = pio_inq_varid(pioid_i, 'CFRAG', pio_varid_cfrag) + rcode = pio_inq_varid(pioid_i, 'BULK', pio_varid_bulk) + rcode = pio_inq_varid(pioid_i, 'PHAQ', pio_varid_phaq) rcode = pio_get_var(pioid_i, pio_varid_sand, sand_i) rcode = pio_get_var(pioid_i, pio_varid_clay, clay_i) rcode = pio_get_var(pioid_i, pio_varid_orgc, orgc_i) + rcode = pio_get_var(pioid_i, pio_varid_cfrag, cfrag_i) + rcode = pio_get_var(pioid_i, pio_varid_bulk, bulk_i) + rcode = pio_get_var(pioid_i, pio_varid_phaq, phaq_i) do no = 1,ns_o @@ -267,26 +297,30 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o sand_o(no,:) = 43._r4 clay_o(no,:) = 18._r4 orgc_o(no,:) = 0._r4 + cfrag_o(no,:) = 0._r4 + bulk_o(no,:) = 1.5_r4 ! TODO Ok as a fill value? + phaq_o(no,:) = 7._r4 + organic_o(no,:) = 0._r4 ! TODO Rm bef merging PR #1732 else ! Determine lookup_index lookup_index = mapunit_lookup(mapunit_o(no)) - ! Determine the top soil layer sand_o, clay_o, and orgc_o - ! If its less than 0 search within the SCID array for the first index - ! that gives a pct sand that is greater than or equal to 0 - ! Then determine the other soil layers sand_o + ! Determine top soil layer sand_o + ! If less than 0 search within the SCID array for the first index + ! that gives a value greater than or equal to 0 + ! Then determine the other soil layers sand_o(no,1) = float(sand_i(1,1,lookup_index)) - if (sand_o(no,1) < 0.) then + if (sand_o(no,1) < 0._r4) then do l = 2,n_scid - if (float(sand_i(1,l,lookup_index)) >= 0.) then + if (float(sand_i(1,l,lookup_index)) >= 0._r4) then sand_o(no,1) = float(sand_i(1,l,lookup_index)) exit end if end do end if - if (sand_o(no,1) < 0.) then + if (sand_o(no,1) < 0._r4) then if (int(sand_o(no,1)) == -4) then write(6,'(a,i8)')'WARNING: changing sand_o from -4 to 99% at no = ',no sand_o(no,:) = 99._r4 @@ -297,22 +331,22 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o end if do l = 2,nlay sand_o(no,l) = float(sand_i(l,1,lookup_index)) - if (sand_o(no,l) < 0.) then + if (sand_o(no,l) < 0._r4) then sand_o(no,l) = sand_o(no,l-1) end if end do ! Same algorithm for clay_o as for sand_o clay_o(no,1) = float(clay_i(1,1,lookup_index)) - if (clay_o(no,1) < 0.) then + if (clay_o(no,1) < 0._r4) then do l = 2,n_scid - if (float(clay_i(1,l,lookup_index)) >= 0.) then + if (float(clay_i(1,l,lookup_index)) >= 0._r4) then clay_o(no,1) = float(clay_i(1,l,lookup_index)) exit end if end do end if - if (clay_o(no,1) < 0.) then + if (clay_o(no,1) < 0._r4) then if (int(clay_o(no,1)) == -4) then write(6,'(a,i8)')'WARNING: changing clay_o from -4 to 1% at no = ',no clay_o(no,:) = 1._r4 @@ -321,64 +355,187 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o clay_o(no,:) = 18._r4 end if end if - if (clay_o(no,1) < 0.) then + if (clay_o(no,1) < 0._r4) then write(6,*)'ERROR: at no, lookup_index = ',no,lookup_index call shr_sys_abort('could not find a value >= 0 for clay_i') end if do l = 2,nlay clay_o(no,l) = float(clay_i(l,1,lookup_index)) - if (clay_o(no,l) < 0.) then + if (clay_o(no,l) < 0._r4) then clay_o(no,l) = clay_o(no,l-1) end if end do ! Same algorithm for orgc_o as for sand_o - ! TODO slevis: Get conversion (units etc) from Will's and Dave's - ! discussion in issue 1303 - orgc_o(no,1) = float(orgc_i(1,1,lookup_index)) - if (orgc_o(no,1) < 0.) then + ! organic_o OPTION 2 (commented out) + ! TODO Rm organic before merging PR #1732 UNLESS we opt for OPTION 2 + ! Calculate from multiple input variables to get the output variable + orgc_o(no,1) = orgc_i(1,1,lookup_index) + organic_o(no,1) = orgc_i(1,1,lookup_index) * bulk_i(1,1,lookup_index) * float(100 - cfrag_i(1,1,lookup_index)) * 0.01_r4 / 0.58_r4 ! TODO Remove? + if (orgc_o(no,1) < 0._r4) then do l = 2,n_scid - if (float(orgc_i(1,l,lookup_index)) >= 0.) then - orgc_o(no,1) = float(orgc_i(1,l,lookup_index)) + if (orgc_i(1,l,lookup_index) >= 0._r4) then + orgc_o(no,1) = orgc_i(1,l,lookup_index) + organic_o(no,1) = orgc_i(1,l,lookup_index) * bulk_i(1,l,lookup_index) * float(100 - cfrag_i(1,l,lookup_index)) * 0.01_r4 / 0.58_r4 ! TODO Rm? exit end if end do end if - if (orgc_o(no,1) < 0.) then - if (int(orgc_o(no,1)) == -4) then - write(6,'(a,i8)')'WARNING: changing orgc_o from -4 to 1 at no = ',no + if (orgc_o(no,1) < 0._r4) then + if (int(orgc_o(no,1)) == -4) then ! sand dunes + write(6,'(a,i8)')'WARNING: changing orgc_o from -4 to 1 at no = ', no orgc_o(no,:) = 1._r4 + write(6,'(a,i8)')'WARNING: changing organic_o from -4 to 1 at no = ', no ! TODO Remove? + organic_o(no,:) = 1._r4 ! TODO Remove? else write(6,'(a,i8,a,i8)')'WARNING: changing orgc_o from ',int(orgc_o(no,1)),' to 0 at no = ',no orgc_o(no,:) = 0._r4 + write(6,'(a,i8,a,i8)')'WARNING: changing organic_o from ',int(organic_o(no,1)),' to 0 at no = ', no ! TODO Remove? + organic_o(no,:) = 0._r4 ! TODO Remove? end if end if - if (orgc_o(no,1) < 0.) then + if (orgc_o(no,1) < 0._r4) then write(6,*)'ERROR: at no, lookup_index = ',no,lookup_index call shr_sys_abort('could not find a value >= 0 for orgc_i') end if do l = 2,nlay - orgc_o(no,l) = float(orgc_i(l,1,lookup_index)) - if (orgc_o(no,l) < 0.) then + orgc_o(no,l) = orgc_i(l,1,lookup_index) + organic_o(no,l) = orgc_i(l,1,lookup_index) * bulk_i(l,1,lookup_index) * float(100 - cfrag_i(l,1,lookup_index)) * 0.01_r4 / 0.58_r4 ! TODO Rm? + if (orgc_o(no,l) < 0._r4) then orgc_o(no,l) = orgc_o(no,l-1) + organic_o(no,l) = organic_o(no,l-1) ! TODO Remove? + end if + end do + + ! Same algorithm for cfrag_o as for sand_o + cfrag_o(no,1) = float(cfrag_i(1,1,lookup_index)) + if (cfrag_o(no,1) < 0._r4) then + do l = 2,n_scid + if (float(cfrag_i(1,l,lookup_index)) >= 0._r4) then + cfrag_o(no,1) = float(cfrag_i(1,l,lookup_index)) + exit + end if + end do + end if + if (cfrag_o(no,1) < 0._r4) then + if (int(cfrag_o(no,1)) == -4) then ! sand dunes + write(6,'(a,i8)')'WARNING: changing cfrag_o from -4 to 1 at no = ',no + cfrag_o(no,:) = 1._r4 + else + write(6,'(a,i8,a,i8)')'WARNING: changing cfrag_o from ',int(cfrag_o(no,1)),' to 0 at no = ',no + cfrag_o(no,:) = 0._r4 + end if + end if + if (cfrag_o(no,1) < 0._r4) then + write(6,*)'ERROR: at no, lookup_index = ',no,lookup_index + call shr_sys_abort('could not find a value >= 0 for cfrag_i') + end if + do l = 2,nlay + cfrag_o(no,l) = float(cfrag_i(l,1,lookup_index)) + if (cfrag_o(no,l) < 0._r4) then + cfrag_o(no,l) = cfrag_o(no,l-1) end if end do + ! Same algorithm for bulk_o as for sand_o + bulk_o(no,1) = bulk_i(1,1,lookup_index) + if (bulk_o(no,1) < 0._r4) then + do l = 2,n_scid + if (bulk_i(1,l,lookup_index) >= 0._r4) then + bulk_o(no,1) = bulk_i(1,l,lookup_index) + exit + end if + end do + end if + if (bulk_o(no,1) < 0._r4) then + if (int(bulk_o(no,1)) == -4) then ! sand dunes + write(6,'(a,i8)')'WARNING: changing bulk_o from -4 to 1 at no = ',no + bulk_o(no,:) = 1.5_r4 ! TODO Ok for sand dunes? + else + write(6,'(a,i8,a,i8)')'WARNING: changing bulk_o from ',int(bulk_o(no,1)),' to 0 at no = ',no + bulk_o(no,:) = 1.5_r4 ! TODO Ok for -7? + end if + end if + if (bulk_o(no,1) < 0._r4) then + write(6,*)'ERROR: at no, lookup_index = ',no,lookup_index + call shr_sys_abort('could not find a value >= 0 for bulk_i') + end if + do l = 2,nlay + bulk_o(no,l) = bulk_i(l,1,lookup_index) + if (bulk_o(no,l) < 0._r4) then + bulk_o(no,l) = bulk_o(no,l-1) + end if + end do + + ! Same algorithm for phaq_o as for sand_o + phaq_o(no,1) = phaq_i(1,1,lookup_index) + if (phaq_o(no,1) < 0._r4) then + do l = 2,n_scid + if (phaq_i(1,l,lookup_index) >= 0._r4) then + phaq_o(no,1) = phaq_i(1,l,lookup_index) + exit + end if + end do + end if + if (phaq_o(no,1) < 0._r4) then + if (int(phaq_o(no,1)) == -4) then ! sand dunes + write(6,'(a,i8)')'WARNING: changing phaq_o from -4 to 1 at no = ',no + phaq_o(no,:) = 7._r4 + else + write(6,'(a,i8,a,i8)')'WARNING: changing phaq_o from ',int(phaq_o(no,1)),' to 0 at no = ',no + phaq_o(no,:) = 7._r4 + end if + end if + if (phaq_o(no,1) < 0._r4) then + write(6,*)'ERROR: at no, lookup_index = ',no,lookup_index + call shr_sys_abort('could not find a value >= 0 for phaq_i') + end if + do l = 2,nlay + phaq_o(no,l) = phaq_i(l,1,lookup_index) + if (phaq_o(no,l) < 0._r4) then + phaq_o(no,l) = phaq_o(no,l-1) + end if + end do + + ! TODO Rm organic before merging PR #1732 UNLESS we opt for OPTION 2 + ! organic_o OPTION 1: as we plan to calculate organic in the CTSM +! do l = 1, nlay +! organic_o(no,l) = orgc_o(no,l) * bulk_o(no,l) * & +! (100._r4 - cfrag_o(no,l)) * 0.01_r4 / 0.58_r4 +! end do + end if end do if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent sand" call mkfile_output(pioid_o, mesh_o, 'PCT_SAND', sand_o, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error calling mkfile_output') if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil percent clay" call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error calling mkfile_output') + + ! TODO Rm ORGANIC before merging PR #1732 + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil organic matter" + call mkfile_output(pioid_o, mesh_o, 'ORGANIC', organic_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error calling mkfile_output') if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil organic carbon content" - call mkfile_output(pioid_o, mesh_o, 'ORGANIC', orgc_o, lev1name='nlevsoi', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call mkfile_output(pioid_o, mesh_o, 'ORGC', orgc_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error calling mkfile_output') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out coarse fragments in soil" + call mkfile_output(pioid_o, mesh_o, 'CFRAG', cfrag_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error calling mkfile_output') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil bulk density" + call mkfile_output(pioid_o, mesh_o, 'BULK', bulk_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error calling mkfile_output') + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil pH measured in H2O" + call mkfile_output(pioid_o, mesh_o, 'PHAQ', phaq_o, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error calling mkfile_output') call pio_syncfile(pioid_o) @@ -390,7 +547,7 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) if (root_task) then - write (ndiag,'(a)') 'Successfully made %sand, %clay, and orgc' + write(ndiag,'(a)') 'Successfully made %sand, %clay, orgc, cfrag, bulk, phaq .....' end if end subroutine mksoiltex From 3fb88c657f65a1857a184851946c6f8938137857 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 8 Jun 2022 16:43:14 -0600 Subject: [PATCH 213/614] Change default bld dir from /bld to /tool_bld for sys test to work The long version... System test MKSURFDATAESMF_P144x1.f10_f10_mg37.I1850Clm50BgcCrop.cheyenne_intel.clm-default relies on the ability to build the mksurfdata executable anywhere. I had named this directory (that can go anywhere) /tool_bld to distinguish from /bld that appears during the sys test in the same case directory in prep for submitting the ctsm run. Due to changes coming in the next commit that make the sys test generate and submit the jobscript that runs the mksurfdata executable (instead of spelling out the command inside the sys test script), I had to make the name of the default bld directory the same as the one expected by the sys test. --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 6 +++--- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index 149face85f..a4a71ef4ff 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -26,7 +26,7 @@ cwd=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) # Default settings verbose="No" -blddir=$cwd/bld # may overwrite this default with command-line option (below) +blddir=$cwd/tool_bld # may overwrite this default with command-line option (below) # Define what machine to use that's been ported to cime # May overwrite this default with command-line option --machine @@ -73,10 +73,10 @@ while [ $# -gt 0 ]; do shift done -# Create /bld directory +# Create /tool_bld directory echo "cime Machine is: $MACH..." if [ -d "$blddir" ]; then - echo "A /bld directory exists; remove it to do a clean build..." + echo "A /tool_bld directory exists; remove it to do a clean build..." exit 1 fi mkdir $blddir diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index b485e4371c..0df64bde93 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -112,9 +112,9 @@ def main (): runfile.write('# Edit the mpirun command to use the MPI executable ' \ 'on your system and the arguments it requires \n') if machine == 'cheyenne': - output = f"mpiexec_mpt -p \"%g:\" -np {n_p} ./bld/mksurfdata < {namelist_file}" + output = f"mpiexec_mpt -p \"%g:\" -np {n_p} ./tool_bld/mksurfdata < {namelist_file}" elif machine == 'casper': - output = f"mpiexec -np {n_p} ./bld/mksurfdata < {namelist_file}" + output = f"mpiexec -np {n_p} ./tool_bld/mksurfdata < {namelist_file}" runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") From c46720f4cd9addffb8dea553ee2d86e6ef8d5452 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 8 Jun 2022 16:57:25 -0600 Subject: [PATCH 214/614] Update sys test to generate & submit the jobscript that runs mksurfdata ...instead of spelling out the mpi command inside the sys test script which also required different outcomes for different hostnames. Now this is handled exclusively in gen_mksurfdata_jobscript_single.py --- cime_config/SystemTests/mksurfdataesmf.py | 30 ++++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index f78c0766c6..af783850ba 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -35,6 +35,8 @@ def __init__(self, case): time_stamp = datetime.today().strftime("%y%m%d") self._res = '10x15' # see important comment in script's docstring self._model_yr = '1850' + self._jobscript = os.path.join(self._get_caseroot(), + 'mksurfdata_jobscript_single') self._fsurdat_namelist = os.path.join(self._get_caseroot(), f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.namelist') self._fsurdat_nc = os.path.join(self._get_caseroot(), @@ -46,7 +48,7 @@ def build_phase(self, sharedlib_only=False, model_only=False): """ Build executable that will generate fsurdat Generate namelist for generating fsurdat - SKIP Generate jobscript that runs executable + Generate jobscript that runs executable Modify user_nl_clm to point to the generated fsurdat """ # build_phase gets called twice: @@ -60,7 +62,10 @@ def build_phase(self, sharedlib_only=False, model_only=False): 'gen_mksurfdata_build.sh') nml_script_path = os.path.join(self._tool_path, 'gen_mksurfdata_namelist.py') + gen_jobscript_path = os.path.join(self._tool_path, + 'gen_mksurfdata_jobscript_single.py') gen_mksurfdata_namelist = f'{nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}' + gen_mksurfdata_jobscript = f'{gen_jobscript_path} --number-of-nodes 12 --tasks-per-node 12 --namelist-file {self._fsurdat_namelist}' # Rm tool_bld and build executable that will generate fsurdat try: @@ -80,6 +85,16 @@ def build_phase(self, sharedlib_only=False, model_only=False): except subprocess.CalledProcessError as e: sys.exit(f'{e} ERROR RUNNING {gen_mksurfdata_namelist}. DETAILS IN {self._TestStatus_log_path}') + # Generate jobscript that will run the executable + if os.path.exists(self._jobscript): + os.remove(self._jobscript) + try: + subprocess.check_call(gen_mksurfdata_jobscript, shell=True) + except subprocess.CalledProcessError as e: + sys.exit(f'{e} ERROR RUNNING {gen_mksurfdata_jobscript}. DETAILS IN {self._TestStatus_log_path}') + # Change self._jobscript to an executable file + subprocess.check_call(f'chmod a+x {self._jobscript}', shell=True) + # Call this step only once even if the test stops and gets restarted. if not os.path.exists(os.path.join(self._get_caseroot(), 'done_MKSURFDATAESMF_setup.txt')): @@ -95,23 +110,14 @@ def run_phase(self): Run executable to generate fsurdat Submit CTSM run that uses fsurdat just generated """ - # Paths and command strings - executable_path = os.path.join(self._tool_bld, 'mksurfdata') - machine = self._case.get_value("MACH") - if machine == 'cheyenne': - mpi_cmd = f'mpiexec_mpt -np 144 {executable_path} < {self._fsurdat_namelist}' - elif machine == 'casper': - mpi_cmd = f'mpiexec -np 144 {executable_path} < {self._fsurdat_namelist}' - else: - sys.exit(f'machine = {machine} not recognized by this script') # Run executable to generate fsurdat (rm fsurdat if exists) if os.path.exists(self._fsurdat_nc): os.remove(self._fsurdat_nc) try: - subprocess.check_call(mpi_cmd, shell=True) + subprocess.check_call(self._jobscript, shell=True) except subprocess.CalledProcessError as e: - sys.exit(f'{e} ERROR RUNNING {mpi_cmd}; details in {self._TestStatus_log_path}') + sys.exit(f'{e} ERROR RUNNING {self._jobscript}; details in {self._TestStatus_log_path}') # Submit CTSM run that uses fsurdat just generated self.run_indv() From 775ac965f0fdb0219504eb5aa2d9645619066d65 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 8 Jun 2022 17:55:58 -0600 Subject: [PATCH 215/614] Write to file pio_iotype.txt from gen_mksurfdata_build.sh --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index df3c5bddb1..2b5dd0ae43 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -7,14 +7,17 @@ case $hostname in ##cheyenne cheyenne* | r* ) export MACH="cheyenne" + pio_iotype=1 ;; ##casper casper* ) export MACH="casper" + pio_iotype=1 ;; ## Other machines *) export MACH="$hostname" + pio_iotype=2 ;; esac @@ -29,6 +32,9 @@ rm -rf bld mkdir bld cd bld +# Write pio_iotype to file with name pio_iotype.txt +echo $pio_iotype > pio_iotype.txt + # Run the cime configure tool to figure out what modules need to be loaded echo "Run cime configure for machine $MACH..." # You can specify the non-default compiler and mpi-library by adding --compiler and --mpilib settings From 57b936afa847bb1a6057b1c9397fed7bf793ccbd Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 8 Jun 2022 18:14:41 -0600 Subject: [PATCH 216/614] Corretion of a path in gen_mksurfdata_jobscript_single.py --- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index 0df64bde93..30f7e552fe 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -108,7 +108,7 @@ def main (): # Run env_mach_specific.sh to control the machine dependent environment # including the paths to compilers and libraries external to cime such # as netcdf - runfile.write('. ./.env_mach_specific.sh \n') + runfile.write('. ./tool_bld/.env_mach_specific.sh \n') runfile.write('# Edit the mpirun command to use the MPI executable ' \ 'on your system and the arguments it requires \n') if machine == 'cheyenne': From 7bf0bcc2cda538941ae6dc38becd28b89c4f7464 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 10 Jun 2022 13:36:52 -0600 Subject: [PATCH 217/614] mksurfdata now reads pio_iotype from txt file instead of hardwiring --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 2 +- tools/mksurfdata_esmf/src/mksurfdata.F90 | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index 2b5dd0ae43..670c699f57 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -33,7 +33,7 @@ mkdir bld cd bld # Write pio_iotype to file with name pio_iotype.txt -echo $pio_iotype > pio_iotype.txt +echo $pio_iotype > $cwd/pio_iotype.txt # Run the cime configure tool to figure out what modules need to be loaded echo "Run cime configure for machine $MACH..." diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 509e2e16a3..f6e0403dc2 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -131,7 +131,7 @@ program mksurfdata integer :: ier,rcode ! error status ! dynamic land use - integer :: nfdyn ! unit numbers + integer :: nfdyn, nfpio ! unit numbers integer :: ntim ! time sample for dynamic land use integer :: year ! year for dynamic land use integer :: year2 ! year for dynamic land use for harvest file @@ -230,7 +230,21 @@ program mksurfdata ! the following returns pio_iosystem call pio_init(iam, mpicom, max(1,petcount/stride), 0, stride, PIO_REARR_SUBSET, pio_iosystem) - pio_iotype = PIO_IOTYPE_PNETCDF + ! Open txt file + if (root_task) then + write(ndiag,*)' Opening file and reading pio_iotype from txt file with the same name' + open (newunit=nfpio, file='pio_iotype.txt', status='old', & + form='formatted', action='read', iostat=ier) + if (ier /= 0) then + call shr_sys_abort(subname//" failed to open file pio_iotype.txt") + end if + read(nfpio, '(i)', iostat=ier) pio_iotype + if (ier /= 0) then + call shr_sys_abort(subname//" failed to read file pio_iotype.txt") + end if + end if + call mpi_bcast(pio_iotype, 1, MPI_INTEGER, 0, mpicom, ier) + pio_ioformat = PIO_64BIT_DATA call ESMF_LogWrite("finished initializing PIO", ESMF_LOGMSG_INFO) From 8efad79918c14a3d29aeeb00826ca9666af4e17c Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 22 Jun 2022 11:43:04 -0600 Subject: [PATCH 218/614] Small corrections to README --- tools/mksurfdata_esmf/README | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index f2d61e2539..d81fb766fc 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -32,7 +32,7 @@ on your machine you will be able to build the tool there. To get a list of the machines that have been ported to cime: -cd ../../cime/scripts +cd ../../cime/scripts # assumes we are in tools/mksurfdata_esmf ./query_config --machines NOTE: @@ -41,16 +41,14 @@ to be referenced with the env variable PIO which will need to be in the porting for the machine. Currently an independent PIO library is not available on cime ported machines. ======================= -building the executable +building the executable (working in tools/mksurfdata_esmf) ======================= -> cd tools/mksurfdata_esmf > ./gen_mksurfdata_build.sh # For machines with a cime build ======================= running for a single submission: ======================= -> cd ../ # to generate your target namelist: > ./gen_mksurfdata_namelist.py --help # for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: From 7806635a18666fe7583752aeb29d2faa91cd41af Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 22 Jun 2022 14:11:39 -0600 Subject: [PATCH 219/614] Clarify help-string pertaining to --model-mesh-nx & --model-mesh-ny --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 4130071c5e..94171120fd 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -88,7 +88,7 @@ def get_parser(): "--model-mesh-nx", help=""" model mesh [default: %(default)s] - Ignore the --res option and force the model mesh to have this nx + Required when using --model-mesh; force the model mesh to have this nx """, action="store", dest="force_model_mesh_nx", @@ -99,7 +99,7 @@ def get_parser(): "--model-mesh-ny", help=""" model mesh [default: %(default)s] - Ignore the --res option and force the model mesh to have this ny + Required when using --model-mesh; force the model mesh to have this ny """, action="store", dest="force_model_mesh_ny", From de3fb92b63bfdb38381ed195e6657dc5b3c01828 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 30 Jun 2022 18:19:09 -0600 Subject: [PATCH 220/614] Updates based on pylint recommendations --- .../gen_mksurfdata_jobscript_multi.py | 8 +++++--- .../gen_mksurfdata_jobscript_single.py | 6 ++++-- .../gen_mksurfdata_namelist.py | 19 +++++++++++++------ 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 286527e527..b9ddfd06ec 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -98,7 +98,9 @@ def get_parser(): return parser def main (): - + """ + See docstring at the top. + """ # -------------------------- # Obtain input args # -------------------------- @@ -229,8 +231,8 @@ def main (): try: run_cmd = subprocess.run(commands, check=True, capture_output=True) - except subprocess.CalledProcessError as e: - sys.exit(f'{e} ERROR calling {command}') + except subprocess.CalledProcessError as err: + sys.exit(f'{err} ERROR calling {command}') output = run_cmd.stdout.decode('utf-8').strip() namelist = output.split(' ')[-1] print (f"generated namelist {namelist}") diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index 30f7e552fe..b2df569dc7 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -50,7 +50,7 @@ def get_parser(): action="store", dest="machine", required=False, - choices=['cheyenne', 'casper'], # TODO Plan on adding izumi here + choices=['cheyenne', 'casper'], default='cheyenne' ) parser.add_argument( @@ -71,7 +71,9 @@ def get_parser(): return parser def main (): - + """ + See docstring at the top. + """ # -------------------------- # Obtain input args # -------------------------- diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 94171120fd..f42f783e29 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -240,7 +240,9 @@ def get_parser(): return parser def main (): - + """ + See docstring at the top. + """ args = get_parser().parse_args() process_logging_args(args) @@ -454,9 +456,11 @@ def main (): if run_type == 'transient': if ssp_rcp == 'none': - landuse_fname = f"landuse_timeseries_hist_{num_pft}pfts_simyr{start_year}-{end_year}.txt" + landuse_fname = \ + f"landuse_timeseries_hist_{num_pft}pfts_simyr{start_year}-{end_year}.txt" else: - landuse_fname = f"landuse_timeseries_{ssp_rcp}_{num_pft}pfts_CMIP6_simyr{start_year}-{end_year}.txt" + landuse_fname = \ + f"landuse_timeseries_{ssp_rcp}_{num_pft}pfts_CMIP6_simyr{start_year}-{end_year}.txt" with open(landuse_fname, "w", encoding='utf-8') as landuse_file: for year in range(start_year, end_year + 1): @@ -507,10 +511,13 @@ def main (): ssp_rcp_name = ssp_rcp if int(end_year) == int(start_year): fdyndat = '' - prefix = f'surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.' + prefix = \ + f'surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.' else: - fdyndat = f'landuse.timeseries_{res}_{ssp_rcp_name}_{num_pft}_CMIP6_{start_year}-{end_year}_c{time_stamp}.nc' - prefix = f'surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.' + fdyndat = \ + f'landuse.timeseries_{res}_{ssp_rcp_name}_{num_pft}_CMIP6_{start_year}-{end_year}_c{time_stamp}.nc' + prefix = \ + f'surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.' nlfname = f'{prefix}namelist' fsurdat = f'{prefix}nc' From cd09b4b71fb4ed3048bd9c9bafad8cf733b7366a Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 1 Jul 2022 14:32:31 -0600 Subject: [PATCH 221/614] Set pio_iotype explicitly for izumi & hobart in gen_mksurfdata_build.sh ...also explain in README that pio_iotype gets set in gen_mksurfdata_build.sh --- tools/mksurfdata_esmf/README | 12 +++++++++--- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 11 +++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 562ec558ef..de92c04ae7 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -2,13 +2,15 @@ Build Requirements: =================== -mksurfdata_esmf is an distributed memory parallel program (using Message Passing Interface -- MPI) that utilizes -both ESMF (Earth System Modelling Framework) for regridding as well as PIO (Parallel I/O) and NetCDF output. As +mksurfdata_esmf is a distributed memory parallel program (using Message Passing +Interface -- MPI) that utilizes +both ESMF (Earth System Modelling Framework) for regridding as well as Parallel +I/O (PIO) and NetCDF output. As such libraries must be built for the following: 1) MPI 2) NetCDF -3) ParallelIO +3) PIO 4) ESMF In addition for the build: python, bash-shell, CMake and GNU-Make are required @@ -45,6 +47,10 @@ building the executable (working in tools/mksurfdata_esmf) ======================= > ./gen_mksurfdata_build.sh # For machines with a cime build +# Note: The pio_iotype value gets set and written to a simple .txt file +# by this build script. The value depends on your machine. If not running +# on cheyenne, casper, izumi, or hobart, you may need to update this, though +# a default value does get set for other machines. ======================= running for a single submission: diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index 6ea85fcd3b..65e8da8bdd 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -42,7 +42,18 @@ case $hostname in export MACH="casper" pio_iotype=1 ;; + ##izumi + izumi*) + export MACH="izumi" + pio_iotype=2 + ;; + ##Hobart + hobart*) + export MACH="hobart" + pio_iotype=2 + ;; ## Other machines + ## Assumption: pnetcdf is off; therefore, pio_iotype = 2 *) export MACH="$hostname" pio_iotype=2 From b8c25b143b9b1757076eb0170cc81292d960ad47 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Sat, 2 Jul 2022 15:36:13 -0600 Subject: [PATCH 222/614] Add header to pio_iotype.txt; make corrections for sys test to work --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 6 ++++-- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py | 4 ++-- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py | 9 +-------- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 5 ++++- tools/mksurfdata_esmf/src/mksurfdata.F90 | 1 + 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index 65e8da8bdd..b864260b70 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -14,7 +14,7 @@ usage() { echo "[-v|--verbose] " echo " Run in verbose mode" echo "[-b|--blddir ] " - echo " Overwrites default, which is /bld in the same directory as ./gen_mksurfdata_build.sh" + echo " Overwrites default, which is /tool_bld in the same directory as ./gen_mksurfdata_build.sh" echo "[-m|--machine ] " echo " Overwrites default MACH" echo "***********************************************************************" @@ -97,7 +97,9 @@ mkdir $blddir cd $blddir # Write pio_iotype to file with name pio_iotype.txt -echo $pio_iotype > $cwd/pio_iotype.txt +pio_iotype_filepath=../pio_iotype.txt # one up from /tool_bld +echo 'VALUE OF pio_iotype WRITTEN BY gen_mksurfdata_build.sh AND USED BY mksurfdata (i.e. THE FORTRAN EXECUTABLE):' > $pio_iotype_filepath +echo $pio_iotype >> $pio_iotype_filepath # Run the cime configure tool to figure out what modules need to be loaded echo "Run cime configure for machine $MACH..." diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 145d8ac03d..5d4cf6bfdb 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -231,8 +231,8 @@ def main (): try: run_cmd = subprocess.run(commands, check=True, capture_output=True) - except subprocess.CalledProcessError as err: - sys.exit(f'{err} ERROR calling {command}') + except subprocess.CalledProcessError as e: + sys.exit(f'{e} ERROR calling {command}') output = run_cmd.stdout.decode('utf-8').strip() namelist = output.split(' ')[-1] print (f"generated namelist {namelist}") diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index bf6c022c03..1dea41b1e1 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -4,6 +4,7 @@ mksurfdata executable to generate a single fsurdat file. For detailed instructions, see README. """ +import os import sys import argparse @@ -95,7 +96,6 @@ def main (): runfile.write('#!/bin/bash \n') runfile.write('# Edit the batch directives for your batch system \n') runfile.write('# Below are the batch directives used on cheyenne \n') - runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -N mksurfdata \n') runfile.write('#PBS -j oe \n') runfile.write('#PBS -l walltime=30:00 \n') @@ -112,13 +112,6 @@ def main (): runfile.write(f'#PBS -l nodes={number_of_nodes}:ppn={tasks_per_node} -r n \n') runfile.write("\n") - tool_path = os.path.dirname(os.path.abspath(__file__)) - - runfile.write(f'cd {tool_path} \n') - runfile.write("\n") - runfile.write('. ./tool_bld/.env_mach_specific.sh \n') - runfile.write("\n") - n_p = int(tasks_per_node) * int(number_of_nodes) # Run env_mach_specific.sh to control the machine dependent environment diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 7147ef5e28..f067bd1723 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -529,8 +529,11 @@ def main (): # The "git -C" option permits a system test to run this tool from # elsewhere while running the git command from the tool_path gitdescribe = subprocess.check_output(git_desc_cmd, shell=True).strip() - except subprocess.CalledProcessError: + except subprocess.CalledProcessError as e: # In case the "git -C" option is unavailable, as on casper (2022/5/24) + # Still, this does NOT allow the system test to work on machines + # without git -C + logger.info('git -C option unavailable on casper as of 2022/7/2', e) gitdescribe = subprocess.check_output('git describe', shell=True).strip() gitdescribe = gitdescribe.decode('utf-8') diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index f6e0403dc2..d3228b06c1 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -238,6 +238,7 @@ program mksurfdata if (ier /= 0) then call shr_sys_abort(subname//" failed to open file pio_iotype.txt") end if + read(nfpio,*) ! skip file header read(nfpio, '(i)', iostat=ier) pio_iotype if (ier /= 0) then call shr_sys_abort(subname//" failed to read file pio_iotype.txt") From 02e4247e47a03114875dcf2c0effa490cc973028 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Sat, 2 Jul 2022 17:43:43 -0600 Subject: [PATCH 223/614] Corrections for mksurfdata_esmf to run again on izumi --- .../gen_mksurfdata_jobscript_single.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index 1dea41b1e1..2112194ece 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -98,21 +98,28 @@ def main (): runfile.write('# Below are the batch directives used on cheyenne \n') runfile.write('#PBS -N mksurfdata \n') runfile.write('#PBS -j oe \n') - runfile.write('#PBS -l walltime=30:00 \n') if machine == 'cheyenne': + runfile.write('#PBS -l walltime=30:00 \n') runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -q regular \n') runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") elif machine == 'casper': + runfile.write('#PBS -l walltime=1:00:00 \n') runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -q casper \n') runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=12:mpiprocs={tasks_per_node}:mem=80GB \n") elif machine == 'izumi': + runfile.write('#PBS -l walltime=2:00:00 \n') runfile.write('#PBS -q medium \n') - runfile.write(f'#PBS -l nodes={number_of_nodes}:ppn={tasks_per_node} -r n \n') + runfile.write(f'#PBS -l nodes={number_of_nodes}:ppn={tasks_per_node},mem=555GB -r n \n') + tool_path = os.path.dirname(os.path.abspath(__file__)) + runfile.write("\n") + runfile.write(f'cd {tool_path} \n') + runfile.write("\n") n_p = int(tasks_per_node) * int(number_of_nodes) + mksurfdata_path = './tool_bld/mksurfdata' # Run env_mach_specific.sh to control the machine dependent environment # including the paths to compilers and libraries external to cime such @@ -121,11 +128,11 @@ def main (): runfile.write('# Edit the mpirun command to use the MPI executable ' \ 'on your system and the arguments it requires \n') if machine == 'cheyenne': - output = f"mpiexec_mpt -p \"%g:\" -np {n_p} ./tool_bld/mksurfdata < {namelist_file}" + output = f"mpiexec_mpt -p \"%g:\" -np {n_p} {mksurfdata_path} < {namelist_file}" elif machine == 'casper': - output = f"mpiexec -np {n_p} ./tool_bld/mksurfdata < {namelist_file}" + output = f"mpiexec -np {n_p} {mksurfdata_path} < {namelist_file}" elif machine == 'izumi': - output = f"mpirun -np {n_p} ./tool_bld/mksurfdata < {namelist_file}" + output = f"mpiexec --machinefile $PBS_NODEFILE -n {n_p} --prepend-rank {mksurfdata_path} < {namelist_file}" runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") From 5b575dc21e3483ad8fbb260f7bad08c7c3afc580 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 5 Jul 2022 18:40:45 -0600 Subject: [PATCH 224/614] Add consistency checks for mesh_nx and mesh_ny --- .../gen_mksurfdata_namelist.py | 58 ++++++++++++++----- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index f067bd1723..f5cdcd47d3 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -11,6 +11,7 @@ import textwrap import subprocess from datetime import datetime +import netCDF4 _CTSM_PYTHON = os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, @@ -77,34 +78,38 @@ def get_parser(): "--model-mesh", help=""" model mesh [default: %(default)s] - Ignore the --res option and force the model mesh file to be this input + Ignore --res and use --model-mesh to be this file """, action="store", dest="force_model_mesh_file", required=False, - default="none", + default=None, ) parser.add_argument( "--model-mesh-nx", help=""" model mesh [default: %(default)s] - Required when using --model-mesh; force the model mesh to have this nx + Required when using --model-mesh: set nx to the grid's number of + columns; expect nx x ny = elementCount for consistency with the + model mesh """, action="store", dest="force_model_mesh_nx", required=False, - default="-999", + default=None ) parser.add_argument( "--model-mesh-ny", help=""" model mesh [default: %(default)s] - Required when using --model-mesh; force the model mesh to have this ny + Required when using --model-mesh: set ny to the grid's number of + rows; expect nx x ny = elementCount for consistency with the model + mesh """, action="store", dest="force_model_mesh_ny", required=False, - default="-999", + default=None ) parser.add_argument( "--glc-nec", @@ -274,8 +279,33 @@ def main (): else: hires_pft = 'off' - if force_model_mesh_file != 'none': - res = force_model_mesh_nx + 'x' + force_model_mesh_ny + if force_model_mesh_file is not None: + mesh_file = netCDF4.Dataset(force_model_mesh_file, 'r') + element_count = mesh_file.dimensions['elementCount'].size + if 'origGridDims' in mesh_file.variables: + orig_grid_dims = mesh_file.variables['origGridDims'] + force_model_mesh_nx = orig_grid_dims[0] + force_model_mesh_ny = orig_grid_dims[1] + mesh_file.close() + important_msg = 'Found data for force_model_mesh_nx and ' \ + 'force_model_mesh_ny in the mesh file so ' \ + 'IGNORING ANY USER-ENTERED VALUES.' + logger.info(important_msg) + elif force_model_mesh_nx is None or force_model_mesh_ny is None: + error_msg = 'ERROR: You set --model-mesh but the file does not ' \ + 'contain the variable origGridDims, so you MUST ALSO ' \ + 'SET --model-mesh-nx AND --model-mesh-ny' + sys.exit(error_msg) + + # using force_model_mesh_nx and force_model_mesh_ny either from the + # mesh file (see previous if statement) or the user-entered values + if element_count != int(force_model_mesh_nx) * int(force_model_mesh_ny): + error_msg = 'ERROR: The product of ' \ + '--model-mesh-nx x --model-mesh-ny must equal ' \ + 'exactly elementCount in --model-mesh' + sys.exit(error_msg) + else: + res = f'{force_model_mesh_nx}x{force_model_mesh_ny}' hostname = os.getenv("HOSTNAME") logname = os.getenv("LOGNAME") @@ -433,7 +463,7 @@ def main (): if child2.tag == 'ny': rawdata_files["mksrf_fgrid_mesh_ny"] = child2.text - if force_model_mesh_file == 'none' and len(model_mesh) == 0: + if not model_mesh and force_model_mesh_file is None: valid_grids = [] for child1 in root: # this is domain tag for _, value in child1.attrib.items(): @@ -558,14 +588,14 @@ def main (): # ------------------- # raw input data # ------------------- - if force_model_mesh_file != 'none': - mksrf_fgrid_mesh_nx = force_model_mesh_nx - mksrf_fgrid_mesh_ny = force_model_mesh_ny - mksrf_fgrid_mesh = force_model_mesh_file - else: + if force_model_mesh_file is None: mksrf_fgrid_mesh_nx = rawdata_files["mksrf_fgrid_mesh_nx"] mksrf_fgrid_mesh_ny = rawdata_files["mksrf_fgrid_mesh_ny"] mksrf_fgrid_mesh = rawdata_files["mksrf_fgrid_mesh"] + else: + mksrf_fgrid_mesh_nx = force_model_mesh_nx + mksrf_fgrid_mesh_ny = force_model_mesh_ny + mksrf_fgrid_mesh = force_model_mesh_file nlfile.write( f" mksrf_fgrid_mesh = \'{mksrf_fgrid_mesh}\' \n") nlfile.write( f" mksrf_fgrid_mesh_nx = {mksrf_fgrid_mesh_nx} \n") nlfile.write( f" mksrf_fgrid_mesh_ny = {mksrf_fgrid_mesh_ny} \n") From e4cd071dcf463351ba726a3c497239079dc7adcc Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 6 Jul 2022 11:40:31 -0600 Subject: [PATCH 225/614] A couple of new comments in gen_mksurfdata_namelist.py --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index f5cdcd47d3..ca1a6938d1 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -280,6 +280,7 @@ def main (): hires_pft = 'off' if force_model_mesh_file is not None: + # open mesh_file to read element_count and, if available, orig_grid_dims mesh_file = netCDF4.Dataset(force_model_mesh_file, 'r') element_count = mesh_file.dimensions['elementCount'].size if 'origGridDims' in mesh_file.variables: @@ -289,7 +290,7 @@ def main (): mesh_file.close() important_msg = 'Found data for force_model_mesh_nx and ' \ 'force_model_mesh_ny in the mesh file so ' \ - 'IGNORING ANY USER-ENTERED VALUES.' + 'IGNORING ANY CORRESPONDING USER-ENTERED VALUES.' logger.info(important_msg) elif force_model_mesh_nx is None or force_model_mesh_ny is None: error_msg = 'ERROR: You set --model-mesh but the file does not ' \ From f97f5a7519e312994106bdf15ba46eee477f4c07 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 6 Jul 2022 13:08:07 -0600 Subject: [PATCH 226/614] Made --res required and added better error checking for it --- .../gen_mksurfdata_namelist.py | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index ca1a6938d1..7bd9e824d0 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -67,11 +67,12 @@ def get_parser(): help=""" model resolution [default: %(default)s] To see available supported resolutions, simply invoke this command - with a --res unknown option + with a --res unknown option. For custom resolutions, provide a grid + name of your choosing to be used in the name of the fsurdat file. """, action="store", dest="res", - required=False, + required=True, default="4x5", ) parser.add_argument( @@ -305,8 +306,6 @@ def main (): '--model-mesh-nx x --model-mesh-ny must equal ' \ 'exactly elementCount in --model-mesh' sys.exit(error_msg) - else: - res = f'{force_model_mesh_nx}x{force_model_mesh_ny}' hostname = os.getenv("HOSTNAME") logname = os.getenv("LOGNAME") @@ -469,9 +468,19 @@ def main (): for child1 in root: # this is domain tag for _, value in child1.attrib.items(): valid_grids.append(value) - error_msg = f'ERROR: invalid input res {res};' \ - f'valid grid values are {valid_grids}' - sys.exit(error_msg) + if res in valid_grids: + error_msg = 'ERROR: You have requested a valid grid for which ' \ + '../../ccs_config/component_grids_nuopc.xml does not include a mesh ' \ + 'file. For a regular regional or 1x1 grid, you may generate the ' \ + 'fsurdat file using the subset_data tool instead. Alternatively ' \ + 'and definitely for curvilinear grids, you may generate ' \ + 'a mesh file using the workflow currently (2022/7/6) described in ' \ + 'https://github.com/ESCOMP/CTSM/issues/1773#issuecomment-1163432584' + sys.exit(error_msg) + else: + error_msg = f'ERROR: invalid input res {res}; ' \ + f'valid grid values are {valid_grids}' + sys.exit(error_msg) # Determine num_pft if nocrop_flag: From e9614509de56633611ffc1fd9cee15f50637aedb Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 6 Jul 2022 17:44:19 -0600 Subject: [PATCH 227/614] Removed default --res from parser.add_argument since now it's required --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 7bd9e824d0..e49bdfde37 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -65,7 +65,7 @@ def get_parser(): parser.add_argument( "--res", help=""" - model resolution [default: %(default)s] + Model resolution (required) To see available supported resolutions, simply invoke this command with a --res unknown option. For custom resolutions, provide a grid name of your choosing to be used in the name of the fsurdat file. @@ -73,7 +73,6 @@ def get_parser(): action="store", dest="res", required=True, - default="4x5", ) parser.add_argument( "--model-mesh", From fb87525e7c6e1ae8092afbe6d643239e22f000a9 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 8 Jul 2022 17:43:34 -0600 Subject: [PATCH 228/614] Get mpirun command from env_mach_specific.xml instead of hardwiring --- .../gen_mksurfdata_jobscript_single.py | 67 +++++++++++++------ 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index 2112194ece..8c9c9c9459 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -7,22 +7,35 @@ import os import sys import argparse +import logging + +_CTSM_PYTHON = os.path.join(os.path.dirname(os.path.realpath(__file__)), + os.pardir, + os.pardir, + 'python') +sys.path.insert(1, _CTSM_PYTHON) + +from ctsm import add_cime_to_path # pylint: disable=unused-import +from ctsm.ctsm_logging import setup_logging_pre_config, add_logging_args, process_logging_args +from CIME.XML.env_mach_specific import EnvMachSpecific +from CIME.BuildTools.configure import FakeCase + +logger = logging.getLogger(__name__) def get_parser(): """ Get parser object for this script. """ + # set up logging allowing user control + setup_logging_pre_config() + parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter ) parser.print_usage = parser.print_help + add_logging_args(parser) - parser.add_argument( - '-v', '--verbose', - help="increase output verbosity", - action="store_true", - ) parser.add_argument( "--account", help="""account number (default: %(default)s)""", @@ -82,6 +95,7 @@ def main (): # Obtain input args # -------------------------- args = get_parser().parse_args() + process_logging_args(args) namelist_file = args.namelist_file jobscript_file = args.jobscript_file number_of_nodes = args.number_of_nodes @@ -90,25 +104,28 @@ def main (): account = args.account # -------------------------- - # Write run script + # Write run script (part 1) # -------------------------- with open(jobscript_file, "w",encoding='utf-8') as runfile: runfile.write('#!/bin/bash \n') runfile.write('# Edit the batch directives for your batch system \n') - runfile.write('# Below are the batch directives used on cheyenne \n') + runfile.write(f'# Below are default batch directives for {machine} \n') runfile.write('#PBS -N mksurfdata \n') runfile.write('#PBS -j oe \n') if machine == 'cheyenne': + attribs = {'mpilib': 'default'} runfile.write('#PBS -l walltime=30:00 \n') runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -q regular \n') runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") elif machine == 'casper': + attribs = {'mpilib': 'default'} runfile.write('#PBS -l walltime=1:00:00 \n') runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -q casper \n') runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=12:mpiprocs={tasks_per_node}:mem=80GB \n") elif machine == 'izumi': + attribs = {'mpilib': 'mvapich2'} runfile.write('#PBS -l walltime=2:00:00 \n') runfile.write('#PBS -q medium \n') runfile.write(f'#PBS -l nodes={number_of_nodes}:ppn={tasks_per_node},mem=555GB -r n \n') @@ -118,22 +135,34 @@ def main (): runfile.write("\n") - n_p = int(tasks_per_node) * int(number_of_nodes) - mksurfdata_path = './tool_bld/mksurfdata' + # -------------------------- + # Obtain mpirun command from env_mach_specific.xml + # -------------------------- + bld_path = './tool_bld' + ems_file = EnvMachSpecific(bld_path, standalone_configure=True) + fake_case = FakeCase(compiler=None, mpilib=attribs['mpilib'], + debug=False, comp_interface=None) + total_tasks = int(tasks_per_node) * int(number_of_nodes) + cmd = ems_file.get_mpirun(fake_case, attribs, job='name', + overrides = {"total_tasks" : total_tasks,}) + executable = f'{cmd[0]} {" ".join(cmd[1])}'.replace('ENV{', ''). \ + replace('}', '') + + mksurfdata_path = os.path.join(bld_path, 'mksurfdata') + env_mach_path = os.path.join(bld_path, '.env_mach_specific.sh') - # Run env_mach_specific.sh to control the machine dependent environment - # including the paths to compilers and libraries external to cime such - # as netcdf - runfile.write('. ./tool_bld/.env_mach_specific.sh \n') + # -------------------------- + # Write run script (part 2) + # -------------------------- + runfile.write('# Run env_mach_specific.sh to control the machine ' \ + 'dependent environment including the paths to ' \ + 'compilers and libraries external to cime such as netcdf') + runfile.write(f'\n. {env_mach_path}\n') runfile.write('# Edit the mpirun command to use the MPI executable ' \ 'on your system and the arguments it requires \n') - if machine == 'cheyenne': - output = f"mpiexec_mpt -p \"%g:\" -np {n_p} {mksurfdata_path} < {namelist_file}" - elif machine == 'casper': - output = f"mpiexec -np {n_p} {mksurfdata_path} < {namelist_file}" - elif machine == 'izumi': - output = f"mpiexec --machinefile $PBS_NODEFILE -n {n_p} --prepend-rank {mksurfdata_path} < {namelist_file}" + output = f'{executable} {mksurfdata_path} < {namelist_file}' runfile.write(f"{output} \n") + logger.info(f'run command is {output} ') print (f"Successfully created jobscript {jobscript_file}") sys.exit(0) From df7d0212acadc6aa2b93652cd73bc945d21ed6fb Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 11 Jul 2022 13:01:14 -0600 Subject: [PATCH 229/614] pylint recommendations --- python/ctsm/mksurfdata_download_input_data.py | 6 ++- .../gen_mksurfdata_jobscript_single.py | 5 +- .../gen_mksurfdata_namelist.py | 51 ++++++++++++------- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/python/ctsm/mksurfdata_download_input_data.py b/python/ctsm/mksurfdata_download_input_data.py index 25df41e969..a38b4935e3 100644 --- a/python/ctsm/mksurfdata_download_input_data.py +++ b/python/ctsm/mksurfdata_download_input_data.py @@ -76,8 +76,10 @@ def _commandline_args(): return args def _create_input_data_list(rundir): - with open(os.path.join(rundir, 'surfdata.namelist')) as namelist: - with open(os.path.join(rundir, '.input_data_list'), 'w') as input_data_list: + with open(os.path.join(rundir, 'surfdata.namelist'), + encoding='utf-8') as namelist: + with open(os.path.join(rundir, '.input_data_list'), 'w', + encoding='utf-8') as input_data_list: for line in namelist: if re.search(_FILENAME, line): # Remove quotes from filename, then output this line diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index 8c9c9c9459..dbb7279d9e 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -123,7 +123,8 @@ def main (): runfile.write('#PBS -l walltime=1:00:00 \n') runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -q casper \n') - runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=12:mpiprocs={tasks_per_node}:mem=80GB \n") + runfile.write(f'#PBS -l select={number_of_nodes}:ncpus=12:' \ + f'mpiprocs={tasks_per_node}:mem=80GB \n') elif machine == 'izumi': attribs = {'mpilib': 'mvapich2'} runfile.write('#PBS -l walltime=2:00:00 \n') @@ -162,7 +163,7 @@ def main (): 'on your system and the arguments it requires \n') output = f'{executable} {mksurfdata_path} < {namelist_file}' runfile.write(f"{output} \n") - logger.info(f'run command is {output} ') + logger.info('run command is %s', output) print (f"Successfully created jobscript {jobscript_file}") sys.exit(0) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index e49bdfde37..b25e3ac8d6 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -423,16 +423,21 @@ def main (): rawdata_files[child1.tag] = os.path.join(input_path, item.text) if '%y' not in rawdata_files[child1.tag]: if not os.path.isfile(rawdata_files[child1.tag]): - print(f"WARNING: input data file {rawdata_files[child1.tag]} for {child1.tag} does not exist") - print(f"WARNING: run ./download_input_data to try TO OBTAIN MISSING FILES") + print('WARNING: input data file ' \ + f'{rawdata_files[child1.tag]} for {child1.tag} ' \ + 'does not exist') + print('WARNING: run ./download_input_data to try TO ' \ + 'OBTAIN MISSING FILES') _must_run_download_input_data = True if item.tag == 'mesh_filename': new_key = f"{child1.tag}_mesh" rawdata_files[new_key] = os.path.join(input_path, item.text) if not os.path.isfile(rawdata_files[new_key]): - print(f"WARNING: input mesh file {rawdata_files[new_key]} does not exist") - print(f"WARNING: run ./download_input_data to try TO OBTAIN MISSING FILES") + print('WARNING: input mesh file ' \ + f'{rawdata_files[new_key]} does not exist') + print('WARNING: run ./download_input_data to try TO ' \ + 'OBTAIN MISSING FILES') _must_run_download_input_data = True if item.tag == 'lake_filename': @@ -518,17 +523,23 @@ def main (): landuse_input_fnam2 = file2.replace("%y", year_str) landuse_input_fnam3 = file3.replace("%y", year_str) if not os.path.isfile(landuse_input_fname): - print(f"WARNING: landunit_input_fname: {landuse_input_fname} does not exist") - print(f"WARNING: run ./download_input_data to try TO OBTAIN MISSING FILES") - _must_run_download_input_data = True + print('WARNING: landunit_input_fname: ' \ + f'{landuse_input_fname} does not exist') + print('WARNING: run ./download_input_data to try TO ' \ + 'OBTAIN MISSING FILES') + _must_run_download_input_data = True if not os.path.isfile(landuse_input_fnam2): - print(f"WARNING: landunit_input_fnam2: {landuse_input_fnam2} does not exist") - print(f"WARNING: run ./download_input_data to try TO OBTAIN MISSING FILES") - _must_run_download_input_data = True + print('WARNING: landunit_input_fnam2: ' \ + f'{landuse_input_fnam2} does not exist') + print('WARNING: run ./download_input_data to try TO ' \ + 'OBTAIN MISSING FILES') + _must_run_download_input_data = True if not os.path.isfile(landuse_input_fnam3): - print(f"WARNING: landunit_input_fnam3: {landuse_input_fnam3} does not exist") - print(f"WARNING: run ./download_input_data to try TO OBTAIN MISSING FILES") - _must_run_download_input_data = True + print('WARNING: landunit_input_fnam3: ' \ + f'{landuse_input_fnam3} does not exist') + print('WARNING: run ./download_input_data to try TO ' \ + 'OBTAIN MISSING FILES') + _must_run_download_input_data = True # -- Each line is written twice in the original perl code: landuse_line = f"{landuse_input_fname:<196}{year_str}\n" @@ -572,7 +583,7 @@ def main (): # In case the "git -C" option is unavailable, as on casper (2022/5/24) # Still, this does NOT allow the system test to work on machines # without git -C - logger.info('git -C option unavailable on casper as of 2022/7/2', e) + logger.info('git -C option unavailable on casper as of 2022/7/2 %s', e) gitdescribe = subprocess.check_output('git describe', shell=True).strip() gitdescribe = gitdescribe.decode('utf-8') @@ -631,12 +642,16 @@ def main (): if '%y' in mksrf_fhrvtyp: mksrf_fhrvtyp = mksrf_fhrvtyp.replace("%y",str(start_year)) if not os.path.isfile(mksrf_fvegtyp): - print(f"WARNING: input mksrf_fvegtyp file {mksrf_fvegtyp} does not exist") - print(f"WARNING: run ./download_input_data to try TO OBTAIN MISSING FILES") + print('WARNING: input mksrf_fvegtyp file ' \ + f'{mksrf_fvegtyp} does not exist') + print('WARNING: run ./download_input_data to try TO ' \ + 'OBTAIN MISSING FILES') _must_run_download_input_data = True if not os.path.isfile(mksrf_fhrvtyp): - print(f"WARNING: input mksrf_fhrvtyp file {mksrf_fhrvtyp} does not exist") - print(f"WARNING: run ./download_input_data to try TO OBTAIN MISSING FILES") + print('WARNING: input mksrf_fhrvtyp file ' \ + f'{mksrf_fhrvtyp} does not exist') + print('WARNING: run ./download_input_data to try TO ' \ + 'OBTAIN MISSING FILES') _must_run_download_input_data = True nlfile.write( f" mksrf_fvegtyp = \'{mksrf_fvegtyp}\' \n") nlfile.write( f" mksrf_fvegtyp_mesh = \'{mksrf_fvegtyp_mesh}\' \n") From 5088869e8f2f90d4719c0b1b16d2428e7ff1e071 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 13 Jul 2022 17:02:56 -0600 Subject: [PATCH 230/614] Improve error check and comments --- .../gen_mksurfdata_jobscript_single.py | 8 ++++++ .../gen_mksurfdata_namelist.py | 26 +++++++++++-------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index dbb7279d9e..01e290a8c5 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -140,12 +140,20 @@ def main (): # Obtain mpirun command from env_mach_specific.xml # -------------------------- bld_path = './tool_bld' + # Get the ems_file object with standalone_configure=True + # and the fake_case object with mpilib=attribs['mpilib'] + # so as to use the get_mpirun function pointing to fake_case ems_file = EnvMachSpecific(bld_path, standalone_configure=True) fake_case = FakeCase(compiler=None, mpilib=attribs['mpilib'], debug=False, comp_interface=None) total_tasks = int(tasks_per_node) * int(number_of_nodes) cmd = ems_file.get_mpirun(fake_case, attribs, job='name', overrides = {"total_tasks" : total_tasks,}) + # cmd is a tuple: + # cmd[0] contains the mpirun command (eg mpirun, mpiexe, etc) as string + # cmd[1] contains a list of strings that we append as options to cmd[0] + # The replace function removes unnecessary characters that appear in + # some such options executable = f'{cmd[0]} {" ".join(cmd[1])}'.replace('ENV{', ''). \ replace('}', '') diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index b25e3ac8d6..6108d034f8 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -285,16 +285,18 @@ def main (): element_count = mesh_file.dimensions['elementCount'].size if 'origGridDims' in mesh_file.variables: orig_grid_dims = mesh_file.variables['origGridDims'] - force_model_mesh_nx = orig_grid_dims[0] - force_model_mesh_ny = orig_grid_dims[1] - mesh_file.close() - important_msg = 'Found data for force_model_mesh_nx and ' \ - 'force_model_mesh_ny in the mesh file so ' \ - 'IGNORING ANY CORRESPONDING USER-ENTERED VALUES.' - logger.info(important_msg) + if int(force_model_mesh_nx) == orig_grid_dims[0] and \ + int(force_model_mesh_ny) == orig_grid_dims[1]: + mesh_file.close() + else: + error_msg = 'ERROR: Found variable origGridDims in ' \ + f'{force_model_mesh_file} with values ' \ + f'{orig_grid_dims[:]} that do not agree with the ' \ + 'user-entered mesh_nx and mesh_ny values of ' \ + f'{[force_model_mesh_nx, force_model_mesh_ny]}.' + sys.exit(error_msg) elif force_model_mesh_nx is None or force_model_mesh_ny is None: - error_msg = 'ERROR: You set --model-mesh but the file does not ' \ - 'contain the variable origGridDims, so you MUST ALSO ' \ + error_msg = 'ERROR: You set --model-mesh so you MUST ALSO ' \ 'SET --model-mesh-nx AND --model-mesh-ny' sys.exit(error_msg) @@ -478,8 +480,10 @@ def main (): 'file. For a regular regional or 1x1 grid, you may generate the ' \ 'fsurdat file using the subset_data tool instead. Alternatively ' \ 'and definitely for curvilinear grids, you may generate ' \ - 'a mesh file using the workflow currently (2022/7/6) described in ' \ - 'https://github.com/ESCOMP/CTSM/issues/1773#issuecomment-1163432584' + 'a mesh file using the workflow currently (2022/7) described in ' \ + 'https://github.com/ESCOMP/CTSM/issues/1773#issuecomment-1163432584' \ + 'TODO Reminder to ultimately place these workflow instructions in ' \ + "the User's Guide." sys.exit(error_msg) else: error_msg = f'ERROR: invalid input res {res}; ' \ From 146b6bd6df65c9d08ce379416aec953424e441a4 Mon Sep 17 00:00:00 2001 From: Keith Oleson Date: Fri, 16 Sep 2022 08:43:31 -0600 Subject: [PATCH 231/614] Implement GaoOneil raw urban datasets into mksurfdata_esmf. --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- .../namelist_defaults_ctsm_tools.xml | 19 +++++++- src/main/clm_initializeMod.F90 | 6 ++- src/main/clm_varpar.F90 | 5 ++- src/main/initVerticalMod.F90 | 5 +++ src/main/surfrdMod.F90 | 43 +++++++++++++++++++ .../gen_mksurfdata_namelist.xml | 30 +++++++++---- 7 files changed, 94 insertions(+), 16 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 2562f9ce88..2d645bbf92 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1725,7 +1725,7 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts 2106 lnd/clm2/urbandata/CLM50_tbuildmax_Oleson_2016_0.9x1.25_simyr1849-2106_c160923.nc +>/glade/p/cgd/tss/people/oleson/urban_sfcdata/Feddema_urban_data_080410/HIGH_RES_VERSION2/URBAN_PROPERTIES_THESIS_TOOL/JUN_22_2018/CLM50_tbuildmax_Oleson_2016_0.9x1.25_simyr1849-2106_c200605.nc lnd/clm2/urbandata/CLM50_tbuildmax_Oleson_2016_0.9x1_ESMFmesh_cdf5_100621.nc diff --git a/bld/namelist_files/namelist_defaults_ctsm_tools.xml b/bld/namelist_files/namelist_defaults_ctsm_tools.xml index ff309c6fc9..44d2580b18 100644 --- a/bld/namelist_files/namelist_defaults_ctsm_tools.xml +++ b/bld/namelist_files/namelist_defaults_ctsm_tools.xml @@ -254,8 +254,23 @@ attributes from the config_cache.xml file (with keys converted to upper-case). >lnd/clm2/rawdata/mksrf_vocef_0.5x0.5_simyr2000.c110531.nc -lnd/clm2/rawdata/mksrf_urban_0.05x0.05_simyr2000.c120621.nc +/glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_2000_c20220910.nc + +/glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/HistoricalPlusSSP5/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_2000_c20220910.nc + +/glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/HistoricalPlusSSP5/urban_properties_GaoOneil_05deg_ThreeClass_ssp2_2000_c20220910.nc + +/glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/HistoricalPlusSSP5/urban_properties_GaoOneil_05deg_ThreeClass_ssp3_2000_c20220910.nc + +/glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/HistoricalPlusSSP5/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_2000_c20220910.nc + +/glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/HistoricalPlusSSP5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_2000_c20220910.nc lnd/clm2/rawdata/mksrf_urban_0.05x0.05_zerourbanpct.c181014.nc diff --git a/src/main/clm_initializeMod.F90 b/src/main/clm_initializeMod.F90 index 73ec4ffd58..b01f2aa599 100644 --- a/src/main/clm_initializeMod.F90 +++ b/src/main/clm_initializeMod.F90 @@ -40,6 +40,7 @@ module clm_initializeMod public :: initialize2 ! Phase two initialization integer :: actual_numcft ! numcft from sfc dataset + integer :: actual_nlevurb ! nlevurb from sfc dataset !----------------------------------------------------------------------- contains @@ -55,7 +56,7 @@ subroutine initialize1(dtime) use clm_varcon , only: clm_varcon_init use landunit_varcon , only: landunit_varcon_init use clm_varctl , only: fsurdat, version - use surfrdMod , only: surfrd_get_num_patches + use surfrdMod , only: surfrd_get_num_patches, surfrd_get_nlevurb use controlMod , only: control_init, control_print, NLFilename use ncdio_pio , only: ncd_pio_init use initGridCellsMod , only: initGridCells @@ -97,7 +98,8 @@ subroutine initialize1(dtime) call control_init(dtime) call ncd_pio_init() call surfrd_get_num_patches(fsurdat, actual_maxsoil_patches, actual_numcft) - call clm_varpar_init(actual_maxsoil_patches, actual_numcft) + call surfrd_get_nlevurb(fsurdat, actual_nlevurb) + call clm_varpar_init(actual_maxsoil_patches, actual_numcft, actual_nlevurb) call decomp_cascade_par_init( NLFilename ) call clm_varcon_init( IsSimpleBuildTemp() ) call landunit_varcon_init() diff --git a/src/main/clm_varpar.F90 b/src/main/clm_varpar.F90 index e5d296bb52..75f0de4209 100644 --- a/src/main/clm_varpar.F90 +++ b/src/main/clm_varpar.F90 @@ -110,7 +110,7 @@ module clm_varpar contains !------------------------------------------------------------------------------ - subroutine clm_varpar_init(actual_maxsoil_patches, actual_numcft) + subroutine clm_varpar_init(actual_maxsoil_patches, actual_numcft, actual_nlevurb) ! ! !DESCRIPTION: ! Initialize module variables @@ -119,6 +119,7 @@ subroutine clm_varpar_init(actual_maxsoil_patches, actual_numcft) implicit none integer, intent(in) :: actual_maxsoil_patches ! value from surface dataset integer, intent(in) :: actual_numcft ! Actual number of crops + integer, intent(in) :: actual_nlevurb ! nlevurb from surface dataset ! ! !LOCAL VARIABLES: ! @@ -159,7 +160,7 @@ subroutine clm_varpar_init(actual_maxsoil_patches, actual_numcft) max_patch_per_col= max(maxsoil_patches, actual_numcft, maxpatch_urb) nlevsoifl = 10 - nlevurb = 5 + nlevurb = actual_nlevurb if ( masterproc ) write(iulog, *) 'soil_layerstruct_predefined varpar ', soil_layerstruct_predefined if ( masterproc ) write(iulog, *) 'soil_layerstruct_userdefined varpar ', soil_layerstruct_userdefined diff --git a/src/main/initVerticalMod.F90 b/src/main/initVerticalMod.F90 index 1bf79706f9..134c5edc1e 100644 --- a/src/main/initVerticalMod.F90 +++ b/src/main/initVerticalMod.F90 @@ -283,6 +283,11 @@ subroutine initVertical(bounds, glc_behavior, thick_wall, thick_roof) write(iulog, *) 'dzsoi_decomp: ',dzsoi_decomp end if + if (nlevurb == ispval) then + call shr_sys_abort(' ERROR nlevurb has not been defined '//& + errMsg(sourcefile, __LINE__)) + end if + if (nlevurb > 0) then allocate(zurb_wall(bounds%begl:bounds%endl,nlevurb), & zurb_roof(bounds%begl:bounds%endl,nlevurb), & diff --git a/src/main/surfrdMod.F90 b/src/main/surfrdMod.F90 index 27da9e24df..057a199e25 100644 --- a/src/main/surfrdMod.F90 +++ b/src/main/surfrdMod.F90 @@ -29,6 +29,7 @@ module surfrdMod ! !PUBLIC MEMBER FUNCTIONS: public :: surfrd_get_data ! Read surface dataset and determine subgrid weights public :: surfrd_get_num_patches ! Read surface dataset to determine maxsoil_patches and numcft + public :: surfrd_get_nlevurb ! Read surface dataset to determine nlevurb ! !PRIVATE MEMBER FUNCTIONS: private :: surfrd_special ! Read the special landunits @@ -300,6 +301,48 @@ subroutine surfrd_get_num_patches (lfsurdat, actual_maxsoil_patches, actual_numc end subroutine surfrd_get_num_patches +!----------------------------------------------------------------------- + subroutine surfrd_get_nlevurb (lfsurdat, actual_nlevurb) + ! + ! !DESCRIPTION: + ! Read nlevurb from the surface dataset + ! + ! !USES: + use fileutils , only : getfil + ! + ! !ARGUMENTS: + character(len=*), intent(in) :: lfsurdat ! surface dataset filename + integer, intent(out) :: actual_nlevurb ! nlevurb from surface dataset + ! + ! !LOCAL VARIABLES: + character(len=256):: locfn ! local file name + type(file_desc_t) :: ncid ! netcdf file id + integer :: dimid ! netCDF dimension id + character(len=32) :: subname = 'surfrd_get_nlevurb' ! subroutine name + !----------------------------------------------------------------------- + + if (masterproc) then + write(iulog,*) 'Attempting to read nlevurb from the surface data .....' + if (lfsurdat == ' ') then + write(iulog,*)'lfsurdat must be specified' + call endrun(msg=errMsg(sourcefile, __LINE__)) + endif + endif + + ! Open surface dataset + call getfil( lfsurdat, locfn, 0 ) + call ncd_pio_openfile (ncid, trim(locfn), 0) + + ! Read nlevurb + call ncd_inqdlen(ncid, dimid, actual_nlevurb, 'nlevurb') + + if ( masterproc )then + write(iulog,*) 'Successfully read nlevurb from the surface data' + write(iulog,*) + end if + + end subroutine surfrd_get_nlevurb + !----------------------------------------------------------------------- subroutine surfrd_special(begg, endg, ncid, ns) ! diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 5ff6f662f2..8a6bc71740 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -97,7 +97,19 @@ - lnd/clm2/rawdata/mksrf_urban_0.05x0.05_simyr2000.c220127.nc + /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_2000_c20220910.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc + + + /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_1850_c20220910.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc + + + /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_2000_c20220910.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc + + + /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_2005_c20220910.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc @@ -252,7 +264,7 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20220305/mksrf_landuse_ctsm52_histLUH2_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc + /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_%y_c20220910.nc @@ -266,49 +278,49 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP26_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc + /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP19_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc + /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP2RCP45_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc + /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP2/urban_properties_GaoOneil_05deg_ThreeClass_ssp2_%y_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP3RCP70_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc + /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP3/urban_properties_GaoOneil_05deg_ThreeClass_ssp3_%y_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP34_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc + /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP60_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc + /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP5RCP85_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc + /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_c20220910.nc From 73950a362c899787007c3b971d92433fb08af2e8 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 16 Sep 2022 12:35:00 -0600 Subject: [PATCH 232/614] Update .xml file with new glacier, new lakedepth files, rm merge_gis opt Discussion pending regarding the consistency between PCT_LAKE in the new 2017 lakedepth file used for year-2000 simulations versus in the new transient lake files. --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 15 --------------- tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml | 12 ++++++------ 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 79c751fca9..413dd71f5c 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -242,19 +242,6 @@ def get_parser(): dest="potveg_flag", default=False, ) - parser.add_argument( - "--merge_gis", - help=""" - If you want to use the glacier dataset that merges in - the Greenland Ice Sheet data that CISM uses (typically - used only if consistency with CISM is important) - [default: %(default)s] - """, - action="store", - dest="merge_gis", - choices=["on","off"], - default="off", - ) return parser def main (): @@ -279,7 +266,6 @@ def main (): glc_flag = args.glc_flag potveg = args.potveg_flag glc_nec = args.glc_nec - merge_gis = args.merge_gis if args.hres_pft: if (start_year == 1850 and end_year == 1850) or \ @@ -393,7 +379,6 @@ def main (): 'pft_years':pft_years, 'pft_years_ssp':pft_years_ssp, 'ssp_rcp':ssp_rcp, - 'mergeGIS':merge_gis, 'res':res} # create dictionary for raw data files names diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index e8dcb3a23a..c52b77b9a1 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -67,7 +67,11 @@ - lnd/clm2/rawdata/mksrf_LakePnDepth_3x3min_simyr2004_csplk_c151015.nc + /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_LakePnDepth_3x3min_simyr2017_MODISgrid.cdf5.c200305.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc + + + /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_LakePnDepth_3x3min_simyr1850_MODISgrid.cdf5.c200304.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc @@ -133,11 +137,7 @@ version of the raw dataset will probably go away. - lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000.cdf5.c120926.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc - - - lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000_mergeGreenland.c120921.nc + lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000.c20210708.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc From 1fbbe0c09c77f9ff7600f982b220abb5e4fd65f8 Mon Sep 17 00:00:00 2001 From: Keith Oleson Date: Fri, 16 Sep 2022 15:59:20 -0600 Subject: [PATCH 233/614] Revert changes to namelist_defaults_ctsm_tools.xml --- .../namelist_defaults_ctsm_tools.xml | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm_tools.xml b/bld/namelist_files/namelist_defaults_ctsm_tools.xml index 44d2580b18..ff309c6fc9 100644 --- a/bld/namelist_files/namelist_defaults_ctsm_tools.xml +++ b/bld/namelist_files/namelist_defaults_ctsm_tools.xml @@ -254,23 +254,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). >lnd/clm2/rawdata/mksrf_vocef_0.5x0.5_simyr2000.c110531.nc -/glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_2000_c20220910.nc - -/glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/HistoricalPlusSSP5/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_2000_c20220910.nc - -/glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/HistoricalPlusSSP5/urban_properties_GaoOneil_05deg_ThreeClass_ssp2_2000_c20220910.nc - -/glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/HistoricalPlusSSP5/urban_properties_GaoOneil_05deg_ThreeClass_ssp3_2000_c20220910.nc - -/glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/HistoricalPlusSSP5/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_2000_c20220910.nc - -/glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/HistoricalPlusSSP5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_2000_c20220910.nc +lnd/clm2/rawdata/mksrf_urban_0.05x0.05_simyr2000.c120621.nc lnd/clm2/rawdata/mksrf_urban_0.05x0.05_zerourbanpct.c181014.nc From 97b93726b2bd4a2a696358b0b4e55878c2bed526 Mon Sep 17 00:00:00 2001 From: Keith Oleson Date: Fri, 16 Sep 2022 16:29:40 -0600 Subject: [PATCH 234/614] Remove explicit and redundant call-out for year 2000 --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 8a6bc71740..07d8420d90 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -104,10 +104,6 @@ /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_1850_c20220910.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc - - /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_2000_c20220910.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc - /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_2005_c20220910.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc From 7012608a32684b6b3faab5eacf2cdc5e29f9784a Mon Sep 17 00:00:00 2001 From: Keith Oleson Date: Tue, 20 Sep 2022 11:21:04 -0600 Subject: [PATCH 235/614] Rename building temperature streams file --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 2d645bbf92..8de359ea80 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1725,7 +1725,7 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts 2106 /glade/p/cgd/tss/people/oleson/urban_sfcdata/Feddema_urban_data_080410/HIGH_RES_VERSION2/URBAN_PROPERTIES_THESIS_TOOL/JUN_22_2018/CLM50_tbuildmax_Oleson_2016_0.9x1.25_simyr1849-2106_c200605.nc +>/glade/p/cgd/tss/people/oleson/urban_sfcdata/Feddema_urban_data_080410/HIGH_RES_VERSION2/URBAN_PROPERTIES_THESIS_TOOL/JUN_22_2018/CTSM52_tbuildmax_OlesonFeddema_2020_0.9x1.25_simyr1849-2106_c200605.nc lnd/clm2/urbandata/CLM50_tbuildmax_Oleson_2016_0.9x1_ESMFmesh_cdf5_100621.nc From 9b37f016dbcd529c5d708018ad397066342e1fa9 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 20 Sep 2022 11:46:16 -0600 Subject: [PATCH 236/614] Upd .xml file w new hist data (1850-2015) w the new absolute values --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index c52b77b9a1..dd83ea0db0 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -248,7 +248,7 @@ version of the raw dataset will probably go away. - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20220305/mksrf_landuse_ctsm52_histLUH2_%y.c220305.nc + /glade/p/cesm/sdwg_dev/thesis/data/cesm_tools/surfacedata/ctsm52finalrawdata/globalctsm52nrhistLUH2deg025_220918/mksrf_landuse_ctsm52_nrhistLUH2_%y.c220918.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc /glade/p/cgd/tss/people/slevis/transient_urban_data/05deg_%y_NoAdjust.cdf5.c20220325.nc From 510bf21d64b714a19b87ca7f17288076ebd56fe0 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 20 Sep 2022 12:47:39 -0600 Subject: [PATCH 237/614] Get timeslice/baseline mksrf_furban from the exact year requested This means that we stop defaulting mksrf_furban to the yr-2000 file for years other than 1850 and 2005. Any timeslice year we ask for, we get the raw file for that year. --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 3 +++ tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml | 10 +--------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 6108d034f8..b5979bf5c3 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -431,6 +431,9 @@ def main (): print('WARNING: run ./download_input_data to try TO ' \ 'OBTAIN MISSING FILES') _must_run_download_input_data = True + else: + rawdata_files[child1.tag] = rawdata_files[child1.tag]. \ + replace("%y",str(start_year)) if item.tag == 'mesh_filename': new_key = f"{child1.tag}_mesh" diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 07d8420d90..e58f4d1bd2 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -97,15 +97,7 @@ - /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_2000_c20220910.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc - - - /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_1850_c20220910.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc - - - /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_2005_c20220910.nc + /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_%y_c20220910.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc From 0d604668f016879722932e298fd985fd3d228c1b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 20 Sep 2022 17:45:15 -0600 Subject: [PATCH 238/614] Change else to elif for previous commit to not break transient cases --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index b5979bf5c3..921028d607 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -431,7 +431,9 @@ def main (): print('WARNING: run ./download_input_data to try TO ' \ 'OBTAIN MISSING FILES') _must_run_download_input_data = True - else: + elif 'urban_properties' in rawdata_files[child1.tag]: + # Time-slice cases pull urban_properties from the transient + # urban_properties data files rawdata_files[child1.tag] = rawdata_files[child1.tag]. \ replace("%y",str(start_year)) From 4083aa444945f2f4651bb1a156fa65e760775caa Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 20 Sep 2022 18:51:32 -0600 Subject: [PATCH 239/614] Small updates needed for gen_mksurfdata_jobscript_multi.py to work --- .../mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 5d4cf6bfdb..5797c5d571 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -200,6 +200,11 @@ def main (): "crop-global-SSP5-8.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-8.5 --res", "future_res") } + # -------------------------- + # TODO Here, reuse code from gen_mksurfdata_jobscript_single.py + # that's found in the section titled "Obtain mpirun command ..." + # -------------------------- + # -------------------------- # Write run script # -------------------------- @@ -210,7 +215,7 @@ def main (): runfile.write('#PBS -N mksurfdata \n') runfile.write('#PBS -j oe \n') runfile.write('#PBS -q regular \n') - runfile.write('#PBS -l walltime=30:00 \n') + runfile.write('#PBS -l walltime=12:00:00 \n') runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") runfile.write("\n") @@ -219,7 +224,7 @@ def main (): # Run env_mach_specific.sh to control the machine dependent # environment including the paths to compilers and libraries # external to cime such as netcdf - runfile.write('. ./.env_mach_specific.sh \n') + runfile.write('. ./tool_bld/.env_mach_specific.sh \n') for target in target_list: res_set = dataset_dict[target][1] for res in resolution_dict[res_set]: @@ -236,7 +241,7 @@ def main (): output = run_cmd.stdout.decode('utf-8').strip() namelist = output.split(' ')[-1] print (f"generated namelist {namelist}") - output = f"mpiexec_mpt -p \"%g:\" -np {n_p} ./tool_bld/mksurfdata < {namelist}" + output = f"mpiexec_mpt -p \"%g:\" -np {n_p} omplace -tm open64 ./tool_bld/mksurfdata < {namelist}" runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") From 49885f5a2580fe5f020d1b534e6fc983cf091614 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 22 Sep 2022 12:40:06 -0600 Subject: [PATCH 240/614] Fix typo in gen_mksurfdata_jobscript_multi.py --- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 5797c5d571..90ebe3d79b 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -171,7 +171,7 @@ def main (): "T42_res" : ['T42'], "nldas_res" : ['0.125nldas2'], "5x5_amazon_res" : ['5x5_amazon'], - "ne16np4_res" : ['ne120np4'], + "ne16np4_res" : ['ne16np4'], "ne120np4_res" : ['ne120np4'], } From 1cb9b54ebe10602d41229e9ea80642378671d702 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 22 Sep 2022 13:06:02 -0600 Subject: [PATCH 241/614] Updating README with latest info --- tools/mksurfdata_esmf/README | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index de92c04ae7..309b57d611 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -1,3 +1,13 @@ +======= +Purpose +======= +This tool is intended to generate fsurdat files (surface datasets) for the +CTSM. It can generate global, regional, and single-point fsurdat files, as long +as a mesh file is available for the grid. + +The subset_data tool allows users to make fsurdat files from existing fsurdat +files when a mesh file is unavailable. Generally, users should consider the +subset_data tool for generating regional and single-point fsurdat files. =================== Build Requirements: =================== @@ -70,13 +80,17 @@ running for a single submission: # to generate your target jobscript (again --help for instructions): > ./gen_mksurfdata_jobscript_single.py --number-of-nodes 24 --tasks-per-node 12 --namelist-file target.namelist > qsub mksurfdata_jobscript_single +# Read note about regional grids below. ======================= running for the generation of multiple datasets ======================= -# Note that gen_mksurfdata_jobscript_multi.py runs ./gen_mksurfdata_namelist.py +# Notes: +# - gen_mksurfdata_jobscript_multi.py runs ./gen_mksurfdata_namelist.py for you +# - The regional grid 5x5_amazon may fail with 24 nodes. +# Task geometry that worked: #PBS -l select=4:ncpus=36:mpiprocs=4 > ./gen_mksurfdata_jobscript_multi.py --help -> ./gen_mksurfdata_jobscript_multi.py --number-of-nodes 24 --tasks-per-node 12 --scenario all +> ./gen_mksurfdata_jobscript_multi.py --number-of-nodes 24 --scenario all > qsub mksurfdata_jobscript_multi ================ From 314510ea14e767dcb4ee74eff4eb733b52261a5b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 23 Sep 2022 10:17:38 -0600 Subject: [PATCH 242/614] Fix another typo in gen_mksurfdata_jobscript_multi.py --- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 90ebe3d79b..679c8e3e05 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -196,7 +196,7 @@ def main (): "crop-global-SSP3-7.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP3-7.0 --res", "future_res"), "crop-global-SSP4-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-3.4 --res", "future_res"), "crop-global-SSP4-6.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-6.0 --res", "future_res"), - "crop-global-SSP5-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-3.4 --res", "future_res"), + "crop-global-SSP5-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-3.4 --res", "future_res"), "crop-global-SSP5-8.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-8.5 --res", "future_res") } From 88f02392eed01cee760abcad5bca96aae4e219e8 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 23 Sep 2022 10:36:27 -0600 Subject: [PATCH 243/614] Addition to .xml file associated with the correction in last commit --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index e58f4d1bd2..c9c3741270 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -310,6 +310,13 @@ version of the raw dataset will probably go away. /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_c20220910.nc + + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP5RCP34_%y.c220305.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc + /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_c20220910.nc + From b6a58cda26917d1cd0148c9db130c2f4b3ea32a3 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 26 Sep 2022 16:48:03 -0600 Subject: [PATCH 244/614] Correction for FUNITCTSM_P1x1... test to PASS --- src/biogeophys/test/Photosynthesis_test/test_Photosynthesis.pf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeophys/test/Photosynthesis_test/test_Photosynthesis.pf b/src/biogeophys/test/Photosynthesis_test/test_Photosynthesis.pf index 78c82e1bf4..229981df39 100644 --- a/src/biogeophys/test/Photosynthesis_test/test_Photosynthesis.pf +++ b/src/biogeophys/test/Photosynthesis_test/test_Photosynthesis.pf @@ -38,7 +38,7 @@ contains soil_layerstruct_predefined = '20SL_8.5m' call setup_ncells_single_veg_patch(ncells=1, pft_type=1) - call clm_varpar_init( actual_maxsoil_patches=17, actual_numcft=2 ) + call clm_varpar_init( actual_maxsoil_patches=17, actual_numcft=2, actual_nlevurb=5 ) call this%photo%Init( bounds ) call this%photo%setParamsForTesting( ) From 540d0c9ef43b6b43023c2e707e78c4be8034035e Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 28 Sep 2022 11:20:44 -0600 Subject: [PATCH 245/614] Cp tbuildmax file from Keith Oleson's dir to lnd/clm2/urbandata --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 8de359ea80..f85ca9b034 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1725,7 +1725,7 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts 2106 /glade/p/cgd/tss/people/oleson/urban_sfcdata/Feddema_urban_data_080410/HIGH_RES_VERSION2/URBAN_PROPERTIES_THESIS_TOOL/JUN_22_2018/CTSM52_tbuildmax_OlesonFeddema_2020_0.9x1.25_simyr1849-2106_c200605.nc +>/glade/p/cesmdata/inputdata/lnd/clm2/urbandata/CTSM52_tbuildmax_OlesonFeddema_2020_0.9x1.25_simyr1849-2106_c200605.nc lnd/clm2/urbandata/CLM50_tbuildmax_Oleson_2016_0.9x1_ESMFmesh_cdf5_100621.nc From 5dded3299fdead1764da828c35f3e73efa042a90 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 28 Sep 2022 12:27:45 -0600 Subject: [PATCH 246/614] Cp transient rawdata from KOleson to lnd/clm2/rawdata/gao_oneill_urban --- .../gen_mksurfdata_namelist.xml | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index c9c3741270..fd86bfd364 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -97,7 +97,7 @@ - /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_%y_c20220910.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc @@ -252,7 +252,7 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20220305/mksrf_landuse_ctsm52_histLUH2_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/Historical/urban_properties_GaoOneil_05deg_ThreeClass_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_%y_c20220910.nc @@ -266,56 +266,56 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP26_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP19_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP2RCP45_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP2/urban_properties_GaoOneil_05deg_ThreeClass_ssp2_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp2/urban_properties_GaoOneil_05deg_ThreeClass_ssp2_%y_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP3RCP70_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP3/urban_properties_GaoOneil_05deg_ThreeClass_ssp3_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp3/urban_properties_GaoOneil_05deg_ThreeClass_ssp3_%y_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP34_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP60_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP5RCP85_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP5RCP34_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - /glade/p/cgd/tss/people/oleson/Dynamic_Urban_Data/GaoOneil/PCTURB_GRID/SSP5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_c20220910.nc From 1cc1fade79dadff773b7d36ba61fd40c0ac165d7 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 28 Sep 2022 17:20:25 -0600 Subject: [PATCH 247/614] Add "_cdf5_" to transient urban rawdata file names This string should have gone in with #1853, but I missed it, so the latest ctsm5.2.mksurfdata branch tag will not work as is right now. The correction will come in with the next tag. --- .../gen_mksurfdata_namelist.xml | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index c131fd8cf8..a5bafa0973 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -100,7 +100,7 @@ - lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_%y_cdf5_c20220910.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc @@ -251,7 +251,7 @@ version of the raw dataset will probably go away. /glade/p/cesm/sdwg_dev/thesis/data/cesm_tools/surfacedata/ctsm52finalrawdata/globalctsm52nrhistLUH2deg025_220918/mksrf_landuse_ctsm52_nrhistLUH2_%y.c220918.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_%y_cdf5_c20220910.nc @@ -265,56 +265,56 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP26_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - lnd/clm2/rawdata/gao_oneill_urban/ssp1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP19_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - lnd/clm2/rawdata/gao_oneill_urban/ssp1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP2RCP45_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - lnd/clm2/rawdata/gao_oneill_urban/ssp2/urban_properties_GaoOneil_05deg_ThreeClass_ssp2_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp2/urban_properties_GaoOneil_05deg_ThreeClass_ssp2_%y_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP3RCP70_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - lnd/clm2/rawdata/gao_oneill_urban/ssp3/urban_properties_GaoOneil_05deg_ThreeClass_ssp3_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp3/urban_properties_GaoOneil_05deg_ThreeClass_ssp3_%y_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP34_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - lnd/clm2/rawdata/gao_oneill_urban/ssp4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP60_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - lnd/clm2/rawdata/gao_oneill_urban/ssp4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP5RCP85_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP5RCP34_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc - lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_cdf5_c20220910.nc From 59785d43bc7a163d34fc5452379b91e0ad59ea8e Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 28 Sep 2022 19:00:21 -0600 Subject: [PATCH 248/614] Read lakedepth & %lake separately to get the latter from transient files --- .../gen_mksurfdata_namelist.py | 7 +- .../gen_mksurfdata_namelist.xml | 13 +- tools/mksurfdata_esmf/src/mkfileMod.F90 | 12 +- tools/mksurfdata_esmf/src/mkinputMod.F90 | 24 +- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 221 +++++++++++++----- tools/mksurfdata_esmf/src/mksurfdata.F90 | 25 +- 6 files changed, 210 insertions(+), 92 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index b60b189cb1..f9226cac2c 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -437,9 +437,10 @@ def main (): print('WARNING: run ./download_input_data to try TO ' \ 'OBTAIN MISSING FILES') _must_run_download_input_data = True - elif 'urban_properties' in rawdata_files[child1.tag]: - # Time-slice cases pull urban_properties from the transient - # urban_properties data files + elif 'urban_properties' in rawdata_files[child1.tag] or \ + 'lake' in rawdata_files[child1.tag]: + # Time-slice cases pull urban_properties and %lake from the + # corresponding transient files rawdata_files[child1.tag] = rawdata_files[child1.tag]. \ replace("%y",str(start_year)) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index a5bafa0973..a53f3e469f 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -65,16 +65,21 @@ - + - /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_LakePnDepth_3x3min_simyr2017_MODISgrid.cdf5.c200305.nc + /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc - + + + + + + /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_LakePnDepth_3x3min_simyr1850_MODISgrid.cdf5.c200304.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc - + diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index a38fe9c1ff..ab59e68d42 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -135,8 +135,10 @@ subroutine mkfile_define_atts(pioid, dynlanduse) ! Raw data file names str = get_filename(mksrf_fgrid_mesh) rcode = pio_put_att(pioid, pio_global, 'Input_grid_dataset', trim(str)) - str = get_filename(mksrf_flakwat) - rcode = pio_put_att(pioid, pio_global, 'Inland_lake_raw_data_file_name', trim(str)) + str = get_filename(mksrf_fpctlak) + rcode = pio_put_att(pioid, pio_global, 'Percent_lake_raw_data_file_name', trim(str)) + str = get_filename(mksrf_flakdep) + rcode = pio_put_att(pioid, pio_global, 'Lake_depth_raw_data_file_name', trim(str)) str = get_filename(mksrf_fwetlnd) rcode = pio_put_att(pioid, pio_global, 'Inland_wetland_raw_data_file_name', trim(str)) str = get_filename(mksrf_fglacier) @@ -167,8 +169,10 @@ subroutine mkfile_define_atts(pioid, dynlanduse) ! Mesh file names str = get_filename(mksrf_fvegtyp_mesh) rcode = pio_put_att(pioid, pio_global, 'mesh_pft_file_name', trim(str)) - str = get_filename(mksrf_flakwat_mesh) - rcode = pio_put_att(pioid, pio_global, 'mesh_lakwat_file', trim(str)) + str = get_filename(mksrf_fpctlak_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_pctlak_file', trim(str)) + str = get_filename(mksrf_flakdep_mesh) + rcode = pio_put_att(pioid, pio_global, 'mesh_lakdep_file', trim(str)) str = get_filename(mksrf_fwetlnd_mesh) rcode = pio_put_att(pioid, pio_global, 'mesh_wetlnd_file', trim(str)) str = get_filename(mksrf_fglacier_mesh) diff --git a/tools/mksurfdata_esmf/src/mkinputMod.F90 b/tools/mksurfdata_esmf/src/mkinputMod.F90 index 6133ac09e9..465d653313 100644 --- a/tools/mksurfdata_esmf/src/mkinputMod.F90 +++ b/tools/mksurfdata_esmf/src/mkinputMod.F90 @@ -66,8 +66,10 @@ module mkinputMod character(CX) , public :: mksrf_fgdp = ' ' ! gdp data file names character(CX) , public :: mksrf_fgdp_mesh = ' ' ! gdp mesh file names - character(CX) , public :: mksrf_flakwat = ' ' ! inland lake data file name - character(CX) , public :: mksrf_flakwat_mesh = ' ' ! inland lake mesh file name + character(CX) , public :: mksrf_fpctlak = ' ' ! percent lake data file name + character(CX) , public :: mksrf_fpctlak_mesh = ' ' ! percent lake file name + character(CX) , public :: mksrf_flakdep = ' ' ! lake depth data file name + character(CX) , public :: mksrf_flakdep_mesh = ' ' ! lake depth file name character(CX) , public :: mksrf_fwetlnd = ' ' ! inland wetlands data file name character(CX) , public :: mksrf_fwetlnd_mesh = ' ' ! inland wetlands mesh file name @@ -140,8 +142,10 @@ subroutine read_namelist_input() mksrf_fsoicol_mesh, & mksrf_fvocef, & mksrf_fvocef_mesh, & - mksrf_flakwat, & - mksrf_flakwat_mesh, & + mksrf_fpctlak, & + mksrf_fpctlak_mesh, & + mksrf_flakdep, & + mksrf_flakdep_mesh, & mksrf_fwetlnd, & mksrf_fwetlnd_mesh, & mksrf_fglacier, & @@ -242,8 +246,10 @@ subroutine read_namelist_input() call mpi_bcast (mksrf_fgdp, len(mksrf_fgdp), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fgdp_mesh, len(mksrf_fgdp_mesh), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_flakwat, len(mksrf_flakwat), MPI_CHARACTER, 0, mpicom, ier) - call mpi_bcast (mksrf_flakwat_mesh, len(mksrf_flakwat_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fpctlak, len(mksrf_fpctlak), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_fpctlak_mesh, len(mksrf_fpctlak_mesh), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_flakdep, len(mksrf_flakdep), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (mksrf_flakdep_mesh, len(mksrf_flakdep_mesh), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fwetlnd, len(mksrf_fwetlnd), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fwetlnd_mesh, len(mksrf_fwetlnd_mesh), MPI_CHARACTER, 0, mpicom, ier) @@ -336,8 +342,10 @@ subroutine write_namelist_input() write(ndiag,'(a)')' PFTs from: '//trim(mksrf_fvegtyp) write(ndiag,'(a)')' mesh for pft '//trim(mksrf_fvegtyp_mesh) write(ndiag,*) - write(ndiag,'(a)')' inland lake from: '//trim(mksrf_flakwat) - write(ndiag,'(a)')' mesh for lake water '//trim(mksrf_flakwat_mesh) + write(ndiag,'(a)')' percent lake from: '//trim(mksrf_fpctlak) + write(ndiag,'(a)')' mesh for percent lake '//trim(mksrf_fpctlak_mesh) + write(ndiag,'(a)')' lake depth from: '//trim(mksrf_flakdep) + write(ndiag,'(a)')' mesh for lake depth '//trim(mksrf_flakdep_mesh) write(ndiag,*) write(ndiag,'(a)')' inland wetland from: '//trim(mksrf_fwetlnd) write(ndiag,'(a)')' mesh for wetland '//trim(mksrf_fwetlnd_mesh) diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index a01ca38515..90c8cf2b0a 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -20,7 +20,8 @@ module mklanwatMod implicit none private - public :: mklakwat ! make %lake and lake dpeth + public :: mkpctlak ! make %lake + public :: mklakdep ! make lake depth public :: mkwetlnd ! make %wetland public :: update_max_array_lake ! Update the maximum lake percent @@ -34,13 +35,11 @@ module mklanwatMod contains !=============================================================== - subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, & - fsurdat, rc, do_depth) + subroutine mkpctlak(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, rc) ! ------------------- - ! make %lake and lake depth - ! PCT_LAKE is written out to fsurdat in mksurfdata after adjustments are made - ! LAKE_DEPTH is written out to fsurdat here + ! make %lake + ! PCT_LAKE is written to fsurdat in mksurfdata after adjustments are made ! ------------------- ! uses @@ -52,23 +51,18 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, & type(ESMF_Mesh) , intent(in) :: mesh_o type(file_desc_t) , intent(inout) :: pioid_o real(r8) , intent(out) :: lake_o(:) ! output grid: %lake - character(len=*) , intent(in) :: fsurdat integer , intent(out) :: rc - logical, optional , intent(in) :: do_depth ! do the depth part of the subroutine ! local variables type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid_i - integer , allocatable :: mask_i(:) + integer , allocatable :: mask_i(:) real(r8), allocatable :: rmask_i(:) real(r8), allocatable :: lake_i(:) ! input grid: percent lake - real(r8), allocatable :: lakedepth_i(:) ! iput grid: lake depth (m) - real(r8), allocatable :: lakedepth_o(:) ! output grid: lake depth (m) integer :: ni,no,k ! indices integer :: ns_i,ns_o ! local sizes integer :: ier,rcode ! error status - real(r8), parameter :: min_valid_lakedepth = 0._r8 - character(len=*), parameter :: subname = ' mklakwat ' + character(len=*), parameter :: subname = ' mkpctlak ' !----------------------------------------------------------------------- rc = ESMF_SUCCESS @@ -77,15 +71,13 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, & write(ndiag,*) write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) - write(ndiag,'(a)')'Attempting to make lake data' + write(ndiag,'(a)')'Attempting to make %lake' write(ndiag,'(a)') ' Input file is '//trim(file_data_i) write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) end if ! ---------------------------------------- ! Read i input data and input mesh and create route handle - ! ** ASSUME ** for now that have only 1 input data file and 1 input mesh - ! for both %lake and lakedepth ! ---------------------------------------- ! Open raw data file @@ -158,73 +150,176 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, & deallocate (lake_i) + ! ---------------------------------------- + ! Wrap things up + ! ---------------------------------------- + + call pio_closefile(pioid_i) + + ! Release memory + if (mksrf_fdynuse == ' ') then ! ...else we will reuse it + deallocate(frac_o_mklak) + call ESMF_RouteHandleDestroy(routehandle_mklak, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + end if + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + if (root_task) then + write (ndiag,*) 'Successfully made %lake' + end if + call ESMF_VMLogMemInfo("At end of "//trim(subname)) + + end subroutine mkpctlak + +!=============================================================== + subroutine mklakdep(file_mesh_i, file_data_i, mesh_o, pioid_o, fsurdat, rc) + + ! ------------------- + ! make lake depth + ! LAKE_DEPTH is written out to fsurdat here + ! ------------------- + + ! uses + + ! input/output variables + character(len=*) , intent(in) :: file_mesh_i ! input mesh file name + character(len=*) , intent(in) :: file_data_i ! input data file name + type(ESMF_Mesh) , intent(in) :: mesh_o + type(file_desc_t) , intent(inout) :: pioid_o + character(len=*) , intent(in) :: fsurdat + integer , intent(out) :: rc + + ! local variables + type(ESMF_Mesh) :: mesh_i + type(file_desc_t) :: pioid_i + integer , allocatable :: mask_i(:) + real(r8), allocatable :: rmask_i(:) + real(r8), allocatable :: lakedepth_i(:) ! iput grid: lake depth (m) + real(r8), allocatable :: lakedepth_o(:) ! output grid: lake depth (m) + integer :: ni,no,k ! indices + integer :: ns_i,ns_o ! local sizes + integer :: ier,rcode ! error status + real(r8), parameter :: min_valid_lakedepth = 0._r8 + character(len=*), parameter :: subname = ' mklakdep ' + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (root_task) then + write(ndiag,*) + write(ndiag,'(1x,80a1)') ('=',k=1,80) + write(ndiag,*) + write(ndiag,'(a)')'Attempting to make lake depth' + write(ndiag,'(a)') ' Input file is '//trim(file_data_i) + write(ndiag,'(a)') ' Input mesh file is '//trim(file_mesh_i) + end if + + ! ---------------------------------------- + ! Read i input data and input mesh and create route handle + ! ---------------------------------------- + + ! Open raw data file + rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_data_i), pio_nowrite) + + ! Read in input mesh + mesh_i = ESMF_MeshCreate(filename=trim(file_mesh_i), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create mesh_i in "//trim(subname)) + + ! Determine ns_i + call ESMF_MeshGet(mesh_i, numOwnedElements=ns_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine ns_o + call ESMF_MeshGet(mesh_o, numOwnedElements=ns_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the landmask from the input data file and reset the mesh mask based on that + allocate(rmask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + allocate(mask_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid_i, 'LANDMASK', mesh_i, rmask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ni = 1,ns_i + if (rmask_i(ni) > 0._r8) then + mask_i(ni) = 1 + else + mask_i(ni) = 0 + end if + end do + call ESMF_MeshSet(mesh_i, elementMask=mask_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create a route handle between the input and output mesh + if (.not. ESMF_RouteHandleIsCreated(routehandle_mklak)) then + allocate(frac_o_mklak(ns_o)) + call create_routehandle_r8(mesh_i, mesh_o, routehandle_mklak, frac_o=frac_o_mklak, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) + end if + ! ---------------------------------------- ! Create lake parameter (lakedepth) ! ---------------------------------------- - if (present(do_depth)) then - if (do_depth) then - if (root_task) then - write (ndiag,*) 'Attempting to make lake depth .....' - end if - - ! lakedepth - allocate(lakedepth_i(ns_i), stat=rcode) - if (rcode/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid_i, 'LAKEDEPTH', mesh_i, lakedepth_i, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! regrid lakedepth_i to lakedepth_o - this also returns lakedepth_i to be used in the global sums below - allocate (lakedepth_o(ns_o)); lakedepth_o(:) = spval - call regrid_rawdata(mesh_i, mesh_o, routehandle_mklak, lakedepth_i, lakedepth_o, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regrid_rawdata for lakedepth in "//trim(subname)) - do no = 1,ns_o - if (frac_o_mklak(no) == 0._r8) then - lakedepth_o(no) = 10._r8 - end if - enddo - if (min_bad(lakedepth_o, min_valid_lakedepth, 'lakedepth')) then - call shr_sys_abort() - end if - - if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing out lakedepth" - call mkfile_output(pioid_o, mesh_o, 'LAKEDEPTH', lakedepth_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - call pio_syncfile(pioid_o) - end if - - ! Check global areas for lake depth - call output_diagnostics_continuous(mesh_i, mesh_o, & - lakedepth_i, lakedepth_o, "lake depth", "m", & - ndiag=ndiag, rc=rc, mask_i=mask_i, frac_o=frac_o_mklak) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (root_task) then + write (ndiag,*) 'Attempting to make lake depth .....' + end if + + ! lakedepth + allocate(lakedepth_i(ns_i), stat=rcode) + if (rcode/=0) call shr_sys_abort() + call mkpio_get_rawdata(pioid_i, 'LAKEDEPTH', mesh_i, lakedepth_i, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! regrid lakedepth_i to lakedepth_o - this also returns lakedepth_i to be used in the global sums below + allocate (lakedepth_o(ns_o)); lakedepth_o(:) = spval + call regrid_rawdata(mesh_i, mesh_o, routehandle_mklak, lakedepth_i, lakedepth_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regrid_rawdata for lakedepth in "//trim(subname)) + do no = 1,ns_o + if (frac_o_mklak(no) == 0._r8) then + lakedepth_o(no) = 10._r8 end if + enddo + if (min_bad(lakedepth_o, min_valid_lakedepth, 'lakedepth')) then + call shr_sys_abort() + end if + + if (fsurdat /= ' ') then + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out lakedepth" + call mkfile_output(pioid_o, mesh_o, 'LAKEDEPTH', lakedepth_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + call pio_syncfile(pioid_o) end if + ! Check global areas for lake depth + call output_diagnostics_continuous(mesh_i, mesh_o, & + lakedepth_i, lakedepth_o, "lake depth", "m", & + ndiag=ndiag, rc=rc, mask_i=mask_i, frac_o=frac_o_mklak) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! ---------------------------------------- ! Wrap things up ! ---------------------------------------- - ! Close the single input data file call pio_closefile(pioid_i) ! Release memory - if (mksrf_fdynuse == ' ') then ! ...else we will reuse it - deallocate(frac_o_mklak) - call ESMF_RouteHandleDestroy(routehandle_mklak, nogarbage = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - end if + deallocate(frac_o_mklak) + call ESMF_RouteHandleDestroy(routehandle_mklak, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() if (root_task) then - write (ndiag,*) 'Successfully made lake data' + write (ndiag,*) 'Successfully made lake depth' end if call ESMF_VMLogMemInfo("At end of "//trim(subname)) - end subroutine mklakwat + end subroutine mklakdep !=============================================================== subroutine mkwetlnd(file_mesh_i, file_data_i, mesh_o, swmp_o, rc) @@ -252,7 +347,7 @@ subroutine mkwetlnd(file_mesh_i, file_data_i, mesh_o, swmp_o, rc) integer :: ni,no,k ! indices integer :: ns_i,ns_o ! local sizes integer :: ier,rcode ! error status - character(len=*), parameter :: subname = ' mklakwat ' + character(len=*), parameter :: subname = ' mkwetlnd ' !----------------------------------------------------------------------- rc = ESMF_SUCCESS diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index e5df09be7e..a7f021e9b4 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -22,8 +22,10 @@ program mksurfdata ! mksrf_fglacierregion_mesh - Mesh for mksrf_fglacierregion ! mksrf_flai - Leaf Area Index dataset ! mksrf_flai_mesh - Mesh for mksrf_flai - ! mksrf_flakwat - Lake water dataset - ! mksrf_flakwat_mesh - Mesh for mksrf_flakwat + ! mksrf_fpctlak - Percent lake dataset + ! mksrf_fpctlak_mesh - Mesh for mksrf_fpctlak + ! mksrf_flakdep - Lake depth dataset + ! mksrf_flakdep_mesh - Mesh for mksrf_flakdep ! mksrf_fwetlnd - Wetland water dataset ! mksrf_fwetlnd_mesh - Mesh for mksrf_fwetlnd ! mksrf_fmax - Max fractional saturated area dataset @@ -106,7 +108,7 @@ program mksurfdata use mksoildepthMod , only : mksoildepth use mksoilcolMod , only : mksoilcol use mkurbanparMod , only : mkurbanInit, mkurban, mkurbanpar, mkurban_topo, numurbl, update_max_array_urban - use mklanwatMod , only : mklakwat, mkwetlnd, update_max_array_lake + use mklanwatMod , only : mkpctlak, mklakdep, mkwetlnd, update_max_array_lake use mkutilsMod , only : normalize_classes_by_gcell, chkerr use mkfileMod , only : mkfile_define_dims, mkfile_define_atts, mkfile_define_vars use mkfileMod , only : mkfile_output @@ -426,15 +428,18 @@ program mksurfdata end if ! ----------------------------------- - ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] + ! Make inland water [pctlak, pctwet] ! ----------------------------------- ! LAKEDEPTH is written out in the subroutine ! Need to keep pctlak and pctwet external for use below allocate ( pctlak(lsize_o)) ; pctlak(:) = spval allocate ( pctlak_max(lsize_o)) ; pctlak_max(:) = spval - call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, pctlak, pioid, & - fsurdat, rc=rc, do_depth=.true.) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') + call mkpctlak(mksrf_fpctlak_mesh, mksrf_fpctlak, mesh_model, pctlak, pioid, & + rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpctlak') + call mklakdep(mksrf_flakdep_mesh, mksrf_flakdep, mesh_model, pioid, fsurdat, & + rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklakdep') allocate ( pctwet(lsize_o)) ; pctwet(:) = spval allocate ( pctwet_orig(lsize_o)) ; pctwet_orig(:) = spval @@ -922,9 +927,9 @@ program mksurfdata call pio_syncfile(pioid) ! Create pctlak data at model resolution (use original mapping file from lake data) - call mklakwat(mksrf_flakwat_mesh, flakname, mesh_model, pctlak, pioid, & - fsurdat, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklakwat') + call mkpctlak(mksrf_fpctlak_mesh, flakname, mesh_model, pctlak, pioid, & + rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpctlak') call pio_syncfile(pioid) call mkurban(mksrf_furban_mesh, furbname, mesh_model, pcturb, & From 94b844becf15ab1c17dca7bf7ff787e1ef484c0d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 29 Sep 2022 17:19:36 -0600 Subject: [PATCH 249/614] Update .xml with "rimport" locations of most new files rimport pending for mksrf_landuse files. Of those, there are: - "final" ones for 1850-2015 that I don't have permission to link to - older ones for other periods that I will check with @lawrencepj1 whether we expect to replace --- .../gen_mksurfdata_namelist.xml | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index a53f3e469f..acbf408b72 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -45,7 +45,7 @@ lnd/clm2/rawdata/mksrf_soil_mapunits_5x5min_WISE.c220330.nc lnd/clm2/rawdata/mksrf_soil_lookup.10level.WISE.c220330.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_c200129.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_5x5min_nomask_cdf5_c200129.nc lnd/clm2/rawdata/mksrf_soil_mapunits_30sec_WISE.c220330.nc @@ -67,7 +67,7 @@ - /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc @@ -76,7 +76,7 @@ - /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_LakePnDepth_3x3min_simyr1850_MODISgrid.cdf5.c200304.nc + lnd/clm2/rawdata/mksrf_LakePnDepth_3x3min_simyr2017_MODISgrid.cdf5.c200305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc @@ -109,7 +109,7 @@ lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc - /glade/p/cgd/tss/people/slevis/pot_veg/mksrf_urban_0.05x0.05_zerourbanpct.cdf5.c181014.nc + lnd/clm2/rawdata/mksrf_urban_0.05x0.05_zerourbanpct.cdf5.c181014.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc @@ -164,7 +164,7 @@ version of the raw dataset will probably go away. lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_cdf5_c200129.nc - /glade/p/cgd/tss/people/slevis/pot_veg/mksrf_gdp_0.5x0_zerogdp.cdf5.c200413.nc + lnd/clm2/rawdata/mksrf_gdp_0.5x0.5_zerogdp.cdf5.c200413.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_cdf5_c200129.nc @@ -189,7 +189,7 @@ version of the raw dataset will probably go away. lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_cdf5_c200129.nc - /glade/p/cgd/tss/people/slevis/pot_veg/mksrf_abm_0.5x0.5_missingabm.cdf5.c200413.nc + lnd/clm2/rawdata/mksrf_abm_0.5x0.5_missingabm.cdf5.c200413.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_cdf5_c200129.nc @@ -223,21 +223,21 @@ version of the raw dataset will probably go away. - /glade/p/cgd/tss/people/slevis/pot_veg/mksrf_landuse_potvegclm50_LUH2.cdf5.c181106.nc + lnd/clm2/rawdata/mksrf_landuse_potvegclm50_LUH2.cdf5.c181106.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.cdf5.c170629/mksrf_landuse_histclm50_LUH2_1850.cdf5.c170629.nc + /glade/p/cesm/sdwg_dev/thesis/data/cesm_tools/surfacedata/ctsm52finalrawdata/globalctsm52nrhistLUH2deg025_220918/mksrf_landuse_ctsm52_nrhistLUH2_1850.c220918.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.cdf5.c170629/mksrf_landuse_histclm50_LUH2_2000.cdf5.c170629.nc + /glade/p/cesm/sdwg_dev/thesis/data/cesm_tools/surfacedata/ctsm52finalrawdata/globalctsm52nrhistLUH2deg025_220918/mksrf_landuse_ctsm52_nrhistLUH2_2000.c220918.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.cdf5.c170629/mksrf_landuse_histclm50_LUH2_2005.cdf5.c170629.nc + /glade/p/cesm/sdwg_dev/thesis/data/cesm_tools/surfacedata/ctsm52finalrawdata/globalctsm52nrhistLUH2deg025_220918/mksrf_landuse_ctsm52_nrhistLUH2_2005.c220918.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc @@ -255,7 +255,7 @@ version of the raw dataset will probably go away. /glade/p/cesm/sdwg_dev/thesis/data/cesm_tools/surfacedata/ctsm52finalrawdata/globalctsm52nrhistLUH2deg025_220918/mksrf_landuse_ctsm52_nrhistLUH2_%y.c220918.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_%y_cdf5_c20220910.nc @@ -269,56 +269,56 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP26_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP19_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP2RCP45_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp2/urban_properties_GaoOneil_05deg_ThreeClass_ssp2_%y_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP3RCP70_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp3/urban_properties_GaoOneil_05deg_ThreeClass_ssp3_%y_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP34_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP60_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP5RCP85_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP5RCP34_%y.c220305.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - /glade/p/cgd/tss/people/slevis/transient_lake_data/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_cdf5_c20220910.nc From e4ad55623a7cb2264bfedff46a70b347bdb78bef Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 3 Oct 2022 14:05:01 -0600 Subject: [PATCH 250/614] Of two calculation options for ORGANIC, switch to the preferred option Keeping the second option commented out for now, rather than deleting --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 2 +- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 46 +++++++++++++--------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index ab59e68d42..09f406bc9e 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -275,7 +275,7 @@ subroutine mkfile_define_vars(pioid, dynlanduse) long_name='soil texture map units', units='unitless') call mkpio_def_spatial_var(pioid=pioid, varname='ORGANIC', xtype=PIO_REAL, & - lev1name='nlevsoi', & ! TODO Rm ORGANIC before merging PR #1732 + lev1name='nlevsoi', & long_name='organic matter density at soil levels', & units='kg/m3 (assumed carbon content 0.58 gC per gOM)') call mkpio_def_spatial_var(pioid=pioid, varname='ORGC', xtype=PIO_REAL, & diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 948c7de086..295217230f 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -77,7 +77,7 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o real(r4), allocatable :: cfrag_o(:,:) ! output grid: coarse fragments (vol% > 2 mm) real(r4), allocatable :: bulk_o(:,:) ! output grid: bulk density (g cm-3) real(r4), allocatable :: phaq_o(:,:) ! output grid: soil pH measured in H2O (unitless) - real(r4), allocatable :: organic_o(:,:) ! output grid: organic matter (kg m-3) TODO Rm before merging PR #1732 + real(r4), allocatable :: organic_o(:,:) ! output grid: organic matter (kg m-3) integer :: n_mapunits integer :: lookup_index integer :: SCID @@ -91,7 +91,7 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o type(var_desc_t) :: pio_varid_cfrag type(var_desc_t) :: pio_varid_bulk type(var_desc_t) :: pio_varid_phaq - type(var_desc_t) :: pio_varid_organic ! TODO Rm bef merging PR #1732 + type(var_desc_t) :: pio_varid_organic integer :: starts(3) ! starting indices for reading lookup table integer :: counts(3) ! dimension counts for reading lookup table integer :: srcTermProcessing_Value = 0 @@ -119,7 +119,7 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o allocate(cfrag_o(ns_o,nlevsoi)) ; cfrag_o(:,:) = spval allocate(bulk_o(ns_o,nlevsoi)) ; bulk_o(:,:) = spval allocate(phaq_o(ns_o,nlevsoi)) ; phaq_o(:,:) = spval - allocate(organic_o(ns_o,nlevsoi)) ; organic_o(:,:) = spval ! TODO Rm bef merging PR #1732 + allocate(organic_o(ns_o,nlevsoi)) ; organic_o(:,:) = spval !--------------------------------- ! Determine mapunits on output grid @@ -368,15 +368,14 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o ! Same algorithm for orgc_o as for sand_o ! organic_o OPTION 2 (commented out) - ! TODO Rm organic before merging PR #1732 UNLESS we opt for OPTION 2 ! Calculate from multiple input variables to get the output variable orgc_o(no,1) = orgc_i(1,1,lookup_index) - organic_o(no,1) = orgc_i(1,1,lookup_index) * bulk_i(1,1,lookup_index) * float(100 - cfrag_i(1,1,lookup_index)) * 0.01_r4 / 0.58_r4 ! TODO Remove? +! organic_o(no,1) = orgc_i(1,1,lookup_index) * bulk_i(1,1,lookup_index) * float(100 - cfrag_i(1,1,lookup_index)) * 0.01_r4 / 0.58_r4 if (orgc_o(no,1) < 0._r4) then do l = 2,n_scid if (orgc_i(1,l,lookup_index) >= 0._r4) then orgc_o(no,1) = orgc_i(1,l,lookup_index) - organic_o(no,1) = orgc_i(1,l,lookup_index) * bulk_i(1,l,lookup_index) * float(100 - cfrag_i(1,l,lookup_index)) * 0.01_r4 / 0.58_r4 ! TODO Rm? +! organic_o(no,1) = orgc_i(1,l,lookup_index) * bulk_i(1,l,lookup_index) * float(100 - cfrag_i(1,l,lookup_index)) * 0.01_r4 / 0.58_r4 exit end if end do @@ -385,13 +384,13 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o if (int(orgc_o(no,1)) == -4) then ! sand dunes write(6,'(a,i8)')'WARNING: changing orgc_o from -4 to 1 at no = ', no orgc_o(no,:) = 1._r4 - write(6,'(a,i8)')'WARNING: changing organic_o from -4 to 1 at no = ', no ! TODO Remove? - organic_o(no,:) = 1._r4 ! TODO Remove? +! write(6,'(a,i8)')'WARNING: changing organic_o from -4 to 1 at no = ', no +! organic_o(no,:) = 1._r4 else write(6,'(a,i8,a,i8)')'WARNING: changing orgc_o from ',int(orgc_o(no,1)),' to 0 at no = ',no orgc_o(no,:) = 0._r4 - write(6,'(a,i8,a,i8)')'WARNING: changing organic_o from ',int(organic_o(no,1)),' to 0 at no = ', no ! TODO Remove? - organic_o(no,:) = 0._r4 ! TODO Remove? +! write(6,'(a,i8,a,i8)')'WARNING: changing organic_o from ',int(organic_o(no,1)),' to 0 at no = ', no +! organic_o(no,:) = 0._r4 end if end if if (orgc_o(no,1) < 0._r4) then @@ -400,10 +399,10 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o end if do l = 2,nlay orgc_o(no,l) = orgc_i(l,1,lookup_index) - organic_o(no,l) = orgc_i(l,1,lookup_index) * bulk_i(l,1,lookup_index) * float(100 - cfrag_i(l,1,lookup_index)) * 0.01_r4 / 0.58_r4 ! TODO Rm? +! organic_o(no,l) = orgc_i(l,1,lookup_index) * bulk_i(l,1,lookup_index) * float(100 - cfrag_i(l,1,lookup_index)) * 0.01_r4 / 0.58_r4 if (orgc_o(no,l) < 0._r4) then orgc_o(no,l) = orgc_o(no,l-1) - organic_o(no,l) = organic_o(no,l-1) ! TODO Remove? +! organic_o(no,l) = organic_o(no,l-1) end if end do @@ -497,12 +496,22 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o end if end do - ! TODO Rm organic before merging PR #1732 UNLESS we opt for OPTION 2 - ! organic_o OPTION 1: as we plan to calculate organic in the CTSM -! do l = 1, nlay -! organic_o(no,l) = orgc_o(no,l) * bulk_o(no,l) * & -! (100._r4 - cfrag_o(no,l)) * 0.01_r4 / 0.58_r4 -! end do + ! --------------------------------------------------------------- + ! organic_o OPTION 1, as we plan to calculate organic in the CTSM + ! --------------------------------------------------------------- + ! Calculate organic from orgc_o, cfrag_o, and bulk_o, i.e. after + ! these terms have been regridded. The plan is to move this + ! calculation step from here to the CTSM. This approach keeps + ! ORGC the same in fsurdat as in the raw data. + ! Alternative approach considered but not selected: Regrid organic_i + ! (calculated from orgc_i, cfrag_i, and bulk_i) to organic_o. This + ! approach first calculates organic_i and then regrids to organic_o + ! rather than regridding all the terms first and then calculating + ! organic_o. Commented out code above belongs to that option. + do l = 1, nlay + organic_o(no,l) = orgc_o(no,l) * bulk_o(no,l) * & + (100._r4 - cfrag_o(no,l)) * 0.01_r4 / 0.58_r4 + end do end if @@ -516,7 +525,6 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o call mkfile_output(pioid_o, mesh_o, 'PCT_CLAY', clay_o, lev1name='nlevsoi', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error calling mkfile_output') - ! TODO Rm ORGANIC before merging PR #1732 if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil organic matter" call mkfile_output(pioid_o, mesh_o, 'ORGANIC', organic_o, lev1name='nlevsoi', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error calling mkfile_output') From 7c054699880cd94feb31cbba3de4c3f25f0e8132 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 3 Oct 2022 16:57:49 -0600 Subject: [PATCH 251/614] Default do_transient_urban & _lakes to .true. for transient compsets --- bld/CLMBuildNamelist.pm | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 7c5859e0ad..0b460d2dba 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2645,6 +2645,13 @@ sub setup_logic_do_transient_lakes { my $var = 'do_transient_lakes'; + # Start by assuming a default value of '.true.'. Then check a number of + # conditions under which do_transient_lakes cannot be true. Under these + # conditions: (1) set default value to '.false.'; (2) make sure that the + # value is indeed false (e.g., that the user didn't try to set it to true). + + my $default_val = ".true."; + # cannot_be_true will be set to a non-empty string in any case where # do_transient_lakes should not be true; if it turns out that # do_transient_lakes IS true in any of these cases, a fatal error will be @@ -2668,7 +2675,7 @@ sub setup_logic_do_transient_lakes { # Note that, if the variable cannot be true, we don't call add_default # - so that we don't clutter up the namelist with variables that don't # matter for this case - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var); + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, var=>$default_val); } # Make sure the value is false when it needs to be false - i.e., that the @@ -2708,6 +2715,13 @@ sub setup_logic_do_transient_urban { my $var = 'do_transient_urban'; + # Start by assuming a default value of '.true.'. Then check a number of + # conditions under which do_transient_urban cannot be true. Under these + # conditions: (1) set default value to '.false.'; (2) make sure that the + # value is indeed false (e.g., that the user didn't try to set it to true). + + my $default_val = ".true."; + # cannot_be_true will be set to a non-empty string in any case where # do_transient_urban should not be true; if it turns out that # do_transient_urban IS true in any of these cases, a fatal error will be @@ -2731,7 +2745,7 @@ sub setup_logic_do_transient_urban { # Note that, if the variable cannot be true, we don't call add_default # - so that we don't clutter up the namelist with variables that don't # matter for this case - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var); + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, val=>$default_val); } # Make sure the value is false when it needs to be false - i.e., that the From ac53754062c041dd880aa3fca9c122feb2b5db63 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 3 Oct 2022 19:59:45 -0600 Subject: [PATCH 252/614] Correcting typo from the last commit --- bld/CLMBuildNamelist.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 0b460d2dba..1aafae5659 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2675,7 +2675,7 @@ sub setup_logic_do_transient_lakes { # Note that, if the variable cannot be true, we don't call add_default # - so that we don't clutter up the namelist with variables that don't # matter for this case - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, var=>$default_val); + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, val=>$default_val); } # Make sure the value is false when it needs to be false - i.e., that the From ea5dbae9161f630a0c95cb1fb819ae4485ba6a8d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 3 Oct 2022 20:35:34 -0600 Subject: [PATCH 253/614] Change variable haslake to pct_lake_max throughout --- .../clm/smallville_dynlakes_monthly/user_nl_clm | 2 +- src/main/clm_initializeMod.F90 | 6 +++--- src/main/clm_varsur.F90 | 2 +- src/main/subgridMod.F90 | 10 +++++----- src/main/surfrdMod.F90 | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm index 923abcdaec..aede147461 100644 --- a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm @@ -1,7 +1,7 @@ do_transient_lakes = .true. ! This file was created with the following command: -! ncap2 -s 'PCT_LAKE=array(0.0,0.0,PCT_CROP); PCT_LAKE={0.,50.,25.,25.,25.,25.}; HASLAKE=array(1.,1.,AREA); PCT_CROP=array(0.0,0.0,PCT_LAKE); PCT_CROP={0.,25.,12.,12.,12.,12.}' landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_c160127.nc landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_dynLakes_c200928.nc +! ncap2 -s 'PCT_LAKE=array(0.0,0.0,PCT_CROP); PCT_LAKE={0.,50.,25.,25.,25.,25.}; PCT_LAKE_MAX=array(1.,1.,AREA); PCT_CROP=array(0.0,0.0,PCT_LAKE); PCT_CROP={0.,25.,12.,12.,12.,12.}' landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_c160127.nc landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_dynLakes_c200928.nc ! Key points are that lake area starts as 0, increases after the first year, then decreases after the second year. ! PCT_CROP is also changed so that PCT_LAKE + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_LAKE in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.) ! Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid. diff --git a/src/main/clm_initializeMod.F90 b/src/main/clm_initializeMod.F90 index b01f2aa599..f1034d3510 100644 --- a/src/main/clm_initializeMod.F90 +++ b/src/main/clm_initializeMod.F90 @@ -16,7 +16,7 @@ module clm_initializeMod use clm_varctl , only : use_lch4, use_cn, use_cndv, use_c13, use_c14, use_fates use clm_varctl , only : use_soil_moisture_streams use clm_instur , only : wt_lunit, urban_valid, wt_nat_patch, wt_cft, fert_cft - use clm_instur , only : irrig_method, wt_glc_mec, topo_glc_mec, haslake, pct_urban_max + use clm_instur , only : irrig_method, wt_glc_mec, topo_glc_mec, pct_lake_max, pct_urban_max use perf_mod , only : t_startf, t_stopf use readParamsMod , only : readParameters use ncdio_pio , only : file_desc_t @@ -218,7 +218,7 @@ subroutine initialize2(ni,nj) allocate (irrig_method (begg:endg, cft_lb:cft_ub )) allocate (wt_glc_mec (begg:endg, maxpatch_glc )) allocate (topo_glc_mec (begg:endg, maxpatch_glc )) - allocate (haslake (begg:endg )) + allocate (pct_lake_max (begg:endg )) allocate (pct_urban_max(begg:endg, numurbl )) ! Read list of Patches and their corresponding parameter values @@ -295,7 +295,7 @@ subroutine initialize2(ni,nj) ! Some things are kept until the end of initialize2; urban_valid is kept through the ! end of the run for error checking, pct_urban_max is kept through the end of the run ! for reweighting in subgridWeights. - deallocate (wt_lunit, wt_cft, wt_glc_mec, haslake) + deallocate (wt_lunit, wt_cft, wt_glc_mec, pct_lake_max) ! Determine processor bounds and clumps for this processor call get_proc_bounds(bounds_proc) diff --git a/src/main/clm_varsur.F90 b/src/main/clm_varsur.F90 index d360941d23..8c50d9810e 100644 --- a/src/main/clm_varsur.F90 +++ b/src/main/clm_varsur.F90 @@ -47,7 +47,7 @@ module clm_instur real(r8), pointer :: topo_glc_mec(:,:) ! whether we have lake to initialise in each grid cell - logical , pointer :: haslake(:) + real(r8), pointer :: pct_lake_max(:) ! whether we have urban to initialize in each grid cell ! (second dimension goes 1:numurbl) diff --git a/src/main/subgridMod.F90 b/src/main/subgridMod.F90 index 645d02a603..7987d85cd5 100644 --- a/src/main/subgridMod.F90 +++ b/src/main/subgridMod.F90 @@ -568,11 +568,11 @@ function lake_landunit_exists(gi) result(exists) ! ! !DESCRIPTION: ! Returns true if a land unit for lakes should be created in memory - ! which is defined for gridcells which will grow lake, given by haslake + ! which is defined for gridcells which will grow lake, given by pct_lake_max ! ! !USES: use dynSubgridControlMod , only : get_do_transient_lakes - use clm_instur , only : haslake + use clm_instur , only : pct_lake_max ! ! !ARGUMENTS: logical :: exists ! function result @@ -584,10 +584,10 @@ function lake_landunit_exists(gi) result(exists) !----------------------------------------------------------------------- if (get_do_transient_lakes()) then - ! To support dynamic landunits, we initialise a lake land unit in each grid cell in which there are lakes. - ! This is defined by the haslake variable + ! To support dynamic landunits, we initialise a lake land unit in + ! each grid cell in which there are lakes as defined by pct_lake_max - if (haslake(gi)) then + if (pct_lake_max(gi) > 0._r8) then exists = .true. else exists = .false. diff --git a/src/main/surfrdMod.F90 b/src/main/surfrdMod.F90 index 057a199e25..deb8a3d93f 100644 --- a/src/main/surfrdMod.F90 +++ b/src/main/surfrdMod.F90 @@ -800,7 +800,7 @@ subroutine surfrd_lakemask(begg, endg) ! Necessary for the initialisation of the lake land units ! ! !USES: - use clm_instur , only : haslake + use clm_instur , only : pct_lake_max use dynSubgridControlMod , only : get_flanduse_timeseries use clm_varctl , only : fname_len use fileutils , only : getfil @@ -836,9 +836,9 @@ subroutine surfrd_lakemask(begg, endg) call ncd_pio_openfile (ncid_dynuse, trim(locfn), 0) ! read the lakemask - call ncd_io(ncid=ncid_dynuse, varname='HASLAKE' , flag='read', data=haslake, & + call ncd_io(ncid=ncid_dynuse, varname='PCT_LAKE_MAX' , flag='read', data=pct_lake_max, & dim1name=grlnd, readvar=readvar) - if (.not. readvar) call endrun( msg=' ERROR: HASLAKE is not on landuse.timeseries file'//errMsg(sourcefile, __LINE__)) + if (.not. readvar) call endrun( msg=' ERROR: PCT_LAKE_MAX is not on landuse.timeseries file'//errMsg(sourcefile, __LINE__)) ! close landuse_timeseries file again call ncd_pio_closefile(ncid_dynuse) From e3764434bdaa19e68b3924ad7e6796df71f431fb Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 6 Oct 2022 13:09:25 -0600 Subject: [PATCH 254/614] Remove pftmask from history and PFTDATA_MASK from fsurdat files --- src/main/histFileMod.F90 | 12 ------------ tools/mksurfdata_esmf/src/mkfileMod.F90 | 5 +---- tools/mksurfdata_esmf/src/mksurfdata.F90 | 24 ++---------------------- 3 files changed, 3 insertions(+), 38 deletions(-) diff --git a/src/main/histFileMod.F90 b/src/main/histFileMod.F90 index 5224f44ae2..9958dcc3c6 100644 --- a/src/main/histFileMod.F90 +++ b/src/main/histFileMod.F90 @@ -3346,17 +3346,6 @@ subroutine htape_timeconst(t, mode) long_name='land/ocean mask (0.=ocean and 1.=land)', ncid=nfid(t), & imissing_value=ispval, ifill_value=ispval) end if - if (ldomain%isgrid2d) then - call ncd_defvar(varname='pftmask' , xtype=ncd_int, & - dim1name='lon', dim2name='lat', & - long_name='pft real/fake mask (0.=fake and 1.=real)', ncid=nfid(t), & - imissing_value=ispval, ifill_value=ispval) - else - call ncd_defvar(varname='pftmask' , xtype=ncd_int, & - dim1name=grlnd, & - long_name='pft real/fake mask (0.=fake and 1.=real)', ncid=nfid(t), & - imissing_value=ispval, ifill_value=ispval) - end if if (ldomain%isgrid2d) then call ncd_defvar(varname='nbedrock' , xtype=ncd_int, & dim1name='lon', dim2name='lat', & @@ -3384,7 +3373,6 @@ subroutine htape_timeconst(t, mode) call ncd_io(varname='area' , data=ldomain%area, dim1name=grlnd, ncid=nfid(t), flag='write') call ncd_io(varname='landfrac', data=ldomain%frac, dim1name=grlnd, ncid=nfid(t), flag='write') call ncd_io(varname='landmask', data=ldomain%mask, dim1name=grlnd, ncid=nfid(t), flag='write') - call ncd_io(varname='pftmask' , data=ldomain%pftm, dim1name=grlnd, ncid=nfid(t), flag='write') call ncd_io(varname='nbedrock' , data=grc%nbedrock, dim1name=grlnd, ncid=nfid(t), flag='write') end if ! (define/write mode diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 09f406bc9e..6c3046a30b 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -604,10 +604,7 @@ subroutine mkfile_define_vars(pioid, dynlanduse) end if call mkpio_def_spatial_var(pioid=pioid, varname='LANDFRAC_PFT', xtype=xtype, & - long_name='land fraction from pft dataset', units='unitless') - - call mkpio_def_spatial_var(pioid=pioid, varname='PFTDATA_MASK', xtype=PIO_INT, & - long_name='land mask from pft dataset, indicative of real/fake points', units='unitless') + long_name='land fraction from pft dataset (DIFF FROM landfrac USED IN SIMULATION, SHOWN IN HISTORY)', units='unitless') if (.not. dynlanduse) then call mkpio_def_spatial_var(pioid=pioid, varname='PCT_NATVEG', xtype=xtype, & diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index a7f021e9b4..5b216671c3 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -145,7 +145,6 @@ program mksurfdata ! pct vegetation data real(r8), allocatable :: landfrac_pft(:) ! PFT data: % land per gridcell real(r8), allocatable :: pctlnd_pft(:) ! PFT data: % of gridcell for PFTs - integer , allocatable :: pftdata_mask(:) ! mask indicating real or fake land type type(pct_pft_type), allocatable :: pctnatpft(:) ! % of grid cell that is nat veg, and breakdown into PFTs type(pct_pft_type), allocatable :: pctcft(:) ! % of grid cell that is crop, and breakdown into CFTs @@ -376,13 +375,12 @@ program mksurfdata ! ----------------------------------- ! Make PFTs [pctnatpft, pctcft] from dataset [fvegtyp] - ! Make landfrac_pft and pftdata_mask + ! Make landfrac_pft ! ----------------------------------- ! Determine fractional land from pft dataset allocate(pctlnd_pft(lsize_o)); pctlnd_pft(:) = spval allocate(pctnatpft(lsize_o)) ; allocate(pctcft(lsize_o)) ; - allocate(pftdata_mask(lsize_o)) ; pftdata_mask(:) = -999 allocate(landfrac_pft(lsize_o)) ; landfrac_pft(:) = spval call mkpft( mksrf_fvegtyp_mesh, mksrf_fvegtyp, mesh_model, & pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) @@ -400,16 +398,8 @@ program mksurfdata call pctcft(n)%set_pct_l2g(0._r8) end if landfrac_pft(n) = pctlnd_pft(n)/100._r8 - if (pctlnd_pft(n) < 1.e-6_r8) then - pftdata_mask(n) = 0 - else - pftdata_mask(n) = 1 - end if end do if (fsurdat /= ' ') then - if (root_task) write(ndiag, '(a)') trim(subname)//" writing land mask from pft dataset" - call mkfile_output(pioid, mesh_model, 'PFTDATA_MASK', pftdata_mask, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') if (root_task) write(ndiag, '(a)') trim(subname)//" writing land fraction from pft dataset" call mkfile_output(pioid, mesh_model, 'LANDFRAC_PFT', landfrac_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') @@ -789,12 +779,6 @@ program mksurfdata rcode = pio_inq_varid(pioid, 'cft', pio_varid) rcode = pio_put_var(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/)) - ! Write out PFTDATA_MASK - ! pftdata_mask was calculated ABOVE - if (root_task) write(ndiag, '(a)') trim(subname)//" writing land mask (calculated in furdata calc)" - call mkfile_output(pioid, mesh_model, 'PFTDATA_MASK', pftdata_mask, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') - ! Write out LANDFRAC_PFT ! landfrac_pft was calculated ABOVE if (root_task) write(ndiag, '(a)') trim(subname)//" writing land fraction calculated in fsurdata calc)" @@ -1097,10 +1081,8 @@ subroutine normalize_and_check_landuse(ns_o) ! Assume wetland, glacier and/or lake when dataset landmask implies ocean ! (assume medium soil color (15) and loamy texture). - ! Also set pftdata_mask here if (pctlnd_pft(n) < 1.e-6_r8) then - pftdata_mask(n) = 0 if (pctgla(n) < 1.e-6_r8) then pctwet(n) = 100._r8 - pctlak(n) pctgla(n) = 0._r8 @@ -1110,8 +1092,6 @@ subroutine normalize_and_check_landuse(ns_o) pcturb(n) = 0._r8 call pctnatpft(n)%set_pct_l2g(0._r8) call pctcft(n)%set_pct_l2g(0._r8) - else - pftdata_mask(n) = 1 end if ! Make sure sum of all land cover types except natural vegetation does @@ -1265,7 +1245,7 @@ subroutine normalize_and_check_landuse(ns_o) ! Make sure that there is no vegetation outside the pft mask do n = 1,ns_o - if (pftdata_mask(n) == 0 .and. (pctnatpft(n)%get_pct_l2g() > 0 .or. pctcft(n)%get_pct_l2g() > 0)) then + if (pctlnd_pft(n) < 1.e-6_r8 .and. (pctnatpft(n)%get_pct_l2g() > 0 .or. pctcft(n)%get_pct_l2g() > 0)) then write (6,*)'vegetation found outside the pft mask at n=',n write (6,*)'pctnatveg,pctcrop=', pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() call shr_sys_abort() From 96154f62844e149ce096c804ed7539e9e4af036d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 10 Oct 2022 21:07:08 -0600 Subject: [PATCH 255/614] Update path to configure --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index b864260b70..1cf102e0fd 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -106,10 +106,10 @@ echo "Run cime configure for machine $MACH..." # You can specify the non-default compiler and mpi-library by adding --compiler and --mpilib settings if [ -z "$COMPILER" ] || [ -z "$MPILIB" ]; then echo "configure for the default MPI-library and compiler..." - $cwd/../../cime/tools/configure --macros-format CMake --machine $MACH + $cwd/../../cime/CIME/scripts/configure --macros-format CMake --machine $MACH else echo "configure for the specific MPILIB=$MPILIB and COMPILER=$COMPILER..." - $cwd/../../cime/tools/configure --macros-format CMake --machine $MACH --compiler $COMPILER --mpilib $MPILIB + $cwd/../../cime/CIME/scripts/configure --macros-format CMake --machine $MACH --compiler $COMPILER --mpilib $MPILIB fi if [ $? != 0 ]; then From ff09451ccdd47a13fc7b0170dc14a33fadc2b3ed Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 11 Oct 2022 11:28:42 -0600 Subject: [PATCH 256/614] Run through black --- python/ctsm/mksurfdata_download_input_data.py | 53 ++++++++++--------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/python/ctsm/mksurfdata_download_input_data.py b/python/ctsm/mksurfdata_download_input_data.py index a38b4935e3..a492ffeda2 100644 --- a/python/ctsm/mksurfdata_download_input_data.py +++ b/python/ctsm/mksurfdata_download_input_data.py @@ -5,7 +5,7 @@ import os import re -from CIME.case import Case # pylint: disable=import-error +from CIME.case import Case # pylint: disable=import-error from ctsm.ctsm_logging import setup_logging_pre_config, add_logging_args, process_logging_args @@ -22,15 +22,16 @@ # Public functions # ======================================================================== + def main(): - """Main function called when download_input_data is run from the command-line - """ + """Main function called when download_input_data is run from the command-line""" setup_logging_pre_config() args = _commandline_args() process_logging_args(args) download_input_data(rundir=args.rundir) + def download_input_data(rundir): """Implementation of the download_input_data command @@ -39,35 +40,36 @@ def download_input_data(rundir): """ _create_input_data_list(rundir) # TODO Remove hardwiring - case = Case(os.path.realpath('/home/slevis/cases_FATES/CZ2_acf_off')) - case.check_all_input_data( - data_list_dir=rundir, - download=True, - chksum=False) - os.remove(os.path.join(rundir, '.input_data_list')) + case = Case(os.path.realpath("/home/slevis/cases_FATES/CZ2_acf_off")) + case.check_all_input_data(data_list_dir=rundir, download=True, chksum=False) + os.remove(os.path.join(rundir, ".input_data_list")) + # ======================================================================== # Private functions # ======================================================================== + def _commandline_args(): - """Parse and return command-line arguments - """ + """Parse and return command-line arguments""" description = """ Script to download any missing input data for mksurfdata_esmf """ parser = argparse.ArgumentParser( - description=description, - formatter_class=argparse.RawTextHelpFormatter) - - parser.add_argument("--rundir", default=os.getcwd(), - help="Full path of the run directory\n" - "(This directory should contain .input_data_list and surfdata.namelist,\n" - "among other files.)\n" - "(Note: it is assumed that this directory exists alongside the other\n" - "directories created by build_ctsm: 'case' and 'inputdata'.)") + description=description, formatter_class=argparse.RawTextHelpFormatter + ) + + parser.add_argument( + "--rundir", + default=os.getcwd(), + help="Full path of the run directory\n" + "(This directory should contain .input_data_list and surfdata.namelist,\n" + "among other files.)\n" + "(Note: it is assumed that this directory exists alongside the other\n" + "directories created by build_ctsm: 'case' and 'inputdata'.)", + ) add_logging_args(parser) @@ -75,14 +77,15 @@ def _commandline_args(): return args + def _create_input_data_list(rundir): - with open(os.path.join(rundir, 'surfdata.namelist'), - encoding='utf-8') as namelist: - with open(os.path.join(rundir, '.input_data_list'), 'w', - encoding='utf-8') as input_data_list: + with open(os.path.join(rundir, "surfdata.namelist"), encoding="utf-8") as namelist: + with open( + os.path.join(rundir, ".input_data_list"), "w", encoding="utf-8" + ) as input_data_list: for line in namelist: if re.search(_FILENAME, line): # Remove quotes from filename, then output this line - line = line.replace('"', '') + line = line.replace('"', "") line = line.replace("'", "") input_data_list.write(line) From 630a2a9237d813003c371d651a4a5bc6192329e0 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 14 Oct 2022 17:05:28 -0600 Subject: [PATCH 257/614] Correction to urban file path to start with "lnd" instead of "/glade" --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 8ead40701c..26db043a02 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1725,7 +1725,7 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts 2106 /glade/p/cesmdata/inputdata/lnd/clm2/urbandata/CTSM52_tbuildmax_OlesonFeddema_2020_0.9x1.25_simyr1849-2106_c200605.nc +>lnd/clm2/urbandata/CTSM52_tbuildmax_OlesonFeddema_2020_0.9x1.25_simyr1849-2106_c200605.nc lnd/clm2/urbandata/CLM50_tbuildmax_Oleson_2016_0.9x1_ESMFmesh_cdf5_100621.nc From e522f443aa130cee4b6508db606ccdb3972ddf55 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 14 Oct 2022 17:07:36 -0600 Subject: [PATCH 258/614] Update code to expect "numurbl" dimension in landuse file --- python/ctsm/site_and_regional/single_point_case.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ctsm/site_and_regional/single_point_case.py b/python/ctsm/site_and_regional/single_point_case.py index 31ab158706..14300472da 100644 --- a/python/ctsm/site_and_regional/single_point_case.py +++ b/python/ctsm/site_and_regional/single_point_case.py @@ -356,7 +356,7 @@ def create_landuse_at_point(self, indir, file, user_mods_dir): f_out = f_out.expand_dims(["lsmlat", "lsmlon"]) # specify dimension order - f_out = f_out.transpose("time", "cft", "natpft", "lsmlat", "lsmlon") + f_out = f_out.transpose("time", "cft", "natpft", "lsmlat", "lsmlon", "numurbl") # revert expand dimensions of YEAR year = np.squeeze(np.asarray(f_out["YEAR"])) From 20ec91199f1f1d1719d8d8a51abc85a6d271d80a Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 14 Oct 2022 17:14:43 -0600 Subject: [PATCH 259/614] Correct PCT_LAKE_MAX to array(50.,0.,AREA) in user_nl_clm in testmod dir Do not expect answers to change as stated here: https://github.com/ESCOMP/CTSM/pull/1732#discussion_r987386215 --- .../testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm index aede147461..2ae2da1919 100644 --- a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm @@ -1,7 +1,7 @@ do_transient_lakes = .true. ! This file was created with the following command: -! ncap2 -s 'PCT_LAKE=array(0.0,0.0,PCT_CROP); PCT_LAKE={0.,50.,25.,25.,25.,25.}; PCT_LAKE_MAX=array(1.,1.,AREA); PCT_CROP=array(0.0,0.0,PCT_LAKE); PCT_CROP={0.,25.,12.,12.,12.,12.}' landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_c160127.nc landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_dynLakes_c200928.nc +! ncap2 -s 'PCT_LAKE=array(0.0,0.0,PCT_CROP); PCT_LAKE={0.,50.,25.,25.,25.,25.}; PCT_LAKE_MAX=array(50.,0.,AREA); PCT_CROP=array(0.0,0.0,PCT_LAKE); PCT_CROP={0.,25.,12.,12.,12.,12.}' landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_c160127.nc landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_dynLakes_c200928.nc ! Key points are that lake area starts as 0, increases after the first year, then decreases after the second year. ! PCT_CROP is also changed so that PCT_LAKE + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_LAKE in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.) ! Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid. From 06bd746d75e810a6f856702dcb7234aa082daf22 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 14 Oct 2022 17:23:18 -0600 Subject: [PATCH 260/614] Update error message --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 5b216671c3..7a549ae244 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -1212,7 +1212,7 @@ subroutine normalize_and_check_landuse(ns_o) else if (pctcft(n)%get_pct_l2g() >= 1.0_r8) then call pctcft(n)%set_pct_l2g(100._r8 - (pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n))) else - write (6,*) subname, 'Error: sum of special land units nearly 100% but none is >= 1% at ', & + write (6,*) subname, 'Error: sum of special plus crop land units nearly 100% but none is >= 1% at ', & 'n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),pctnatveg(n),pctcrop(n),suma = ', & n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(),suma From 54009456fbbc76c02e25e8e82e7d9bef4a405c86 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 14 Oct 2022 17:49:26 -0600 Subject: [PATCH 261/614] Mv certain mksoiltexture warnings to .log & output only once per warning --- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 28 ++++++++++------------ 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 295217230f..d87c3609dc 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -234,6 +234,18 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o ! Determine %sand, %clay, orgc, cfrag, bulk, phaq on output grid using ! mapunits !--------------------------------- + if (root_task) then + write(ndiag,'(a)') 'WARNING: assigning sand_o = -4 to 99%' + write(ndiag,'(a)') 'WARNING: assigning other sand_o < 0 to 43%' + write(ndiag,'(a)') 'WARNING: assigning clay_o = -4 to 1%' + write(ndiag,'(a)') 'WARNING: assigning other clay_o < 0 to 18%' + write(ndiag,'(a)') 'WARNING: assigning orgc_o = -4 to 1' + write(ndiag,'(a)') 'WARNING: assigning other orgc_o < 0 to 0' +! write(ndiag,'(a)') 'WARNING: same warnings for organic_o as for orgc_o' + write(ndiag,'(a)') 'WARNING: same warnings for cfrag_o as for orgc_o' + write(ndiag,'(a)') 'WARNING: assigning bulk_o < 0 to 1.5' + write(ndiag,'(a)') 'WARNING: assigning phaq_o < 0 to 7' + end if rcode = pio_openfile(pio_iosystem, pioid_i, pio_iotype, trim(file_lookup_i), pio_nowrite) @@ -300,7 +312,7 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o cfrag_o(no,:) = 0._r4 bulk_o(no,:) = 1.5_r4 ! TODO Ok as a fill value? phaq_o(no,:) = 7._r4 - organic_o(no,:) = 0._r4 ! TODO Rm bef merging PR #1732 + organic_o(no,:) = 0._r4 else @@ -322,10 +334,8 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o end if if (sand_o(no,1) < 0._r4) then if (int(sand_o(no,1)) == -4) then - write(6,'(a,i8)')'WARNING: changing sand_o from -4 to 99% at no = ',no sand_o(no,:) = 99._r4 else - write(6,'(a,i8,a,i8)')'WARNING: changing sand_o from ',int(sand_o(no,1)),' to 43 at no = ',no sand_o(no,:) = 43._r4 end if end if @@ -348,10 +358,8 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o end if if (clay_o(no,1) < 0._r4) then if (int(clay_o(no,1)) == -4) then - write(6,'(a,i8)')'WARNING: changing clay_o from -4 to 1% at no = ',no clay_o(no,:) = 1._r4 else - write(6,'(a,i8,a,i8)')'WARNING: changing clay_o from ',int(clay_o(no,1)),' to 18 at no = ',no clay_o(no,:) = 18._r4 end if end if @@ -382,14 +390,10 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o end if if (orgc_o(no,1) < 0._r4) then if (int(orgc_o(no,1)) == -4) then ! sand dunes - write(6,'(a,i8)')'WARNING: changing orgc_o from -4 to 1 at no = ', no orgc_o(no,:) = 1._r4 -! write(6,'(a,i8)')'WARNING: changing organic_o from -4 to 1 at no = ', no ! organic_o(no,:) = 1._r4 else - write(6,'(a,i8,a,i8)')'WARNING: changing orgc_o from ',int(orgc_o(no,1)),' to 0 at no = ',no orgc_o(no,:) = 0._r4 -! write(6,'(a,i8,a,i8)')'WARNING: changing organic_o from ',int(organic_o(no,1)),' to 0 at no = ', no ! organic_o(no,:) = 0._r4 end if end if @@ -418,10 +422,8 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o end if if (cfrag_o(no,1) < 0._r4) then if (int(cfrag_o(no,1)) == -4) then ! sand dunes - write(6,'(a,i8)')'WARNING: changing cfrag_o from -4 to 1 at no = ',no cfrag_o(no,:) = 1._r4 else - write(6,'(a,i8,a,i8)')'WARNING: changing cfrag_o from ',int(cfrag_o(no,1)),' to 0 at no = ',no cfrag_o(no,:) = 0._r4 end if end if @@ -448,10 +450,8 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o end if if (bulk_o(no,1) < 0._r4) then if (int(bulk_o(no,1)) == -4) then ! sand dunes - write(6,'(a,i8)')'WARNING: changing bulk_o from -4 to 1 at no = ',no bulk_o(no,:) = 1.5_r4 ! TODO Ok for sand dunes? else - write(6,'(a,i8,a,i8)')'WARNING: changing bulk_o from ',int(bulk_o(no,1)),' to 0 at no = ',no bulk_o(no,:) = 1.5_r4 ! TODO Ok for -7? end if end if @@ -478,10 +478,8 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o end if if (phaq_o(no,1) < 0._r4) then if (int(phaq_o(no,1)) == -4) then ! sand dunes - write(6,'(a,i8)')'WARNING: changing phaq_o from -4 to 1 at no = ',no phaq_o(no,:) = 7._r4 else - write(6,'(a,i8,a,i8)')'WARNING: changing phaq_o from ',int(phaq_o(no,1)),' to 0 at no = ',no phaq_o(no,:) = 7._r4 end if end if From df0bb20d43518d8de145d99958dc82c8bd136fd9 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 17 Oct 2022 17:15:06 -0600 Subject: [PATCH 262/614] Stop referring to personal files in README.mesh_mask_modifier --- tools/modify_input_files/README.mesh_mask_modifier | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/modify_input_files/README.mesh_mask_modifier b/tools/modify_input_files/README.mesh_mask_modifier index 13d98b9e7f..3d99355747 100644 --- a/tools/modify_input_files/README.mesh_mask_modifier +++ b/tools/modify_input_files/README.mesh_mask_modifier @@ -29,12 +29,8 @@ F-Case, modifying the continental geometry User wants to make the Indian Ocean into grassland. They specify their own land fraction mask on the CESM 1-degree grid, as well as the area to be specified as grassland in a netcdf file. This has been obtained by -modifying the default land fraction of CESM. An example netcdf file -containing the masks for such a case is on cheyenne: +modifying the default land fraction of CESM. The file contains two arrays: -/glade/work/slevis/git/mksurfdata_toolchain/tools/modify_input_files/islas_examples/modify_mesh_mask/fill_indian_ocean/fill_indianocean_slevis.nc - -This contains two arrays: - landmask = the new landmask - mod_lnd_props = set to 1 where the new land surface has been specified (i.e., where grassland needs to be specified) and zero elsewhere From 858539a6114e5b7dce4bb9db101ba9976b9e5411 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 18 Oct 2022 15:01:09 -0600 Subject: [PATCH 263/614] Bypass ch4 gridcell bal. error in hybrid/startup runs w transient lakes --- src/biogeochem/ch4Mod.F90 | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/biogeochem/ch4Mod.F90 b/src/biogeochem/ch4Mod.F90 index afb8af351b..b13165511a 100644 --- a/src/biogeochem/ch4Mod.F90 +++ b/src/biogeochem/ch4Mod.F90 @@ -1684,7 +1684,7 @@ subroutine ch4 (bounds, num_soilc, filter_soilc, num_lakec, filter_lakec, & use ch4varcon , only : replenishlakec, allowlakeprod, ch4offline use clm_varcon , only : secspday use ch4varcon , only : finundation_mtd, finundation_mtd_h2osfc - use clm_time_manager, only : is_beg_curr_year + use clm_time_manager, only : is_beg_curr_year, is_first_step use dynSubgridControlMod, only : get_do_transient_lakes ! ! !ARGUMENTS: @@ -2324,10 +2324,13 @@ subroutine ch4 (bounds, num_soilc, filter_soilc, num_lakec, filter_lakec, & ! Gricell level balance ! - ! Skip the check if it's the beginning of a new year and dynamic lakes are on - ! See (https://github.com/ESCOMP/CTSM/issues/1356#issuecomment-905963583) + ! Skip the check if dynamic lakes are on and it's + ! - the beginning of a new year (ok for restart runs) OR + ! - the beginning of a simulation (needed for hybrid/startup runs) + ! See (https://github.com/ESCOMP/CTSM/issues/43#issuecomment-1282609233) ! - if ( is_beg_curr_year() .and. get_do_transient_lakes() )then + if ( is_beg_curr_year() .and. get_do_transient_lakes() .or. & + is_first_step() .and. get_do_transient_lakes() )then ch4_first_time_grc(begg:endg) = .true. end if From 2e4dbfd11333dff1a2fca47bcb0a6d95d259fd0c Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 27 Oct 2022 13:19:05 -0600 Subject: [PATCH 264/614] Stop reading PFTDATA_MASK in surfrdMod since not on fsurdat anymore --- src/main/surfrdMod.F90 | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/main/surfrdMod.F90 b/src/main/surfrdMod.F90 index a8bbf17ec7..426a07256d 100644 --- a/src/main/surfrdMod.F90 +++ b/src/main/surfrdMod.F90 @@ -120,13 +120,6 @@ subroutine surfrd_get_data (begg, endg, ldomain, lfsurdat, actual_numcft) call getfil( lfsurdat, locfn, 0 ) call ncd_pio_openfile (ncid, trim(locfn), 0) - ! Read in patch mask - this variable is only on the surface dataset - but not - ! on the domain dataset - - call ncd_io(ncid=ncid, varname= 'PFTDATA_MASK', flag='read', data=ldomain%pftm, & - dim1name=grlnd, readvar=readvar) - if (.not. readvar) call endrun( msg=' ERROR: pftm NOT on surface dataset'//errMsg(sourcefile, __LINE__)) - ! Cmopare surfdat_domain attributes to ldomain attributes call check_var(ncid=ncid, varname='xc', readvar=readvar) From 932c28816d84493c78b3ba509c21b2013c73d931 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Fri, 28 Oct 2022 12:03:28 -0600 Subject: [PATCH 265/614] Add option to convert ocean/wetland to land Resolves ESCOMP/CTSM#1878 --- bld/CLMBuildNamelist.pm | 1 + bld/namelist_files/namelist_defaults_ctsm.xml | 3 ++ .../namelist_definition_ctsm.xml | 7 ++++ src/main/clm_varctl.F90 | 5 +++ src/main/controlMod.F90 | 4 ++ src/main/surfrdMod.F90 | 8 +++- src/main/surfrdUtilsMod.F90 | 42 ++++++++++++++++++- 7 files changed, 67 insertions(+), 3 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index ead6c054f7..797a0acfa3 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2034,6 +2034,7 @@ sub setup_logic_subgrid { my $var = 'run_zero_weight_urban'; add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var); + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'convert_ocean_to_land'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'collapse_urban', 'structure'=>$nl_flags->{'structure'}); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'n_dom_landunits', diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 8ead40701c..82910d7191 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1754,6 +1754,9 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts .false. +.false. +.true. + .false. .true. diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index a08795dd1f..ad901107d3 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -1161,6 +1161,13 @@ Toggle for vancouver specific logic. Toggle for mexico city specific logic. + +If true, any ocean (i.e., wetland) points on the surface dataset are +converted to bare ground (or whatever vegetation is given in that grid +cell - but typically this will be bare ground). + + diff --git a/src/main/clm_varctl.F90 b/src/main/clm_varctl.F90 index 9be9af2f73..208baa9be4 100644 --- a/src/main/clm_varctl.F90 +++ b/src/main/clm_varctl.F90 @@ -168,6 +168,11 @@ module clm_varctl ! true => make ALL patches, cols & landunits active (even if weight is 0) logical, public :: all_active = .false. + ! true => any ocean (i.e., "wetland") points on the surface dataset are converted to + ! bare ground (or whatever vegetation is given in that grid cell... but typically this + ! will be bare ground) + logical, public :: convert_ocean_to_land = .false. + logical, public :: collapse_urban = .false. ! true => collapse urban landunits to the dominant urban landunit; default = .false. means "do nothing" i.e. keep all urban landunits as found in the input data integer, public :: n_dom_landunits = -1 ! # of dominant landunits; determines the number of active landunits; default = 0 (set in namelist_defaults_ctsm.xml) means "do nothing" integer, public :: n_dom_pfts = -1 ! # of dominant pfts; determines the number of active pfts; default = 0 (set in namelist_defaults_ctsm.xml) means "do nothing" diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index a07228aa0d..eaa97d8230 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -259,6 +259,8 @@ subroutine control_init(dtime) ! All old cpp-ifdefs are below and have been converted to namelist variables + namelist /clm_inparm/ convert_ocean_to_land + ! Number of dominant pfts and landunits. Enhance ctsm performance by ! reducing the number of active pfts to n_dom_pfts and ! active landunits to n_dom_landunits. @@ -668,6 +670,7 @@ subroutine control_spmd() ! Other subgrid logic call mpi_bcast(run_zero_weight_urban, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast(all_active, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast(convert_ocean_to_land, 1, MPI_LOGICAL, 0, mpicom, ier) ! Number of dominant pfts and landunits. Enhance ctsm performance by ! reducing the number of active pfts to n_dom_pfts and @@ -890,6 +893,7 @@ subroutine control_print () else write(iulog,*) ' land frac data = ',trim(fatmlndfrc) end if + write(iulog,*) ' Convert ocean to land = ', convert_ocean_to_land write(iulog,*) ' Number of ACTIVE PFTS (0 means input pft data NOT collapsed to n_dom_pfts) =', n_dom_pfts write(iulog,*) ' Number of ACTIVE LANDUNITS (0 means input landunit data NOT collapsed to n_dom_landunits) =', n_dom_landunits write(iulog,*) ' Collapse urban landunits; done before collapsing all landunits to n_dom_landunits; .false. means do nothing i.e. keep all the urban landunits, though n_dom_landunits may still remove them =', collapse_urban diff --git a/src/main/surfrdMod.F90 b/src/main/surfrdMod.F90 index a8bbf17ec7..d2c37f85f6 100644 --- a/src/main/surfrdMod.F90 +++ b/src/main/surfrdMod.F90 @@ -15,7 +15,7 @@ module surfrdMod use clm_varcon , only : grlnd use clm_varctl , only : iulog use clm_varctl , only : use_cndv, use_crop, use_fates - use surfrdUtilsMod , only : check_sums_equal_1, collapse_crop_types + use surfrdUtilsMod , only : check_sums_equal_1, apply_convert_ocean_to_land, collapse_crop_types use surfrdUtilsMod , only : collapse_to_dominant, collapse_crop_var, collapse_individual_lunits use ncdio_pio , only : file_desc_t, var_desc_t, ncd_pio_openfile, ncd_pio_closefile use ncdio_pio , only : ncd_io, check_var, ncd_inqfdims, check_dim_size, ncd_inqdid, ncd_inqdlen @@ -70,7 +70,7 @@ subroutine surfrd_get_data (begg, endg, ldomain, lfsurdat, actual_numcft) ! o real % abundance PFTs (as a percent of vegetated area) ! ! !USES: - use clm_varctl , only : create_crop_landunit, collapse_urban, & + use clm_varctl , only : create_crop_landunit, convert_ocean_to_land, collapse_urban, & toosmall_soil, toosmall_crop, toosmall_glacier, & toosmall_lake, toosmall_wetland, toosmall_urban, & n_dom_landunits @@ -200,6 +200,10 @@ subroutine surfrd_get_data (begg, endg, ldomain, lfsurdat, actual_numcft) call check_sums_equal_1(wt_lunit, begg, 'wt_lunit', subname) + if (convert_ocean_to_land) then + call apply_convert_ocean_to_land(wt_lunit(begg:endg,:), begg, endg) + end if + ! if collapse_urban = .true. ! collapse urban landunits to the dominant urban landunit diff --git a/src/main/surfrdUtilsMod.F90 b/src/main/surfrdUtilsMod.F90 index 0763d43a16..95303322a4 100644 --- a/src/main/surfrdUtilsMod.F90 +++ b/src/main/surfrdUtilsMod.F90 @@ -20,7 +20,8 @@ module surfrdUtilsMod ! !PUBLIC MEMBER FUNCTIONS: public :: check_sums_equal_1 ! Confirm that sum(arr(n,:)) == 1 for all n public :: renormalize ! Renormalize an array - public :: convert_cft_to_pft ! Conversion of crop CFT to natural veg PFT:w + public :: apply_convert_ocean_to_land ! Apply the conversion of ocean to land points + public :: convert_cft_to_pft ! Conversion of crop CFT to natural veg PFT public :: collapse_crop_types ! Collapse unused crop types into types used in this run public :: collapse_individual_lunits ! Collapse landunits by user-defined thresholds public :: collapse_to_dominant ! Collapse to dominant pfts or landunits @@ -112,6 +113,45 @@ subroutine renormalize(arr, lb, normal) end subroutine renormalize + !----------------------------------------------------------------------- + subroutine apply_convert_ocean_to_land(wt_lunit, begg, endg) + ! + ! !DESCRIPTION: + ! Apply the conversion of ocean points to land, by changing all "wetland" points to + ! natveg; typically this will result in these points becoming bare ground. + ! + ! The motivation for doing this is to avoid the negative runoff that sometimes comes + ! from wetlands. + ! + ! !USES: + use landunit_varcon, only : istsoil, istwet, max_lunit + ! + ! !ARGUMENTS: + integer, intent(in) :: begg ! Beginning grid cell index + integer, intent(in) :: endg ! Ending grid cell index + ! This array is modified in-place: + real(r8), intent(inout) :: wt_lunit(begg:endg, max_lunit) ! Weights of landunits per grid cell + ! + ! !LOCAL VARIABLES: + integer :: g + + character(len=*), parameter :: subname = 'apply_convert_ocean_to_land' + !----------------------------------------------------------------------- + + ! BUG(wjs, 2022-10-27, ESCOMP/CTSM#1886) Ideally we would distinguish between ocean + ! vs. true wetland points on the surface dataset; for now oceans are included in the + ! wetland area on the surface dataset, so we convert all wetlands to land. (Typically + ! there are no true/inland wetlands on the surface dataset, so this is currently okay, + ! but this would become a problem if we started having inland wetlands on the surface + ! dataset again.) + do g = begg, endg + wt_lunit(g,istsoil) = wt_lunit(g,istsoil) + wt_lunit(g,istwet) + wt_lunit(g,istwet) = 0._r8 + end do + + end subroutine apply_convert_ocean_to_land + + !----------------------------------------------------------------------- subroutine convert_cft_to_pft( begg, endg, cftsize, wt_cft ) ! From dd00ebbba749c2132272ac01db9632a812db3a2f Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 28 Oct 2022 14:58:57 -0600 Subject: [PATCH 266/614] Update mkglacier upper tolerance from 100.000001 to 101.0 Original tolerance caused mpasa3.75 grid to fail while generating the fsurdat file, so relaxing the tolerance. Keeping a warning for when glac_o(no) > 100.000001 and truncating values > 100 back to 100. --- tools/mksurfdata_esmf/src/mkglcmecMod.F90 | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 index d3bec92b15..9a20388023 100644 --- a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 @@ -590,13 +590,18 @@ subroutine mkglacier(file_mesh_i, file_data_i, mesh_o, glac_o, rc) call regrid_rawdata(mesh_i, mesh_o, routehandle, glac_i, glac_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do no = 1,ns_o - if (glac_o(no) < 1.) glac_o(no) = 0. - enddo - do no = 1,ns_o - if ((glac_o(no)) > 100.000001_r8) then - write (6,*) 'MKGLACIER error: glacier = ',glac_o(no), & - ' greater than 100.000001 for column, row = ',no + if (glac_o(no) < 1._r8) then + glac_o(no) = 0._r8 + else if ((glac_o(no)) > 101._r8) then + write(6,*) 'MKGLACIER error: glacier = ', glac_o(no), & + ' > 101 for no = ', no call shr_sys_abort() + else if ((glac_o(no)) > 100._r8) then + if ((glac_o(no)) > 100.000001_r8) then + write(6,*) 'MKGLACIER warning: glacier = ', glac_o(no), & + ' > 100.000001 for no = ', no, ' Changing glacier > 100 to 100.' + end if + glac_o(no) = 100._r8 end if enddo From 5786052bb96df248256a50aa01212c5a6c67ac9e Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Tue, 1 Nov 2022 17:33:40 -0600 Subject: [PATCH 267/614] Don't overwrite soil properties just because pctlnd_pft is small It doesn't seem like there's any reason why we need to overwrite soil properties with a default value just because pctlnd_pft is small. Doing so was fine when we turned those grid cells into wetland, but now that we aren't necessarily doing that, it makes sense to keep valid soil data wherever we have it. This could change answers in places where we have valid soil data despite pctlnd_pft being near 0. --- tools/mksurfdata_esmf/src/mksoilcolMod.F90 | 12 ++---------- tools/mksurfdata_esmf/src/mksoiltexMod.F90 | 7 +++---- tools/mksurfdata_esmf/src/mksurfdata.F90 | 4 ++-- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 index 25ba6956b0..6fa9600f3c 100644 --- a/tools/mksurfdata_esmf/src/mksoilcolMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilcolMod.F90 @@ -29,13 +29,12 @@ module mksoilcolMod contains !================================================================================= - subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, pctlnd_pft_o, pioid_o, rc) + subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, pioid_o, rc) ! input/output variables character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesho - real(r8) , intent(in) :: pctlnd_pft_o(:) type(file_desc_t) , intent(inout) :: pioid_o integer , intent(out) :: rc @@ -185,13 +184,6 @@ subroutine mksoilcol(file_data_i, file_mesh_i, mesh_o, pctlnd_pft_o, pioid_o, rc end if end do - ! assume medium soil color (15) and loamy texture if pct_lndpft is small - do no = 1,ns_o - if (pctlnd_pft_o(no) < 1.e-6_r8) then - soil_color_o(no) = 15 - end if - end do - ! Write output data if (root_task) write(ndiag, '(a)') trim(subname)//" writing out soil color" call mkfile_output(pioid_o, mesh_o, 'SOIL_COLOR', soil_color_o, rc=rc) @@ -277,7 +269,7 @@ subroutine get_dominant_soilcol(dynamicMaskList, dynamicSrcMaskValue, dynamicDst soil_color_o = maxindex(1) end if - ! If land but no color, set color to 15 (in older dataset generic soil color 4) + ! If no color, set color to 15 (in older dataset generic soil color 4) if (num_soilcolors == 8) then if (soil_color_o == 0) then soil_color_o = 4 diff --git a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 index 295217230f..ae975a9ed9 100644 --- a/tools/mksurfdata_esmf/src/mksoiltexMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoiltexMod.F90 @@ -33,7 +33,7 @@ module mksoiltexMod contains !================================================================================= - subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o, pctlnd_pft_o, rc) + subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o, rc) ! ! make %sand, %clay, organic carbon content, coarse fragments, bulk density, ! and pH measured in H2O @@ -44,7 +44,6 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o character(len=*) , intent(in) :: file_lookup_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! output mesh type(file_desc_t) , intent(inout) :: pioid_o - real(r8) , intent(in) :: pctlnd_pft_o(:) ! PFT data: % of gridcell for PFTs integer , intent(out) :: rc ! local variables @@ -291,9 +290,9 @@ subroutine mksoiltex(file_mesh_i, file_mapunit_i, file_lookup_i, mesh_o, pioid_o do no = 1,ns_o - if (pctlnd_pft_o(no) < 1.e-6_r8 .or. mapunit_o(no) == 0) then + if (mapunit_o(no) == 0) then - ! Set sand and clay to loam if pctlnd_pft is < 1.e-6 or mapunit is 0 + ! Set sand and clay to loam if mapunit is 0 sand_o(no,:) = 43._r4 clay_o(no,:) = 18._r4 orgc_o(no,:) = 0._r4 diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 5b216671c3..6a542d36bb 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -458,7 +458,7 @@ program mksurfdata ! ----------------------------------- if (fsurdat /= ' ') then call mksoiltex( mksrf_fsoitex_mesh, file_mapunit_i=mksrf_fsoitex, file_lookup_i=mksrf_fsoitex_lookup, & - mesh_o=mesh_model, pioid_o=pioid, pctlnd_pft_o=pctlnd_pft, rc=rc) + mesh_o=mesh_model, pioid_o=pioid, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') end if @@ -467,7 +467,7 @@ program mksurfdata ! ----------------------------------- if (fsurdat /= ' ') then ! SOIL_COLOR and mxsoil_color is written out in the subroutine - call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, pctlnd_pft, pioid, rc) + call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, pioid, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilcol') end if From 27ab891ccf0849cfd83ac58d728bb8e7943b55a5 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Tue, 1 Nov 2022 18:13:27 -0600 Subject: [PATCH 268/614] Remove a comment that is no longer true --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 6a542d36bb..526a999a84 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -1080,7 +1080,6 @@ subroutine normalize_and_check_landuse(ns_o) pctgla(n) = float(nint(pctgla(n))) ! Assume wetland, glacier and/or lake when dataset landmask implies ocean - ! (assume medium soil color (15) and loamy texture). if (pctlnd_pft(n) < 1.e-6_r8) then if (pctgla(n) < 1.e-6_r8) then From 137bd5d1292514c7ad1b4d7867b039f418c44243 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Mon, 7 Nov 2022 17:36:50 -0700 Subject: [PATCH 269/614] Add a note --- bld/namelist_files/namelist_definition_ctsm.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index ad901107d3..ffd6ea53eb 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -1165,7 +1165,8 @@ Toggle for mexico city specific logic. group="clm_inparm" value=".false."> If true, any ocean (i.e., wetland) points on the surface dataset are converted to bare ground (or whatever vegetation is given in that grid -cell - but typically this will be bare ground). +cell - but typically this will be bare ground due to lack of vegetation +in grid cells with 100% ocean). Date: Fri, 11 Nov 2022 14:02:14 -0700 Subject: [PATCH 270/614] Add a norm_by_fracs argument to create_routehandle This will allow switching between FRACAREA and DSTAREA normalization; we'll use the latter for PCT areas. --- tools/mksurfdata_esmf/src/mkVICparamsMod.F90 | 3 +- tools/mksurfdata_esmf/src/mkesmfMod.F90 | 42 +++++++++++++++++-- tools/mksurfdata_esmf/src/mkgdpMod.F90 | 3 +- .../src/mkglacierregionMod.F90 | 3 +- tools/mksurfdata_esmf/src/mkglcmecMod.F90 | 6 ++- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 3 +- tools/mksurfdata_esmf/src/mklaiMod.F90 | 3 +- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 9 ++-- tools/mksurfdata_esmf/src/mkpeatMod.F90 | 3 +- tools/mksurfdata_esmf/src/mkpftMod.F90 | 3 +- tools/mksurfdata_esmf/src/mksoildepthMod.F90 | 6 ++- tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 | 3 +- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 6 ++- tools/mksurfdata_esmf/src/mkvocefMod.F90 | 3 +- 14 files changed, 74 insertions(+), 22 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 index 7742eb282a..5f69152e2d 100644 --- a/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkVICparamsMod.F90 @@ -116,7 +116,8 @@ subroutine mkVICparams(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! Create a route handle between the input and output mesh allocate(frac_o(ns_o)) - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle, frac_o=frac_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) do n = 1, ns_o diff --git a/tools/mksurfdata_esmf/src/mkesmfMod.F90 b/tools/mksurfdata_esmf/src/mkesmfMod.F90 index ee31104b80..893b1fec80 100644 --- a/tools/mksurfdata_esmf/src/mkesmfMod.F90 +++ b/tools/mksurfdata_esmf/src/mkesmfMod.F90 @@ -27,11 +27,21 @@ module mkesmfMod contains !=============================================================== - subroutine create_routehandle_r4(mesh_i, mesh_o, routehandle, frac_o, rc) + subroutine create_routehandle_r4(mesh_i, mesh_o, norm_by_fracs, routehandle, frac_o, rc) ! input/output variables type(ESMF_Mesh) , intent(in) :: mesh_i type(ESMF_Mesh) , intent(in) :: mesh_o + ! If norm_by_fracs is .true., then remapping is done using ESMF_NORMTYPE_FRACAREA; + ! otherwise, remapping is done using ESMF_NORMTYPE_DSTAREA. FRACAREA normalization + ! adds a normalization factor of the fraction of the unmasked source grid that + ! overlaps with a destination cell. FRACAREA normalization is appropriate when you + ! want to treat values outside the mask as missing values that shouldn't contribute + ! to the average (this is appropriate for most fields); DSTAREA normalization is + ! appropriate when you want to treat values outside the mask as 0 (this is + ! appropriate for PCT cover fields where we want the final value to be expressed as + ! percent of the entire gridcell area). + logical , intent(in) :: norm_by_fracs type(ESMF_RouteHandle) , intent(inout) :: routehandle real(r4), optional , intent(inout) :: frac_o(:) integer , intent(out) :: rc @@ -40,6 +50,7 @@ subroutine create_routehandle_r4(mesh_i, mesh_o, routehandle, frac_o, rc) integer :: srcMaskValue = 0 ! ignore source points where the mesh mask is 0 integer :: dstMaskValue = -987987 ! don't ingore any destination points integer :: srcTermProcessing_Value = 0 + type(ESMF_NormType_Flag) :: normtype type(ESMF_Field) :: field_i type(ESMF_Field) :: field_o type(ESMF_Field) :: dstfracfield @@ -56,9 +67,15 @@ subroutine create_routehandle_r4(mesh_i, mesh_o, routehandle, frac_o, rc) dstfracfield = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (norm_by_fracs) then + normtype = ESMF_NORMTYPE_FRACAREA + else + normtype = ESMF_NORMTYPE_DSTAREA + end if + ! Create route handle to map field_model to field_data call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_FRACAREA, & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=normtype, & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & srcTermProcessing=srcTermProcessing_Value, & @@ -83,11 +100,21 @@ subroutine create_routehandle_r4(mesh_i, mesh_o, routehandle, frac_o, rc) end subroutine create_routehandle_r4 !=============================================================== - subroutine create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o, rc) + subroutine create_routehandle_r8(mesh_i, mesh_o, norm_by_fracs, routehandle, frac_o, rc) ! input/output variables type(ESMF_Mesh) , intent(in) :: mesh_i type(ESMF_Mesh) , intent(in) :: mesh_o + ! If norm_by_fracs is .true., then remapping is done using ESMF_NORMTYPE_FRACAREA; + ! otherwise, remapping is done using ESMF_NORMTYPE_DSTAREA. FRACAREA normalization + ! adds a normalization factor of the fraction of the unmasked source grid that + ! overlaps with a destination cell. FRACAREA normalization is appropriate when you + ! want to treat values outside the mask as missing values that shouldn't contribute + ! to the average (this is appropriate for most fields); DSTAREA normalization is + ! appropriate when you want to treat values outside the mask as 0 (this is + ! appropriate for PCT cover fields where we want the final value to be expressed as + ! percent of the entire gridcell area). + logical , intent(in) :: norm_by_fracs type(ESMF_RouteHandle) , intent(inout) :: routehandle real(r8), optional , intent(inout) :: frac_o(:) integer , intent(out) :: rc @@ -96,6 +123,7 @@ subroutine create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o, rc) integer :: srcMaskValue = 0 ! ignore source points where the mesh mask is 0 integer :: dstMaskValue = -987987 ! don't ingore any destination points integer :: srcTermProcessing_Value = 0 + type(ESMF_NormType_Flag) :: normtype type(ESMF_Field) :: field_i type(ESMF_Field) :: field_o type(ESMF_Field) :: dstfracfield @@ -112,9 +140,15 @@ subroutine create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o, rc) dstfracfield = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (norm_by_fracs) then + normtype = ESMF_NORMTYPE_FRACAREA + else + normtype = ESMF_NORMTYPE_DSTAREA + end if + ! Create route handle to map field_model to field_data call ESMF_FieldRegridStore(field_i, field_o, routehandle=routehandle, & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=ESMF_NORMTYPE_FRACAREA, & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, normType=normtype, & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & srcTermProcessing=srcTermProcessing_Value, & diff --git a/tools/mksurfdata_esmf/src/mkgdpMod.F90 b/tools/mksurfdata_esmf/src/mkgdpMod.F90 index 801ba5e604..cb37de8bbd 100644 --- a/tools/mksurfdata_esmf/src/mkgdpMod.F90 +++ b/tools/mksurfdata_esmf/src/mkgdpMod.F90 @@ -111,7 +111,8 @@ subroutine mkgdp(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! Create a route handle between the input and output mesh and get frac_o allocate(frac_o(ns_o),stat=ier) if (ier/=0) call shr_sys_abort() - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle, frac_o=frac_o, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) diff --git a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 index 176271a48c..267e46ddfa 100644 --- a/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglacierregionMod.F90 @@ -117,7 +117,8 @@ subroutine mkglacierregion(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! Create a route handle between the input and output mesh allocate(frac_o(ns_o)) if (ier/=0) call abort() - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle, frac_o=frac_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) diff --git a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 index 9a20388023..343e772de7 100644 --- a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 @@ -284,7 +284,8 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! Create a route handle between the input and output mesh and get frac_o allocate(frac_o(ns_o),stat=ier) if (ier/=0) call shr_sys_abort(subname//" error in allocating frac_o") - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle, frac_o=frac_o, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) @@ -580,7 +581,8 @@ subroutine mkglacier(file_mesh_i, file_data_i, mesh_o, glac_o, rc) ! Create a route handle between the input and output mesh and get frac_o allocate(frac_o(ns_o),stat=ier) if (ier/=0) call shr_sys_abort() - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle, frac_o=frac_o, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index ac5fbf69d0..6e219a2164 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -153,7 +153,8 @@ subroutine mkharvest(file_mesh_i, file_data_i, mesh_o, pioid_o, ntime, rc) ! NOTE: this must be done after mask_i is set in mesh_i if (.not. ESMF_RouteHandleIsCreated(routehandle_r8)) then allocate(frac_o(ns_o)) - call create_routehandle_r8(mesh_i, mesh_o, routehandle_r8, frac_o=frac_o, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle_r8, frac_o=frac_o, rc=rc) call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) end if diff --git a/tools/mksurfdata_esmf/src/mklaiMod.F90 b/tools/mksurfdata_esmf/src/mklaiMod.F90 index 84069bded4..ba1014c2b9 100644 --- a/tools/mksurfdata_esmf/src/mklaiMod.F90 +++ b/tools/mksurfdata_esmf/src/mklaiMod.F90 @@ -121,7 +121,8 @@ subroutine mklai(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! Create a route handle between the input and output mesh allocate(frac_o(ns_o)) - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle, frac_o=frac_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 90c8cf2b0a..b6802ea6b6 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -116,7 +116,8 @@ subroutine mkpctlak(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, rc) ! Create a route handle between the input and output mesh if (.not. ESMF_RouteHandleIsCreated(routehandle_mklak)) then allocate(frac_o_mklak(ns_o)) - call create_routehandle_r8(mesh_i, mesh_o, routehandle_mklak, frac_o=frac_o_mklak, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle_mklak, frac_o=frac_o_mklak, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) end if @@ -255,7 +256,8 @@ subroutine mklakdep(file_mesh_i, file_data_i, mesh_o, pioid_o, fsurdat, rc) ! Create a route handle between the input and output mesh if (.not. ESMF_RouteHandleIsCreated(routehandle_mklak)) then allocate(frac_o_mklak(ns_o)) - call create_routehandle_r8(mesh_i, mesh_o, routehandle_mklak, frac_o=frac_o_mklak, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle_mklak, frac_o=frac_o_mklak, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) end if @@ -402,7 +404,8 @@ subroutine mkwetlnd(file_mesh_i, file_data_i, mesh_o, swmp_o, rc) ! Create a route handle between the input and output mesh allocate(frac_o(ns_o)) - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle, frac_o=frac_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) diff --git a/tools/mksurfdata_esmf/src/mkpeatMod.F90 b/tools/mksurfdata_esmf/src/mkpeatMod.F90 index 6dad412427..3acd93b755 100644 --- a/tools/mksurfdata_esmf/src/mkpeatMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpeatMod.F90 @@ -108,7 +108,8 @@ subroutine mkpeat(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! Create a route handle between the input and output mesh and get frac_o allocate(frac_o(ns_o),stat=ier) if (ier/=0) call shr_sys_abort() - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle, frac_o=frac_o, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index 0062940513..3ab941c6a0 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -331,7 +331,8 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & if (.not. ESMF_RouteHandleIsCreated(routehandle)) then allocate(frac_o(ns_o),stat=ier) if (ier/=0) call shr_sys_abort() - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle, frac_o=frac_o, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) end if diff --git a/tools/mksurfdata_esmf/src/mksoildepthMod.F90 b/tools/mksurfdata_esmf/src/mksoildepthMod.F90 index e8f09b20aa..9b7b44f709 100644 --- a/tools/mksurfdata_esmf/src/mksoildepthMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoildepthMod.F90 @@ -87,7 +87,8 @@ subroutine mksoildepth(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! Get the landmask from the file and reset the mesh mask based on that allocate(frac_o(ns_o),stat=ier) if (ier/=0) call shr_sys_abort() - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle, frac_o=frac_o, rc=rc) call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) allocate(frac_i(ns_i), stat=ier) if (ier/=0) call shr_sys_abort() @@ -106,7 +107,8 @@ subroutine mksoildepth(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle between the input and output mesh and get frac_o - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle, frac_o=frac_o, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) do no = 1, ns_o diff --git a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 index 65534ed00a..22cf159849 100644 --- a/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 +++ b/tools/mksurfdata_esmf/src/mksoilfmaxMod.F90 @@ -102,7 +102,8 @@ subroutine mksoilfmax(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) ! Create a route handle between the input and output mesh allocate(frac_o(ns_o)) - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle, frac_o=frac_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) do n = 1, ns_o diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index b25a34a34c..c16cb6682e 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -184,7 +184,8 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, & ! Create a route handle between the input and output mesh if (.not. ESMF_RouteHandleIsCreated(routehandle_mkurban)) then allocate(frac_o_mkurban(ns_o)) - call create_routehandle_r8(mesh_i, mesh_o, routehandle_mkurban, frac_o=frac_o_mkurban, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle_mkurban, frac_o=frac_o_mkurban, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) end if @@ -938,7 +939,8 @@ subroutine mkurban_topo(file_mesh_i, file_data_i, mesh_o, varname, elev_o, rc) ! Create a route handle between the input and output mesh allocate(frac_o(ns_o), stat=ier) if (ier/=0) call shr_sys_abort() - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle, frac_o=frac_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) diff --git a/tools/mksurfdata_esmf/src/mkvocefMod.F90 b/tools/mksurfdata_esmf/src/mkvocefMod.F90 index ae95bb5a14..6aa8ba6ec4 100644 --- a/tools/mksurfdata_esmf/src/mkvocefMod.F90 +++ b/tools/mksurfdata_esmf/src/mkvocefMod.F90 @@ -122,7 +122,8 @@ subroutine mkvocef(file_mesh_i, file_data_i, mesh_o, pioid_o, lat_o, rc) ! Create a route handle between the input and output mesh allocate(frac_o(ns_o)) - call create_routehandle_r8(mesh_i, mesh_o, routehandle, frac_o=frac_o, rc=rc) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle, frac_o=frac_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) From 80e89efe96e8fb0b54a6513c45f675b2fb8a8d9f Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Sat, 12 Nov 2022 05:29:51 -0700 Subject: [PATCH 271/614] Map PCT fields using DSTAREA normalization Partially addresses ESCOMP/CTSM#1716 --- tools/mksurfdata_esmf/src/mkglcmecMod.F90 | 46 ++++++++------- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 64 +++++++++++---------- tools/mksurfdata_esmf/src/mkpftMod.F90 | 34 +++++------ tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 28 +++++---- 4 files changed, 94 insertions(+), 78 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 index 343e772de7..25fa4a8edc 100644 --- a/tools/mksurfdata_esmf/src/mkglcmecMod.F90 +++ b/tools/mksurfdata_esmf/src/mkglcmecMod.F90 @@ -134,7 +134,7 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) integer , intent(out) :: rc ! local variables: - type(ESMF_RouteHandle) :: routehandle ! nearest neighbor routehandle + type(ESMF_RouteHandle) :: routehandle_nonorm type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid_i type(var_desc_t) :: pio_varid @@ -148,7 +148,7 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) integer :: nlev ! number of levels in input file integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) - real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: frac_o_nonorm(:) real(r8), allocatable :: area_i(:) real(r8), allocatable :: area_o(:) real(r8), allocatable :: data_pctglc_i(:) @@ -281,11 +281,13 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) call mkpio_iodesc_rawdata(mesh_i, 'PCT_GLC_GIC', pioid_i, pio_varid, pio_vartype, pio_iodesc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Create a route handle between the input and output mesh and get frac_o - allocate(frac_o(ns_o),stat=ier) - if (ier/=0) call shr_sys_abort(subname//" error in allocating frac_o") - call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & - routehandle=routehandle, frac_o=frac_o, rc=rc) + ! Create a route handle between the input and output mesh and get frac_o_nonorm + allocate(frac_o_nonorm(ns_o),stat=ier) + if (ier/=0) call shr_sys_abort(subname//" error in allocating frac_o_nonorm") + ! Note that norm_by_fracs is false in the following because this routehandle is + ! used to map fields that are expressed in terms of % of the grid cell. + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.false., & + routehandle=routehandle_nonorm, frac_o=frac_o_nonorm, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) @@ -308,11 +310,11 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) data_pctglc_i(:) = data_pctglc_gic_i(:) + data_pctglc_icesheet_i(:) ! Map level of data to output grid - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_pctglc_i, data_pctglc_o, rc=rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle_nonorm, data_pctglc_i, data_pctglc_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_pctglc_gic_i, data_pctglc_gic_o, rc=rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle_nonorm, data_pctglc_gic_i, data_pctglc_gic_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, data_pctglc_icesheet_i, data_pctglc_icesheet_o, rc=rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle_nonorm, data_pctglc_icesheet_i, data_pctglc_icesheet_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Compute output variables @@ -470,7 +472,7 @@ subroutine mkglcmec(file_mesh_i, file_data_i, mesh_o, pioid_o, rc) end if ! Deallocate dynamic memory - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + call ESMF_RouteHandleDestroy(routehandle_nonorm, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() @@ -506,14 +508,14 @@ subroutine mkglacier(file_mesh_i, file_data_i, mesh_o, glac_o, rc) integer , intent(out) :: rc ! ! local variables - type(ESMF_RouteHandle) :: routehandle + type(ESMF_RouteHandle) :: routehandle_nonorm type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid integer :: ni,no,k integer :: ns_i, ns_o integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) - real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: frac_o_nonorm(:) real(r8), allocatable :: area_i(:) real(r8), allocatable :: area_o(:) real(r8), allocatable :: glac_i(:) ! input grid: percent glac @@ -578,18 +580,20 @@ subroutine mkglacier(file_mesh_i, file_data_i, mesh_o, glac_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) - ! Create a route handle between the input and output mesh and get frac_o - allocate(frac_o(ns_o),stat=ier) + ! Create a route handle between the input and output mesh and get frac_o_nonorm + allocate(frac_o_nonorm(ns_o),stat=ier) if (ier/=0) call shr_sys_abort() - call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & - routehandle=routehandle, frac_o=frac_o, rc=rc) + ! Note that norm_by_fracs is false in the following because this routehandle is + ! used to map fields that are expressed in terms of % of the grid cell. + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.false., & + routehandle=routehandle_nonorm, frac_o=frac_o_nonorm, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) ! Area-average percent cover on input grid to output grid (with correction for landmask) ! Note that percent cover is in terms of total grid area. ! Regrid glac_i to glac_o - call regrid_rawdata(mesh_i, mesh_o, routehandle, glac_i, glac_o, rc=rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle_nonorm, glac_i, glac_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do no = 1,ns_o if (glac_o(no) < 1._r8) then @@ -608,13 +612,13 @@ subroutine mkglacier(file_mesh_i, file_data_i, mesh_o, glac_o, rc) enddo ! Check global areas - call output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o, & + call output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o_nonorm, & glac_i, glac_o, "pct glacier", percent=.true., ndiag=ndiag, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Deallocate dynamic memory - deallocate (glac_i, frac_o, mask_i) - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + deallocate (glac_i, frac_o_nonorm, mask_i) + call ESMF_RouteHandleDestroy(routehandle_nonorm, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index b6802ea6b6..b4160a830c 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -25,8 +25,8 @@ module mklanwatMod public :: mkwetlnd ! make %wetland public :: update_max_array_lake ! Update the maximum lake percent - real(r8), allocatable :: frac_o_mklak(:) - type(ESMF_RouteHandle) :: routehandle_mklak + real(r8), allocatable :: frac_o_mklak_nonorm(:) + type(ESMF_RouteHandle) :: routehandle_mklak_nonorm character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -114,10 +114,12 @@ subroutine mkpctlak(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle between the input and output mesh - if (.not. ESMF_RouteHandleIsCreated(routehandle_mklak)) then - allocate(frac_o_mklak(ns_o)) - call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & - routehandle=routehandle_mklak, frac_o=frac_o_mklak, rc=rc) + if (.not. ESMF_RouteHandleIsCreated(routehandle_mklak_nonorm)) then + allocate(frac_o_mklak_nonorm(ns_o)) + ! Note that norm_by_fracs is false in the following because this routehandle is + ! used to map fields that are expressed in terms of % of the grid cell. + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.false., & + routehandle=routehandle_mklak_nonorm, frac_o=frac_o_mklak_nonorm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) end if @@ -138,14 +140,14 @@ subroutine mkpctlak(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Regrid lake_i to lake_o - call regrid_rawdata(mesh_i, mesh_o, routehandle_mklak, lake_i, lake_o, rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle_mklak_nonorm, lake_i, lake_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do no = 1,ns_o if (lake_o(no) < 1.) lake_o(no) = 0. enddo ! Check global areas - call output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o_mklak, & + call output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o_mklak_nonorm, & lake_i, lake_o, "pct lake", percent=.true., ndiag=ndiag, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -159,8 +161,8 @@ subroutine mkpctlak(file_mesh_i, file_data_i, mesh_o, lake_o, pioid_o, rc) ! Release memory if (mksrf_fdynuse == ' ') then ! ...else we will reuse it - deallocate(frac_o_mklak) - call ESMF_RouteHandleDestroy(routehandle_mklak, nogarbage = .true., rc=rc) + deallocate(frac_o_mklak_nonorm) + call ESMF_RouteHandleDestroy(routehandle_mklak_nonorm, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() end if call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) @@ -193,9 +195,11 @@ subroutine mklakdep(file_mesh_i, file_data_i, mesh_o, pioid_o, fsurdat, rc) ! local variables type(ESMF_Mesh) :: mesh_i + type(ESMF_RouteHandle) :: routehandle type(file_desc_t) :: pioid_i integer , allocatable :: mask_i(:) real(r8), allocatable :: rmask_i(:) + real(r8), allocatable :: frac_o(:) real(r8), allocatable :: lakedepth_i(:) ! iput grid: lake depth (m) real(r8), allocatable :: lakedepth_o(:) ! output grid: lake depth (m) integer :: ni,no,k ! indices @@ -254,13 +258,11 @@ subroutine mklakdep(file_mesh_i, file_data_i, mesh_o, pioid_o, fsurdat, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle between the input and output mesh - if (.not. ESMF_RouteHandleIsCreated(routehandle_mklak)) then - allocate(frac_o_mklak(ns_o)) - call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & - routehandle=routehandle_mklak, frac_o=frac_o_mklak, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) - end if + allocate(frac_o(ns_o)) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & + routehandle=routehandle, frac_o=frac_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) ! ---------------------------------------- ! Create lake parameter (lakedepth) @@ -278,11 +280,11 @@ subroutine mklakdep(file_mesh_i, file_data_i, mesh_o, pioid_o, fsurdat, rc) ! regrid lakedepth_i to lakedepth_o - this also returns lakedepth_i to be used in the global sums below allocate (lakedepth_o(ns_o)); lakedepth_o(:) = spval - call regrid_rawdata(mesh_i, mesh_o, routehandle_mklak, lakedepth_i, lakedepth_o, rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle, lakedepth_i, lakedepth_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regrid_rawdata for lakedepth in "//trim(subname)) do no = 1,ns_o - if (frac_o_mklak(no) == 0._r8) then + if (frac_o(no) == 0._r8) then lakedepth_o(no) = 10._r8 end if enddo @@ -300,7 +302,7 @@ subroutine mklakdep(file_mesh_i, file_data_i, mesh_o, pioid_o, fsurdat, rc) ! Check global areas for lake depth call output_diagnostics_continuous(mesh_i, mesh_o, & lakedepth_i, lakedepth_o, "lake depth", "m", & - ndiag=ndiag, rc=rc, mask_i=mask_i, frac_o=frac_o_mklak) + ndiag=ndiag, rc=rc, mask_i=mask_i, frac_o=frac_o) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! ---------------------------------------- @@ -310,8 +312,8 @@ subroutine mklakdep(file_mesh_i, file_data_i, mesh_o, pioid_o, fsurdat, rc) call pio_closefile(pioid_i) ! Release memory - deallocate(frac_o_mklak) - call ESMF_RouteHandleDestroy(routehandle_mklak, nogarbage = .true., rc=rc) + deallocate(frac_o) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() @@ -339,12 +341,12 @@ subroutine mkwetlnd(file_mesh_i, file_data_i, mesh_o, swmp_o, rc) integer , intent(out) :: rc ! local variables - type(ESMF_RouteHandle) :: routehandle + type(ESMF_RouteHandle) :: routehandle_nonorm type(ESMF_Mesh) :: mesh_i type(file_desc_t) :: pioid_i integer , allocatable :: mask_i(:) real(r8), allocatable :: rmask_i(:) - real(r8), allocatable :: frac_o(:) + real(r8), allocatable :: frac_o_nonorm(:) real(r8), allocatable :: swmp_i(:) ! input grid: percent wetland integer :: ni,no,k ! indices integer :: ns_i,ns_o ! local sizes @@ -403,9 +405,11 @@ subroutine mkwetlnd(file_mesh_i, file_data_i, mesh_o, swmp_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle between the input and output mesh - allocate(frac_o(ns_o)) - call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & - routehandle=routehandle, frac_o=frac_o, rc=rc) + allocate(frac_o_nonorm(ns_o)) + ! Note that norm_by_fracs is false in the following because this routehandle is + ! used to map fields that are expressed in terms of % of the grid cell. + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.false., & + routehandle=routehandle_nonorm, frac_o=frac_o_nonorm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) @@ -416,7 +420,7 @@ subroutine mkwetlnd(file_mesh_i, file_data_i, mesh_o, swmp_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! regrid swmp_i to swmp_o - this also returns swmp_i to be used in the global sums below - call regrid_rawdata(mesh_i, mesh_o, routehandle, swmp_i, swmp_o, rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle_nonorm, swmp_i, swmp_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regrid_data for wetland") if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -425,7 +429,7 @@ subroutine mkwetlnd(file_mesh_i, file_data_i, mesh_o, swmp_o, rc) enddo ! Check global areas - call output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o, & + call output_diagnostics_area(mesh_i, mesh_o, mask_i, frac_o_nonorm, & swmp_i, swmp_o, "pct wetland", percent=.true., ndiag=ndiag, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -433,7 +437,7 @@ subroutine mkwetlnd(file_mesh_i, file_data_i, mesh_o, swmp_o, rc) call pio_closefile(pioid_i) ! Release memory - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + call ESMF_RouteHandleDestroy(routehandle_nonorm, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index 3ab941c6a0..cb3899fd44 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -24,8 +24,8 @@ module mkpftMod integer :: m ! index character(len=35) :: veg(0:maxpft) ! vegetation types - real(r8), allocatable :: frac_o(:) - type(ESMF_RouteHandle) :: routehandle + real(r8), allocatable :: frac_o_nonorm(:) + type(ESMF_RouteHandle) :: routehandle_nonorm character(len=*) , parameter :: u_FILE_u = & __FILE__ @@ -250,7 +250,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & real(r8), allocatable :: glob_gpft_o(:) ! output global area pfts integer :: ier, rcode ! error status real(r8) :: relerr = 0.0001_r8 ! max error: sum overlap wts ne 1 - character(len=*), parameter :: subname = 'mkpf' + character(len=*), parameter :: subname = 'mkpft' !----------------------------------------------------------------------- if (root_task) then @@ -326,13 +326,15 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & endif ! ---------------------------------------- - ! Create a route handle between the input and output mesh and get frac_o + ! Create a route handle between the input and output mesh and get frac_o_nonorm ! ---------------------------------------- - if (.not. ESMF_RouteHandleIsCreated(routehandle)) then - allocate(frac_o(ns_o),stat=ier) + if (.not. ESMF_RouteHandleIsCreated(routehandle_nonorm)) then + allocate(frac_o_nonorm(ns_o),stat=ier) if (ier/=0) call shr_sys_abort() - call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & - routehandle=routehandle, frac_o=frac_o, rc=rc) + ! Note that norm_by_fracs is false in the following because this routehandle is + ! used to map fields that are expressed in terms of % of the grid cell. + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.false., & + routehandle=routehandle_nonorm, frac_o=frac_o_nonorm, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) end if @@ -340,7 +342,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & ! ---------------------------------------- ! Determine pctlnd_o(:) (in/out argument) ! ---------------------------------------- - pctlnd_o(:) = frac_o(:) * 100._r8 + pctlnd_o(:) = frac_o_nonorm(:) * 100._r8 ! ---------------------------------------- ! Determine pct_nat_pft_o(:,:) @@ -357,7 +359,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & if (chkerr(rc,__LINE__,u_FILE_u)) return ! Regrid to determine pctnatveg_o - call regrid_rawdata(mesh_i, mesh_o, routehandle, pctnatveg_i, pctnatveg_o, rc=rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle_nonorm, pctnatveg_i, pctnatveg_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return allocate(pct_nat_pft_i(0:num_natpft,ns_i)) @@ -375,7 +377,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & end do ! Readgrid to determine pct_nat_pft_o - call regrid_rawdata(mesh_i, mesh_o, routehandle, pct_nat_pft_i, pct_nat_pft_o, 0, num_natpft, rc=rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle_nonorm, pct_nat_pft_i, pct_nat_pft_o, 0, num_natpft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Rescale pct_nat_pft_o @@ -420,7 +422,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & if (ier/=0) call shr_sys_abort() call mkpio_get_rawdata(pioid, 'PCT_CROP', mesh_i, pctcrop_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call regrid_rawdata(mesh_i, mesh_o, routehandle, pctcrop_i, pctcrop_o, rc=rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle_nonorm, pctcrop_i, pctcrop_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return allocate(pct_cft_i(1:num_cft,ns_i), stat=ier) @@ -464,7 +466,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & end do ! Readgrid pct_cft_i to determine pct_cft_o - call regrid_rawdata(mesh_i, mesh_o, routehandle, pct_cft_i, pct_cft_o, 1, num_cft, rc=rc) + call regrid_rawdata(mesh_i, mesh_o, routehandle_nonorm, pct_cft_i, pct_cft_o, 1, num_cft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Rescale pct_nat_pft_o @@ -538,7 +540,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & loc_gpft_o(:) = 0. do no = 1,ns_o do m = 0, numpft_i-1 - loc_gpft_o(m) = loc_gpft_o(m) + pctpft_o(no,m) * area_o(no) * frac_o(no) + loc_gpft_o(m) = loc_gpft_o(m) + pctpft_o(no,m) * area_o(no) * frac_o_nonorm(no) end do end do do m = 0,numpft_i-1 @@ -562,8 +564,8 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & ! Clean up memory if (mksrf_fdynuse == ' ') then ! ...else we will reuse it - deallocate(frac_o) - call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + deallocate(frac_o_nonorm) + call ESMF_RouteHandleDestroy(routehandle_nonorm, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() end if call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index c16cb6682e..05ec0cafe5 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -42,8 +42,8 @@ module mkurbanparMod ! private data members: ! flag to indicate nodata for index variables in output file: integer , parameter :: index_nodata = 0 - real(r8) , allocatable :: frac_o_mkurban(:) - type(ESMF_RouteHandle) :: routehandle_mkurban + real(r8) , allocatable :: frac_o_mkurban_nonorm(:) + type(ESMF_RouteHandle) :: routehandle_mkurban_nonorm character(len=*), parameter :: modname = 'mkurbanparMod' private :: index_nodata @@ -182,10 +182,10 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, & if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create a route handle between the input and output mesh - if (.not. ESMF_RouteHandleIsCreated(routehandle_mkurban)) then - allocate(frac_o_mkurban(ns_o)) - call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.true., & - routehandle=routehandle_mkurban, frac_o=frac_o_mkurban, rc=rc) + if (.not. ESMF_RouteHandleIsCreated(routehandle_mkurban_nonorm)) then + allocate(frac_o_mkurban_nonorm(ns_o)) + call create_routehandle_r8(mesh_i=mesh_i, mesh_o=mesh_o, norm_by_fracs=.false., & + routehandle=routehandle_mkurban_nonorm, frac_o=frac_o_mkurban_nonorm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After create routehandle in "//trim(subname)) end if @@ -203,7 +203,9 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, & call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) ! Regrid input data to model resolution - call regrid_rawdata(mesh_i, mesh_o, routehandle_mkurban, data_i, data_o, 1, numurbl, rc) + ! + ! Use a nonorm mapper because we're mapping a field expressed as % of the grid cell area + call regrid_rawdata(mesh_i, mesh_o, routehandle_mkurban_nonorm, data_i, data_o, 1, numurbl, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regrid_data for in "//trim(subname)) @@ -301,7 +303,11 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, & if (allocated(data_o)) deallocate(data_o) allocate(data_o(max_regions, ns_o), stat=ier) if (ier/=0) call shr_sys_abort('error allocating data_i(max_regions, ns_o)') - call regrid_rawdata(mesh_i, mesh_o, routehandle_mkurban, data_i, data_o, 1, nregions, rc) + ! This regridding could be done either with or without fracarea normalization, + ! because we just use it to find a dominant value. We use nonorm because we already + ! have a nonorm mapper for the sake of PCTURB and this way we don't need to make a + ! separate mapper with fracarea normalization. + call regrid_rawdata(mesh_i, mesh_o, routehandle_mkurban_nonorm, data_i, data_o, 1, nregions, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Now find dominant region in each output gridcell - this is identical to the maximum index @@ -319,7 +325,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, & end if ! Output diagnostics - call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o_mkurban, & + call output_diagnostics_index(mesh_i, mesh_o, mask_i, frac_o_mkurban_nonorm, & 1, max_regions, region_i, region_o, 'urban region', ndiag, rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() @@ -331,9 +337,9 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, & ! TODO: determine what to deallocate ! deallocate (urban_classes_gcell_i, urban_classes_gcell_o, region_i) if (mksrf_fdynuse == ' ') then ! ...else we will reuse it - deallocate(frac_o_mkurban) + deallocate(frac_o_mkurban_nonorm) call ESMF_VMLogMemInfo("Before destroy operation in "//trim(subname)) - call ESMF_RouteHandleDestroy(routehandle_mkurban, nogarbage = .true., rc=rc) + call ESMF_RouteHandleDestroy(routehandle_mkurban_nonorm, nogarbage = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() end if call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) From dc8cb25b930577d97f6559cbca590067fb63cd53 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Tue, 15 Nov 2022 13:14:19 -0700 Subject: [PATCH 272/614] Remove / rework some redundant adjustments based on pctlnd_pft Do some rework of adjustments now that we are mapping pctnatveg and pctcrop with DSTAREA rather than FRACAREA normalization - so they end up as percent of the grid cell rather than percent of the land area. The end result won't be identical in all cases, but in practice it should do the same thing as before. - Zero out pctnatveg and pctcrop if their areas are less than 1e-6, rather than the previous logic of zeroing these if pctlnd is less than 1e-6. (This zeroing is now done in mkpft rather than in the main mksurfdata program.) - In deciding whether to set pct_nat_pft or pct_cft to a fixed value, only check for tiny values of pctnatveg / pctcrop, rather than checking for a tiny value of pctlnd (it should now be the case that a tiny value of pctlnd implies tiny values of pctnatveg and pctcrop as well). - Remove the check for no vegetation outside the pft mask. This check no longer seems important and risks doing more harm than good if the threshold for this check differs slightly from the threshold used to zero pctnatveg / pctcrop. --- tools/mksurfdata_esmf/src/mkpftMod.F90 | 16 ++++++---------- tools/mksurfdata_esmf/src/mksurfdata.F90 | 13 ------------- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index cb3899fd44..162b462db2 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -380,16 +380,14 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & call regrid_rawdata(mesh_i, mesh_o, routehandle_nonorm, pct_nat_pft_i, pct_nat_pft_o, 0, num_natpft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Rescale pct_nat_pft_o + ! Rescale pct_nat_pft_o, and set tiny pctnatveg to 0 do no = 1,ns_o - if (pctnatveg_o(no) > 0._r8) then + if (pctnatveg_o(no) >= 1.0e-6_r8) then do m = 0,num_natpft pct_nat_pft_o(m,no) = pct_nat_pft_o(m,no) / (pctnatveg_o(no) * 0.01_r8) end do else - pct_nat_pft_o(0:num_natpft,no) = 0._r8 - end if - if (pctlnd_o(no) < 1.0e-6 .or. pctnatveg_o(no) < 1.0e-6) then + pctnatveg_o(no) = 0._r8 pct_nat_pft_o(0,no) = 100._r8 pct_nat_pft_o(1:num_natpft,no) = 0._r8 end if @@ -469,16 +467,14 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & call regrid_rawdata(mesh_i, mesh_o, routehandle_nonorm, pct_cft_i, pct_cft_o, 1, num_cft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Rescale pct_nat_pft_o + ! Rescale pct_cft_o, and set tiny pctcrop to 0 do no = 1,ns_o - if (pctcrop_o(no) > 0._r8) then + if (pctcrop_o(no) >= 1.0e-6_r8) then do m = 1,num_cft pct_cft_o(m,no) = pct_cft_o(m,no) / (pctcrop_o(no) * 0.01_r8) end do else - pct_cft_o(1:num_cft,no) = 0._r8 - end if - if (pctlnd_o(no) < 1.0e-6 .or. pctcrop_o(no) < 1.0e-6) then + pctcrop_o(no) = 0._r8 pct_cft_o(1,no) = 100._r8 pct_cft_o(2:num_cft,no) = 0._r8 end if diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 526a999a84..d637df378d 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -393,10 +393,6 @@ program mksurfdata call pctnatpft(n)%set_pct_l2g(0._r8) call pctcft(n)%set_pct_l2g(0._r8) end if - if (pctlnd_pft(n) < 1.e-6_r8) then - call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) - end if landfrac_pft(n) = pctlnd_pft(n)/100._r8 end do if (fsurdat /= ' ') then @@ -1242,15 +1238,6 @@ subroutine normalize_and_check_landuse(ns_o) end do - ! Make sure that there is no vegetation outside the pft mask - do n = 1,ns_o - if (pctlnd_pft(n) < 1.e-6_r8 .and. (pctnatpft(n)%get_pct_l2g() > 0 .or. pctcft(n)%get_pct_l2g() > 0)) then - write (6,*)'vegetation found outside the pft mask at n=',n - write (6,*)'pctnatveg,pctcrop=', pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() - call shr_sys_abort() - end if - end do - ! Make sure that sums at the landunit level all add to 100% ! (Note that we don't check pctglcmec here, because it isn't computed at the point ! that this subroutine is called -- but the check of sum(pctglcmec) is done in From d83278cb6b86608fba0b36419db3633f3c29dafd Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Wed, 16 Nov 2022 13:01:33 -0700 Subject: [PATCH 273/614] Use LANDFRAC instead of mask for setting pctlnd_pft --- tools/mksurfdata_esmf/src/mkpftMod.F90 | 16 +++++++++-- tools/mksurfdata_esmf/src/mksurfdata.F90 | 35 ++++++++++-------------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkpftMod.F90 b/tools/mksurfdata_esmf/src/mkpftMod.F90 index 162b462db2..54827e7ad3 100644 --- a/tools/mksurfdata_esmf/src/mkpftMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftMod.F90 @@ -209,7 +209,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & character(len=*) , intent(in) :: file_mesh_i ! input mesh file name character(len=*) , intent(in) :: file_data_i ! input data file name type(ESMF_Mesh) , intent(in) :: mesh_o ! model mesh - real(r8) , intent(inout) :: pctlnd_o(:) ! output grid:%land/gridcell + real(r8) , intent(out) :: pctlnd_o(:) ! output grid:%land/gridcell type(pct_pft_type), intent(inout) :: pctnatpft_o(:) ! natural PFT cover type(pct_pft_type), intent(inout) :: pctcft_o(:) ! crop (CFT) cover @@ -234,6 +234,7 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & real(r8), allocatable :: output_pct_cft_o(:,:) integer , allocatable :: mask_i(:) real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: pctlnd_i(:) ! input land fraction real(r8), allocatable :: pctnatveg_i(:) ! input natural veg percent (% of grid cell) real(r8), allocatable :: pctnatveg_o(:) ! output natural veg percent (% of grid cell) real(r8), allocatable :: pctcrop_i(:) ! input all crop percent (% of grid cell) @@ -340,9 +341,18 @@ subroutine mkpft(file_mesh_i, file_data_i, mesh_o, pctlnd_o, pctnatpft_o, & end if ! ---------------------------------------- - ! Determine pctlnd_o(:) (in/out argument) + ! Determine pctlnd_o(:) ! ---------------------------------------- - pctlnd_o(:) = frac_o_nonorm(:) * 100._r8 + allocate(pctlnd_i(ns_i), stat=ier) + if (ier/=0) call shr_sys_abort('error allocating pctlnd_i') + + call mkpio_get_rawdata(pioid, 'LANDFRAC', mesh_i, pctlnd_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call regrid_rawdata(mesh_i, mesh_o, routehandle_nonorm, pctlnd_i, pctlnd_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Convert from fraction to percent: + pctlnd_o(:) = pctlnd_o(:) * 100._r8 ! ---------------------------------------- ! Determine pct_nat_pft_o(:,:) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index d637df378d..a2eecb1af5 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -878,26 +878,21 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpft') call pio_syncfile(pioid) -! ! Consistency check on input land fraction -! ! pctlnd_pft was calculated ABOVE -! ! TODO This error check serves no purpose now that mkpft calls -! ! create_routehandle_r8 only once and, therefore, doesn't update -! ! frac_o and pctlnd_o. Delete? (slevis) -! do n = 1,lsize_o -! if (pctlnd_pft_dyn(n) /= pctlnd_pft(n)) then -! if (root_task) then -! write(ndiag,*) subname,' error: pctlnd_pft for dynamics data = ',& -! pctlnd_pft_dyn(n), ' not equal to pctlnd_pft for surface data = ',& -! pctlnd_pft(n),' at n= ',n -! if ( trim(fname) == ' ' )then -! write(ndiag,*) ' PFT string = ',trim(string) -! else -! write(ndiag,*) ' PFT file = ', fname -! end if -! end if -! call shr_sys_abort() -! end if -! end do + ! Consistency check on input land fraction + ! pctlnd_pft was calculated ABOVE + do n = 1,lsize_o + if (pctlnd_pft_dyn(n) /= pctlnd_pft(n)) then + write(ndiag,*) subname,' error: pctlnd_pft for dynamics data = ',& + pctlnd_pft_dyn(n), ' not equal to pctlnd_pft for surface data = ',& + pctlnd_pft(n),' at n= ',n + if ( trim(fname) == ' ' )then + write(ndiag,*) ' PFT string = ',trim(string) + else + write(ndiag,*) ' PFT file = ', fname + end if + call shr_sys_abort() + end if + end do ! Create harvesting data at model resolution ! Output data is written in mkharvest From e29e26c81d670a9e33300db167ef88fed4e92bb9 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Tue, 22 Nov 2022 15:56:05 -0700 Subject: [PATCH 274/614] Rework calculation of wetland area and normalization of landunits This rework makes things work correctly given that the landunit areas coming into normalize_and_check_landuse are in % of grid cell, but the outputs are in % of land area. Addresses much of the remainder of ESCOMP/CTSM#1716. Especially see https://github.com/ESCOMP/CTSM/issues/1716#issuecomment-1322557821 --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 159 ++++++++++++++++++----- 1 file changed, 124 insertions(+), 35 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index a2eecb1af5..eb91be30c7 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -1046,6 +1046,11 @@ subroutine normalize_and_check_landuse(ns_o) ! Normalize land use and make sure things add up to 100% as well as ! checking that things are as they should be. ! + ! Coming into this subroutine, landunit areas are expressed as percent of the + ! gridcell and are NOT normalized to sum to 100%. Coming out of this subroutine, + ! landunit areas are expressed as percent of the land portion of the gridcell and + ! ARE normalized to sum to 100%. + ! ! input/output variables: integer, intent(in) :: ns_o @@ -1054,49 +1059,23 @@ subroutine normalize_and_check_landuse(ns_o) integer :: nsmall ! number of small PFT values for a single check integer :: nsmall_tot ! total number of small PFT values in all grid cells real(r8) :: suma ! sum for error check + real(r8) :: pct_land ! area considered to be land (% of grid cell) + real(r8) :: frac_land ! area considered to be land (fraction of grid cell) real(r8) :: new_total_natveg_pct ! new % veg (% of grid cell, natural veg) real(r8), parameter :: tol_loose = 1.e-4_r8 ! tolerance for some 'loose' error checks real(r8), parameter :: toosmallPFT = 1.e-10_r8 ! tolerance for PFT's to ignore - character(len=32) :: subname = 'normalizencheck_landuse' ! subroutine name + character(len=32) :: subname = 'normalize_and_check_landuse' ! subroutine name !----------------------------------------------------------------------- do n = 1,ns_o ! Truncate all percentage fields on output grid. This is needed to - ! insure that wt is zero (not a very small number such as + ! ensure that wt is zero (not a very small number such as ! 1e-16) where it really should be zero - pctlak(n) = float(nint(pctlak(n))) pctwet(n) = float(nint(pctwet(n))) pctgla(n) = float(nint(pctgla(n))) - ! Assume wetland, glacier and/or lake when dataset landmask implies ocean - - if (pctlnd_pft(n) < 1.e-6_r8) then - if (pctgla(n) < 1.e-6_r8) then - pctwet(n) = 100._r8 - pctlak(n) - pctgla(n) = 0._r8 - else - pctwet(n) = max(100._r8 - pctgla(n) - pctlak(n), 0.0_r8) - end if - pcturb(n) = 0._r8 - call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) - end if - - ! Make sure sum of all land cover types except natural vegetation does - ! not exceed 100. If it does, subtract excess from these land cover - ! types proportionally. - - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() - if (suma > 100._r4) then - pctlak(n) = pctlak(n) * 100._r8/suma - pctwet(n) = pctwet(n) * 100._r8/suma - pcturb(n) = pcturb(n) * 100._r8/suma - pctgla(n) = pctgla(n) * 100._r8/suma - call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8/suma) - end if - ! Check preconditions if ( pctlak(n) < 0.0_r8 )then write(6,*) subname, ' ERROR: pctlak is negative!' @@ -1124,6 +1103,18 @@ subroutine normalize_and_check_landuse(ns_o) call shr_sys_abort() end if + ! Make sure sum of all land cover types except natural vegetation does + ! not exceed 100. If it does, subtract excess from these land cover + ! types proportionally. + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() + if (suma > 100._r4) then + pctlak(n) = pctlak(n) * 100._r8/suma + pctwet(n) = pctwet(n) * 100._r8/suma + pcturb(n) = pcturb(n) * 100._r8/suma + pctgla(n) = pctgla(n) * 100._r8/suma + call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() * 100._r8/suma) + end if + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() if (suma > (100._r8 + tol_loose)) then write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla + pctcrop must be' @@ -1133,13 +1124,111 @@ subroutine normalize_and_check_landuse(ns_o) call shr_sys_abort() end if - ! Natural vegetated cover is 100% minus the sum of all other landunits + ! Determine the percent of each grid cell considered to be land. (See comments in + ! https://github.com/ESCOMP/CTSM/issues/1716 for details.) + ! + ! Start by using the land fraction field from the PFT raw data set: + pct_land = pctlnd_pft(n) + ! + ! But we don't want to overwrite special landunits or crop with ocean where these + ! special landunits extend beyond the PFT data's land fraction. In essence, this + ! is saying that we'll let special landunit area grow into the natveg area before + ! growing into ocean, but we'll have special landunit area grow into ocean before + ! growing into crop or any other special landunit area. (This check of special + ! landunit area is particularly important for glaciers, where we can have + ! floating ice shelves, so we can have a scenario where pctlnd_pft is 0 but we + ! have non-zero glacier cover and we want the final grid cell to be + ! glacier-covered.) (We could possibly do better by considering the land mask + ! from each special landunit raw dataset, and even better by mapping these + ! various notions of land mask onto each other, but that starts to get messy, and + ! relies on the trustworthiness of each raw dataset's land mask... this + ! formulation seems reasonable enough.) + ! + ! Note that we include pct_crop in the following, but NOT pct_natveg. The + ! assumption behind that is that pct_crop is more reliable and/or more important, + ! and should not be overwritten, whereas pct_natveg can be overwritten with a + ! special landunit. For example, consider a case where the PFT dataset specifies + ! 40% land, with 20% crop and 10% natveg (so, implicitly, 10% special landunits). + ! If the only special landunit is glacier and it has 15% cover, then we want to + ! end up with the glacier overwriting natural veg, so we end up with 20% crop, 5% + ! natveg, 15% glacier and 60% ocean. However, if glacier has 30% cover, then we + ! will assume that some of that glacier extends over the ocean rather than + ! overwriting crop, so we end up with 20% crop, 30% glacier, 50% ocean and 0% + ! natveg. + ! + ! Another reason for excluding pct_natveg from the following is more pragmatic: + ! Typically, we expect the initial sum of all landunit areas to approximately + ! equal pctlnd_pft. This means that, in a coastal grid cell, if we included all + ! landunit areas in the following sum, then in many cases we would take the + ! final pct_land from the landunit sum rather than from pctlnd_pft. But in this + ! scenario where we take pct_land from the landunit sum, it is likely that + ! pct_land will vary from year to year on the landuse timeseries file. This + ! variation from year to year will cause a renormalization of all landunits, + ! leading to changes in the areas of landunits that should really stay fixed + ! from one year to the next. By excluding pct_natveg we give more wiggle room: + ! it will usually be the case that we take the final pct_land from pctlnd_pft, + ! which stays fixed in time, so that the renormalization stays the same from one + ! year to the next. The possible downside is that pct_natveg may end up varying + ! more than is ideal, but this seems better than letting all of the other + ! landunits vary when they should stay fixed. + ! + ! Also, note that this landunit sum agrees with the suma sums elsewhere; this + ! agreement may be important in some cases (so that if we changed the set of + ! landunits included in the sum here, some other changes may be needed below.) + pct_land = max(pct_land, suma) + ! + ! Make sure that we're not ending up with > 100% land area. This can arise if the + ! sum of special landunits exceeds 100% by roundoff; also, due to rounding + ! errors, pctlnd_pft may slightly differ from 100% when it should really be + ! exactly 100%; we want pct_land to be exactly 100% in this case: + if (pct_land > (100._r8 - 1.e-4_r8)) then + pct_land = 100._r8 + end if - new_total_natveg_pct = 100._r8 - suma - ! correct for rounding error: - new_total_natveg_pct = max(new_total_natveg_pct, 0._r8) + if (pct_land < 1.e-6_r8) then + ! If we have essentially 0 land area, set land area to exactly 0 and put all + ! area in wetlands (to simulate ocean). Note that, based on the formulation + ! for pct_land above, this should only arise if the non-natveg landunits + ! already have near-zero area, so the zeroing of these other landunits should + ! only result in changes near the roundoff level. + pct_land = 0._r8 + frac_land = 0._r8 + call pctnatpft(n)%set_pct_l2g(0._r8) + call pctcft(n)%set_pct_l2g(0._r8) + pctlak(n) = 0._r8 + pcturb(n) = 0._r8 + pctgla(n) = 0._r8 + pctwet(n) = 100._r8 + else + ! Fill the rest of the land area with natveg, then renormalize landunits so + ! that they are expressed as percent of the land area rather than percent of + ! the full gridcell area. + + ! First fill the rest of the land area with natveg: + new_total_natveg_pct = pct_land - suma + ! Based on the formulation of pct_land above, pct_land is guaranteed to be at + ! least as large as suma. However, correct it just in case there is rounding + ! error: + new_total_natveg_pct = max(new_total_natveg_pct, 0._r8) + + ! Now renormalize landunit areas so they are expressed as percent of the land + ! area rather than percent of the total gridcell area. Note that we have + ! already corrected pct_land above so that if it was slightly less than 100 + ! it was set to exactly 100, so we can check for any values less than 100 + ! here (rather than having some tolerance): + frac_land = pct_land / 100._r8 + if (pct_land < 100._r8) then + new_total_natveg_pct = new_total_natveg_pct / frac_land + call pctcft(n)%set_pct_l2g(pctcft(n)%get_pct_l2g() / frac_land) + pctlak(n) = pctlak(n) / frac_land + pcturb(n) = pcturb(n) / frac_land + pctgla(n) = pctgla(n) / frac_land + pctwet(n) = pctwet(n) / frac_land + end if - call pctnatpft(n)%set_pct_l2g(new_total_natveg_pct) + ! Finally, set the actual pct_natveg: + call pctnatpft(n)%set_pct_l2g(new_total_natveg_pct) + end if ! Confirm that we have done the rescaling correctly: now the sum of all landunits ! should be 100% within tol_loose From 277db0f9a36892470410e82d0e222c4bcecbaad1 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Thu, 1 Dec 2022 16:34:36 -0700 Subject: [PATCH 275/614] Add documentation of the specification of landunit areas --- doc/design/surface_dataset_areas.rst | 39 ++++++++++++++++++++++++ tools/mksurfdata_esmf/src/mksurfdata.F90 | 6 ++-- 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 doc/design/surface_dataset_areas.rst diff --git a/doc/design/surface_dataset_areas.rst b/doc/design/surface_dataset_areas.rst new file mode 100644 index 0000000000..ce2c96fac2 --- /dev/null +++ b/doc/design/surface_dataset_areas.rst @@ -0,0 +1,39 @@ +.. sectnum:: + +.. contents:: + +================================== + Overview of this design document +================================== + +This document gives a high-level overview of the specification of sub-grid areas on surface datasets and the raw datasets used to create them. + +See also https://github.com/ESCOMP/CTSM/issues/1716 for related discussion. + +================================================= + Specification of landunit areas in raw datasets +================================================= + +In the high-resolution raw datasets used as input to the mksurfdata tool, landunit areas should be specified as percent of the grid cell, **not** percent of the land area. For example, on the urban raw dataset, if there is a grid cell that is 50% land and 50% ocean, and 60% of the land area is urban, the urban area in that grid cell should be given as 30%. + +One reason for this is that it makes reconciling the different landunit areas more straightforward if different raw datasets disagree about the land mask. In addition, this convention makes it easier to map raw datasets to the model resolution. For example, consider averaging two grid cells into a destination grid cell: one with 2% land area, of which 50% is glacier; and one with 100% land area, of which none is glacier. If we encode these as percent of the land area, we would have 50% glacier and 0% glacier, and then the final glacier cover would be 25%, suggesting that 25% of the land area is glacier, but this is incorrect. If we instead encode these as percent of the total grid cell area, we would have 1% glacier and 0% glacier, and then the final glacier cover would be 0.5%, suggesting that 0.5% of the total grid cell is glacier, which is correct. + +===================================================== + Specification of landunit areas in surface datasets +===================================================== + +In contrast to the raw datasets, landunit areas in surface datasets are specified as percent of the land area, **not** as percent of the total grid cell. This is because we don't know what the model's actual land fraction will be at the time when the surface datasets are created: instead, this land fraction is determined at runtime based on the ocean grid. + +=========================================================================================== + Procedure for converting landunit areas from percent of grid cell to percent of land area +=========================================================================================== + +There are a few important aspects to how we determine final landunit areas in mksurfdata: + +When mapping landunit areas from the raw data resolution to the model resolution, we initially want to maintain areas as percent of the total grid cell area. To achieve this, we set ``norm_by_fracs=.false.`` in the call to ``create_routehandle``, resulting in the use of ``ESMF_NORMTYPE_DSTAREA`` rather than ``ESMF_NORMTYPE_FRACAREA`` as a ``normType`` when computing mapping weights. Using ``FRACAREA`` normalization is appropriate when you want to treat areas outside of the source mask as missing values that do not contribute in any way to the final destination value. Using ``DSTAREA`` normalization, in contrast, essentially treats areas outside of the source mask as zeroes. ``FRACAREA`` normalization is appropriate for many surface dataset fields, but ``DSTAREA`` is appropriate for areas specified as percent of the grid cell. For example, if a source grid cell is entirely ocean, then we want to treat glacier area in that source grid cell as 0%. + +The conversion from percent of the grid cell area to percent of the land area happens in the subroutine ``normalize_and_check_landuse``. An important piece of doing this conversion is to determine an estimate of the land fraction for each model grid cell. This is not straightforward given the disparate land masks used for each raw dataset. We start by using the land fraction from the vegetation (PFT) raw dataset, with the assumption that that is probably the most reliable land mask. However, there are areas where using that land fraction is problematic, particularly where the areas of other landunits extend beyond the PFT's land mask. This is especially an issue for glaciers, where floating ice shelves can extend beyond the land-ocean border. To deal with this problem, if the sum of the areas of special landunits and crops exceeds the land fraction from the PFT data, we instead use that sum as an estimate of the land fraction. Exactly which landunits to include in this sum is a bit arbitrary. Arguably, the natural vegetated landunit should also be included in this sum. However, we ideally want to avoid changes in this estimated land fraction through time in transient datasets, which means that we generally want to use the PFT data's land fraction, only falling back on this landunit sum in exceptional cases. By excluding the natural vegetated area from this sum, we are more likely to use the PFT's land fraction. An implication of this choice is that we are more likely to replace natural vegetated areas with special landunits in cases where there are disagreements between the different raw datasets in coastal grid cells. For more detailed explanation and rationale, see some comments in ``normalize_and_check_landuse``. + +In grid cells where the estimated land fraction is essentially zero, we set the land cover to wetland, as a rough parameterization of ocean. This situation will only arise if the areas of all landunits on the raw datasets are essentially zero for the given grid cell, so we would have no information to choose any particular land cover for the grid cell. (This wetland area may end up being changed to bare ground at runtime, depending on the value of the ``convert_ocean_to_land`` namelist flag.) + +In grid cells where the estimated land fraction is greater than zero, we fill any unclaimed land area with the natural vegetated landunit. We then normalize all landunit areas based on the estimated land fraction so that they now specify areas as percent of the land area rather than as percent of the grid cell. diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index eb91be30c7..09fe291cd5 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -1189,8 +1189,10 @@ subroutine normalize_and_check_landuse(ns_o) ! If we have essentially 0 land area, set land area to exactly 0 and put all ! area in wetlands (to simulate ocean). Note that, based on the formulation ! for pct_land above, this should only arise if the non-natveg landunits - ! already have near-zero area, so the zeroing of these other landunits should - ! only result in changes near the roundoff level. + ! already have near-zero area (and the natveg landunit should also have + ! near-zero area in this case, because its area should be no greater than the + ! land fraction from the PFT raw dataset), so the zeroing of these other + ! landunits should only result in changes near the roundoff level. pct_land = 0._r8 frac_land = 0._r8 call pctnatpft(n)%set_pct_l2g(0._r8) From 4ee2a0012b613334cd204c49bdb119c72327b850 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Thu, 1 Dec 2022 16:58:03 -0700 Subject: [PATCH 276/614] Add example scenarios --- doc/design/surface_dataset_areas.rst | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/doc/design/surface_dataset_areas.rst b/doc/design/surface_dataset_areas.rst index ce2c96fac2..de12f951da 100644 --- a/doc/design/surface_dataset_areas.rst +++ b/doc/design/surface_dataset_areas.rst @@ -37,3 +37,33 @@ The conversion from percent of the grid cell area to percent of the land area ha In grid cells where the estimated land fraction is essentially zero, we set the land cover to wetland, as a rough parameterization of ocean. This situation will only arise if the areas of all landunits on the raw datasets are essentially zero for the given grid cell, so we would have no information to choose any particular land cover for the grid cell. (This wetland area may end up being changed to bare ground at runtime, depending on the value of the ``convert_ocean_to_land`` namelist flag.) In grid cells where the estimated land fraction is greater than zero, we fill any unclaimed land area with the natural vegetated landunit. We then normalize all landunit areas based on the estimated land fraction so that they now specify areas as percent of the land area rather than as percent of the grid cell. + +=================== + Example scenarios +=================== + +The following example scenarios illustrate the operation of ``normalize_and_check_landuse``; in the following, any landunit not explicitly mentioned has 0% area: + +(a) With pctlnd_pft = 0% and all initial landunit areas 0%: wetland area = 100% + +(b) With pctlnd_pft = 0% and initial glacier area 1%: glacier area = 100% + +(c) With pctlnd_pft > 0% and all initial landunit areas 0%: natural vegetated area = 100% + +(d) With pctlnd_pft = 40%, initial crop area 20%, natural vegetated area 10%: crop area = 50%, natural vegetated area = 50% + +(e) With pctlnd_pft = 40%, initial crop area 20%, natural vegetated area 10%, glacier area 10%: crop area = 50%, natural vegetated area = 25%, glacier area = 25% + +(f) With pctlnd_pft = 40%, initial crop area 20%, natural vegetated area 10%, glacier area 15%: crop area = 50%, natural vegetated area = 12.5%, glacier area = 37.5% + +(g) With pctlnd_pft = 40%, initial crop area 20%, natural vegetated area 10%, glacier area 20%: crop area = 50%, glacier area = 50% + +(h) With pctlnd_pft = 40%, initial crop area 20%, natural vegetated area 10%, glacier area 30%: crop area = 40%, glacier area = 60% + +(i) With pctlnd_pft = 40%, initial crop area 0%, natural vegetated area 40%, glacier area 40%: glacier area = 100% + +(j) With pctlnd_pft = 2%, initial natural vegetated area 1%, glacier area 1%: natural vegetated area = 50%, glacier area = 50% + +(k) With pctlnd_pft = 2%, initial natural vegetated area 0%, glacier area 1%: natural vegetated area = 50%, glacier area = 50% + +(l) With pctlnd_pft = 2%, initial natural vegetated area 2%, glacier area 1%: natural vegetated area = 50%, glacier area = 50% From 344c12abe4c081fad3f95bf3eed2504ca8e7a27f Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Fri, 2 Dec 2022 05:47:17 -0700 Subject: [PATCH 277/614] Fix minor copy and paste error in error message --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 09fe291cd5..e3ea832926 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -1008,7 +1008,7 @@ program mksurfdata if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CROP_MAX" call get_pct_l2g_array(pctcft_max, pctcrop) call mkfile_output(pioid, mesh_model, 'PCT_CROP_MAX', pctcrop, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP') + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP_MAX') if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_URBAN_MAX" call mkfile_output(pioid, mesh_model, 'PCT_URBAN_MAX', pcturb_max, rc=rc) From d48239391fed0ed923c705ae5e98ab873b17ce15 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Fri, 2 Dec 2022 06:31:42 -0700 Subject: [PATCH 278/614] Write LANDFRAC_MKSURFDATA to surface dataset and landuse timeseries --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 11 +++++++++++ tools/mksurfdata_esmf/src/mksurfdata.F90 | 20 +++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 6c3046a30b..335a9a508b 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -606,6 +606,17 @@ subroutine mkfile_define_vars(pioid, dynlanduse) call mkpio_def_spatial_var(pioid=pioid, varname='LANDFRAC_PFT', xtype=xtype, & long_name='land fraction from pft dataset (DIFF FROM landfrac USED IN SIMULATION, SHOWN IN HISTORY)', units='unitless') + if (.not. dynlanduse) then + call mkpio_def_spatial_var(pioid=pioid, varname='LANDFRAC_MKSURFDATA', xtype=xtype, & + long_name='land fraction used for renormalization of areas in mksurfdata (DIFF FROM landfrac USED IN SIMULATION)', & + units='unitless') + else + call mkpio_def_spatial_var(pioid=pioid, varname='LANDFRAC_MKSURFDATA', xtype=xtype, & + lev1name='time', & + long_name='land fraction used for renormalization of areas in mksurfdata (DIFF FROM landfrac USED IN SIMULATION)', & + units='unitless') + end if + if (.not. dynlanduse) then call mkpio_def_spatial_var(pioid=pioid, varname='PCT_NATVEG', xtype=xtype, & long_name='total percent natural vegetation landunit', units='unitless') diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index e3ea832926..0b304079bc 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -172,6 +172,9 @@ program mksurfdata real(r8), allocatable :: pctwet_orig(:) ! percent wetland of gridcell before dynamic land use adjustments real(r8), allocatable :: pctgla_orig(:) ! percent glacier of gridcell before dynamic land use adjustments + ! other variables written to file + real(r8), allocatable :: landfrac_mksurfdata(:) ! land fraction used for renormalization of areas + ! pio/esmf variables type(file_desc_t) :: pioid type(var_desc_t) :: pio_varid @@ -595,6 +598,7 @@ program mksurfdata ! Normalize land use and make sure things add up to 100% as well as ! checking that things are as they should be. + allocate(landfrac_mksurfdata(lsize_o)) call normalize_and_check_landuse(lsize_o) ! Write out sum of PFT's @@ -692,6 +696,10 @@ program mksurfdata call mkfile_output(pioid, mesh_model, 'PCT_CFT', pct_cft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CFT') end if + + if (root_task) write(ndiag, '(a)') trim(subname)//" writing LANDFRAC_MKSURFDATA" + call mkfile_output(pioid, mesh_model, 'LANDFRAC_MKSURFDATA', landfrac_mksurfdata, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for LANDFRAC_MKSURFDATA') end if ! ---------------------------------------------------------------------- @@ -779,7 +787,7 @@ program mksurfdata ! landfrac_pft was calculated ABOVE if (root_task) write(ndiag, '(a)') trim(subname)//" writing land fraction calculated in fsurdata calc)" call mkfile_output(pioid, mesh_model, 'LANDFRAC_PFT', landfrac_pft, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for LANDFRAC_PFT') ! ----------------------------------------- ! Read in each dynamic pft landuse dataset @@ -993,6 +1001,13 @@ program mksurfdata call pio_syncfile(pioid) end if + if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing LANDFRAC_MKSURFDATA for year ",year + rcode = pio_inq_varid(pioid, 'LANDFRAC_MKSURFDATA', pio_varid) + call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) + call mkfile_output(pioid, mesh_model, 'LANDFRAC_MKSURFDATA', landfrac_mksurfdata, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for LANDFRAC_MKSURFDATA') + call pio_syncfile(pioid) + if (root_task) then write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) @@ -1232,6 +1247,9 @@ subroutine normalize_and_check_landuse(ns_o) call pctnatpft(n)%set_pct_l2g(new_total_natveg_pct) end if + ! Save landfrac for output to file + landfrac_mksurfdata(n) = frac_land + ! Confirm that we have done the rescaling correctly: now the sum of all landunits ! should be 100% within tol_loose suma = pctlak(n) + pctwet(n) + pctgla(n) + pcturb(n) + pctcft(n)%get_pct_l2g() From 7bb66addd2d071eebbe742550267b3e5c0a7023b Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Mon, 5 Dec 2022 07:03:09 -0700 Subject: [PATCH 279/614] Stop hard-coding the settings of pole points --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 37 +----------------------- 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 0b304079bc..e0f0108d7c 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -389,13 +389,7 @@ program mksurfdata pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') - ! If have pole points on grid - set south pole to glacier - ! north pole is assumed as non-land do n = 1,lsize_o - if (abs((lat(n) - 90._r8)) < 1.e-6_r8) then - call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) - end if landfrac_pft(n) = pctlnd_pft(n)/100._r8 end do if (fsurdat /= ' ') then @@ -573,22 +567,9 @@ program mksurfdata end if ! ----------------------------------- - ! Adjust pctlak, pctwet, pcturb and pctgla + ! Save special land unit areas of surface dataset ! ----------------------------------- - do n = 1,lsize_o - - ! If have pole points on grid - set south pole to glacier - ! north pole is assumed as non-land - if (abs((lat(n) - 90._r8)) < 1.e-6_r8) then - pctlak(n) = 0._r8 - pctwet(n) = 0._r8 - pcturb(n) = 0._r8 - pctgla(n) = 100._r8 - end if - - end do - ! Save special land unit areas of surface dataset pctwet_orig(:) = pctwet(:) pctgla_orig(:) = pctgla(:) @@ -929,22 +910,6 @@ program mksurfdata pctwet(:) = pctwet_orig(:) pctgla(:) = pctgla_orig(:) - ! If have pole points on grid - set south pole to glacier - ! north pole is assumed as non-land - ! pctlak, pctwet, pcturb and pctgla were calculated ABOVE - ! pctnatpft and pctcft were calculated ABOVE - do n = 1,lsize_o - if (abs(lat(n) - 90._r8) < 1.e-6_r8) then - pctlak(n) = 0._r8 - pctwet(n) = 0._r8 - pcturb(n) = 0._r8 - pctgla(n) = 100._r8 - call pctnatpft(n)%set_pct_l2g(0._r8) - call pctcft(n)%set_pct_l2g(0._r8) - end if - - end do - ! Normalize land use and make sure things add up to 100% as well as ! checking that things are as they should be. if (root_task) then From 821fdc724199e05949e644f253eda254289e79d3 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Mon, 19 Dec 2022 16:24:22 -0700 Subject: [PATCH 280/614] Tweak a comment --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 30 ++++++++++++++---------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index e0f0108d7c..9678308800 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -1110,19 +1110,23 @@ subroutine normalize_and_check_landuse(ns_o) ! Start by using the land fraction field from the PFT raw data set: pct_land = pctlnd_pft(n) ! - ! But we don't want to overwrite special landunits or crop with ocean where these - ! special landunits extend beyond the PFT data's land fraction. In essence, this - ! is saying that we'll let special landunit area grow into the natveg area before - ! growing into ocean, but we'll have special landunit area grow into ocean before - ! growing into crop or any other special landunit area. (This check of special - ! landunit area is particularly important for glaciers, where we can have - ! floating ice shelves, so we can have a scenario where pctlnd_pft is 0 but we - ! have non-zero glacier cover and we want the final grid cell to be - ! glacier-covered.) (We could possibly do better by considering the land mask - ! from each special landunit raw dataset, and even better by mapping these - ! various notions of land mask onto each other, but that starts to get messy, and - ! relies on the trustworthiness of each raw dataset's land mask... this - ! formulation seems reasonable enough.) + ! Brief summary of the following: But we don't want to overwrite special + ! landunits or crop with ocean where these special landunits extend beyond the + ! PFT data's land fraction. + ! + ! More details: + ! + ! In essence, this is saying that we'll let special landunit area grow into the + ! natveg area before growing into ocean, but we'll have special landunit area + ! grow into ocean before growing into crop or any other special landunit area. + ! (This check of special landunit area is particularly important for glaciers, + ! where we can have floating ice shelves, so we can have a scenario where + ! pctlnd_pft is 0 but we have non-zero glacier cover and we want the final grid + ! cell to be glacier-covered.) (We could possibly do better by considering the + ! land mask from each special landunit raw dataset, and even better by mapping + ! these various notions of land mask onto each other, but that starts to get + ! messy, and relies on the trustworthiness of each raw dataset's land mask... + ! this formulation seems reasonable enough.) ! ! Note that we include pct_crop in the following, but NOT pct_natveg. The ! assumption behind that is that pct_crop is more reliable and/or more important, From 43246192ace1539aba80b03bd235f9387c00e52b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 27 Jan 2023 11:29:42 -0700 Subject: [PATCH 281/614] Update .xml to point to the new pft, lai, & soilcolor raw datasets Also update an error message in gen_mksurfdata_namelist.py and instructions in the README. --- tools/mksurfdata_esmf/README | 22 ++++++++---- .../gen_mksurfdata_namelist.py | 8 +++-- .../gen_mksurfdata_namelist.xml | 34 +++++++++++++------ 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 7e1b49311c..05bae02d6c 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -56,6 +56,8 @@ is not available on cime ported machines. Building the executable (working in tools/mksurfdata_esmf) ======================= +# Before starting, be sure that you have run +> ./manage_externals/checkout_externals > ./gen_mksurfdata_build.sh # For machines with a cime build # Note: The pio_iotype value gets set and written to a simple .txt file # by this build script. The value depends on your machine. If not running @@ -65,6 +67,10 @@ Building the executable (working in tools/mksurfdata_esmf) ======================= Running for a single submission: ======================= +# Work in the ctsm_py environment, which requires the following steps: +> module unload python; module load conda +> cd ../..; ./py_env_create +> conda activate ctsm_py; cd cd tools/mksurfdata_esmf # to generate your target namelist: > ./gen_mksurfdata_namelist.py --help # for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: @@ -97,9 +103,9 @@ Running for the generation of multiple datasets NOTES ================ ------------------------------------------------------------- -slevis HAS RUN THESE CASES and HAS LISTED ISSUES ENCOUNTERED ------------------------------------------------------------- +------------------------------------ +slevis HAS LISTED ISSUES ENCOUNTERED +------------------------------------ REMEMBER TO compare against existing fsurdat files in /glade/p/cesmdata/cseg/inputdata/lnd/clm2/surfdata_map/release-clm5.0.18 0) New 30-sec raw data for soil texture fails. Try requesting more mem. @@ -109,10 +115,14 @@ REMEMBER TO compare against existing fsurdat files in 3) Slope, stddev have chged in the .log bc the old diag. used frac_o 4) 1x1_brazil min number-of-nodes tested: 4; 10x15 min tested: 3 ------------------------------------------------------- -NOT ALL FILES HAVE BEEN TRANSLATED to cdf5 : check last millenium ------------------------------------------------------- +-------------------------------------- +ALL raw dataset .nc FILES MUST BE cdf5 +-------------------------------------- > nccopy -k cdf5 oldfile newfile +------------------------------------------------------------- +LAI raw dataset .nc FILE MUST HAVE "unlimited" time dimension +------------------------------------------------------------- +ncks --mk_rec_dmn time file_with_time_equals_12.nc -o file_with_time_unlimited.nc -------------------------------------------------------- Override options removed that need to be placed in fsurdat_modifier diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index f9226cac2c..5933d15900 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -355,8 +355,12 @@ def main (): pft_years_ssp = "2016-2100" else: error_msg = f'ERROR: start_year is {start_year} and end_year is ' \ - f'{end_year}; start/end years should be between 850 and ' \ - ' 2105 or pot_veg flag must be set' + f'{end_year}; expected start/end-year options are: ' \ + '- 1850, 2000, 2005 for time-slice options ' \ + '- in the range from 850 to 1849 ' \ + '- in the range from 1850 to 2100 ' \ + '- TODO in the range from 2101 to 2300 ' \ + '- OR user must set the potveg_flag ' sys.exit(error_msg) logger.info('pft_years = %s', pft_years) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index acbf408b72..95d3433182 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -10,7 +10,7 @@ - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20220305/mksrf_lai_ctsm52_histLUH2_2005.c220305.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230116/mksrf_pftlaihgt_ctsm52_histLUH2_2005.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc @@ -32,7 +32,7 @@ - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20220305/mksrf_soilcolor_ctsm52_histLUH2_2005.c220305.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230116/mksrf_soilcolor_ctsm52_histLUH2_2005.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc @@ -247,7 +247,7 @@ version of the raw dataset will probably go away. - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_%y.c171012.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1850.c20230116/mksrf_landuse_ctsm52_histLUH2_%y.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc @@ -267,60 +267,72 @@ version of the raw dataset will probably go away. - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP26_%y.c220305.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP1-2.6_%y.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_cdf5_c20220910.nc + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2100-2300.c20230116/mksrf_landuse_ctsm52_SSP1-2.6_%y.c20230116.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc + - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP1RCP19_%y.c220305.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP1-1.9_%y.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_cdf5_c20220910.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP2RCP45_%y.c220305.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP2-4.5_%y.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp2/urban_properties_GaoOneil_05deg_ThreeClass_ssp2_%y_cdf5_c20220910.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP3RCP70_%y.c220305.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP3-7.0_%y.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp3/urban_properties_GaoOneil_05deg_ThreeClass_ssp3_%y_cdf5_c20220910.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP34_%y.c220305.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP4-3.4_%y.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_cdf5_c20220910.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP4RCP60_%y.c220305.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP4-6.0_%y.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_cdf5_c20220910.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP5RCP85_%y.c220305.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP5-8.5_%y.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_cdf5_c20220910.nc + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2100-2300.c20230116/mksrf_landuse_ctsm52_SSP5-8.5_%y.c20230116.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc + - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2015-2100.c20220305/mksrf_landuse_ctsm52_SSP5RCP34_%y.c220305.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP5-3.4_%y.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_cdf5_c20220910.nc + + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2100-2300.c20230116/mksrf_landuse_ctsm52_SSP5-3.4_%y.c20230116.nc + lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc + From a3bfdcbd26a57fb24f1740c9ccd260e803e4e79f Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 31 Jan 2023 14:56:45 -0700 Subject: [PATCH 282/614] Additional file path/name updates to gen_mksurfdata_namelist.xml --- .../mksurfdata_esmf/gen_mksurfdata_namelist.xml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 95d3433182..9d235fd796 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -63,11 +63,12 @@ + + - lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc @@ -101,11 +102,12 @@ + + - lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_%y_cdf5_c20220910.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc @@ -223,21 +225,21 @@ version of the raw dataset will probably go away. - lnd/clm2/rawdata/mksrf_landuse_potvegclm50_LUH2.cdf5.c181106.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.noanthro.c20230116/mksrf_landuse_ctsm52_noanthroLUH2_1.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - /glade/p/cesm/sdwg_dev/thesis/data/cesm_tools/surfacedata/ctsm52finalrawdata/globalctsm52nrhistLUH2deg025_220918/mksrf_landuse_ctsm52_nrhistLUH2_1850.c220918.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230116/mksrf_landuse_ctsm52_histLUH2_1850.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - /glade/p/cesm/sdwg_dev/thesis/data/cesm_tools/surfacedata/ctsm52finalrawdata/globalctsm52nrhistLUH2deg025_220918/mksrf_landuse_ctsm52_nrhistLUH2_2000.c220918.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230116/mksrf_landuse_ctsm52_histLUH2_2000.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - /glade/p/cesm/sdwg_dev/thesis/data/cesm_tools/surfacedata/ctsm52finalrawdata/globalctsm52nrhistLUH2deg025_220918/mksrf_landuse_ctsm52_nrhistLUH2_2005.c220918.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230116/mksrf_landuse_ctsm52_histLUH2_2005.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc @@ -253,7 +255,7 @@ version of the raw dataset will probably go away. - /glade/p/cesm/sdwg_dev/thesis/data/cesm_tools/surfacedata/ctsm52finalrawdata/globalctsm52nrhistLUH2deg025_220918/mksrf_landuse_ctsm52_nrhistLUH2_%y.c220918.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230116/mksrf_landuse_ctsm52_histLUH2_%y.c20230116.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_%y_cdf5_c20220910.nc From a0e698cd3343df1886386c4feabe26bcaa2b6280 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 31 Jan 2023 14:58:38 -0700 Subject: [PATCH 283/614] Repl code that sort-of worked: transient lake+urb use actual first yr With code that I had added before in gen_mksurfdata_namelist.py, mksurfdata_esmf aborted when trying to continue from 2015 to 2016. To troubleshoot, I tried mksurfdata_esmf from 2016 to 2100 and found that urban was not starting with the correct 2016 file. I modified the code for both urban and lakes to use the method already in use for transient pfts. I tested 1850-2100 and 2016-2100 and they worked. --- .../gen_mksurfdata_namelist.py | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 5933d15900..a69e6b3e40 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -441,12 +441,6 @@ def main (): print('WARNING: run ./download_input_data to try TO ' \ 'OBTAIN MISSING FILES') _must_run_download_input_data = True - elif 'urban_properties' in rawdata_files[child1.tag] or \ - 'lake' in rawdata_files[child1.tag]: - # Time-slice cases pull urban_properties and %lake from the - # corresponding transient files - rawdata_files[child1.tag] = rawdata_files[child1.tag]. \ - replace("%y",str(start_year)) if item.tag == 'mesh_filename': new_key = f"{child1.tag}_mesh" @@ -656,15 +650,23 @@ def main (): mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] mksrf_fhrvtyp = rawdata_files["mksrf_fvegtyp"] mksrf_fhrvtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] + mksrf_fpctlak = rawdata_files["mksrf_fvegtyp_lake"] + mksrf_furban = rawdata_files["mksrf_fvegtyp_urban"] else: mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp_ssp"] mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] mksrf_fhrvtyp = rawdata_files["mksrf_fvegtyp_ssp"] mksrf_fhrvtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] + mksrf_fpctlak = rawdata_files["mksrf_fvegtyp_ssp_lake"] + mksrf_furban = rawdata_files["mksrf_fvegtyp_ssp_urban"] if '%y' in mksrf_fvegtyp: mksrf_fvegtyp = mksrf_fvegtyp.replace("%y",str(start_year)) if '%y' in mksrf_fhrvtyp: mksrf_fhrvtyp = mksrf_fhrvtyp.replace("%y",str(start_year)) + if '%y' in mksrf_fpctlak: + mksrf_fpctlak = mksrf_fpctlak.replace("%y",str(start_year)) + if '%y' in mksrf_furban: + mksrf_furban = mksrf_furban.replace("%y",str(start_year)) if not os.path.isfile(mksrf_fvegtyp): print('WARNING: input mksrf_fvegtyp file ' \ f'{mksrf_fvegtyp} does not exist') @@ -677,10 +679,24 @@ def main (): print('WARNING: run ./download_input_data to try TO ' \ 'OBTAIN MISSING FILES') _must_run_download_input_data = True + if not os.path.isfile(mksrf_fpctlak): + print('WARNING: input mksrf_fpctlak file ' \ + f'{mksrf_fpctlak} does not exist') + print('WARNING: run ./download_input_data to try TO ' \ + 'OBTAIN MISSING FILES') + _must_run_download_input_data = True + if not os.path.isfile(mksrf_furban): + print('WARNING: input mksrf_furban file ' \ + f'{mksrf_furban} does not exist') + print('WARNING: run ./download_input_data to try TO ' \ + 'OBTAIN MISSING FILES') + _must_run_download_input_data = True nlfile.write( f" mksrf_fvegtyp = \'{mksrf_fvegtyp}\' \n") nlfile.write( f" mksrf_fvegtyp_mesh = \'{mksrf_fvegtyp_mesh}\' \n") nlfile.write( f" mksrf_fhrvtyp = \'{mksrf_fhrvtyp}\' \n") nlfile.write( f" mksrf_fhrvtyp_mesh = \'{mksrf_fhrvtyp_mesh}\' \n") + nlfile.write( f" mksrf_fpctlak = \'{mksrf_fpctlak}\' \n") + nlfile.write( f" mksrf_furban = \'{mksrf_furban}\' \n") if vic_flag: mksrf_fvic = rawdata_files["mksrf_fvic"] From 3815da24aaa7316111d72d5f02339cb082a59765 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 16 Feb 2023 14:55:16 -0700 Subject: [PATCH 284/614] Very minor correction in README --- tools/mksurfdata_esmf/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 05bae02d6c..12048e40e2 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -70,7 +70,7 @@ Running for a single submission: # Work in the ctsm_py environment, which requires the following steps: > module unload python; module load conda > cd ../..; ./py_env_create -> conda activate ctsm_py; cd cd tools/mksurfdata_esmf +> conda activate ctsm_py; cd tools/mksurfdata_esmf # to generate your target namelist: > ./gen_mksurfdata_namelist.py --help # for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: From b1204ca46c51960849ecd6d237f7cc3a2c3f5019 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 16 Feb 2023 16:27:29 -0700 Subject: [PATCH 285/614] A more important new comment in the README --- tools/mksurfdata_esmf/README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 12048e40e2..55ce09dd61 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -58,6 +58,8 @@ Building the executable (working in tools/mksurfdata_esmf) # Before starting, be sure that you have run > ./manage_externals/checkout_externals +# because without it I have come across strange behavior, such as transient +# file generation (1850-2015) that aborts in the 1870s for no apparent reason. > ./gen_mksurfdata_build.sh # For machines with a cime build # Note: The pio_iotype value gets set and written to a simple .txt file # by this build script. The value depends on your machine. If not running From ba50804f5e37ba0d62976366b5a6114d53ddbd8e Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 2 May 2023 17:41:47 -0600 Subject: [PATCH 286/614] Upd gen_mksurfdata_namelist.xml: new pftlaihgt, soilcolor, landuse files --- .../gen_mksurfdata_namelist.xml | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 9d235fd796..cd6911561c 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -10,7 +10,7 @@ - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230116/mksrf_pftlaihgt_ctsm52_histLUH2_2005.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230226/mksrf_pftlaihgt_ctsm52_histLUH2_2005.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc @@ -32,7 +32,7 @@ - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230116/mksrf_soilcolor_ctsm52_histLUH2_2005.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230226/mksrf_soilcolor_ctsm52_histLUH2_2005.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc @@ -225,21 +225,21 @@ version of the raw dataset will probably go away. - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.noanthro.c20230116/mksrf_landuse_ctsm52_noanthroLUH2_1.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.noanthro.c20230226/mksrf_landuse_ctsm52_noanthroLUH2_1.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230116/mksrf_landuse_ctsm52_histLUH2_1850.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230226/mksrf_landuse_ctsm52_histLUH2_1850.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230116/mksrf_landuse_ctsm52_histLUH2_2000.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230226/mksrf_landuse_ctsm52_histLUH2_2000.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230116/mksrf_landuse_ctsm52_histLUH2_2005.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230226/mksrf_landuse_ctsm52_histLUH2_2005.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc @@ -249,13 +249,13 @@ version of the raw dataset will probably go away. - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1850.c20230116/mksrf_landuse_ctsm52_histLUH2_%y.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1850.c20230226/mksrf_landuse_ctsm52_histLUH2_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230116/mksrf_landuse_ctsm52_histLUH2_%y.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230226/mksrf_landuse_ctsm52_histLUH2_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_%y_cdf5_c20220910.nc @@ -269,70 +269,70 @@ version of the raw dataset will probably go away. - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP1-2.6_%y.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2015-2100.c20230226/mksrf_landuse_ctsm52_SSP1-2.6_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_cdf5_c20220910.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2100-2300.c20230116/mksrf_landuse_ctsm52_SSP1-2.6_%y.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2100-2300.c20230226/mksrf_landuse_ctsm52_SSP1-2.6_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP1-1.9_%y.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2015-2100.c20230226/mksrf_landuse_ctsm52_SSP1-1.9_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_%y_cdf5_c20220910.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP2-4.5_%y.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2015-2100.c20230226/mksrf_landuse_ctsm52_SSP2-4.5_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp2/urban_properties_GaoOneil_05deg_ThreeClass_ssp2_%y_cdf5_c20220910.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP3-7.0_%y.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2015-2100.c20230226/mksrf_landuse_ctsm52_SSP3-7.0_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp3/urban_properties_GaoOneil_05deg_ThreeClass_ssp3_%y_cdf5_c20220910.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP4-3.4_%y.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2015-2100.c20230226/mksrf_landuse_ctsm52_SSP4-3.4_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_cdf5_c20220910.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP4-6.0_%y.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2015-2100.c20230226/mksrf_landuse_ctsm52_SSP4-6.0_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp4/urban_properties_GaoOneil_05deg_ThreeClass_ssp4_%y_cdf5_c20220910.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP5-8.5_%y.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2015-2100.c20230226/mksrf_landuse_ctsm52_SSP5-8.5_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_cdf5_c20220910.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2100-2300.c20230116/mksrf_landuse_ctsm52_SSP5-8.5_%y.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2100-2300.c20230226/mksrf_landuse_ctsm52_SSP5-8.5_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2015-2100.c20230116/mksrf_landuse_ctsm52_SSP5-3.4_%y.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2015-2100.c20230226/mksrf_landuse_ctsm52_SSP5-3.4_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_%y.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_%y_cdf5_c20220910.nc - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2100-2300.c20230116/mksrf_landuse_ctsm52_SSP5-3.4_%y.c20230116.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2100-2300.c20230226/mksrf_landuse_ctsm52_SSP5-3.4_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc From 2f84b2608d6bcf17845ff81eed0ba0304f1811ec Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 10 May 2023 15:41:27 -0600 Subject: [PATCH 287/614] Add lake & urban to the timeslice cases (1850, etc) in the .xml file Same handling of lakes & urban as pfts. Also added a comment to gen_mksurfdata_namelist.py to address later. --- .../mksurfdata_esmf/gen_mksurfdata_namelist.py | 1 + .../gen_mksurfdata_namelist.xml | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index a69e6b3e40..167954ec4b 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -415,6 +415,7 @@ def main (): max_match_child = child2 if max_match_child is None: + # TODO slevis: Are these if-statements backwards? # For years greater than 2015 - mksrf_fvegtyp_ssp must have a match if start_year <= 2015: if 'mksrf_fvegtyp_ssp' not in child1.tag: diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index cd6911561c..d54f3a5ae7 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -227,30 +227,42 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.noanthro.c20230226/mksrf_landuse_ctsm52_noanthroLUH2_1.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_1850.cdf5.c20220325.nc + lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_1850_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230226/mksrf_landuse_ctsm52_histLUH2_1850.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_1850.cdf5.c20220325.nc + lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_1850_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230226/mksrf_landuse_ctsm52_histLUH2_2000.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_2000.cdf5.c20220325.nc + lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_2000_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230226/mksrf_landuse_ctsm52_histLUH2_2005.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_2005.cdf5.c20220325.nc + lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_2005_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_2005.cdf5.c190119.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_2005.cdf5.c20220325.nc + lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_2005_cdf5_c20220910.nc lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1850.c20230226/mksrf_landuse_ctsm52_histLUH2_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_1850.cdf5.c20220325.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_1850_cdf5_c20220910.nc @@ -277,6 +289,8 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2100-2300.c20230226/mksrf_landuse_ctsm52_SSP1-2.6_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_2100.cdf5.c20220325.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_2100_cdf5_c20220910.nc @@ -323,6 +337,8 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2100-2300.c20230226/mksrf_landuse_ctsm52_SSP5-8.5_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_2100.cdf5.c20220325.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_2100_cdf5_c20220910.nc @@ -334,6 +350,8 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2100-2300.c20230226/mksrf_landuse_ctsm52_SSP5-3.4_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc + lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_2100.cdf5.c20220325.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_2100_cdf5_c20220910.nc From 371255858c9dc8dc6ab16286189209f74f8a139f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 18 May 2023 12:07:01 -0600 Subject: [PATCH 288/614] Move makefile and config files over from the mksurfdata_map directory --- tools/{mksurfdata_map => mksurfdata_esmf}/Makefile.data | 0 tools/{mksurfdata_map => mksurfdata_esmf}/default_data_1850.cfg | 0 .../modify_1x1_mexicocityMEX.cfg | 0 .../modify_1x1_urbanc_alpha.cfg | 0 .../modify_1x1_vancouverCAN.cfg | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename tools/{mksurfdata_map => mksurfdata_esmf}/Makefile.data (100%) rename tools/{mksurfdata_map => mksurfdata_esmf}/default_data_1850.cfg (100%) rename tools/{mksurfdata_map => mksurfdata_esmf}/modify_1x1_mexicocityMEX.cfg (100%) rename tools/{mksurfdata_map => mksurfdata_esmf}/modify_1x1_urbanc_alpha.cfg (100%) rename tools/{mksurfdata_map => mksurfdata_esmf}/modify_1x1_vancouverCAN.cfg (100%) diff --git a/tools/mksurfdata_map/Makefile.data b/tools/mksurfdata_esmf/Makefile.data similarity index 100% rename from tools/mksurfdata_map/Makefile.data rename to tools/mksurfdata_esmf/Makefile.data diff --git a/tools/mksurfdata_map/default_data_1850.cfg b/tools/mksurfdata_esmf/default_data_1850.cfg similarity index 100% rename from tools/mksurfdata_map/default_data_1850.cfg rename to tools/mksurfdata_esmf/default_data_1850.cfg diff --git a/tools/mksurfdata_map/modify_1x1_mexicocityMEX.cfg b/tools/mksurfdata_esmf/modify_1x1_mexicocityMEX.cfg similarity index 100% rename from tools/mksurfdata_map/modify_1x1_mexicocityMEX.cfg rename to tools/mksurfdata_esmf/modify_1x1_mexicocityMEX.cfg diff --git a/tools/mksurfdata_map/modify_1x1_urbanc_alpha.cfg b/tools/mksurfdata_esmf/modify_1x1_urbanc_alpha.cfg similarity index 100% rename from tools/mksurfdata_map/modify_1x1_urbanc_alpha.cfg rename to tools/mksurfdata_esmf/modify_1x1_urbanc_alpha.cfg diff --git a/tools/mksurfdata_map/modify_1x1_vancouverCAN.cfg b/tools/mksurfdata_esmf/modify_1x1_vancouverCAN.cfg similarity index 100% rename from tools/mksurfdata_map/modify_1x1_vancouverCAN.cfg rename to tools/mksurfdata_esmf/modify_1x1_vancouverCAN.cfg From ff156176b4dc5084f3bd4a37a9fcaba8087d4047 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 18 May 2023 13:47:46 -0600 Subject: [PATCH 289/614] Get Makefile working with mksurfdata_esmf --- tools/mksurfdata_esmf/Makefile.data | 113 ++++++++++++++-------------- 1 file changed, 58 insertions(+), 55 deletions(-) diff --git a/tools/mksurfdata_esmf/Makefile.data b/tools/mksurfdata_esmf/Makefile.data index 1609b35a75..834a81ece4 100644 --- a/tools/mksurfdata_esmf/Makefile.data +++ b/tools/mksurfdata_esmf/Makefile.data @@ -34,25 +34,13 @@ PROJECT = $(shell cat $(HOME)/.cesm_proj) LOGOUT = $@.stdout.txt PWD = $(shell pwd) -# Setup batch handling for either cheyenne or yellowstone -# Determine what to use by machine hostname -BATCHJOBS_ys = execgy -# Send to regular queue for 2 processors with extra memory, combine stdout/stderr output to log file, and send email on abort or exit -BATCHJOBS_ch = qsub -A $(PROJECT) -q regular -l select=1:ncpus=2:mem=110GB -l walltime=4:00:00 -j oe -N $(LOGOUT) -m ae -- -HOST = $(shell hostname) -FINDCH = $(findstring cheyenne,$(HOST)) -ifeq ($(FINDCH),$(null)) - ifeq ($(PROJECT),$(null)) - $(error Can NOT find PROJECT number from ~/.cesm_proj file create it and try again) - endif - BATCHJOBS = $(BATCHJOBS_ys) - BACKGROUND = &> $(LOGOUT) & -else - BATCHJOBS = $(BATCHJOBS_ch) - BACKGROUND = -rundir $(PWD) +BATCHJOBS_ch = qsub +ifeq ($(PROJECT),$(null)) + $(error Can NOT find PROJECT number from ~/.cesm_proj file create it and try again) endif +BATCHJOBS = $(BATCHJOBS_ch) -MKSURFDATA = $(BATCHJOBS) $(PWD)/mksurfdata.pl +MKSURFDATA = $(PWD)/gen_mksurfdata_jobscript_multi.py --account $(PROJECT) SUBSETDATA = $(PWD)/../site_and_regional/subset_data MODIFYSURF = $(PWD)/../modify_input_files/fsurdat_modifier --overwrite @@ -128,8 +116,8 @@ all-subset : \ DEBUG: @echo "HOST := $(HOST)" @echo "PROJECT := $(PROJECT)" + @echo "MKSURFDATA := $(MKSURFDATA)" @echo "BATCHJOBS := $(BATCHJOBS)" - @echo "BACKGROUND := $(BACKGROUND)" # # standard @@ -137,14 +125,17 @@ DEBUG: standard : $(STANDARD) global-present : FORCE - $(MKSURFDATA) -no-crop -vic -glc_nec 10 -y 2000 -res $(STANDARD_RES_NO_CROP) $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh # T42 is needed for SCAM global-present-T42 : FORCE - $(MKSURFDATA) -no-crop -glc_nec 10 -y 2000 -res 64x128 $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh global-present-nldas : FORCE - $(MKSURFDATA) -no-crop -hirespft -glc_nec 10 -y 2005 -res 0.125nldas2 $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh # # tropics @@ -152,7 +143,8 @@ global-present-nldas : FORCE tropics : $(TROPICS) crop-tropics-present : brazil-tropics-present - $(MKSURFDATA) -glc_nec 10 -y 2000 -res 5x5_amazon $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh 1x1_brazil-tropics-present : FORCE $(SUBSETDATA_POINT_ALLLU) --create-surface $(SUBSETDATA_1X1_BRAZIL) @@ -170,13 +162,16 @@ crop-tropics-transient : FORCE crop : $(CROP) crop-global-present : FORCE - $(MKSURFDATA) -glc_nec 10 -y 2000 -r $(STANDARD_RES) $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-global-present-0.125 : FORCE - $(MKSURFDATA) -hirespft -glc_nec 10 -y 2000 -r 0.125x0.125 $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-global-present-f05 : FORCE - $(MKSURFDATA) -glc_nec 10 -y 1850,2000 -res 0.47x0.63 $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-numa-present : FORCE $(SUBSETDATA_POINT_ALLLU) --create-surface $(SUBSETDATA_1X1_NUMAIA) @@ -188,10 +183,12 @@ crop-smallville : FORCE $(SUBSETDATA_POINT) --create-surface $(SUBSETDATA_1X1_SMALL) crop-global-present-ne16np4 : FORCE - $(MKSURFDATA) -glc_nec 10 -y 2000 -res ne16np4 $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 12 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-global-present-ne120np4 : FORCE - $(MKSURFDATA) -glc_nec 10 -y 2000 -res ne120np4 $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh # Note that the smallville 1850 dataset is entirely natural vegetation. This # facilitates testing a transient case that starts with no crop, and then later @@ -202,22 +199,28 @@ crop-smallville-historical : FORCE # Setup the historical case for SSP5-8.5 so that historical can be used to go into the future. crop-global-historical : FORCE - $(MKSURFDATA) -glc_nec 10 -y 1850 -ssp_rcp SSP5-8.5 -res $(STANDARD_RES) $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-global-historical-f05 : FORCE - $(MKSURFDATA) -glc_nec 10 -y 1850 -r 0.47x0.63 $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-global-historical-ne120np4 : FORCE - $(MKSURFDATA) -glc_nec 10 -y 1850 -res ne120np4 $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-global-transient: FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2000 -res $(TRANS_RES) $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-global-transient-ne120np4 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2000 -res ne120np4 $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-global-transient-f05 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2000 -res 0.47x0.63 $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh # # Crop with future scenarios @@ -226,36 +229,36 @@ crop-global-future : crop-global-SSP1-2.6 crop-global-SSP3-7.0 crop-global-SSP5- crop-global-SSP1-1.9 crop-global-SSP4-3.4 crop-global-SSP4-6.0 crop-global-SSP5-8.5 crop-global-SSP1-2.6 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP1-2.6 -res $(FUTURE_RES) $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-global-SSP3-7.0 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP3-7.0 -res $(FUTURE_RES) $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-global-SSP5-3.4 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP5-3.4 -res $(FUTURE_RES) $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-global-SSP2-4.5 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP2-4.5 -res $(FUTURE_RES) $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-global-SSP1-1.9 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP1-1.9 -res $(FUTURE_RES) $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-global-SSP4-3.4 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP4-3.4 -res $(FUTURE_RES) $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-global-SSP4-6.0 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP4-6.0 -res $(FUTURE_RES) $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh crop-global-SSP5-8.5 : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-2100 \ - -ssp_rcp SSP5-8.5 -res $(FUTURE_RES) $(BACKGROUND) + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(BATCHJOBS) $@.sh # # urban @@ -287,12 +290,12 @@ urban-alpha : FORCE landuse-timeseries : landuse-timeseries-smallville # NOTE: TODO: This needs to be chagned to use subset_data when transient configurations are resolved (see Issue #1673 -landuse-timeseries-smallville : FORCE - $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-1855 -r 1x1_smallvilleIA \ - -pft_idx 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78 \ - -pft_frc 6.5,1.5,1.6,1.7,1.8,1.9,1.5,1.6,1.7,1.8,1.9,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5 \ - -dynpft single_point_dynpft_files/landuse_timeseries_smallvilleIA_hist_simyr1850-1855.txt \ - $(BACKGROUND) +#landuse-timeseries-smallville : FORCE +# $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-1855 -r 1x1_smallvilleIA \ +# -pft_idx 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78 \ +# -pft_frc 6.5,1.5,1.6,1.7,1.8,1.9,1.5,1.6,1.7,1.8,1.9,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5 \ +# -dynpft single_point_dynpft_files/landuse_timeseries_smallvilleIA_hist_simyr1850-1855.txt \ +# $(BACKGROUND) # # clean up the working directory by removing generated files From d9b5c064a27e27db90a64986de05d9384371d95d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 18 May 2023 14:27:46 -0600 Subject: [PATCH 290/614] Correct documentation, add new resolutions into gen_mksurfdata jobscript --- tools/mksurfdata_esmf/Makefile.data | 31 ++++++------------- .../gen_mksurfdata_jobscript_multi.py | 1 + 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/tools/mksurfdata_esmf/Makefile.data b/tools/mksurfdata_esmf/Makefile.data index 834a81ece4..41f70d6190 100644 --- a/tools/mksurfdata_esmf/Makefile.data +++ b/tools/mksurfdata_esmf/Makefile.data @@ -10,20 +10,6 @@ # # NOTE: The default behavior is to parallelize data set creation using # the batch system by submitting jobs to the batch queue (on cheyenne). -# On yellowstone we submit to an interactive queue in the -# background. Standard out and standard error are redirected to a text -# file. To change this behavior, you can comment out the BATCHJOBS and -# BACKGROUND variables and replace them with empty variables. -# -# WARNING: Do not put more than one mksurfdata call per rule. output -# redirection is based on the rule name, and multiple rules will over -# write the previous output or incomprehensively merge output from -# simultaneously running jobs. -# -# Note that we typically use -no_surfdata in rules for transient files, having -# separate rules to make the year-1850 and year-2000 surface datasets. This -# results in extra processes, but ensures that the surface datasets have the -# correct name (rather than having 'hist' or 'rcpXXX' in their file name). # # Set up special characters @@ -114,10 +100,14 @@ all-subset : \ urban-present urban-alpha DEBUG: - @echo "HOST := $(HOST)" - @echo "PROJECT := $(PROJECT)" - @echo "MKSURFDATA := $(MKSURFDATA)" - @echo "BATCHJOBS := $(BATCHJOBS)" + @echo "HOST := $(HOST)" + @echo "PROJECT := $(PROJECT)" + @echo "MKSURFDATA := $(MKSURFDATA)" + @echo "SUBSETDATA_POINT := $(SUBSETDATA_POINT)" + @echo "MODIFYSURF := $(MODIFYSURF)" + @echo "BATCHJOBS := $(BATCHJOBS)" + @echo "CDATE := $(CDATE)" + @echo "RM := $(RM)" # # standard @@ -285,10 +275,9 @@ urban-alpha : FORCE $(RM) surfdata_1x1_urbanc_alpha_hist_78pfts_CMIP6_simyr2000.nc # -# landuse timeseries +# landuse timeseries with subset data # -landuse-timeseries : landuse-timeseries-smallville - +#landuse-timeseries : landuse-timeseries-smallville # NOTE: TODO: This needs to be chagned to use subset_data when transient configurations are resolved (see Issue #1673 #landuse-timeseries-smallville : FORCE # $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-1855 -r 1x1_smallvilleIA \ diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 679c8e3e05..f24fcf67d5 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -165,6 +165,7 @@ def main (): "standard_res" : ['0.9x1.25','1.9x2.5','10x15','4x5','C96', 'ne30np4','ne30np4.pg2','ne30np4.pg3','ne30np4.pg4','ne120np4.pg3', 'ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4', 'ne0np4CONUS.ne30x8'], + 'ne3np4.pg3','ne5np4.pg3','ne16np4.pg3','mpasa480','mpasa120' "future_res" : ["0.9x1.25","1.9x2.5","10x15"], "trans_res" : ['0.9x1.25','1.9x2.5','10x15','ne30np4', 'ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4','ne0np4CONUS.ne30x8','ne120np4'], From 7a536c4087a78eee2f69dda713c979a8ba574d6d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 18 May 2023 14:35:43 -0600 Subject: [PATCH 291/614] Add more to the git ignore --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 329662fd2a..e405af9f4d 100644 --- a/.gitignore +++ b/.gitignore @@ -93,6 +93,12 @@ ctsm.input_data_list.previous /tools/mksurfdata_esmf/src /tools/mksurfdata_esmf/surfdata_*.nc /tools/mksurfdata_esmf/landuse.timeseries_*.nc +/tools/mksurfdata_esmf/mksurfdata_jobscript_multi +/tools/mksurfdata_esmf/mksurfdata_jobscript_single +/tools/mksurfdata_esmf/pio_iotype.txt +/tools/mksurfdata_esmf/*.sh +/tools/mksurfdata_esmf/makesurfdata.o* +/tools/mksurfdata_esmf/tool_bld # mksurfdata unit tests unit_test_build From 521ad2504739eb87fd4339a997cb77b29651e583 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 18 May 2023 15:02:12 -0600 Subject: [PATCH 292/614] Fix some errors, have script die if mksurfdata_esmf was not built --- tools/mksurfdata_esmf/Makefile.data | 2 +- .../gen_mksurfdata_jobscript_multi.py | 23 +++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/tools/mksurfdata_esmf/Makefile.data b/tools/mksurfdata_esmf/Makefile.data index 41f70d6190..efe7d85b53 100644 --- a/tools/mksurfdata_esmf/Makefile.data +++ b/tools/mksurfdata_esmf/Makefile.data @@ -132,7 +132,7 @@ global-present-nldas : FORCE # tropics : $(TROPICS) -crop-tropics-present : brazil-tropics-present +crop-tropics-present : 1x1_brazil-tropics-present $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh $(BATCHJOBS) $@.sh diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index f24fcf67d5..6b1dd5cb21 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -164,8 +164,8 @@ def main (): "standard_res_no_crop" : ["0.9x1.25","1.9x2.5","10x15"], "standard_res" : ['0.9x1.25','1.9x2.5','10x15','4x5','C96', 'ne30np4','ne30np4.pg2','ne30np4.pg3','ne30np4.pg4','ne120np4.pg3', - 'ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4', 'ne0np4CONUS.ne30x8'], - 'ne3np4.pg3','ne5np4.pg3','ne16np4.pg3','mpasa480','mpasa120' + 'ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4', 'ne0np4CONUS.ne30x8', + 'ne3np4.pg3','ne5np4.pg3','ne16np4.pg3','mpasa480','mpasa120'], "future_res" : ["0.9x1.25","1.9x2.5","10x15"], "trans_res" : ['0.9x1.25','1.9x2.5','10x15','ne30np4', 'ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4','ne0np4CONUS.ne30x8','ne120np4'], @@ -206,6 +206,21 @@ def main (): # that's found in the section titled "Obtain mpirun command ..." # -------------------------- + # -------------------------- + # Make sure files exist or exit + # -------------------------- + if not os.path.exists("./tool_bld"): + print( "tool_bld directory does NOT exist -- build mksurdata_esmf before running this script") + sys.exit(1) + + env_specific_script = "./tool_bld/.env_mach_specific.sh" + if not os.path.exists(env_specific_script): + print( env_specific_script+" does NOT exist") + sys.exit(1) + mksurfdata = "./tool_bld/mksurfdata" + if not os.path.exists(mksurfdata): + print( mksurfdata+" does NOT exist") + sys.exit(1) # -------------------------- # Write run script # -------------------------- @@ -225,7 +240,7 @@ def main (): # Run env_mach_specific.sh to control the machine dependent # environment including the paths to compilers and libraries # external to cime such as netcdf - runfile.write('. ./tool_bld/.env_mach_specific.sh \n') + runfile.write('. '+env_specific_script + '\n') for target in target_list: res_set = dataset_dict[target][1] for res in resolution_dict[res_set]: @@ -242,7 +257,7 @@ def main (): output = run_cmd.stdout.decode('utf-8').strip() namelist = output.split(' ')[-1] print (f"generated namelist {namelist}") - output = f"mpiexec_mpt -p \"%g:\" -np {n_p} omplace -tm open64 ./tool_bld/mksurfdata < {namelist}" + output = f"mpiexec_mpt -p \"%g:\" -np {n_p} omplace -tm open64 "+mksurfdata+" < {namelist}" runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") From 0fffce46ac1d07616507ba60855b2d17c8f9f25b Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 18 May 2023 15:47:40 -0600 Subject: [PATCH 293/614] Fix syntax, add scenario name to PBS name, add more to error message about building --- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 6b1dd5cb21..cc8badad01 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -210,7 +210,7 @@ def main (): # Make sure files exist or exit # -------------------------- if not os.path.exists("./tool_bld"): - print( "tool_bld directory does NOT exist -- build mksurdata_esmf before running this script") + print( "tool_bld directory does NOT exist -- build mksurdata_esmf before running this script -- using ./gen_mksurfdata_build.sh") sys.exit(1) env_specific_script = "./tool_bld/.env_mach_specific.sh" @@ -228,7 +228,7 @@ def main (): runfile.write('#!/bin/bash \n') runfile.write(f"#PBS -A {account} \n") - runfile.write('#PBS -N mksurfdata \n') + runfile.write(f'#PBS -N mksrf_{scenario} \n') runfile.write('#PBS -j oe \n') runfile.write('#PBS -q regular \n') runfile.write('#PBS -l walltime=12:00:00 \n') @@ -257,7 +257,7 @@ def main (): output = run_cmd.stdout.decode('utf-8').strip() namelist = output.split(' ')[-1] print (f"generated namelist {namelist}") - output = f"mpiexec_mpt -p \"%g:\" -np {n_p} omplace -tm open64 "+mksurfdata+" < {namelist}" + output = f"mpiexec_mpt -p \"%g:\" -np {n_p} omplace -tm open64 {mksurfdata} < {namelist}" runfile.write(f"{output} \n") print (f"Successfully created jobscript {jobscript_file}") From 8b6ec058abc280e78910db20df813ac7615d3164 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 18 May 2023 15:53:21 -0600 Subject: [PATCH 294/614] Adjust name for output batch files... --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e405af9f4d..199f064cdb 100644 --- a/.gitignore +++ b/.gitignore @@ -97,7 +97,7 @@ ctsm.input_data_list.previous /tools/mksurfdata_esmf/mksurfdata_jobscript_single /tools/mksurfdata_esmf/pio_iotype.txt /tools/mksurfdata_esmf/*.sh -/tools/mksurfdata_esmf/makesurfdata.o* +/tools/mksurfdata_esmf/mksrf_*.o* /tools/mksurfdata_esmf/tool_bld # mksurfdata unit tests From 2d349db88947a7b5a7851044115bedb07b66e189 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 18 May 2023 16:17:24 -0600 Subject: [PATCH 295/614] Add walltime and set it for the different scenarios --- tools/mksurfdata_esmf/Makefile.data | 46 +++++++++---------- .../gen_mksurfdata_jobscript_multi.py | 11 ++++- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/tools/mksurfdata_esmf/Makefile.data b/tools/mksurfdata_esmf/Makefile.data index efe7d85b53..4385b2d2e4 100644 --- a/tools/mksurfdata_esmf/Makefile.data +++ b/tools/mksurfdata_esmf/Makefile.data @@ -115,16 +115,16 @@ DEBUG: standard : $(STANDARD) global-present : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh # T42 is needed for SCAM global-present-T42 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh global-present-nldas : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh # @@ -133,7 +133,7 @@ global-present-nldas : FORCE tropics : $(TROPICS) crop-tropics-present : 1x1_brazil-tropics-present - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh 1x1_brazil-tropics-present : FORCE @@ -152,15 +152,15 @@ crop-tropics-transient : FORCE crop : $(CROP) crop-global-present : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-present-0.125 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh crop-global-present-f05 : FORCE - $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh crop-numa-present : FORCE @@ -173,11 +173,11 @@ crop-smallville : FORCE $(SUBSETDATA_POINT) --create-surface $(SUBSETDATA_1X1_SMALL) crop-global-present-ne16np4 : FORCE - $(MKSURFDATA) --number-of-nodes 12 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 12 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-present-ne120np4 : FORCE - $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 03:00:00 $(BATCHJOBS) $@.sh # Note that the smallville 1850 dataset is entirely natural vegetation. This @@ -189,27 +189,27 @@ crop-smallville-historical : FORCE # Setup the historical case for SSP5-8.5 so that historical can be used to go into the future. crop-global-historical : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 03:00:00 $(BATCHJOBS) $@.sh crop-global-historical-f05 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 06:00:00 $(BATCHJOBS) $@.sh crop-global-historical-ne120np4 : FORCE - $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 06:00:00 $(BATCHJOBS) $@.sh crop-global-transient: FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 03:00:00 $(BATCHJOBS) $@.sh crop-global-transient-ne120np4 : FORCE - $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 06:00:00 $(BATCHJOBS) $@.sh crop-global-transient-f05 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 06:00:00 $(BATCHJOBS) $@.sh # @@ -219,35 +219,35 @@ crop-global-future : crop-global-SSP1-2.6 crop-global-SSP3-7.0 crop-global-SSP5- crop-global-SSP1-1.9 crop-global-SSP4-3.4 crop-global-SSP4-6.0 crop-global-SSP5-8.5 crop-global-SSP1-2.6 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh crop-global-SSP3-7.0 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh crop-global-SSP5-3.4 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh crop-global-SSP1-1.9 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh crop-global-SSP4-3.4 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh crop-global-SSP4-6.0 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh crop-global-SSP5-8.5 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh # diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index cc8badad01..2a7e4f083a 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -78,6 +78,14 @@ def get_parser(): required=False, default="12", ) + parser.add_argument( + "--walltime", + help="""Wallclock time for job submission default is 12:00:00)""", + action="store", + dest="walltime", + required=False, + default="12:00:00", + ) parser.add_argument( "--scenario", help="""scenario""", @@ -110,6 +118,7 @@ def main (): number_of_nodes = args.number_of_nodes tasks_per_node = args.tasks_per_node account = args.account + walltime = args.walltime # -------------------------- # Determine target list @@ -231,7 +240,7 @@ def main (): runfile.write(f'#PBS -N mksrf_{scenario} \n') runfile.write('#PBS -j oe \n') runfile.write('#PBS -q regular \n') - runfile.write('#PBS -l walltime=12:00:00 \n') + runfile.write(f'#PBS -l walltime={walltime} \n') runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") runfile.write("\n") From 97787b974f6cf788a9d2e5ecc37671ebdc551154 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 5 Jun 2023 14:17:47 -0600 Subject: [PATCH 296/614] First update of namelist_defaults_ctsm.xml with ctsm5.2 datasets - mapping files removed - T31 (48x96) removed - new files found in lnd/clm2/surfdata_esmf/ctsm5.2.0 Also update for consistency: - modify_fsurdat.py to not look for PFTDATA_MASK in new fsurdat - /python/ctsm/test/testinputs fsurdat files - /python/ctsm/test/testinputs .cfg files - tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py --- bld/namelist_files/namelist_defaults_ctsm.xml | 959 ++---------------- .../clm/FatesColdLandUse/user_nl_clm | 2 +- .../README | 15 +- .../user_nl_clm | 4 +- .../clm/f09_dec1990Start_GU_LULCC/user_nl_clm | 4 +- .../ctsm/modify_input_files/modify_fsurdat.py | 1 - python/ctsm/test/test_sys_fsurdat_modifier.py | 8 +- python/ctsm/test/testinputs/default_data.cfg | 12 +- .../test/testinputs/modify_fsurdat_short.cfg | 4 +- tools/mksurfdata_esmf/README | 10 +- .../gen_mksurfdata_jobscript_multi.py | 64 +- 11 files changed, 169 insertions(+), 914 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 62b959422c..0d779789d4 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -768,11 +768,6 @@ attributes from the config_cache.xml file (with keys converted to upper-case). >hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. -hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. - - hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. @@ -1030,41 +1025,39 @@ p - -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_48x96_hist_16pfts_Irrig_CMIP6_simyr2000_c190214.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr2000_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_16pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr2000_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_16pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_1.9x2.5_hist_16pfts_Irrig_CMIP6_simyr2000_c190304.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_16pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_1.9x2.5_hist_16pfts_Irrig_CMIP6_simyr2000_c190304.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_16pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_4x5_hist_16pfts_Irrig_CMIP6_simyr2000_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_10x15_hist_16pfts_Irrig_CMIP6_simyr2000_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_16pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_10x15_hist_16pfts_Irrig_CMIP6_simyr2000_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_16pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_ne30np4_hist_16pfts_Irrig_CMIP6_simyr2000_c190303.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_ne16np4_hist_16pfts_Irrig_CMIP6_simyr2000_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/surfdata_0.125nldas2_hist_16pfts_Irrig_CMIP6_simyr2005_c190412.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.125nldas2_hist_16pfts_CMIP6_2000_c230517.nc lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_brazil_hist_78pfts_CMIP6_simyr2000_c230123.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_5x5_amazon_hist_16pfts_Irrig_CMIP6_simyr2000_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_64x128_hist_16pfts_Irrig_CMIP6_simyr2000_c190214.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_T42_hist_16pfts_CMIP6_2000_c230517.nc @@ -1072,46 +1065,46 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C384_hist_78pfts_CMIP6_simyr200 lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C192_hist_78pfts_CMIP6_simyr2000_c200317.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C96_hist_78pfts_CMIP6_simyr2000_c200317.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_78pfts_CMIP6_2000_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C48_hist_78pfts_CMIP6_simyr2000_c200317.nc lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C24_hist_78pfts_CMIP6_simyr2000_c200317.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_0.9x1.25_hist_78pfts_CMIP6_simyr2000_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_1.9x2.5_hist_78pfts_CMIP6_simyr2000_c190304.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_78pfts_CMIP6_2000_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.24/surfdata_0.125x0.125_hist_78pfts_CMIP6_simyr2005_c190624.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_10x15_hist_78pfts_CMIP6_simyr2000_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_4x5_hist_78pfts_CMIP6_simyr2000_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_2000_c230517.nc lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_numaIA_hist_78pfts_CMIP6_simyr2000_c230123.nc lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_simyr2000_c230123.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_ne16np4_hist_78pfts_CMIP6_simyr2000_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne30np4_hist_78pfts_CMIP6_simyr2000_c200426.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne30np4.pg2_hist_78pfts_CMIP6_simyr2000_c200426.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne30np4.pg3_hist_78pfts_CMIP6_simyr2000_c200426.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne120np4_hist_78pfts_CMIP6_simyr2000_c200427.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4_hist_78pfts_CMIP6_2000_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne120np4.pg2_hist_78pfts_CMIP6_simyr2000_c200426.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne120np4.pg3_hist_78pfts_CMIP6_simyr2000_c200427.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4.pg3_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.ARCTICGRIS.ne30x8_hist_78pfts_CMIP6_simyr2000_c200426.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x8_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.ARCTIC.ne30x4_hist_78pfts_CMIP6_simyr2000_c200426.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x4_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts_CMIP6_simyr2000_c200426.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts_CMIP6_2000_c230517.nc @@ -1122,43 +1115,39 @@ lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_mexicocityMEX_hist_78pfts_CMIP lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_urbanc_alpha_hist_78pfts_CMIP6_simyr2000_c230123.nc - - lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_48x96_hist_16pfts_Irrig_CMIP6_simyr1850_c190214.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr1850_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_1.9x2.5_hist_16pfts_Irrig_CMIP6_simyr1850_c190304.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_10x15_hist_16pfts_Irrig_CMIP6_simyr1850_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_4x5_hist_16pfts_Irrig_CMIP6_simyr1850_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_ne30np4_hist_16pfts_Irrig_CMIP6_simyr1850_c190303.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc - -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_48x96_hist_78pfts_CMIP6_simyr1850_c190214.nc lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C384_hist_78pfts_CMIP6_simyr1850_c200317.nc lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C192_hist_78pfts_CMIP6_simyr1850_c200317.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C96_hist_78pfts_CMIP6_simyr1850_c200317.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C48_hist_78pfts_CMIP6_simyr1850_c200317.nc lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C24_hist_78pfts_CMIP6_simyr1850_c200317.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_0.9x1.25_hist_78pfts_CMIP6_simyr1850_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_1.9x2.5_hist_78pfts_CMIP6_simyr1850_c190304.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_10x15_hist_78pfts_CMIP6_simyr1850_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.18/surfdata_4x5_hist_78pfts_CMIP6_simyr1850_c190214.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_simyr1850_c230123.nc @@ -1168,23 +1157,23 @@ lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_numaIA_hist_78pfts_CMIP6_simyr lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_brazil_hist_78pfts_CMIP6_simyr1850_c230123.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne30np4_hist_78pfts_CMIP6_simyr1850_c200426.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne30np4.pg2_hist_78pfts_CMIP6_simyr1850_c200426.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne30np4.pg3_hist_78pfts_CMIP6_simyr1850_c200426.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne120np4_hist_78pfts_CMIP6_simyr1850_c200427.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4_hist_78pfts_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne120np4.pg2_hist_78pfts_CMIP6_simyr1850_c200426.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne120np4.pg3_hist_78pfts_CMIP6_simyr1850_c200427.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4.pg3_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.ARCTICGRIS.ne30x8_hist_78pfts_CMIP6_simyr1850_c200426.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x8_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.ARCTIC.ne30x4_hist_78pfts_CMIP6_simyr1850_c200426.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTIC.ne30x4_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts_CMIP6_simyr1850_c200426.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.CONUS.ne30x8_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc + lnd/clm2/surfdata_map/landuse.timeseries_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/landuse.timeseries_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/landuse.timeseries_1.9x2.5_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_hist_78_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/landuse.timeseries_1.9x2.5_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_hist_78_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_4x5_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_48x96_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c190214.nc - + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/landuse.timeseries_ne30np4_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c170824.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np4_hist_78_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/landuse.timeseries_ne0np4.ARCTIC.ne30x4_hist_78pfts_CMIP6_simyr1850-2015_c191023.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne0np4.ARCTIC.ne30x4_hist_78_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/landuse.timeseries_0.9x1.25_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/landuse.timeseries_1.9x2.5_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_hist_78_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_4x5_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc -lnd/clm2/surfdata_map/landuse.timeseries_48x96_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/ctsm5.1.dev116/landuse.timeseries_1x1_brazil_hist_78pfts_CMIP6_simyr1850-2015_c230123.nc @@ -1234,17 +1215,13 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts use_crop=".true." >lnd/clm2/surfdata_map/landuse.timeseries_1x1_numaIA_hist_78pfts_CMIP6_simyr1850-2015_c170917.nc lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_ne30np4_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200426.nc -lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_ne30np4.pg2_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200426.nc -lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_ne30np4.pg3_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200426.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np4_hist_78_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_ne0np4.ARCTICGRIS.ne30x8_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200426.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne0np4.ARCTICGRIS.ne30x8_hist_78_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_ne0np4.ARCTIC.ne30x4_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200426.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne0np4.ARCTIC.ne30x4_hist_78_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_ne0np4.CONUS.ne30x8_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200426.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne0np4.CONUS.ne30x8_hist_78_CMIP6_1850-2000_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_C24_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200317.nc @@ -1261,11 +1238,11 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c190214.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP5-8.5_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP5-8.5_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP5-8.5_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_C24_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200317.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP1-2.6_78pfts_CMIP6_simyr1850-2100_c190214.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP1-2.6_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP1-2.6_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP1-2.6_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP1-2.6_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP1-2.6_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP2-4.5_78pfts_CMIP6_simyr1850-2100_c190214.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP2-4.5_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP2-4.5_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP3-7.0_78pfts_CMIP6_simyr1850-2100_c190214.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP3-7.0_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP3-7.0_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP3-7.0_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP3-7.0_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP3-7.0_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP4-3.4_78pfts_CMIP6_simyr1850-2100_c190214.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP4-3.4_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP4-3.4_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP4-3.4_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP4-3.4_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP4-3.4_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP1-1.9_78pfts_CMIP6_simyr1850-2100_c190214.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP1-1.9_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP1-1.9_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP1-1.9_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP1-1.9_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP1-1.9_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP4-6.0_78pfts_CMIP6_simyr1850-2100_c190214.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP4-6.0_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP4-6.0_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP4-6.0_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP4-6.0_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP4-6.0_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP5-3.4_78pfts_CMIP6_simyr1850-2100_c190214.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP5-3.4_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP5-3.4_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP5-3.4_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP5-3.4_78pfts_CMIP6_simyr1850-2100_c190228.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP5-3.4_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP5-8.5_16pfts_Irrig_CMIP6_simyr1850-2100_c190214.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP5-8.5_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP5-8.5_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP5-8.5_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP5-8.5_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP5-8.5_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP1-2.6_16pfts_Irrig_CMIP6_simyr1850-2100_c190214.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP1-2.6_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP1-2.6_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP1-2.6_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP1-2.6_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP1-2.6_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP2-4.5_16pfts_Irrig_CMIP6_simyr1850-2100_c190214.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP2-4.5_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP2-4.5_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP3-7.0_16pfts_Irrig_CMIP6_simyr1850-2100_c190214.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP3-7.0_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP3-7.0_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP3-7.0_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP3-7.0_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP3-7.0_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP4-3.4_16pfts_Irrig_CMIP6_simyr1850-2100_c190214.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP4-3.4_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP4-3.4_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP4-3.4_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP4-3.4_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP4-3.4_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP1-1.9_16pfts_Irrig_CMIP6_simyr1850-2100_c190214.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP1-1.9_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP1-1.9_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP1-1.9_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP1-1.9_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP1-1.9_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP4-6.0_16pfts_Irrig_CMIP6_simyr1850-2100_c190214.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP4-6.0_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP4-6.0_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP4-6.0_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP4-6.0_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP4-6.0_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_0.9x1.25_SSP5-3.4_16pfts_Irrig_CMIP6_simyr1850-2100_c190214.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP5-3.4_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_1.9x2.5_SSP5-3.4_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP5-3.4_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.18/landuse.timeseries_10x15_SSP5-3.4_16pfts_Irrig_CMIP6_simyr1850-2100_c190228.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP5-3.4_78_CMIP6_1850-2100_c230517.nc .true. @@ -1792,724 +1769,6 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts 35 - - - - - - -lnd/clm2/mappingdata/maps/1x1_asphaltjungleNJ/map_0.125x0.125_nomask_to_1x1_asphaltjungleNJ_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_asphaltjungleNJ/map_0.5x0.5_nomask_to_1x1_asphaltjungleNJ_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_asphaltjungleNJ/map_0.25x0.25_nomask_to_1x1_asphaltjungleNJ_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_asphaltjungleNJ/map_3x3min_nomask_to_1x1_asphaltjungleNJ_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_asphaltjungleNJ/map_10x10min_nomask_to_1x1_asphaltjungleNJ_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_asphaltjungleNJ/map_5x5min_nomask_to_1x1_asphaltjungleNJ_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_asphaltjungleNJ/map_0.9x1.25_nomask_to_1x1_asphaltjungleNJ_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_asphaltjungleNJ/map_1km-merge-10min_HYDRO1K-merge-nomask_to_1x1_asphaltjungleNJ_nomask_aave_da_c130403.nc - - - -lnd/clm2/mappingdata/maps/1x1_brazil/map_0.125x0.125_nomask_to_1x1_brazil_nomask_aave_da_c211212.nc -lnd/clm2/mappingdata/maps/1x1_brazil/map_0.5x0.5_nomask_to_1x1_brazil_nomask_aave_da_c211212.nc -lnd/clm2/mappingdata/maps/1x1_brazil/map_0.25x0.25_nomask_to_1x1_brazil_nomask_aave_da_c211212.nc -lnd/clm2/mappingdata/maps/1x1_brazil/map_3x3min_nomask_to_1x1_brazil_nomask_aave_da_c211212.nc -lnd/clm2/mappingdata/maps/1x1_brazil/map_10x10min_nomask_to_1x1_brazil_nomask_aave_da_c211212.nc -lnd/clm2/mappingdata/maps/1x1_brazil/map_5x5min_nomask_to_1x1_brazil_nomask_aave_da_c211212.nc -lnd/clm2/mappingdata/maps/1x1_brazil/map_0.9x1.25_nomask_to_1x1_brazil_nomask_aave_da_c211212.nc -lnd/clm2/mappingdata/maps/1x1_brazil/map_1km-merge-10min_HYDRO1K-merge-nomask_to_1x1_brazil_nomask_aave_da_c211212.nc - - - -lnd/clm2/mappingdata/maps/1x1_mexicocityMEX/map_0.125x0.125_nomask_to_1x1_mexicocityMEX_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_mexicocityMEX/map_0.5x0.5_nomask_to_1x1_mexicocityMEX_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_mexicocityMEX/map_0.25x0.25_nomask_to_1x1_mexicocityMEX_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_mexicocityMEX/map_3x3min_nomask_to_1x1_mexicocityMEX_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_mexicocityMEX/map_10x10min_nomask_to_1x1_mexicocityMEX_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_mexicocityMEX/map_5x5min_nomask_to_1x1_mexicocityMEX_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_mexicocityMEX/map_0.9x1.25_nomask_to_1x1_mexicocityMEX_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_mexicocityMEX/map_1km-merge-10min_HYDRO1K-merge-nomask_to_1x1_mexicocityMEX_nomask_aave_da_c130403.nc - - - -lnd/clm2/mappingdata/maps/1x1_numaIA/map_0.125x0.125_nomask_to_1x1_numaIA_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_numaIA/map_0.5x0.5_nomask_to_1x1_numaIA_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_numaIA/map_0.25x0.25_nomask_to_1x1_numaIA_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_numaIA/map_3x3min_nomask_to_1x1_numaIA_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_numaIA/map_10x10min_nomask_to_1x1_numaIA_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_numaIA/map_5x5min_nomask_to_1x1_numaIA_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_numaIA/map_0.9x1.25_nomask_to_1x1_numaIA_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_numaIA/map_1km-merge-10min_HYDRO1K-merge-nomask_to_1x1_numaIA_nomask_aave_da_c130403.nc - - - -lnd/clm2/mappingdata/maps/1x1_smallvilleIA/map_0.125x0.125_nomask_to_1x1_smallvilleIA_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_smallvilleIA/map_0.25x0.25_nomask_to_1x1_smallvilleIA_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_smallvilleIA/map_0.5x0.5_nomask_to_1x1_smallvilleIA_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_smallvilleIA/map_10x10min_nomask_to_1x1_smallvilleIA_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_smallvilleIA/map_3x3min_nomask_to_1x1_smallvilleIA_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_smallvilleIA/map_5x5min_nomask_to_1x1_smallvilleIA_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_smallvilleIA/map_0.9x1.25_nomask_to_1x1_smallvilleIA_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_smallvilleIA/map_1km-merge-10min_HYDRO1K-merge-nomask_to_1x1_smallvilleIA_nomask_aave_da_c130403.nc - - - -lnd/clm2/mappingdata/maps/1x1_urbanc_alpha/map_0.125x0.125_nomask_to_1x1_urbanc_alpha_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_urbanc_alpha/map_0.25x0.25_nomask_to_1x1_urbanc_alpha_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_urbanc_alpha/map_0.5x0.5_nomask_to_1x1_urbanc_alpha_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_urbanc_alpha/map_10x10min_nomask_to_1x1_urbanc_alpha_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_urbanc_alpha/map_3x3min_nomask_to_1x1_urbanc_alpha_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_urbanc_alpha/map_5x5min_nomask_to_1x1_urbanc_alpha_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_urbanc_alpha/map_0.9x1.25_nomask_to_1x1_urbanc_alpha_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_urbanc_alpha/map_1km-merge-10min_HYDRO1K-merge-nomask_to_1x1_urbanc_alpha_nomask_aave_da_c130403.nc - - - -lnd/clm2/mappingdata/maps/1x1_vancouverCAN/map_0.125x0.125_nomask_to_1x1_vancouverCAN_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_vancouverCAN/map_0.25x0.25_nomask_to_1x1_vancouverCAN_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_vancouverCAN/map_0.5x0.5_nomask_to_1x1_vancouverCAN_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_vancouverCAN/map_10x10min_nomask_to_1x1_vancouverCAN_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_vancouverCAN/map_3x3min_nomask_to_1x1_vancouverCAN_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_vancouverCAN/map_5x5min_nomask_to_1x1_vancouverCAN_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1x1_vancouverCAN/map_0.9x1.25_nomask_to_1x1_vancouverCAN_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1x1_vancouverCAN/map_1km-merge-10min_HYDRO1K-merge-nomask_to_1x1_vancouverCAN_nomask_aave_da_c130403.nc - - - -lnd/clm2/mappingdata/maps/0.47x0.63/map_0.125x0.125_nomask_to_0.47x0.63_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.47x0.63/map_0.5x0.5_nomask_to_0.47x0.63_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.47x0.63/map_0.25x0.25_nomask_to_0.47x0.63_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.47x0.63/map_10x10min_nomask_to_0.47x0.63_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.47x0.63/map_1km-merge-10min_HYDRO1K-merge-nomask_to_0.47x0.63_nomask_aave_da_c170914.nc -lnd/clm2/mappingdata/maps/0.47x0.63/map_3x3min_nomask_to_0.47x0.63_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.47x0.63/map_5x5min_nomask_to_0.47x0.63_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.47x0.63/map_0.9x1.25_nomask_to_0.47x0.63_nomask_aave_da_c200206.nc - - - -lnd/clm2/mappingdata/maps/0.9x1.25/map_0.125x0.125_nomask_to_0.9x1.25_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.9x1.25/map_0.5x0.5_nomask_to_0.9x1.25_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.9x1.25/map_0.25x0.25_nomask_to_0.9x1.25_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.9x1.25/map_10x10min_nomask_to_0.9x1.25_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.9x1.25/map_5x5min_nomask_to_0.9x1.25_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.9x1.25/map_3x3min_nomask_to_0.9x1.25_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.9x1.25/map_0.9x1.25_nomask_to_0.9x1.25_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.9x1.25/map_1km-merge-10min_HYDRO1K-merge-nomask_to_0.9x1.25_nomask_aave_da_c130405.nc - -lnd/clm2/mappingdata/maps/1.9x2.5/map_0.125x0.125_nomask_to_1.9x2.5_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1.9x2.5/map_0.5x0.5_nomask_to_1.9x2.5_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1.9x2.5/map_0.25x0.25_nomask_to_1.9x2.5_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1.9x2.5/map_10x10min_nomask_to_1.9x2.5_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1.9x2.5/map_5x5min_nomask_to_1.9x2.5_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1.9x2.5/map_3x3min_nomask_to_1.9x2.5_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/1.9x2.5/map_0.9x1.25_nomask_to_1.9x2.5_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/1.9x2.5/map_1km-merge-10min_HYDRO1K-merge-nomask_to_1.9x2.5_nomask_aave_da_c130405.nc - - -lnd/clm2/mappingdata/maps/10x15/map_0.125x0.125_nomask_to_10x15_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/10x15/map_0.5x0.5_nomask_to_10x15_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/10x15/map_0.25x0.25_nomask_to_10x15_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/10x15/map_10x10min_nomask_to_10x15_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/10x15/map_5x5min_nomask_to_10x15_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/10x15/map_3x3min_nomask_to_10x15_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/10x15/map_0.9x1.25_nomask_to_10x15_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/10x15/map_1km-merge-10min_HYDRO1K-merge-nomask_to_10x15_nomask_aave_da_c130411.nc - - - - - -lnd/clm2/mappingdata/maps/360x720/map_0.125x0.125_nomask_to_360x720cru_nomask_aave_da_c210823.nc -lnd/clm2/mappingdata/maps/360x720/map_0.5x0.5_nomask_to_360x720_nomask_aave_da_c120830.nc -lnd/clm2/mappingdata/maps/360x720/map_0.25x0.25_nomask_to_360x720cru_nomask_aave_da_c210823.nc -lnd/clm2/mappingdata/maps/360x720/map_3x3min_nomask_to_360x720cru_nomask_aave_da_c210823.nc -lnd/clm2/mappingdata/maps/360x720/map_10x10min_nomask_to_360x720_nomask_aave_da_c120830.nc -lnd/clm2/mappingdata/maps/360x720/map_5x5min_nomask_to_360x720_nomask_aave_da_c120830.nc -lnd/clm2/mappingdata/maps/360x720/map_0.9x1.25_nomask_to_360x720cru_nomask_aave_da_c210823.nc -lnd/clm2/mappingdata/maps/360x720/map_1km-merge-10min_HYDRO1K-merge-nomask_to_360x720_nomask_aave_da_c130403.nc - - - -lnd/clm2/mappingdata/maps/512x1024/map_0.125x0.125_nomask_to_512x1024_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/512x1024/map_0.5x0.5_nomask_to_512x1024_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/512x1024/map_0.25x0.25_nomask_to_512x1024_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/512x1024/map_10x10min_nomask_to_512x1024_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/512x1024/map_5x5min_nomask_to_512x1024_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/512x1024/map_3x3min_nomask_to_512x1024_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/512x1024/map_0.9x1.25_nomask_to_512x1024_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/512x1024/map_1km-merge-10min_HYDRO1K-merge-nomask_to_512x1024_nomask_aave_da_c130403.nc - - -lnd/clm2/mappingdata/maps/128x256/map_0.125x0.125_nomask_to_128x256_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/128x256/map_0.5x0.5_nomask_to_128x256_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/128x256/map_0.25x0.25_nomask_to_128x256_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/128x256/map_10x10min_nomask_to_128x256_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/128x256/map_5x5min_nomask_to_128x256_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/128x256/map_3x3min_nomask_to_128x256_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/128x256/map_0.9x1.25_nomask_to_128x256_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/128x256/map_1km-merge-10min_HYDRO1K-merge-nomask_to_128x256_nomask_aave_da_c130403.nc - - -lnd/clm2/mappingdata/maps/64x128/map_0.125x0.125_nomask_to_64x128_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/64x128/map_0.5x0.5_nomask_to_64x128_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/64x128/map_0.25x0.25_nomask_to_64x128_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/64x128/map_10x10min_nomask_to_64x128_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/64x128/map_5x5min_nomask_to_64x128_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/64x128/map_3x3min_nomask_to_64x128_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/64x128/map_0.9x1.25_nomask_to_64x128_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/64x128/map_1km-merge-10min_HYDRO1K-merge-nomask_to_64x128_nomask_aave_da_c130403.nc - -lnd/clm2/mappingdata/maps/48x96/map_0.125x0.125_nomask_to_48x96_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/48x96/map_0.5x0.5_nomask_to_48x96_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/48x96/map_0.25x0.25_nomask_to_48x96_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/48x96/map_10x10min_nomask_to_48x96_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/48x96/map_5x5min_nomask_to_48x96_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/48x96/map_3x3min_nomask_to_48x96_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/48x96/map_0.9x1.25_nomask_to_48x96_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/48x96/map_1km-merge-10min_HYDRO1K-merge-nomask_to_48x96_nomask_aave_da_c130405.nc - -lnd/clm2/mappingdata/maps/4x5/map_0.125x0.125_nomask_to_4x5_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/4x5/map_0.5x0.5_nomask_to_4x5_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/4x5/map_0.25x0.25_nomask_to_4x5_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/4x5/map_10x10min_nomask_to_4x5_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/4x5/map_5x5min_nomask_to_4x5_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/4x5/map_3x3min_nomask_to_4x5_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/4x5/map_0.9x1.25_nomask_to_4x5_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/4x5/map_1km-merge-10min_HYDRO1K-merge-nomask_to_4x5_nomask_aave_da_c130411.nc - -lnd/clm2/mappingdata/maps/0.23x0.31/map_0.125x0.125_nomask_to_0.23x0.31_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.23x0.31/map_0.5x0.5_nomask_to_0.23x0.31_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.23x0.31/map_0.25x0.25_nomask_to_0.23x0.31_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.23x0.31/map_10x10min_nomask_to_0.23x0.31_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.23x0.31/map_5x5min_nomask_to_0.23x0.31_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.23x0.31/map_3x3min_nomask_to_0.23x0.31_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.23x0.31/map_0.9x1.25_nomask_to_0.23x0.31_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.23x0.31/map_1km-merge-10min_HYDRO1K-merge-nomask_to_0.23x0.31_nomask_aave_da_c130405.nc - - -lnd/clm2/mappingdata/maps/2.5x3.33/map_0.125x0.125_nomask_to_2.5x3.33_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/2.5x3.33/map_0.5x0.5_nomask_to_2.5x3.33_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/2.5x3.33/map_0.25x0.25_nomask_to_2.5x3.33_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/2.5x3.33/map_10x10min_nomask_to_2.5x3.33_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/2.5x3.33/map_5x5min_nomask_to_2.5x3.33_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/2.5x3.33/map_3x3min_nomask_to_2.5x3.33_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/2.5x3.33/map_0.9x1.25_nomask_to_2.5x3.33_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/2.5x3.33/map_1km-merge-10min_HYDRO1K-merge-nomask_to_2.5x3.33_nomask_aave_da_c130405.nc - - - -lnd/clm2/mappingdata/maps/0.5x0.5/map_0.125x0.125_nomask_to_0.5x0.5_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.5x0.5/map_0.5x0.5_nomask_to_0.5x0.5_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.5x0.5/map_10x10min_nomask_to_0.5x0.5_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.5x0.5/map_0.25x0.25_nomask_to_0.5x0.5_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.5x0.5/map_3x3min_nomask_to_0.5x0.5_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.5x0.5/map_5x5min_nomask_to_0.5x0.5_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.5x0.5/map_0.9x1.25_nomask_to_0.5x0.5_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.5x0.5/map_1km-merge-10min_HYDRO1K-merge-nomask_to_0.5x0.5_nomask_aave_da_c130405.nc - - -lnd/clm2/mappingdata/maps/ne4np4/map_0.125x0.125_nomask_to_ne4np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne4np4/map_0.5x0.5_nomask_to_ne4np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne4np4/map_0.25x0.25_nomask_to_ne4np4_nomask_aave_da_c200309.nc - -lnd/clm2/mappingdata/maps/C24/map_0.5x0.5_TO_C24_aave.181018.nc -lnd/clm2/mappingdata/maps/C24/map_10x10min_nomask_to_C24_nomask_aave_da_c181018.nc -lnd/clm2/mappingdata/maps/C24/map_5x5min_nomask_to_C24_nomask_aave_da_c181018.nc -lnd/clm2/mappingdata/maps/C24/map_1km-merge-10min_HYDRO1K-merge-nomask_to_C24_nomask_aave_da_c181018.nc -lnd/clm2/mappingdata/maps/C24/map_C24_nomask_to_0.5x0.5_nomask_aave_da_c181018.nc - - - -lnd/clm2/mappingdata/maps/C48/map_0.5x0.5_TO_C48_aave.181018.nc -lnd/clm2/mappingdata/maps/C48/map_10x10min_nomask_to_C48_nomask_aave_da_c181018.nc -lnd/clm2/mappingdata/maps/C48/map_5x5min_nomask_to_C48_nomask_aave_da_c181018.nc -lnd/clm2/mappingdata/maps/C48/map_1km-merge-10min_HYDRO1K-merge-nomask_to_C48_nomask_aave_da_c181018.nc -lnd/clm2/mappingdata/maps/C48/map_C48_nomask_to_0.5x0.5_nomask_aave_da_c181018.nc - - - -lnd/clm2/mappingdata/maps/C96/map_0.5x0.5_TO_C96_aave.181018.nc -lnd/clm2/mappingdata/maps/C96/map_10x10min_nomask_to_C96_nomask_aave_da_c181018.nc -lnd/clm2/mappingdata/maps/C96/map_5x5min_nomask_to_C96_nomask_aave_da_c181018.nc -lnd/clm2/mappingdata/maps/C96/map_1km-merge-10min_HYDRO1K-merge-nomask_to_C96_nomask_aave_da_c181018.nc -lnd/clm2/mappingdata/maps/C96/map_C96_nomask_to_0.5x0.5_nomask_aave_da_c181018.nc - - - -lnd/clm2/mappingdata/maps/C192/map_0.5x0.5_TO_C192_aave.181018.nc -lnd/clm2/mappingdata/maps/C192/map_10x10min_nomask_to_C192_nomask_aave_da_c181018.nc -lnd/clm2/mappingdata/maps/C192/map_5x5min_nomask_to_C192_nomask_aave_da_c181018.nc -lnd/clm2/mappingdata/maps/C192/map_1km-merge-10min_HYDRO1K-merge-nomask_to_C192_nomask_aave_da_c181018.nc -lnd/clm2/mappingdata/maps/C192/map_C192_nomask_to_0.5x0.5_nomask_aave_da_c181018.nc - - - -lnd/clm2/mappingdata/maps/C384/map_0.5x0.5_TO_C384_aave.181018.nc -lnd/clm2/mappingdata/maps/C384/map_10x10min_nomask_to_C384_nomask_aave_da_c181018.nc -lnd/clm2/mappingdata/maps/C384/map_5x5min_nomask_to_C384_nomask_aave_da_c181018.nc -lnd/clm2/mappingdata/maps/C384/map_1km-merge-10min_HYDRO1K-merge-nomask_to_C384_nomask_aave_da_c181018.nc -lnd/clm2/mappingdata/maps/C384/map_C384_nomask_to_0.5x0.5_nomask_aave_da_c181018.nc - - -lnd/clm2/mappingdata/maps/ne4np4/map_10x10min_nomask_to_ne4np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne4np4/map_5x5min_nomask_to_ne4np4_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/ne4np4/map_3x3min_nomask_to_ne4np4_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/ne4np4/map_0.9x1.25_nomask_to_ne4np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne4np4/map_1km-merge-10min_HYDRO1K-merge-nomask_to_ne4np4_nomask_aave_da_c130411.nc - - -lnd/clm2/mappingdata/maps/ne16np4/map_0.125x0.125_nomask_to_ne16np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne16np4/map_0.5x0.5_nomask_to_ne16np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne16np4/map_0.25x0.25_nomask_to_ne16np4_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/ne16np4/map_10x10min_nomask_to_ne16np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne16np4/map_5x5min_nomask_to_ne16np4_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/ne16np4/map_3x3min_nomask_to_ne16np4_nomask_aave_da_c210506.nc -lnd/clm2/mappingdata/maps/ne16np4/map_0.9x1.25_nomask_to_ne16np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne16np4/map_1km-merge-10min_HYDRO1K-merge-nomask_to_ne16np4_nomask_aave_da_c130408.nc - - -lnd/clm2/mappingdata/maps/ne30np4/map_0.125x0.125_nomask_to_ne30np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne30np4/map_0.5x0.5_nomask_to_ne30np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne30np4/map_0.25x0.25_nomask_to_ne30np4_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/ne30np4/map_10x10min_nomask_to_ne30np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne30np4/map_5x5min_nomask_to_ne30np4_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/ne30np4/map_3x3min_nomask_to_ne30np4_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/ne30np4/map_0.9x1.25_nomask_to_ne30np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne30np4/map_1km-merge-10min_HYDRO1K-merge-nomask_to_ne30np4_nomask_aave_da_c130405.nc - - -lnd/clm2/mappingdata/maps/ne60np4/map_0.125x0.125_nomask_to_ne60np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne60np4/map_0.5x0.5_nomask_to_ne60np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne60np4/map_0.25x0.25_nomask_to_ne60np4_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/ne60np4/map_10x10min_nomask_to_ne60np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne60np4/map_5x5min_nomask_to_ne60np4_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/ne60np4/map_3x3min_nomask_to_ne60np4_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/ne60np4/map_0.9x1.25_nomask_to_ne60np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne60np4/map_1km-merge-10min_HYDRO1K-merge-nomask_to_ne60np4_nomask_aave_da_c130405.nc - -lnd/clm2/mappingdata/maps/ne120np4/map_0.125x0.125_nomask_to_ne120np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne120np4/map_0.5x0.5_nomask_to_ne120np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne120np4/map_0.25x0.25_nomask_to_ne120np4_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/ne120np4/map_10x10min_nomask_to_ne120np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne120np4/map_5x5min_nomask_to_ne120np4_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/ne120np4/map_3x3min_nomask_to_ne120np4_nomask_aave_da_c210506.nc -lnd/clm2/mappingdata/maps/ne120np4/map_0.9x1.25_nomask_to_ne120np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne120np4/map_1km-merge-10min_HYDRO1K-merge-nomask_to_ne120np4_nomask_aave_da_c130405.nc - - - - - - - - - - -lnd/clm2/mappingdata/maps/0.125x0.125/map_0.125x0.125_nomask_to_0.125nldas2_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.125x0.125/map_0.5x0.5_nomask_to_0.125nldas2_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.125x0.125/map_0.25x0.25_nomask_to_0.125nldas2_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.125x0.125/map_3x3min_nomask_to_0.125nldas2_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.125x0.125/map_1km-merge-10min_HYDRO1K-merge-nomask_to_0.125nldas2_nomask_aave_da_c140702.nc -lnd/clm2/mappingdata/maps/0.125x0.125/map_5x5min_nomask_to_0.125nldas2_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.125x0.125/map_10x10min_nomask_to_0.125nldas2_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.125x0.125/map_0.9x1.25_nomask_to_0.125nldas2_nomask_aave_da_c200206.nc - - - -lnd/clm2/mappingdata/maps/5x5_amazon/map_0.125x0.125_nomask_to_5x5_amazon_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/5x5_amazon/map_0.5x0.5_nomask_to_5x5_amazon_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/5x5_amazon/map_0.25x0.25_nomask_to_5x5_amazon_nomask_aave_da_c200309.nc - - - -lnd/clm2/mappingdata/maps/ne0np4CONUS.ne30x8/map_5x5min_nomask_to_ne0np4CONUS.ne30x8_nomask_aave_da_c200426.nc -lnd/clm2/mappingdata/maps/ne0np4CONUS.ne30x8/map_10x10min_nomask_to_ne0np4CONUS.ne30x8_nomask_aave_da_c200426.nc -lnd/clm2/mappingdata/maps/ne0np4CONUS.ne30x8/map_1km-merge-10min_HYDRO1K-merge-nomask_to_ne0np4CONUS.ne30x8_nomask_aave_da_c200426.nc - - -lnd/clm2/mappingdata/maps/5x5_amazon/map_10x10min_nomask_to_5x5_amazon_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/5x5_amazon/map_5x5min_nomask_to_5x5_amazon_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/5x5_amazon/map_3x3min_nomask_to_5x5_amazon_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/5x5_amazon/map_0.9x1.25_nomask_to_5x5_amazon_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/5x5_amazon/map_1km-merge-10min_HYDRO1K-merge-nomask_to_5x5_amazon_nomask_aave_da_c130403.nc - -lnd/clm2/mappingdata/maps/ne240np4/map_0.125x0.125_nomask_to_ne240np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne240np4/map_10x10min_nomask_to_ne240np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne240np4/map_0.5x0.5_nomask_to_ne240np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne240np4/map_0.25x0.25_nomask_to_ne240np4_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/ne240np4/map_3x3min_nomask_to_ne240np4_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/ne240np4/map_5x5min_nomask_to_ne240np4_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/ne240np4/map_0.9x1.25_nomask_to_ne240np4_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/ne240np4/map_1km-merge-10min_HYDRO1K-merge-nomask_to_ne240np4_nomask_aave_da_c130405.nc - - - - -lnd/clm2/mappingdata/maps/0.125x0.125/map_0.125x0.125_nomask_to_0.125x0.125_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.125x0.125/map_10x10min_nomask_to_0.125x0.125_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.125x0.125/map_1km-merge-10min_HYDRO1K-merge-nomask_to_0.125x0.125_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.125x0.125/map_0.5x0.5_nomask_to_0.125x0.125_nomask_aave_da_c200206.nc -lnd/clm2/mappingdata/maps/0.125x0.125/map_0.25x0.25_nomask_to_0.125x0.125_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.125x0.125/map_3x3min_nomask_to_0.125x0.125_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.125x0.125/map_5x5min_nomask_to_0.125x0.125_nomask_aave_da_c200309.nc -lnd/clm2/mappingdata/maps/0.125x0.125/map_0.9x1.25_nomask_to_0.125x0.125_nomask_aave_da_c200206.nc - - - - - -lnd/clm2/mappingdata/maps/1km/map_0.5x0.5_nomask_to_1km-merge-10min_HYDRO1K-merge-nomask_aave_da_c200206.nc - - - - - - - -lnd/clm2/mappingdata/maps/94x192/map_0.5x0.5_nomask_to_94x192_nomask_aave_da_c110823.nc -lnd/clm2/mappingdata/maps/94x192/map_94x192_nomask_to_0.5x0.5_nomask_aave_da_c110823.nc -lnd/clm2/mappingdata/maps/94x192/map_1km-merge-10min_HYDRO1K-merge-nomask_to_94x192_nomask_aave_da_c190521.nc -lnd/clm2/mappingdata/maps/94x192/map_5x5min_nomask_to_94x192_nomask_aave_da_c110823.nc -lnd/clm2/mappingdata/maps/94x192/map_10x10min_nomask_to_94x192_nomask_aave_da_c110823.nc - - - - - - -lnd/clm2/mappingdata/maps/ARCTIC/map_1km-merge-10min_HYDRO1K-merge-nomask_to_ne0np4.ARCTIC.ne30x4_nomask_aave_da_c200426.nc -lnd/clm2/mappingdata/maps/ARCTIC/map_5x5min_nomask_to_ne0np4.ARCTIC.ne30x4_nomask_aave_da_c200426.nc -lnd/clm2/mappingdata/maps/ARCTIC/map_10x10min_nomask_to_ne0np4.ARCTIC.ne30x4_nomask_aave_da_c200426.nc - - - - - - -lnd/clm2/mappingdata/maps/ARCTICGRIS/map_1km-merge-10min_HYDRO1K-merge-nomask_to_ne0np4.ARCTICGRIS.ne30x8_nomask_aave_da_c200426.nc -lnd/clm2/mappingdata/maps/ARCTICGRIS/map_5x5min_nomask_to_ne0np4.ARCTICGRIS.ne30x8_nomask_aave_da_c200426.nc -lnd/clm2/mappingdata/maps/ARCTICGRIS/map_10x10min_nomask_to_ne0np4.ARCTICGRIS.ne30x8_nomask_aave_da_c200426.nc - - - - - - -lnd/clm2/mappingdata/maps/ne30np4.pg2/map_5x5min_nomask_to_ne30np4.pg2_nomask_aave_da_c200426.nc -lnd/clm2/mappingdata/maps/ne30np4.pg2/map_1km-merge-10min_HYDRO1K-merge-nomask_to_ne30np4.pg2_nomask_aave_da_c200426.nc -lnd/clm2/mappingdata/maps/ne30np4.pg2/map_10x10min_nomask_to_ne30np4.pg2_nomask_aave_da_c200426.nc - - - - - - -lnd/clm2/mappingdata/maps/ne30pg3/map_5x5min_nomask_to_ne30np4.pg3_nomask_aave_da_c200426.nc -lnd/clm2/mappingdata/maps/ne30pg3/map_10x10min_nomask_to_ne30np4.pg3_nomask_aave_da_c200426.nc -lnd/clm2/mappingdata/maps/ne30pg3/map_1km-merge-10min_HYDRO1K-merge-nomask_to_ne30np4.pg3_nomask_aave_da_c200426.nc - - - - - - -lnd/clm2/mappingdata/maps/ne120np4.pg2/map_10x10min_nomask_to_ne120np4.pg2_nomask_aave_da_c200426.nc -lnd/clm2/mappingdata/maps/ne120np4.pg2/map_5x5min_nomask_to_ne120np4.pg2_nomask_aave_da_c200426.nc -lnd/clm2/mappingdata/maps/ne120np4.pg2/map_1km-merge-10min_HYDRO1K-merge-nomask_to_ne120np4.pg2_nomask_aave_da_c200426.nc - - - - - - -lnd/clm2/mappingdata/maps/ne120np4.pg3/map_10x10min_nomask_to_ne120np4.pg3_nomask_aave_da_c200426.nc -lnd/clm2/mappingdata/maps/ne120np4.pg3/map_1km-merge-10min_HYDRO1K-merge-nomask_to_ne120np4.pg3_nomask_aave_da_c200426.nc -lnd/clm2/mappingdata/maps/ne120np4.pg3/map_5x5min_nomask_to_ne120np4.pg3_nomask_aave_da_c200426.nc - - diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdLandUse/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesColdLandUse/user_nl_clm index 098d4fd33a..03031ac5b5 100644 --- a/cime_config/testdefs/testmods_dirs/clm/FatesColdLandUse/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdLandUse/user_nl_clm @@ -1,2 +1,2 @@ -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/landuse.timeseries_4x5_hist_simyr1850-2015_200311.nc' +flanduse_timeseries = '$DIN_LOC_ROOTlnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2000_c230517.nc' do_harvest = .true. diff --git a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README index 81fb991ed0..b51a675fdc 100644 --- a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README +++ b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README @@ -5,19 +5,18 @@ exercising the collapse2gencrop branch ability to collapse the full crop data to clm's generic crops. According to the file -/glade/work/slevis/git/collapse_pfts/bld/namelist_files/namelist_defaults_clm4_5.xml +bld/namelist_files/namelist_defaults_ctsm.xml the following two files used in this test are default files for the following options: -fsurdat = '/glade/p/cesmdata/cseg/inputdata/lnd/clm2/surfdata_map/surfdata_10x15_78pfts_CMIP6_simyr1850_c170824.nc' +fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc' +hgrid="10x15" sim_year="1850" use_crop=".false." irrigate=".true." hgrid="10x15" sim_year="1850" use_crop=".true." -flanduse_timeseries = '/glade/p/cesmdata/cseg/inputdata/lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc' -hgrid="10x15" sim_year_range="1850-2000" use_crop=".true." -hgrid="10x15" rcp="8.5" sim_year_range="1850-2100" use_crop=".true." -hgrid="10x15" rcp="6" sim_year_range="1850-2100" use_crop=".true." -hgrid="10x15" rcp="4.5" sim_year_range="1850-2100" use_crop=".true." -hgrid="10x15" rcp="2.6" sim_year_range="1850-2100" use_crop=".true." +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2000_c230517.nc' +hgrid="10x15" sim_year_range="1850-2000" irrigate=".true." use_vichydro=".true." +hgrid="10x15" sim_year_range="1850-2000" irrigate=".true." +hgrid="10x15" sim_year_range="1850-2000" use_vichydro=".false." This test includes the settings of the decStart test so as to also test the end-of-year transition since it's an IHist case and transient vegetation gets diff --git a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm index ff78e0122c..9662b3ed28 100644 --- a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm @@ -1,2 +1,2 @@ -fsurdat = '/glade/p/cesmdata/cseg/inputdata/lnd/clm2/surfdata_map/surfdata_10x15_78pfts_CMIP6_simyr1850_c170824.nc' -flanduse_timeseries = '/glade/p/cesmdata/cseg/inputdata/lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc' +fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc' +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2000_c230517.nc' diff --git a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm index efb3212d5f..c3d324ed88 100644 --- a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm @@ -1,5 +1,5 @@ ! Specify a dataset that has non-zero Gross Unrepresented Land Use change fields on it ! And turn it on - flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_0.9x1.25_hist_78pfts_CMIP6_simyr1700-2021_c220825.nc' - fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_0.9x1.25_hist_78pfts_CMIP6_simyr1700_c220825.nc' + flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2000_c230517.nc' + fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc' do_grossunrep = .true. diff --git a/python/ctsm/modify_input_files/modify_fsurdat.py b/python/ctsm/modify_input_files/modify_fsurdat.py index 9b3760e303..ae5dd3a527 100644 --- a/python/ctsm/modify_input_files/modify_fsurdat.py +++ b/python/ctsm/modify_input_files/modify_fsurdat.py @@ -414,7 +414,6 @@ def set_idealized(self): self.setvar_lev0("SLOPE", slope) self.setvar_lev0("zbedrock", zbedrock) self.setvar_lev0("SOIL_COLOR", soil_color) - self.setvar_lev0("PFTDATA_MASK", pftdata_mask) self.setvar_lev0("LANDFRAC_PFT", landfrac_pft) self.setvar_lev0("PCT_WETLAND", pct_not_nat_veg) self.setvar_lev0("PCT_CROP", pct_not_nat_veg) diff --git a/python/ctsm/test/test_sys_fsurdat_modifier.py b/python/ctsm/test/test_sys_fsurdat_modifier.py index 72d38732cf..23eefb57d4 100755 --- a/python/ctsm/test/test_sys_fsurdat_modifier.py +++ b/python/ctsm/test/test_sys_fsurdat_modifier.py @@ -45,7 +45,7 @@ def setUp(self): self._testinputs_path = testinputs_path self._fsurdat_in = os.path.join( testinputs_path, - "surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc", + "surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc", ) self._tempdir = tempfile.mkdtemp() self._cfg_file_path = os.path.join(self._tempdir, "modify_fsurdat.cfg") @@ -77,7 +77,7 @@ def test_short_config(self): sys.argv = ["fsurdat_modifier", self._cfg_file_path] parser = fsurdat_modifier_arg_process() fsurdat_out = ( - "ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_out.nc" + "ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_out.nc" ) if os.path.exists(fsurdat_out): os.remove(fsurdat_out) @@ -134,14 +134,14 @@ def test_opt_sections(self): self._cfg_file_path = os.path.join(self._testinputs_path, "modify_fsurdat_opt_sections.cfg") outfile = os.path.join( self._tempdir, - "surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_output_urban.nc", + "surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_output_urban.nc", ) sys.argv = [ "fsurdat_modifier", self._cfg_file_path, "-i", os.path.join( - self._testinputs_path, "surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc" + self._testinputs_path, "surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc" ), "-o", outfile, diff --git a/python/ctsm/test/testinputs/default_data.cfg b/python/ctsm/test/testinputs/default_data.cfg index 7e841dca54..7f78cde62a 100644 --- a/python/ctsm/test/testinputs/default_data.cfg +++ b/python/ctsm/test/testinputs/default_data.cfg @@ -15,14 +15,14 @@ precname = CLMGSWP3v1.Precip tpqwname = CLMGSWP3v1.TPQW [surfdat] -dir = lnd/clm2/surfdata_map/release-clm5.0.18 -surfdat_16pft = surfdata_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr2000_c190214.nc -surfdat_78pft = surfdata_0.9x1.25_hist_78pfts_CMIP6_simyr2000_c190214.nc +dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 +surfdat_16pft = surfdata_0.9x1.25_hist_16pfts_CMIP6_2000_c230517.nc +surfdat_78pft = surfdata_0.9x1.25_hist_78pfts_CMIP6_2000_c230517.nc [landuse] -dir = lnd/clm2/surfdata_map/release-clm5.0.18 -landuse_16pft = landuse.timeseries_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c190214.nc -landuse_78pft = landuse.timeseries_0.9x1.25_hist_78pfts_CMIP6_simyr1850-2015_c190214.nc +dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 +landuse_16pft = landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2000_c230517.nc +landuse_78pft = landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2000_c230517.nc [domain] file = share/domains/domain.lnd.fv0.9x1.25_gx1v7.151020.nc diff --git a/python/ctsm/test/testinputs/modify_fsurdat_short.cfg b/python/ctsm/test/testinputs/modify_fsurdat_short.cfg index 74c6639899..d43a8e8847 100644 --- a/python/ctsm/test/testinputs/modify_fsurdat_short.cfg +++ b/python/ctsm/test/testinputs/modify_fsurdat_short.cfg @@ -1,7 +1,7 @@ [modify_fsurdat_basic_options] -fsurdat_in = ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc -fsurdat_out = ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_out.nc +fsurdat_in = ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc +fsurdat_out = ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_out.nc idealized = False process_subgrid_section = False diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 55ce09dd61..877e40e993 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -69,7 +69,7 @@ Building the executable (working in tools/mksurfdata_esmf) ======================= Running for a single submission: ======================= -# Work in the ctsm_py environment, which requires the following steps: +# Work in the ctsm_pylib environment, which requires the following steps: > module unload python; module load conda > cd ../..; ./py_env_create > conda activate ctsm_py; cd tools/mksurfdata_esmf @@ -93,10 +93,10 @@ Running for a single submission: ======================= Running for the generation of multiple datasets ======================= -# Notes: -# - gen_mksurfdata_jobscript_multi.py runs ./gen_mksurfdata_namelist.py for you -# - The regional grid 5x5_amazon may fail with 24 nodes. -# Task geometry that worked: #PBS -l select=4:ncpus=36:mpiprocs=4 +# Work in the ctsm_pylib environment, as explained in earlier section. +# gen_mksurfdata_jobscript_multi.py runs ./gen_mksurfdata_namelist.py for you +# The regional grid 5x5_amazon may fail with 24 nodes. +# Task geometry that worked: #PBS -l select=4:ncpus=36:mpiprocs=4 > ./gen_mksurfdata_jobscript_multi.py --help > ./gen_mksurfdata_jobscript_multi.py --number-of-nodes 24 --scenario all > qsub mksurfdata_jobscript_multi diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 679c8e3e05..bf06c458f9 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -16,20 +16,15 @@ "global-present-nldas", "tropics", "crop-tropics-present", - "crop-tropics-historical", - "crop-tropics-transient", "crop", "crop-global-present", "crop-global-present-ne16np4", "crop-global-present-ne120np4", "crop-global-present-0.125", "crop-global-present-f05", - "crop-global-historical", - "crop-global-historical-f05", - "crop-global-historical-ne120np4", - "crop-global-transient", - "crop-global-transient-ne120np4", - "crop-global-transient-f05", + "crop-global-1850", + "crop-global-1850-ne120np4", + "crop-global-hist", "crop-global-future", "crop-global-SSP1-2.6", "crop-global-SSP3-7.0", @@ -38,7 +33,8 @@ "crop-global-SSP1-1.9", "crop-global-SSP4-3.4", "crop-global-SSP4-6.0", - "crop-global-SSP5-8.5"] + "crop-global-SSP5-8.5", + "crop-global-SSP5-8.5-neres"] def get_parser(): """ @@ -122,8 +118,8 @@ def main (): "crop-global-present", "crop-global-present-ne16np4", "crop-global-present-ne120np4", - "crop-global-historical", - "crop-global-transient", + "crop-global-1850", + "crop-global-hist", "crop-tropics-present", "crop-global-SSP1-2.6", "crop-global-SSP3-7.0", @@ -132,7 +128,8 @@ def main (): "crop-global-SSP1-1.9", "crop-global-SSP4-3.4", "crop-global-SSP4-6.0", - "crop-global-SSP5-8.5"] + "crop-global-SSP5-8.5", + "crop-global-SSP5-8.5-neres"] elif scenario == 'standard': target_list = ["global-present", "global-present-T42", @@ -141,8 +138,8 @@ def main (): target_list = ["crop-global-present", "crop-global-present-ne16np4", "crop-global-present-ne120np4", - "crop-global-historical", - "crop-global-transient"] + "crop-global-1850", + "crop-global-hist"] elif scenario == "crop-global-future": target_list = ["crop-global-SSP1-2.6", "crop-global-SSP3-7.0", @@ -151,7 +148,8 @@ def main (): "crop-global-SSP1-1.9", "crop-global-SSP4-3.4", "crop-global-SSP4-6.0", - "crop-global-SSP5-8.5"] + "crop-global-SSP5-8.5", + "crop-global-SSP5-8.5-neres"] elif scenario == "tropics": target_list = ["crop-tropics-present"] else: @@ -161,13 +159,13 @@ def main (): # Determine resolution sets that are referenced in commands # -------------------------- resolution_dict = { - "standard_res_no_crop" : ["0.9x1.25","1.9x2.5","10x15"], - "standard_res" : ['0.9x1.25','1.9x2.5','10x15','4x5','C96', + "standard_res_no_crop" : ["0.9x1.25","1.9x2.5","10x15","4x5"], + "most_res" : ['0.9x1.25','1.9x2.5','10x15','4x5','C96', 'ne30np4','ne30np4.pg2','ne30np4.pg3','ne30np4.pg4','ne120np4.pg3', 'ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4', 'ne0np4CONUS.ne30x8'], - "future_res" : ["0.9x1.25","1.9x2.5","10x15"], - "trans_res" : ['0.9x1.25','1.9x2.5','10x15','ne30np4', - 'ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4','ne0np4CONUS.ne30x8','ne120np4'], + "standard_res" : ["0.9x1.25","1.9x2.5","10x15"], + "future_ne_res" : ['ne30np4','ne0np4.ARCTICGRIS.ne30x8', + 'ne0np4.ARCTIC.ne30x4','ne0np4CONUS.ne30x8','ne120np4'], "T42_res" : ['T42'], "nldas_res" : ['0.125nldas2'], "5x5_amazon_res" : ['5x5_amazon'], @@ -182,22 +180,22 @@ def main (): "global-present-T42" : ("--start-year 2000 --end-year 2000 --nocrop --vic --res", "T42_res"), "global-present-nldas" : ("--start-year 2000 --end-year 2000 --nocrop --vic --res", "nldas_res"), "crop-tropics-present" : ("--start-year 2000 --end-year 2000 --res", "5x5_amazon_res"), - "crop-global-present" : ("--start-year 2000 --end-year 2000 --res", "standard_res"), + "crop-global-present" : ("--start-year 2000 --end-year 2000 --res", "most_res"), "crop-global-present-ne16np4" : ("--start-year 2000 --end-year 2000 --res", "ne16np4_res"), "crop-global-present-ne120np4" : ("--start-year 2000 --end-year 2000 --res", "ne120np4_res"), "crop-global-present-0.125" : ("--start-year 2000 --end-year 2000 --hirespft --res", "nldas_res"), - "crop-global-historical" : ("--start-year 1850 --end-year 1850 --ssp-rcp SSP5-8.5 --res", "standard_res"), - "crop-global-historical-ne120np4" : ("--start-year 1850 --end-year 1850 --ssp-rcp SSP5-8.5 --res", "ne120np4_res"), - "crop-global-transient" : ("--start-year 1850 --end-year 2000 --nosurfdata --res", "trans_res"), - "crop-global-transient-ne120np4" : ("--start-year 1850 --end-year 2000 --nosurfdata --res", "ne120np4_res"), - "crop-global-SSP1-1.9" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-1.9 --res", "future_res"), - "crop-global-SSP1-2.6" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-2.6 --res", "future_res"), - "crop-global-SSP2-4.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", "future_res"), - "crop-global-SSP3-7.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP3-7.0 --res", "future_res"), - "crop-global-SSP4-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-3.4 --res", "future_res"), - "crop-global-SSP4-6.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-6.0 --res", "future_res"), - "crop-global-SSP5-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-3.4 --res", "future_res"), - "crop-global-SSP5-8.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-8.5 --res", "future_res") + "crop-global-1850" : ("--start-year 1850 --end-year 1850 --res", "most_res"), + "crop-global-1850-ne120np4" : ("--start-year 1850 --end-year 1850 --res", "ne120np4_res"), + "crop-global-hist" : ("--start-year 1850 --end-year 2015 --nosurfdata --res", "standard_res"), + "crop-global-SSP1-1.9" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-1.9 --res", "standard_res"), + "crop-global-SSP1-2.6" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-2.6 --res", "standard_res"), + "crop-global-SSP2-4.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", "standard_res"), + "crop-global-SSP3-7.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP3-7.0 --res", "standard_res"), + "crop-global-SSP4-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-3.4 --res", "standard_res"), + "crop-global-SSP4-6.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-6.0 --res", "standard_res"), + "crop-global-SSP5-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-3.4 --res", "standard_res"), + "crop-global-SSP5-8.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-8.5 --res", "standard_res"), + "crop-global-SSP5-8.5-neres" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-8.5 --res", "future_ne_res") } # -------------------------- From 470efa990e163dee7ec5eebd1e71c288d49997e6 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 5 Jun 2023 14:39:37 -0600 Subject: [PATCH 297/614] 2nd update of namelist_defaults_ctsm.xml + other files for consistency --- bld/namelist_files/namelist_defaults_ctsm.xml | 68 +++++++++---------- .../README | 4 +- .../user_nl_clm | 4 +- .../clm/f09_dec1990Start_GU_LULCC/user_nl_clm | 4 +- python/ctsm/test/testinputs/default_data.cfg | 4 +- 5 files changed, 42 insertions(+), 42 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 0d779789d4..c48c643190 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1035,7 +1035,7 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_16pfts_CMIP6_2000_c230517 lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_16pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_16pfts_CMIP6_2000_c230530.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_16pfts_CMIP6_2000_c230517.nc @@ -1117,16 +1117,16 @@ lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_urbanc_alpha_hist_78pfts_CMIP6 -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_78pfts_CMIP6_1850_c230517.nc @@ -1135,19 +1135,19 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C384_hist_78pfts_CMIP6_simyr185 lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C192_hist_78pfts_CMIP6_simyr1850_c200317.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_78pfts_CMIP6_1850_c230517.nc lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C48_hist_78pfts_CMIP6_simyr1850_c200317.nc lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C24_hist_78pfts_CMIP6_simyr1850_c200317.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_1850_c230517.nc lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_simyr1850_c230123.nc @@ -1157,23 +1157,23 @@ lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_numaIA_hist_78pfts_CMIP6_simyr lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_brazil_hist_78pfts_CMIP6_simyr1850_c230123.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4_hist_78pfts_CMIP6_1850-2000_c230517.nc +lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne120np4_hist_78pfts_CMIP6_simyr1850_c200427.nc lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne120np4.pg2_hist_78pfts_CMIP6_simyr1850_c200426.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4.pg3_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4.pg3_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x8_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x8_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTIC.ne30x4_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTIC.ne30x4_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.CONUS.ne30x8_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts_CMIP6_1850_c230517.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2000_c230517.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c230601.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2000_c230517.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c230601.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_hist_78_CMIP6_1850-2000_c230517.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_hist_78_CMIP6_1850-2015_c230601.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_hist_78_CMIP6_1850-2000_c230517.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_hist_78_CMIP6_1850-2015_c230601.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2000_c230517.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2015_c230601.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2000_c230517.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2015_c230601.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np4_hist_78_CMIP6_1850-2000_c230517.nc + use_crop=".false." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np4_SSP5-8.5_78_CMIP6_1850-2100_c230530.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne0np4.ARCTIC.ne30x4_hist_78_CMIP6_1850-2000_c230517.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne0np4.ARCTIC.ne30x4_SSP5-8.5_78_CMIP6_1850-2100_c230530.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2000_c230517.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c230601.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_hist_78_CMIP6_1850-2000_c230517.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_hist_78_CMIP6_1850-2015_c230601.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2000_c230517.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2015_c230601.nc lnd/clm2/surfdata_map/ctsm5.1.dev116/landuse.timeseries_1x1_brazil_hist_78pfts_CMIP6_simyr1850-2015_c230123.nc @@ -1215,13 +1215,13 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.CONUS.ne30x8_SSP5-8.5_78pfts_CM use_crop=".true." >lnd/clm2/surfdata_map/landuse.timeseries_1x1_numaIA_hist_78pfts_CMIP6_simyr1850-2015_c170917.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np4_hist_78_CMIP6_1850-2000_c230517.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np4_SSP5-8.5_78_CMIP6_1850-2100_c230530.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne0np4.ARCTICGRIS.ne30x8_hist_78_CMIP6_1850-2000_c230517.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne0np4.ARCTICGRIS.ne30x8_SSP5-8.5_78_CMIP6_1850-2100_c230530. lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne0np4.ARCTIC.ne30x4_hist_78_CMIP6_1850-2000_c230517.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne0np4.ARCTIC.ne30x4_SSP5-8.5_78_CMIP6_1850-2100_c230530.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne0np4.CONUS.ne30x8_hist_78_CMIP6_1850-2000_c230517.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne0np4CONUS.ne30x8_SSP5-8.5_78_CMIP6_1850-2100_c230530.nc lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_C24_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200317.nc diff --git a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README index b51a675fdc..6d7466459a 100644 --- a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README +++ b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README @@ -9,11 +9,11 @@ bld/namelist_files/namelist_defaults_ctsm.xml the following two files used in this test are default files for the following options: -fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc' +fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_1850_c230517.nc' hgrid="10x15" sim_year="1850" use_crop=".false." irrigate=".true." hgrid="10x15" sim_year="1850" use_crop=".true." -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2000_c230517.nc' +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2015_c230601.nc' hgrid="10x15" sim_year_range="1850-2000" irrigate=".true." use_vichydro=".true." hgrid="10x15" sim_year_range="1850-2000" irrigate=".true." hgrid="10x15" sim_year_range="1850-2000" use_vichydro=".false." diff --git a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm index 9662b3ed28..0bd2a29688 100644 --- a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm @@ -1,2 +1,2 @@ -fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc' -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2000_c230517.nc' +fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_1850_c230517.nc' +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2015_c230601.nc' diff --git a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm index c3d324ed88..3b8eeaf33e 100644 --- a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm @@ -1,5 +1,5 @@ ! Specify a dataset that has non-zero Gross Unrepresented Land Use change fields on it ! And turn it on - flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2000_c230517.nc' - fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_SSP5-8.5_78pfts_CMIP6_1850_c230517.nc' + flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c230601.nc' + fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_78pfts_CMIP6_1850_c230517.nc' do_grossunrep = .true. diff --git a/python/ctsm/test/testinputs/default_data.cfg b/python/ctsm/test/testinputs/default_data.cfg index 7f78cde62a..17c7ef5f99 100644 --- a/python/ctsm/test/testinputs/default_data.cfg +++ b/python/ctsm/test/testinputs/default_data.cfg @@ -21,8 +21,8 @@ surfdat_78pft = surfdata_0.9x1.25_hist_78pfts_CMIP6_2000_c230517.nc [landuse] dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -landuse_16pft = landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2000_c230517.nc -landuse_78pft = landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2000_c230517.nc +landuse_16pft = landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c230601.nc +landuse_78pft = landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c230601.nc [domain] file = share/domains/domain.lnd.fv0.9x1.25_gx1v7.151020.nc From aadf54d63b2b615fa879b66c10efc8f288504d05 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 21 Jun 2023 18:52:18 -0600 Subject: [PATCH 298/614] Updates to address failures in cheyenne test-suite --- bld/namelist_files/namelist_defaults_ctsm.xml | 4 ++-- cime_config/testdefs/testlist_clm.xml | 4 ++-- .../clm/FatesColdLandUse/user_nl_clm | 2 +- .../gen_mksurfdata_jobscript_multi.py | 17 +++++++++++------ 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index c48c643190..bd14538b4d 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1226,7 +1226,7 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts_CMIP6_ lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_C24_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200317.nc lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_C96_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200317.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_C96_SSP5-8.5_78_CMIP6_1850-2100_c230621.nc -lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_vancouverCAN_hist_78pfts_CMIP6_simyr2000_c230123.nc +/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_vancouverCAN_hist_78pfts_CMIP6_simyr2000_c230726.nc + -lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_mexicocityMEX_hist_78pfts_CMIP6_simyr2000_c230123.nc +/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_mexicocityMEX_hist_78pfts_CMIP6_simyr2000_c230726.nc + -lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_urbanc_alpha_hist_78pfts_CMIP6_simyr2000_c230123.nc +/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_urbanc_alpha_hist_78pfts_CMIP6_simyr2000_c230726.nc + @@ -1226,12 +1232,15 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_1850_c230517.n lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_simyr1850_c230123.nc +/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_1850_c230726.nc + -lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_numaIA_hist_78pfts_CMIP6_simyr1850_c230123.nc +/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_numaIA_hist_78pfts_CMIP6_1850_c230726.nc + -lnd/clm2/surfdata_map/ctsm5.1.dev116/surfdata_1x1_brazil_hist_78pfts_CMIP6_simyr1850_c230123.nc +/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_brazil_hist_78pfts_CMIP6_1850_c230726.nc + lnd/clm2/surfdata_map/ctsm5.1.dev120/surfdata_ne3np4.pg3_hist_78pfts_CMIP6_simyr1850_c230405.nc @@ -1293,7 +1302,8 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts_CMIP6_ use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2015_c230601.nc lnd/clm2/surfdata_map/ctsm5.1.dev116/landuse.timeseries_1x1_brazil_hist_78pfts_CMIP6_simyr1850-2015_c230123.nc +>/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/landuse.timeseries_1x1_brazil_hist_78_CMIP6_1850-2015_c230726.nc + lnd/clm2/surfdata_map/landuse.timeseries_1x1_numaIA_hist_78pfts_CMIP6_simyr1850-2015_c170917.nc From 72cdabcd1654e0a8ae80ef497181e1172fea4359 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 23 Aug 2023 19:23:10 -0600 Subject: [PATCH 309/614] Don't hardwire soil depths for Vancouver or Mexicocity --- src/main/initVerticalMod.F90 | 142 +++++++---------------------------- 1 file changed, 28 insertions(+), 114 deletions(-) diff --git a/src/main/initVerticalMod.F90 b/src/main/initVerticalMod.F90 index 134c5edc1e..4d28638440 100644 --- a/src/main/initVerticalMod.F90 +++ b/src/main/initVerticalMod.F90 @@ -16,7 +16,7 @@ module initVerticalMod use clm_varpar , only : toplev_equalspace, nlev_equalspace use clm_varpar , only : nlevsoi, nlevsoifl, nlevurb, nlevmaxurbgrnd use clm_varctl , only : fsurdat, iulog - use clm_varctl , only : use_vancouver, use_mexicocity, use_extralakelayers + use clm_varctl , only : use_extralakelayers use clm_varctl , only : use_bedrock, rundef use clm_varctl , only : soil_layerstruct_predefined, soil_layerstruct_userdefined use clm_varctl , only : use_fates @@ -308,122 +308,36 @@ subroutine initVertical(bounds, glc_behavior, thick_wall, thick_roof) ! "0" refers to urban wall/roof surface and "nlevsoi" refers to urban wall/roof bottom if (lun%urbpoi(l)) then - if (use_vancouver) then - zurb_wall(l,1) = 0.010_r8/2._r8 - zurb_wall(l,2) = zurb_wall(l,1) + 0.010_r8/2._r8 + 0.020_r8/2._r8 - zurb_wall(l,3) = zurb_wall(l,2) + 0.020_r8/2._r8 + 0.070_r8/2._r8 - zurb_wall(l,4) = zurb_wall(l,3) + 0.070_r8/2._r8 + 0.070_r8/2._r8 - zurb_wall(l,5) = zurb_wall(l,4) + 0.070_r8/2._r8 + 0.030_r8/2._r8 - - zurb_roof(l,1) = 0.010_r8/2._r8 - zurb_roof(l,2) = zurb_roof(l,1) + 0.010_r8/2._r8 + 0.010_r8/2._r8 - zurb_roof(l,3) = zurb_roof(l,2) + 0.010_r8/2._r8 + 0.010_r8/2._r8 - zurb_roof(l,4) = zurb_roof(l,3) + 0.010_r8/2._r8 + 0.010_r8/2._r8 - zurb_roof(l,5) = zurb_roof(l,4) + 0.010_r8/2._r8 + 0.030_r8/2._r8 - - dzurb_wall(l,1) = 0.010_r8 - dzurb_wall(l,2) = 0.020_r8 - dzurb_wall(l,3) = 0.070_r8 - dzurb_wall(l,4) = 0.070_r8 - dzurb_wall(l,5) = 0.030_r8 - write(iulog,*)'Total thickness of wall: ',sum(dzurb_wall(l,:)) - write(iulog,*)'Wall layer thicknesses: ',dzurb_wall(l,:) - - dzurb_roof(l,1) = 0.010_r8 - dzurb_roof(l,2) = 0.010_r8 - dzurb_roof(l,3) = 0.010_r8 - dzurb_roof(l,4) = 0.010_r8 - dzurb_roof(l,5) = 0.030_r8 - write(iulog,*)'Total thickness of roof: ',sum(dzurb_roof(l,:)) - write(iulog,*)'Roof layer thicknesses: ',dzurb_roof(l,:) - - ziurb_wall(l,0) = 0. - ziurb_wall(l,1) = dzurb_wall(l,1) - do j = 2,nlevurb - ziurb_wall(l,j) = sum(dzurb_wall(l,1:j)) - end do - write(iulog,*)'Wall layer interface depths: ',ziurb_wall(l,:) + do j = 1, nlevurb + zurb_wall(l,j) = (j-0.5)*(thick_wall(l)/float(nlevurb)) !node depths + end do + do j = 1, nlevurb + zurb_roof(l,j) = (j-0.5)*(thick_roof(l)/float(nlevurb)) !node depths + end do - ziurb_roof(l,0) = 0. - ziurb_roof(l,1) = dzurb_roof(l,1) - do j = 2,nlevurb - ziurb_roof(l,j) = sum(dzurb_roof(l,1:j)) - end do - write(iulog,*)'Roof layer interface depths: ',ziurb_roof(l,:) - else if (use_mexicocity) then - zurb_wall(l,1) = 0.015_r8/2._r8 - zurb_wall(l,2) = zurb_wall(l,1) + 0.015_r8/2._r8 + 0.120_r8/2._r8 - zurb_wall(l,3) = zurb_wall(l,2) + 0.120_r8/2._r8 + 0.150_r8/2._r8 - zurb_wall(l,4) = zurb_wall(l,3) + 0.150_r8/2._r8 + 0.150_r8/2._r8 - zurb_wall(l,5) = zurb_wall(l,4) + 0.150_r8/2._r8 + 0.015_r8/2._r8 - - zurb_roof(l,1) = 0.010_r8/2._r8 - zurb_roof(l,2) = zurb_roof(l,1) + 0.010_r8/2._r8 + 0.050_r8/2._r8 - zurb_roof(l,3) = zurb_roof(l,2) + 0.050_r8/2._r8 + 0.050_r8/2._r8 - zurb_roof(l,4) = zurb_roof(l,3) + 0.050_r8/2._r8 + 0.050_r8/2._r8 - zurb_roof(l,5) = zurb_roof(l,4) + 0.050_r8/2._r8 + 0.025_r8/2._r8 - - dzurb_wall(l,1) = 0.015_r8 - dzurb_wall(l,2) = 0.120_r8 - dzurb_wall(l,3) = 0.150_r8 - dzurb_wall(l,4) = 0.150_r8 - dzurb_wall(l,5) = 0.015_r8 - write(iulog,*)'Total thickness of wall: ',sum(dzurb_wall(l,:)) - write(iulog,*)'Wall layer thicknesses: ',dzurb_wall(l,:) - - dzurb_roof(l,1) = 0.010_r8 - dzurb_roof(l,2) = 0.050_r8 - dzurb_roof(l,3) = 0.050_r8 - dzurb_roof(l,4) = 0.050_r8 - dzurb_roof(l,5) = 0.025_r8 - write(iulog,*)'Total thickness of roof: ',sum(dzurb_roof(l,:)) - write(iulog,*)'Roof layer thicknesses: ',dzurb_roof(l,:) - - ziurb_wall(l,0) = 0. - ziurb_wall(l,1) = dzurb_wall(l,1) - do j = 2,nlevurb - ziurb_wall(l,j) = sum(dzurb_wall(l,1:j)) - end do - write(iulog,*)'Wall layer interface depths: ',ziurb_wall(l,:) + dzurb_roof(l,1) = 0.5*(zurb_roof(l,1)+zurb_roof(l,2)) !thickness b/n two interfaces + do j = 2,nlevurb-1 + dzurb_roof(l,j)= 0.5*(zurb_roof(l,j+1)-zurb_roof(l,j-1)) + enddo + dzurb_roof(l,nlevurb) = zurb_roof(l,nlevurb)-zurb_roof(l,nlevurb-1) - ziurb_roof(l,0) = 0. - ziurb_roof(l,1) = dzurb_roof(l,1) - do j = 2,nlevurb - ziurb_roof(l,j) = sum(dzurb_roof(l,1:j)) - end do - write(iulog,*)'Roof layer interface depths: ',ziurb_roof(l,:) - else - do j = 1, nlevurb - zurb_wall(l,j) = (j-0.5)*(thick_wall(l)/float(nlevurb)) !node depths - end do - do j = 1, nlevurb - zurb_roof(l,j) = (j-0.5)*(thick_roof(l)/float(nlevurb)) !node depths - end do + dzurb_wall(l,1) = 0.5*(zurb_wall(l,1)+zurb_wall(l,2)) !thickness b/n two interfaces + do j = 2,nlevurb-1 + dzurb_wall(l,j)= 0.5*(zurb_wall(l,j+1)-zurb_wall(l,j-1)) + enddo + dzurb_wall(l,nlevurb) = zurb_wall(l,nlevurb)-zurb_wall(l,nlevurb-1) - dzurb_roof(l,1) = 0.5*(zurb_roof(l,1)+zurb_roof(l,2)) !thickness b/n two interfaces - do j = 2,nlevurb-1 - dzurb_roof(l,j)= 0.5*(zurb_roof(l,j+1)-zurb_roof(l,j-1)) - enddo - dzurb_roof(l,nlevurb) = zurb_roof(l,nlevurb)-zurb_roof(l,nlevurb-1) - - dzurb_wall(l,1) = 0.5*(zurb_wall(l,1)+zurb_wall(l,2)) !thickness b/n two interfaces - do j = 2,nlevurb-1 - dzurb_wall(l,j)= 0.5*(zurb_wall(l,j+1)-zurb_wall(l,j-1)) - enddo - dzurb_wall(l,nlevurb) = zurb_wall(l,nlevurb)-zurb_wall(l,nlevurb-1) - - ziurb_wall(l,0) = 0. - do j = 1, nlevurb-1 - ziurb_wall(l,j) = 0.5*(zurb_wall(l,j)+zurb_wall(l,j+1)) !interface depths - enddo - ziurb_wall(l,nlevurb) = zurb_wall(l,nlevurb) + 0.5*dzurb_wall(l,nlevurb) - - ziurb_roof(l,0) = 0. - do j = 1, nlevurb-1 - ziurb_roof(l,j) = 0.5*(zurb_roof(l,j)+zurb_roof(l,j+1)) !interface depths - enddo - ziurb_roof(l,nlevurb) = zurb_roof(l,nlevurb) + 0.5*dzurb_roof(l,nlevurb) - end if + ziurb_wall(l,0) = 0. + do j = 1, nlevurb-1 + ziurb_wall(l,j) = 0.5*(zurb_wall(l,j)+zurb_wall(l,j+1)) !interface depths + enddo + ziurb_wall(l,nlevurb) = zurb_wall(l,nlevurb) + 0.5*dzurb_wall(l,nlevurb) + + ziurb_roof(l,0) = 0. + do j = 1, nlevurb-1 + ziurb_roof(l,j) = 0.5*(zurb_roof(l,j)+zurb_roof(l,j+1)) !interface depths + enddo + ziurb_roof(l,nlevurb) = zurb_roof(l,nlevurb) + 0.5*dzurb_roof(l,nlevurb) end if end do From 6935fb8bc1f6107d3585a554dde9df0383a0122f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 25 Aug 2023 17:06:41 -0600 Subject: [PATCH 310/614] Set URBAN_REGION_ID as it's required for urban datasets --- tools/mksurfdata_esmf/modify_1x1_urbanc_alpha.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/mksurfdata_esmf/modify_1x1_urbanc_alpha.cfg b/tools/mksurfdata_esmf/modify_1x1_urbanc_alpha.cfg index 01f77c40f0..09dffcbe66 100644 --- a/tools/mksurfdata_esmf/modify_1x1_urbanc_alpha.cfg +++ b/tools/mksurfdata_esmf/modify_1x1_urbanc_alpha.cfg @@ -94,6 +94,9 @@ PCT_LAKE = 0.0 # Add variables on the file and assign a new value # can't specify soil_color, max_sat_area or other things that are above. +# URBAN_REGION_ID MUST be set, when there is urban area +URBAN_REGION_ID = 2 + # Variables on numurbl which is 3 CANYON_HWR = 0.42 0.42 0.42 EM_IMPROAD = 0.973 0.973 0.973 From e71900e498fef657f16823238e35bac7c28f2bbb Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 25 Aug 2023 17:08:28 -0600 Subject: [PATCH 311/614] Use the corrected urbanc_alpha site that has URBAN_REGION_ID set, so tests with it now work --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 819b647bec..8d35df281b 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1181,7 +1181,7 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts_CMIP6_ /glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_mexicocityMEX_hist_78pfts_CMIP6_simyr2000_c230726.nc -/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_urbanc_alpha_hist_78pfts_CMIP6_simyr2000_c230726.nc +/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_urbanc_alpha_hist_78pfts_CMIP6_simyr2000_c230825.nc From 0c0ffe43e146eca112eb6b94ad0ed43175741976 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 25 Aug 2023 17:10:04 -0600 Subject: [PATCH 312/614] Remove variable that is not used as pointed out by pylint --- python/ctsm/modify_input_files/modify_fsurdat.py | 1 - 1 file changed, 1 deletion(-) diff --git a/python/ctsm/modify_input_files/modify_fsurdat.py b/python/ctsm/modify_input_files/modify_fsurdat.py index ae5dd3a527..ec2d35513a 100644 --- a/python/ctsm/modify_input_files/modify_fsurdat.py +++ b/python/ctsm/modify_input_files/modify_fsurdat.py @@ -396,7 +396,6 @@ def set_idealized(self): max_sat_area = 0 # max saturated area std_elev = 0 # standard deviation of elevation slope = 0 # mean topographic slope - pftdata_mask = 1 landfrac_pft = 1 # if pct_nat_veg had to be set to less than 100, then each special # landunit would have to receive a unique pct value rather than the From b33359cec68edf9ae61830059b86df9c90777c2d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 25 Aug 2023 17:10:37 -0600 Subject: [PATCH 313/614] Update more of the datasets to new ones --- python/ctsm/test/test_sys_mesh_modifier.py | 2 +- python/ctsm/test/test_unit_fsurdat_modifier.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ctsm/test/test_sys_mesh_modifier.py b/python/ctsm/test/test_sys_mesh_modifier.py index 0889a505ba..713def39cb 100755 --- a/python/ctsm/test/test_sys_mesh_modifier.py +++ b/python/ctsm/test/test_sys_mesh_modifier.py @@ -46,7 +46,7 @@ def setUp(self): testinputs_path = os.path.join(path_to_ctsm_root(), "python/ctsm/test/testinputs") fsurdat_in = os.path.join( testinputs_path, - "surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc", + "surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc", ) self._tempdir = tempfile.mkdtemp() self._cfg_file_path = os.path.join(self._tempdir, "modify_mesh_mask.cfg") diff --git a/python/ctsm/test/test_unit_fsurdat_modifier.py b/python/ctsm/test/test_unit_fsurdat_modifier.py index 0ea862a8e4..b76604f609 100755 --- a/python/ctsm/test/test_unit_fsurdat_modifier.py +++ b/python/ctsm/test/test_unit_fsurdat_modifier.py @@ -44,12 +44,12 @@ def setUp(self): self._testinputs_path = testinputs_path self._fsurdat_in = os.path.join( testinputs_path, - "surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc", + "surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc", ) self._tempdir = tempfile.mkdtemp() self._fsurdat_in = os.path.join( testinputs_path, - "surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc", + "surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc", ) self._fsurdat_out = os.path.join(self._tempdir, "fsurdat_out.nc") sys.argv = [ From dd27d4ffe522aec3bd258edbf2c5833d5f6d6d0f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 25 Aug 2023 17:39:50 -0600 Subject: [PATCH 314/614] Fix the unit tests, with updated expected filename --- python/ctsm/test/test_unit_subset_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ctsm/test/test_unit_subset_data.py b/python/ctsm/test/test_unit_subset_data.py index fd9aef631d..f116331436 100755 --- a/python/ctsm/test/test_unit_subset_data.py +++ b/python/ctsm/test/test_unit_subset_data.py @@ -46,7 +46,7 @@ def test_inputdata_setup_files_basic(self): files = setup_files(self.args, self.defaults, self.cesmroot) self.assertEqual( files["fsurf_in"], - "surfdata_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr2000_c190214.nc", + "surfdata_0.9x1.25_hist_16pfts_CMIP6_2000_c230517.nc", "fsurf_in filename not whats expected", ) self.assertEqual( From 4a7f6bf68f0d34dc767037e2956a2292788d7859 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 25 Aug 2023 17:49:22 -0600 Subject: [PATCH 315/614] Get the mesh test to work for mesh_modifier by replacing PFTDATA_MASK with LANDFRAC_PFT --- python/ctsm/test/test_sys_mesh_modifier.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ctsm/test/test_sys_mesh_modifier.py b/python/ctsm/test/test_sys_mesh_modifier.py index 713def39cb..55badcfa6c 100755 --- a/python/ctsm/test/test_sys_mesh_modifier.py +++ b/python/ctsm/test/test_sys_mesh_modifier.py @@ -96,8 +96,8 @@ def setUp(self): self._lon_dimname = fsurdat_in_data[self._lat_varname].dims[1] ncap2_cmd = ( - "ncap2 -A -v -s 'mod_lnd_props=PFTDATA_MASK' " - + "-A -v -s 'landmask=PFTDATA_MASK' " + "ncap2 -A -v -s 'mod_lnd_props=LANDFRAC_PFT' " + + "-A -v -s 'landmask=LANDFRAC_PFT' " + f"-A -v -s {self._lat_varname}={self._lat_varname} " + f"-A -v -s {self._lon_varname}={self._lon_varname} " + f"{fsurdat_in} {self._landmask_file}" From bb19750f7e5477fdaee8473ea53ebb18028de46f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 30 Aug 2023 19:52:50 -0600 Subject: [PATCH 316/614] Make it more clear what the issue is for issues with the config file for the checkvarlist, and increase the size of TK_ROOF in the config file to the now needed 10 --- python/ctsm/modify_input_files/fsurdat_modifier.py | 2 +- python/ctsm/modify_input_files/modify_fsurdat.py | 11 ++++++----- .../test/testinputs/modify_fsurdat_opt_sections.cfg | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/python/ctsm/modify_input_files/fsurdat_modifier.py b/python/ctsm/modify_input_files/fsurdat_modifier.py index 492fa74230..8ca7387381 100644 --- a/python/ctsm/modify_input_files/fsurdat_modifier.py +++ b/python/ctsm/modify_input_files/fsurdat_modifier.py @@ -601,7 +601,7 @@ def fsurdat_modifier(parser): if process_var_list: varlist = read_cfg_var_list(config, idealized=idealized) - update_list = modify_fsurdat.check_varlist(varlist, allow_uppercase_vars=True) + update_list = modify_fsurdat.check_varlist(varlist, allow_uppercase_vars=True, source="Config file: "+cfg_path) modify_fsurdat.set_varlist(update_list, cfg_path) logger.info("process_var_list is complete") else: diff --git a/python/ctsm/modify_input_files/modify_fsurdat.py b/python/ctsm/modify_input_files/modify_fsurdat.py index ec2d35513a..22dd31ef03 100644 --- a/python/ctsm/modify_input_files/modify_fsurdat.py +++ b/python/ctsm/modify_input_files/modify_fsurdat.py @@ -225,7 +225,7 @@ def set_dom_pft(self, dom_pft, lai, sai, hgt_top, hgt_bot): if val is not None: self.set_lai_sai_hgts(dom_pft=dom_pft, var=var, val=val) - def check_varlist(self, settings, allow_uppercase_vars=False): + def check_varlist(self, settings, allow_uppercase_vars=False, source="input settings dictionary"): """ Check a list of variables from a dictionary of settings """ @@ -236,10 +236,10 @@ def check_varlist(self, settings, allow_uppercase_vars=False): val = settings[varname] if not var in self.file: if not allow_uppercase_vars: - errmsg = "Error: Variable " + varname + " is NOT in the file" + errmsg = "Error: Variable " + varname + " is NOT in the " + source abort(errmsg) if not varname.upper() in self.file: - errmsg = "Error: Variable " + varname.upper() + " is NOT in the file" + errmsg = "Error: Variable " + varname.upper() + " is NOT in the " + source abort(errmsg) varname = varname.upper() @@ -250,7 +250,7 @@ def check_varlist(self, settings, allow_uppercase_vars=False): if len(self.file[varname].dims) == 2: if not isinstance(val, float): abort( - "For 2D vars, there should only be a single value for variable = " + varname + "For 2D vars, there should only be a single value for variable = " + varname + " in " + source ) elif len(self.file[varname].dims) >= 3: dim1 = int(self.file.sizes[self.file[varname].dims[0]]) @@ -261,10 +261,11 @@ def check_varlist(self, settings, allow_uppercase_vars=False): + str(dim1) + " for variable=" + varname + + " in " + source ) if len(val) != dim1: abort( - "Variable " + varname + " is of the wrong size. It should be = " + str(dim1) + "Variable " + varname + " is of the wrong size. It should be = " + str(dim1) + " in " + source ) return settings_return diff --git a/python/ctsm/test/testinputs/modify_fsurdat_opt_sections.cfg b/python/ctsm/test/testinputs/modify_fsurdat_opt_sections.cfg index c068c5d851..eddb4265fd 100644 --- a/python/ctsm/test/testinputs/modify_fsurdat_opt_sections.cfg +++ b/python/ctsm/test/testinputs/modify_fsurdat_opt_sections.cfg @@ -48,4 +48,4 @@ CANYON_HWR = 200.00 150.0 100. HT_ROOF = 200.0 150.0 100. T_BUILDING_MIN = 200 150.0 100. ALB_ROOF_DIR = 200. 100. -TK_ROOF = 1. 2. 3. 4. 5. +TK_ROOF = 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. From f1174886a95435fdd4c7fbec8724d0b4f2a9aa42 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 30 Aug 2023 19:54:13 -0600 Subject: [PATCH 317/614] Update the test files, and remove the previous ones --- ...surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc | 3 --- ...5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_modified.nc | 3 --- ..._16pfts_Irrig_CMIP6_simyr2000_c171214_modified_with_crop.nc | 3 --- .../surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc | 3 +++ ...fdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modified.nc | 3 +++ ...amazon_hist_78pfts_CMIP6_2000_c230517_modified_with_crop.nc | 3 +++ 6 files changed, 9 insertions(+), 9 deletions(-) delete mode 100644 python/ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc delete mode 100644 python/ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_modified.nc delete mode 100644 python/ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_modified_with_crop.nc create mode 100644 python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc create mode 100644 python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modified.nc create mode 100644 python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modified_with_crop.nc diff --git a/python/ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc b/python/ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc deleted file mode 100644 index 56e5ed5fdd..0000000000 --- a/python/ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2b23addc0a7bdafaa5fc83368aa0939da02d2ad7a51e71cd5b4b78a3d440b2a5 -size 245144 diff --git a/python/ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_modified.nc b/python/ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_modified.nc deleted file mode 100644 index bb0a52a83f..0000000000 --- a/python/ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_modified.nc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c05cb73bc232aa250bd9d752da986b58fee93ca1bb881a092d92b7e1752dd26f -size 247976 diff --git a/python/ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_modified_with_crop.nc b/python/ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_modified_with_crop.nc deleted file mode 100644 index 69f28b2239..0000000000 --- a/python/ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_modified_with_crop.nc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0217926e5dea2f563a01ad7149be68cf6d0acb0a140715a5402fdf39a925b3e7 -size 247880 diff --git a/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc new file mode 100644 index 0000000000..f0b82db8c5 --- /dev/null +++ b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3bd17959d5d72a5a7adcafc8e5ee3e5fb936f1a30cacbdbb0a1b02e1ffc5878 +size 893312 diff --git a/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modified.nc b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modified.nc new file mode 100644 index 0000000000..f9746052a2 --- /dev/null +++ b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modified.nc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3552caef9d6ea97d61f5ce765cfe9ab30f2d58d5fee4314b71f88f8c03fd1295 +size 891524 diff --git a/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modified_with_crop.nc b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modified_with_crop.nc new file mode 100644 index 0000000000..b3e1860bc7 --- /dev/null +++ b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modified_with_crop.nc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:93b0b528ef608b6762f3ee0e8b37d961adf2d83e91cf8552c9310bf5ef8e1743 +size 891444 From c7b7ca1d94ac19abb9ecea9fb5b712ddbdd6645d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 30 Aug 2023 22:56:35 -0600 Subject: [PATCH 318/614] Run through black --- .../modify_input_files/fsurdat_modifier.py | 4 +++- .../ctsm/modify_input_files/modify_fsurdat.py | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/python/ctsm/modify_input_files/fsurdat_modifier.py b/python/ctsm/modify_input_files/fsurdat_modifier.py index 8ca7387381..01b7f3f517 100644 --- a/python/ctsm/modify_input_files/fsurdat_modifier.py +++ b/python/ctsm/modify_input_files/fsurdat_modifier.py @@ -601,7 +601,9 @@ def fsurdat_modifier(parser): if process_var_list: varlist = read_cfg_var_list(config, idealized=idealized) - update_list = modify_fsurdat.check_varlist(varlist, allow_uppercase_vars=True, source="Config file: "+cfg_path) + update_list = modify_fsurdat.check_varlist( + varlist, allow_uppercase_vars=True, source="Config file: " + cfg_path + ) modify_fsurdat.set_varlist(update_list, cfg_path) logger.info("process_var_list is complete") else: diff --git a/python/ctsm/modify_input_files/modify_fsurdat.py b/python/ctsm/modify_input_files/modify_fsurdat.py index 22dd31ef03..7ea6cf3873 100644 --- a/python/ctsm/modify_input_files/modify_fsurdat.py +++ b/python/ctsm/modify_input_files/modify_fsurdat.py @@ -225,7 +225,9 @@ def set_dom_pft(self, dom_pft, lai, sai, hgt_top, hgt_bot): if val is not None: self.set_lai_sai_hgts(dom_pft=dom_pft, var=var, val=val) - def check_varlist(self, settings, allow_uppercase_vars=False, source="input settings dictionary"): + def check_varlist( + self, settings, allow_uppercase_vars=False, source="input settings dictionary" + ): """ Check a list of variables from a dictionary of settings """ @@ -250,7 +252,10 @@ def check_varlist(self, settings, allow_uppercase_vars=False, source="input sett if len(self.file[varname].dims) == 2: if not isinstance(val, float): abort( - "For 2D vars, there should only be a single value for variable = " + varname + " in " + source + "For 2D vars, there should only be a single value for variable = " + + varname + + " in " + + source ) elif len(self.file[varname].dims) >= 3: dim1 = int(self.file.sizes[self.file[varname].dims[0]]) @@ -261,11 +266,17 @@ def check_varlist(self, settings, allow_uppercase_vars=False, source="input sett + str(dim1) + " for variable=" + varname - + " in " + source + + " in " + + source ) if len(val) != dim1: abort( - "Variable " + varname + " is of the wrong size. It should be = " + str(dim1) + " in " + source + "Variable " + + varname + + " is of the wrong size. It should be = " + + str(dim1) + + " in " + + source ) return settings_return From 75c7f236907bcc9e4dce4ec79ab3698d64312e84 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 30 Aug 2023 22:58:17 -0600 Subject: [PATCH 319/614] Add black commit to ignore file for git blame --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index a3795e4c6b..302ce050e5 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -7,3 +7,4 @@ e44dc469439e02e9ee582dab274d890ebdfab104 b88e1cd1b28e3609684c79a2ec0e88f26cfc362b 51c102c5df2e0ef971b5f8eeeb477567899af63a 7dacad70e74e2ec97f6492d4e7a3cb5dd498bcd7 +c7b7ca1d94ac19abb9ecea9fb5b712ddbdd6645d From 9035bdd07e8928f1ee5d2392496d61c7fcfef3d0 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 31 Aug 2023 15:13:07 -0600 Subject: [PATCH 320/614] Fix the unit tests with the updated missing variable error --- python/ctsm/test/test_unit_modify_fsurdat.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ctsm/test/test_unit_modify_fsurdat.py b/python/ctsm/test/test_unit_modify_fsurdat.py index a075035b73..2e7dc61905 100755 --- a/python/ctsm/test/test_unit_modify_fsurdat.py +++ b/python/ctsm/test/test_unit_modify_fsurdat.py @@ -426,13 +426,13 @@ def test_check_varlist_uppercase(self): def test_check_varlist_badvar(self): """Test the check_varlist method for a variable not on the file""" settings = {"badvar": 100.0} - with self.assertRaisesRegex(SystemExit, "Variable badvar is NOT in the file"): + with self.assertRaisesRegex(SystemExit, "Variable badvar is NOT in the input settings dictionary"): self.modify_fsurdat.check_varlist(settings) def test_check_varlist_badvar_uppercase(self): """Test the check_varlist method for a variable not on the file with allow uppercase""" settings = {"badvar": 100.0} - with self.assertRaisesRegex(SystemExit, "Variable BADVAR is NOT in the file"): + with self.assertRaisesRegex(SystemExit, "Variable BADVAR is NOT in the input settings dictionary"): self.modify_fsurdat.check_varlist(settings, allow_uppercase_vars=True) def test_set_varlist_toohighdim(self): From f6b0cb028d83e203b8225a3e8d92f2b51aed51f0 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 31 Aug 2023 15:15:51 -0600 Subject: [PATCH 321/614] Run black --- python/ctsm/test/test_unit_modify_fsurdat.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/python/ctsm/test/test_unit_modify_fsurdat.py b/python/ctsm/test/test_unit_modify_fsurdat.py index 2e7dc61905..4d8cf719bb 100755 --- a/python/ctsm/test/test_unit_modify_fsurdat.py +++ b/python/ctsm/test/test_unit_modify_fsurdat.py @@ -426,13 +426,17 @@ def test_check_varlist_uppercase(self): def test_check_varlist_badvar(self): """Test the check_varlist method for a variable not on the file""" settings = {"badvar": 100.0} - with self.assertRaisesRegex(SystemExit, "Variable badvar is NOT in the input settings dictionary"): + with self.assertRaisesRegex( + SystemExit, "Variable badvar is NOT in the input settings dictionary" + ): self.modify_fsurdat.check_varlist(settings) def test_check_varlist_badvar_uppercase(self): """Test the check_varlist method for a variable not on the file with allow uppercase""" settings = {"badvar": 100.0} - with self.assertRaisesRegex(SystemExit, "Variable BADVAR is NOT in the input settings dictionary"): + with self.assertRaisesRegex( + SystemExit, "Variable BADVAR is NOT in the input settings dictionary" + ): self.modify_fsurdat.check_varlist(settings, allow_uppercase_vars=True) def test_set_varlist_toohighdim(self): From 7c067a4ffe8bb35104ef9d521edb7da9e2c3ba09 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 1 Sep 2023 14:10:29 -0600 Subject: [PATCH 322/614] Get all python tests working, increase size for TK_ROOF, and convert mask used for the mesh sys test to integer in ncap2 so that it will work --- python/ctsm/test/test_sys_fsurdat_modifier.py | 6 +++++- python/ctsm/test/test_sys_mesh_modifier.py | 8 +++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/python/ctsm/test/test_sys_fsurdat_modifier.py b/python/ctsm/test/test_sys_fsurdat_modifier.py index 23eefb57d4..7697e8bad6 100755 --- a/python/ctsm/test/test_sys_fsurdat_modifier.py +++ b/python/ctsm/test/test_sys_fsurdat_modifier.py @@ -186,6 +186,10 @@ def test_opt_sections(self): lev2_five[2, :, :, :] = 3.0 lev2_five[3, :, :, :] = 4.0 lev2_five[4, :, :, :] = 5.0 + lev2_ten = np.empty((10, 3, 5, 5)) + for l in range(10): + lev2_ten[l, :, :, :] = float(l + 1) + lev1 = np.array( [ [ @@ -221,7 +225,7 @@ def test_opt_sections(self): np.testing.assert_array_equal(fsurdat_out_data.LAKEDEPTH, one0d * 200.0) np.testing.assert_array_equal(fsurdat_out_data.T_BUILDING_MIN, lev1) np.testing.assert_array_equal(fsurdat_out_data.ALB_ROOF_DIR, lev2_two) - np.testing.assert_array_equal(fsurdat_out_data.TK_ROOF, lev2_five) + np.testing.assert_array_equal(fsurdat_out_data.TK_ROOF, lev2_ten) def test_1x1_mexicocity(self): """ diff --git a/python/ctsm/test/test_sys_mesh_modifier.py b/python/ctsm/test/test_sys_mesh_modifier.py index 55badcfa6c..138dba948e 100755 --- a/python/ctsm/test/test_sys_mesh_modifier.py +++ b/python/ctsm/test/test_sys_mesh_modifier.py @@ -96,8 +96,8 @@ def setUp(self): self._lon_dimname = fsurdat_in_data[self._lat_varname].dims[1] ncap2_cmd = ( - "ncap2 -A -v -s 'mod_lnd_props=LANDFRAC_PFT' " - + "-A -v -s 'landmask=LANDFRAC_PFT' " + "ncap2 -A -v -s 'mod_lnd_props=LANDFRAC_PFT.convert(NC_INT)' " + + "-A -v -s 'landmask=LANDFRAC_PFT.convert(NC_INT)' " + f"-A -v -s {self._lat_varname}={self._lat_varname} " + f"-A -v -s {self._lon_varname}={self._lon_varname} " + f"{fsurdat_in} {self._landmask_file}" @@ -137,7 +137,9 @@ def test_allInfo(self): # the Mask variable will now equal zeros, not ones element_mask_in = mesh_mask_in_data.elementMask element_mask_out = mesh_mask_out_data.elementMask - self.assertTrue(element_mask_out.equals(element_mask_in - 1)) + self.assertTrue( + element_mask_out.equals(element_mask_in - 1) + ) # The -1 is because of the comment above about the mask def _create_config_file(self): """ From 6ad4fe47d243b1f02371c2d6e7c1ea9884a50a01 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 1 Sep 2023 18:46:55 -0600 Subject: [PATCH 323/614] Only allow the masks to be integer 0 or 1 --- python/ctsm/modify_input_files/modify_mesh_mask.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/python/ctsm/modify_input_files/modify_mesh_mask.py b/python/ctsm/modify_input_files/modify_mesh_mask.py index a0dccedeb2..5c7e418ef7 100644 --- a/python/ctsm/modify_input_files/modify_mesh_mask.py +++ b/python/ctsm/modify_input_files/modify_mesh_mask.py @@ -101,16 +101,12 @@ def set_mesh_mask(self, var): "landmask not 0 or 1 at row, col, value = " + f"{row} {col} {landmask[row, col]}" ) - assert isclose(landmask[row, col], 0, abs_tol=1e-9) or isclose( - landmask[row, col], 1, abs_tol=1e-9 - ), errmsg + assert landmask[row, col] == 0 or landmask[row, col] == 1, errmsg errmsg = ( "mod_lnd_props not 0 or 1 at row, col, value = " + f"{row} {col} {mod_lnd_props[row, col]}" ) - assert isclose(mod_lnd_props[row, col], 0, abs_tol=1e-9) or isclose( - mod_lnd_props[row, col], 1, abs_tol=1e-9 - ), errmsg + assert mod_lnd_props[row, col] == 0 or mod_lnd_props[row, col] == 1, errmsg if int(mod_lnd_props[row, col]) == 1: errmsg = ( "landmask should = mod_lnd_props where the " From 22e8ecc65cda42eff376b3c60b7b1834b05c140a Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 5 Sep 2023 15:55:42 -0600 Subject: [PATCH 324/614] Add a test for mesh modifier that has a more complex mesh pattern, this failes at line 181 --- python/ctsm/test/test_sys_mesh_modifier.py | 56 ++++++++++++++++++---- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/python/ctsm/test/test_sys_mesh_modifier.py b/python/ctsm/test/test_sys_mesh_modifier.py index 138dba948e..935c1dfef5 100755 --- a/python/ctsm/test/test_sys_mesh_modifier.py +++ b/python/ctsm/test/test_sys_mesh_modifier.py @@ -43,9 +43,9 @@ def setUp(self): self._cfg_template_path = os.path.join( path_to_ctsm_root(), "tools/modify_input_files/modify_mesh_template.cfg" ) - testinputs_path = os.path.join(path_to_ctsm_root(), "python/ctsm/test/testinputs") - fsurdat_in = os.path.join( - testinputs_path, + self.testinputs_path = os.path.join(path_to_ctsm_root(), "python/ctsm/test/testinputs") + self.fsurdat_in = os.path.join( + self.testinputs_path, "surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc", ) self._tempdir = tempfile.mkdtemp() @@ -69,13 +69,13 @@ def setUp(self): # Generate scrip file from fsurdat_in using nco # In the ctsm_py environment this requires running 'module load nco' # interactively - ncks_cmd = f"ncks --rgr infer --rgr scrip={scrip_file} {fsurdat_in} {metadata_file}" + ncks_cmd = f"ncks --rgr infer --rgr scrip={scrip_file} {self.fsurdat_in} {metadata_file}" try: subprocess.check_call(ncks_cmd, shell=True) except subprocess.CalledProcessError as e: err_msg = ( f"{e} ERROR using ncks to generate {scrip_file} from " - + f"{fsurdat_in}; MOST LIKELY SHOULD INVOKE module load nco" + + f"{self.fsurdat_in}; MOST LIKELY SHOULD INVOKE module load nco" ) sys.exit(err_msg) # Run .env_mach_specific.sh to load esmf and generate mesh_mask_in @@ -89,23 +89,28 @@ def setUp(self): # Generate landmask_file from fsurdat_in self._lat_varname = "LATIXY" # same as in fsurdat_in self._lon_varname = "LONGXY" # same as in fsurdat_in - fsurdat_in_data = xr.open_dataset(fsurdat_in) + fsurdat_in_data = xr.open_dataset(self.fsurdat_in) assert self._lat_varname in fsurdat_in_data.variables assert self._lon_varname in fsurdat_in_data.variables self._lat_dimname = fsurdat_in_data[self._lat_varname].dims[0] self._lon_dimname = fsurdat_in_data[self._lat_varname].dims[1] + self.createLandMaskFile() + def createLandMaskFile(self): + """ Create the LandMask file from the input fsurdat_in file""" + if os.path.exists(self._landmask_file): + os.remove(self._landmask_file) ncap2_cmd = ( "ncap2 -A -v -s 'mod_lnd_props=LANDFRAC_PFT.convert(NC_INT)' " + "-A -v -s 'landmask=LANDFRAC_PFT.convert(NC_INT)' " + f"-A -v -s {self._lat_varname}={self._lat_varname} " + f"-A -v -s {self._lon_varname}={self._lon_varname} " - + f"{fsurdat_in} {self._landmask_file}" + + f"{self.fsurdat_in} {self._landmask_file}" ) try: subprocess.check_call(ncap2_cmd, shell=True) except subprocess.CalledProcessError as e: - sys.exit(f"{e} ERROR using ncap2 to generate {self._landmask_file} from {fsurdat_in}") + sys.exit(f"{e} ERROR using ncap2 to generate {self._landmask_file} from {self.fsurdat_in}") def tearDown(self): """ @@ -118,6 +123,8 @@ def test_allInfo(self): """ This test specifies all the information that one may specify Create .cfg file, run the tool, compare mesh_mask_in to mesh_mask_out + For a case where the mesh remains unchanged, it's just output as + ocean so the mesh is output as all zero's rather than the all 1's that came in. """ self._create_config_file() @@ -141,6 +148,39 @@ def test_allInfo(self): element_mask_out.equals(element_mask_in - 1) ) # The -1 is because of the comment above about the mask + def test_modifyMesh(self): + """ + This test specifies all the information that one may specify + Create .cfg file, run the tool, compare mesh_mask_in to mesh_mask_out + For a case where the mesh is changed. + """ + + self.fsurdat_in = os.path.join( + self.testinputs_path, + "surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modify_mask.nc", + ) + self.createLandMaskFile() + self._create_config_file() + + # run the mesh_mask_modifier tool + mesh_mask_modifier(self._cfg_file_path) + # the critical piece of this test is that the above command + # doesn't generate errors; however, we also do some assertions below + + # Error checks + mesh_mask_in_data = xr.open_dataset(self._mesh_mask_in) + mesh_mask_out_data = xr.open_dataset(self._mesh_mask_out) + + center_coords_in = mesh_mask_in_data.centerCoords + center_coords_out = mesh_mask_out_data.centerCoords + self.assertTrue(center_coords_out.equals(center_coords_in)) + # the Mask variable will now equal zeros, not ones + element_mask_in = mesh_mask_in_data.elementMask + element_mask_out = mesh_mask_out_data.elementMask + self.assertTrue( + element_mask_out.equals(element_mask_in - 1) + ) # The -1 is because of the comment above about the mask + def _create_config_file(self): """ Open the new and the template .cfg files From 49fabff88343539edb35173dea66e0344ead0dd5 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 5 Sep 2023 16:00:07 -0600 Subject: [PATCH 325/614] Add a modified mesh with a recognizable X pattern in LANDMASK_PFT --- ...ta_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modify_mask.nc | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modify_mask.nc diff --git a/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modify_mask.nc b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modify_mask.nc new file mode 100644 index 0000000000..4e1ca411ab --- /dev/null +++ b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modify_mask.nc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb94fa214fcf08fbf075c45864ab059f052f8cf618f32049b13301318987b26f +size 893312 From b565b55ce7a9f8d812a573d716a5fd3d78cfea81 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 5 Sep 2023 16:00:25 -0600 Subject: [PATCH 326/614] Run in black --- python/ctsm/test/test_sys_mesh_modifier.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/python/ctsm/test/test_sys_mesh_modifier.py b/python/ctsm/test/test_sys_mesh_modifier.py index 935c1dfef5..1241ca7daf 100755 --- a/python/ctsm/test/test_sys_mesh_modifier.py +++ b/python/ctsm/test/test_sys_mesh_modifier.py @@ -97,9 +97,9 @@ def setUp(self): self.createLandMaskFile() def createLandMaskFile(self): - """ Create the LandMask file from the input fsurdat_in file""" + """Create the LandMask file from the input fsurdat_in file""" if os.path.exists(self._landmask_file): - os.remove(self._landmask_file) + os.remove(self._landmask_file) ncap2_cmd = ( "ncap2 -A -v -s 'mod_lnd_props=LANDFRAC_PFT.convert(NC_INT)' " + "-A -v -s 'landmask=LANDFRAC_PFT.convert(NC_INT)' " @@ -110,7 +110,9 @@ def createLandMaskFile(self): try: subprocess.check_call(ncap2_cmd, shell=True) except subprocess.CalledProcessError as e: - sys.exit(f"{e} ERROR using ncap2 to generate {self._landmask_file} from {self.fsurdat_in}") + sys.exit( + f"{e} ERROR using ncap2 to generate {self._landmask_file} from {self.fsurdat_in}" + ) def tearDown(self): """ From 725ddfc5d1676727efef0a56e58f74dc9cfa21fe Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 5 Sep 2023 16:01:35 -0600 Subject: [PATCH 327/614] Update git-blame --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 302ce050e5..d0a83de93d 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -8,3 +8,4 @@ b88e1cd1b28e3609684c79a2ec0e88f26cfc362b 51c102c5df2e0ef971b5f8eeeb477567899af63a 7dacad70e74e2ec97f6492d4e7a3cb5dd498bcd7 c7b7ca1d94ac19abb9ecea9fb5b712ddbdd6645d +b565b55ce7a9f8d812a573d716a5fd3d78cfea81 From 3f61bd0ffba8171a753c287ff1917d0c37a8a8a9 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 11 Sep 2023 16:17:23 -0600 Subject: [PATCH 328/614] A litle rearranging so that the new test can work, and also add a mesh file to compare to, that can be seen that it looks like it's expected to for the fsurdat landmask. A question now is why the identity test needs to subtract 1, when the new test doesn't --- python/ctsm/test/test_sys_mesh_modifier.py | 60 ++++++++++++++----- ...t_amazon-modify_mask_ESMFmesh_c20230911.nc | 3 + ...t_78pfts_CMIP6_2000_c230517_modify_mask.nc | 2 +- 3 files changed, 50 insertions(+), 15 deletions(-) create mode 100644 python/ctsm/test/testinputs/5x5pt_amazon-modify_mask_ESMFmesh_c20230911.nc diff --git a/python/ctsm/test/test_sys_mesh_modifier.py b/python/ctsm/test/test_sys_mesh_modifier.py index 1241ca7daf..4c95dc5ab4 100755 --- a/python/ctsm/test/test_sys_mesh_modifier.py +++ b/python/ctsm/test/test_sys_mesh_modifier.py @@ -44,19 +44,21 @@ def setUp(self): path_to_ctsm_root(), "tools/modify_input_files/modify_mesh_template.cfg" ) self.testinputs_path = os.path.join(path_to_ctsm_root(), "python/ctsm/test/testinputs") - self.fsurdat_in = os.path.join( - self.testinputs_path, - "surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc", - ) + self.fsurdat_in = None self._tempdir = tempfile.mkdtemp() self._cfg_file_path = os.path.join(self._tempdir, "modify_mesh_mask.cfg") self._mesh_mask_in = os.path.join(self._tempdir, "mesh_mask_in.nc") self._mesh_mask_out = os.path.join(self._tempdir, "mesh_mask_out.nc") self._landmask_file = os.path.join(self._tempdir, "landmask.nc") - scrip_file = os.path.join(self._tempdir, "scrip.nc") - metadata_file = os.path.join(self._tempdir, "metadata.nc") + self.scrip_file = os.path.join(self._tempdir, "scrip.nc") + self.metadata_file = os.path.join(self._tempdir, "metadata.nc") configure_path = os.path.join(path_to_cime(), "CIME/scripts/configure") + self._lat_varname = None + self._lon_varname = None + self._lat_dimname = None + self._lon_dimname = None + os.chdir(self._tempdir) # cd to tempdir # Run configure to generate .env_mach_specific.sh @@ -66,21 +68,35 @@ def setUp(self): except subprocess.CalledProcessError as e: sys.exit(f"{e} ERROR using {configure_cmd}") + def createScripGridAndMask(self): + """Create the SCRIP gird and mask file""" # Generate scrip file from fsurdat_in using nco # In the ctsm_py environment this requires running 'module load nco' # interactively - ncks_cmd = f"ncks --rgr infer --rgr scrip={scrip_file} {self.fsurdat_in} {metadata_file}" + if os.path.exists(self.scrip_file): + os.remove(self.scrip_file) + # --rgr infer, means create the vertices bases on the cell centers (--rgr is the regrid options for ncks) + # --rgr scrip=, names the output SCRIP grid file + # The mask will be idnetically 1, no matter the input grid (you can, change it, but you have to get it from a mapping file) + # Since, the mask is going to be changed later, it's fine that the mask at this point is identically 1. + + # This could also alturnatively be done, by using the stored SCRIP grid file for the resolution under CESM inputdata + ncks_cmd = ( + f"ncks --rgr infer --rgr scrip={self.scrip_file} {self.fsurdat_in} {self.metadata_file}" + ) try: subprocess.check_call(ncks_cmd, shell=True) except subprocess.CalledProcessError as e: err_msg = ( - f"{e} ERROR using ncks to generate {scrip_file} from " + f"{e} ERROR using ncks to generate {self.scrip_file} from " + f"{self.fsurdat_in}; MOST LIKELY SHOULD INVOKE module load nco" ) sys.exit(err_msg) # Run .env_mach_specific.sh to load esmf and generate mesh_mask_in # Execute two commands at once to preserve the results of the first - two_commands = f". {self._tempdir}/.env_mach_specific.sh; ESMF_Scrip2Unstruct {scrip_file} {self._mesh_mask_in} 0" + if os.path.exists(self._mesh_mask_in): + os.remove(self._mesh_mask_in) + two_commands = f". {self._tempdir}/.env_mach_specific.sh; ESMF_Scrip2Unstruct {self.scrip_file} {self._mesh_mask_in} 0" try: subprocess.check_call(two_commands, shell=True) except subprocess.CalledProcessError as e: @@ -94,7 +110,6 @@ def setUp(self): assert self._lon_varname in fsurdat_in_data.variables self._lat_dimname = fsurdat_in_data[self._lat_varname].dims[0] self._lon_dimname = fsurdat_in_data[self._lat_varname].dims[1] - self.createLandMaskFile() def createLandMaskFile(self): """Create the LandMask file from the input fsurdat_in file""" @@ -128,15 +143,24 @@ def test_allInfo(self): For a case where the mesh remains unchanged, it's just output as ocean so the mesh is output as all zero's rather than the all 1's that came in. """ + self.fsurdat_in = os.path.join( + self.testinputs_path, + "surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc", + ) + self.createScripGridAndMask() + self.createLandMaskFile() self._create_config_file() # run the mesh_mask_modifier tool + if os.path.exists(self._mesh_mask_out): + os.remove(self._mesh_mask_out) mesh_mask_modifier(self._cfg_file_path) # the critical piece of this test is that the above command # doesn't generate errors; however, we also do some assertions below # Error checks + # Use the mesh file that was created with to compare to with a mask identical to 1 mesh_mask_in_data = xr.open_dataset(self._mesh_mask_in) mesh_mask_out_data = xr.open_dataset(self._mesh_mask_out) @@ -161,16 +185,26 @@ def test_modifyMesh(self): self.testinputs_path, "surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modify_mask.nc", ) + print(self.fsurdat_in) + self.createScripGridAndMask() self.createLandMaskFile() self._create_config_file() + if os.path.exists(self._mesh_mask_out): + os.remove(self._mesh_mask_out) + # run the mesh_mask_modifier tool mesh_mask_modifier(self._cfg_file_path) # the critical piece of this test is that the above command # doesn't generate errors; however, we also do some assertions below + mesh_compare = os.path.join( + self.testinputs_path, "5x5pt_amazon-modify_mask_ESMFmesh_c20230911.nc" + ) # Error checks - mesh_mask_in_data = xr.open_dataset(self._mesh_mask_in) + print(mesh_compare) + print(self._mesh_mask_out) + mesh_mask_in_data = xr.open_dataset(mesh_compare) mesh_mask_out_data = xr.open_dataset(self._mesh_mask_out) center_coords_in = mesh_mask_in_data.centerCoords @@ -179,9 +213,7 @@ def test_modifyMesh(self): # the Mask variable will now equal zeros, not ones element_mask_in = mesh_mask_in_data.elementMask element_mask_out = mesh_mask_out_data.elementMask - self.assertTrue( - element_mask_out.equals(element_mask_in - 1) - ) # The -1 is because of the comment above about the mask + self.assertTrue(element_mask_out.equals(element_mask_in)) def _create_config_file(self): """ diff --git a/python/ctsm/test/testinputs/5x5pt_amazon-modify_mask_ESMFmesh_c20230911.nc b/python/ctsm/test/testinputs/5x5pt_amazon-modify_mask_ESMFmesh_c20230911.nc new file mode 100644 index 0000000000..67bb069848 --- /dev/null +++ b/python/ctsm/test/testinputs/5x5pt_amazon-modify_mask_ESMFmesh_c20230911.nc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2909296cb8fc663974cb66f7a2101ab2ef9c98b72f180e4f4de030487f80f4ee +size 3236 diff --git a/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modify_mask.nc b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modify_mask.nc index 4e1ca411ab..c07424cf50 100644 --- a/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modify_mask.nc +++ b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modify_mask.nc @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fb94fa214fcf08fbf075c45864ab059f052f8cf618f32049b13301318987b26f +oid sha256:544478d315d2e994fc7b301aeb1b4825ebb6c60f2ef198c2d9c2cb13707f1d34 size 893312 From 32a99e06a9e14a7ffaf60a2fcc3bf1d90548dae4 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 11 Sep 2023 18:13:19 -0600 Subject: [PATCH 329/614] Remove print statements in test, add a note that the new test has identical mask rather than -1, because the file already had the -1 taken out --- python/ctsm/test/test_sys_mesh_modifier.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/python/ctsm/test/test_sys_mesh_modifier.py b/python/ctsm/test/test_sys_mesh_modifier.py index 4c95dc5ab4..7fad92e1d7 100755 --- a/python/ctsm/test/test_sys_mesh_modifier.py +++ b/python/ctsm/test/test_sys_mesh_modifier.py @@ -185,7 +185,6 @@ def test_modifyMesh(self): self.testinputs_path, "surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modify_mask.nc", ) - print(self.fsurdat_in) self.createScripGridAndMask() self.createLandMaskFile() self._create_config_file() @@ -202,15 +201,13 @@ def test_modifyMesh(self): ) # Error checks - print(mesh_compare) - print(self._mesh_mask_out) mesh_mask_in_data = xr.open_dataset(mesh_compare) mesh_mask_out_data = xr.open_dataset(self._mesh_mask_out) center_coords_in = mesh_mask_in_data.centerCoords center_coords_out = mesh_mask_out_data.centerCoords self.assertTrue(center_coords_out.equals(center_coords_in)) - # the Mask variable will now equal zeros, not ones + # the Mask variable will now equal the comparision file element_mask_in = mesh_mask_in_data.elementMask element_mask_out = mesh_mask_out_data.elementMask self.assertTrue(element_mask_out.equals(element_mask_in)) From 663d707297bbd74b67d522c35945fe7ae5197520 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 15 Sep 2023 12:35:25 -0600 Subject: [PATCH 330/614] Add pctocn to fsurdat files made by mksurfdata_esmf --- tools/mksurfdata_esmf/README | 4 +-- tools/mksurfdata_esmf/src/mkfileMod.F90 | 3 ++ tools/mksurfdata_esmf/src/mksurfdata.F90 | 35 +++++++++++++++++------- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 55ce09dd61..4be45e83d1 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -69,10 +69,10 @@ Building the executable (working in tools/mksurfdata_esmf) ======================= Running for a single submission: ======================= -# Work in the ctsm_py environment, which requires the following steps: +# Work in the ctsm_pylib environment, which requires the following steps: > module unload python; module load conda > cd ../..; ./py_env_create -> conda activate ctsm_py; cd tools/mksurfdata_esmf +> conda activate ctsm_pylib; cd tools/mksurfdata_esmf # to generate your target namelist: > ./gen_mksurfdata_namelist.py --help # for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 335a9a508b..1072c4710b 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -456,6 +456,9 @@ subroutine mkfile_define_vars(pioid, dynlanduse) end if + call mkpio_def_spatial_var(pioid=pioid, varname='PCT_OCEAN', xtype=xtype, & + long_name='percent ocean', units='unitless') + call mkpio_def_spatial_var(pioid=pioid, varname='LAKEDEPTH', xtype=xtype, & long_name='lake depth', units='m') diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index ace3999f0f..6a7f3d168f 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -162,6 +162,7 @@ program mksurfdata real(r8), allocatable :: pctlak(:) ! percent of grid cell that is lake real(r8), allocatable :: pctlak_max(:) ! maximum percent of grid cell that is lake real(r8), allocatable :: pctwet(:) ! percent of grid cell that is wetland + real(r8), allocatable :: pctocn(:) ! percent of grid cell that is ocean real(r8), allocatable :: pctgla(:) ! percent of grid cell that is glacier integer , allocatable :: urban_region(:) ! urban region ID real(r8), allocatable :: pcturb(:) ! percent of grid cell that is urbanized (total across all urban classes) @@ -429,6 +430,12 @@ program mksurfdata call mkwetlnd(mksrf_fwetlnd_mesh, mksrf_fwetlnd, mesh_model, pctwet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkwetlnd') + ! Initialize pctocn to zero. + ! Traditionally we have set pctwet = 100 at ocean points rather than + ! setting a pctocn. We now set pctocn = 100 at ocean points in + ! subroutine normalize_and_check_landuse. No regridding required. + allocate ( pctocn(lsize_o)); pctocn(:) = 0._r8 + ! ----------------------------------- ! Make glacier fraction [pctgla] from [fglacier] dataset ! ----------------------------------- @@ -648,6 +655,10 @@ program mksurfdata call mkfile_output(pioid, mesh_model, 'PCT_WETLAND', pctwet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in in mkfile_output for pctwet') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing out PCT_OCEAN" + call mkfile_output(pioid, mesh_model, 'PCT_OCEAN', pctocn, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in in mkfile_output for pctocn') + if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_NATVEG" call get_pct_l2g_array(pctnatpft, pctnatveg) call mkfile_output(pioid, mesh_model, 'PCT_NATVEG', pctnatveg, rc=rc) @@ -1171,7 +1182,7 @@ subroutine normalize_and_check_landuse(ns_o) if (pct_land < 1.e-6_r8) then ! If we have essentially 0 land area, set land area to exactly 0 and put all - ! area in wetlands (to simulate ocean). Note that, based on the formulation + ! area in pctocn. Note that, based on the formulation ! for pct_land above, this should only arise if the non-natveg landunits ! already have near-zero area (and the natveg landunit should also have ! near-zero area in this case, because its area should be no greater than the @@ -1184,7 +1195,8 @@ subroutine normalize_and_check_landuse(ns_o) pctlak(n) = 0._r8 pcturb(n) = 0._r8 pctgla(n) = 0._r8 - pctwet(n) = 100._r8 + pctwet(n) = 0._r8 + pctocn(n) = 100._r8 ! the only asignment of non-zero ocean else ! Fill the rest of the land area with natveg, then renormalize landunits so ! that they are expressed as percent of the land area rather than percent of @@ -1222,12 +1234,12 @@ subroutine normalize_and_check_landuse(ns_o) ! Confirm that we have done the rescaling correctly: now the sum of all landunits ! should be 100% within tol_loose suma = pctlak(n) + pctwet(n) + pctgla(n) + pcturb(n) + pctcft(n)%get_pct_l2g() - suma = suma + pctnatpft(n)%get_pct_l2g() + suma = suma + pctnatpft(n)%get_pct_l2g() + pctocn(n) if (abs(suma - 100._r8) > tol_loose) then write(6,*) subname, ' ERROR: landunits do not sum to 100%' - write(6,*) 'n, suma, pctlak, pctwet, pctgla, pcturb, pctnatveg, pctcrop = ' + write(6,*) 'n, suma, pctlak, pctwet, pctgla, pcturb, pctnatveg, pctcrop, pctocn = ' write(6,*) n, suma, pctlak(n), pctwet(n), pctgla(n), pcturb(n), & - pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() + pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g(), pctocn(n) call shr_sys_abort() end if @@ -1248,7 +1260,10 @@ subroutine normalize_and_check_landuse(ns_o) call pctcft(n)%remove_small_cover(toosmallPFT, nsmall) nsmall_tot = nsmall_tot + nsmall - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + ! Include pctocn in suma but do not include in the + ! renormalization. When pctocn /= 0, it is 100, and + ! all other terms are 0. + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctocn(n) suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() if ( abs(suma - 100.0_r8) > 2.0*epsilon(suma) )then pctlak(n) = pctlak(n) * 100._r8/suma @@ -1299,12 +1314,12 @@ subroutine normalize_and_check_landuse(ns_o) end if suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() - suma = suma + pctnatpft(n)%get_pct_l2g() + suma = suma + pctnatpft(n)%get_pct_l2g() + pctocn(n) if ( abs(suma-100._r8) > 1.e-10_r8) then - write (6,*) subname, ' error: sum of pctlak, pctwet,', & + write (6,*) subname, ' error: sum of pctocn, pctlak, pctwet,', & 'pcturb, pctgla, pctnatveg and pctcrop is NOT equal to 100' - write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,sum= ', & - n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& + write (6,*)'n,pctcon,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,sum= ', & + n,pctocn(n),pctlak(n),pctwet(n),pcturb(n),pctgla(n),& pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), suma call shr_sys_abort() end if From 1054dbf49e8a266d5d0f4766578044a63368914a Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 15 Sep 2023 16:38:17 -0600 Subject: [PATCH 331/614] Add pctocn to surfrdMod, NOT TESTED --- src/main/surfrdMod.F90 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/surfrdMod.F90 b/src/main/surfrdMod.F90 index 3a3c892c58..dece33386f 100644 --- a/src/main/surfrdMod.F90 +++ b/src/main/surfrdMod.F90 @@ -390,6 +390,7 @@ subroutine surfrd_special(begg, endg, ncid, ns) real(r8),pointer :: pctgla(:) ! percent of grid cell is glacier real(r8),pointer :: pctlak(:) ! percent of grid cell is lake real(r8),pointer :: pctwet(:) ! percent of grid cell is wetland + real(r8),pointer :: pctocn(:) ! percent of grid cell is ocean real(r8),pointer :: pcturb(:,:) ! percent of grid cell is urbanized integer ,pointer :: urban_region_id(:) real(r8),pointer :: pcturb_tot(:) ! percent of grid cell is urban (sum over density classes) @@ -403,6 +404,7 @@ subroutine surfrd_special(begg, endg, ncid, ns) allocate(pctgla(begg:endg)) allocate(pctlak(begg:endg)) allocate(pctwet(begg:endg)) + allocate(pctocn(begg:endg)) allocate(pcturb(begg:endg,numurbl)) allocate(pcturb_tot(begg:endg)) allocate(urban_region_id(begg:endg)) @@ -412,6 +414,10 @@ subroutine surfrd_special(begg, endg, ncid, ns) ! Obtain non-grid surface properties of surface dataset other than percent patch + call ncd_io(ncid=ncid, varname='PCT_OCEAN', flag='read', data=pctocn, & + dim1name=grlnd, readvar=readvar) + if (.not. readvar) call endrun( msg=' ERROR: PCT_OCEAN NOT on surfdata file'//errMsg(sourcefile, __LINE__)) + call ncd_io(ncid=ncid, varname='PCT_WETLAND', flag='read', data=pctwet, & dim1name=grlnd, readvar=readvar) if (.not. readvar) call endrun( msg=' ERROR: PCT_WETLAND NOT on surfdata file'//errMsg(sourcefile, __LINE__)) @@ -512,7 +518,7 @@ subroutine surfrd_special(begg, endg, ncid, ns) call CheckUrban(begg, endg, pcturb(begg:endg,:), subname) - deallocate(pctgla,pctlak,pctwet,pcturb,pcturb_tot,urban_region_id,pctspec) + deallocate(pctgla,pctlak,pctwet,pctocn,pcturb,pcturb_tot,urban_region_id,pctspec) end subroutine surfrd_special From b9bdb7705460c3f1920122dfd163d487d3873985 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 15 Sep 2023 16:42:18 -0600 Subject: [PATCH 332/614] Add PCT_OCEAN to various tools and tests that will expect it --- python/ctsm/modify_input_files/modify_fsurdat.py | 2 ++ python/ctsm/site_and_regional/single_point_case.py | 1 + python/ctsm/test/test_sys_fsurdat_modifier.py | 2 +- python/ctsm/test/test_unit_singlept_data_surfdata.py | 12 ++++++++++++ .../test/testinputs/modify_fsurdat_1x1mexicocity.cfg | 1 + .../test/testinputs/modify_fsurdat_opt_sections.cfg | 1 + tools/contrib/modify_singlept_site | 1 + 7 files changed, 19 insertions(+), 1 deletion(-) diff --git a/python/ctsm/modify_input_files/modify_fsurdat.py b/python/ctsm/modify_input_files/modify_fsurdat.py index 9b3760e303..6fa3701acc 100644 --- a/python/ctsm/modify_input_files/modify_fsurdat.py +++ b/python/ctsm/modify_input_files/modify_fsurdat.py @@ -351,6 +351,7 @@ def zero_nonveg(self): self.setvar_lev0("PCT_WETLAND", 0) self.setvar_lev0("PCT_URBAN", 0) self.setvar_lev0("PCT_GLACIER", 0) + self.setvar_lev0("PCT_OCEAN", 0) def setvar_lev0(self, var, val): """ @@ -421,6 +422,7 @@ def set_idealized(self): self.setvar_lev0("PCT_LAKE", pct_not_nat_veg) self.setvar_lev0("PCT_URBAN", pct_not_nat_veg) self.setvar_lev0("PCT_GLACIER", pct_not_nat_veg) + self.setvar_lev0("PCT_OCEAN", pct_not_nat_veg) self.setvar_lev0("PCT_NATVEG", pct_nat_veg) for lev in self.file.nlevsoi: diff --git a/python/ctsm/site_and_regional/single_point_case.py b/python/ctsm/site_and_regional/single_point_case.py index 0508891a89..163820456e 100644 --- a/python/ctsm/site_and_regional/single_point_case.py +++ b/python/ctsm/site_and_regional/single_point_case.py @@ -421,6 +421,7 @@ def modify_surfdata_atpoint(self, f_orig): f_mod["PCT_WETLAND"][:, :] = 0.0 f_mod["PCT_URBAN"][:, :, :] = 0.0 f_mod["PCT_GLACIER"][:, :] = 0.0 + f_mod["PCT_OCEAN"][:, :] = 0.0 if self.dom_pft is not None: max_dom_pft = max(self.dom_pft) diff --git a/python/ctsm/test/test_sys_fsurdat_modifier.py b/python/ctsm/test/test_sys_fsurdat_modifier.py index 72d38732cf..7bd57ce8af 100755 --- a/python/ctsm/test/test_sys_fsurdat_modifier.py +++ b/python/ctsm/test/test_sys_fsurdat_modifier.py @@ -215,7 +215,7 @@ def test_opt_sections(self): np.testing.assert_array_equal(fsurdat_out_data.PCT_CROP, zero0d) np.testing.assert_array_equal(fsurdat_out_data.PCT_LAKE, zero0d) np.testing.assert_array_equal(fsurdat_out_data.PCT_WETLAND, zero0d) - np.testing.assert_array_equal(fsurdat_out_data.PCT_LAKE, zero0d) + np.testing.assert_array_equal(fsurdat_out_data.PCT_OCEAN, zero0d) np.testing.assert_array_equal(fsurdat_out_data.PCT_GLACIER, zero0d) np.testing.assert_array_equal(fsurdat_out_data.PCT_URBAN, pct_urban) np.testing.assert_array_equal(fsurdat_out_data.LAKEDEPTH, one0d * 200.0) diff --git a/python/ctsm/test/test_unit_singlept_data_surfdata.py b/python/ctsm/test/test_unit_singlept_data_surfdata.py index 9623975452..427cbac6da 100755 --- a/python/ctsm/test/test_unit_singlept_data_surfdata.py +++ b/python/ctsm/test/test_unit_singlept_data_surfdata.py @@ -106,6 +106,12 @@ class TestSinglePointCaseSurfaceNoCrop(unittest.TestCase): coords={"lsmlat": lsmlat, "lsmlon": lsmlon}, attrs={"long_name": "percent wetland", "units": "unitless"}, ), + "PCT_OCEAN": xr.DataArray( + data=np.random.rand(1, 1), + dims=["lsmlat", "lsmlon"], + coords={"lsmlat": lsmlat, "lsmlon": lsmlon}, + attrs={"long_name": "percent ocean", "units": "unitless"}, + ), "PCT_URBAN": xr.DataArray( data=np.random.rand(1, 1, 3), dims=["lsmlat", "lsmlon", "numurbl"], @@ -656,6 +662,12 @@ class TestSinglePointCaseSurfaceCrop(unittest.TestCase): coords={"lsmlat": lsmlat, "lsmlon": lsmlon}, attrs={"long_name": "percent wetland", "units": "unitless"}, ), + "PCT_OCEAN": xr.DataArray( + data=np.random.rand(1, 1), + dims=["lsmlat", "lsmlon"], + coords={"lsmlat": lsmlat, "lsmlon": lsmlon}, + attrs={"long_name": "percent ocean", "units": "unitless"}, + ), "PCT_URBAN": xr.DataArray( data=np.random.rand(1, 1, 3), dims=["lsmlat", "lsmlon", "numurbl"], diff --git a/python/ctsm/test/testinputs/modify_fsurdat_1x1mexicocity.cfg b/python/ctsm/test/testinputs/modify_fsurdat_1x1mexicocity.cfg index a4118a3255..a854ebcc53 100644 --- a/python/ctsm/test/testinputs/modify_fsurdat_1x1mexicocity.cfg +++ b/python/ctsm/test/testinputs/modify_fsurdat_1x1mexicocity.cfg @@ -36,6 +36,7 @@ PCT_NATVEG= 0.0 PCT_GLACIER= 0.0 PCT_WETLAND= 0.0 PCT_LAKE = 0.0 +PCT_OCEAN = 0.0 # Section with a list of variables to prcoess [modify_fsurdat_variable_list] diff --git a/python/ctsm/test/testinputs/modify_fsurdat_opt_sections.cfg b/python/ctsm/test/testinputs/modify_fsurdat_opt_sections.cfg index c068c5d851..38e7a529f0 100644 --- a/python/ctsm/test/testinputs/modify_fsurdat_opt_sections.cfg +++ b/python/ctsm/test/testinputs/modify_fsurdat_opt_sections.cfg @@ -33,6 +33,7 @@ PCT_CROP = 0.0 PCT_LAKE = 0.0 PCT_GLACIER = 0.0 PCT_WETLAND = 0.0 +PCT_OCEAN = 0.0 # NOTE: PCT_URBAN must be a list of three floats that sum to the total urban area PCT_URBAN = 100.0 0.0 0.0 diff --git a/tools/contrib/modify_singlept_site b/tools/contrib/modify_singlept_site index 46c1bcda1a..df89f6fb73 100755 --- a/tools/contrib/modify_singlept_site +++ b/tools/contrib/modify_singlept_site @@ -231,6 +231,7 @@ if create_surfdata: f2['PCT_WETLAND'] = 0. f2['PCT_URBAN'] = 0. f2['PCT_GLACIER'] = 0. + f2['PCT_OCEAN'] = 0. #-- Overwrite global data with raw data ---------------------------- f2['LONGXY'] = plon From 099fb360dfb8555aa46fc627e9fb3a5c3ee94c46 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Sat, 16 Sep 2023 15:33:49 -0600 Subject: [PATCH 333/614] Corrections in surfrdMod for error checks to pass --- src/main/surfrdMod.F90 | 20 ++++++++++++++------ tools/mksurfdata_esmf/src/mksurfdata.F90 | 7 ++++--- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/main/surfrdMod.F90 b/src/main/surfrdMod.F90 index dece33386f..368e3264a4 100644 --- a/src/main/surfrdMod.F90 +++ b/src/main/surfrdMod.F90 @@ -481,9 +481,9 @@ subroutine surfrd_special(begg, endg, ncid, ns) topo_glc_mec(:,:) = max(topo_glc_mec(:,:), 0._r8) - pctspec = pctwet + pctlak + pcturb_tot + pctgla + pctspec = pctwet + pctlak + pcturb_tot + pctgla + pctocn - ! Error check: glacier, lake, wetland, urban sum must be less than 100 + ! Error check: sum of glacier, lake, wetland, urban, ocean must be < 100 found = .false. do nl = begg,endg @@ -503,15 +503,23 @@ subroutine surfrd_special(begg, endg, ncid, ns) do nl = begg,endg - wt_lunit(nl,istdlak) = pctlak(nl)/100._r8 + wt_lunit(nl,istdlak) = pctlak(nl) / 100._r8 - wt_lunit(nl,istwet) = pctwet(nl)/100._r8 + ! Until ctsm5.1 we would label ocean points as wetland in fsurdat + ! files. Starting with ctsm5.2 we label ocean points as ocean + ! (always 100%) and wetland points as wetland. Here we merge them + ! again to keep model behavior unchanged for now. + if (pctocn(nl) > 100._r8 - 1.e-04_r8) then + wt_lunit(nl,istwet) = pctocn(nl) / 100._r8 + else + wt_lunit(nl,istwet) = pctwet(nl) / 100._r8 + end if - wt_lunit(nl,istice) = pctgla(nl)/100._r8 + wt_lunit(nl,istice) = pctgla(nl) / 100._r8 do n = isturb_MIN, isturb_MAX dens_index = n - isturb_MIN + 1 - wt_lunit(nl,n) = pcturb(nl,dens_index) / 100._r8 + wt_lunit(nl,n) = pcturb(nl,dens_index) / 100._r8 end do end do diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 6a7f3d168f..c40fee5c47 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -431,9 +431,10 @@ program mksurfdata if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkwetlnd') ! Initialize pctocn to zero. - ! Traditionally we have set pctwet = 100 at ocean points rather than - ! setting a pctocn. We now set pctocn = 100 at ocean points in - ! subroutine normalize_and_check_landuse. No regridding required. + ! Until ctsm5.1 we set pctwet = 100 at ocean points rather than + ! setting a pctocn. Starting with ctsm5.2, we set pctocn = 100 at + ! ocean points in subroutine normalize_and_check_landuse. + ! No regridding required. allocate ( pctocn(lsize_o)); pctocn(:) = 0._r8 ! ----------------------------------- From 11a754241c2f3ec3c0bb1a510c780065f7c160ab Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Sun, 17 Sep 2023 09:58:39 -0600 Subject: [PATCH 334/614] Simpler use of pctocn in surfrdMod --- src/main/surfrdMod.F90 | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/surfrdMod.F90 b/src/main/surfrdMod.F90 index 368e3264a4..1d07229b3b 100644 --- a/src/main/surfrdMod.F90 +++ b/src/main/surfrdMod.F90 @@ -509,11 +509,7 @@ subroutine surfrd_special(begg, endg, ncid, ns) ! files. Starting with ctsm5.2 we label ocean points as ocean ! (always 100%) and wetland points as wetland. Here we merge them ! again to keep model behavior unchanged for now. - if (pctocn(nl) > 100._r8 - 1.e-04_r8) then - wt_lunit(nl,istwet) = pctocn(nl) / 100._r8 - else - wt_lunit(nl,istwet) = pctwet(nl) / 100._r8 - end if + wt_lunit(nl,istwet) = (pctocn(nl) + pctwet(nl)) / 100._r8 wt_lunit(nl,istice) = pctgla(nl) / 100._r8 From c47c309af3d2529dd72803b12ad8ad9c495a7497 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 19 Sep 2023 21:58:57 -0600 Subject: [PATCH 335/614] Add a long list of tests to the ctsm_sci test list to ensure supported grids are being run, there are a few grids that don't test both 1850 and 2000 for example, but most cases are covered --- cime_config/testdefs/testlist_clm.xml | 369 +++++++++++++++++++++++++- 1 file changed, 366 insertions(+), 3 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 36192aa8df..db75c685b6 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -1,4 +1,15 @@ + @@ -17,6 +28,15 @@ + + + + + + + + + @@ -44,7 +64,34 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -53,13 +100,85 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -273,6 +392,7 @@ + @@ -331,6 +451,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -888,6 +1215,7 @@ + @@ -1214,6 +1542,7 @@ + @@ -1309,6 +1638,7 @@ + @@ -1569,6 +1899,7 @@ + @@ -1816,6 +2147,7 @@ + @@ -1877,9 +2209,11 @@ + + @@ -2133,6 +2467,12 @@ + + + + + + @@ -2355,6 +2695,7 @@ + @@ -2501,6 +2842,12 @@ + + + + + + @@ -2516,6 +2863,12 @@ + + + + + + @@ -2524,6 +2877,16 @@ + + + + + + + + + + From 6e8508c1b5b6e9d8b69acecbde14048d3dd8e89b Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 19 Sep 2023 23:31:43 -0600 Subject: [PATCH 336/614] Add testmods for clm51cam6 lnd_tuning_mode --- .../clm/clm51cam6LndTuningMode/include_user_mods | 1 + .../testmods_dirs/clm/clm51cam6LndTuningMode/shell_commands | 5 +++++ .../clm/clm51cam6LndTuningMode_1979Start/include_user_mods | 1 + .../clm/clm51cam6LndTuningMode_1979Start/shell_commands | 1 + .../clm/clm51cam6LndTuningMode_2013Start/include_user_mods | 1 + .../clm/clm51cam6LndTuningMode_2013Start/shell_commands | 1 + 6 files changed, 10 insertions(+) create mode 100644 cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode/include_user_mods create mode 100644 cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode/shell_commands create mode 100644 cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_1979Start/include_user_mods create mode 100644 cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_1979Start/shell_commands create mode 100644 cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_2013Start/include_user_mods create mode 100644 cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_2013Start/shell_commands diff --git a/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode/include_user_mods new file mode 100644 index 0000000000..fe0e18cf88 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode/include_user_mods @@ -0,0 +1 @@ +../default diff --git a/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode/shell_commands b/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode/shell_commands new file mode 100644 index 0000000000..cf39cca1c0 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode/shell_commands @@ -0,0 +1,5 @@ +#!/bin/bash + +./xmlchange LND_TUNING_MODE="clm5_1_cam6.0" +./xmlchange ROF_NCPL='$ATM_NCPL' + diff --git a/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_1979Start/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_1979Start/include_user_mods new file mode 100644 index 0000000000..1c3eece35d --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_1979Start/include_user_mods @@ -0,0 +1 @@ +../clm50cam6LndTuningMode diff --git a/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_1979Start/shell_commands b/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_1979Start/shell_commands new file mode 100644 index 0000000000..2aafcc1186 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_1979Start/shell_commands @@ -0,0 +1 @@ +./xmlchange RUN_STARTDATE=1979-01-01 diff --git a/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_2013Start/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_2013Start/include_user_mods new file mode 100644 index 0000000000..aa76c52034 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_2013Start/include_user_mods @@ -0,0 +1 @@ +../clm51cam6LndTuningMode diff --git a/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_2013Start/shell_commands b/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_2013Start/shell_commands new file mode 100644 index 0000000000..035842f982 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_2013Start/shell_commands @@ -0,0 +1 @@ +./xmlchange RUN_STARTDATE=2013-01-01 From 3b6851e882a9550bcda5c5ba60065490b91a7922 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 20 Sep 2023 09:36:50 -0600 Subject: [PATCH 337/614] Add some more latest CLM version compsets, do some organizing and commenting work --- cime_config/config_compsets.xml | 73 +++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 13 deletions(-) diff --git a/cime_config/config_compsets.xml b/cime_config/config_compsets.xml index 61931c94ba..ae54bbacb9 100644 --- a/cime_config/config_compsets.xml +++ b/cime_config/config_compsets.xml @@ -152,6 +152,11 @@ + + I1850Clm51SpCru + 1850_DATM%CRUv7_CLM51%SP_SICE_SOCN_MOSART_SGLC_SWAV + + I1850Clm50BgcCrop 1850_DATM%GSWP3v1_CLM50%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV @@ -176,17 +181,20 @@ + I1850Clm50BgcCropCmip6 1850_DATM%GSWP3v1_CLM50%BGC-CROP-CMIP6DECK_SICE_SOCN_MOSART_SGLC_SWAV + I1850Clm50BgcCropCmip6waccm 1850_DATM%GSWP3v1_CLM50%BGC-CROP-CMIP6WACCMDECK_SICE_SOCN_MOSART_SGLC_SWAV + I1850Clm50BgcCropCru 1850_DATM%CRUv7_CLM50%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV @@ -194,9 +202,19 @@ + + + I1850Clm51BgcCropCru + 1850_DATM%CRUv7_CLM51%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV + + + + I2000Clm51BgcCropQianRs + 2000_DATM%QIA_CLM51%BGC-CROP_SICE_SOCN_SROF_SGLC_SWAV + I2000Clm50BgcCropQianRs 2000_DATM%QIA_CLM50%BGC-CROP_SICE_SOCN_SROF_SGLC_SWAV @@ -308,6 +326,11 @@ + + IHistClm51SpCru + HIST_DATM%CRUv7_CLM51%SP_SICE_SOCN_MOSART_SGLC_SWAV + + IHistClm50Bgc HIST_DATM%GSWP3v1_CLM50%BGC_SICE_SOCN_MOSART_SGLC_SWAV @@ -326,7 +349,14 @@ HIST_DATM%QIA_CLM50%BGC_SICE_SOCN_SROF_SGLC_SWAV - + + IHistClm51BgcQianRs + HIST_DATM%QIA_CLM51%BGC_SICE_SOCN_SROF_SGLC_SWAV + + + ISSP585Clm50BgcCrop SSP585_DATM%GSWP3v1_CLM50%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV @@ -367,10 +397,16 @@ SSP534_DATM%GSWP3v1_CLM50%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV + + + ISSP585Clm51BgcCrop + SSP585_DATM%GSWP3v1_CLM51%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV + - + + IHistClm50BgcCropQianRs HIST_DATM%QIA_CLM50%BGC-CROP_SICE_SOCN_SROF_SGLC_SWAV @@ -517,7 +553,9 @@ 2000_DATM%CRUv7_CLM45%SP-VIC_SICE_SOCN_RTM_SGLC_SWAV - + I1850Clm50SpG @@ -534,12 +572,6 @@ 1850_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_MOSART_CISM2%AIS-EVOLVE%GRIS-EVOLVE_SWAV - - - I1850Clm50SpRsGag - 1850_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_SROF_CISM2%AIS-EVOLVE%GRIS-EVOLVE_SWAV - - IHistClm50SpG HIST_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_MOSART_CISM2%GRIS-EVOLVE_SWAV @@ -555,13 +587,28 @@ HIST_DATM%GSWP3v1_CLM50%BGC-CROP_SICE_SOCN_MOSART_CISM2%GRIS-EVOLVE_SWAV - + + I1850Clm51BgcCropG + 1850_DATM%GSWP3v1_CLM51%BGC-CROP_SICE_SOCN_MOSART_CISM2%GRIS-EVOLVE_SWAV + + + + + + I1850Clm50SpRsGag + 1850_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_SROF_CISM2%AIS-EVOLVE%GRIS-EVOLVE_SWAV + + + + + both purposes.) +--> I2000Ctsm50NwpSpAsRs 2000_SATM_CLM50%NWP-SP_SICE_SOCN_SROF_SGLC_SWAV From 82e527dc7e0d63662319c9d6b08a8f2565537a10 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 20 Sep 2023 12:49:46 -0600 Subject: [PATCH 338/614] Change some tests to latest CLM version, and add to the comments about it --- cime_config/testdefs/testlist_clm.xml | 138 ++++++++++++++------------ 1 file changed, 73 insertions(+), 65 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index db75c685b6..45da5e0344 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -28,13 +28,13 @@ - + - + @@ -70,7 +70,7 @@ - + @@ -79,7 +79,7 @@ - + @@ -88,7 +88,7 @@ - + @@ -97,7 +97,7 @@ - + @@ -106,7 +106,7 @@ - + @@ -115,7 +115,7 @@ - + @@ -124,7 +124,7 @@ - + @@ -133,7 +133,7 @@ - + @@ -142,7 +142,7 @@ - + @@ -151,7 +151,7 @@ - + @@ -160,7 +160,7 @@ - + @@ -169,7 +169,7 @@ - + @@ -178,7 +178,7 @@ - + @@ -296,13 +296,13 @@ - + - + @@ -457,7 +457,7 @@ - + @@ -466,7 +466,7 @@ - + @@ -475,7 +475,7 @@ - + @@ -484,7 +484,7 @@ - + @@ -493,7 +493,7 @@ - + @@ -502,7 +502,7 @@ - + @@ -511,7 +511,7 @@ - + @@ -520,7 +520,7 @@ - + @@ -529,7 +529,7 @@ - + @@ -538,16 +538,16 @@ - + - + - + @@ -556,7 +556,7 @@ - + @@ -565,25 +565,25 @@ - + - + - + - + - + @@ -592,25 +592,25 @@ - + - + - + - + - + @@ -619,7 +619,7 @@ - + @@ -628,25 +628,25 @@ - + - + - + - + - + @@ -655,7 +655,7 @@ - + @@ -1323,13 +1323,13 @@ - + - + @@ -1540,7 +1540,7 @@ - + @@ -1671,17 +1671,17 @@ - + - - + @@ -1690,7 +1690,7 @@ - + @@ -1699,7 +1699,7 @@ - + @@ -1897,7 +1897,7 @@ - + @@ -2147,13 +2147,21 @@ - + + + + + + + + + @@ -2205,7 +2213,7 @@ - + @@ -2213,7 +2221,7 @@ - + @@ -2840,12 +2848,12 @@ - + - + @@ -2861,12 +2869,12 @@ - + - + @@ -2877,12 +2885,12 @@ - + - + From 61305e679e99dca1eefeda44e4d82c52fbbd9909 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 20 Sep 2023 14:17:08 -0600 Subject: [PATCH 339/614] Add some clm5_1 f09 and f19 science test list tests for standard configurations --- cime_config/testdefs/testlist_clm.xml | 92 +++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 6 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 45da5e0344..7cf870bdf2 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -206,6 +206,7 @@ + @@ -242,6 +243,25 @@ + + + + + + + + + + + + + + + + + + + @@ -425,13 +445,14 @@ + - + @@ -440,7 +461,26 @@ - + + + + + + + + + + + + + + + + + + + + @@ -667,13 +707,14 @@ + - + @@ -682,7 +723,26 @@ - + + + + + + + + + + + + + + + + + + + + @@ -1708,13 +1768,14 @@ + - + @@ -1723,7 +1784,26 @@ - + + + + + + + + + + + + + + + + + + + + From 0d729b96adfc029770d5e845e9e5bc314181b309 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 20 Sep 2023 15:58:34 -0600 Subject: [PATCH 340/614] Change some of the test compset names as well as add some new compsets needed for testing --- cime_config/config_compsets.xml | 14 +++++++++ cime_config/testdefs/testlist_clm.xml | 42 +++++++++++++-------------- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/cime_config/config_compsets.xml b/cime_config/config_compsets.xml index ae54bbacb9..85452830d9 100644 --- a/cime_config/config_compsets.xml +++ b/cime_config/config_compsets.xml @@ -83,6 +83,10 @@ I2000Clm50SpRs 2000_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_SROF_SGLC_SWAV + + I2000Clm51SpRs + 2000_DATM%GSWP3v1_CLM51%SP_SICE_SOCN_SROF_SGLC_SWAV + I2000Clm51Sp @@ -302,6 +306,11 @@ HIST_DATM%GSWP3v1_CLM51%SP_SICE_SOCN_MOSART_SGLC_SWAV + + IHistClm51SpRs + HIST_DATM%GSWP3v1_CLM51%SP_SICE_SOCN_SROF_SGLC_SWAV + + IHistClm51Bgc HIST_DATM%GSWP3v1_CLM51%BGC_SICE_SOCN_MOSART_SGLC_SWAV @@ -600,6 +609,11 @@ 1850_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_SROF_CISM2%AIS-EVOLVE%GRIS-EVOLVE_SWAV + + I1850Clm51SpRs + 1850_DATM%GSWP3v1_CLM51%SP_SICE_SOCN_SROF_SGLC_SWAV + + diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 2d348bccd3..2a7736d721 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -536,6 +536,7 @@ + @@ -653,7 +655,7 @@ - + @@ -662,7 +664,7 @@ - + @@ -1695,7 +1697,7 @@ - + From e359f9e7adc976cec61f1897f9dd4fbcfb9a3308 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 20 Sep 2023 17:04:08 -0600 Subject: [PATCH 343/614] Add clm5_1_cam6.0 lnd_tuning_mode --- bld/namelist_files/namelist_defaults_ctsm.xml | 4 ++++ bld/namelist_files/namelist_definition_ctsm.xml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 8d35df281b..bd0471c9fa 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -278,6 +278,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). >30.0d00 20.0d00 +20.0d00 80.0d00 0.85d00 0.98d00 @@ -289,6 +291,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). >0.010d00 0.008d00 +0.008d00 0.17d-3 1.6d-4 0.33d00 diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 41a03a6868..22ee44f0f3 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -2051,7 +2051,7 @@ Land mask description + valid_values="clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_cam6.0,clm5_0_cam6.0,clm5_0_CRUv7,clm5_0_GSWP3v1,clm5_1_GSWP3v1,clm5_1_cam6.0"> General configuration of model version and atmospheric forcing to tune the model to run under. This sets the model to run with constants and initial conditions that were set to run well under the configuration of model version and atmospheric forcing. To run well constants would need to be changed From 4b99455303d3332ac39dcb30a0b718a64c444f97 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 20 Sep 2023 17:08:11 -0600 Subject: [PATCH 344/614] Add clm5_1_cam6.0 lnd_tuning_mode --- cime_config/config_component.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 743e9229b9..677219ec8c 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -63,7 +63,7 @@ Tuning parameters and initial conditions should be optimized for what CLM model version and what meteorlogical forcing combination? UNSET - clm5_0_cam6.0,clm5_0_GSWP3v1,clm5_0_CRUv7,clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_cam6.0,clm5_1_GSWP3v1 + clm5_0_cam6.0,clm5_0_GSWP3v1,clm5_0_CRUv7,clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_cam6.0,clm5_1_GSWP3v1,clm5_1_cam6.0 clm4_5_CRUv7 clm4_5_CRUv7 @@ -75,6 +75,8 @@ clm5_0_GSWP3v1 clm5_0_cam6.0 clm5_0_cam6.0 + clm5_1_cam6.0 + clm5_1_cam6.0 clm5_1_GSWP3v1 From 4346ea59ae34749c0ee98dca8ca30d6f2ab1717b Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 21 Sep 2023 15:02:25 -0600 Subject: [PATCH 345/614] Add use_init_interp settings for clm5_0_cam6.0 lnd_tuning_mode options --- bld/namelist_files/namelist_defaults_ctsm.xml | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index bd0471c9fa..3803e79b1b 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -633,7 +633,12 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .true. - + + .true. @@ -650,6 +655,27 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .true. + + +.true. +.true. +.true. +.true. + +.true. + + +.true. + + .true. .true. From 2841a0554bdc5b333992c6c55b99a3449a76f8ed Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 25 Sep 2023 10:50:00 -0600 Subject: [PATCH 346/614] Work on handling more LND_TUNING_MODE which is then changed in buildnml to a smaller subset --- cime_config/config_component.xml | 63 ++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 677219ec8c..9199947205 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -61,23 +61,56 @@ run_component_ctsm env_run.xml Tuning parameters and initial conditions should be optimized for what CLM model version and what meteorlogical forcing combination? + Options for all combinations of CLM physics and atm forcing are given. The buildnml and namelist_defaults will narrow it down to the ones + that have been tuned. The buildnml will also warn you if a tuning combination is based on another set. + Atm forcing options: + CRUv7 + GSWP3 + CAM6.0 + QIAN (not tuned) + 1PT (not tuned) + NLDAS2 (not tuned) + ERA5 (not tuned) + Other atm forcing options are invalid to run CLM and will result in an error. UNSET - clm5_0_cam6.0,clm5_0_GSWP3v1,clm5_0_CRUv7,clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_cam6.0,clm5_1_GSWP3v1,clm5_1_cam6.0 - - clm4_5_CRUv7 - clm4_5_CRUv7 - clm4_5_GSWP3v1 - clm4_5_cam6.0 - clm4_5_cam6.0 - clm5_0_CRUv7 - clm5_0_CRUv7 - clm5_0_GSWP3v1 - clm5_0_cam6.0 - clm5_0_cam6.0 - clm5_1_cam6.0 - clm5_1_cam6.0 - clm5_1_GSWP3v1 + + clm5_0_cam6.0,clm5_0_GSWP3v1,clm5_0_CRUv7,clm5_0_QIAN,clm5_0_1PT,clm5_0_NLDAS2,clm5_0_ERA5,clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_cam6.0,clm4_5_1PT,clm4_5_NLDAS2,clm4_5_ERA5,clm5_1_CRUv7,clm5_1_GSWP3v1,clm5_1_cam6.0,clm5_1_QIAN,clm5_1_1PT,clm5_1_NLDAS2,clm5_1_ERA5 + + + + clm4_5_CRUv7 + clm4_5_CRUv7 + clm4_5_GSWP3v1 + clm4_5_cam6.0 + clm4_5_cam6.0 + clm4_5_QIAN + clm4_5_QIAN + clm4_5_1PT + clm4_5_NLDAS2 + clm4_5_ERA5 + + clm5_0_CRUv7 + clm5_0_CRUv7 + clm5_0_GSWP3v1 + clm5_0_cam6.0 + clm5_0_cam6.0 + clm5_0_QIAN + clm5_0_QIAN + clm5_0_1PT + clm5_0_NLDAS2 + clm5_0_ERA5 + + clm5_1_CRUv7 + clm5_1_CRUv7 + clm5_1_GSWP3v1 + clm5_1_cam6.0 + clm5_1_cam6.0 + clm5_1_QIAN + clm5_1_QIAN + clm5_1_1PT + clm5_1_NLDAS2 + clm5_1_ERA5 From 552c029d4ae67bc6a20fd61247bbaceeb6c7ff55 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 25 Sep 2023 15:02:51 -0600 Subject: [PATCH 347/614] Add invalid options for LND_TUNING_MODE For DATM ocean forcing options, make CAM match more explicit --- cime_config/config_component.xml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 9199947205..2e6bbe6c22 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -82,7 +82,7 @@ clm4_5_CRUv7 clm4_5_CRUv7 clm4_5_GSWP3v1 - clm4_5_cam6.0 + clm4_5_cam6.0 clm4_5_cam6.0 clm4_5_QIAN clm4_5_QIAN @@ -93,7 +93,7 @@ clm5_0_CRUv7 clm5_0_CRUv7 clm5_0_GSWP3v1 - clm5_0_cam6.0 + clm5_0_cam6.0 clm5_0_cam6.0 clm5_0_QIAN clm5_0_QIAN @@ -104,13 +104,18 @@ clm5_1_CRUv7 clm5_1_CRUv7 clm5_1_GSWP3v1 - clm5_1_cam6.0 + clm5_1_cam6.0 clm5_1_cam6.0 clm5_1_QIAN clm5_1_QIAN clm5_1_1PT clm5_1_NLDAS2 clm5_1_ERA5 + + INVALID_DATM_FORCING_FOR_RUNNING_CTSM + INVALID_DATM_FORCING_FOR_RUNNING_CTSM + INVALID_DATM_FORCING_FOR_RUNNING_CTSM + INVALID_DATM_FORCING_FOR_RUNNING_CTSM From 75502016f2e57d623d71047b232ccfa3a1548393 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 25 Sep 2023 15:04:48 -0600 Subject: [PATCH 348/614] Add messaging about LND_TUNING_MODE so that user will see a message about what mode is being picked, and also about what the settings are based on if an option isn't fully tuned --- cime_config/buildnml | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/cime_config/buildnml b/cime_config/buildnml index 25724def82..9dda86572e 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -74,6 +74,48 @@ def buildnml(case, caseroot, compname): if ( clm_bldnml_opts.find("-namelist") >= 0 ): expect(False, "The -namelist option is NOT allowed to be part of CLM_BLDNML_OPTS, " + \ "use the CLM_NAMELIST_OPTS option or add namelist items to user_nl_clm instead " ); + # + # Warnings for land tuning modes + # + closest_tuning = { + "clm4_5_1PT": "clm4_5_CRUv7", + "clm4_5_QIAN": "clm4_5_CRUv7", + "clm4_5_NLDAS2": "clm4_5_CRUv7", + "clm4_5_ERA5": "clm4_5_CRUv7", + "clm5_0_1PT": "clm5_0_GSWP3", + "clm5_0_QIAN": "clm5_0_GSWP3v1", + "clm5_0_NLDAS2": "clm5_0_GSWP3v1", + "clm5_0_ERA5": "clm5_0_GSWP3v1", + "clm5_1_1PT": "clm5_1_GSWP3v1", + "clm5_1_QIAN": "clm5_1_GSWP3v1", + "clm5_1_NLDAS2": "clm5_1_GSWP3v1", + "clm5_1_ERA5": "clm5_1_GSWP3v1", + "clm5_1_CRUv7": "clm5_1_GSWP3v1", + } + for mode, closest in closest_tuning.items(): + if lnd_tuning_mode == mode: + logger.warning( + "IMPORTANT NOTE: LND_TUNING_MODE is " + + lnd_tuning_mode + + " which does NOT have tuned settings, so using the closest option which is " + + closest + ) + logger.warning( + " : To suppress this message explicitly set LND_TUNING_MODE=" + + lnd_tuning_mode + + " for your case" + ) + lnd_tuning_mode = closest + + tuning_based_on = {"clm5_1_GSWP3v1": "clm5_0_GSWP3v1", "clm5_1_cam6.0": "clm5_0_cam6.0"} + for mode, based_on in tuning_based_on.items(): + if lnd_tuning_mode == mode: + logger.warning( + "NOTE: LND_TUNING_MODE is " + + lnd_tuning_mode + + " which is NOT tuned, but is based on " + + based_on + ) # ----------------------------------------------------- # Set ctsmconf From aa3c5cc8a06fffa5d745747a99ec6edf2035acd4 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 25 Sep 2023 15:29:18 -0600 Subject: [PATCH 349/614] Fix the GSWP3v1 lnd_tuning_mode as well as adding clm4_5_QIAN to the valid_values --- cime_config/config_component.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 2e6bbe6c22..8f6b47dd5b 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -75,13 +75,13 @@ UNSET - clm5_0_cam6.0,clm5_0_GSWP3v1,clm5_0_CRUv7,clm5_0_QIAN,clm5_0_1PT,clm5_0_NLDAS2,clm5_0_ERA5,clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_cam6.0,clm4_5_1PT,clm4_5_NLDAS2,clm4_5_ERA5,clm5_1_CRUv7,clm5_1_GSWP3v1,clm5_1_cam6.0,clm5_1_QIAN,clm5_1_1PT,clm5_1_NLDAS2,clm5_1_ERA5 + clm5_0_cam6.0,clm5_0_GSWP3v1,clm5_0_CRUv7,clm5_0_QIAN,clm5_0_1PT,clm5_0_NLDAS2,clm5_0_ERA5,clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_QIAN,clm4_5_cam6.0,clm4_5_1PT,clm4_5_NLDAS2,clm4_5_ERA5,clm5_1_CRUv7,clm5_1_GSWP3v1,clm5_1_cam6.0,clm5_1_QIAN,clm5_1_1PT,clm5_1_NLDAS2,clm5_1_ERA5 clm4_5_CRUv7 clm4_5_CRUv7 - clm4_5_GSWP3v1 + clm4_5_GSWP3v1 clm4_5_cam6.0 clm4_5_cam6.0 clm4_5_QIAN @@ -92,7 +92,7 @@ clm5_0_CRUv7 clm5_0_CRUv7 - clm5_0_GSWP3v1 + clm5_0_GSWP3v1 clm5_0_cam6.0 clm5_0_cam6.0 clm5_0_QIAN @@ -103,7 +103,7 @@ clm5_1_CRUv7 clm5_1_CRUv7 - clm5_1_GSWP3v1 + clm5_1_GSWP3v1 clm5_1_cam6.0 clm5_1_cam6.0 clm5_1_QIAN From e2022fbd09bed74eaa9b90711149e0c595b45ca6 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 25 Sep 2023 17:36:46 -0600 Subject: [PATCH 350/614] Add more documentation about finidat searching --- bld/namelist_files/namelist_defaults_ctsm.xml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 3803e79b1b..c546a9a866 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -730,6 +730,10 @@ attributes from the config_cache.xml file (with keys converted to upper-case). >hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.false. glc_nec=10 do_transient_pfts=.false. +hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.false. glc_nec=10 do_transient_pfts=.false. + + hgrid=1.9x2.5 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. - + + hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. @@ -871,7 +876,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). - + hgrid=0.9x1.25 maxpft=17 mask=gx1v7 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false. @@ -891,7 +896,6 @@ attributes from the config_cache.xml file (with keys converted to upper-case). hgrid="ne0np4.ARCTICGRIS.ne30x8" use_cn=".false." maxpft="17" >hgrid=ne0np4.ARCTICGRIS.ne30x8 maxpft=17 mask=tx0.1v2 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false. -p Date: Mon, 25 Sep 2023 17:54:59 -0600 Subject: [PATCH 351/614] Add clm5_1_CRUv1, so all physics options have all three forcing options: CRU, GSWP3, and cam6 --- bld/namelist_files/namelist_definition_ctsm.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 22ee44f0f3..1f3b5db490 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -2049,13 +2049,15 @@ hist means do NOT use a future scenario, just use historical data. Land mask description + + valid_values="clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_cam6.0,clm5_0_cam6.0,clm5_0_CRUv7,clm5_0_GSWP3v1,clm5_1_CRUv1,clm5_1_GSWP3v1,clm5_1_cam6.0"> General configuration of model version and atmospheric forcing to tune the model to run under. This sets the model to run with constants and initial conditions that were set to run well under the configuration of model version and atmospheric forcing. To run well constants would need to be changed to run with a different type of atmospheric forcing. +(Some options for the newest physics will be based on previous tuning, and buildnml will let you know about this) Date: Tue, 26 Sep 2023 10:22:32 -0600 Subject: [PATCH 352/614] Remove 1x1_asphaltjungleNJ and add mpasa15-3,mpasa15-3-conus,mpasa7p5,mpasa3p75 --- bld/namelist_files/namelist_definition_ctsm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 1f3b5db490..7d22867de0 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -2028,7 +2028,7 @@ CLM run type. + valid_values="512x1024,360x720cru,128x256,64x128,48x96,94x192,0.23x0.31,0.47x0.63,0.9x1.25,1.9x2.5,2.5x3.33,4x5,10x15,0.125nldas2,5x5_amazon,1x1_vancouverCAN,1x1_mexicocityMEX,1x1_brazil,1x1_urbanc_alpha,1x1_numaIA,1x1_smallvilleIA,0.25x0.25,0.5x0.5,3x3min,5x5min,10x10min,0.33x0.33,0.125x0.125,ne3np4.pg3,ne4np4,ne5np4.pg3,ne16np4,ne16np4.pg3,ne30np4.pg2,ne30np4.pg3,ne30np4,ne60np4,ne120np4,ne120np4.pg2,ne120np4.pg3,ne0np4CONUS.ne30x8,ne0np4.ARCTIC.ne30x4,ne0np4.ARCTICGRIS.ne30x8,ne240np4,1km-merge-10min,C24,C48,C96,C192,C384,mpasa480,mpasa240,mpasa120,mpasa60,mpasa30,mpasa15,mpasa15-3,mpasa15-3-conus,mpasa7p5,mpasa3p75"> Horizontal resolutions Note: 0.25x0.25, 0.5x0.5, 5x5min, 10x10min, 3x3min, 1km-merge-10min and 0.33x0.33 are only used for CLM toolsI From 4ac84f3df44930072c62cc07f02148f4ec4d8c09 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 26 Sep 2023 12:53:07 -0600 Subject: [PATCH 353/614] Test more resolutions and include mpasa, FV^3, and more SE grids --- bld/unit_testers/build-namelist_test.pl | 85 +++++++++++++++++-------- 1 file changed, 58 insertions(+), 27 deletions(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 8e16ab3e9b..5e25bf286e 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,7 +163,7 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 1958; +my $ntests = 2462; if ( defined($opts{'compare'}) ) { $ntests += 1335; } @@ -1265,12 +1265,8 @@ sub cat_and_create_namelistinfile { print "=== Test $res === \n"; my $options = "-res $res -bgc sp -envxml_dir ."; - # Regional single point resolutions - if ( $res =~ /^([0-9]+x[0-9]+_[a-zA-Z]+)$/ ) { - push( @regional, $res ); - next; # Resolutions for mksurfdata mapping - } elsif ( $res eq "0.5x0.5" || + if ( $res eq "0.5x0.5" || $res eq "0.25x0.25" || $res eq "3x3min" || $res eq "5x5min" || @@ -1279,23 +1275,62 @@ sub cat_and_create_namelistinfile { $res eq "0.33x0.33" || $res eq "1km-merge-10min" ) { next; - # Resolutions that were supported in clm40 but NOT clm45/clm50 - } elsif ( $res eq "ne240np4" || + # Resolutions that don't have surface datasets created for them + # SE grids: + } elsif ( + $res eq "ne240np4" || + $res eq "ne240np4.pg2"|| + $res eq "ne240np4.pg3"|| + $res eq "ne120np4" || + $res eq "ne120np4.pg2"|| + $res eq "ne120np4.pg4"|| $res eq "ne60np4" || - $res eq "ne4np4" || + $res eq "ne60np4.pg2" || + $res eq "ne60np4.pg3" || + $res eq "ne60np4.pg4" || + $res eq "ne30np4.pg2" || + $res eq "ne30np4.pg4" || + $res eq "ne16np4.pg3" || + $res eq "ne5np4" || + $res eq "ne5np4.pg2" || + $res eq "ne5np4.pg4" || + $res eq "ne3np4" + ) { + next; + # FV grids: + } elsif ( $res eq "2.5x3.33" || $res eq "0.23x0.31" || - $res eq "0.47x0.63" || - $res eq "94x192" || + $res eq "0.47x0.63" + ) { + next; + # FV^3 grids: + } elsif ( + $res eq "C192" || + $res eq "C384" + ) { + next; + # mpasa grids: + } elsif ( + $res eq "mpasa240" || + $res eq "mpasa240" || + $res eq "mpasa60" || + $res eq "mpasa30" || + $res eq "mpasa15" || + $res eq "mpasa15-3conus" || + $res eq "mpasa12" || + $res eq "mpasa7p5" || + $res eq "mpasa3p75" + ) { + next; + # EUL grids: + } elsif ( $res eq "8x16" || $res eq "32x64" || + $res eq "64x128" || $res eq "128x256" || - $res eq "360x720cru" || - $res eq "512x1024" ) { - next; - # Resolutions not supported on release branch - } elsif ( $res eq "ne120np4" || - $res eq "conus_30_x8" ) { + $res eq "512x1024" + ) { next; } @@ -1322,7 +1357,7 @@ sub cat_and_create_namelistinfile { print " Test important resolutions for BGC\n"; print "==================================================\n"; -my @resolutions = ( "4x5", "10x15", "ne30np4", "ne16np4", "1.9x2.5", "0.9x1.25" ); +my @resolutions = ( "4x5", "10x15", "ne120np4.pg3", "ne30np4", "ne30np4.pg3", "ne16np4", "ne3np4.pg3", "1.9x2.5", "0.9x1.25", "C96", "mpasa120", "mpasa480" ); my @regional; my $nlbgcmode = "bgc"; my $mode = "$phys-$nlbgcmode"; @@ -1383,7 +1418,7 @@ sub cat_and_create_namelistinfile { print "==================================================\n"; # Check for crop resolutions -my @crop_res = ( "1x1_numaIA", "1x1_smallvilleIA", "4x5", "10x15", "0.9x1.25", "1.9x2.5", "ne30np4" ); +my @crop_res = ( "1x1_numaIA", "1x1_smallvilleIA", "4x5", "10x15", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne30np4", "ne30np4.pg3", "C96", "mpasa120" ); foreach my $res ( @crop_res ) { $options = "-bgc bgc -crop -res $res -envxml_dir ."; &make_env_run(); @@ -1534,7 +1569,7 @@ sub cat_and_create_namelistinfile { "-bgc bgc -clm_demand flanduse_timeseries -sim_year 1850-2000 -namelist '&a start_ymd=18500101/'", "-bgc bgc -envxml_dir . -namelist '&a use_c13=.true.,use_c14=.true.,use_c14_bombspike=.true./'" ); foreach my $clmopts ( @clmoptions ) { - my @clmres = ( "10x15", "0.9x1.25", "1.9x2.5" ); + my @clmres = ( "10x15", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne30np4", "C96", "mpasa120" ); foreach my $res ( @clmres ) { $options = "-res $res -envxml_dir . "; &make_env_run( ); @@ -1621,20 +1656,16 @@ sub cat_and_create_namelistinfile { } } # -# Run over the differen lnd_tuning modes +# Run over the different lnd_tuning modes # my $res = "0.9x1.25"; -my $mask = "gx1v6"; +my $mask = "gx1v7"; my $simyr = "1850"; foreach my $phys ( "clm4_5", 'clm5_0', 'clm5_1' ) { my $mode = "-phys $phys"; &make_config_cache($phys); my @forclist = (); - if ( $phys == "clm5_1" ) { - @forclist = ( "GSWP3v1" ); - } else { - @forclist = ( "CRUv7", "GSWP3v1", "cam6.0" ); - } + @forclist = ( "CRUv7", "GSWP3v1", "cam6.0" ); foreach my $forc ( @forclist ) { foreach my $bgc ( "sp", "bgc" ) { my $lndtuningmode = "${phys}_${forc}"; From b25636e50d874a01411b42d2f5207e8c14b0f76d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sat, 30 Sep 2023 16:10:50 -0600 Subject: [PATCH 354/614] Make the list of all resolutions explicit, because we just want the ones that have surface datasets, and the list of exclusions was larger than the list of inclusions, and also we want to get away from using the resolution list so we can remove it --- bld/unit_testers/build-namelist_test.pl | 78 ++----------------------- 1 file changed, 4 insertions(+), 74 deletions(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 5e25bf286e..bacc69416d 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,9 +163,9 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 2462; +my $ntests = 2426; if ( defined($opts{'compare'}) ) { - $ntests += 1335; + $ntests += 1686; } plan( tests=>$ntests ); @@ -1253,87 +1253,17 @@ sub cat_and_create_namelistinfile { &make_config_cache($phys); print "\n==================================================\n"; -print "Test ALL resolutions with SP\n"; +print "Test ALL resolutions that have surface datasets with SP\n"; print "==================================================\n"; # Check for ALL resolutions with CLM50SP -my $reslist = `../queryDefaultNamelist.pl -res list -s`; -my @resolutions = split( / /, $reslist ); +my @resolutions = ( "1x1_brazil", "1x1_numaIA", "1x1_smallvilleIA", "1x1_mexicocityMEX", "1x1_vancouverCAN", "1x1_urbanc_alpha", "5x5_amazon", "360x720cru", "0.125x0.125", "0.125nldas2", "10x15", "4x5", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne5np4.pg2", "ne16np4", "ne30np4", "ne30np4.pg3", "ne120np4.pg3", "ne0np4CONUS.ne30x8", "ne0np4.ARCTIC.ne30x4", "ne0np4.ARCTICGRIS.ne30x8", "C24", "C48", "C96", "mpasa480", "mpasa120" ); my @regional; foreach my $res ( @resolutions ) { chomp($res); print "=== Test $res === \n"; my $options = "-res $res -bgc sp -envxml_dir ."; - # Resolutions for mksurfdata mapping - if ( $res eq "0.5x0.5" || - $res eq "0.25x0.25" || - $res eq "3x3min" || - $res eq "5x5min" || - $res eq "10x10min" || - $res eq "0.125x0.125" || - $res eq "0.33x0.33" || - $res eq "1km-merge-10min" ) { - next; - # Resolutions that don't have surface datasets created for them - # SE grids: - } elsif ( - $res eq "ne240np4" || - $res eq "ne240np4.pg2"|| - $res eq "ne240np4.pg3"|| - $res eq "ne120np4" || - $res eq "ne120np4.pg2"|| - $res eq "ne120np4.pg4"|| - $res eq "ne60np4" || - $res eq "ne60np4.pg2" || - $res eq "ne60np4.pg3" || - $res eq "ne60np4.pg4" || - $res eq "ne30np4.pg2" || - $res eq "ne30np4.pg4" || - $res eq "ne16np4.pg3" || - $res eq "ne5np4" || - $res eq "ne5np4.pg2" || - $res eq "ne5np4.pg4" || - $res eq "ne3np4" - ) { - next; - # FV grids: - } elsif ( - $res eq "2.5x3.33" || - $res eq "0.23x0.31" || - $res eq "0.47x0.63" - ) { - next; - # FV^3 grids: - } elsif ( - $res eq "C192" || - $res eq "C384" - ) { - next; - # mpasa grids: - } elsif ( - $res eq "mpasa240" || - $res eq "mpasa240" || - $res eq "mpasa60" || - $res eq "mpasa30" || - $res eq "mpasa15" || - $res eq "mpasa15-3conus" || - $res eq "mpasa12" || - $res eq "mpasa7p5" || - $res eq "mpasa3p75" - ) { - next; - # EUL grids: - } elsif ( - $res eq "8x16" || - $res eq "32x64" || - $res eq "64x128" || - $res eq "128x256" || - $res eq "512x1024" - ) { - next; - } - &make_env_run(); eval{ system( "$bldnml $options > $tempfile 2>&1 " ); }; is( $@, '', "$options" ); From b364458d5ca249292400308e93a4accccb927e5b Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 2 Oct 2023 15:45:15 -0600 Subject: [PATCH 355/614] Improve some of the error checking for the finidat finding --- bld/CLMBuildNamelist.pm | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 895c2e8a4d..ac15f85e1b 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2343,11 +2343,17 @@ sub setup_logic_initial_conditions { } my $useinitvar = "use_init_interp"; + my %settings; + my $use_init_interp_default = $nl->get_value($useinitvar); + $settings{$useinitvar} = $use_init_interp_default; + if ( string_is_undef_or_empty( $use_init_interp_default ) ) { + $use_init_interp_default = $defaults->get_value($useinitvar, \%settings); + $settings{$useinitvar} = ".false."; + } if (not defined $finidat ) { my $ic_date = $nl->get_value('start_ymd'); my $st_year = $nl_flags->{'st_year'}; my $nofail = 1; - my %settings; $settings{'hgrid'} = $nl_flags->{'res'}; $settings{'phys'} = $physv->as_string(); $settings{'nofail'} = $nofail; @@ -2384,12 +2390,6 @@ sub setup_logic_initial_conditions { } my $try = 0; my $done = 2; - my $use_init_interp_default = $nl->get_value($useinitvar); - $settings{$useinitvar} = $use_init_interp_default; - if ( string_is_undef_or_empty( $use_init_interp_default ) ) { - $use_init_interp_default = $defaults->get_value($useinitvar, \%settings); - $settings{$useinitvar} = ".false."; - } do { $try++; add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, %settings ); @@ -2436,14 +2436,24 @@ SIMYR: foreach my $sim_yr ( @sim_years ) { } } # SIMYR: $settings{'sim_year'} = $closest_sim_year; + # Add options set here to the "$set" variable below... add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $useinitvar, 'use_cndv'=>$nl_flags->{'use_cndv'}, 'phys'=>$physv->as_string(), 'hgrid'=>$nl_flags->{'res'}, 'sim_year'=>$settings{'sim_year'}, 'nofail'=>1, 'lnd_tuning_mode'=>$nl_flags->{'lnd_tuning_mode'}, 'use_fates'=>$nl_flags->{'use_fates'} ); $settings{$useinitvar} = $nl->get_value($useinitvar); if ( ! &value_is_true($nl->get_value($useinitvar) ) ) { - if ( $nl_flags->{'clm_start_type'} =~ /startup/ ) { - $log->fatal_error("clm_start_type is startup so an initial conditions ($var) file is required, but can't find one without $useinitvar being set to true"); + if ( $nl_flags->{'clm_start_type'} =~ /startup/ ) { + my $err_msg = "clm_start_type is startup so an initial conditions ($var) file is required,"; + if ( defined($use_init_interp_default) ) { + $log->fatal_error($err_msg." but can't find one without $useinitvar being set to true, change it to true in your user_nl_clm file in your case"); + } else { + my $set = "Relevent settings: use_cndv = ". $nl_flags->{'use_cndv'} . " phys = " . + $physv->as_string() . " hgrid = " . $nl_flags->{'res'} . " sim_year = " . + $settings{'sim_year'} . " lnd_tuning_mode = " . $nl_flags->{'lnd_tuning_mode'} . + "use_fates = " . $nl_flags->{'use_fates'}; + $log->fatal_error($err_msg." but the default setting of $useinitvar is false, so set both $var to a startup file and $useinitvar==TRUE, or developers should modify the namelist_defaults file".$set); + } } } else { my $stat = add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, "init_interp_attributes", @@ -2452,7 +2462,7 @@ SIMYR: foreach my $sim_yr ( @sim_years ) { 'hgrid'=>$nl_flags->{'res'}, 'use_cn'=>$nl_flags->{'use_cn'}, 'lnd_tuning_mode'=>$nl_flags->{'lnd_tuning_mode'}, 'nofail'=>1 ); if ( $stat ) { - $log->fatal_error("$useinitvar is NOT synchronized with init_interp_attributes"); + $log->fatal_error("$useinitvar is NOT synchronized with init_interp_attributes in the namelist_defaults file, this should be corrected there"); } my $attributes = $nl->get_value("init_interp_attributes"); my $attributes_string = remove_leading_and_trailing_quotes($attributes); @@ -2460,7 +2470,7 @@ SIMYR: foreach my $sim_yr ( @sim_years ) { if ( $pair =~ /^([a-z_]+)=([a-zA-Z._0-9]+)$/ ) { $settings{$1} = $2; } else { - $log->fatal_error("Problem interpreting init_interp_attributes: $pair"); + $log->fatal_error("Problem interpreting init_interp_attributes from the namelist_defaults file: $pair"); } } } @@ -2475,7 +2485,11 @@ SIMYR: foreach my $sim_yr ( @sim_years ) { } $finidat = $nl->get_value($var); if ( &value_is_true($nl->get_value($useinitvar) ) && string_is_undef_or_empty($finidat) ) { - $log->fatal_error("$useinitvar is set BUT $var is NOT, need to set both" ); + if ( ! defined($use_init_interp_default) ) { + $log->fatal_error("You set $useinitvar but a $var file could not be found for this case, try setting $var explicitly, and/or removing the setting for $useinitvar" ); + } else { + $log->fatal_error("$useinitvar is being set for you but a $var was not found, so $useinitvar, init_interp_attributes, and finidat must not be set correctly for this configuration in the namelist_default file" ); + } } } # end initial conditions From 4da8042896ba493381d91fb3cc779458b6045c28 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 2 Oct 2023 16:19:14 -0600 Subject: [PATCH 356/614] Repeat clm5_0_cam6.0 finidat files for clm5_1_cam6.0, this gets more namelist tests to pass --- bld/namelist_files/namelist_defaults_ctsm.xml | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index c546a9a866..34decf8edf 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -987,6 +987,14 @@ attributes from the config_cache.xml file (with keys converted to upper-case). lnd_tuning_mode="clm5_1_GSWP3v1" >lnd/clm2/initdata_map/clmi.I1850Clm50BgcCrop-ciso.1366-01-01.0.9x1.25_gx1v7_simyr1850_c200428.nc + +lnd/clm2/initdata_map/clmi.B1850Clm50BgcCrop.0161-01-01.0.9x1.25_gx1v7_simyr1850_c200729.nc + + + lnd/clm2/initdata_map/clmi.FHISTSp.2013-01-01.ne0CONUSne30x8_mt12_simyr2013_c200806.nc + +lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.0.9x1.25_gx1v7_simyr1979_c200806.nc + + +lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.1.9x2.5_gx1v7_simyr1979_c200806.nc + + + +lnd/clm2/initdata_map/clmi.FHISTSp.1979-01-01.ARCTIC_ne30x4_mt12_simyr1979_c200806.nc + + + +lnd/clm2/initdata_map/clmi.FHISTSp.1979-01-01.ARCTICGRIS_ne30x8_mt12_simyr1979_c200806.nc + + + +lnd/clm2/initdata_map/clmi.F2000.2000-01-01.ne120pg3_mt13_simyr2000_c200728.nc + + + +lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.0.9x1.25_gx1v7_simyr2000_c200728.nc + + + +lnd/clm2/initdata_map/clmi.BHISTSp.2000-01-01.1.9x2.5_gx1v7_simyr2003_c200807.nc + + + + +lnd/clm2/initdata_map/clmi.FHISTSp.2013-01-01.ne0CONUSne30x8_mt12_simyr2013_c200806.nc + From d65a7ba0aacfa387f7a88b1b2a8bc832f9cf011f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 2 Oct 2023 17:22:26 -0600 Subject: [PATCH 357/614] Remove tests that are not expected to work --- bld/unit_testers/build-namelist_test.pl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index bacc69416d..26e94750ac 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,9 +163,9 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 2426; +my $ntests = 2394; if ( defined($opts{'compare'}) ) { - $ntests += 1686; + $ntests += 1662; } plan( tests=>$ntests ); @@ -1257,7 +1257,7 @@ sub cat_and_create_namelistinfile { print "==================================================\n"; # Check for ALL resolutions with CLM50SP -my @resolutions = ( "1x1_brazil", "1x1_numaIA", "1x1_smallvilleIA", "1x1_mexicocityMEX", "1x1_vancouverCAN", "1x1_urbanc_alpha", "5x5_amazon", "360x720cru", "0.125x0.125", "0.125nldas2", "10x15", "4x5", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne5np4.pg2", "ne16np4", "ne30np4", "ne30np4.pg3", "ne120np4.pg3", "ne0np4CONUS.ne30x8", "ne0np4.ARCTIC.ne30x4", "ne0np4.ARCTICGRIS.ne30x8", "C24", "C48", "C96", "mpasa480", "mpasa120" ); +my @resolutions = ( "1x1_brazil", "1x1_mexicocityMEX", "1x1_vancouverCAN", "1x1_urbanc_alpha", "5x5_amazon", "360x720cru", "0.125x0.125", "0.125nldas2", "10x15", "4x5", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne5np4.pg2", "ne16np4", "ne30np4", "ne30np4.pg3", "ne120np4.pg3", "ne0np4CONUS.ne30x8", "ne0np4.ARCTIC.ne30x4", "ne0np4.ARCTICGRIS.ne30x8", "C24", "C48", "C96", "mpasa480", "mpasa120" ); my @regional; foreach my $res ( @resolutions ) { chomp($res); @@ -1599,6 +1599,9 @@ sub cat_and_create_namelistinfile { foreach my $forc ( @forclist ) { foreach my $bgc ( "sp", "bgc" ) { my $lndtuningmode = "${phys}_${forc}"; + if ( $lndtuningmode eq "clm5_1_CRUv7" ) { + next; + } my $clmoptions = "-res $res -mask $mask -sim_year $simyr -envxml_dir . -lnd_tuning_mod $lndtuningmode -bgc $bgc"; &make_env_run( ); eval{ system( "$bldnml $clmoptions > $tempfile 2>&1 " ); }; From 7338e0171b3fad1fb7fa3efcf97f0b8e207bb831 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 2 Oct 2023 17:23:24 -0600 Subject: [PATCH 358/614] remove clm5_1_CRUv1 as for clm5_1 only the GSWP3 option should be chosen right now --- bld/namelist_files/namelist_definition_ctsm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 7d22867de0..ddc0215582 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -2052,7 +2052,7 @@ Land mask description + valid_values="clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_cam6.0,clm5_0_cam6.0,clm5_0_CRUv7,clm5_0_GSWP3v1,clm5_1_GSWP3v1,clm5_1_cam6.0"> General configuration of model version and atmospheric forcing to tune the model to run under. This sets the model to run with constants and initial conditions that were set to run well under the configuration of model version and atmospheric forcing. To run well constants would need to be changed From cea39d0b4891762979b6b0b54ac6b7ffdd214ff4 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 3 Oct 2023 11:03:21 -0600 Subject: [PATCH 359/614] Update tests to what we need to have in place, make SSP tests that are expected to work just SSP2-4.5, and others should fail --- bld/unit_testers/build-namelist_test.pl | 27 ++++++++++--------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 26e94750ac..5e030fee01 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,9 +163,9 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 2394; +my $ntests = 2425; if ( defined($opts{'compare'}) ) { - $ntests += 1662; + $ntests += 1683; } plan( tests=>$ntests ); @@ -188,7 +188,7 @@ sub cat_and_create_namelistinfile { my $mode = "-phys $phys"; &make_config_cache($phys); -my $DOMFILE = "$inputdata_rootdir/atm/datm7/domain.lnd.T31_gx3v7.090928.nc"; +my $DOMFILE = "$inputdata_rootdir/atm/datm7/domain.lnd.fv0.9x1.25_gx1v6.090309.nc"; my $real_par_file = "user_nl_ctsm_real_parameters"; my $bldnml = "../build-namelist -verbose -csmdata $inputdata_rootdir -configuration clm -structure standard -glc_nec 10 -no-note -output_reals $real_par_file"; if ( $opts{'test'} ) { @@ -259,7 +259,7 @@ sub cat_and_create_namelistinfile { # Exercise a bunch of options my $options = "-co2_ppmv 250 "; - $options .= " -res 0.9x1.25 -ssp_rcp SSP1-2.6 -envxml_dir ."; + $options .= " -res 10x15 -ssp_rcp SSP2-4.5 -envxml_dir ."; &make_env_run(); eval{ system( "$bldnml $options > $tempfile 2>&1 " ); }; @@ -321,7 +321,7 @@ sub cat_and_create_namelistinfile { # configuration, structure, irrigate, verbose, clm_demand, ssp_rcp, test, sim_year, use_case foreach my $options ( "-res 0.9x1.25 -configuration nwp", "-res 0.9x1.25 -structure fast", - "-res 0.9x1.25 -namelist '&a irrigate=.true./'", "-res 0.9x1.25 -verbose", "-res 0.9x1.25 -ssp_rcp SSP1-2.6", "-res 0.9x1.25 -test", "-res 0.9x1.25 -sim_year 1850", + "-res 0.9x1.25 -namelist '&a irrigate=.true./'", "-res 0.9x1.25 -verbose", "-res 0.9x1.25 -ssp_rcp SSP4-2.5", "-res 0.9x1.25 -test", "-res 0.9x1.25 -sim_year 1850", "-res 0.9x1.25 -namelist '&a use_lai_streams=.true.,use_soil_moisture_streams=.true./'", "-res 0.9x1.25 -use_case 1850_control", "-res 1x1pt_US-UMB -clm_usr_name 1x1pt_US-UMB -namelist '&a fsurdat=\"/dev/null\"/'", @@ -455,14 +455,12 @@ sub cat_and_create_namelistinfile { $mode = "-phys $phys"; &make_config_cache($phys); foreach my $options ( - "-bgc bgc -use_case 1850-2100_SSP1-2.6_transient -namelist '&a start_ymd=20100101/'", - "-bgc sp -use_case 1850-2100_SSP2-4.5_transient -namelist '&a start_ymd=18501223/'", - "-bgc bgc -use_case 1850-2100_SSP3-7.0_transient -namelist '&a start_ymd=20701029/'", + "--res 0.9x1.25 --bgc sp --use_case 1850-2100_SSP2-4.5_transient --namelist '&a start_ymd=18501223/'", "-bgc fates -use_case 2000_control -no-megan", "-bgc fates -use_case 20thC_transient -no-megan", "-bgc fates -use_case 1850_control -no-megan -namelist \"&a use_fates_sp=T, soil_decomp_method='None'/\"", "-bgc sp -use_case 2000_control -res 0.9x1.25 -namelist '&a use_soil_moisture_streams = T/'", - "-bgc bgc -use_case 1850-2100_SSP5-8.5_transient -namelist '&a start_ymd=19101023/'", + "--res 1.9x2.5 --bgc bgc --use_case 1850-2100_SSP2-4.5_transient --namelist '&a start_ymd=19101023/'", "-bgc bgc -use_case 2000_control -namelist \"&a fire_method='nofire'/\" -crop", "-res 0.9x1.25 -bgc sp -use_case 1850_noanthro_control -drydep -fire_emis", "-res 0.9x1.25 -bgc bgc -use_case 1850_noanthro_control -drydep -fire_emis -light_res 360x720", @@ -1382,10 +1380,8 @@ sub cat_and_create_namelistinfile { # cases; I'm not sure if it's actually important to test this with all # of the different use cases. my @glc_res = ( "0.9x1.25", "1.9x2.5" ); -my @use_cases = ( "1850-2100_SSP1-2.6_transient", +my @use_cases = ( "1850-2100_SSP2-4.5_transient", - "1850-2100_SSP3-7.0_transient", - "1850-2100_SSP5-8.5_transient", "1850_control", "2000_control", "2010_control", @@ -1441,9 +1437,8 @@ sub cat_and_create_namelistinfile { &cleanup(); } # Transient ssp_rcp scenarios that work -my @tran_res = ( "0.9x1.25", "1.9x2.5", "10x15" ); -foreach my $usecase ( "1850_control", "1850-2100_SSP5-8.5_transient", "1850-2100_SSP1-2.6_transient", "1850-2100_SSP3-7.0_transient", - "1850-2100_SSP2-4.5_transient" ) { +my @tran_res = ( "4x5", "0.9x1.25", "1.9x2.5", "10x15", "ne3np4.pg3", "ne30np4", "ne30np4.pg2", "C96", "mpasa120" ); +foreach my $usecase ( "1850_control", "1850-2100_SSP2-4.5_transient" ) { my $startymd = undef; if ( $usecase eq "1850_control") { $startymd = 18500101; @@ -1479,7 +1474,7 @@ sub cat_and_create_namelistinfile { &make_config_cache($phys); my $res = "0.9x1.25"; foreach my $usecase ( "1850-2100_SSP4-3.4_transient", "1850-2100_SSP5-3.4_transient", "1850-2100_SSP1-1.9_transient", - "1850-2100_SSP4-6.0_transient" ) { + "1850-2100_SSP4-6.0_transient", "1850-2100_SSP5-8.5_transient", "1850-2100_SSP1-2.6_transient", "1850-2100_SSP3-7.0_transient" ) { $options = "-res $res -bgc bgc -crop -use_case $usecase -envxml_dir . -namelist '&a start_ymd=20150101/'"; &make_env_run(); eval{ system( "$bldnml $options > $tempfile 2>&1 " ); }; From 04a58ce8876e12ab0aadb769b88f4d651d71304b Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 4 Oct 2023 08:29:53 -0600 Subject: [PATCH 360/614] Remove all but SSP2-4.5 transient creation, set subset datafiles to variables, so they can be modified in one place, make sure subset data files all work --- tools/mksurfdata_esmf/Makefile.data | 58 +++++++++-------------------- 1 file changed, 18 insertions(+), 40 deletions(-) diff --git a/tools/mksurfdata_esmf/Makefile.data b/tools/mksurfdata_esmf/Makefile.data index 0ae0270250..d9dec833f9 100644 --- a/tools/mksurfdata_esmf/Makefile.data +++ b/tools/mksurfdata_esmf/Makefile.data @@ -47,9 +47,16 @@ SUBSETDATA_1X1_SMALL := --lat 40.6878 --lon 267.0228 --site 1x1_smallvilleIA \ # NOTE: The 1850 smallvilleIA site is constructed to start with 100% natural vegetation, so we can test transition to crops SUBSETDATA_1X1_SMALL1850 := --lat 40.6878 --lon 267.0228 --site 1x1_smallvilleIA --dompft 13 --pctpft 100 -SUBSETDATA_1X1_MEXICOCITY := --lat 19.5 --lon 260.5 --site 1x1_mexicocityMEX --out-surface surfdata_1x1_mexicocityMEX_hist_78pfts_CMIP6_simyr2000.nc -SUBSETDATA_1X1_VANCOUVER := --lat 49.5 --lon 236.5 --site 1x1_vancouverCAN --out-surface surfdata_1x1_vancouverCAN_hist_78pfts_CMIP6_simyr2000.nc -SUBSETDATA_1X1_URBALPHA := --lat -37.7308 --lon 0 --site 1x1_urbanc_alpha --out-surface surfdata_1x1_urbanc_alpha_hist_78pfts_CMIP6_simyr2000.nc +MEXICOCITY_TMP_FNAME := surfdata_1x1_mexicocityMEX_hist_2000_78pfts.nc +MEXICOCITY_FNAME := surfdata_1x1_mexicocityMEX_hist_2000_78pfts_c$(CDATE).nc +VANCOUVER_TMP_FNAME := surfdata_1x1_vancouverCAN_hist_2000_78pfts.nc +VANCOUVER_FNAME := surfdata_1x1_vancouverCAN_hist_2000_78pfts_c$(CDATE).nc +URBALPHA_TMP_FNAME := surfdata_1x1_urbanc_alpha_hist_2000_78pfts.nc +URBALPHA_TMP2_FNAME := surfdata_1x1_urbanc_alpha_hist_2000_78pfts_tmp.nc +URBALPHA_FNAME := surfdata_1x1_urbanc_alpha_hist_2000_78pfts_c$(CDATE).nc +SUBSETDATA_1X1_MEXICOCITY := --lat 19.5 --lon 260.5 --site 1x1_mexicocityMEX --out-surface $(MEXICOCITY_TMP_FNAME) +SUBSETDATA_1X1_VANCOUVER := --lat 49.5 --lon 236.5 --site 1x1_vancouverCAN --out-surface $(VANCOUVER_TMP_FNAME) +SUBSETDATA_1X1_URBALPHA := --lat -37.7308 --lon 0 --site 1x1_urbanc_alpha --out-surface $(URBALPHA_TMP_FNAME) # f19 and f09 are standard resolutions, f10 is used for testing, f45 is used for FATES # ne30np4 is standard resolution for SE dycore in CAM, C96 is standard for fv3 dycore # The ne30np4 series (including pg2, pg3, pg4) are standard for SE dycore @@ -215,41 +222,12 @@ crop-global-transient-f05 : FORCE # # Crop with future scenarios # -crop-global-future : crop-global-SSP1-2.6 crop-global-SSP3-7.0 crop-global-SSP5-3.4 crop-global-SSP2-4.5 \ - crop-global-SSP1-1.9 crop-global-SSP4-3.4 crop-global-SSP4-6.0 crop-global-SSP5-8.5 - -crop-global-SSP1-2.6 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 - $(BATCHJOBS) $@.sh - -crop-global-SSP3-7.0 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 - $(BATCHJOBS) $@.sh - -crop-global-SSP5-3.4 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 - $(BATCHJOBS) $@.sh +crop-global-future : crop-global-SSP2-4.5 crop-global-SSP2-4.5 : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh -crop-global-SSP1-1.9 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 - $(BATCHJOBS) $@.sh - -crop-global-SSP4-3.4 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 - $(BATCHJOBS) $@.sh - -crop-global-SSP4-6.0 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 - $(BATCHJOBS) $@.sh - -crop-global-SSP5-8.5 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 - $(BATCHJOBS) $@.sh - # # urban # @@ -259,22 +237,22 @@ urban-present : mexicocity vancouver mexicocity : FORCE $(SUBSETDATA_POINT_URBAN) --create-surface $(SUBSETDATA_1X1_MEXICOCITY) - $(MODIFYSURF) modify_1x1_mexicocityMEX.cfg -i surfdata_1x1_mexicocityMEX_hist_78pfts_CMIP6_simyr2000.nc -o surfdata_1x1_mexicocityMEX_hist_78pfts_CMIP6_simyr2000_c$(CDATE).nc - $(RM) surfdata_1x1_mexicocityMEX_hist_78pfts_CMIP6_simyr2000.nc + $(MODIFYSURF) modify_1x1_mexicocityMEX.cfg -i $(MEXICOCITY_TMP_FNAME) -o $(MEXICOCITY_FNAME) + $(RM) $(MEXICOCITY_TMP_FNAME) vancouver : FORCE $(SUBSETDATA_POINT_URBAN) --create-surface $(SUBSETDATA_1X1_VANCOUVER) - $(MODIFYSURF) modify_1x1_vancouverCAN.cfg -i surfdata_1x1_vancouverCAN_hist_78pfts_CMIP6_simyr2000.nc -o surfdata_1x1_vancouverCAN_hist_78pfts_CMIP6_simyr2000_c$(CDATE).nc - $(RM) surfdata_1x1_vancouverCAN_hist_78pfts_CMIP6_simyr2000.nc + $(MODIFYSURF) modify_1x1_vancouverCAN.cfg -i $(VANCOUVER_TMP_FNAME) -o $(VANCOUVER_FNAME) + $(RM) $(VANCOUVER_TMP_FNAME) # NOTE(bja, 2015-01) skip abort on invalid data necessary as of 2015-01. See # /glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 urban-alpha : FORCE $(SUBSETDATA_POINT_URBAN) --create-surface $(SUBSETDATA_1X1_URBALPHA) # Set number of nlevurb dimension to 4 for this site - ncks -O --dmn nlevurb,0,3 -o surfdata_1x1_urbanc_alpha_hist_78pfts_CMIP6_simyr2000_tmp.nc surfdata_1x1_urbanc_alpha_hist_78pfts_CMIP6_simyr2000.nc - $(MODIFYSURF) modify_1x1_urbanc_alpha.cfg -i surfdata_1x1_urbanc_alpha_hist_78pfts_CMIP6_simyr2000_tmp.nc -o surfdata_1x1_urbanc_alpha_hist_78pfts_CMIP6_simyr2000_c$(CDATE).nc - $(RM) surfdata_1x1_urbanc_alpha_hist_78pfts_CMIP6_simyr2000.nc surfdata_1x1_urbanc_alpha_hist_78pfts_CMIP6_simyr2000_tmp.nc + ncks -O --dmn nlevurb,0,3 -o $(URBALPHA_TMP2_FNAME) $(URBALPHA_TMP_FNAME) + $(MODIFYSURF) modify_1x1_urbanc_alpha.cfg -i $(URBALPHA_TMP2_FNAME) -o $(URBALPHA_FNAME) + $(RM) $(URBALPHA_TMP_FNAME) $(URBALPHA_TMP2_FNAME) # # landuse timeseries with subset data From f42b54f7644c32ad750d034e9967b443589a920e Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 4 Oct 2023 15:16:58 -0600 Subject: [PATCH 361/614] Remove T42 and f05 as no longer needed --- tools/mksurfdata_esmf/Makefile.data | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/tools/mksurfdata_esmf/Makefile.data b/tools/mksurfdata_esmf/Makefile.data index d9dec833f9..0cd86e618a 100644 --- a/tools/mksurfdata_esmf/Makefile.data +++ b/tools/mksurfdata_esmf/Makefile.data @@ -70,13 +70,10 @@ FUTURE_RES = 0.9x1.25,1.9x2.5,10x15 TRANS_RES = 0.9x1.25,1.9x2.5,10x15,ne30np4,ne0np4ARCTICGRISne30x8,ne0np4ARCTICne30x4,ne0np4CONUSne30x8 # ne120np4 is for high resolution SE dycore, ne16 is for testing SE dycore -# T42 is for SCAM -# f05 is needed for running full chemistry model # nldas is for NWP working with WRF STANDARD = \ global-present \ - global-present-nldas \ - global-present-T42 + global-present-nldas TROPICS = \ crop-tropics-present \ @@ -125,11 +122,6 @@ global-present : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -# T42 is needed for SCAM -global-present-T42 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 - $(BATCHJOBS) $@.sh - global-present-nldas : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh @@ -166,10 +158,6 @@ crop-global-present-0.125 : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh -crop-global-present-f05 : FORCE - $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 - $(BATCHJOBS) $@.sh - crop-numa-present : FORCE $(SUBSETDATA_POINT_ALLLU) --create-surface $(SUBSETDATA_1X1_NUMAIA) @@ -199,10 +187,6 @@ crop-global-historical : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 03:00:00 $(BATCHJOBS) $@.sh -crop-global-historical-f05 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 06:00:00 - $(BATCHJOBS) $@.sh - crop-global-historical-ne120np4 : FORCE $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 06:00:00 $(BATCHJOBS) $@.sh @@ -215,10 +199,6 @@ crop-global-transient-ne120np4 : FORCE $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 06:00:00 $(BATCHJOBS) $@.sh -crop-global-transient-f05 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 06:00:00 - $(BATCHJOBS) $@.sh - # # Crop with future scenarios # From 18c3c7c9219d99b02c4aad2ae2ed116e50720400 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 4 Oct 2023 15:41:23 -0600 Subject: [PATCH 362/614] Update output file names according to #2073 --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index 167954ec4b..af2e6b2c6e 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -521,10 +521,10 @@ def main (): if run_type == 'transient': if ssp_rcp == 'none': landuse_fname = \ - f"landuse_timeseries_hist_{num_pft}pfts_simyr{start_year}-{end_year}.txt" + f"landuse_timeseries_hist_{start_year}-{end_year}_{num_pft}pfts.txt" else: landuse_fname = \ - f"landuse_timeseries_{ssp_rcp}_{num_pft}pfts_CMIP6_simyr{start_year}-{end_year}.txt" + f"landuse_timeseries_{ssp_rcp}_{start_year}-{end_year}_{num_pft}pfts.txt" with open(landuse_fname, "w", encoding='utf-8') as landuse_file: for year in range(start_year, end_year + 1): @@ -581,13 +581,12 @@ def main (): ssp_rcp_name = ssp_rcp if int(end_year) == int(start_year): fdyndat = '' - prefix = \ - f'surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}_c{time_stamp}.' else: fdyndat = \ - f'landuse.timeseries_{res}_{ssp_rcp_name}_{num_pft}_CMIP6_{start_year}-{end_year}_c{time_stamp}.nc' - prefix = \ - f'surfdata_{res}_{ssp_rcp_name}_{num_pft}pfts_CMIP6_{start_year}-{end_year}_c{time_stamp}.' + f'landuse.timeseries_{res}_{ssp_rcp_name}_{start_year}-{end_year}_{num_pft}_c{time_stamp}.nc' + + prefix = \ + f'surfdata_{res}_{ssp_rcp_name}_{start_year}_num_pft}pfts_c{time_stamp}.' nlfname = f'{prefix}namelist' fsurdat = f'{prefix}nc' From 7e02454d9074a87d5c8e40e62c4fabc76bdc14cb Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 4 Oct 2023 15:47:49 -0600 Subject: [PATCH 363/614] Remove T42 and f05 from jobscript script --- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 5a9833cadf..cc1c6247cf 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -12,7 +12,6 @@ valid_scenarios=["all", "standard", "global-present", - "global-present-T42", "global-present-nldas", "global-hist-4x5", "tropics", @@ -22,7 +21,6 @@ "crop-global-present-ne16np4", "crop-global-present-ne120np4", "crop-global-present-0.125", - "crop-global-present-f05", "crop-global-1850", "crop-global-1850-ne120np4", "crop-global-hist", @@ -123,7 +121,6 @@ def main (): target_list = [] if scenario == 'all': target_list = ["global-present", - "global-present-T42", "global-present-nldas", "global-hist-4x5", "crop-global-present", @@ -143,7 +140,6 @@ def main (): "crop-global-SSP5-8.5-other"] elif scenario == 'standard': target_list = ["global-present", - "global-present-T42", "global-present-nldas", "global-hist-4x5"] elif scenario == "crop": @@ -180,7 +176,6 @@ def main (): "ssp585_res" : ['C96','ne30np4','ne0np4.ARCTICGRIS.ne30x8', 'ne0np4.ARCTIC.ne30x4','ne0np4CONUS.ne30x8','ne120np4'], "4x5_res" : ['4x5'], - "T42_res" : ['T42'], "nldas_res" : ['0.125nldas2'], "5x5_amazon_res" : ['5x5_amazon'], "ne16np4_res" : ['ne16np4'], @@ -191,7 +186,6 @@ def main (): # Determine commands for each target list # -------------------------- dataset_dict={"global-present" : ("--start-year 2000 --end-year 2000 --nocrop --vic --res", "standard_res_no_crop"), - "global-present-T42" : ("--start-year 2000 --end-year 2000 --nocrop --vic --res", "T42_res"), "global-present-nldas" : ("--start-year 2000 --end-year 2000 --nocrop --vic --res", "nldas_res"), "global-hist-4x5" : ("--start-year 1850 --end-year 2015 --nocrop --res", "4x5_res"), "crop-tropics-present" : ("--start-year 2000 --end-year 2000 --res", "5x5_amazon_res"), From 87ba565d6a591135cd34b981361625ec8a52db0e Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 4 Oct 2023 18:00:21 -0600 Subject: [PATCH 364/614] Get the Makefile and the python script synchronized to do things in terms of low, medium(ne16), and high (ne120 and hi-res) resolutions --- tools/mksurfdata_esmf/Makefile.data | 76 +++++++++---------- .../gen_mksurfdata_jobscript_multi.py | 47 ++++++------ 2 files changed, 58 insertions(+), 65 deletions(-) diff --git a/tools/mksurfdata_esmf/Makefile.data b/tools/mksurfdata_esmf/Makefile.data index 0cd86e618a..5c4757f176 100644 --- a/tools/mksurfdata_esmf/Makefile.data +++ b/tools/mksurfdata_esmf/Makefile.data @@ -57,41 +57,33 @@ URBALPHA_FNAME := surfdata_1x1_urbanc_alpha_hist_2000_78pfts_c$(CDAT SUBSETDATA_1X1_MEXICOCITY := --lat 19.5 --lon 260.5 --site 1x1_mexicocityMEX --out-surface $(MEXICOCITY_TMP_FNAME) SUBSETDATA_1X1_VANCOUVER := --lat 49.5 --lon 236.5 --site 1x1_vancouverCAN --out-surface $(VANCOUVER_TMP_FNAME) SUBSETDATA_1X1_URBALPHA := --lat -37.7308 --lon 0 --site 1x1_urbanc_alpha --out-surface $(URBALPHA_TMP_FNAME) -# f19 and f09 are standard resolutions, f10 is used for testing, f45 is used for FATES -# ne30np4 is standard resolution for SE dycore in CAM, C96 is standard for fv3 dycore -# The ne30np4 series (including pg2, pg3, pg4) are standard for SE dycore -# The variable resolution grids for ARCTIC, ARCTICGRIS and CONUS are also standard -STANDARD_RES_NO_CROP = 0.9x1.25,1.9x2.5,10x15 -STANDARD_RES = 0.9x1.25,1.9x2.5,10x15,4x5,ne30np4,C96,ne30pg2,ne30pg3,ne30pg4,ne120np4pg3,ne0np4ARCTICGRISne30x8,ne0np4ARCTICne30x4,ne0np4CONUSne30x8,ne3np4.pg3,ne5np4.pg3,ne16np4.pg3,mpasa480,mpasa120 - -# For future CMIP6 scenarios: SSP-RCP's -FUTURE_RES = 0.9x1.25,1.9x2.5,10x15 -# For historical transient cases (TRY TO KEEP THIS LIST AS SHORT AS POSSIBLE) -TRANS_RES = 0.9x1.25,1.9x2.5,10x15,ne30np4,ne0np4ARCTICGRISne30x8,ne0np4ARCTICne30x4,ne0np4CONUSne30x8 - -# ne120np4 is for high resolution SE dycore, ne16 is for testing SE dycore + +# ne120np4 and hi-res are for high resolution, ne16 is for mid-resolution testing +# low-res is for low resolutions for testing # nldas is for NWP working with WRF STANDARD = \ global-present \ + global-present-low-res \ global-present-nldas TROPICS = \ - crop-tropics-present \ - crop-tropics-historical \ - crop-tropics-transient + crop-tropics-present CROP = \ crop-global-present \ + crop-global-present-low-res \ crop-global-present-ne16np4 \ crop-global-present-ne120np4 \ + crop-global-1850 \ + crop-global-1850-low-res \ + crop-global-1850-ne16np4 \ + crop-global-1850-ne120np4 \ crop-numa-present \ crop-numa-historical \ crop-smallville \ crop-smallville-historical \ - crop-global-historical \ - crop-global-transient \ crop-global-future -all : standard tropics crop urban landuse-timeseries +all : standard tropics crop urban landuse-timeseries all-subset all-subset : \ 1x1_brazil-tropics-present \ @@ -122,6 +114,10 @@ global-present : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh +global-present-low-res : FORCE + $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + global-present-nldas : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh @@ -131,14 +127,13 @@ global-present-nldas : FORCE # tropics : $(TROPICS) -crop-tropics-present : 1x1_brazil-tropics-present - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 +crop-tropics-present : FORCE + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh 1x1_brazil-tropics-present : FORCE $(SUBSETDATA_POINT_ALLLU) --create-surface $(SUBSETDATA_1X1_BRAZIL) - crop-tropics-historical : FORCE $(SUBSETDATA_POINT_ALLLU) --create-surface $(SUBSETDATA_1X1_BRAZIL) --cfg-file default_data_1850.cfg @@ -151,9 +146,17 @@ crop-tropics-transient : FORCE crop : $(CROP) crop-global-present : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + +crop-global-present-ne16 : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh +crop-global-present-ne120 : FORCE + $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + crop-global-present-0.125 : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh @@ -168,7 +171,7 @@ crop-smallville : FORCE $(SUBSETDATA_POINT) --create-surface $(SUBSETDATA_1X1_SMALL) crop-global-present-ne16np4 : FORCE - $(MKSURFDATA) --number-of-nodes 12 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-present-ne120np4 : FORCE @@ -182,32 +185,23 @@ crop-global-present-ne120np4 : FORCE crop-smallville-historical : FORCE $(SUBSETDATA_POINT) --create-surface $(SUBSETDATA_1X1_SMALL1850) --cfg-file default_data_1850.cfg -# Setup the historical case for SSP5-8.5 so that historical can be used to go into the future. -crop-global-historical : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 03:00:00 - $(BATCHJOBS) $@.sh - -crop-global-historical-ne120np4 : FORCE - $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 06:00:00 - $(BATCHJOBS) $@.sh - -crop-global-transient: FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 03:00:00 - $(BATCHJOBS) $@.sh - -crop-global-transient-ne120np4 : FORCE - $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 06:00:00 - $(BATCHJOBS) $@.sh - # # Crop with future scenarios # -crop-global-future : crop-global-SSP2-4.5 +crop-global-future : crop-global-SSP2-4.5 crop-global-SSP2-4.5-low-res crop-global-SSP2-4.5-hi-res crop-global-SSP2-4.5 : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh +crop-global-SSP2-4.5-low-res : FORCE + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 + $(BATCHJOBS) $@.sh + +crop-global-SSP2-4.5-hi-res : FORCE + $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 + $(BATCHJOBS) $@.sh + # # urban # diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index cc1c6247cf..1206359ebe 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -12,9 +12,9 @@ valid_scenarios=["all", "standard", "global-present", + "global-present-low-res", "global-present-nldas", "global-hist-4x5", - "tropics", "crop-tropics-present", "crop", "crop-global-present", @@ -29,6 +29,8 @@ "crop-global-SSP3-7.0", "crop-global-SSP5-3.4", "crop-global-SSP2-4.5", + "crop-global-SSP2-4.5-low-res", + "crop-global-SSP2-4.5-hi-res", "crop-global-SSP1-1.9", "crop-global-SSP4-3.4", "crop-global-SSP4-6.0", @@ -121,11 +123,7 @@ def main (): target_list = [] if scenario == 'all': target_list = ["global-present", - "global-present-nldas", - "global-hist-4x5", "crop-global-present", - "crop-global-present-ne16np4", - "crop-global-present-ne120np4", "crop-global-1850", "crop-global-hist", "crop-tropics-present", @@ -136,16 +134,13 @@ def main (): "crop-global-SSP1-1.9", "crop-global-SSP4-3.4", "crop-global-SSP4-6.0", - "crop-global-SSP5-8.5", - "crop-global-SSP5-8.5-other"] + "crop-global-SSP5-8.5"], elif scenario == 'standard': target_list = ["global-present", "global-present-nldas", - "global-hist-4x5"] + ], elif scenario == "crop": target_list = ["crop-global-present", - "crop-global-present-ne16np4", - "crop-global-present-ne120np4", "crop-global-1850", "crop-global-hist"] elif scenario == "crop-global-future": @@ -167,44 +162,48 @@ def main (): # Determine resolution sets that are referenced in commands # -------------------------- resolution_dict = { - "standard_res_no_crop" : ["0.9x1.25","1.9x2.5","10x15","4x5"], - "most_res" : ['0.9x1.25','1.9x2.5','10x15','4x5','C96', - 'ne30np4','ne30np4.pg2','ne30np4.pg3','ne30np4.pg4','ne120np4.pg3', - 'ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4', 'ne0np4CONUS.ne30x8', - 'ne3np4.pg3','ne5np4.pg3','ne16np4.pg3','mpasa480','mpasa120'], - "standard_res" : ["0.9x1.25","1.9x2.5","10x15"], - "ssp585_res" : ['C96','ne30np4','ne0np4.ARCTICGRIS.ne30x8', - 'ne0np4.ARCTIC.ne30x4','ne0np4CONUS.ne30x8','ne120np4'], - "4x5_res" : ['4x5'], + "standard_res_no_crop" : ["0.9x1.25","1.9x2.5"], + "low_res_no_crop" : ["10x15"], + "low_res_all" : ['10x15', 'ne3np4.pg3'], + "hi_res_all" : ['ne120np4.pg3'], + "standard_res" : ['0.9x1.25','1.9x2.5','C96', 'ne30np4.pg3', 'mpasa120'], + "low_res" : ['10x15', '4x5', 'ne3np4.pg3', 'ne5np4.pg3', 'C24', 'mpasa480'], + "4x5_res" : ['10x15', '4x5', 'C24', 'mpasa480'], "nldas_res" : ['0.125nldas2'], "5x5_amazon_res" : ['5x5_amazon'], - "ne16np4_res" : ['ne16np4'], - "ne120np4_res" : ['ne120np4'], + "ne16np4_res" : ['C48', 'ne16np4'], + "ne120np4_res" : ['ne120np4.pg3', + 'ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4', 'ne0np4CONUS.ne30x8'], } # -------------------------- # Determine commands for each target list # -------------------------- dataset_dict={"global-present" : ("--start-year 2000 --end-year 2000 --nocrop --vic --res", "standard_res_no_crop"), + "global-present-low-res" : ("--start-year 2000 --end-year 2000 --nocrop --vic --res", "low_res_no_crop"), "global-present-nldas" : ("--start-year 2000 --end-year 2000 --nocrop --vic --res", "nldas_res"), "global-hist-4x5" : ("--start-year 1850 --end-year 2015 --nocrop --res", "4x5_res"), "crop-tropics-present" : ("--start-year 2000 --end-year 2000 --res", "5x5_amazon_res"), - "crop-global-present" : ("--start-year 2000 --end-year 2000 --res", "most_res"), + "crop-global-present" : ("--start-year 2000 --end-year 2000 --res", "standard_res"), + "crop-global-present-low-res" : ("--start-year 2000 --end-year 2000 --res", "low_res"), "crop-global-present-ne16np4" : ("--start-year 2000 --end-year 2000 --res", "ne16np4_res"), "crop-global-present-ne120np4" : ("--start-year 2000 --end-year 2000 --res", "ne120np4_res"), "crop-global-present-0.125" : ("--start-year 2000 --end-year 2000 --hirespft --res", "nldas_res"), - "crop-global-1850" : ("--start-year 1850 --end-year 1850 --res", "most_res"), + "crop-global-1850" : ("--start-year 1850 --end-year 1850 --res", "standard_res"), + "crop-global-1850-low-res" : ("--start-year 1850 --end-year 1850 --res", "low_res"), + "crop-global-1850-ne16np4" : ("--start-year 1850 --end-year 1850 --res", "ne16np4_res"), "crop-global-1850-ne120np4" : ("--start-year 1850 --end-year 1850 --res", "ne120np4_res"), "crop-global-hist" : ("--start-year 1850 --end-year 2015 --nosurfdata --res", "standard_res"), "crop-global-SSP1-1.9" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-1.9 --res", "standard_res"), "crop-global-SSP1-2.6" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-2.6 --res", "standard_res"), "crop-global-SSP2-4.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", "standard_res"), + "crop-global-SSP2-4.5-low-res" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", "low_res_all"), + "crop-global-SSP2-4.5-hi-res" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", "hi_res_all"), "crop-global-SSP3-7.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP3-7.0 --res", "standard_res"), "crop-global-SSP4-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-3.4 --res", "standard_res"), "crop-global-SSP4-6.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-6.0 --res", "standard_res"), "crop-global-SSP5-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-3.4 --res", "standard_res"), "crop-global-SSP5-8.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-8.5 --res", "standard_res"), - "crop-global-SSP5-8.5-other" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-8.5 --res", "ssp585_res") } # -------------------------- From 664b9d84b14888fe8df67888062c8aca3bb5ff31 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 4 Oct 2023 18:07:09 -0600 Subject: [PATCH 365/614] Fix syntax error --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py index af2e6b2c6e..d18e96f939 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py @@ -586,7 +586,7 @@ def main (): f'landuse.timeseries_{res}_{ssp_rcp_name}_{start_year}-{end_year}_{num_pft}_c{time_stamp}.nc' prefix = \ - f'surfdata_{res}_{ssp_rcp_name}_{start_year}_num_pft}pfts_c{time_stamp}.' + f'surfdata_{res}_{ssp_rcp_name}_{start_year}_{num_pft}pfts_c{time_stamp}.' nlfname = f'{prefix}namelist' fsurdat = f'{prefix}nc' From f4d616cd635bcb7eaa3eabe273efff4685de3214 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 4 Oct 2023 19:18:17 -0600 Subject: [PATCH 366/614] Get makefile working for all, and make sure all needed recipes can be made --- tools/mksurfdata_esmf/Makefile.data | 32 ++++++++++++++----- .../gen_mksurfdata_jobscript_multi.py | 3 ++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/tools/mksurfdata_esmf/Makefile.data b/tools/mksurfdata_esmf/Makefile.data index 5c4757f176..7ccac6982b 100644 --- a/tools/mksurfdata_esmf/Makefile.data +++ b/tools/mksurfdata_esmf/Makefile.data @@ -58,7 +58,7 @@ SUBSETDATA_1X1_MEXICOCITY := --lat 19.5 --lon 260.5 --site 1x1_mexicocityMEX -- SUBSETDATA_1X1_VANCOUVER := --lat 49.5 --lon 236.5 --site 1x1_vancouverCAN --out-surface $(VANCOUVER_TMP_FNAME) SUBSETDATA_1X1_URBALPHA := --lat -37.7308 --lon 0 --site 1x1_urbanc_alpha --out-surface $(URBALPHA_TMP_FNAME) -# ne120np4 and hi-res are for high resolution, ne16 is for mid-resolution testing +# ne120np4 and hi-res are for high resolution, ne16np4 is for mid-resolution testing # low-res is for low resolutions for testing # nldas is for NWP working with WRF STANDARD = \ @@ -78,10 +78,6 @@ CROP = \ crop-global-1850-low-res \ crop-global-1850-ne16np4 \ crop-global-1850-ne120np4 \ - crop-numa-present \ - crop-numa-historical \ - crop-smallville \ - crop-smallville-historical \ crop-global-future all : standard tropics crop urban landuse-timeseries all-subset @@ -149,7 +145,11 @@ crop-global-present : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -crop-global-present-ne16 : FORCE +crop-global-present-low-res : FORCE + $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + +crop-global-present-ne16np4 : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh @@ -157,6 +157,22 @@ crop-global-present-ne120 : FORCE $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh +crop-global-1850 : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + +crop-global-1850-low-res : FORCE + $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + +crop-global-1850-ne16np4 : FORCE + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + +crop-global-1850-ne120np4 : FORCE + $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + crop-global-present-0.125 : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh @@ -231,9 +247,9 @@ urban-alpha : FORCE # # landuse timeseries with subset data # -#landuse-timeseries : landuse-timeseries-smallville +landuse-timeseries : landuse-timeseries-smallville # NOTE: TODO: This needs to be chagned to use subset_data when transient configurations are resolved (see Issue #1673 -#landuse-timeseries-smallville : FORCE +landuse-timeseries-smallville : FORCE # $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-1855 -r 1x1_smallvilleIA \ # -pft_idx 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78 \ # -pft_frc 6.5,1.5,1.6,1.7,1.8,1.9,1.5,1.6,1.7,1.8,1.9,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5 \ diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 1206359ebe..4db49941ab 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -18,10 +18,13 @@ "crop-tropics-present", "crop", "crop-global-present", + "crop-global-present-low-res", "crop-global-present-ne16np4", "crop-global-present-ne120np4", "crop-global-present-0.125", "crop-global-1850", + "crop-global-1850-low-res", + "crop-global-1850-ne16np4", "crop-global-1850-ne120np4", "crop-global-hist", "crop-global-future", From ba81bea711f9837cb28d4b38659a125f05d66981 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 6 Oct 2023 17:15:07 -0600 Subject: [PATCH 367/614] Add error checking to jobs scripts --- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py | 7 ++++++- tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 4db49941ab..05f8a07b42 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -267,8 +267,13 @@ def main (): print (f"generated namelist {namelist}") output = f"mpiexec_mpt -p \"%g:\" -np {n_p} omplace -tm open64 {mksurfdata} < {namelist}" runfile.write(f"{output} \n") + check = f"if [ $? != 0 ]; then echo 'Error running resolution {res}'; exit -4; fi" + runfile.write(f"{check} \n") + runfile.write(f"Successfully ran resolution {res}\n") - print (f"Successfully created jobscript {jobscript_file}") + runfile.write(f"Successfully ran {jobscript_file}\n") + + print (f"Successfully created jobscript {jobscript_file}\n") sys.exit(0) if __name__ == "__main__": diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index 01e290a8c5..851d2ab29d 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -173,7 +173,11 @@ def main (): runfile.write(f"{output} \n") logger.info('run command is %s', output) - print (f"Successfully created jobscript {jobscript_file}") + check = f'if [ $? != 0 ]; then echo "Error running resolution {res}"; exit -4; fi' + runfile.write(f"{check} \n") + runfile.write(f"Successfully ran resolution\n") + + print (f"Successfully created jobscript {jobscript_file}\n") sys.exit(0) if __name__ == "__main__": From bfa1112caeea368bb796f391263e7031ebfc16cd Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 6 Oct 2023 17:15:48 -0600 Subject: [PATCH 368/614] Rename Makefile.data so that we don't have to name it on the make command --- tools/mksurfdata_esmf/{Makefile.data => Makefile} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tools/mksurfdata_esmf/{Makefile.data => Makefile} (100%) diff --git a/tools/mksurfdata_esmf/Makefile.data b/tools/mksurfdata_esmf/Makefile similarity index 100% rename from tools/mksurfdata_esmf/Makefile.data rename to tools/mksurfdata_esmf/Makefile From 30f9af7ea4692bb5822e9615b1debb120cfa82e5 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 6 Oct 2023 17:27:14 -0600 Subject: [PATCH 369/614] Remove duplicated recipes and correct name of a recipe --- tools/mksurfdata_esmf/Makefile | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index 7ccac6982b..c9953a5a8e 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -153,7 +153,7 @@ crop-global-present-ne16np4 : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -crop-global-present-ne120 : FORCE +crop-global-present-ne120np4 : FORCE $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh @@ -186,14 +186,6 @@ crop-numa-historical : FORCE crop-smallville : FORCE $(SUBSETDATA_POINT) --create-surface $(SUBSETDATA_1X1_SMALL) -crop-global-present-ne16np4 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 - $(BATCHJOBS) $@.sh - -crop-global-present-ne120np4 : FORCE - $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 03:00:00 - $(BATCHJOBS) $@.sh - # Note that the smallville 1850 dataset is entirely natural vegetation. This # facilitates testing a transient case that starts with no crop, and then later # adds crop (to make sure that it works properly to add crop in a grid cell From 5cc6b237334e01d4f2fa518dc1042521b795a840 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 6 Oct 2023 22:02:44 -0600 Subject: [PATCH 370/614] Number of nodes for 5x5_amazon case needs to be 2 (2x12=24) so it's smaller than the grid size of 25 (5x5) --- tools/mksurfdata_esmf/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index c9953a5a8e..d5f86cd822 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -124,7 +124,7 @@ global-present-nldas : FORCE tropics : $(TROPICS) crop-tropics-present : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh 1x1_brazil-tropics-present : FORCE From 92cc9b6278e30f3bb41bd0d0840a67fa09b962d4 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sun, 8 Oct 2023 16:22:37 -0600 Subject: [PATCH 371/614] Add more flush statements to assess ongoing progress in case of an early abort, add success message on landuse.timeseries (Fixing #2131), read in namelist before MPI and ESMF initialize so can set default name for PET files, and split out namelist broadcast to a seperate call --- tools/mksurfdata_esmf/src/mkinputMod.F90 | 30 +++++- tools/mksurfdata_esmf/src/mksurfdata.F90 | 112 +++++++++++++++++++++-- tools/mksurfdata_esmf/src/mkvarctl.F90 | 2 +- 3 files changed, 132 insertions(+), 12 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkinputMod.F90 b/tools/mksurfdata_esmf/src/mkinputMod.F90 index 465d653313..3922420cb0 100644 --- a/tools/mksurfdata_esmf/src/mkinputMod.F90 +++ b/tools/mksurfdata_esmf/src/mkinputMod.F90 @@ -18,9 +18,10 @@ module mkinputMod ! routines ! --------------------- - public :: read_namelist_input - public :: check_namelist_input - public :: write_namelist_input + public :: read_namelist_input ! Read the input control namelist + public :: bcast_namelist_input ! Broadcast the namelist to all processors + public :: check_namelist_input ! Check the input control namelist for errors + public :: write_namelist_input ! Write information on the control namelist ! --------------------- ! variables @@ -34,6 +35,8 @@ module mkinputMod character(CL) , public :: furbname ! generic transient urban land cover filename character(CL) , public :: flakname ! generic lake filename + character(CS) , public :: mksrf_grid_name = ' ' ! Name of this grid + character(CX) , public :: mksrf_fgrid_mesh = ' ' ! land grid file name to use integer , public :: mksrf_fgrid_mesh_nx = -999 integer , public :: mksrf_fgrid_mesh_ny = -999 @@ -126,11 +129,13 @@ subroutine read_namelist_input() integer :: ier integer :: k integer :: fileunit + integer :: grid_size ! Number of columne in the grid logical :: lexist character(len=*), parameter :: subname = 'read_namelist_input' ! ------------------------------------------------------------ namelist /mksurfdata_input/ & + mksrf_grid_name, & mksrf_fvegtyp, & mksrf_fvegtyp_mesh, & mksrf_fhrvtyp, & @@ -213,6 +218,21 @@ subroutine read_namelist_input() call shr_sys_abort(subname//' error reading in mksurfdata_input namelist from standard input') end if end if + if ( mksrf_grid_name == ' ' )then + grid_size = mksrf_fgrid_mesh_nx * mksrf_fgrid_mesh_ny + write(mksrf_grid_name,'("Grid",I07)') grid_size + end if + + end subroutine read_namelist_input + + !=============================================================== + + subroutine bcast_namelist_input() + + ! Braodcast the namelist to all processors + + ! local variables + integer :: ier call mpi_bcast (mksrf_fgrid_mesh, len(mksrf_fgrid_mesh), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fgrid_mesh_nx, 1, MPI_INTEGER, 0, mpicom, ier) @@ -301,7 +321,7 @@ subroutine read_namelist_input() call mpi_bcast (logname, len(logname), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (hostname, len(hostname), MPI_CHARACTER, 0, mpicom, ier) - end subroutine read_namelist_input + end subroutine bcast_namelist_input !=============================================================== subroutine check_namelist_input() @@ -338,6 +358,7 @@ subroutine write_namelist_input() ! ------------------------------------------------------------ if (root_task) then + write(ndiag,'(a)')'Grid_name: '//trim(mksrf_grid_name) write(ndiag,'(a)')'Input rawdata files and corresponding meshes' write(ndiag,'(a)')' PFTs from: '//trim(mksrf_fvegtyp) write(ndiag,'(a)')' mesh for pft '//trim(mksrf_fvegtyp_mesh) @@ -434,6 +455,7 @@ subroutine write_namelist_input() write(ndiag, '(a)') " WARNING: aborting on invalid data check in urban has been disabled!" write(ndiag, '(a)') " WARNING: urban data may be invalid!" end if + flush(ndiag) end if end subroutine write_namelist_input diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index ace3999f0f..6c04e9b9c0 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -189,6 +189,7 @@ program mksurfdata logical :: create_esmf_pet_files = .false. ! character variables + character(len=CL) :: default_log_suffix ! default log file suffix to use for ESMF PET files character(len=CL) :: string ! string read in character(len=CL) :: fname character(len=*), parameter :: subname = 'mksrfdata' ! program name @@ -196,6 +197,11 @@ program mksurfdata character(len=*), parameter :: u_FILE_u = & __FILE__ + ! ====================================================================== + ! Read in namelist before initializing MPI or ESMF + ! ====================================================================== + call read_namelist_input() + ! ====================================================================== ! Initialize MPI ! ====================================================================== @@ -212,8 +218,9 @@ program mksurfdata else logkindflag = ESMF_LOGKIND_MULTI_ON_ERROR end if + default_log_suffix = mksrf_grid_name // 'ESMF_LogFile' call ESMF_Initialize(mpiCommunicator=MPICOM, logkindflag=logkindflag, logappendflag=.false., & - ioUnitLBound=5001, ioUnitUBound=5101, vm=vm, rc=rc) + defaultDefaultLogFilename=mksrf_grid_name, ioUnitLBound=5001, ioUnitUBound=5101, vm=vm, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_VMGetGlobal(vm, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() @@ -252,13 +259,9 @@ program mksurfdata call ESMF_LogWrite("finished initializing PIO", ESMF_LOGMSG_INFO) - ! ====================================================================== - ! Read in namelist - ! ====================================================================== - - ! Read input namelist on root_task and broadcast to all pes + ! Broadcast namelist to all pes ! root_task is a module variable in mkvarctl - call read_namelist_input() + call bcast_namelist_input() ! open output ndiag file if (fsurlog == ' ') then @@ -271,6 +274,7 @@ program mksurfdata end if write (ndiag,'(a)') 'Attempting to create surface boundary data .....' write (ndiag,'(72a1)') ("-",n=1,60) + flush(ndiag) else ndiag = 6 end if @@ -316,6 +320,7 @@ program mksurfdata if (root_task)then write(ndiag,*) write(ndiag,'(1x,80a1)') ('=',k=1,80) + flush(ndiag) end if ! Open file @@ -359,9 +364,11 @@ program mksurfdata if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing out model grid" if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" + if (root_task) flush(ndiag) call mkfile_output(pioid, mesh_model, 'LONGXY', lon, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for LONGXY') if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LATIXY" + if (root_task) flush(ndiag) call mkfile_output(pioid, mesh_model, 'LATIXY', lat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for LATIXY') call pio_syncfile(pioid) @@ -373,6 +380,7 @@ program mksurfdata ! ----------------------------------- if (fsurdat /= ' ') then call mklai(mksrf_flai_mesh, mksrf_flai, mesh_model, pioid, rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklai') end if @@ -387,6 +395,7 @@ program mksurfdata allocate(landfrac_pft(lsize_o)) ; landfrac_pft(:) = spval call mkpft( mksrf_fvegtyp_mesh, mksrf_fvegtyp, mesh_model, & pctlnd_o=pctlnd_pft, pctnatpft_o=pctnatpft, pctcft_o=pctcft, rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') do n = 1,lsize_o @@ -394,6 +403,7 @@ program mksurfdata end do if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing land fraction from pft dataset" + if (root_task) flush(ndiag) call mkfile_output(pioid, mesh_model, 'LANDFRAC_PFT', landfrac_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') call pio_syncfile(pioid) @@ -407,6 +417,7 @@ program mksurfdata if (fsurdat /= ' ') then call mkharvest( mksrf_fhrvtyp_mesh, mksrf_fhrvtyp, mesh_model, pioid, & rc=rc ) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest_init') end if @@ -419,14 +430,17 @@ program mksurfdata allocate ( pctlak_max(lsize_o)) ; pctlak_max(:) = spval call mkpctlak(mksrf_fpctlak_mesh, mksrf_fpctlak, mesh_model, pctlak, pioid, & rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpctlak') call mklakdep(mksrf_flakdep_mesh, mksrf_flakdep, mesh_model, pioid, fsurdat, & rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklakdep') allocate ( pctwet(lsize_o)) ; pctwet(:) = spval allocate ( pctwet_orig(lsize_o)) ; pctwet_orig(:) = spval call mkwetlnd(mksrf_fwetlnd_mesh, mksrf_fwetlnd, mesh_model, pctwet, rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkwetlnd') ! ----------------------------------- @@ -435,6 +449,7 @@ program mksurfdata allocate (pctgla(lsize_o)) ; pctgla(:) = spval allocate (pctgla_orig(lsize_o)) ; pctgla_orig(:) = spval call mkglacier (mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, glac_o=pctgla, rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacier') ! ----------------------------------- @@ -443,6 +458,7 @@ program mksurfdata if (fsurdat /= ' ') then ! GLACIER_REGION is written out in the subroutine call mkglacierregion(mksrf_fglacierregion_mesh, mksrf_fglacierregion, mesh_model, pioid, rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglacierregion') end if @@ -452,6 +468,7 @@ program mksurfdata if (fsurdat /= ' ') then call mksoiltex( mksrf_fsoitex_mesh, file_mapunit_i=mksrf_fsoitex, file_lookup_i=mksrf_fsoitex_lookup, & mesh_o=mesh_model, pioid_o=pioid, rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoiltex') end if @@ -461,6 +478,7 @@ program mksurfdata if (fsurdat /= ' ') then ! SOIL_COLOR and mxsoil_color is written out in the subroutine call mksoilcol( mksrf_fsoicol, mksrf_fsoicol_mesh, mesh_model, pioid, rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilcol') end if @@ -470,6 +488,7 @@ program mksurfdata if (fsurdat /= ' ') then ! FMAX is written out in the subroutine call mksoilfmax( mksrf_fmax_mesh, mksrf_fmax, mesh_model, pioid, rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoilfmax') end if @@ -479,6 +498,7 @@ program mksurfdata if (fsurdat /= ' ') then ! gdp is written out in the subroutine call mkgdp (mksrf_fgdp_mesh, mksrf_fgdp, mesh_model, pioid, rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkdomain') end if @@ -487,6 +507,7 @@ program mksurfdata ! ----------------------------------- if (fsurdat /= ' ') then call mkpeat (mksrf_fpeat_mesh, mksrf_fpeat, mesh_model, pioid, rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpeat') end if @@ -495,6 +516,7 @@ program mksurfdata ! ----------------------------------- if (fsurdat /= ' ') then call mksoildepth( mksrf_fsoildepth_mesh, mksrf_fsoildepth, mesh_model, pioid, rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mksoildepth') end if @@ -503,6 +525,7 @@ program mksurfdata ! ----------------------------------- if (fsurdat /= ' ') then call mkagfirepkmon (mksrf_fabm_mesh, mksrf_fabm, mesh_model, pioid, rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkagfirepkmon') end if @@ -515,9 +538,11 @@ program mksurfdata allocate (urban_region(lsize_o)) ; urban_region(:) = -999 call mkurban(mksrf_furban_mesh, mksrf_furban, mesh_model, pcturb, & urban_classes, urban_region, rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing out urban region id" + if (root_task) flush(ndiag) call mkfile_output(pioid, mesh_model, 'URBAN_REGION_ID', urban_region, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') call pio_syncfile(pioid) @@ -534,6 +559,7 @@ program mksurfdata ! TODO(wjs, 2016-01-15) A better solution for this urban screening would probably ! be to modify the raw urban data; in that case, I believe we could remove furbtopo. call mkurban_topo ( mksrf_furbtopo_mesh, mksrf_furbtopo, mesh_model, varname='TOPO_ICE', elev_o=elev, rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban_topo') where (elev > elev_thresh) pcturb = 0._r8 @@ -545,6 +571,7 @@ program mksurfdata if (fsurdat /= ' ') then call mktopostats ( mksrf_ftopostats_mesh, mksrf_ftopostats, mksrf_ftopostats_override, & mesh_model, pioid, rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mktopostats') end if @@ -554,6 +581,7 @@ program mksurfdata if (fsurdat /= ' ') then if (outnc_vic) then call mkVICparams ( mksrf_fvic_mesh, mksrf_fvic, mesh_model, pioid, rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkVICparams') end if end if @@ -563,6 +591,7 @@ program mksurfdata ! ----------------------------------- if (fsurdat /= ' ') then call mkvocef ( mksrf_fvocef_mesh, mksrf_fvocef, mesh_model, pioid, lat, rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkvocef') end if @@ -591,6 +620,7 @@ program mksurfdata call mpi_reduce(loc_suma, glob_suma, 1, MPI_REAL8, MPI_SUM, 0, mpicom, ier) if (root_task) then write(ndiag,*) 'sum over domain of pft ',k,glob_suma + flush(ndiag) end if enddo if (root_task) write(ndiag,*) @@ -605,18 +635,21 @@ program mksurfdata end if enddo if (root_task) write(ndiag,*) + if (root_task) flush(ndiag) ! Make final values of percent urban by class and compute urban parameters ! This call needs to occur after all corrections are made to pcturb allocate (urban_classes_g(lsize_o,numurbl)); urban_classes_g(:,:) = spval call normalize_classes_by_gcell(urban_classes, pcturb, urban_classes_g) if (root_task) write(ndiag, '(a)') trim(subname)//" writing out percnt urban" + if (root_task) flush(ndiag) ! Make Urban Parameters from raw input data and write to surface dataset ! Write to netcdf file is done inside mkurbanpar routine if (fsurdat /= ' ') then call mkurbanpar(mksrf_furban, pioid, mesh_model, urban_region, urban_classes_g, & urban_skip_abort_on_invalid_data_check) + flush(ndiag) end if ! ----------------------------------- @@ -633,32 +666,40 @@ program mksurfdata if (fsurdat /= ' ') then if (root_task) write(ndiag, '(a)') trim(subname)//" writing out PCT_URBAN" + if (root_task) flush(ndiag) call mkfile_output(pioid, mesh_model, 'PCT_URBAN', urban_classes_g, lev1name='numurbl', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_URBAN') if (root_task) write(ndiag, '(a)') trim(subname)//" writing out PCT_GLACIER" + if (root_task) flush(ndiag) call mkfile_output(pioid, mesh_model, 'PCT_GLACIER', pctgla, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in mkfile_output for pctgla') if (root_task) write(ndiag, '(a)') trim(subname)//" writing out PCT_LAKE" + if (root_task) flush(ndiag) call mkfile_output(pioid, mesh_model, 'PCT_LAKE', pctlak, rc=rc) + if (root_task) flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in mkfile_output for pctlak') if (root_task) write(ndiag, '(a)') trim(subname)//" writing out PCT_WETLAND" + if (root_task) flush(ndiag) call mkfile_output(pioid, mesh_model, 'PCT_WETLAND', pctwet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in in mkfile_output for pctwet') if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_NATVEG" + if (root_task) flush(ndiag) call get_pct_l2g_array(pctnatpft, pctnatveg) call mkfile_output(pioid, mesh_model, 'PCT_NATVEG', pctnatveg, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NATVEG') if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_CROP" + if (root_task) flush(ndiag) call get_pct_l2g_array(pctcft, pctcrop) call mkfile_output(pioid, mesh_model, 'PCT_CROP', pctcrop, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP') if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_NAT_PFT" + if (root_task) flush(ndiag) if (lsize_o /= 0) then call get_pct_p2l_array(pctnatpft, ndim1=lsize_o, ndim2=num_natpft+1, pct_p2l=pct_nat_pft) else @@ -669,6 +710,7 @@ program mksurfdata if (num_cft > 0) then if (root_task) write(ndiag, '(a)') trim(subname)//" writing PCT_CFT" + if (root_task) flush(ndiag) if (lsize_o /= 0) then call get_pct_p2l_array(pctcft, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) else @@ -679,6 +721,7 @@ program mksurfdata end if if (root_task) write(ndiag, '(a)') trim(subname)//" writing LANDFRAC_MKSURFDATA" + if (root_task) flush(ndiag) call mkfile_output(pioid, mesh_model, 'LANDFRAC_MKSURFDATA', landfrac_mksurfdata, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for LANDFRAC_MKSURFDATA') end if @@ -690,6 +733,7 @@ program mksurfdata if (fsurdat /= ' ') then call mkglcmecInit (pioid) call mkglcmec(mksrf_fglacier_mesh, mksrf_fglacier, mesh_model, pioid, rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkglcmec') end if @@ -703,6 +747,7 @@ program mksurfdata write(ndiag,'(a)') 'Successfully created surface data output file = '//trim(fsurdat) write(ndiag,'(a)') ' This file contains the land model surface data' write(ndiag,*) + flush(ndiag) end if end if @@ -725,6 +770,7 @@ program mksurfdata write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)')'Creating dynamic land use dataset '//trim(fdyndat) + flush(ndiag) end if allocate(pctcft_max(lsize_o)) ; @@ -748,25 +794,30 @@ program mksurfdata ! Write out model grid if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LONGXY" + if (root_task) flush(ndiag) call mkfile_output(pioid, mesh_model, 'LONGXY', lon, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') if (root_task) write(ndiag, '(a)') trim(subname)//" writing out LATIXY" + if (root_task) flush(ndiag) call mkfile_output(pioid, mesh_model, 'LATIXY', lat, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output') ! Write out natpft if (root_task) write(ndiag, '(a)') trim(subname)//" writing out natpft" + if (root_task) flush(ndiag) rcode = pio_inq_varid(pioid, 'natpft', pio_varid) rcode = pio_put_var(pioid, pio_varid, (/(n,n=natpft_lb,natpft_ub)/)) ! Write out cft if (root_task) write(ndiag, '(a)') trim(subname)//" writing out cft" + if (root_task) flush(ndiag) rcode = pio_inq_varid(pioid, 'cft', pio_varid) rcode = pio_put_var(pioid, pio_varid, (/(n,n=cft_lb,cft_ub)/)) ! Write out LANDFRAC_PFT ! landfrac_pft was calculated ABOVE if (root_task) write(ndiag, '(a)') trim(subname)//" writing land fraction calculated in fsurdata calc)" + if (root_task) flush(ndiag) call mkfile_output(pioid, mesh_model, 'LANDFRAC_PFT', landfrac_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for LANDFRAC_PFT') @@ -777,6 +828,7 @@ program mksurfdata ! Open txt file if (root_task) then write(ndiag,'(a)')' Opening '//trim(mksrf_fdynuse)//' to read dynamic data forcing ' + flush(ndiag) open (newunit=nfdyn, file=trim(mksrf_fdynuse), form='formatted', iostat=ier) if (ier /= 0) then call shr_sys_abort(subname//" failed to open file "//trim(mksrf_fdynuse)) @@ -810,12 +862,14 @@ program mksurfdata if (root_task) then read(nfdyn, '(A195,1x,I4)', iostat=ier) fhrvname, year2 write(ndiag,'(a,i8,a)')' input pft dynamic dataset for year ', year,' is : '//trim(fname) + flush(ndiag) end if call mpi_bcast (fhrvname, len(fhrvname), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (year2, 1, MPI_INTEGER, 0, mpicom, ier) if ( year2 /= year ) then if (root_task) then write(ndiag,*) subname, ' error: year for harvest not equal to year for PFT files' + flush(ndiag) end if call shr_sys_abort() end if @@ -823,12 +877,14 @@ program mksurfdata if (root_task) then read(nfdyn, '(A195,1x,I4)', iostat=ier) furbname, year2 write(ndiag,*)'input urban dynamic dataset for year ', year2, ' is : ', trim(furbname) + flush(ndiag) end if call mpi_bcast (furbname, len(furbname), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (year2, 1, MPI_INTEGER, 0, mpicom, ier) if ( year2 /= year ) then if (root_task) then write(ndiag,*) subname, ' error: year for urban not equal to year for PFT files' + flush(ndiag) end if call shr_sys_abort() end if @@ -836,12 +892,14 @@ program mksurfdata if (root_task) then read(nfdyn, '(A195,1x,I4)', iostat=ier) flakname, year2 write(ndiag,*)'input lake dynamic dataset for year ', year2, ' is : ', trim(flakname) + flush(ndiag) end if call mpi_bcast (flakname, len(flakname), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (year2, 1, MPI_INTEGER, 0, mpicom, ier) if ( year2 /= year ) then if (root_task) then write(ndiag,*) subname, ' error: year for lake not equal to year for PFT files' + flush(ndiag) end if call shr_sys_abort() end if @@ -849,6 +907,7 @@ program mksurfdata ntim = ntim + 1 if (root_task) then write(ndiag,'(a,i8)')subname//' ntime = ',ntim + flush(ndiag) end if rcode = pio_inq_varid(pioid, 'YEAR', pio_varid) @@ -864,6 +923,7 @@ program mksurfdata call mkpft( mksrf_fvegtyp_mesh, fname, mesh_model, & pctlnd_o=pctlnd_pft_dyn, pctnatpft_o=pctnatpft, pctcft_o=pctcft, & rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpft') call pio_syncfile(pioid) @@ -879,6 +939,7 @@ program mksurfdata else write(ndiag,*) ' PFT file = ', fname end if + flush(ndiag) call shr_sys_abort() end if end do @@ -887,17 +948,20 @@ program mksurfdata ! Output data is written in mkharvest call mkharvest( mksrf_fhrvtyp_mesh, fhrvname, mesh_model, pioid, & ntime=ntim, rc=rc ) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkharvest') call pio_syncfile(pioid) ! Create pctlak data at model resolution (use original mapping file from lake data) call mkpctlak(mksrf_fpctlak_mesh, flakname, mesh_model, pctlak, pioid, & rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkpctlak') call pio_syncfile(pioid) call mkurban(mksrf_furban_mesh, furbname, mesh_model, pcturb, & urban_classes, urban_region, rc=rc) + flush(ndiag) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkurban') call pio_syncfile(pioid) ! screen pcturb using elevation @@ -916,6 +980,7 @@ program mksurfdata write(ndiag,*) write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,'(a)')' calling normalize_and_check_landuse' + flush(ndiag) end if call normalize_and_check_landuse(lsize_o) call normalize_classes_by_gcell(urban_classes, pcturb, urban_classes_g) @@ -927,6 +992,7 @@ program mksurfdata call update_max_array_lake(pctlak_max,pctlak) if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_NAT_PFT for year ",year + if (root_task) flush(ndiag) rcode = pio_inq_varid(pioid, 'PCT_NAT_PFT', pio_varid) call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) call get_pct_p2l_array(pctnatpft, ndim1=lsize_o, ndim2=num_natpft+1, pct_p2l=pct_nat_pft) @@ -935,6 +1001,7 @@ program mksurfdata call pio_syncfile(pioid) if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CROP for year ",year + if (root_task) flush(ndiag) rcode = pio_inq_varid(pioid, 'PCT_CROP', pio_varid) call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) call get_pct_l2g_array(pctcft, pctcrop) @@ -943,6 +1010,7 @@ program mksurfdata call pio_syncfile(pioid) if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_URBAN for year ",year + if (root_task) flush(ndiag) rcode = pio_inq_varid(pioid, 'PCT_URBAN', pio_varid) call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) call mkfile_output(pioid, mesh_model, 'PCT_URBAN', urban_classes_g, rc=rc) @@ -950,6 +1018,7 @@ program mksurfdata call pio_syncfile(pioid) if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_LAKE for year ",year + if (root_task) flush(ndiag) rcode = pio_inq_varid(pioid, 'PCT_LAKE', pio_varid) call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) call mkfile_output(pioid, mesh_model, 'PCT_LAKE', pctlak, rc=rc) @@ -958,6 +1027,7 @@ program mksurfdata if (num_cft > 0) then if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CFT for year ",year + if (root_task) flush(ndiag) rcode = pio_inq_varid(pioid, 'PCT_CFT', pio_varid) call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) call get_pct_p2l_array(pctcft, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) @@ -967,6 +1037,7 @@ program mksurfdata end if if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing LANDFRAC_MKSURFDATA for year ",year + if (root_task) flush(ndiag) rcode = pio_inq_varid(pioid, 'LANDFRAC_MKSURFDATA', pio_varid) call pio_setframe(pioid, pio_varid, int(ntim, kind=Pio_Offset_Kind)) call mkfile_output(pioid, mesh_model, 'LANDFRAC_MKSURFDATA', landfrac_mksurfdata, rc=rc) @@ -976,30 +1047,36 @@ program mksurfdata if (root_task) then write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) + flush(ndiag) end if end do ! end of read loop if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_NAT_PFT_MAX " + if (root_task) flush(ndiag) call get_pct_p2l_array(pctnatpft_max, ndim1=lsize_o, ndim2=num_natpft+1, pct_p2l=pct_nat_pft) call mkfile_output(pioid, mesh_model, 'PCT_NAT_PFT_MAX', pct_nat_pft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_NAT_PFT') if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CROP_MAX" + if (root_task) flush(ndiag) call get_pct_l2g_array(pctcft_max, pctcrop) call mkfile_output(pioid, mesh_model, 'PCT_CROP_MAX', pctcrop, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CROP_MAX') if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_URBAN_MAX" + if (root_task) flush(ndiag) call mkfile_output(pioid, mesh_model, 'PCT_URBAN_MAX', pcturb_max, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_URBAN_MAX') if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_LAKE_MAX" + if (root_task) flush(ndiag) call mkfile_output(pioid, mesh_model, 'PCT_LAKE_MAX', pctlak_max, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_LAKE_MAX') if (num_cft > 0) then if (root_task) write(ndiag, '(a,i8)') trim(subname)//" writing PCT_CFT_MAX" + if (root_task) flush(ndiag) call get_pct_p2l_array(pctcft_max, ndim1=lsize_o, ndim2=num_cft, pct_p2l=pct_cft) call mkfile_output(pioid, mesh_model, 'PCT_CFT_MAX', pct_cft, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mkfile_output for PCT_CFT') @@ -1007,12 +1084,20 @@ program mksurfdata ! Close the file call pio_closefile(pioid) + if (root_task) then + write(ndiag,*) + write(ndiag,'(a)') 'Successfully created landuse timeseries data output file = '//trim(fdyndat) + write(ndiag,'(a)') ' This file contains the land model time series data' + write(ndiag,*) + flush(ndiag) + end if end if ! end of if-create dynamic landust dataset ! ----------------------------------- ! Wrap things up ! ----------------------------------- + write(ndiag,'(a)') 'Successfully ran mksurfdata_esmf' close (ndiag) call ESMF_Finalize() @@ -1060,26 +1145,31 @@ subroutine normalize_and_check_landuse(ns_o) if ( pctlak(n) < 0.0_r8 )then write(6,*) subname, ' ERROR: pctlak is negative!' write(6,*) 'n, pctlak = ', n, pctlak(n) + flush(6) call shr_sys_abort() end if if ( pctwet(n) < 0.0_r8 )then write(6,*) subname, ' ERROR: pctwet is negative!' write(6,*) 'n, pctwet = ', n, pctwet(n) + flush(6) call shr_sys_abort() end if if ( pcturb(n) < 0.0_r8 )then write(6,*) subname, ' ERROR: pcturb is negative!' write(6,*) 'n, pcturb = ', n, pcturb(n) + flush(6) call shr_sys_abort() end if if ( pctgla(n) < 0.0_r8 )then write(6,*) subname, ' ERROR: pctgla is negative!' write(6,*) 'n, pctgla = ', n, pctgla(n) + flush(6) call shr_sys_abort() end if if ( pctcft(n)%get_pct_l2g() < 0.0_r8 )then write(6,*) subname, ' ERROR: pctcrop is negative!' write(6,*) 'n, pctcrop = ', n, pctcft(n)%get_pct_l2g() + flush(6) call shr_sys_abort() end if @@ -1101,6 +1191,7 @@ subroutine normalize_and_check_landuse(ns_o) write(6,*) '<= 100% before normalizing natural vegetation area' write(6,*) 'n, pctlak, pctwet, pcturb, pctgla, pctcrop = ', & n, pctlak(n), pctwet(n), pcturb(n), pctgla(n), pctcft(n)%get_pct_l2g() + flush(6) call shr_sys_abort() end if @@ -1228,6 +1319,7 @@ subroutine normalize_and_check_landuse(ns_o) write(6,*) 'n, suma, pctlak, pctwet, pctgla, pcturb, pctnatveg, pctcrop = ' write(6,*) n, suma, pctlak(n), pctwet(n), pctgla(n), pcturb(n), & pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() + flush(6) call shr_sys_abort() end if @@ -1269,6 +1361,7 @@ subroutine normalize_and_check_landuse(ns_o) (pctnatpft(n)%get_pct_l2g() > 0.0_r8 .and. pctnatpft(n)%get_pct_l2g() < 1.e-6_r8) ) then write (6,*) 'Special plus crop land units near 100%, but not quite for n,suma =',n,suma write (6,*) 'Adjusting special plus crop land units to 100%' + flush(6) if (pctlak(n) >= 1.0_r8) then pctlak(n) = 100._r8 - (pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g()) else if (pctwet(n) >= 1.0_r8) then @@ -1284,6 +1377,7 @@ subroutine normalize_and_check_landuse(ns_o) 'n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),pctnatveg(n),pctcrop(n),suma = ', & n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(),suma + flush(6) call shr_sys_abort() end if call pctnatpft(n)%set_pct_l2g(0._r8) @@ -1295,6 +1389,7 @@ subroutine normalize_and_check_landuse(ns_o) write (6,*) 'pctcft%pct_p2l = ', pctcft(n)%get_pct_p2l() write (6,*) 'pctnatpft%pct_l2g = ', pctnatpft(n)%get_pct_l2g() write (6,*) 'pctcft%pct_l2g = ', pctcft(n)%get_pct_l2g() + flush(6) call shr_sys_abort() end if @@ -1306,6 +1401,7 @@ subroutine normalize_and_check_landuse(ns_o) write (6,*)'n,pctlak,pctwet,pcturb,pctgla,pctnatveg,pctcrop,sum= ', & n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(), suma + flush(6) call shr_sys_abort() end if @@ -1320,6 +1416,7 @@ subroutine normalize_and_check_landuse(ns_o) do n = 1,ns_o if (abs(sum(urban_classes(n,:)) - 100._r8) > 1.e-12_r8) then write(6,*) 'sum(urban_classes(n,:)) != 100: ', n, sum(urban_classes(n,:)) + flush(6) call shr_sys_abort() end if end do @@ -1327,6 +1424,7 @@ subroutine normalize_and_check_landuse(ns_o) if (root_task) then if ( nsmall_tot > 0 )then write(ndiag,*)'number of small pft = ', nsmall_tot + flush(ndiag) end if end if diff --git a/tools/mksurfdata_esmf/src/mkvarctl.F90 b/tools/mksurfdata_esmf/src/mkvarctl.F90 index af127553ee..53e90a9cc8 100644 --- a/tools/mksurfdata_esmf/src/mkvarctl.F90 +++ b/tools/mksurfdata_esmf/src/mkvarctl.F90 @@ -10,7 +10,7 @@ module mkvarctl private integer, public :: ndiag ! output log unit - logical, public :: root_task ! proc 0 logical for printing msgs + logical, public :: root_task = .TRUE.! proc 0 logical for printing msgs integer, public :: iam ! processor number integer, public :: npes ! number of processors integer, public :: mpicom ! communicator group From eb778a4a6de6bd9418f45dca67d90c505bcd7adf Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 9 Oct 2023 16:33:32 -0600 Subject: [PATCH 372/614] Add note about how to use the current build --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index 1cf102e0fd..8a4d89cb53 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -91,6 +91,10 @@ done echo "cime Machine is: $MACH..." if [ -d "$blddir" ]; then echo "A /tool_bld directory exists; remove it to do a clean build..." + echo " or if you want to use the existing build do (assuming using bash):" + echo "cd $blddir" + echo ". .env_mach_specific.sh" + echo "make" exit 1 fi mkdir $blddir From db2a42facb8c511f44ce7697a374ebcc9c58e7e7 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 9 Oct 2023 16:37:01 -0600 Subject: [PATCH 373/614] Remove run_mksurfdata which must have been an early test script --- tools/mksurfdata_esmf/src/run_mksurfdata | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 tools/mksurfdata_esmf/src/run_mksurfdata diff --git a/tools/mksurfdata_esmf/src/run_mksurfdata b/tools/mksurfdata_esmf/src/run_mksurfdata deleted file mode 100644 index a4d4dd973b..0000000000 --- a/tools/mksurfdata_esmf/src/run_mksurfdata +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -#PBS -A P93300606 -#PBS -N job_name -#PBS -j oe -#PBS -q premium -#PBS -l walltime=45:00 -##PBS -l select=1:ncpus=36:mpiprocs=36 -#PBS -l select=4:ncpus=36:mpiprocs=36 -##PBS -l select=16:ncpus=36:mpiprocs=9 -#PBS -o log.out - -# note for -l input above -# -l select={num_nodes}:ncpus={max_tasks_per_node}:mpiprocs={tasks_per_node} - -export TMPDIR=/glade/scratch/$USER/temp -mkdir -p $TMPDIR - -#module rm netcdf -#module load netcdf-mpi pnetcdf pio/2.5.5 -#make - -# -np {total_tasks} -mpiexec_mpt -p "%g:" -np 144 /glade/u/home/mvertens/src/ctsm.toolchain/tools/mksurfdata_esmf/src/run/mksurfdata From 90e9483646d3db39b42c0109bce5ec510a8fa605 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 10 Oct 2023 13:02:22 -0600 Subject: [PATCH 374/614] Add queue option, fix some issues with the batch submission, remove use of omplace only needed for hybrid MPI/OpenMP code, because of duplication this had to go in two places --- .../gen_mksurfdata_jobscript_multi.py | 29 ++++++++++++++----- .../gen_mksurfdata_jobscript_single.py | 12 +++++--- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py index 05f8a07b42..265898d8a2 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py @@ -86,6 +86,14 @@ def get_parser(): required=False, default="12:00:00", ) + parser.add_argument( + "--queue", + help="""Queue to submit to)""", + action="store", + dest="queue", + required=False, + default="regular", + ) parser.add_argument( "--scenario", help="""scenario""", @@ -119,6 +127,7 @@ def main (): tasks_per_node = args.tasks_per_node account = args.account walltime = args.walltime + queue = args.queue # -------------------------- # Determine target list @@ -238,9 +247,13 @@ def main (): runfile.write(f"#PBS -A {account} \n") runfile.write(f'#PBS -N mksrf_{scenario} \n') runfile.write('#PBS -j oe \n') - runfile.write('#PBS -q regular \n') + runfile.write('#PBS -k eod \n') + runfile.write('#PBS -S /bin/bash \n') + runfile.write(f'#PBS -q {queue} \n') runfile.write(f'#PBS -l walltime={walltime} \n') - runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") + runfile.write(f"#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node}:mem=109GB \n") + runfile.write(f'# This is a batch script to run a set of resolutions for mksurfdata_esmf {scenario} \n') + runfile.write('# NOTE: THIS SCRIPT IS AUTOMATICALLY GENERATED SO IN GENERAL YOU SHOULD NOT EDIT it!!\n\n') runfile.write("\n") n_p = int(tasks_per_node) * int(number_of_nodes) @@ -249,6 +262,8 @@ def main (): # environment including the paths to compilers and libraries # external to cime such as netcdf runfile.write('. '+env_specific_script + '\n') + check = f"if [ $? != 0 ]; then echo 'Error running env_specific_script'; exit -4; fi" + runfile.write(f"{check} \n") for target in target_list: res_set = dataset_dict[target][1] for res in resolution_dict[res_set]: @@ -258,22 +273,22 @@ def main (): print (f"command is {command}") commands = [x for x in command.split(' ') if x] try: - run_cmd = subprocess.run(commands, check=True, + run_cmd = subprocess.run(commands, check=True, shell=True, capture_output=True) except subprocess.CalledProcessError as e: sys.exit(f'{e} ERROR calling {command}') output = run_cmd.stdout.decode('utf-8').strip() namelist = output.split(' ')[-1] print (f"generated namelist {namelist}") - output = f"mpiexec_mpt -p \"%g:\" -np {n_p} omplace -tm open64 {mksurfdata} < {namelist}" + output = f"time mpiexec_mpt -p \"%g:\" -np {n_p} {mksurfdata} < {namelist}" runfile.write(f"{output} \n") check = f"if [ $? != 0 ]; then echo 'Error running resolution {res}'; exit -4; fi" runfile.write(f"{check} \n") - runfile.write(f"Successfully ran resolution {res}\n") + runfile.write(f"echo Successfully ran resolution {res}\n") - runfile.write(f"Successfully ran {jobscript_file}\n") + runfile.write(f"echo Successfully ran {jobscript_file}\n") - print (f"Successfully created jobscript {jobscript_file}\n") + print (f"echo Successfully created jobscript {jobscript_file}\n") sys.exit(0) if __name__ == "__main__": diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py index 851d2ab29d..2e01f89194 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py @@ -112,18 +112,20 @@ def main (): runfile.write(f'# Below are default batch directives for {machine} \n') runfile.write('#PBS -N mksurfdata \n') runfile.write('#PBS -j oe \n') + runfile.write('#PBS -k eod \n') + runfile.write('#PBS -S /bin/bash \n') if machine == 'cheyenne': attribs = {'mpilib': 'default'} runfile.write('#PBS -l walltime=30:00 \n') runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -q regular \n') - runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=36:mpiprocs={tasks_per_node} \n") + runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=tasks_per_node}:mpiprocs={tasks_per_node} \n") elif machine == 'casper': attribs = {'mpilib': 'default'} runfile.write('#PBS -l walltime=1:00:00 \n') runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -q casper \n') - runfile.write(f'#PBS -l select={number_of_nodes}:ncpus=12:' \ + runfile.write(f'#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:' \ f'mpiprocs={tasks_per_node}:mem=80GB \n') elif machine == 'izumi': attribs = {'mpilib': 'mvapich2'} @@ -167,6 +169,8 @@ def main (): 'dependent environment including the paths to ' \ 'compilers and libraries external to cime such as netcdf') runfile.write(f'\n. {env_mach_path}\n') + check = f'if [ $? != 0 ]; then echo "Error running env_mach_specific"; exit -4; fi' + runfile.write(f"{check} \n") runfile.write('# Edit the mpirun command to use the MPI executable ' \ 'on your system and the arguments it requires \n') output = f'{executable} {mksurfdata_path} < {namelist_file}' @@ -175,9 +179,9 @@ def main (): check = f'if [ $? != 0 ]; then echo "Error running resolution {res}"; exit -4; fi' runfile.write(f"{check} \n") - runfile.write(f"Successfully ran resolution\n") + runfile.write(f"echo Successfully ran resolution\n") - print (f"Successfully created jobscript {jobscript_file}\n") + print (f"echo Successfully created jobscript {jobscript_file}\n") sys.exit(0) if __name__ == "__main__": From 83383a25ea7e50910ec822950079637ba7d3b1b1 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 10 Oct 2023 21:17:44 -0600 Subject: [PATCH 375/614] Add create_esmf_pet_files to the namelist, fix some issues so the error checking is robust, add more flush statements, change some of the output from write(6 to write(ndiag --- tools/mksurfdata_esmf/src/mkdomainMod.F90 | 2 + tools/mksurfdata_esmf/src/mkinputMod.F90 | 21 ++- tools/mksurfdata_esmf/src/mksurfdata.F90 | 178 ++++++++++++++-------- 3 files changed, 130 insertions(+), 71 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkdomainMod.F90 b/tools/mksurfdata_esmf/src/mkdomainMod.F90 index 8bb6f0f5d7..32c5854d4e 100644 --- a/tools/mksurfdata_esmf/src/mkdomainMod.F90 +++ b/tools/mksurfdata_esmf/src/mkdomainMod.F90 @@ -48,6 +48,7 @@ subroutine mkdomain(mesh_o, lon_o, lat_o, rc) write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) write(ndiag,'(a)') 'Attempting to create model lats and lons from model mesh .....' + flush(ndiag) end if call ESMF_MeshGet(mesh_o, spatialDim=spatialDim, numOwnedElements=ns_o, rc=rc) @@ -62,6 +63,7 @@ subroutine mkdomain(mesh_o, lon_o, lat_o, rc) if (root_task) then write (ndiag,'(a)') 'Successfully made model lats and lons' + flush(ndiag) end if end subroutine mkdomain diff --git a/tools/mksurfdata_esmf/src/mkinputMod.F90 b/tools/mksurfdata_esmf/src/mkinputMod.F90 index 3922420cb0..9c8564df03 100644 --- a/tools/mksurfdata_esmf/src/mkinputMod.F90 +++ b/tools/mksurfdata_esmf/src/mkinputMod.F90 @@ -36,6 +36,7 @@ module mkinputMod character(CL) , public :: flakname ! generic lake filename character(CS) , public :: mksrf_grid_name = ' ' ! Name of this grid + integer , public :: grid_size ! Number of columne in the grid character(CX) , public :: mksrf_fgrid_mesh = ' ' ! land grid file name to use integer , public :: mksrf_fgrid_mesh_nx = -999 @@ -112,6 +113,7 @@ module mkinputMod character(CS) , public :: logname = ' ' ! user name character(CS) , public :: hostname = ' ' ! machine name + logical , public :: create_esmf_pet_files = .false. ! Always create ESMF PET files (.false. if only on error) logical , public :: urban_skip_abort_on_invalid_data_check character(len=*), parameter :: u_FILE_u = & @@ -129,7 +131,6 @@ subroutine read_namelist_input() integer :: ier integer :: k integer :: fileunit - integer :: grid_size ! Number of columne in the grid logical :: lexist character(len=*), parameter :: subname = 'read_namelist_input' ! ------------------------------------------------------------ @@ -198,6 +199,7 @@ subroutine read_namelist_input() fdyndat, & fsurlog, & std_elev, & + create_esmf_pet_files, & urban_skip_abort_on_invalid_data_check ! Set default namelist values - make these the defaults in gen_mksurfdata_namelist.py @@ -209,7 +211,7 @@ subroutine read_namelist_input() urban_skip_abort_on_invalid_data_check = .false. ! default value for bug work around if (root_task) then - write(6,*) 'Attempting to initialize control settings .....' + write(ndiag,*) 'Attempting to initialize control settings .....' end if if (root_task) then @@ -217,10 +219,10 @@ subroutine read_namelist_input() if (ier > 0) then call shr_sys_abort(subname//' error reading in mksurfdata_input namelist from standard input') end if - end if - if ( mksrf_grid_name == ' ' )then grid_size = mksrf_fgrid_mesh_nx * mksrf_fgrid_mesh_ny - write(mksrf_grid_name,'("Grid",I07)') grid_size + if ( mksrf_grid_name == ' ' )then + write(mksrf_grid_name,'("Cols",I7.7)') grid_size + end if end if end subroutine read_namelist_input @@ -237,6 +239,8 @@ subroutine bcast_namelist_input() call mpi_bcast (mksrf_fgrid_mesh, len(mksrf_fgrid_mesh), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fgrid_mesh_nx, 1, MPI_INTEGER, 0, mpicom, ier) call mpi_bcast (mksrf_fgrid_mesh_ny, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (grid_size, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (mksrf_grid_name, len(mksrf_grid_name), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fvegtyp, len(mksrf_fvegtyp), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (mksrf_fvegtyp_mesh, len(mksrf_fvegtyp_mesh), MPI_CHARACTER, 0, mpicom, ier) @@ -313,6 +317,7 @@ subroutine bcast_namelist_input() call mpi_bcast (outnc_3dglc, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (urban_skip_abort_on_invalid_data_check, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (create_esmf_pet_files, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (numpft, 1, MPI_INTEGER, 0, mpicom, ier) call mpi_bcast (no_inlandwet, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (std_elev, 1, MPI_REAL, 0, mpicom, ier) @@ -428,6 +433,7 @@ subroutine write_namelist_input() write(ndiag,'(a)')' mksrf_fgrid_mesh = '//trim(mksrf_fgrid_mesh) write(ndiag,'(a,i8)')' nlon= ',mksrf_fgrid_mesh_nx write(ndiag,'(a,i8)')' nlat= ',mksrf_fgrid_mesh_ny + write(ndiag,'(a,i8)')'Grid_size: ', grid_size write(ndiag,*) write(ndiag,'(1x,80a1)') ('=',k=1,80) write(ndiag,*) @@ -451,6 +457,11 @@ subroutine write_namelist_input() if ( outnc_3dglc )then write(ndiag,'(a)')' Output optional 3D glacier fields (mostly used for verification of the glacier model)' end if + if (create_esmf_pet_files) then + write(ndiag,'(a)')' Always output ESMF PET files' + else + write(ndiag,'(a)')' Only output ESMF PET files if fatal errors happen in ESMF' + end if if (urban_skip_abort_on_invalid_data_check) then write(ndiag, '(a)') " WARNING: aborting on invalid data check in urban has been disabled!" write(ndiag, '(a)') " WARNING: urban data may be invalid!" diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index 6c04e9b9c0..75fcd94d1c 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -125,7 +125,10 @@ program mksurfdata ! indices integer :: k,n ! indices - integer :: lsize_o + integer :: lsize_o ! Size of the local mesh elments + integer :: node_count ! Number of gridcells on the mesh + integer :: local_nodes(1) ! Local gridcells on the mesh + integer :: total_nodes(1) ! Total gridcells on the mesh ! error status integer :: ier,rcode ! error status @@ -186,7 +189,6 @@ program mksurfdata type(ESMF_LogKind_Flag) :: logkindflag type(ESMF_VM) :: vm integer :: rc - logical :: create_esmf_pet_files = .false. ! character variables character(len=CL) :: default_log_suffix ! default log file suffix to use for ESMF PET files @@ -198,17 +200,26 @@ program mksurfdata __FILE__ ! ====================================================================== - ! Read in namelist before initializing MPI or ESMF - ! ====================================================================== - call read_namelist_input() - - ! ====================================================================== - ! Initialize MPI + ! Initialize MPI get the rank and determine root task ! ====================================================================== call MPI_init(rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() mpicom = mpi_comm_world + ! Determine root task + call MPI_comm_rank(mpicom, iam, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + root_task = (iam == 0) + call MPI_comm_size(mpicom, npes, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + + + ! ====================================================================== + ! Read in namelist before initializing MPI or ESMF + ! ====================================================================== + call read_namelist_input() + ! ====================================================================== ! Initialize ESMF and get mpicom from ESMF ! ====================================================================== @@ -218,19 +229,50 @@ program mksurfdata else logkindflag = ESMF_LOGKIND_MULTI_ON_ERROR end if - default_log_suffix = mksrf_grid_name // 'ESMF_LogFile' + default_log_suffix = trim(mksrf_grid_name) // '_ESMF_LogFile' call ESMF_Initialize(mpiCommunicator=MPICOM, logkindflag=logkindflag, logappendflag=.false., & - defaultDefaultLogFilename=mksrf_grid_name, ioUnitLBound=5001, ioUnitUBound=5101, vm=vm, rc=rc) + defaultDefaultLogFilename=trim(default_log_suffix), ioUnitLBound=5001, ioUnitUBound=5101, vm=vm, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_VMGetGlobal(vm, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_VMGet(vm, mpicommunicator=mpicom, localPet=iam, petcount=petcount, & ssiLocalPetCount=stride, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() call ESMF_LogSet(flush=.true.) call ESMF_LogWrite("mksurfdata starting", ESMF_LOGMSG_INFO) + ! + ! open output ndiag file + ! + if (root_task) then + open (newunit=ndiag, file=trim(fsurlog), iostat=ier) + if (ier /= 0) then + call shr_sys_abort(' failed to open ndiag file '//trim(fsurlog)) + end if + write (ndiag,'(a)') 'Attempting to create surface boundary data .....' + write (ndiag,'(72a1)') ("-",n=1,60) + flush(ndiag) + else + ndiag = 6 + end if + ! + ! Finish handling of the namelist control variables + ! + ! Broadcast namelist to all pes + ! root_task is a module variable in mkvarctl + call bcast_namelist_input() - ! Determine root task - root_task = (iam == 0) + ! Write out namelist input to ndiag + call check_namelist_input() + call write_namelist_input() + + ! Some checking + if (root_task) then + write(ndiag,'(2(a,I))') ' npes = ', npes, ' grid size = ', grid_size + flush(ndiag) + end if + if (petcount > grid_size ) then + call shr_sys_abort(' ERROR: number of tasks exceeds the size of the grid' ) + end if ! ====================================================================== ! Initialize PIO @@ -242,6 +284,7 @@ program mksurfdata ! Open txt file if (root_task) then write(ndiag,*)' Opening file and reading pio_iotype from txt file with the same name' + flush(ndiag) open (newunit=nfpio, file='pio_iotype.txt', status='old', & form='formatted', action='read', iostat=ier) if (ier /= 0) then @@ -259,46 +302,39 @@ program mksurfdata call ESMF_LogWrite("finished initializing PIO", ESMF_LOGMSG_INFO) - ! Broadcast namelist to all pes - ! root_task is a module variable in mkvarctl - call bcast_namelist_input() - - ! open output ndiag file if (fsurlog == ' ') then call shr_sys_abort(' ERROR: must specify fsurlog in namelist') end if - if (root_task) then - open (newunit=ndiag, file=trim(fsurlog), iostat=ier) - if (ier /= 0) then - call shr_sys_abort(' failed to open ndiag file '//trim(fsurlog)) - end if - write (ndiag,'(a)') 'Attempting to create surface boundary data .....' - write (ndiag,'(72a1)') ("-",n=1,60) - flush(ndiag) - else - ndiag = 6 - end if - - ! Write out namelist input to ndiag - call check_namelist_input() - call write_namelist_input() ! ====================================================================== ! Create fsurdat ! ====================================================================== ! Read in model mesh to determine the number of local points + call ESMF_LogWrite("MESH creation (if this takes too long [more than an hour] and hangs, you may need more memory...)", ESMF_LOGMSG_INFO) mesh_model = ESMF_MeshCreate(filename=trim(mksrf_fgrid_mesh), fileformat=ESMF_FILEFORMAT_ESMFMESH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() ! Get the number of local destination points on my processor (lsize_o) call ESMF_MeshGet(mesh_model, numOwnedElements=lsize_o, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - + local_nodes(1) = lsize_o + call ESMF_VMAllReduce(vm, local_nodes, total_nodes, count=1, reduceflag=ESMF_REDUCE_SUM, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + node_count = total_nodes(1) + if (node_count /= grid_size) then + if (root_task) then + write (ndiag,'(a, I, a, I)') ' node_count = ', node_count, ' grid_size = ', grid_size + flush(ndiag) + end if + call shr_sys_abort(' ERROR: size of input mesh file does not agree with expected size of nx*ny' ) + end if ! Initialize urban dimensions (needed to initialize the dimensions in fsurdat) + call ESMF_LogWrite("mkurbanInit...") call mkurbanInit(mksrf_furban) ! Initialize pft/cft dimensions (needed to initialize the dimensions in fsurdat) + call ESMF_LogWrite("mkpftInit...") call mkpftInit( ) ! If fsurdat is blank, then we do not write a surface dataset - but we may still @@ -323,6 +359,7 @@ program mksurfdata flush(ndiag) end if + call ESMF_LogWrite("mkfile...") ! Open file ! TODO: what about setting no fill values? call mkpio_wopen(trim(fsurdat), clobber=.true., pioid=pioid) @@ -374,6 +411,11 @@ program mksurfdata call pio_syncfile(pioid) end if + if (root_task)then + write(ndiag,*)' Initialization is complete, going on to process types of input files' + flush(ndiag) + end if + ! ----------------------------------- ! Make LAI and SAI from 1/2 degree data and write to surface dataset ! Write to netcdf file is done inside mklai routine @@ -631,7 +673,7 @@ program mksurfdata enddo call mpi_reduce(loc_suma, glob_suma, 1, MPI_REAL8, MPI_SUM, 0, mpicom, ier) if (root_task) then - write(6,*) 'sum over domain of cft ',k,glob_suma + write(ndiag,*) 'sum over domain of cft ',k,glob_suma end if enddo if (root_task) write(ndiag,*) @@ -1097,8 +1139,10 @@ program mksurfdata ! ----------------------------------- ! Wrap things up ! ----------------------------------- - write(ndiag,'(a)') 'Successfully ran mksurfdata_esmf' - close (ndiag) + if (root_task) then + write(ndiag,'(a)') 'Successfully ran mksurfdata_esmf' + close (ndiag) + end if call ESMF_Finalize() @@ -1143,33 +1187,33 @@ subroutine normalize_and_check_landuse(ns_o) ! Check preconditions if ( pctlak(n) < 0.0_r8 )then - write(6,*) subname, ' ERROR: pctlak is negative!' - write(6,*) 'n, pctlak = ', n, pctlak(n) - flush(6) + write(ndiag,*) subname, ' ERROR: pctlak is negative!' + write(ndiag,*) 'n, pctlak = ', n, pctlak(n) + flush(ndiag) call shr_sys_abort() end if if ( pctwet(n) < 0.0_r8 )then - write(6,*) subname, ' ERROR: pctwet is negative!' - write(6,*) 'n, pctwet = ', n, pctwet(n) - flush(6) + write(ndiag,*) subname, ' ERROR: pctwet is negative!' + write(ndiag,*) 'n, pctwet = ', n, pctwet(n) + flush(ndiag) call shr_sys_abort() end if if ( pcturb(n) < 0.0_r8 )then - write(6,*) subname, ' ERROR: pcturb is negative!' - write(6,*) 'n, pcturb = ', n, pcturb(n) - flush(6) + write(ndiag,*) subname, ' ERROR: pcturb is negative!' + write(ndiag,*) 'n, pcturb = ', n, pcturb(n) + flush(ndiag) call shr_sys_abort() end if if ( pctgla(n) < 0.0_r8 )then - write(6,*) subname, ' ERROR: pctgla is negative!' - write(6,*) 'n, pctgla = ', n, pctgla(n) - flush(6) + write(ndiag,*) subname, ' ERROR: pctgla is negative!' + write(ndiag,*) 'n, pctgla = ', n, pctgla(n) + flush(ndiag) call shr_sys_abort() end if if ( pctcft(n)%get_pct_l2g() < 0.0_r8 )then - write(6,*) subname, ' ERROR: pctcrop is negative!' - write(6,*) 'n, pctcrop = ', n, pctcft(n)%get_pct_l2g() - flush(6) + write(ndiag,*) subname, ' ERROR: pctcrop is negative!' + write(ndiag,*) 'n, pctcrop = ', n, pctcft(n)%get_pct_l2g() + flush(ndiag) call shr_sys_abort() end if @@ -1187,11 +1231,11 @@ subroutine normalize_and_check_landuse(ns_o) suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() if (suma > (100._r8 + tol_loose)) then - write(6,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla + pctcrop must be' - write(6,*) '<= 100% before normalizing natural vegetation area' - write(6,*) 'n, pctlak, pctwet, pcturb, pctgla, pctcrop = ', & + write(ndiag,*) subname, ' ERROR: pctlak + pctwet + pcturb + pctgla + pctcrop must be' + write(ndiag,*) '<= 100% before normalizing natural vegetation area' + write(ndiag,*) 'n, pctlak, pctwet, pcturb, pctgla, pctcrop = ', & n, pctlak(n), pctwet(n), pcturb(n), pctgla(n), pctcft(n)%get_pct_l2g() - flush(6) + flush(ndiag) call shr_sys_abort() end if @@ -1315,11 +1359,11 @@ subroutine normalize_and_check_landuse(ns_o) suma = pctlak(n) + pctwet(n) + pctgla(n) + pcturb(n) + pctcft(n)%get_pct_l2g() suma = suma + pctnatpft(n)%get_pct_l2g() if (abs(suma - 100._r8) > tol_loose) then - write(6,*) subname, ' ERROR: landunits do not sum to 100%' - write(6,*) 'n, suma, pctlak, pctwet, pctgla, pcturb, pctnatveg, pctcrop = ' - write(6,*) n, suma, pctlak(n), pctwet(n), pctgla(n), pcturb(n), & + write(ndiag,*) subname, ' ERROR: landunits do not sum to 100%' + write(ndiag,*) 'n, suma, pctlak, pctwet, pctgla, pcturb, pctnatveg, pctcrop = ' + write(ndiag,*) n, suma, pctlak(n), pctwet(n), pctgla(n), pcturb(n), & pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g() - flush(6) + flush(ndiag) call shr_sys_abort() end if @@ -1359,9 +1403,11 @@ subroutine normalize_and_check_landuse(ns_o) suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() if ( (suma < 100._r8 .and. suma > (100._r8 - 1.e-6_r8)) .or. & (pctnatpft(n)%get_pct_l2g() > 0.0_r8 .and. pctnatpft(n)%get_pct_l2g() < 1.e-6_r8) ) then - write (6,*) 'Special plus crop land units near 100%, but not quite for n,suma =',n,suma - write (6,*) 'Adjusting special plus crop land units to 100%' - flush(6) + if ( root_task ) then + write (ndiag,*) 'Special plus crop land units near 100%, but not quite for n,suma =',n,suma + write (ndiag,*) 'Adjusting special plus crop land units to 100%' + flush(ndiag) + end if if (pctlak(n) >= 1.0_r8) then pctlak(n) = 100._r8 - (pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g()) else if (pctwet(n) >= 1.0_r8) then @@ -1373,11 +1419,11 @@ subroutine normalize_and_check_landuse(ns_o) else if (pctcft(n)%get_pct_l2g() >= 1.0_r8) then call pctcft(n)%set_pct_l2g(100._r8 - (pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n))) else - write (6,*) subname, 'Error: sum of special plus crop land units nearly 100% but none is >= 1% at ', & + write (ndiag,*) subname, 'Error: sum of special plus crop land units nearly 100% but none is >= 1% at ', & 'n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),pctnatveg(n),pctcrop(n),suma = ', & n,pctlak(n),pctwet(n),pcturb(n),pctgla(n),& pctnatpft(n)%get_pct_l2g(),pctcft(n)%get_pct_l2g(),suma - flush(6) + flush(ndiag) call shr_sys_abort() end if call pctnatpft(n)%set_pct_l2g(0._r8) @@ -1415,8 +1461,8 @@ subroutine normalize_and_check_landuse(ns_o) ! is done internally by the pct_pft_type routines.) do n = 1,ns_o if (abs(sum(urban_classes(n,:)) - 100._r8) > 1.e-12_r8) then - write(6,*) 'sum(urban_classes(n,:)) != 100: ', n, sum(urban_classes(n,:)) - flush(6) + write(ndiag,*) 'sum(urban_classes(n,:)) != 100: ', n, sum(urban_classes(n,:)) + flush(ndiag) call shr_sys_abort() end if end do From 3f30333bac5e6f0b2af97b4e72f555e94cab7416 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 11 Oct 2023 17:56:29 -0600 Subject: [PATCH 376/614] Move gen_mksurfdata scripts over to the python directory for python development --- .../gen_mksurfdata_jobscript_multi.py | 4 --- .../gen_mksurfdata_jobscript_single.py | 12 +------ .../toolchain}/gen_mksurfdata_namelist.py | 10 ------ tools/README | 8 ++--- tools/mksurfdata_esmf/README | 18 +++++----- .../gen_mksurfdata_jobscript_multi | 34 +++++++++++++++++++ .../gen_mksurfdata_jobscript_single | 34 +++++++++++++++++++ tools/mksurfdata_esmf/gen_mksurfdata_namelist | 34 +++++++++++++++++++ 8 files changed, 116 insertions(+), 38 deletions(-) rename {tools/mksurfdata_esmf => python/ctsm/toolchain}/gen_mksurfdata_jobscript_multi.py (99%) rename {tools/mksurfdata_esmf => python/ctsm/toolchain}/gen_mksurfdata_jobscript_single.py (95%) rename {tools/mksurfdata_esmf => python/ctsm/toolchain}/gen_mksurfdata_namelist.py (99%) create mode 100755 tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi create mode 100755 tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single create mode 100755 tools/mksurfdata_esmf/gen_mksurfdata_namelist diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py similarity index 99% rename from tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py rename to python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 265898d8a2..4f6e77f6b3 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 """ gen_mksurfdata_jobscript_multi.py generates a jobscript for running the mksurfdata executable to generate many fsurdat files at once. For detailed @@ -290,6 +289,3 @@ def main (): print (f"echo Successfully created jobscript {jobscript_file}\n") sys.exit(0) - -if __name__ == "__main__": - main() diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py similarity index 95% rename from tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py rename to python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 2e01f89194..69653e9afc 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 """ gen_mksurfdata_jobscript_single.py generates a jobscript for running the mksurfdata executable to generate a single fsurdat file. For detailed @@ -9,12 +8,6 @@ import argparse import logging -_CTSM_PYTHON = os.path.join(os.path.dirname(os.path.realpath(__file__)), - os.pardir, - os.pardir, - 'python') -sys.path.insert(1, _CTSM_PYTHON) - from ctsm import add_cime_to_path # pylint: disable=unused-import from ctsm.ctsm_logging import setup_logging_pre_config, add_logging_args, process_logging_args from CIME.XML.env_mach_specific import EnvMachSpecific @@ -119,7 +112,7 @@ def main (): runfile.write('#PBS -l walltime=30:00 \n') runfile.write(f"#PBS -A {account} \n") runfile.write('#PBS -q regular \n') - runfile.write(f"#PBS -l select={number_of_nodes}:ncpus=tasks_per_node}:mpiprocs={tasks_per_node} \n") + runfile.write(f"#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node} \n") elif machine == 'casper': attribs = {'mpilib': 'default'} runfile.write('#PBS -l walltime=1:00:00 \n') @@ -183,6 +176,3 @@ def main (): print (f"echo Successfully created jobscript {jobscript_file}\n") sys.exit(0) - -if __name__ == "__main__": - main() diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py b/python/ctsm/toolchain/gen_mksurfdata_namelist.py similarity index 99% rename from tools/mksurfdata_esmf/gen_mksurfdata_namelist.py rename to python/ctsm/toolchain/gen_mksurfdata_namelist.py index d18e96f939..ca337d37ea 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py +++ b/python/ctsm/toolchain/gen_mksurfdata_namelist.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 """ gen_mksurfdata_namelist.py generates a namelist for use with the mksurfdata executable. For detailed instructions, see README. @@ -13,12 +12,6 @@ from datetime import datetime import netCDF4 -_CTSM_PYTHON = os.path.join(os.path.dirname(os.path.realpath(__file__)), - os.pardir, - os.pardir, - 'python') -sys.path.insert(1, _CTSM_PYTHON) - from ctsm.ctsm_logging import setup_logging_pre_config, add_logging_args, process_logging_args logger = logging.getLogger(__name__) @@ -738,6 +731,3 @@ def main (): print (f"Successfully created input namelist file {nlfname}") sys.exit(0) - -if __name__ == "__main__": - main() diff --git a/tools/README b/tools/README index f87655a81f..c65e694b98 100644 --- a/tools/README +++ b/tools/README @@ -198,8 +198,8 @@ III. Process sequence to create input datasets needed to run CTSM (See mksurfdata_esmf/README for more help on doing this) - gen_mksurfdata_build.sh to build - - gen_mksurfdata_namelist.py to build the namelist - - gen_mksurfdata_jobscript_single.py to build a batch script to run on cheyenne + - gen_mksurfdata_namelist to build the namelist + - gen_mksurfdata_jobscript_single to build a batch script to run on cheyenne - Submit the batch script just created above - This step uses the results of step (3) entered into the XML database @@ -211,8 +211,8 @@ III. Process sequence to create input datasets needed to run CTSM cd mksurfdata_esmf ./gen_mksurfdata_build.sh - ./gen_mksurfdata_namelist.py --res 0.9x1.25 --start-year 1850 --end-year 1850 - ./gen_mksurfdata_jobscript_single.py --number-of-nodes 24 --tasks-per-node 12 --namelist-file target.namelist + ./gen_mksurfdata_namelist --res 0.9x1.25 --start-year 1850 --end-year 1850 + ./gen_mksurfdata_jobscript_single --number-of-nodes 24 --tasks-per-node 12 --namelist-file target.namelist qsub mksurfdata_jobscript_single NOTE that surface dataset will be used by default for fatmgrid - and it will diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 877e40e993..274b4d862c 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -74,19 +74,19 @@ Running for a single submission: > cd ../..; ./py_env_create > conda activate ctsm_py; cd tools/mksurfdata_esmf # to generate your target namelist: -> ./gen_mksurfdata_namelist.py --help +> ./gen_mksurfdata_namelist --help # for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: -> ./gen_mksurfdata_namelist.py --res --start-year --end-year +> ./gen_mksurfdata_namelist --res --start-year --end-year # IF FILES ARE MISSING FROM /inputdata, a target namelist will be generated # but with a generic name and with warning to run ./download_input_data next. # IF A SMALLER SET OF FILES IS STILL MISSING AFTER RUNNING ./download_input_data -# and rerunning ./gen_mksurfdata_namelist.py, then rerun -# ./gen_mksurfdata_namelist.py with --vic selected (and iteratively additional +# and rerunning ./gen_mksurfdata_namelist, then rerun +# ./gen_mksurfdata_namelist with --vic selected (and iteratively additional # options if still necessary) and rerun ./download_input_data until -# ./gen_mksurfdata_namelist.py finds all files. +# ./gen_mksurfdata_namelist finds all files. # to generate your target jobscript (again --help for instructions): -> ./gen_mksurfdata_jobscript_single.py --number-of-nodes 24 --tasks-per-node 12 --namelist-file target.namelist +> ./gen_mksurfdata_jobscript_single --number-of-nodes 24 --tasks-per-node 12 --namelist-file target.namelist > qsub mksurfdata_jobscript_single # Read note about regional grids below. @@ -94,11 +94,11 @@ Running for a single submission: Running for the generation of multiple datasets ======================= # Work in the ctsm_pylib environment, as explained in earlier section. -# gen_mksurfdata_jobscript_multi.py runs ./gen_mksurfdata_namelist.py for you +# gen_mksurfdata_jobscript_multi runs ./gen_mksurfdata_namelist for you # The regional grid 5x5_amazon may fail with 24 nodes. # Task geometry that worked: #PBS -l select=4:ncpus=36:mpiprocs=4 -> ./gen_mksurfdata_jobscript_multi.py --help -> ./gen_mksurfdata_jobscript_multi.py --number-of-nodes 24 --scenario all +> ./gen_mksurfdata_jobscript_multi --help +> ./gen_mksurfdata_jobscript_multi --number-of-nodes 24 --scenario all > qsub mksurfdata_jobscript_multi ================ diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi new file mode 100755 index 0000000000..be2cc7a00d --- /dev/null +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_multi @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +""" +This is a just top-level skeleton script that calls +gen_mksurfdata_jobscript_multi.py. +The original code (gen_mksurfdata_jobscript_multi.py) is located under the +python/ctsm/toolchain folder. + +For full instructions on how to run the code and different options, +please check the python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py file. + +To run this script the following packages are required: + - netCDF4 +---------------------------------------------------------------- +To see all available options for gen_mksurfdata_jobscript_multi + ./gen_mksurfdata_jobscript_multi --help +---------------------------------------------------------------- +Instructions for running using the conda python environments: +../../py_env_create +conda activate ctsm_py +""" + +import os +import sys + +# -- add python/ctsm to path +_CTSM_PYTHON = os.path.join( + os.path.dirname(os.path.realpath(__file__)), os.pardir, os.pardir, "python" +) +sys.path.insert(1, _CTSM_PYTHON) + +from ctsm.toolchain.gen_mksurfdata_jobscript_multi import main + +if __name__ == "__main__": + main() diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single new file mode 100755 index 0000000000..a9b510962c --- /dev/null +++ b/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +""" +This is a just top-level skeleton script that calls +gen_mksurfdata_jobscript_single.py. +The original code (gen_mksurfdata_jobscript_single.py) is located under the +python/ctsm/toolchain folder. + +For full instructions on how to run the code and different options, +please check the python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py file. + +To run this script the following packages are required: + - netCDF4 +---------------------------------------------------------------- +To see all available options for gen_mksurfdata_jobscript_single + ./gen_mksurfdata_jobscript_single --help +---------------------------------------------------------------- +Instructions for running using the conda python environments: +../../py_env_create +conda activate ctsm_py +""" + +import os +import sys + +# -- add python/ctsm to path +_CTSM_PYTHON = os.path.join( + os.path.dirname(os.path.realpath(__file__)), os.pardir, os.pardir, "python" +) +sys.path.insert(1, _CTSM_PYTHON) + +from ctsm.toolchain.gen_mksurfdata_jobscript_single import main + +if __name__ == "__main__": + main() diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist b/tools/mksurfdata_esmf/gen_mksurfdata_namelist new file mode 100755 index 0000000000..e3688f7cb0 --- /dev/null +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +""" +This is a just top-level skeleton script that calls +gen_mksurfdata_namelist.py. +The original code (gen_mksurfdata_namelist.py) is located under the +python/ctsm/toolchain folder. + +For full instructions on how to run the code and different options, +please check the python/ctsm/toolchain/gen_mksurfdata_namelist.py file. + +To run this script the following packages are required: + - netCDF4 +---------------------------------------------------------------- +To see all available options for gen_mksurfdata_namelist + ./gen_mksurfdata_namelist --help +---------------------------------------------------------------- +Instructions for running using the conda python environments: +../../py_env_create +conda activate ctsm_py +""" + +import os +import sys + +# -- add python/ctsm to path +_CTSM_PYTHON = os.path.join( + os.path.dirname(os.path.realpath(__file__)), os.pardir, os.pardir, "python" +) +sys.path.insert(1, _CTSM_PYTHON) + +from ctsm.toolchain.gen_mksurfdata_namelist import main + +if __name__ == "__main__": + main() From 05f264a5a870b29088091989d201f9f065c2e4fd Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 11 Oct 2023 18:06:48 -0600 Subject: [PATCH 377/614] Remove the .py from the top level script names --- cime_config/SystemTests/mksurfdataesmf.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index af783850ba..9756ff4bf2 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -7,7 +7,7 @@ memory on cheyenne. Currently casper complains that `git -C` is not a valid option. -I added -C to the `git describe` in gen_mksurfdata_namelist.py for this +I added -C to the `git describe` in gen_mksurfdata_namelist for this system test to work. """ import os @@ -61,9 +61,9 @@ def build_phase(self, sharedlib_only=False, model_only=False): build_script_path = os.path.join(self._tool_path, 'gen_mksurfdata_build.sh') nml_script_path = os.path.join(self._tool_path, - 'gen_mksurfdata_namelist.py') + 'gen_mksurfdata_namelist') gen_jobscript_path = os.path.join(self._tool_path, - 'gen_mksurfdata_jobscript_single.py') + 'gen_mksurfdata_jobscript_single') gen_mksurfdata_namelist = f'{nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}' gen_mksurfdata_jobscript = f'{gen_jobscript_path} --number-of-nodes 12 --tasks-per-node 12 --namelist-file {self._fsurdat_namelist}' From fdf72cd011e2ba318987a1e100efc5a1847c9d04 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 11 Oct 2023 18:08:36 -0600 Subject: [PATCH 378/614] Run gen_mksurfdata_ scripts through black --- .../gen_mksurfdata_jobscript_multi.py | 356 ++++++++------ .../gen_mksurfdata_jobscript_single.py | 112 +++-- .../ctsm/toolchain/gen_mksurfdata_namelist.py | 437 +++++++++--------- 3 files changed, 519 insertions(+), 386 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 4f6e77f6b3..180d9b6e80 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -8,36 +8,39 @@ import argparse import subprocess -valid_scenarios=["all", - "standard", - "global-present", - "global-present-low-res", - "global-present-nldas", - "global-hist-4x5", - "crop-tropics-present", - "crop", - "crop-global-present", - "crop-global-present-low-res", - "crop-global-present-ne16np4", - "crop-global-present-ne120np4", - "crop-global-present-0.125", - "crop-global-1850", - "crop-global-1850-low-res", - "crop-global-1850-ne16np4", - "crop-global-1850-ne120np4", - "crop-global-hist", - "crop-global-future", - "crop-global-SSP1-2.6", - "crop-global-SSP3-7.0", - "crop-global-SSP5-3.4", - "crop-global-SSP2-4.5", - "crop-global-SSP2-4.5-low-res", - "crop-global-SSP2-4.5-hi-res", - "crop-global-SSP1-1.9", - "crop-global-SSP4-3.4", - "crop-global-SSP4-6.0", - "crop-global-SSP5-8.5", - "crop-global-SSP5-8.5-other"] +valid_scenarios = [ + "all", + "standard", + "global-present", + "global-present-low-res", + "global-present-nldas", + "global-hist-4x5", + "crop-tropics-present", + "crop", + "crop-global-present", + "crop-global-present-low-res", + "crop-global-present-ne16np4", + "crop-global-present-ne120np4", + "crop-global-present-0.125", + "crop-global-1850", + "crop-global-1850-low-res", + "crop-global-1850-ne16np4", + "crop-global-1850-ne120np4", + "crop-global-hist", + "crop-global-future", + "crop-global-SSP1-2.6", + "crop-global-SSP3-7.0", + "crop-global-SSP5-3.4", + "crop-global-SSP2-4.5", + "crop-global-SSP2-4.5-low-res", + "crop-global-SSP2-4.5-hi-res", + "crop-global-SSP1-1.9", + "crop-global-SSP4-3.4", + "crop-global-SSP4-6.0", + "crop-global-SSP5-8.5", + "crop-global-SSP5-8.5-other", +] + def get_parser(): """ @@ -50,7 +53,8 @@ def get_parser(): parser.print_usage = parser.print_help parser.add_argument( - '-v', '--verbose', + "-v", + "--verbose", help="ncrease output verbosity", action="store_true", ) @@ -60,7 +64,7 @@ def get_parser(): action="store", dest="account", required=False, - default="P93300606" + default="P93300606", ) parser.add_argument( "--number-of-nodes", @@ -108,11 +112,12 @@ def get_parser(): action="store", dest="jobscript_file", required=False, - default="mksurfdata_jobscript_multi" + default="mksurfdata_jobscript_multi", ) return parser -def main (): + +def main(): """ See docstring at the top. """ @@ -132,38 +137,45 @@ def main (): # Determine target list # -------------------------- target_list = [] - if scenario == 'all': - target_list = ["global-present", - "crop-global-present", - "crop-global-1850", - "crop-global-hist", - "crop-tropics-present", - "crop-global-SSP1-2.6", - "crop-global-SSP3-7.0", - "crop-global-SSP5-3.4", - "crop-global-SSP2-4.5", - "crop-global-SSP1-1.9", - "crop-global-SSP4-3.4", - "crop-global-SSP4-6.0", - "crop-global-SSP5-8.5"], - elif scenario == 'standard': - target_list = ["global-present", - "global-present-nldas", - ], + if scenario == "all": + target_list = ( + [ + "global-present", + "crop-global-present", + "crop-global-1850", + "crop-global-hist", + "crop-tropics-present", + "crop-global-SSP1-2.6", + "crop-global-SSP3-7.0", + "crop-global-SSP5-3.4", + "crop-global-SSP2-4.5", + "crop-global-SSP1-1.9", + "crop-global-SSP4-3.4", + "crop-global-SSP4-6.0", + "crop-global-SSP5-8.5", + ], + ) + elif scenario == "standard": + target_list = ( + [ + "global-present", + "global-present-nldas", + ], + ) elif scenario == "crop": - target_list = ["crop-global-present", - "crop-global-1850", - "crop-global-hist"] + target_list = ["crop-global-present", "crop-global-1850", "crop-global-hist"] elif scenario == "crop-global-future": - target_list = ["crop-global-SSP1-2.6", - "crop-global-SSP3-7.0", - "crop-global-SSP5-3.4", - "crop-global-SSP2-4.5", - "crop-global-SSP1-1.9", - "crop-global-SSP4-3.4", - "crop-global-SSP4-6.0", - "crop-global-SSP5-8.5", - "crop-global-SSP5-8.5-other"] + target_list = [ + "crop-global-SSP1-2.6", + "crop-global-SSP3-7.0", + "crop-global-SSP5-3.4", + "crop-global-SSP2-4.5", + "crop-global-SSP1-1.9", + "crop-global-SSP4-3.4", + "crop-global-SSP4-6.0", + "crop-global-SSP5-8.5", + "crop-global-SSP5-8.5-other", + ] elif scenario == "tropics": target_list = ["crop-tropics-present"] else: @@ -173,49 +185,129 @@ def main (): # Determine resolution sets that are referenced in commands # -------------------------- resolution_dict = { - "standard_res_no_crop" : ["0.9x1.25","1.9x2.5"], - "low_res_no_crop" : ["10x15"], - "low_res_all" : ['10x15', 'ne3np4.pg3'], - "hi_res_all" : ['ne120np4.pg3'], - "standard_res" : ['0.9x1.25','1.9x2.5','C96', 'ne30np4.pg3', 'mpasa120'], - "low_res" : ['10x15', '4x5', 'ne3np4.pg3', 'ne5np4.pg3', 'C24', 'mpasa480'], - "4x5_res" : ['10x15', '4x5', 'C24', 'mpasa480'], - "nldas_res" : ['0.125nldas2'], - "5x5_amazon_res" : ['5x5_amazon'], - "ne16np4_res" : ['C48', 'ne16np4'], - "ne120np4_res" : ['ne120np4.pg3', - 'ne0np4.ARCTICGRIS.ne30x8','ne0np4.ARCTIC.ne30x4', 'ne0np4CONUS.ne30x8'], + "standard_res_no_crop": ["0.9x1.25", "1.9x2.5"], + "low_res_no_crop": ["10x15"], + "low_res_all": ["10x15", "ne3np4.pg3"], + "hi_res_all": ["ne120np4.pg3"], + "standard_res": ["0.9x1.25", "1.9x2.5", "C96", "ne30np4.pg3", "mpasa120"], + "low_res": ["10x15", "4x5", "ne3np4.pg3", "ne5np4.pg3", "C24", "mpasa480"], + "4x5_res": ["10x15", "4x5", "C24", "mpasa480"], + "nldas_res": ["0.125nldas2"], + "5x5_amazon_res": ["5x5_amazon"], + "ne16np4_res": ["C48", "ne16np4"], + "ne120np4_res": [ + "ne120np4.pg3", + "ne0np4.ARCTICGRIS.ne30x8", + "ne0np4.ARCTIC.ne30x4", + "ne0np4CONUS.ne30x8", + ], } # -------------------------- # Determine commands for each target list # -------------------------- - dataset_dict={"global-present" : ("--start-year 2000 --end-year 2000 --nocrop --vic --res", "standard_res_no_crop"), - "global-present-low-res" : ("--start-year 2000 --end-year 2000 --nocrop --vic --res", "low_res_no_crop"), - "global-present-nldas" : ("--start-year 2000 --end-year 2000 --nocrop --vic --res", "nldas_res"), - "global-hist-4x5" : ("--start-year 1850 --end-year 2015 --nocrop --res", "4x5_res"), - "crop-tropics-present" : ("--start-year 2000 --end-year 2000 --res", "5x5_amazon_res"), - "crop-global-present" : ("--start-year 2000 --end-year 2000 --res", "standard_res"), - "crop-global-present-low-res" : ("--start-year 2000 --end-year 2000 --res", "low_res"), - "crop-global-present-ne16np4" : ("--start-year 2000 --end-year 2000 --res", "ne16np4_res"), - "crop-global-present-ne120np4" : ("--start-year 2000 --end-year 2000 --res", "ne120np4_res"), - "crop-global-present-0.125" : ("--start-year 2000 --end-year 2000 --hirespft --res", "nldas_res"), - "crop-global-1850" : ("--start-year 1850 --end-year 1850 --res", "standard_res"), - "crop-global-1850-low-res" : ("--start-year 1850 --end-year 1850 --res", "low_res"), - "crop-global-1850-ne16np4" : ("--start-year 1850 --end-year 1850 --res", "ne16np4_res"), - "crop-global-1850-ne120np4" : ("--start-year 1850 --end-year 1850 --res", "ne120np4_res"), - "crop-global-hist" : ("--start-year 1850 --end-year 2015 --nosurfdata --res", "standard_res"), - "crop-global-SSP1-1.9" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-1.9 --res", "standard_res"), - "crop-global-SSP1-2.6" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-2.6 --res", "standard_res"), - "crop-global-SSP2-4.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", "standard_res"), - "crop-global-SSP2-4.5-low-res" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", "low_res_all"), - "crop-global-SSP2-4.5-hi-res" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", "hi_res_all"), - "crop-global-SSP3-7.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP3-7.0 --res", "standard_res"), - "crop-global-SSP4-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-3.4 --res", "standard_res"), - "crop-global-SSP4-6.0" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-6.0 --res", "standard_res"), - "crop-global-SSP5-3.4" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-3.4 --res", "standard_res"), - "crop-global-SSP5-8.5" : ("--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-8.5 --res", "standard_res"), - } + dataset_dict = { + "global-present": ( + "--start-year 2000 --end-year 2000 --nocrop --vic --res", + "standard_res_no_crop", + ), + "global-present-low-res": ( + "--start-year 2000 --end-year 2000 --nocrop --vic --res", + "low_res_no_crop", + ), + "global-present-nldas": ( + "--start-year 2000 --end-year 2000 --nocrop --vic --res", + "nldas_res", + ), + "global-hist-4x5": ( + "--start-year 1850 --end-year 2015 --nocrop --res", + "4x5_res", + ), + "crop-tropics-present": ( + "--start-year 2000 --end-year 2000 --res", + "5x5_amazon_res", + ), + "crop-global-present": ( + "--start-year 2000 --end-year 2000 --res", + "standard_res", + ), + "crop-global-present-low-res": ( + "--start-year 2000 --end-year 2000 --res", + "low_res", + ), + "crop-global-present-ne16np4": ( + "--start-year 2000 --end-year 2000 --res", + "ne16np4_res", + ), + "crop-global-present-ne120np4": ( + "--start-year 2000 --end-year 2000 --res", + "ne120np4_res", + ), + "crop-global-present-0.125": ( + "--start-year 2000 --end-year 2000 --hirespft --res", + "nldas_res", + ), + "crop-global-1850": ( + "--start-year 1850 --end-year 1850 --res", + "standard_res", + ), + "crop-global-1850-low-res": ( + "--start-year 1850 --end-year 1850 --res", + "low_res", + ), + "crop-global-1850-ne16np4": ( + "--start-year 1850 --end-year 1850 --res", + "ne16np4_res", + ), + "crop-global-1850-ne120np4": ( + "--start-year 1850 --end-year 1850 --res", + "ne120np4_res", + ), + "crop-global-hist": ( + "--start-year 1850 --end-year 2015 --nosurfdata --res", + "standard_res", + ), + "crop-global-SSP1-1.9": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-1.9 --res", + "standard_res", + ), + "crop-global-SSP1-2.6": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-2.6 --res", + "standard_res", + ), + "crop-global-SSP2-4.5": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", + "standard_res", + ), + "crop-global-SSP2-4.5-low-res": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", + "low_res_all", + ), + "crop-global-SSP2-4.5-hi-res": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", + "hi_res_all", + ), + "crop-global-SSP3-7.0": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP3-7.0 --res", + "standard_res", + ), + "crop-global-SSP4-3.4": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-3.4 --res", + "standard_res", + ), + "crop-global-SSP4-6.0": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-6.0 --res", + "standard_res", + ), + "crop-global-SSP5-3.4": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-3.4 --res", + "standard_res", + ), + "crop-global-SSP5-8.5": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-8.5 --res", + "standard_res", + ), + } # -------------------------- # TODO Here, reuse code from gen_mksurfdata_jobscript_single.py @@ -226,33 +318,41 @@ def main (): # Make sure files exist or exit # -------------------------- if not os.path.exists("./tool_bld"): - print( "tool_bld directory does NOT exist -- build mksurdata_esmf before running this script -- using ./gen_mksurfdata_build.sh") + print( + "tool_bld directory does NOT exist -- build mksurdata_esmf before running this script -- using ./gen_mksurfdata_build.sh" + ) sys.exit(1) env_specific_script = "./tool_bld/.env_mach_specific.sh" if not os.path.exists(env_specific_script): - print( env_specific_script+" does NOT exist") + print(env_specific_script + " does NOT exist") sys.exit(1) mksurfdata = "./tool_bld/mksurfdata" if not os.path.exists(mksurfdata): - print( mksurfdata+" does NOT exist") + print(mksurfdata + " does NOT exist") sys.exit(1) # -------------------------- # Write run script # -------------------------- - with open(jobscript_file, "w",encoding='utf-8') as runfile: + with open(jobscript_file, "w", encoding="utf-8") as runfile: - runfile.write('#!/bin/bash \n') + runfile.write("#!/bin/bash \n") runfile.write(f"#PBS -A {account} \n") - runfile.write(f'#PBS -N mksrf_{scenario} \n') - runfile.write('#PBS -j oe \n') - runfile.write('#PBS -k eod \n') - runfile.write('#PBS -S /bin/bash \n') - runfile.write(f'#PBS -q {queue} \n') - runfile.write(f'#PBS -l walltime={walltime} \n') - runfile.write(f"#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node}:mem=109GB \n") - runfile.write(f'# This is a batch script to run a set of resolutions for mksurfdata_esmf {scenario} \n') - runfile.write('# NOTE: THIS SCRIPT IS AUTOMATICALLY GENERATED SO IN GENERAL YOU SHOULD NOT EDIT it!!\n\n') + runfile.write(f"#PBS -N mksrf_{scenario} \n") + runfile.write("#PBS -j oe \n") + runfile.write("#PBS -k eod \n") + runfile.write("#PBS -S /bin/bash \n") + runfile.write(f"#PBS -q {queue} \n") + runfile.write(f"#PBS -l walltime={walltime} \n") + runfile.write( + f"#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node}:mem=109GB \n" + ) + runfile.write( + f"# This is a batch script to run a set of resolutions for mksurfdata_esmf {scenario} \n" + ) + runfile.write( + "# NOTE: THIS SCRIPT IS AUTOMATICALLY GENERATED SO IN GENERAL YOU SHOULD NOT EDIT it!!\n\n" + ) runfile.write("\n") n_p = int(tasks_per_node) * int(number_of_nodes) @@ -260,26 +360,24 @@ def main (): # Run env_mach_specific.sh to control the machine dependent # environment including the paths to compilers and libraries # external to cime such as netcdf - runfile.write('. '+env_specific_script + '\n') + runfile.write(". " + env_specific_script + "\n") check = f"if [ $? != 0 ]; then echo 'Error running env_specific_script'; exit -4; fi" runfile.write(f"{check} \n") for target in target_list: res_set = dataset_dict[target][1] for res in resolution_dict[res_set]: - command = os.path.join(os.getcwd(), - "gen_mksurfdata_namelist.py") + command = os.path.join(os.getcwd(), "gen_mksurfdata_namelist.py") command = command + " " + dataset_dict[target][0] + " " + res - print (f"command is {command}") - commands = [x for x in command.split(' ') if x] + print(f"command is {command}") + commands = [x for x in command.split(" ") if x] try: - run_cmd = subprocess.run(commands, check=True, shell=True, - capture_output=True) + run_cmd = subprocess.run(commands, check=True, shell=True, capture_output=True) except subprocess.CalledProcessError as e: - sys.exit(f'{e} ERROR calling {command}') - output = run_cmd.stdout.decode('utf-8').strip() - namelist = output.split(' ')[-1] - print (f"generated namelist {namelist}") - output = f"time mpiexec_mpt -p \"%g:\" -np {n_p} {mksurfdata} < {namelist}" + sys.exit(f"{e} ERROR calling {command}") + output = run_cmd.stdout.decode("utf-8").strip() + namelist = output.split(" ")[-1] + print(f"generated namelist {namelist}") + output = f'time mpiexec_mpt -p "%g:" -np {n_p} {mksurfdata} < {namelist}' runfile.write(f"{output} \n") check = f"if [ $? != 0 ]; then echo 'Error running resolution {res}'; exit -4; fi" runfile.write(f"{check} \n") @@ -287,5 +385,5 @@ def main (): runfile.write(f"echo Successfully ran {jobscript_file}\n") - print (f"echo Successfully created jobscript {jobscript_file}\n") + print(f"echo Successfully created jobscript {jobscript_file}\n") sys.exit(0) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 69653e9afc..a937f3770c 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -15,6 +15,7 @@ logger = logging.getLogger(__name__) + def get_parser(): """ Get parser object for this script. @@ -35,7 +36,7 @@ def get_parser(): action="store", dest="account", required=False, - default="P93300606" + default="P93300606", ) parser.add_argument( "--number-of-nodes", @@ -60,8 +61,8 @@ def get_parser(): action="store", dest="machine", required=False, - choices=['cheyenne', 'casper', 'izumi'], - default='cheyenne' + choices=["cheyenne", "casper", "izumi"], + default="cheyenne", ) parser.add_argument( "--namelist-file", @@ -76,11 +77,12 @@ def get_parser(): action="store", dest="jobscript_file", required=False, - default="mksurfdata_jobscript_single" + default="mksurfdata_jobscript_single", ) return parser -def main (): + +def main(): """ See docstring at the top. """ @@ -99,80 +101,94 @@ def main (): # -------------------------- # Write run script (part 1) # -------------------------- - with open(jobscript_file, "w",encoding='utf-8') as runfile: - runfile.write('#!/bin/bash \n') - runfile.write('# Edit the batch directives for your batch system \n') - runfile.write(f'# Below are default batch directives for {machine} \n') - runfile.write('#PBS -N mksurfdata \n') - runfile.write('#PBS -j oe \n') - runfile.write('#PBS -k eod \n') - runfile.write('#PBS -S /bin/bash \n') - if machine == 'cheyenne': - attribs = {'mpilib': 'default'} - runfile.write('#PBS -l walltime=30:00 \n') + with open(jobscript_file, "w", encoding="utf-8") as runfile: + runfile.write("#!/bin/bash \n") + runfile.write("# Edit the batch directives for your batch system \n") + runfile.write(f"# Below are default batch directives for {machine} \n") + runfile.write("#PBS -N mksurfdata \n") + runfile.write("#PBS -j oe \n") + runfile.write("#PBS -k eod \n") + runfile.write("#PBS -S /bin/bash \n") + if machine == "cheyenne": + attribs = {"mpilib": "default"} + runfile.write("#PBS -l walltime=30:00 \n") runfile.write(f"#PBS -A {account} \n") - runfile.write('#PBS -q regular \n') - runfile.write(f"#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node} \n") - elif machine == 'casper': - attribs = {'mpilib': 'default'} - runfile.write('#PBS -l walltime=1:00:00 \n') + runfile.write("#PBS -q regular \n") + runfile.write( + f"#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node} \n" + ) + elif machine == "casper": + attribs = {"mpilib": "default"} + runfile.write("#PBS -l walltime=1:00:00 \n") runfile.write(f"#PBS -A {account} \n") - runfile.write('#PBS -q casper \n') - runfile.write(f'#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:' \ - f'mpiprocs={tasks_per_node}:mem=80GB \n') - elif machine == 'izumi': - attribs = {'mpilib': 'mvapich2'} - runfile.write('#PBS -l walltime=2:00:00 \n') - runfile.write('#PBS -q medium \n') - runfile.write(f'#PBS -l nodes={number_of_nodes}:ppn={tasks_per_node},mem=555GB -r n \n') + runfile.write("#PBS -q casper \n") + runfile.write( + f"#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:" + f"mpiprocs={tasks_per_node}:mem=80GB \n" + ) + elif machine == "izumi": + attribs = {"mpilib": "mvapich2"} + runfile.write("#PBS -l walltime=2:00:00 \n") + runfile.write("#PBS -q medium \n") + runfile.write(f"#PBS -l nodes={number_of_nodes}:ppn={tasks_per_node},mem=555GB -r n \n") tool_path = os.path.dirname(os.path.abspath(__file__)) runfile.write("\n") - runfile.write(f'cd {tool_path} \n') + runfile.write(f"cd {tool_path} \n") runfile.write("\n") # -------------------------- # Obtain mpirun command from env_mach_specific.xml # -------------------------- - bld_path = './tool_bld' + bld_path = "./tool_bld" # Get the ems_file object with standalone_configure=True # and the fake_case object with mpilib=attribs['mpilib'] # so as to use the get_mpirun function pointing to fake_case ems_file = EnvMachSpecific(bld_path, standalone_configure=True) - fake_case = FakeCase(compiler=None, mpilib=attribs['mpilib'], - debug=False, comp_interface=None) + fake_case = FakeCase( + compiler=None, mpilib=attribs["mpilib"], debug=False, comp_interface=None + ) total_tasks = int(tasks_per_node) * int(number_of_nodes) - cmd = ems_file.get_mpirun(fake_case, attribs, job='name', - overrides = {"total_tasks" : total_tasks,}) + cmd = ems_file.get_mpirun( + fake_case, + attribs, + job="name", + overrides={ + "total_tasks": total_tasks, + }, + ) # cmd is a tuple: # cmd[0] contains the mpirun command (eg mpirun, mpiexe, etc) as string # cmd[1] contains a list of strings that we append as options to cmd[0] # The replace function removes unnecessary characters that appear in # some such options - executable = f'{cmd[0]} {" ".join(cmd[1])}'.replace('ENV{', ''). \ - replace('}', '') + executable = f'{cmd[0]} {" ".join(cmd[1])}'.replace("ENV{", "").replace("}", "") - mksurfdata_path = os.path.join(bld_path, 'mksurfdata') - env_mach_path = os.path.join(bld_path, '.env_mach_specific.sh') + mksurfdata_path = os.path.join(bld_path, "mksurfdata") + env_mach_path = os.path.join(bld_path, ".env_mach_specific.sh") # -------------------------- # Write run script (part 2) # -------------------------- - runfile.write('# Run env_mach_specific.sh to control the machine ' \ - 'dependent environment including the paths to ' \ - 'compilers and libraries external to cime such as netcdf') - runfile.write(f'\n. {env_mach_path}\n') + runfile.write( + "# Run env_mach_specific.sh to control the machine " + "dependent environment including the paths to " + "compilers and libraries external to cime such as netcdf" + ) + runfile.write(f"\n. {env_mach_path}\n") check = f'if [ $? != 0 ]; then echo "Error running env_mach_specific"; exit -4; fi' runfile.write(f"{check} \n") - runfile.write('# Edit the mpirun command to use the MPI executable ' \ - 'on your system and the arguments it requires \n') - output = f'{executable} {mksurfdata_path} < {namelist_file}' + runfile.write( + "# Edit the mpirun command to use the MPI executable " + "on your system and the arguments it requires \n" + ) + output = f"{executable} {mksurfdata_path} < {namelist_file}" runfile.write(f"{output} \n") - logger.info('run command is %s', output) + logger.info("run command is %s", output) check = f'if [ $? != 0 ]; then echo "Error running resolution {res}"; exit -4; fi' runfile.write(f"{check} \n") runfile.write(f"echo Successfully ran resolution\n") - print (f"echo Successfully created jobscript {jobscript_file}\n") + print(f"echo Successfully created jobscript {jobscript_file}\n") sys.exit(0) diff --git a/python/ctsm/toolchain/gen_mksurfdata_namelist.py b/python/ctsm/toolchain/gen_mksurfdata_namelist.py index ca337d37ea..2e37687477 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_namelist.py +++ b/python/ctsm/toolchain/gen_mksurfdata_namelist.py @@ -17,9 +17,20 @@ logger = logging.getLogger(__name__) # valid options for SSP/RCP scenarios -valid_opts = {'ssp-rcp': ['SSP1-2.6', 'SSP3-7.0', 'SSP5-3.4', 'SSP2-4.5', - 'SSP1-1.9', 'SSP4-3.4', 'SSP4-6.0', 'SSP5-8.5', - 'none']} +valid_opts = { + "ssp-rcp": [ + "SSP1-2.6", + "SSP3-7.0", + "SSP5-3.4", + "SSP2-4.5", + "SSP1-1.9", + "SSP4-3.4", + "SSP4-6.0", + "SSP5-8.5", + "none", + ] +} + def get_parser(): """ @@ -37,9 +48,11 @@ def get_parser(): parser.add_argument( "--start-year", - help = textwrap.dedent('''\ + help=textwrap.dedent( + """\ Simulation start year. - [Required]'''), + [Required]""" + ), action="store", dest="start_year", required=True, @@ -47,9 +60,11 @@ def get_parser(): ) parser.add_argument( "--end-year", - help = textwrap.dedent('''\ + help=textwrap.dedent( + """\ Simulation end year. - [Required]'''), + [Required]""" + ), action="store", dest="end_year", required=True, @@ -89,7 +104,7 @@ def get_parser(): action="store", dest="force_model_mesh_nx", required=False, - default=None + default=None, ) parser.add_argument( "--model-mesh-ny", @@ -102,7 +117,7 @@ def get_parser(): action="store", dest="force_model_mesh_ny", required=False, - default=None + default=None, ) parser.add_argument( "--glc-nec", @@ -237,7 +252,8 @@ def get_parser(): ) return parser -def main (): + +def main(): """ See docstring at the top. """ @@ -261,68 +277,81 @@ def main (): glc_nec = args.glc_nec if args.hres_pft: - if (start_year == 1850 and end_year == 1850) or \ - (start_year == 2005 and end_year == 2005): - hires_pft = 'on' + if (start_year == 1850 and end_year == 1850) or (start_year == 2005 and end_year == 2005): + hires_pft = "on" else: - error_msg = 'ERROR: for --hires_pft you must set both start-year ' \ - 'and end-year to 1850 or to 2005' + error_msg = ( + "ERROR: for --hires_pft you must set both start-year " + "and end-year to 1850 or to 2005" + ) sys.exit(error_msg) else: - hires_pft = 'off' + hires_pft = "off" if args.hres_soitex: - hires_soitex = 'on' + hires_soitex = "on" else: - hires_soitex = 'off' + hires_soitex = "off" verbose = args.verbose if force_model_mesh_file is not None: # open mesh_file to read element_count and, if available, orig_grid_dims - mesh_file = netCDF4.Dataset(force_model_mesh_file, 'r') - element_count = mesh_file.dimensions['elementCount'].size - if 'origGridDims' in mesh_file.variables: - orig_grid_dims = mesh_file.variables['origGridDims'] - if int(force_model_mesh_nx) == orig_grid_dims[0] and \ - int(force_model_mesh_ny) == orig_grid_dims[1]: + mesh_file = netCDF4.Dataset(force_model_mesh_file, "r") + element_count = mesh_file.dimensions["elementCount"].size + if "origGridDims" in mesh_file.variables: + orig_grid_dims = mesh_file.variables["origGridDims"] + if ( + int(force_model_mesh_nx) == orig_grid_dims[0] + and int(force_model_mesh_ny) == orig_grid_dims[1] + ): mesh_file.close() else: - error_msg = 'ERROR: Found variable origGridDims in ' \ - f'{force_model_mesh_file} with values ' \ - f'{orig_grid_dims[:]} that do not agree with the ' \ - 'user-entered mesh_nx and mesh_ny values of ' \ - f'{[force_model_mesh_nx, force_model_mesh_ny]}.' + error_msg = ( + "ERROR: Found variable origGridDims in " + f"{force_model_mesh_file} with values " + f"{orig_grid_dims[:]} that do not agree with the " + "user-entered mesh_nx and mesh_ny values of " + f"{[force_model_mesh_nx, force_model_mesh_ny]}." + ) sys.exit(error_msg) elif force_model_mesh_nx is None or force_model_mesh_ny is None: - error_msg = 'ERROR: You set --model-mesh so you MUST ALSO ' \ - 'SET --model-mesh-nx AND --model-mesh-ny' + error_msg = ( + "ERROR: You set --model-mesh so you MUST ALSO " + "SET --model-mesh-nx AND --model-mesh-ny" + ) sys.exit(error_msg) # using force_model_mesh_nx and force_model_mesh_ny either from the # mesh file (see previous if statement) or the user-entered values if element_count != int(force_model_mesh_nx) * int(force_model_mesh_ny): - error_msg = 'ERROR: The product of ' \ - '--model-mesh-nx x --model-mesh-ny must equal ' \ - 'exactly elementCount in --model-mesh' + error_msg = ( + "ERROR: The product of " + "--model-mesh-nx x --model-mesh-ny must equal " + "exactly elementCount in --model-mesh" + ) sys.exit(error_msg) hostname = os.getenv("HOSTNAME") logname = os.getenv("LOGNAME") - logger.info('hostname is %s', hostname) - logger.info('logname is %s', logname) + logger.info("hostname is %s", hostname) + logger.info("logname is %s", logname) - if ssp_rcp == 'none': + if ssp_rcp == "none": if int(start_year) > 2015: - error_msg = 'ERROR: if start-year > 2015 must add an --ssp_rcp ' \ - 'argument that is not none: valid opts for ssp-rcp ' \ - f'are {valid_opts}' + error_msg = ( + "ERROR: if start-year > 2015 must add an --ssp_rcp " + "argument that is not none: valid opts for ssp-rcp " + f"are {valid_opts}" + ) sys.exit(error_msg) elif int(end_year) > 2015: - error_msg = 'ERROR: if end-year > 2015 must add an --ssp-rcp ' \ - 'argument that is not none: valid opts for ssp-rcp ' \ - f'are {valid_opts}' + error_msg = ( + "ERROR: if end-year > 2015 must add an --ssp-rcp " + "argument that is not none: valid opts for ssp-rcp " + f"are {valid_opts}" + ) sys.exit(error_msg) pft_years_ssp = "-999" @@ -343,20 +372,22 @@ def main (): elif int(start_year) >= 1850 and int(start_year) <= 2100 and int(end_year) <= 2100: pft_years = "1850-2015" pft_years_ssp = "2016-2100" - elif int(start_year) >= 2016 and int(start_year) <= 2100 and int(end_year) <=2100: + elif int(start_year) >= 2016 and int(start_year) <= 2100 and int(end_year) <= 2100: pft_years = "-999" pft_years_ssp = "2016-2100" else: - error_msg = f'ERROR: start_year is {start_year} and end_year is ' \ - f'{end_year}; expected start/end-year options are: ' \ - '- 1850, 2000, 2005 for time-slice options ' \ - '- in the range from 850 to 1849 ' \ - '- in the range from 1850 to 2100 ' \ - '- TODO in the range from 2101 to 2300 ' \ - '- OR user must set the potveg_flag ' + error_msg = ( + f"ERROR: start_year is {start_year} and end_year is " + f"{end_year}; expected start/end-year options are: " + "- 1850, 2000, 2005 for time-slice options " + "- in the range from 850 to 1849 " + "- in the range from 1850 to 2100 " + "- TODO in the range from 2101 to 2300 " + "- OR user must set the potveg_flag " + ) sys.exit(error_msg) - logger.info('pft_years = %s', pft_years) + logger.info("pft_years = %s", pft_years) # Create land-use txt file for a transient case. # Determine the run type and if a transient run create output landuse txt file @@ -364,19 +395,21 @@ def main (): run_type = "transient" else: run_type = "timeslice" - logger.info('run_type = %s', run_type) + logger.info("run_type = %s", run_type) # error check on glc_nec if (glc_nec <= 0) or (glc_nec >= 100): raise argparse.ArgumentTypeError("ERROR: glc_nec must be between 1 and 99.") # create attribute list for parsing xml file - attribute_list = {'hires_pft':hires_pft, - 'hires_soitex':hires_soitex, - 'pft_years':pft_years, - 'pft_years_ssp':pft_years_ssp, - 'ssp_rcp':ssp_rcp, - 'res':res} + attribute_list = { + "hires_pft": hires_pft, + "hires_soitex": hires_soitex, + "pft_years": pft_years, + "pft_years_ssp": pft_years_ssp, + "ssp_rcp": ssp_rcp, + "res": res, + } # create dictionary for raw data files names rawdata_files = {} @@ -384,16 +417,16 @@ def main (): # determine input rawdata _must_run_download_input_data = False tool_path = os.path.dirname(os.path.abspath(__file__)) - xml_path = os.path.join(tool_path, 'gen_mksurfdata_namelist.xml') + xml_path = os.path.join(tool_path, "gen_mksurfdata_namelist.xml") tree1 = ET.parse(xml_path) root = tree1.getroot() - logger.info('root.tag: %s', root.tag) - logger.info('root.attrib: %s', root.attrib) + logger.info("root.tag: %s", root.tag) + logger.info("root.attrib: %s", root.attrib) for child1 in root: max_match_num = -1 max_match_child = None for child2 in child1: - if child2.tag == 'entry': + if child2.tag == "entry": num_match = 0 for attrib in attribute_list: # Get the value of the attrib for the entry @@ -411,55 +444,56 @@ def main (): # TODO slevis: Are these if-statements backwards? # For years greater than 2015 - mksrf_fvegtyp_ssp must have a match if start_year <= 2015: - if 'mksrf_fvegtyp_ssp' not in child1.tag: - error_msg = f'ERROR: {child1.tag} has no matches' + if "mksrf_fvegtyp_ssp" not in child1.tag: + error_msg = f"ERROR: {child1.tag} has no matches" sys.exit(error_msg) else: continue else: # For years less than 2015 - mksrf_fvegtyp must have a match - if 'mksrf_fvegtyp' not in child1.tag: - error_msg = f'ERROR: {child1.tag} has no matches' + if "mksrf_fvegtyp" not in child1.tag: + error_msg = f"ERROR: {child1.tag} has no matches" sys.exit(error_msg) else: continue for item in max_match_child: - if item.tag == 'data_filename': + if item.tag == "data_filename": rawdata_files[child1.tag] = os.path.join(input_path, item.text) - if '%y' not in rawdata_files[child1.tag]: + if "%y" not in rawdata_files[child1.tag]: if not os.path.isfile(rawdata_files[child1.tag]): - print('WARNING: input data file ' \ - f'{rawdata_files[child1.tag]} for {child1.tag} ' \ - 'does not exist') - print('WARNING: run ./download_input_data to try TO ' \ - 'OBTAIN MISSING FILES') + print( + "WARNING: input data file " + f"{rawdata_files[child1.tag]} for {child1.tag} " + "does not exist" + ) + print( + "WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES" + ) _must_run_download_input_data = True - if item.tag == 'mesh_filename': + if item.tag == "mesh_filename": new_key = f"{child1.tag}_mesh" rawdata_files[new_key] = os.path.join(input_path, item.text) if not os.path.isfile(rawdata_files[new_key]): - print('WARNING: input mesh file ' \ - f'{rawdata_files[new_key]} does not exist') - print('WARNING: run ./download_input_data to try TO ' \ - 'OBTAIN MISSING FILES') + print("WARNING: input mesh file " f"{rawdata_files[new_key]} does not exist") + print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") _must_run_download_input_data = True - if item.tag == 'lake_filename': + if item.tag == "lake_filename": new_key = f"{child1.tag}_lake" rawdata_files[new_key] = os.path.join(input_path, item.text) - if item.tag == 'urban_filename': + if item.tag == "urban_filename": new_key = f"{child1.tag}_urban" rawdata_files[new_key] = os.path.join(input_path, item.text) - if item.tag == 'lookup_filename': + if item.tag == "lookup_filename": new_key = f"{child1.tag}_lookup" rawdata_files[new_key] = os.path.join(input_path, item.text) # determine output mesh - xml_path = os.path.join(tool_path, '../../ccs_config/component_grids_nuopc.xml') + xml_path = os.path.join(tool_path, "../../ccs_config/component_grids_nuopc.xml") tree2 = ET.parse(xml_path) root = tree2.getroot() model_mesh = "" @@ -467,14 +501,14 @@ def main (): for _, value in child1.attrib.items(): if value == res: for child2 in child1: - if child2.tag == 'mesh': + if child2.tag == "mesh": model_mesh = child2.text - rawdata_files['mksrf_fgrid_mesh'] = \ - os.path.join(input_path, - model_mesh.strip('$DIN_LOC_ROOT/')) - if child2.tag == 'nx': + rawdata_files["mksrf_fgrid_mesh"] = os.path.join( + input_path, model_mesh.strip("$DIN_LOC_ROOT/") + ) + if child2.tag == "nx": rawdata_files["mksrf_fgrid_mesh_nx"] = child2.text - if child2.tag == 'ny': + if child2.tag == "ny": rawdata_files["mksrf_fgrid_mesh_ny"] = child2.text if not model_mesh and force_model_mesh_file is None: @@ -483,19 +517,20 @@ def main (): for _, value in child1.attrib.items(): valid_grids.append(value) if res in valid_grids: - error_msg = 'ERROR: You have requested a valid grid for which ' \ - '../../ccs_config/component_grids_nuopc.xml does not include a mesh ' \ - 'file. For a regular regional or 1x1 grid, you may generate the ' \ - 'fsurdat file using the subset_data tool instead. Alternatively ' \ - 'and definitely for curvilinear grids, you may generate ' \ - 'a mesh file using the workflow currently (2022/7) described in ' \ - 'https://github.com/ESCOMP/CTSM/issues/1773#issuecomment-1163432584' \ - 'TODO Reminder to ultimately place these workflow instructions in ' \ - "the User's Guide." + error_msg = ( + "ERROR: You have requested a valid grid for which " + "../../ccs_config/component_grids_nuopc.xml does not include a mesh " + "file. For a regular regional or 1x1 grid, you may generate the " + "fsurdat file using the subset_data tool instead. Alternatively " + "and definitely for curvilinear grids, you may generate " + "a mesh file using the workflow currently (2022/7) described in " + "https://github.com/ESCOMP/CTSM/issues/1773#issuecomment-1163432584" + "TODO Reminder to ultimately place these workflow instructions in " + "the User's Guide." + ) sys.exit(error_msg) else: - error_msg = f'ERROR: invalid input res {res}; ' \ - f'valid grid values are {valid_grids}' + error_msg = f"ERROR: invalid input res {res}; " f"valid grid values are {valid_grids}" sys.exit(error_msg) # Determine num_pft @@ -503,23 +538,23 @@ def main (): num_pft = "16" else: num_pft = "78" - logger.info('num_pft is %s', num_pft) + logger.info("num_pft is %s", num_pft) # Write out if surface dataset will be created if nosurfdata_flag: - logger.info('surface dataset will not be created') + logger.info("surface dataset will not be created") else: - logger.info('surface dataset will be created') + logger.info("surface dataset will be created") - if run_type == 'transient': - if ssp_rcp == 'none': - landuse_fname = \ - f"landuse_timeseries_hist_{start_year}-{end_year}_{num_pft}pfts.txt" + if run_type == "transient": + if ssp_rcp == "none": + landuse_fname = f"landuse_timeseries_hist_{start_year}-{end_year}_{num_pft}pfts.txt" else: - landuse_fname = \ - f"landuse_timeseries_{ssp_rcp}_{start_year}-{end_year}_{num_pft}pfts.txt" + landuse_fname = ( + f"landuse_timeseries_{ssp_rcp}_{start_year}-{end_year}_{num_pft}pfts.txt" + ) - with open(landuse_fname, "w", encoding='utf-8') as landuse_file: + with open(landuse_fname, "w", encoding="utf-8") as landuse_file: for year in range(start_year, end_year + 1): year_str = str(year) if year <= 2015: @@ -535,22 +570,16 @@ def main (): landuse_input_fnam2 = file2.replace("%y", year_str) landuse_input_fnam3 = file3.replace("%y", year_str) if not os.path.isfile(landuse_input_fname): - print('WARNING: landunit_input_fname: ' \ - f'{landuse_input_fname} does not exist') - print('WARNING: run ./download_input_data to try TO ' \ - 'OBTAIN MISSING FILES') + print("WARNING: landunit_input_fname: " f"{landuse_input_fname} does not exist") + print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") _must_run_download_input_data = True if not os.path.isfile(landuse_input_fnam2): - print('WARNING: landunit_input_fnam2: ' \ - f'{landuse_input_fnam2} does not exist') - print('WARNING: run ./download_input_data to try TO ' \ - 'OBTAIN MISSING FILES') + print("WARNING: landunit_input_fnam2: " f"{landuse_input_fnam2} does not exist") + print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") _must_run_download_input_data = True if not os.path.isfile(landuse_input_fnam3): - print('WARNING: landunit_input_fnam3: ' \ - f'{landuse_input_fnam3} does not exist') - print('WARNING: run ./download_input_data to try TO ' \ - 'OBTAIN MISSING FILES') + print("WARNING: landunit_input_fnam3: " f"{landuse_input_fnam3} does not exist") + print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") _must_run_download_input_data = True # -- Each line is written twice in the original perl code: @@ -561,31 +590,29 @@ def main (): landuse_file.write(landuse_line) landuse_file.write(landuse_lin2) landuse_file.write(landuse_lin3) - logger.debug('year : %s', year_str) + logger.debug("year : %s", year_str) logger.debug(landuse_line) print(f"Successfully created input landuse file {landuse_fname}") else: landuse_fname = "" time_stamp = datetime.today().strftime("%y%m%d") - if ssp_rcp == 'none': - ssp_rcp_name = 'hist' + if ssp_rcp == "none": + ssp_rcp_name = "hist" else: ssp_rcp_name = ssp_rcp if int(end_year) == int(start_year): - fdyndat = '' + fdyndat = "" else: - fdyndat = \ - f'landuse.timeseries_{res}_{ssp_rcp_name}_{start_year}-{end_year}_{num_pft}_c{time_stamp}.nc' + fdyndat = f"landuse.timeseries_{res}_{ssp_rcp_name}_{start_year}-{end_year}_{num_pft}_c{time_stamp}.nc" - prefix = \ - f'surfdata_{res}_{ssp_rcp_name}_{start_year}_{num_pft}pfts_c{time_stamp}.' + prefix = f"surfdata_{res}_{ssp_rcp_name}_{start_year}_{num_pft}pfts_c{time_stamp}." - nlfname = f'{prefix}namelist' - fsurdat = f'{prefix}nc' - fsurlog = f'{prefix}log' + nlfname = f"{prefix}namelist" + fsurdat = f"{prefix}nc" + fsurlog = f"{prefix}log" - git_desc_cmd = f'git -C {tool_path} describe' + git_desc_cmd = f"git -C {tool_path} describe" try: # The "git -C" option permits a system test to run this tool from # elsewhere while running the git command from the tool_path @@ -594,18 +621,18 @@ def main (): # In case the "git -C" option is unavailable, as on casper (2022/5/24) # Still, this does NOT allow the system test to work on machines # without git -C - logger.info('git -C option unavailable on casper as of 2022/7/2 %s', e) - gitdescribe = subprocess.check_output('git describe', shell=True).strip() - gitdescribe = gitdescribe.decode('utf-8') + logger.info("git -C option unavailable on casper as of 2022/7/2 %s", e) + gitdescribe = subprocess.check_output("git describe", shell=True).strip() + gitdescribe = gitdescribe.decode("utf-8") # The below two overrides are only used for testing an validation # it takes a long time to generate the mapping files # from 1km to the following two resolutions since the output mesh has so few points if res == "10x15": - mksrf_ftopostats_override = os.path.join(input_path, 'lnd', 'clm2', - 'rawdata', 'surfdata_topo_10x15_c220303.nc') - logger.info('will override mksrf_ftopostats with = %s', - mksrf_ftopostats_override) + mksrf_ftopostats_override = os.path.join( + input_path, "lnd", "clm2", "rawdata", "surfdata_topo_10x15_c220303.nc" + ) + logger.info("will override mksrf_ftopostats with = %s", mksrf_ftopostats_override) else: mksrf_ftopostats_override = "" @@ -613,7 +640,7 @@ def main (): # Write output namelist file # ---------------------------------------- - with open(nlfname, "w",encoding='utf-8') as nlfile: + with open(nlfname, "w", encoding="utf-8") as nlfile: nlfile.write("&mksurfdata_input \n") # ------------------- @@ -622,92 +649,84 @@ def main (): if force_model_mesh_file is None: mksrf_fgrid_mesh_nx = rawdata_files["mksrf_fgrid_mesh_nx"] mksrf_fgrid_mesh_ny = rawdata_files["mksrf_fgrid_mesh_ny"] - mksrf_fgrid_mesh = rawdata_files["mksrf_fgrid_mesh"] + mksrf_fgrid_mesh = rawdata_files["mksrf_fgrid_mesh"] else: mksrf_fgrid_mesh_nx = force_model_mesh_nx mksrf_fgrid_mesh_ny = force_model_mesh_ny - mksrf_fgrid_mesh = force_model_mesh_file - nlfile.write( f" mksrf_fgrid_mesh = \'{mksrf_fgrid_mesh}\' \n") - nlfile.write( f" mksrf_fgrid_mesh_nx = {mksrf_fgrid_mesh_nx} \n") - nlfile.write( f" mksrf_fgrid_mesh_ny = {mksrf_fgrid_mesh_ny} \n") - - for key,value in rawdata_files.items(): - if key == 'mksrf_ftopostats' and mksrf_ftopostats_override != '': - nlfile.write(f" mksrf_ftopostats_override = \'{mksrf_ftopostats_override}\' \n") - elif '_fvic' not in key and 'mksrf_fvegtyp' not in key and 'mksrf_fgrid' not in key: + mksrf_fgrid_mesh = force_model_mesh_file + nlfile.write(f" mksrf_fgrid_mesh = '{mksrf_fgrid_mesh}' \n") + nlfile.write(f" mksrf_fgrid_mesh_nx = {mksrf_fgrid_mesh_nx} \n") + nlfile.write(f" mksrf_fgrid_mesh_ny = {mksrf_fgrid_mesh_ny} \n") + + for key, value in rawdata_files.items(): + if key == "mksrf_ftopostats" and mksrf_ftopostats_override != "": + nlfile.write(f" mksrf_ftopostats_override = '{mksrf_ftopostats_override}' \n") + elif "_fvic" not in key and "mksrf_fvegtyp" not in key and "mksrf_fgrid" not in key: # write everything else - nlfile.write(f" {key} = \'{value}\' \n") + nlfile.write(f" {key} = '{value}' \n") if start_year <= 2015: - mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp"] - mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] - mksrf_fhrvtyp = rawdata_files["mksrf_fvegtyp"] - mksrf_fhrvtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] - mksrf_fpctlak = rawdata_files["mksrf_fvegtyp_lake"] - mksrf_furban = rawdata_files["mksrf_fvegtyp_urban"] + mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp"] + mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] + mksrf_fhrvtyp = rawdata_files["mksrf_fvegtyp"] + mksrf_fhrvtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] + mksrf_fpctlak = rawdata_files["mksrf_fvegtyp_lake"] + mksrf_furban = rawdata_files["mksrf_fvegtyp_urban"] else: - mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp_ssp"] - mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] - mksrf_fhrvtyp = rawdata_files["mksrf_fvegtyp_ssp"] - mksrf_fhrvtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] - mksrf_fpctlak = rawdata_files["mksrf_fvegtyp_ssp_lake"] - mksrf_furban = rawdata_files["mksrf_fvegtyp_ssp_urban"] - if '%y' in mksrf_fvegtyp: - mksrf_fvegtyp = mksrf_fvegtyp.replace("%y",str(start_year)) - if '%y' in mksrf_fhrvtyp: - mksrf_fhrvtyp = mksrf_fhrvtyp.replace("%y",str(start_year)) - if '%y' in mksrf_fpctlak: - mksrf_fpctlak = mksrf_fpctlak.replace("%y",str(start_year)) - if '%y' in mksrf_furban: - mksrf_furban = mksrf_furban.replace("%y",str(start_year)) + mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp_ssp"] + mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] + mksrf_fhrvtyp = rawdata_files["mksrf_fvegtyp_ssp"] + mksrf_fhrvtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] + mksrf_fpctlak = rawdata_files["mksrf_fvegtyp_ssp_lake"] + mksrf_furban = rawdata_files["mksrf_fvegtyp_ssp_urban"] + if "%y" in mksrf_fvegtyp: + mksrf_fvegtyp = mksrf_fvegtyp.replace("%y", str(start_year)) + if "%y" in mksrf_fhrvtyp: + mksrf_fhrvtyp = mksrf_fhrvtyp.replace("%y", str(start_year)) + if "%y" in mksrf_fpctlak: + mksrf_fpctlak = mksrf_fpctlak.replace("%y", str(start_year)) + if "%y" in mksrf_furban: + mksrf_furban = mksrf_furban.replace("%y", str(start_year)) if not os.path.isfile(mksrf_fvegtyp): - print('WARNING: input mksrf_fvegtyp file ' \ - f'{mksrf_fvegtyp} does not exist') - print('WARNING: run ./download_input_data to try TO ' \ - 'OBTAIN MISSING FILES') + print("WARNING: input mksrf_fvegtyp file " f"{mksrf_fvegtyp} does not exist") + print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") _must_run_download_input_data = True if not os.path.isfile(mksrf_fhrvtyp): - print('WARNING: input mksrf_fhrvtyp file ' \ - f'{mksrf_fhrvtyp} does not exist') - print('WARNING: run ./download_input_data to try TO ' \ - 'OBTAIN MISSING FILES') + print("WARNING: input mksrf_fhrvtyp file " f"{mksrf_fhrvtyp} does not exist") + print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") _must_run_download_input_data = True if not os.path.isfile(mksrf_fpctlak): - print('WARNING: input mksrf_fpctlak file ' \ - f'{mksrf_fpctlak} does not exist') - print('WARNING: run ./download_input_data to try TO ' \ - 'OBTAIN MISSING FILES') + print("WARNING: input mksrf_fpctlak file " f"{mksrf_fpctlak} does not exist") + print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") _must_run_download_input_data = True if not os.path.isfile(mksrf_furban): - print('WARNING: input mksrf_furban file ' \ - f'{mksrf_furban} does not exist') - print('WARNING: run ./download_input_data to try TO ' \ - 'OBTAIN MISSING FILES') + print("WARNING: input mksrf_furban file " f"{mksrf_furban} does not exist") + print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") _must_run_download_input_data = True - nlfile.write( f" mksrf_fvegtyp = \'{mksrf_fvegtyp}\' \n") - nlfile.write( f" mksrf_fvegtyp_mesh = \'{mksrf_fvegtyp_mesh}\' \n") - nlfile.write( f" mksrf_fhrvtyp = \'{mksrf_fhrvtyp}\' \n") - nlfile.write( f" mksrf_fhrvtyp_mesh = \'{mksrf_fhrvtyp_mesh}\' \n") - nlfile.write( f" mksrf_fpctlak = \'{mksrf_fpctlak}\' \n") - nlfile.write( f" mksrf_furban = \'{mksrf_furban}\' \n") + nlfile.write(f" mksrf_fvegtyp = '{mksrf_fvegtyp}' \n") + nlfile.write(f" mksrf_fvegtyp_mesh = '{mksrf_fvegtyp_mesh}' \n") + nlfile.write(f" mksrf_fhrvtyp = '{mksrf_fhrvtyp}' \n") + nlfile.write(f" mksrf_fhrvtyp_mesh = '{mksrf_fhrvtyp_mesh}' \n") + nlfile.write(f" mksrf_fpctlak = '{mksrf_fpctlak}' \n") + nlfile.write(f" mksrf_furban = '{mksrf_furban}' \n") if vic_flag: mksrf_fvic = rawdata_files["mksrf_fvic"] - nlfile.write(f" mksrf_fvic = \'{mksrf_fvic}\' \n") + nlfile.write(f" mksrf_fvic = '{mksrf_fvic}' \n") mksrf_fvic_mesh = rawdata_files["mksrf_fvic_mesh"] - nlfile.write(f" mksrf_fvic_mesh = \'{mksrf_fvic_mesh}\' \n") + nlfile.write(f" mksrf_fvic_mesh = '{mksrf_fvic_mesh}' \n") - nlfile.write( f" mksrf_fdynuse = \'{landuse_fname} \' \n") + nlfile.write(f" mksrf_fdynuse = '{landuse_fname} ' \n") # ------------------- # output data files # ------------------- if nosurfdata_flag: - nlfile.write(" fsurdat = \' \' \n") + nlfile.write(" fsurdat = ' ' \n") else: - nlfile.write(f" fsurdat = \'{fsurdat}'\n") - nlfile.write(f" fsurlog = \'{fsurlog}\' \n") - nlfile.write(f" fdyndat = \'{fdyndat}\' \n") + nlfile.write(f" fsurdat = '{fsurdat}'\n") + nlfile.write(f" fsurlog = '{fsurlog}' \n") + nlfile.write(f" fdyndat = '{fdyndat}' \n") # ------------------- # output data logicals @@ -716,18 +735,18 @@ def main (): nlfile.write(f" no_inlandwet = .{str(not inlandwet).lower()}. \n") nlfile.write(f" outnc_3dglc = .{str(glc_flag).lower()}. \n") nlfile.write(f" outnc_vic = .{str(vic_flag).lower()}. \n") - nlfile.write( " outnc_large_files = .false. \n") - nlfile.write( " outnc_double = .true. \n") - nlfile.write(f" logname = \'{logname}\' \n") - nlfile.write(f" hostname = \'{hostname}\' \n") - nlfile.write(f" gitdescribe = \'{gitdescribe}\' \n") + nlfile.write(" outnc_large_files = .false. \n") + nlfile.write(" outnc_double = .true. \n") + nlfile.write(f" logname = '{logname}' \n") + nlfile.write(f" hostname = '{hostname}' \n") + nlfile.write(f" gitdescribe = '{gitdescribe}' \n") nlfile.write("/ \n") if _must_run_download_input_data: - temp_nlfname = 'surfdata.namelist' + temp_nlfname = "surfdata.namelist" os.rename(nlfname, temp_nlfname) nlfname = temp_nlfname - print (f"Successfully created input namelist file {nlfname}") + print(f"Successfully created input namelist file {nlfname}") sys.exit(0) From 9c6dd8270e3b9e46f314bb767b70402085788bf2 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 11 Oct 2023 18:11:10 -0600 Subject: [PATCH 379/614] Add black formatting to git-blame ignore list --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index d0a83de93d..e4a5b14ea0 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -9,3 +9,4 @@ b88e1cd1b28e3609684c79a2ec0e88f26cfc362b 7dacad70e74e2ec97f6492d4e7a3cb5dd498bcd7 c7b7ca1d94ac19abb9ecea9fb5b712ddbdd6645d b565b55ce7a9f8d812a573d716a5fd3d78cfea81 +fdf72cd011e2ba318987a1e100efc5a1847c9d04 From 36c104204492cfa65692ef00abec5e991703398f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 11 Oct 2023 21:12:42 -0600 Subject: [PATCH 380/614] Fix some pylint issues --- .../ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 6 +++--- .../ctsm/toolchain/gen_mksurfdata_jobscript_single.py | 10 +++++----- python/ctsm/toolchain/gen_mksurfdata_namelist.py | 6 ++---- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 180d9b6e80..5b1e5ecbda 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -361,7 +361,7 @@ def main(): # environment including the paths to compilers and libraries # external to cime such as netcdf runfile.write(". " + env_specific_script + "\n") - check = f"if [ $? != 0 ]; then echo 'Error running env_specific_script'; exit -4; fi" + check = "if [ $? != 0 ]; then echo 'Error running env_specific_script'; exit -4; fi" runfile.write(f"{check} \n") for target in target_list: res_set = dataset_dict[target][1] @@ -372,8 +372,8 @@ def main(): commands = [x for x in command.split(" ") if x] try: run_cmd = subprocess.run(commands, check=True, shell=True, capture_output=True) - except subprocess.CalledProcessError as e: - sys.exit(f"{e} ERROR calling {command}") + except subprocess.CalledProcessError as error: + sys.exit(f"{error} ERROR calling {command}") output = run_cmd.stdout.decode("utf-8").strip() namelist = output.split(" ")[-1] print(f"generated namelist {namelist}") diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index a937f3770c..5a666cd722 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -10,8 +10,8 @@ from ctsm import add_cime_to_path # pylint: disable=unused-import from ctsm.ctsm_logging import setup_logging_pre_config, add_logging_args, process_logging_args -from CIME.XML.env_mach_specific import EnvMachSpecific -from CIME.BuildTools.configure import FakeCase +from CIME.XML.env_mach_specific import EnvMachSpecific # pylint: disable=import-error +from CIME.BuildTools.configure import FakeCase # pylint: disable=import-error logger = logging.getLogger(__name__) @@ -176,7 +176,7 @@ def main(): "compilers and libraries external to cime such as netcdf" ) runfile.write(f"\n. {env_mach_path}\n") - check = f'if [ $? != 0 ]; then echo "Error running env_mach_specific"; exit -4; fi' + check = 'if [ $? != 0 ]; then echo "Error running env_mach_specific"; exit -4; fi' runfile.write(f"{check} \n") runfile.write( "# Edit the mpirun command to use the MPI executable " @@ -186,9 +186,9 @@ def main(): runfile.write(f"{output} \n") logger.info("run command is %s", output) - check = f'if [ $? != 0 ]; then echo "Error running resolution {res}"; exit -4; fi' + check = f'if [ $? != 0 ]; then echo "Error running for namelist {namelist_file}"; exit -4; fi' runfile.write(f"{check} \n") - runfile.write(f"echo Successfully ran resolution\n") + runfile.write("echo Successfully ran resolution\n") print(f"echo Successfully created jobscript {jobscript_file}\n") sys.exit(0) diff --git a/python/ctsm/toolchain/gen_mksurfdata_namelist.py b/python/ctsm/toolchain/gen_mksurfdata_namelist.py index 2e37687477..c3ba2690b4 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_namelist.py +++ b/python/ctsm/toolchain/gen_mksurfdata_namelist.py @@ -293,8 +293,6 @@ def main(): else: hires_soitex = "off" - verbose = args.verbose - if force_model_mesh_file is not None: # open mesh_file to read element_count and, if available, orig_grid_dims mesh_file = netCDF4.Dataset(force_model_mesh_file, "r") @@ -617,11 +615,11 @@ def main(): # The "git -C" option permits a system test to run this tool from # elsewhere while running the git command from the tool_path gitdescribe = subprocess.check_output(git_desc_cmd, shell=True).strip() - except subprocess.CalledProcessError as e: + except subprocess.CalledProcessError as error: # In case the "git -C" option is unavailable, as on casper (2022/5/24) # Still, this does NOT allow the system test to work on machines # without git -C - logger.info("git -C option unavailable on casper as of 2022/7/2 %s", e) + logger.info("git -C option unavailable on casper as of 2022/7/2 %s", error) gitdescribe = subprocess.check_output("git describe", shell=True).strip() gitdescribe = gitdescribe.decode("utf-8") From 12cdecc93f1b4beb2a919bd560ff020d245fcc66 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 12 Oct 2023 01:36:55 -0600 Subject: [PATCH 381/614] Add a simple system test for gen_mksurfdata_namelist --- .../test/test_sys_gen_mksurfdata_namelist.py | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100755 python/ctsm/test/test_sys_gen_mksurfdata_namelist.py diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py b/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py new file mode 100755 index 0000000000..4e418b8e80 --- /dev/null +++ b/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +"""System tests for gen_mksurfdata_namelist + +""" + +import os +import re + +import unittest +import tempfile +import shutil +import sys + +from ctsm.path_utils import path_to_ctsm_root +from ctsm.toolchain.gen_mksurfdata_namelist import main +from ctsm import unit_testing + +# Allow test names that pylint doesn't like; otherwise hard to make them +# readable +# pylint: disable=invalid-name + + +class TestSysGenMkSurfNML(unittest.TestCase): + """System tests for gen_mksurfdata_namelist""" + + def setUp(self): + """ + """ + testinputs_path = os.path.join(path_to_ctsm_root(), "python/ctsm/test/testinputs") + self._testinputs_path = testinputs_path + self._tempdir = tempfile.mkdtemp() + + def tearDown(self): + """ + Remove temporary directory + """ + shutil.rmtree(self._tempdir, ignore_errors=True) + + def test_simple_namelist(self): + """ + Test that a standard simple namelist works + """ + sys.argv = [ + "gen_mksurfdata_namelist", + "--start-year", + "2000", + "--end-year", + "2000", + "--res", + "0.9x1.25", + ] + gen_mksurfdata_namelist.main() + + +if __name__ == "__main__": + unit_testing.setup_for_tests() + unittest.main() From de9a30bfbbec36f9dcacc4380005ab596da47af4 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 12 Oct 2023 08:46:30 -0600 Subject: [PATCH 382/614] Black format --- python/ctsm/test/test_sys_gen_mksurfdata_namelist.py | 3 +-- python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py | 8 +++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py b/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py index 4e418b8e80..cc5de0816c 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py @@ -25,8 +25,7 @@ class TestSysGenMkSurfNML(unittest.TestCase): """System tests for gen_mksurfdata_namelist""" def setUp(self): - """ - """ + """ """ testinputs_path = os.path.join(path_to_ctsm_root(), "python/ctsm/test/testinputs") self._testinputs_path = testinputs_path self._tempdir = tempfile.mkdtemp() diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 5a666cd722..4e69d83b5b 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -10,8 +10,8 @@ from ctsm import add_cime_to_path # pylint: disable=unused-import from ctsm.ctsm_logging import setup_logging_pre_config, add_logging_args, process_logging_args -from CIME.XML.env_mach_specific import EnvMachSpecific # pylint: disable=import-error -from CIME.BuildTools.configure import FakeCase # pylint: disable=import-error +from CIME.XML.env_mach_specific import EnvMachSpecific # pylint: disable=import-error +from CIME.BuildTools.configure import FakeCase # pylint: disable=import-error logger = logging.getLogger(__name__) @@ -186,7 +186,9 @@ def main(): runfile.write(f"{output} \n") logger.info("run command is %s", output) - check = f'if [ $? != 0 ]; then echo "Error running for namelist {namelist_file}"; exit -4; fi' + check = ( + f'if [ $? != 0 ]; then echo "Error running for namelist {namelist_file}"; exit -4; fi' + ) runfile.write(f"{check} \n") runfile.write("echo Successfully ran resolution\n") From 429c1d44279edff9a1470c5ef62eca406a5300ba Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 12 Oct 2023 08:47:15 -0600 Subject: [PATCH 383/614] Add to git-blame --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index e4a5b14ea0..5d418c4d07 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -10,3 +10,4 @@ b88e1cd1b28e3609684c79a2ec0e88f26cfc362b c7b7ca1d94ac19abb9ecea9fb5b712ddbdd6645d b565b55ce7a9f8d812a573d716a5fd3d78cfea81 fdf72cd011e2ba318987a1e100efc5a1847c9d04 +de9a30bfbbec36f9dcacc4380005ab596da47af4 From 4120145bc72463fbdb41adfbf237cbbe1426ac15 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 12 Oct 2023 09:03:02 -0600 Subject: [PATCH 384/614] Fix LILAC test which needed a setting for LND_TUNING_MODE for SATM which is needed for LILAC --- cime_config/config_component.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 8f6b47dd5b..96a1abea21 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -79,6 +79,7 @@ + clm4_5_CRUv7 clm4_5_CRUv7 clm4_5_CRUv7 clm4_5_GSWP3v1 @@ -92,6 +93,7 @@ clm5_0_CRUv7 clm5_0_CRUv7 + clm5_0_GSWP3v1 clm5_0_GSWP3v1 clm5_0_cam6.0 clm5_0_cam6.0 @@ -103,6 +105,7 @@ clm5_1_CRUv7 clm5_1_CRUv7 + clm5_1_GSWP3v1 clm5_1_GSWP3v1 clm5_1_cam6.0 clm5_1_cam6.0 From e045e5b152977783e45b48e611927013a8cf82dd Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 12 Oct 2023 13:41:13 -0600 Subject: [PATCH 385/614] Get the basic gen_mksurfdata_namelist test working --- python/ctsm/test/test_sys_gen_mksurfdata_namelist.py | 2 +- python/ctsm/toolchain/gen_mksurfdata_namelist.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py b/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py index cc5de0816c..8e6cd5dc6d 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py @@ -49,7 +49,7 @@ def test_simple_namelist(self): "--res", "0.9x1.25", ] - gen_mksurfdata_namelist.main() + main() if __name__ == "__main__": diff --git a/python/ctsm/toolchain/gen_mksurfdata_namelist.py b/python/ctsm/toolchain/gen_mksurfdata_namelist.py index c3ba2690b4..b2be00c1d1 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_namelist.py +++ b/python/ctsm/toolchain/gen_mksurfdata_namelist.py @@ -12,6 +12,7 @@ from datetime import datetime import netCDF4 +from ctsm.path_utils import path_to_ctsm_root from ctsm.ctsm_logging import setup_logging_pre_config, add_logging_args, process_logging_args logger = logging.getLogger(__name__) @@ -414,7 +415,7 @@ def main(): # determine input rawdata _must_run_download_input_data = False - tool_path = os.path.dirname(os.path.abspath(__file__)) + tool_path = os.path.join( path_to_ctsm_root(), "tools", "mksurfdata_esmf" ) xml_path = os.path.join(tool_path, "gen_mksurfdata_namelist.xml") tree1 = ET.parse(xml_path) root = tree1.getroot() @@ -747,4 +748,3 @@ def main(): nlfname = temp_nlfname print(f"Successfully created input namelist file {nlfname}") - sys.exit(0) From 48bb7c5f6f5c0eac99d657066943ddc5ba67a49a Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 12 Oct 2023 14:20:15 -0600 Subject: [PATCH 386/614] Simple test of more namelists that are expected to work --- .../test/test_sys_gen_mksurfdata_namelist.py | 72 +++++++++++++++++++ .../ctsm/toolchain/gen_mksurfdata_namelist.py | 2 +- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py b/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py index 8e6cd5dc6d..c226bed312 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py @@ -51,6 +51,78 @@ def test_simple_namelist(self): ] main() + def test_vic_nocrop_inlandwet_glc_namelist(self): + """ + Test that a namelist with several options on + """ + sys.argv = [ + "gen_mksurfdata_namelist", + "--start-year", + "1850", + "--end-year", + "1850", + "--res", + "1.9x2.5", + "--vic", + "--nocrop", + "--inlandwet", + "--glc", + ] + main() + + def test_hires_namelist(self): + """ + Test that a high resolution namelist works + """ + sys.argv = [ + "gen_mksurfdata_namelist", + "--start-year", + "1850", + "--end-year", + "1850", + "--res", + "mpasa15", + "--glc-nec", + "10", + "--hires_pft", + "--hires_soitex", + ] + main() + + def test_ssp_transient_namelist(self): + """ + Test that a SSP transient namelist works + """ + sys.argv = [ + "gen_mksurfdata_namelist", + "--start-year", + "1850", + "--end-year", + "2100", + "--res", + "ne30np4.pg3", + "--ssp-rcp", + "SSP2-4.5", + "--nosurfdata", + ] + main() + + def test_potveg_namelist(self): + """ + Test that a potential vegetation namelist works + """ + sys.argv = [ + "gen_mksurfdata_namelist", + "--start-year", + "1850", + "--end-year", + "1850", + "--res", + "4x5", + "--potveg_flag", + ] + main() + if __name__ == "__main__": unit_testing.setup_for_tests() diff --git a/python/ctsm/toolchain/gen_mksurfdata_namelist.py b/python/ctsm/toolchain/gen_mksurfdata_namelist.py index b2be00c1d1..4a2c9476d7 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_namelist.py +++ b/python/ctsm/toolchain/gen_mksurfdata_namelist.py @@ -415,7 +415,7 @@ def main(): # determine input rawdata _must_run_download_input_data = False - tool_path = os.path.join( path_to_ctsm_root(), "tools", "mksurfdata_esmf" ) + tool_path = os.path.join(path_to_ctsm_root(), "tools", "mksurfdata_esmf") xml_path = os.path.join(tool_path, "gen_mksurfdata_namelist.xml") tree1 = ET.parse(xml_path) root = tree1.getroot() From 21883555bd9f2bbba923c69e99729ec4d224ce29 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 12 Oct 2023 14:46:51 -0600 Subject: [PATCH 387/614] Fix some lint issues --- python/ctsm/test/test_sys_gen_mksurfdata_namelist.py | 8 ++++++-- python/ctsm/toolchain/gen_mksurfdata_namelist.py | 5 ++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py b/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py index c226bed312..06c583206e 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py @@ -5,7 +5,6 @@ """ import os -import re import unittest import tempfile @@ -25,7 +24,7 @@ class TestSysGenMkSurfNML(unittest.TestCase): """System tests for gen_mksurfdata_namelist""" def setUp(self): - """ """ + """Setp temporary directory to make the files in""" testinputs_path = os.path.join(path_to_ctsm_root(), "python/ctsm/test/testinputs") self._testinputs_path = testinputs_path self._tempdir = tempfile.mkdtemp() @@ -40,6 +39,7 @@ def test_simple_namelist(self): """ Test that a standard simple namelist works """ + # pylint: disable=no-self-use sys.argv = [ "gen_mksurfdata_namelist", "--start-year", @@ -55,6 +55,7 @@ def test_vic_nocrop_inlandwet_glc_namelist(self): """ Test that a namelist with several options on """ + # pylint: disable=no-self-use sys.argv = [ "gen_mksurfdata_namelist", "--start-year", @@ -74,6 +75,7 @@ def test_hires_namelist(self): """ Test that a high resolution namelist works """ + # pylint: disable=no-self-use sys.argv = [ "gen_mksurfdata_namelist", "--start-year", @@ -93,6 +95,7 @@ def test_ssp_transient_namelist(self): """ Test that a SSP transient namelist works """ + # pylint: disable=no-self-use sys.argv = [ "gen_mksurfdata_namelist", "--start-year", @@ -111,6 +114,7 @@ def test_potveg_namelist(self): """ Test that a potential vegetation namelist works """ + # pylint: disable=no-self-use sys.argv = [ "gen_mksurfdata_namelist", "--start-year", diff --git a/python/ctsm/toolchain/gen_mksurfdata_namelist.py b/python/ctsm/toolchain/gen_mksurfdata_namelist.py index 4a2c9476d7..2e504169cd 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_namelist.py +++ b/python/ctsm/toolchain/gen_mksurfdata_namelist.py @@ -603,7 +603,10 @@ def main(): if int(end_year) == int(start_year): fdyndat = "" else: - fdyndat = f"landuse.timeseries_{res}_{ssp_rcp_name}_{start_year}-{end_year}_{num_pft}_c{time_stamp}.nc" + fdyndat = ( + f"landuse.timeseries_{res}_{ssp_rcp_name}" + "_{start_year}-{end_year}_{num_pft}_c{time_stamp}.nc" + ) prefix = f"surfdata_{res}_{ssp_rcp_name}_{start_year}_{num_pft}pfts_c{time_stamp}." From 60bd47f8eee868a31dea0c0d2c815cffc5ff2e4f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 13 Oct 2023 17:33:59 -0600 Subject: [PATCH 388/614] Add a namelist option so the namelist filenames can be set and checked for --- .../test/test_sys_gen_mksurfdata_namelist.py | 133 ++++++++++-------- .../ctsm/toolchain/gen_mksurfdata_namelist.py | 29 ++-- 2 files changed, 92 insertions(+), 70 deletions(-) diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py b/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py index 06c583206e..575a2d4bbd 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py @@ -28,6 +28,13 @@ def setUp(self): testinputs_path = os.path.join(path_to_ctsm_root(), "python/ctsm/test/testinputs") self._testinputs_path = testinputs_path self._tempdir = tempfile.mkdtemp() + os.chdir(self._tempdir) + self.outfile = "surfdata.namelist" + sys.argv = [ + "gen_mksurfdata_namelist", + "--namelist", + self.outfile, + ] def tearDown(self): """ @@ -40,92 +47,102 @@ def test_simple_namelist(self): Test that a standard simple namelist works """ # pylint: disable=no-self-use - sys.argv = [ - "gen_mksurfdata_namelist", - "--start-year", - "2000", - "--end-year", - "2000", - "--res", - "0.9x1.25", - ] + sys.argv.extend( + [ + "--start-year", + "2000", + "--end-year", + "2000", + "--res", + "0.9x1.25", + ] + ) main() + self.assertTrue(os.path.exists(self.outfile), "Output surface dataset file should exist") def test_vic_nocrop_inlandwet_glc_namelist(self): """ - Test that a namelist with several options on + Test a namelist with several options on """ # pylint: disable=no-self-use - sys.argv = [ - "gen_mksurfdata_namelist", - "--start-year", - "1850", - "--end-year", - "1850", - "--res", - "1.9x2.5", - "--vic", - "--nocrop", - "--inlandwet", - "--glc", - ] + sys.argv.extend( + [ + "--start-year", + "1850", + "--end-year", + "1850", + "--res", + "1.9x2.5", + "--vic", + "--nocrop", + "--inlandwet", + "--glc", + ] + ) main() + self.assertTrue(os.path.exists(self.outfile), "Output surface dataset file should exist") def test_hires_namelist(self): """ Test that a high resolution namelist works """ # pylint: disable=no-self-use - sys.argv = [ - "gen_mksurfdata_namelist", - "--start-year", - "1850", - "--end-year", - "1850", - "--res", - "mpasa15", - "--glc-nec", - "10", - "--hires_pft", - "--hires_soitex", - ] + sys.argv.extend( + [ + "--start-year", + "1850", + "--end-year", + "1850", + "--res", + "mpasa15", + "--glc-nec", + "10", + "--hires_pft", + "--hires_soitex", + ] + ) main() + self.assertTrue(os.path.exists(self.outfile), "Output surface dataset file should exist") def test_ssp_transient_namelist(self): """ Test that a SSP transient namelist works """ # pylint: disable=no-self-use - sys.argv = [ - "gen_mksurfdata_namelist", - "--start-year", - "1850", - "--end-year", - "2100", - "--res", - "ne30np4.pg3", - "--ssp-rcp", - "SSP2-4.5", - "--nosurfdata", - ] + sys.argv.extend( + [ + "--start-year", + "1850", + "--end-year", + "2100", + "--res", + "ne30np4.pg3", + "--ssp-rcp", + "SSP2-4.5", + "--nosurfdata", + ] + ) main() + self.assertTrue(os.path.exists(self.outfile), "Output surface dataset file should exist") def test_potveg_namelist(self): """ Test that a potential vegetation namelist works """ # pylint: disable=no-self-use - sys.argv = [ - "gen_mksurfdata_namelist", - "--start-year", - "1850", - "--end-year", - "1850", - "--res", - "4x5", - "--potveg_flag", - ] + sys.argv.extend( + [ + "--start-year", + "1850", + "--end-year", + "1850", + "--res", + "4x5", + "--potveg_flag", + ] + ) main() + self.assertTrue(os.path.exists(self.outfile), "Output surface dataset file should exist") if __name__ == "__main__": diff --git a/python/ctsm/toolchain/gen_mksurfdata_namelist.py b/python/ctsm/toolchain/gen_mksurfdata_namelist.py index 2e504169cd..aee942eca7 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_namelist.py +++ b/python/ctsm/toolchain/gen_mksurfdata_namelist.py @@ -94,6 +94,18 @@ def get_parser(): required=False, default=None, ) + parser.add_argument( + "--namelist", + help=""" + name of output namelist filename + if NOT given the name will be the same as the surface + dataset name with a *.namelist extension rather than *.nc + """, + action="store", + dest="namelist_fname", + required=False, + default=None, + ) parser.add_argument( "--model-mesh-nx", help=""" @@ -130,17 +142,6 @@ def get_parser(): type=int, default=10, ) - parser.add_argument( - "--rundir", - help=""" - Directory to run in. - [default: %(default)s] - """, - action="store", - dest="run_dir", - required=False, - default=os.getcwd(), - ) parser.add_argument( "--ssp-rcp", help=""" @@ -610,7 +611,11 @@ def main(): prefix = f"surfdata_{res}_{ssp_rcp_name}_{start_year}_{num_pft}pfts_c{time_stamp}." - nlfname = f"{prefix}namelist" + if args.namelist_fname is None: + nlfname = f"{prefix}namelist" + else: + nlfname = args.namelist_fname + fsurdat = f"{prefix}nc" fsurlog = f"{prefix}log" From 9a270e84b89fe4fdea54f2942d573b546cbb0044 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 13 Oct 2023 19:19:50 -0600 Subject: [PATCH 389/614] Get the build script working for an existing build directory, and seperate out verbose status logging from without it --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 103 ++++++++++++------ 1 file changed, 68 insertions(+), 35 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index 8a4d89cb53..c000a1bc72 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -14,9 +14,9 @@ usage() { echo "[-v|--verbose] " echo " Run in verbose mode" echo "[-b|--blddir ] " - echo " Overwrites default, which is /tool_bld in the same directory as ./gen_mksurfdata_build.sh" + echo " Overrides default, which is /tool_bld in the same directory as ./gen_mksurfdata_build.sh" echo "[-m|--machine ] " - echo " Overwrites default MACH" + echo " Overrides default MACH" echo "***********************************************************************" } @@ -68,7 +68,7 @@ while [ $# -gt 0 ]; do exit 0 ;; -v|--verbose ) - verbose="Yes" + verbose="YES" ;; -b|--blddir ) blddir=$2 @@ -88,57 +88,90 @@ while [ $# -gt 0 ]; do done # Create /tool_bld directory -echo "cime Machine is: $MACH..." +if [ "$verbose" = "YES" ]; then + echo "cime Machine is: $MACH..." +fi if [ -d "$blddir" ]; then - echo "A /tool_bld directory exists; remove it to do a clean build..." - echo " or if you want to use the existing build do (assuming using bash):" - echo "cd $blddir" - echo ". .env_mach_specific.sh" - echo "make" - exit 1 + echo "Build directory exists so will skip the configure and cmake steps..." + existing_bld=YES +else + if [ "$verbose" = "YES" ]; then echo "Build directory does NOT exist so do the configure and cmake steps"; fi + existing_bld=No +fi +if [ "existing_bld" = "No" ]; then + mkdir $blddir fi -mkdir $blddir cd $blddir # Write pio_iotype to file with name pio_iotype.txt pio_iotype_filepath=../pio_iotype.txt # one up from /tool_bld -echo 'VALUE OF pio_iotype WRITTEN BY gen_mksurfdata_build.sh AND USED BY mksurfdata (i.e. THE FORTRAN EXECUTABLE):' > $pio_iotype_filepath -echo $pio_iotype >> $pio_iotype_filepath - -# Run the cime configure tool to figure out what modules need to be loaded -echo "Run cime configure for machine $MACH..." -# You can specify the non-default compiler and mpi-library by adding --compiler and --mpilib settings -if [ -z "$COMPILER" ] || [ -z "$MPILIB" ]; then - echo "configure for the default MPI-library and compiler..." - $cwd/../../cime/CIME/scripts/configure --macros-format CMake --machine $MACH +if [ ! -f "$pio_iotype_filepath" ]; then + echo 'VALUE OF pio_iotype WRITTEN BY gen_mksurfdata_build.sh AND USED BY mksurfdata (i.e. THE FORTRAN EXECUTABLE):' > $pio_iotype_filepath + echo $pio_iotype >> $pio_iotype_filepath else - echo "configure for the specific MPILIB=$MPILIB and COMPILER=$COMPILER..." - $cwd/../../cime/CIME/scripts/configure --macros-format CMake --machine $MACH --compiler $COMPILER --mpilib $MPILIB + echo "Use existing $pio_iotype_filepath file" fi -if [ $? != 0 ]; then - echo "Error doing configure for machine name: $MACH" - exit 1 +# +# If NOT an existing build, run the configure +# +if [ "existing_bld" = "No" ]; then + # Run the cime configure tool to figure out what modules need to be loaded + if [ "$verbose" = "YES" ]; then + echo "Run cime configure for machine $MACH..." + fi + # You can specify the non-default compiler and mpi-library by adding --compiler and --mpilib settings + if [ -z "$COMPILER" ] || [ -z "$MPILIB" ]; then + if [ "$verbose" = "YES" ]; then echo "configure for the default MPI-library and compiler..."; fi + options="" + else + if [ "$verbose" = "YES" ]; then echo "configure for the specific MPILIB=$MPILIB and COMPILER=$COMPILER..."; fi + options="-compiler $COMPILER --mpilib $MPILIB" + fi + if [ "$verbose" != "YES" ]; then + options="$options --silent" + fi + $cwd/../../cime/CIME/scripts/configure --macros-format CMake --machine $MACH $options + + if [ $? != 0 ]; then + echo "Error doing configure for machine name: $MACH" + exit 1 + fi fi + +# +# Create the machine environment (always) +# . ./.env_mach_specific.sh -echo "COMPILER = $COMPILER, MPILIB = $MPILIB, DEBUG = $DEBUG, OS = $OS" +if [ "$verbose" = "YES" ]; then echo "COMPILER = $COMPILER, MPILIB = $MPILIB, DEBUG = $DEBUG, OS = $OS"; fi if [ -z "$PIO" ]; then echo "The PIO directory for the PIO build is required and was not set in the configure" echo "Make sure a PIO build is provided for $MACH_$COMPILER with $MPILIB in config_machines" exit 1 fi -# Build the cmake files -echo "Do the cmake build..." -CC=mpicc FC=mpif90 cmake -DCMAKE_BUILD_TYPE=debug $cwd/src -if [ $? != 0 ]; then - echo "Error doing cmake for $MACH $MPILIB $COMPILER" - exit 1 +# Build the cmake files (only if not an existing build) +if [ "existing_bld" = "No" ]; then + if [ "$verbose" = "YES" ]; then + echo "Do the cmake build..." + options="-Wno-dev" + else + options="-Wno-dev -Wno-error=dev -Wno-deprecated -Wno-error=deprecated" + fi + CC=mpicc FC=mpif90 cmake $options -DCMAKE_BUILD_TYPE=Debug $cwd/src + if [ $? != 0 ]; then + echo "Error doing cmake for $MACH $MPILIB $COMPILER" + exit 1 + fi fi -# Build the executable -echo "Build the mksurfdata_esmf build..." -make VERBOSE=1 +# Build the executable (always) +if [ "$verbose" = "YES" ]; then + echo "Build mksurfdata_esmf..." + make VERBOSE=1 +else + make +fi if [ $? != 0 ]; then echo "Error doing make for $MACH $MPILIB $COMPILER" exit 1 From c8c1bf2a0a12fbab225ce17a2175d0cf41579076 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 17 Oct 2023 13:50:40 -0600 Subject: [PATCH 390/614] Add some error checking around the build paths, and a basic sys tester for jobscript_single --- ...est_sys_gen_mksurfdata_jobscript_single.py | 74 +++++++++++++++++++ .../gen_mksurfdata_jobscript_single.py | 27 ++++++- 2 files changed, 99 insertions(+), 2 deletions(-) create mode 100755 python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py new file mode 100755 index 0000000000..5ae11bc593 --- /dev/null +++ b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 + +"""System tests for gen_mksurfdata_jobscript_single + +""" + +import os + +import unittest +import tempfile +import shutil +import sys + +from ctsm.path_utils import path_to_ctsm_root +from ctsm.toolchain.gen_mksurfdata_jobscript_single import main +from ctsm import unit_testing + +# Allow test names that pylint doesn't like; otherwise hard to make them +# readable +# pylint: disable=invalid-name + + +class TestSysGenMkSurfJSSingle(unittest.TestCase): + """System tests for gen_mksurfdata_jobscript_single""" + + def setUp(self): + """Setp temporary directory to make the files in""" + self._tempdir = tempfile.mkdtemp() + os.chdir(self._tempdir) + self.outfile = "jobscript.sh" + self.namelist = "res.namelist" + sys.argv = [ + "gen_mksurfdata_jobscript_single", + "--namelist", + self.namelist, + "--jobscript-file", + self.outfile, + ] + + def tearDown(self): + """ + Remove temporary directory + """ + shutil.rmtree(self._tempdir, ignore_errors=True) + + def createJS(self, nodes, tasks_per_node, options=[]): + """ + Create a JobScript by sending a list of options in + """ + if len(options) > 1: + sys.argv.extend(options) + sys.argv.extend( + [ + "--number-of-nodes", + nodes, + "--tasks-per-node", + tasks_per_node, + ] + ) + print(sys.argv) + main() + self.assertTrue(os.path.exists(self.outfile), "Output jobscript file should exist") + + def test_simple_jobscript_single(self): + """ + Test that a standard simple namelist works + """ + # pylint: disable=no-self-use + self.createJS(nodes="4", tasks_per_node="12") + + +if __name__ == "__main__": + unit_testing.setup_for_tests() + unittest.main() diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 4e69d83b5b..b9e74ba7bd 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -10,6 +10,8 @@ from ctsm import add_cime_to_path # pylint: disable=unused-import from ctsm.ctsm_logging import setup_logging_pre_config, add_logging_args, process_logging_args +from ctsm.utils import abort +from ctsm.path_utils import path_to_ctsm_root from CIME.XML.env_mach_specific import EnvMachSpecific # pylint: disable=import-error from CIME.BuildTools.configure import FakeCase # pylint: disable=import-error @@ -45,6 +47,13 @@ def get_parser(): dest="number_of_nodes", required=True, ) + parser.add_argument( + "--bld-path", + help="""Path to build directory for mksurfdata_esmf""", + action="store", + dest="bld_path", + default=os.path.join(path_to_ctsm_root(), "tools", "mksurfdata_esmf", "tool_bld"), + ) parser.add_argument( "--tasks-per-node", help="""number of mpi tasks per node for cheyenne requested (required)""", @@ -140,7 +149,9 @@ def main(): # -------------------------- # Obtain mpirun command from env_mach_specific.xml # -------------------------- - bld_path = "./tool_bld" + bld_path = args.bld_path + if not os.path.exists(bld_path): + abort("Input Build path (" + bld_path + ") does NOT exist, aborting") # Get the ems_file object with standalone_configure=True # and the fake_case object with mpilib=attribs['mpilib'] # so as to use the get_mpirun function pointing to fake_case @@ -153,6 +164,7 @@ def main(): fake_case, attribs, job="name", + exe_only=True, overrides={ "total_tasks": total_tasks, }, @@ -165,7 +177,19 @@ def main(): executable = f'{cmd[0]} {" ".join(cmd[1])}'.replace("ENV{", "").replace("}", "") mksurfdata_path = os.path.join(bld_path, "mksurfdata") + if not os.path.exists(mksurfdata_path): + abort( + "mksurfdata_esmf executable (" + + mksurfdata_path + + ") does NOT exist in the bld-path, aborting" + ) env_mach_path = os.path.join(bld_path, ".env_mach_specific.sh") + if not os.path.exists(env_mach_path): + abort( + "Environment machine specific file (" + + env_mach_path + + ") does NOT exist in the bld-path, aborting" + ) # -------------------------- # Write run script (part 2) @@ -193,4 +217,3 @@ def main(): runfile.write("echo Successfully ran resolution\n") print(f"echo Successfully created jobscript {jobscript_file}\n") - sys.exit(0) From b00090c7196d9324a2f3fde191066cb42d3622e7 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 17 Oct 2023 16:26:33 -0600 Subject: [PATCH 391/614] Add a mksurfdata_esmf build mock directory for testing --- ...est_sys_gen_mksurfdata_jobscript_single.py | 3 + .../mksurfdata_esmf_bld/.env_mach_specific.sh | 18 ++ .../mksurfdata_esmf_bld/env_mach_specific.xml | 271 ++++++++++++++++++ .../testinputs/mksurfdata_esmf_bld/mksurfdata | 2 + 4 files changed, 294 insertions(+) create mode 100644 python/ctsm/test/testinputs/mksurfdata_esmf_bld/.env_mach_specific.sh create mode 100644 python/ctsm/test/testinputs/mksurfdata_esmf_bld/env_mach_specific.xml create mode 100755 python/ctsm/test/testinputs/mksurfdata_esmf_bld/mksurfdata diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py index 5ae11bc593..c8120ea7b5 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py @@ -29,8 +29,11 @@ def setUp(self): os.chdir(self._tempdir) self.outfile = "jobscript.sh" self.namelist = "res.namelist" + bld_path = os.path.join( path_to_ctsm_root(), "python", "ctsm", "test", "testinputs", "mksurfdata_esmf_bld" ) sys.argv = [ "gen_mksurfdata_jobscript_single", + "--bld-path", + bld_path, "--namelist", self.namelist, "--jobscript-file", diff --git a/python/ctsm/test/testinputs/mksurfdata_esmf_bld/.env_mach_specific.sh b/python/ctsm/test/testinputs/mksurfdata_esmf_bld/.env_mach_specific.sh new file mode 100644 index 0000000000..7b797d907a --- /dev/null +++ b/python/ctsm/test/testinputs/mksurfdata_esmf_bld/.env_mach_specific.sh @@ -0,0 +1,18 @@ +# This file is for user convenience only and is not used by the model +# Changes to this file will be ignored and overwritten +# Changes to the environment should be made in env_mach_specific.xml +# Run ./case.setup --reset to regenerate this file +. /glade/u/apps/ch/opt/lmod/7.5.3/lmod/lmod/init/sh +module purge +module load ncarenv/1.3 python/3.7.9 cmake/3.22.0 intel/19.1.1 esmf_libs mkl +module use /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ +module load esmf-8.4.1b02-ncdfio-mpt-O mpt/2.25 netcdf-mpi/4.9.0 pnetcdf/1.12.3 ncarcompilers/0.5.0 pio/2.5.10 +export OMP_STACKSIZE=1024M +export TMPDIR=/glade/scratch/erik +export MPI_TYPE_DEPTH=16 +export MPI_USE_ARRAY=None +export TMPDIR=/glade/scratch/erik +export COMPILER=intel +export MPILIB=mpt +export DEBUG=FALSE +export OS=LINUX diff --git a/python/ctsm/test/testinputs/mksurfdata_esmf_bld/env_mach_specific.xml b/python/ctsm/test/testinputs/mksurfdata_esmf_bld/env_mach_specific.xml new file mode 100644 index 0000000000..a718f1e2a5 --- /dev/null +++ b/python/ctsm/test/testinputs/mksurfdata_esmf_bld/env_mach_specific.xml @@ -0,0 +1,271 @@ + + +
      + These variables control the machine dependent environment including + the paths to compilers and libraries external to cime such as netcdf, + environment variables for use in the running job should also be set here. +
      + + + char + executable name + + + char + redirect for job output + + + + /glade/u/apps/ch/opt/lmod/7.5.3/lmod/lmod/init/perl + /glade/u/apps/ch/opt/lmod/7.5.3/lmod/lmod/init/env_modules_python.py + /glade/u/apps/ch/opt/lmod/7.5.3/lmod/lmod/init/csh + /glade/u/apps/ch/opt/lmod/7.5.3/lmod/lmod/init/sh + /glade/u/apps/ch/opt/lmod/7.5.3/lmod/lmod/libexec/lmod perl + /glade/u/apps/ch/opt/lmod/7.5.3/lmod/lmod/libexec/lmod python + module + module + + + ncarenv/1.3 + python/3.7.9 + cmake/3.22.0 + + + intel/19.1.1 + esmf_libs + mkl + + + gnu/10.1.0 + openblas/0.3.9 + + + pgi/20.4 + + + nvhpc/22.2 + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ + esmf-8.4.1b02-ncdfio-mpt-g + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ + esmf-8.4.1b02-ncdfio-mpt-O + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ + esmf-8.4.1b02-ncdfio-openmpi-g + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ + esmf-8.4.1b02-ncdfio-openmpi-O + + + mpi-serial/2.3.0 + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ + esmf-8.4.1b02-ncdfio-mpiuni-g + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ + esmf-8.4.1b02-ncdfio-mpiuni-O + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ + esmf-8.4.1b02-ncdfio-mpt-g + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ + esmf-8.4.1b02-ncdfio-mpt-O + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ + esmf-8.4.1b02-ncdfio-openmpi-g + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ + esmf-8.4.1b02-ncdfio-openmpi-O + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ + esmf-8.4.1b02-ncdfio-mpiuni-g + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ + esmf-8.4.1b02-ncdfio-mpiuni-O + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ + esmf-8.2.0b23-ncdfio-mpt-g + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ + esmf-8.2.0b23-ncdfio-mpt-O + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 + esmf-8.4.1b02-ncdfio-mpt-O + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 + esmf-8.4.1b02-ncdfio-mpt-g + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 + esmf-8.4.1b02-ncdfio-openmpi-O + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 + esmf-8.4.1b02-ncdfio-openmpi-g + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ + esmf-8.2.0b23-ncdfio-openmpi-g + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ + esmf-8.2.0b23-ncdfio-openmpi-O + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ + esmf-8.2.0b23-ncdfio-mpiuni-g + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ + esmf-8.2.0b23-ncdfio-mpiuni-O + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 + esmf-8.4.1.b01-ncdfio-mpiuni-O + + + /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 + esmf-8.4.1b02-ncdfio-mpiuni-O + + + mpt/2.25 + netcdf-mpi/4.9.0 + pnetcdf/1.12.3 + + + mpt/2.25 + netcdf-mpi/4.9.0 + pnetcdf/1.12.3 + + + mpt/2.22 + netcdf-mpi/4.7.4 + pnetcdf/1.12.1 + + + mpt/2.25 + netcdf-mpi/4.9.0 + pnetcdf/1.12.3 + + + openmpi/4.1.4 + netcdf-mpi/4.9.0 + pnetcdf/1.12.3 + + + openmpi/4.1.4 + netcdf-mpi/4.9.0 + pnetcdf/1.12.3 + + + openmpi/4.0.5 + netcdf-mpi/4.7.4 + + + openmpi/4.1.4 + netcdf-mpi/4.9.0 + pnetcdf/1.12.3 + + + ncarcompilers/0.5.0 + + + netcdf/4.9.0 + + + netcdf/4.9.0 + + + netcdf/4.9.0 + + + netcdf/4.9.0 + + + pio/2.5.10 + + + pio/2.5.10d + + + + 1024M + /glade/scratch/$USER + 16 + + + + ON + SUMMARY + /glade/work/turuncu/FV3GFS/benchmark-inputs/2012010100/gfs/fcst + /glade/work/turuncu/FV3GFS/fix_am + /glade/work/turuncu/FV3GFS/addon + PASSIVE + true + + + false + + + /glade/scratch/$USER + + + -1 + + + mpiexec_mpt + + -p "%g:" + -np {{ total_tasks }} + omplace -tm open64 + + + + mpirun `hostname` + + -np {{ total_tasks }} + omplace -tm open64 + + + + mpiexec_mpt + + -p "%g:" + -np {{ total_tasks }} + omplace -tm open64 -vv + + + + mpirun `hostname` + + -np {{ total_tasks }} + + + + mpirun + + -np {{ total_tasks }} + --tag-output + + + + /opt/sgi/mpt/mpt-2.15/bin/mpirun $ENV{UNIT_TEST_HOST} -np 1 + +
      diff --git a/python/ctsm/test/testinputs/mksurfdata_esmf_bld/mksurfdata b/python/ctsm/test/testinputs/mksurfdata_esmf_bld/mksurfdata new file mode 100755 index 0000000000..04909dbb93 --- /dev/null +++ b/python/ctsm/test/testinputs/mksurfdata_esmf_bld/mksurfdata @@ -0,0 +1,2 @@ +#!/bin/bash +# File to take the place of the mksurfdata_esmf executable for testing From cda0cf1412212e6f4363e6e8eb39f74c944b454d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 17 Oct 2023 17:11:09 -0600 Subject: [PATCH 392/614] Black format --- python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py index c8120ea7b5..ccc21ca2b4 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py @@ -29,7 +29,9 @@ def setUp(self): os.chdir(self._tempdir) self.outfile = "jobscript.sh" self.namelist = "res.namelist" - bld_path = os.path.join( path_to_ctsm_root(), "python", "ctsm", "test", "testinputs", "mksurfdata_esmf_bld" ) + bld_path = os.path.join( + path_to_ctsm_root(), "python", "ctsm", "test", "testinputs", "mksurfdata_esmf_bld" + ) sys.argv = [ "gen_mksurfdata_jobscript_single", "--bld-path", From 3bf85f74b7ec4d39f9533eae6614e060500399ff Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 17 Oct 2023 17:43:35 -0600 Subject: [PATCH 393/614] Add a check for a bad bld-path directory --- .../ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py index ccc21ca2b4..91fac39405 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py @@ -73,6 +73,14 @@ def test_simple_jobscript_single(self): # pylint: disable=no-self-use self.createJS(nodes="4", tasks_per_node="12") + def test_bad_bld_path(self): + """ + Test aborts if the input bld-path does NOT exist + """ + # pylint: disable=no-self-use + with self.assertRaisesRegex(SystemExit, "Input Build path"): + self.createJS(nodes="4", tasks_per_node="12", options=["--bld-path", "zztop"]) + if __name__ == "__main__": unit_testing.setup_for_tests() From 7155d4ea04835777fcdfd82d791a874aff405c18 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 17 Oct 2023 21:26:06 -0600 Subject: [PATCH 394/614] Add tests for casper and izumi --- ...est_sys_gen_mksurfdata_jobscript_single.py | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py index 91fac39405..a8cf8af648 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py @@ -48,12 +48,12 @@ def tearDown(self): """ shutil.rmtree(self._tempdir, ignore_errors=True) - def createJS(self, nodes, tasks_per_node, options=[]): + def createJS(self, nodes, tasks_per_node, option_list=[]): """ Create a JobScript by sending a list of options in """ - if len(options) > 1: - sys.argv.extend(options) + if len(option_list) > 1: + sys.argv.extend(option_list) sys.argv.extend( [ "--number-of-nodes", @@ -73,13 +73,29 @@ def test_simple_jobscript_single(self): # pylint: disable=no-self-use self.createJS(nodes="4", tasks_per_node="12") + def test_casper_jobscript_single(self): + """ + Test that a standard simple namelist works for casper + """ + # pylint: disable=no-self-use + opt_list = ["--machine", "casper"] + self.createJS(nodes="4", tasks_per_node="12", option_list=opt_list) + + def test_izumi_jobscript_single(self): + """ + Test that a standard simple namelist works for asper + """ + # pylint: disable=no-self-use + opt_list = ["--machine", "izumi"] + self.createJS(nodes="4", tasks_per_node="12", option_list=opt_list) + def test_bad_bld_path(self): """ Test aborts if the input bld-path does NOT exist """ # pylint: disable=no-self-use with self.assertRaisesRegex(SystemExit, "Input Build path"): - self.createJS(nodes="4", tasks_per_node="12", options=["--bld-path", "zztop"]) + self.createJS(nodes="4", tasks_per_node="12", option_list=["--bld-path", "zztop"]) if __name__ == "__main__": From 232297d54ba0a610e01617e11e1a50bcfcccc115 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 17 Oct 2023 23:21:15 -0600 Subject: [PATCH 395/614] Add some tests on the node and task counts and restrict them to positive integers --- ...est_sys_gen_mksurfdata_jobscript_single.py | 22 +++++++++++++++++++ .../gen_mksurfdata_jobscript_single.py | 6 +++++ 2 files changed, 28 insertions(+) diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py index a8cf8af648..25cdf00131 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py @@ -97,6 +97,28 @@ def test_bad_bld_path(self): with self.assertRaisesRegex(SystemExit, "Input Build path"): self.createJS(nodes="4", tasks_per_node="12", option_list=["--bld-path", "zztop"]) + def test_neg_nodes(self): + """ + Test aborts if the input node count is negative + """ + # pylint: disable=no-self-use + with self.assertRaisesRegex( + SystemExit, + "Input argument --number_of_nodes is zero or negative and needs to be positive", + ): + self.createJS(nodes="-4", tasks_per_node="12") + + def test_neg_tasks(self): + """ + Test aborts if the input tasks_per_node is zero or negative + """ + # pylint: disable=no-self-use + with self.assertRaisesRegex( + SystemExit, + "Input argument --tasks_per_node is zero or negative and needs to be positive", + ): + self.createJS(nodes="4", tasks_per_node="0") + if __name__ == "__main__": unit_testing.setup_for_tests() diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index b9e74ba7bd..58dabf8058 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -45,6 +45,7 @@ def get_parser(): help="""number of cheyenne nodes requested (required)""", action="store", dest="number_of_nodes", + type=int, required=True, ) parser.add_argument( @@ -59,6 +60,7 @@ def get_parser(): help="""number of mpi tasks per node for cheyenne requested (required)""", action="store", dest="tasks_per_node", + type=int, required=True, ) parser.add_argument( @@ -103,7 +105,11 @@ def main(): namelist_file = args.namelist_file jobscript_file = args.jobscript_file number_of_nodes = args.number_of_nodes + if number_of_nodes < 1: + abort("Input argument --number_of_nodes is zero or negative and needs to be positive") tasks_per_node = args.tasks_per_node + if tasks_per_node < 1: + abort("Input argument --tasks_per_node is zero or negative and needs to be positive") machine = args.machine account = args.account From c1e1e02cfd1b1cf2c6ea51a096f1a644f4a81969 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sun, 22 Oct 2023 19:52:48 -0600 Subject: [PATCH 396/614] Remove subprocess so can call the namelist directly, test now works --- .../gen_mksurfdata_jobscript_multi.py | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 5b1e5ecbda..d7ec360496 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -6,7 +6,9 @@ import os import sys import argparse -import subprocess + +from ctsm.path_utils import path_to_ctsm_root +from ctsm.toolchain.gen_mksurfdata_namelist import main as main_nml valid_scenarios = [ "all", @@ -66,6 +68,13 @@ def get_parser(): required=False, default="P93300606", ) + parser.add_argument( + "--bld-path", + help="""Path to build directory for mksurfdata_esmf""", + action="store", + dest="bld_path", + default=os.path.join(path_to_ctsm_root(), "tools", "mksurfdata_esmf", "tool_bld"), + ) parser.add_argument( "--number-of-nodes", help="""number of cheyenne nodes requested (required)""", @@ -310,24 +319,25 @@ def main(): } # -------------------------- - # TODO Here, reuse code from gen_mksurfdata_jobscript_single.py + # TODO Here, reuse code from gen_mksurfdata_jobscript_single # that's found in the section titled "Obtain mpirun command ..." # -------------------------- # -------------------------- # Make sure files exist or exit # -------------------------- - if not os.path.exists("./tool_bld"): + if not os.path.exists(args.bld_path): print( - "tool_bld directory does NOT exist -- build mksurdata_esmf before running this script -- using ./gen_mksurfdata_build.sh" + args.bld_path + + " directory does NOT exist -- build mksurdata_esmf before running this script -- using ./gen_mksurfdata_build.sh" ) sys.exit(1) - env_specific_script = "./tool_bld/.env_mach_specific.sh" + env_specific_script = os.path.join(args.bld_path, ".env_mach_specific.sh") if not os.path.exists(env_specific_script): print(env_specific_script + " does NOT exist") sys.exit(1) - mksurfdata = "./tool_bld/mksurfdata" + mksurfdata = os.path.join(args.bld_path, "mksurfdata") if not os.path.exists(mksurfdata): print(mksurfdata + " does NOT exist") sys.exit(1) @@ -366,16 +376,14 @@ def main(): for target in target_list: res_set = dataset_dict[target][1] for res in resolution_dict[res_set]: - command = os.path.join(os.getcwd(), "gen_mksurfdata_namelist.py") + namelist = f"{scenario}_{res}.namelist" + command = os.path.join(os.getcwd(), "gen_mksurfdata_namelist") command = command + " " + dataset_dict[target][0] + " " + res + command = command + "--silent" + command = command + "--namelist {namelist}" print(f"command is {command}") - commands = [x for x in command.split(" ") if x] - try: - run_cmd = subprocess.run(commands, check=True, shell=True, capture_output=True) - except subprocess.CalledProcessError as error: - sys.exit(f"{error} ERROR calling {command}") - output = run_cmd.stdout.decode("utf-8").strip() - namelist = output.split(" ")[-1] + sys.argv = [x for x in command.split(" ") if x] + main_nml() print(f"generated namelist {namelist}") output = f'time mpiexec_mpt -p "%g:" -np {n_p} {mksurfdata} < {namelist}' runfile.write(f"{output} \n") @@ -386,4 +394,3 @@ def main(): runfile.write(f"echo Successfully ran {jobscript_file}\n") print(f"echo Successfully created jobscript {jobscript_file}\n") - sys.exit(0) From 7cbe4922b5b7ee683ba12eb0f15447519307c07a Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sun, 22 Oct 2023 19:56:16 -0600 Subject: [PATCH 397/614] Add test for multi jobscript --- ...test_sys_gen_mksurfdata_jobscript_multi.py | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100755 python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py new file mode 100755 index 0000000000..751ca23dd9 --- /dev/null +++ b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 + +"""System tests for gen_mksurfdata_jobscript_multi + +""" + +import os + +import unittest +import tempfile +import shutil +import sys + +from ctsm.path_utils import path_to_ctsm_root +from ctsm.toolchain.gen_mksurfdata_jobscript_multi import main +from ctsm import unit_testing + +# Allow test names that pylint doesn't like; otherwise hard to make them +# readable +# pylint: disable=invalid-name + + +class TestSysGenMkSurfJSMulti(unittest.TestCase): + """System tests for gen_mksurfdata_jobscript_multi""" + + def setUp(self): + """Setp temporary directory to make the files in""" + self._tempdir = tempfile.mkdtemp() + os.chdir(self._tempdir) + self.outfile = "jobscript.sh" + bld_path = os.path.join( + path_to_ctsm_root(), "python", "ctsm", "test", "testinputs", "mksurfdata_esmf_bld" + ) + sys.argv = [ + "gen_mksurfdata_jobscript_multi", + "--bld-path", + bld_path, + "--jobscript-file", + self.outfile, + ] + + def tearDown(self): + """ + Remove temporary directory + """ + shutil.rmtree(self._tempdir, ignore_errors=True) + + def createJS(self, nodes, tasks_per_node, scenario, option_list=[]): + """ + Create a JobScript by sending a list of options in + """ + if len(option_list) > 1: + sys.argv.extend(option_list) + sys.argv.extend( + [ + "--number-of-nodes", + nodes, + "--tasks-per-node", + tasks_per_node, + "--scenario", + scenario, + ] + ) + print(sys.argv) + main() + self.assertTrue(os.path.exists(self.outfile), "Output jobscript file should exist") + + def test_simple_jobscript_multi(self): + """ + Test that a standard simple namelist works + """ + # pylint: disable=no-self-use + self.createJS(nodes="4", tasks_per_node="12", scenario="standard") + + +if __name__ == "__main__": + unit_testing.setup_for_tests() + unittest.main() From 1609ff058959378bfe26485b0b3db125ad554e10 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sun, 22 Oct 2023 19:56:57 -0600 Subject: [PATCH 398/614] Add black commit to list --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 5d418c4d07..d959e90fe6 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -11,3 +11,4 @@ c7b7ca1d94ac19abb9ecea9fb5b712ddbdd6645d b565b55ce7a9f8d812a573d716a5fd3d78cfea81 fdf72cd011e2ba318987a1e100efc5a1847c9d04 de9a30bfbbec36f9dcacc4380005ab596da47af4 +cda0cf1412212e6f4363e6e8eb39f74c944b454d` From 9cb21e8148cb03042599499f0b6d520783ce8615 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sun, 22 Oct 2023 23:44:13 -0600 Subject: [PATCH 399/614] Get makefile working with updated script --- python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 4 ++-- tools/mksurfdata_esmf/Makefile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index d7ec360496..4226e73a04 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -379,8 +379,8 @@ def main(): namelist = f"{scenario}_{res}.namelist" command = os.path.join(os.getcwd(), "gen_mksurfdata_namelist") command = command + " " + dataset_dict[target][0] + " " + res - command = command + "--silent" - command = command + "--namelist {namelist}" + command = command + " --silent" + command = command + f" --namelist {namelist}" print(f"command is {command}") sys.argv = [x for x in command.split(" ") if x] main_nml() diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index d5f86cd822..c7469ce7e6 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -26,7 +26,7 @@ ifeq ($(PROJECT),$(null)) endif BATCHJOBS = $(BATCHJOBS_ch) -MKSURFDATA = $(PWD)/gen_mksurfdata_jobscript_multi.py --account $(PROJECT) +MKSURFDATA = $(PWD)/gen_mksurfdata_jobscript_multi --account $(PROJECT) SUBSETDATA = $(PWD)/../site_and_regional/subset_data MODIFYSURF = $(PWD)/../modify_input_files/fsurdat_modifier --overwrite From 83bc76f4f9a1808ab365ab7c24d81bef3c42a1df Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 23 Oct 2023 15:50:03 -0600 Subject: [PATCH 400/614] Introduce istocn = 3 and related code --- src/biogeophys/EnergyFluxType.F90 | 16 ++++------------ src/main/landunit_varcon.F90 | 9 +++++---- src/main/surfrdMod.F90 | 9 ++++----- src/main/surfrdUtilsMod.F90 | 19 +++++++------------ 4 files changed, 20 insertions(+), 33 deletions(-) diff --git a/src/biogeophys/EnergyFluxType.F90 b/src/biogeophys/EnergyFluxType.F90 index 685663b83d..2e709596a1 100644 --- a/src/biogeophys/EnergyFluxType.F90 +++ b/src/biogeophys/EnergyFluxType.F90 @@ -170,7 +170,7 @@ subroutine InitAllocate(this, bounds) ! ! !USES: use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=) - use clm_varpar , only : nlevsno, nlevgrnd, nlevlak + use clm_varpar , only : nlevgrnd implicit none ! ! !ARGUMENTS: @@ -287,7 +287,7 @@ subroutine InitHistory(this, bounds, is_simple_buildtemp, is_prog_buildtemp) ! ! !USES: use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=) - use clm_varpar , only : nlevsno, nlevgrnd + use clm_varpar , only : nlevgrnd use clm_varctl , only : use_cn, use_hydrstress use histFileMod , only : hist_addfld1d, hist_addfld2d, no_snow_normal use ncdio_pio , only : ncd_inqvdlen @@ -700,13 +700,8 @@ subroutine InitCold(this, bounds, t_grnd_col, is_simple_buildtemp, is_prog_build ! ! !USES: use shr_kind_mod , only : r8 => shr_kind_r8 - use shr_const_mod , only : SHR_CONST_TKFRZ - use clm_varpar , only : nlevsoi, nlevgrnd, nlevsno, nlevlak, nlevurb - use clm_varcon , only : denice, denh2o, sb - use landunit_varcon , only : istwet, istsoil, istdlak - use column_varcon , only : icol_road_imperv, icol_roof, icol_sunwall - use column_varcon , only : icol_shadewall, icol_road_perv - use clm_varctl , only : use_vancouver, use_mexicocity + use clm_varpar , only : nlevgrnd + use clm_varcon , only : sb implicit none ! ! !ARGUMENTS: @@ -936,7 +931,6 @@ subroutine InitAccBuffer (this, bounds) ! !USES use accumulMod , only : init_accum_field use clm_time_manager , only : get_step_size_real - use shr_const_mod , only : SHR_CONST_CDAY, SHR_CONST_TKFRZ ! ! !ARGUMENTS: class(energyflux_type) :: this @@ -964,7 +958,6 @@ subroutine InitAccVars(this, bounds) ! is read in and the accumulation buffer is obtained) ! ! !USES - use accumulMod , only : init_accum_field, extract_accum_field use clm_time_manager , only : get_nstep use clm_varctl , only : nsrest, nsrStartup use abortutils , only : endrun @@ -994,7 +987,6 @@ end subroutine InitAccVars subroutine UpdateAccVars (this, bounds) ! ! USES - use shr_const_mod , only : SHR_CONST_CDAY, SHR_CONST_TKFRZ use clm_time_manager , only : get_step_size, get_nstep, is_end_curr_day, get_curr_date use accumulMod , only : update_accum_field, extract_accum_field, accumResetVal use abortutils , only : endrun diff --git a/src/main/landunit_varcon.F90 b/src/main/landunit_varcon.F90 index 36eccb7001..0483b50182 100644 --- a/src/main/landunit_varcon.F90 +++ b/src/main/landunit_varcon.F90 @@ -18,9 +18,10 @@ module landunit_varcon integer, parameter, public :: istsoil = 1 !soil landunit type (natural vegetation) integer, parameter, public :: istcrop = 2 !crop landunit type - ! Landunit 3 currently unused (used to be non-multiple elevation class glacier type: - ! istice, and landunit 4 was istice_mec; now they are combined into a single landunit - ! type, 4) + integer, parameter, public :: istocn = 3 !ocean landunit type + ! Landunit 3 used to be non-multiple elevation class glacier type, istice + ! Landunit 4 was istice_mec; now landunit 4 and old landunit 3 are combined + ! into landunit 4 integer, parameter, public :: istice = 4 !land ice landunit type integer, parameter, public :: istdlak = 5 !deep lake landunit type (now used for all lakes) integer, parameter, public :: istwet = 6 !wetland landunit type (swamp, marsh, etc.) @@ -118,7 +119,7 @@ subroutine set_landunit_names landunit_names(istsoil) = 'vegetated_or_bare_soil' landunit_names(istcrop) = 'crop' - landunit_names(istcrop+1) = unused + landunit_names(istocn) = 'ocean' landunit_names(istice) = 'landice' landunit_names(istdlak) = 'deep_lake' landunit_names(istwet) = 'wetland' diff --git a/src/main/surfrdMod.F90 b/src/main/surfrdMod.F90 index 1d07229b3b..bbd4639828 100644 --- a/src/main/surfrdMod.F90 +++ b/src/main/surfrdMod.F90 @@ -370,7 +370,7 @@ subroutine surfrd_special(begg, endg, ncid, ns) ! ! !USES: use clm_varpar , only : maxpatch_glc, nlevurb - use landunit_varcon , only : isturb_MIN, isturb_MAX, istdlak, istwet, istice + use landunit_varcon , only : isturb_MIN, isturb_MAX, istdlak, istwet, istice, istocn use clm_instur , only : wt_lunit, urban_valid, wt_glc_mec, topo_glc_mec use UrbanParamsType , only : CheckUrban ! @@ -507,10 +507,9 @@ subroutine surfrd_special(begg, endg, ncid, ns) ! Until ctsm5.1 we would label ocean points as wetland in fsurdat ! files. Starting with ctsm5.2 we label ocean points as ocean - ! (always 100%) and wetland points as wetland. Here we merge them - ! again to keep model behavior unchanged for now. - wt_lunit(nl,istwet) = (pctocn(nl) + pctwet(nl)) / 100._r8 - + ! (always 100%) and wetland points as wetland. + wt_lunit(nl,istwet) = pctwet(nl) / 100._r8 + wt_lunit(nl,istocn) = pctocn(nl) / 100._r8 wt_lunit(nl,istice) = pctgla(nl) / 100._r8 do n = isturb_MIN, isturb_MAX diff --git a/src/main/surfrdUtilsMod.F90 b/src/main/surfrdUtilsMod.F90 index 95303322a4..78d90a9357 100644 --- a/src/main/surfrdUtilsMod.F90 +++ b/src/main/surfrdUtilsMod.F90 @@ -117,14 +117,15 @@ end subroutine renormalize subroutine apply_convert_ocean_to_land(wt_lunit, begg, endg) ! ! !DESCRIPTION: - ! Apply the conversion of ocean points to land, by changing all "wetland" points to - ! natveg; typically this will result in these points becoming bare ground. + ! Convert ocean points to land by changing ocean to natveg; + ! typically these points will become bare ground. ! - ! The motivation for doing this is to avoid the negative runoff that sometimes comes + ! Originally ocean points were assigned to wetland, so the motivation for + ! for this subroutine was to avoid the negative runoff that sometimes comes ! from wetlands. ! ! !USES: - use landunit_varcon, only : istsoil, istwet, max_lunit + use landunit_varcon, only : istsoil, istocn, max_lunit ! ! !ARGUMENTS: integer, intent(in) :: begg ! Beginning grid cell index @@ -138,15 +139,9 @@ subroutine apply_convert_ocean_to_land(wt_lunit, begg, endg) character(len=*), parameter :: subname = 'apply_convert_ocean_to_land' !----------------------------------------------------------------------- - ! BUG(wjs, 2022-10-27, ESCOMP/CTSM#1886) Ideally we would distinguish between ocean - ! vs. true wetland points on the surface dataset; for now oceans are included in the - ! wetland area on the surface dataset, so we convert all wetlands to land. (Typically - ! there are no true/inland wetlands on the surface dataset, so this is currently okay, - ! but this would become a problem if we started having inland wetlands on the surface - ! dataset again.) do g = begg, endg - wt_lunit(g,istsoil) = wt_lunit(g,istsoil) + wt_lunit(g,istwet) - wt_lunit(g,istwet) = 0._r8 + wt_lunit(g,istsoil) = wt_lunit(g,istsoil) + wt_lunit(g,istocn) + wt_lunit(g,istocn) = 0._r8 end do end subroutine apply_convert_ocean_to_land From d876d78cce5828ec5bba776476d91153ecb245b3 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 24 Oct 2023 23:45:39 -0600 Subject: [PATCH 401/614] Get test to work with valid scenario, remove the uneeded all and standard scenarios, and add error checking for resolution and scenario --- ...test_sys_gen_mksurfdata_jobscript_multi.py | 3 +- .../gen_mksurfdata_jobscript_multi.py | 38 +++++-------------- 2 files changed, 11 insertions(+), 30 deletions(-) diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py index 751ca23dd9..6245e2de86 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py @@ -61,7 +61,6 @@ def createJS(self, nodes, tasks_per_node, scenario, option_list=[]): scenario, ] ) - print(sys.argv) main() self.assertTrue(os.path.exists(self.outfile), "Output jobscript file should exist") @@ -70,7 +69,7 @@ def test_simple_jobscript_multi(self): Test that a standard simple namelist works """ # pylint: disable=no-self-use - self.createJS(nodes="4", tasks_per_node="12", scenario="standard") + self.createJS(nodes="4", tasks_per_node="12", scenario="crop-global-present") if __name__ == "__main__": diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 4226e73a04..59a07107a9 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -9,10 +9,9 @@ from ctsm.path_utils import path_to_ctsm_root from ctsm.toolchain.gen_mksurfdata_namelist import main as main_nml +from ctsm.utils import abort valid_scenarios = [ - "all", - "standard", "global-present", "global-present-low-res", "global-present-nldas", @@ -146,32 +145,7 @@ def main(): # Determine target list # -------------------------- target_list = [] - if scenario == "all": - target_list = ( - [ - "global-present", - "crop-global-present", - "crop-global-1850", - "crop-global-hist", - "crop-tropics-present", - "crop-global-SSP1-2.6", - "crop-global-SSP3-7.0", - "crop-global-SSP5-3.4", - "crop-global-SSP2-4.5", - "crop-global-SSP1-1.9", - "crop-global-SSP4-3.4", - "crop-global-SSP4-6.0", - "crop-global-SSP5-8.5", - ], - ) - elif scenario == "standard": - target_list = ( - [ - "global-present", - "global-present-nldas", - ], - ) - elif scenario == "crop": + if scenario == "crop": target_list = ["crop-global-present", "crop-global-1850", "crop-global-hist"] elif scenario == "crop-global-future": target_list = [ @@ -191,6 +165,12 @@ def main(): target_list = [scenario] # -------------------------- + # Error checking + # -------------------------- + for scenario_list in target_list: + if scenario_list not in valid_scenarios: + abort("Input scenario is NOT in valid_scenarios") + # -------------------------- # Determine resolution sets that are referenced in commands # -------------------------- resolution_dict = { @@ -375,6 +355,8 @@ def main(): runfile.write(f"{check} \n") for target in target_list: res_set = dataset_dict[target][1] + if res_set not in resolution_dict: + abort(f"Resolution is not in the resolution_dict: {res_set}") for res in resolution_dict[res_set]: namelist = f"{scenario}_{res}.namelist" command = os.path.join(os.getcwd(), "gen_mksurfdata_namelist") From 9f1a976427cfbe9f8f459912f56e97728568bf22 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 24 Oct 2023 23:51:25 -0600 Subject: [PATCH 402/614] Default script names end with .sh --- python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 2 +- python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 59a07107a9..f38e879295 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -120,7 +120,7 @@ def get_parser(): action="store", dest="jobscript_file", required=False, - default="mksurfdata_jobscript_multi", + default="mksurfdata_jobscript_multi.sh", ) return parser diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 58dabf8058..bdb2c0fdcb 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -88,7 +88,7 @@ def get_parser(): action="store", dest="jobscript_file", required=False, - default="mksurfdata_jobscript_single", + default="mksurfdata_jobscript_single.sh", ) return parser From bc3ed7c317f086fa7a5539429fee049628db5890 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 26 Oct 2023 16:21:14 -0600 Subject: [PATCH 403/614] A few more adjustments to get the list look like the supported grids list, mostly adding an ultra-hi-res option for non-crop present day --- .../ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index f38e879295..22da54261a 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -14,6 +14,7 @@ valid_scenarios = [ "global-present", "global-present-low-res", + "global-present-ultra-hi-res", "global-present-nldas", "global-hist-4x5", "crop-tropics-present", @@ -174,8 +175,9 @@ def main(): # Determine resolution sets that are referenced in commands # -------------------------- resolution_dict = { - "standard_res_no_crop": ["0.9x1.25", "1.9x2.5"], + "standard_res_no_crop": ["0.9x1.25", "1.9x2.5", "mpasa60"], "low_res_no_crop": ["10x15"], + "ultra_hi_res_no_crop": ["mpasa15", "mpasa15-3conus", "mpasa3p75"], "low_res_all": ["10x15", "ne3np4.pg3"], "hi_res_all": ["ne120np4.pg3"], "standard_res": ["0.9x1.25", "1.9x2.5", "C96", "ne30np4.pg3", "mpasa120"], @@ -183,7 +185,7 @@ def main(): "4x5_res": ["10x15", "4x5", "C24", "mpasa480"], "nldas_res": ["0.125nldas2"], "5x5_amazon_res": ["5x5_amazon"], - "ne16np4_res": ["C48", "ne16np4"], + "ne16np4_res": ["C48", "ne16np4.pg3"], "ne120np4_res": [ "ne120np4.pg3", "ne0np4.ARCTICGRIS.ne30x8", @@ -204,6 +206,10 @@ def main(): "--start-year 2000 --end-year 2000 --nocrop --vic --res", "low_res_no_crop", ), + "global-present-ultra-hi-res": ( + "--start-year 2000 --end-year 2000 --nocrop --res", + "ultra_hi_res_no_crop", + ), "global-present-nldas": ( "--start-year 2000 --end-year 2000 --nocrop --vic --res", "nldas_res", From 99352188dbcab9f8bce0bfe278c1c8086ff79d8f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 26 Oct 2023 17:41:56 -0600 Subject: [PATCH 404/614] More adjustments to get the list right, don't do the ne120 SSP by default, nor ultra-high res --- python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 22da54261a..d7d6266316 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -181,11 +181,10 @@ def main(): "low_res_all": ["10x15", "ne3np4.pg3"], "hi_res_all": ["ne120np4.pg3"], "standard_res": ["0.9x1.25", "1.9x2.5", "C96", "ne30np4.pg3", "mpasa120"], - "low_res": ["10x15", "4x5", "ne3np4.pg3", "ne5np4.pg3", "C24", "mpasa480"], - "4x5_res": ["10x15", "4x5", "C24", "mpasa480"], + "low_res": ["10x15", "4x5", "ne3np4.pg3", "mpasa480"], "nldas_res": ["0.125nldas2"], "5x5_amazon_res": ["5x5_amazon"], - "ne16np4_res": ["C48", "ne16np4.pg3"], + "ne16np4_res": ["ne16np4.pg3"], "ne120np4_res": [ "ne120np4.pg3", "ne0np4.ARCTICGRIS.ne30x8", @@ -214,10 +213,6 @@ def main(): "--start-year 2000 --end-year 2000 --nocrop --vic --res", "nldas_res", ), - "global-hist-4x5": ( - "--start-year 1850 --end-year 2015 --nocrop --res", - "4x5_res", - ), "crop-tropics-present": ( "--start-year 2000 --end-year 2000 --res", "5x5_amazon_res", From a766c2864f6bd8b1bae74daa0cd0d69fcc3320aa Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 26 Oct 2023 17:42:07 -0600 Subject: [PATCH 405/614] More adjustments to get the list right, don't do the ne120 SSP by default, nor ultra-high res --- tools/mksurfdata_esmf/Makefile | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index c7469ce7e6..ca25f1243c 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -66,6 +66,9 @@ STANDARD = \ global-present-low-res \ global-present-nldas +ULTRA_HIRES = \ + global-present-ultra-hi-res + TROPICS = \ crop-tropics-present @@ -118,6 +121,15 @@ global-present-nldas : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh +# +# Ultra high resolutions (Don't do by default user should select this by hand) +# +ultra_hires : $(ULTRA_HIRES) + +global-present-ultra-hi-res : FORCE + $(MKSURFDATA) --number-of-nodes 200 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + # # tropics # @@ -196,7 +208,7 @@ crop-smallville-historical : FORCE # # Crop with future scenarios # -crop-global-future : crop-global-SSP2-4.5 crop-global-SSP2-4.5-low-res crop-global-SSP2-4.5-hi-res +crop-global-future : crop-global-SSP2-4.5 crop-global-SSP2-4.5-low-res crop-global-SSP2-4.5 : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 @@ -206,6 +218,7 @@ crop-global-SSP2-4.5-low-res : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh +# Don't do the high-resolution cases by default... crop-global-SSP2-4.5-hi-res : FORCE $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 $(BATCHJOBS) $@.sh From 246048251581b3159d79d1869bc6e66cbc02d649 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 26 Oct 2023 17:53:49 -0600 Subject: [PATCH 406/614] More work at getting the existing build or not working --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index c000a1bc72..90b94f6471 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -98,7 +98,7 @@ else if [ "$verbose" = "YES" ]; then echo "Build directory does NOT exist so do the configure and cmake steps"; fi existing_bld=No fi -if [ "existing_bld" = "No" ]; then +if [ "$existing_bld" = "No" ]; then mkdir $blddir fi cd $blddir @@ -115,7 +115,7 @@ fi # # If NOT an existing build, run the configure # -if [ "existing_bld" = "No" ]; then +if [ "$existing_bld" = "No" ]; then # Run the cime configure tool to figure out what modules need to be loaded if [ "$verbose" = "YES" ]; then echo "Run cime configure for machine $MACH..." @@ -143,6 +143,10 @@ fi # Create the machine environment (always) # . ./.env_mach_specific.sh +if [ $? != 0 ]; then + echo "Error sourcing the env_mach_specific.sh file" + exit 1 +fi if [ "$verbose" = "YES" ]; then echo "COMPILER = $COMPILER, MPILIB = $MPILIB, DEBUG = $DEBUG, OS = $OS"; fi if [ -z "$PIO" ]; then echo "The PIO directory for the PIO build is required and was not set in the configure" @@ -151,7 +155,7 @@ if [ -z "$PIO" ]; then fi # Build the cmake files (only if not an existing build) -if [ "existing_bld" = "No" ]; then +if [ "$existing_bld" = "No" ]; then if [ "$verbose" = "YES" ]; then echo "Do the cmake build..." options="-Wno-dev" From 6be1728977430e80e1e820fedf4e7278ed700782 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 27 Oct 2023 00:25:19 -0600 Subject: [PATCH 407/614] Fix fdyndat filename --- python/ctsm/toolchain/gen_mksurfdata_namelist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_namelist.py b/python/ctsm/toolchain/gen_mksurfdata_namelist.py index aee942eca7..7893205763 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_namelist.py +++ b/python/ctsm/toolchain/gen_mksurfdata_namelist.py @@ -606,7 +606,7 @@ def main(): else: fdyndat = ( f"landuse.timeseries_{res}_{ssp_rcp_name}" - "_{start_year}-{end_year}_{num_pft}_c{time_stamp}.nc" + f"_{start_year}-{end_year}_{num_pft}_c{time_stamp}.nc" ) prefix = f"surfdata_{res}_{ssp_rcp_name}_{start_year}_{num_pft}pfts_c{time_stamp}." From 9ee78503d9d6e3deebad3a5f05bf36d397678848 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 27 Oct 2023 15:53:52 -0600 Subject: [PATCH 408/614] Merge suma lines that need not be separate --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index c40fee5c47..c814c98fee 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -1234,8 +1234,8 @@ subroutine normalize_and_check_landuse(ns_o) ! Confirm that we have done the rescaling correctly: now the sum of all landunits ! should be 100% within tol_loose - suma = pctlak(n) + pctwet(n) + pctgla(n) + pcturb(n) + pctcft(n)%get_pct_l2g() - suma = suma + pctnatpft(n)%get_pct_l2g() + pctocn(n) + suma = pctlak(n) + pctwet(n) + pctgla(n) + pcturb(n) + pctocn(n) + & + pctcft(n)%get_pct_l2g() + pctnatpft(n)%get_pct_l2g() if (abs(suma - 100._r8) > tol_loose) then write(6,*) subname, ' ERROR: landunits do not sum to 100%' write(6,*) 'n, suma, pctlak, pctwet, pctgla, pcturb, pctnatveg, pctcrop, pctocn = ' @@ -1264,8 +1264,8 @@ subroutine normalize_and_check_landuse(ns_o) ! Include pctocn in suma but do not include in the ! renormalization. When pctocn /= 0, it is 100, and ! all other terms are 0. - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctocn(n) - suma = suma + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctocn(n) + & + pctnatpft(n)%get_pct_l2g() + pctcft(n)%get_pct_l2g() if ( abs(suma - 100.0_r8) > 2.0*epsilon(suma) )then pctlak(n) = pctlak(n) * 100._r8/suma pctwet(n) = pctwet(n) * 100._r8/suma @@ -1314,8 +1314,8 @@ subroutine normalize_and_check_landuse(ns_o) call shr_sys_abort() end if - suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctcft(n)%get_pct_l2g() - suma = suma + pctnatpft(n)%get_pct_l2g() + pctocn(n) + suma = pctlak(n) + pctwet(n) + pcturb(n) + pctgla(n) + pctocn(n) + & + pctcft(n)%get_pct_l2g() + pctnatpft(n)%get_pct_l2g() if ( abs(suma-100._r8) > 1.e-10_r8) then write (6,*) subname, ' error: sum of pctocn, pctlak, pctwet,', & 'pcturb, pctgla, pctnatveg and pctcrop is NOT equal to 100' From 889c0cd1cd99c190a3d2cf64ebeed8f0e62e5359 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 31 Oct 2023 11:12:15 -0600 Subject: [PATCH 409/614] add 360x720cru to standard resolutions --- python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index d7d6266316..b02f03fb54 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -180,7 +180,7 @@ def main(): "ultra_hi_res_no_crop": ["mpasa15", "mpasa15-3conus", "mpasa3p75"], "low_res_all": ["10x15", "ne3np4.pg3"], "hi_res_all": ["ne120np4.pg3"], - "standard_res": ["0.9x1.25", "1.9x2.5", "C96", "ne30np4.pg3", "mpasa120"], + "standard_res": ["360x720cru", "0.9x1.25", "1.9x2.5", "C96", "ne30np4.pg3", "mpasa120"], "low_res": ["10x15", "4x5", "ne3np4.pg3", "mpasa480"], "nldas_res": ["0.125nldas2"], "5x5_amazon_res": ["5x5_amazon"], From 0d7264a81aff47da5049dd8f745b226d88e35047 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 31 Oct 2023 15:46:02 -0600 Subject: [PATCH 410/614] Remove comment that referred to past code history --- src/main/landunit_varcon.F90 | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/landunit_varcon.F90 b/src/main/landunit_varcon.F90 index 0483b50182..001fe95a06 100644 --- a/src/main/landunit_varcon.F90 +++ b/src/main/landunit_varcon.F90 @@ -19,9 +19,6 @@ module landunit_varcon integer, parameter, public :: istsoil = 1 !soil landunit type (natural vegetation) integer, parameter, public :: istcrop = 2 !crop landunit type integer, parameter, public :: istocn = 3 !ocean landunit type - ! Landunit 3 used to be non-multiple elevation class glacier type, istice - ! Landunit 4 was istice_mec; now landunit 4 and old landunit 3 are combined - ! into landunit 4 integer, parameter, public :: istice = 4 !land ice landunit type integer, parameter, public :: istdlak = 5 !deep lake landunit type (now used for all lakes) integer, parameter, public :: istwet = 6 !wetland landunit type (swamp, marsh, etc.) From 0c2c886e6d5a9d368dea712eeb0ee005fe1bfd5c Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 2 Nov 2023 23:17:32 -0600 Subject: [PATCH 411/614] Remove the grids that won't be used, add some of the new ones, make sure crop datasets are used for all options if possible --- bld/namelist_files/namelist_defaults_ctsm.xml | 71 ++++++------------- 1 file changed, 22 insertions(+), 49 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 34decf8edf..d2f16d8ca7 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -818,11 +818,6 @@ attributes from the config_cache.xml file (with keys converted to upper-case). >hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. -hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. - - hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. @@ -1197,6 +1192,10 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_16pfts_CMIP6_2000_c230517.n lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_78pfts_CMIP6_2000_c230517.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_78pfts_CMIP6_2000_c230517.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_78pfts_CMIP6_2000_c230517.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4_hist_78pfts_CMIP6_2000_c230517.nc @@ -1210,32 +1209,18 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.125nldas2_hist_16pfts_CMIP6_2000_c23 lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc - - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_T42_hist_16pfts_CMIP6_2000_c230517.nc - - -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C384_hist_78pfts_CMIP6_simyr2000_c200317.nc - -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C192_hist_78pfts_CMIP6_simyr2000_c200317.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_78pfts_CMIP6_2000_c230517.nc - -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C48_hist_78pfts_CMIP6_simyr2000_c200317.nc - -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C24_hist_78pfts_CMIP6_simyr2000_c200317.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_78pfts_CMIP6_2000_c230517.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_78pfts_CMIP6_2000_c230517.nc - -lnd/clm2/surfdata_map/release-clm5.0.24/surfdata_0.125x0.125_hist_78pfts_CMIP6_simyr2005_c190624.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_2000_c230517.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_2000_c230517.nc - + /glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_numaIA_hist_78pfts_CMIP6_2000_c230726.nc @@ -1244,12 +1229,10 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_2000_c230517.nc< lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa480_hist_78pfts_CMIP6_simyr2000_c211110.nc - -lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa240_hist_78pfts_CMIP6_simyr2000_c211115.nc lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa120_hist_78pfts_CMIP6_simyr2000_c211108.nc - -lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa60_hist_78pfts_CMIP6_simyr2000_c211110.nc +> +lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa60_hist_2000_16pfts_simyr2000_c211110.nc lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa30_hist_78pfts_CMIP6_simyr2000_c211111.nc @@ -1304,34 +1287,24 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_1850_c230517.n lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_1850_c230517.nc - + lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa480_hist_78pfts_CMIP6_simyr1850_c211110.nc - -lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa240_hist_78pfts_CMIP6_simyr1850_c211115.nc - + lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa120_hist_78pfts_CMIP6_simyr1850_c211108.nc - -lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa60_hist_78pfts_CMIP6_simyr1850_c211110.nc - -lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa30_hist_78pfts_CMIP6_simyr1850_c211111.nc - -lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa15_hist_78pfts_CMIP6_simyr1850_c211111.nc - - + + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_78pfts_CMIP6_1850_c230517.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_78pfts_CMIP6_1850_c230517.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_78pfts_CMIP6_1850_c230517.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c231006.nc - -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C384_hist_78pfts_CMIP6_simyr1850_c200317.nc - -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C192_hist_78pfts_CMIP6_simyr1850_c200317.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_78pfts_CMIP6_1850_c230517.nc - -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C48_hist_78pfts_CMIP6_simyr1850_c200317.nc - -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_C24_hist_78pfts_CMIP6_simyr1850_c200317.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_78pfts_CMIP6_1850_c230517.nc From dbfa9fa88ee8852a0c21d7a552d0eb0e6e55de62 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 3 Nov 2023 01:46:45 -0600 Subject: [PATCH 412/614] Write out number of tasks as an attribute to the output file --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 335a9a508b..897c607263 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -128,6 +128,7 @@ subroutine mkfile_define_atts(pioid, dynlanduse) rcode = pio_put_att (pioid, pio_global, 'Version', trim(gitdescribe)) rcode = pio_put_att (pioid, pio_global, 'Logname', trim(logname)) rcode = pio_put_att (pioid, pio_global, 'Host', trim(hostname)) + rcode = pio_put_att (pioid, pio_global, 'Number-of-tasks', npes) ! TODO: check that this works !rcode = pio_put_att_int(pioid, pio_global, 'nglcec', nglcec) From f9ef5a44df66a4ac269881e57fd769a7a0102a4d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 3 Nov 2023 01:48:16 -0600 Subject: [PATCH 413/614] Add more to the git ignore for files in tools/mksurfdata_esmf --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 49ae8aac38..6a8f4f6b48 100644 --- a/.gitignore +++ b/.gitignore @@ -79,9 +79,8 @@ test_driver_*.sh # mksurfdata output surfdata_*.log -surfdata_*.namelist +*.namelist mksurfdata.o* -landuse.timeseries_*.namelist landuse.timeseries_*.log landuse_timeseries_*.txt ctsm.input_data_list @@ -100,6 +99,7 @@ ctsm.input_data_list.previous /tools/mksurfdata_esmf/*.sh /tools/mksurfdata_esmf/mksrf_*.o* /tools/mksurfdata_esmf/tool_bld +/tools/mksurfdata_esmf/pio_iotype.txt # mksurfdata unit tests unit_test_build From 61baf1293f93729d8e38fd0e52f82af40d404eb3 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 3 Nov 2023 01:50:02 -0600 Subject: [PATCH 414/614] Reduce the number of nodes used for most cases, and make the SSP cases do only one resolution so can fit in a reasonable time --- tools/mksurfdata_esmf/Makefile | 80 ++++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 9 deletions(-) diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index ca25f1243c..60b3bb32b2 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -166,7 +166,7 @@ crop-global-present-ne16np4 : FORCE $(BATCHJOBS) $@.sh crop-global-present-ne120np4 : FORCE - $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-1850 : FORCE @@ -182,11 +182,11 @@ crop-global-1850-ne16np4 : FORCE $(BATCHJOBS) $@.sh crop-global-1850-ne120np4 : FORCE - $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-present-0.125 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-numa-present : FORCE @@ -208,19 +208,81 @@ crop-smallville-historical : FORCE # # Crop with future scenarios # -crop-global-future : crop-global-SSP2-4.5 crop-global-SSP2-4.5-low-res +crop-global-future : crop-global-SSP1-1.9-f09 crop-global-SSP1-2.6-f09 crop-global-SSP2-4.5 crop-global-SSP2-4.5-low-res \ + crop-global-SSP3-7.0-f09 crop-global-SSP4-3.4-f09 crop-global-SSP4-6.0-f09 crop-global-SSP5-8.5-f09 + +crop-global-SSP2-4.5-low-res : crop-global-SSP2-4.5-f10 crop-global-SSP2-4.5-ne3 +crop-global-SSP2-4.5 : crop-global-SSP2-4.5-f19 crop-global-SSP2-4.5-f09 crop-global-SSP2-4.5-f45 \ + crop-global-SSP2-4.5-hcru crop-global-SSP2-4.5-ne16 crop-global-SSP2-4.5-ne30 \ + crop-global-SSP2-4.5-C96 crop-global-SSP2-4.5-mpasa120 + +crop-global-SSP1-1.9-f09 : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh + +crop-global-SSP1-2.6-f09 : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh + +crop-global-SSP2-4.5-f09 : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh + +crop-global-SSP2-4.5-f19 : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh + +crop-global-SSP2-4.5-f45 : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh + +crop-global-SSP2-4.5-hcru : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh -crop-global-SSP2-4.5 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 +crop-global-SSP2-4.5-ne16 : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh -crop-global-SSP2-4.5-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 +crop-global-SSP2-4.5-ne30 : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh + +crop-global-SSP2-4.5-C96 : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh + +crop-global-SSP2-4.5-mpasa120 : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh + +crop-global-SSP2-4.5-f10 : FORCE + $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh + +crop-global-SSP2-4.5-ne3 : FORCE + $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh # Don't do the high-resolution cases by default... crop-global-SSP2-4.5-hi-res : FORCE - $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 04:00:00 + $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh + +crop-global-SSP3-7.0-f09 : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh + +crop-global-SSP4-3.4-f09 : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh + +crop-global-SSP4-6.0-f09 : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh + +crop-global-SSP5-8.5-f09 : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh # From 5179d62750eaf2c4e9513fb1455fb114023f8cc4 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 3 Nov 2023 02:07:23 -0600 Subject: [PATCH 415/614] Seperate out the SSP cases by single resolution, remove some of the scenarios that put everything into one thing --- .../gen_mksurfdata_jobscript_multi.py | 115 +++++++++++------- 1 file changed, 74 insertions(+), 41 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index b02f03fb54..148e5c2c35 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -30,17 +30,24 @@ "crop-global-1850-ne120np4", "crop-global-hist", "crop-global-future", - "crop-global-SSP1-2.6", - "crop-global-SSP3-7.0", - "crop-global-SSP5-3.4", - "crop-global-SSP2-4.5", - "crop-global-SSP2-4.5-low-res", + "crop-global-SSP1-2.6-f09", + "crop-global-SSP3-7.0-f09", + "crop-global-SSP5-3.4-f09", + "crop-global-SSP2-4.5-f09", + "crop-global-SSP2-4.5-f19", + "crop-global-SSP2-4.5-f10", + "crop-global-SSP2-4.5-f45", + "crop-global-SSP2-4.5-ne3", + "crop-global-SSP2-4.5-ne30", + "crop-global-SSP2-4.5-ne16", + "crop-global-SSP2-4.5-hcru", + "crop-global-SSP2-4.5-C96", + "crop-global-SSP2-4.5-mpasa120", "crop-global-SSP2-4.5-hi-res", - "crop-global-SSP1-1.9", - "crop-global-SSP4-3.4", - "crop-global-SSP4-6.0", - "crop-global-SSP5-8.5", - "crop-global-SSP5-8.5-other", + "crop-global-SSP1-1.9-f09", + "crop-global-SSP4-3.4-f09", + "crop-global-SSP4-6.0-f09", + "crop-global-SSP5-8.5-f09", ] @@ -147,19 +154,7 @@ def main(): # -------------------------- target_list = [] if scenario == "crop": - target_list = ["crop-global-present", "crop-global-1850", "crop-global-hist"] - elif scenario == "crop-global-future": - target_list = [ - "crop-global-SSP1-2.6", - "crop-global-SSP3-7.0", - "crop-global-SSP5-3.4", - "crop-global-SSP2-4.5", - "crop-global-SSP1-1.9", - "crop-global-SSP4-3.4", - "crop-global-SSP4-6.0", - "crop-global-SSP5-8.5", - "crop-global-SSP5-8.5-other", - ] + target_list = ["crop-global-present", "crop-global-1850"] elif scenario == "tropics": target_list = ["crop-tropics-present"] else: @@ -176,6 +171,16 @@ def main(): # -------------------------- resolution_dict = { "standard_res_no_crop": ["0.9x1.25", "1.9x2.5", "mpasa60"], + "f09": ["0.9x1.25"], + "f19": ["1.9x2.5"], + "hcru": ["360x720cru"], + "C96": ["C96"], + "mpasa120": ["mpasa120"], + "f10": ["10x15"], + "f45": ["4x5"], + "ne3": ["ne3np4.pg3"], + "ne16": ["ne16np4.pg3"], + "ne30": ["ne30np4.pg3"], "low_res_no_crop": ["10x15"], "ultra_hi_res_no_crop": ["mpasa15", "mpasa15-3conus", "mpasa3p75"], "low_res_all": ["10x15", "ne3np4.pg3"], @@ -257,45 +262,73 @@ def main(): "--start-year 1850 --end-year 2015 --nosurfdata --res", "standard_res", ), - "crop-global-SSP1-1.9": ( + "crop-global-SSP1-1.9-f09": ( "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-1.9 --res", - "standard_res", + "f09", ), - "crop-global-SSP1-2.6": ( + "crop-global-SSP1-2.6-f09": ( "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-2.6 --res", - "standard_res", + "f09", ), - "crop-global-SSP2-4.5": ( + "crop-global-SSP2-4.5-f09": ( "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", - "standard_res", + "f09", + ), + "crop-global-SSP2-4.5-hcru": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", + "hcru", + ), + "crop-global-SSP2-4.5-f19": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", + "f19", + ), + "crop-global-SSP2-4.5-f10": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", + "f10", + ), + "crop-global-SSP2-4.5-ne3": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", + "ne3", ), - "crop-global-SSP2-4.5-low-res": ( + "crop-global-SSP2-4.5-ne30": ( "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", - "low_res_all", + "ne30", + ), + "crop-global-SSP2-4.5-ne16": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", + "ne16", + ), + "crop-global-SSP2-4.5-C96": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", + "C96", + ), + "crop-global-SSP2-4.5-mpasa120": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", + "mpasa120", ), "crop-global-SSP2-4.5-hi-res": ( "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", "hi_res_all", ), - "crop-global-SSP3-7.0": ( + "crop-global-SSP3-7.0-f09": ( "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP3-7.0 --res", - "standard_res", + "f09", ), - "crop-global-SSP4-3.4": ( + "crop-global-SSP4-3.4-f09": ( "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-3.4 --res", - "standard_res", + "f09", ), - "crop-global-SSP4-6.0": ( + "crop-global-SSP4-6.0-f09": ( "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP4-6.0 --res", - "standard_res", + "f09", ), - "crop-global-SSP5-3.4": ( + "crop-global-SSP5-3.4-f09": ( "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-3.4 --res", - "standard_res", + "f09", ), - "crop-global-SSP5-8.5": ( + "crop-global-SSP5-8.5-f09": ( "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP5-8.5 --res", - "standard_res", + "f09", ), } From c4420db00bd47e19b56871e460847c3fac52fb82 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 7 Nov 2023 12:38:03 -0700 Subject: [PATCH 416/614] Updates for ./run_ctsm_py_tests --sys and --unit to pass --- .../modify_input_files/fsurdat_modifier.py | 2 +- .../ctsm/modify_input_files/modify_fsurdat.py | 6 ++--- python/ctsm/test/test_sys_fsurdat_modifier.py | 27 ++++++++----------- python/ctsm/test/test_sys_mesh_modifier.py | 6 ++--- .../ctsm/test/test_unit_fsurdat_modifier.py | 10 +++---- python/ctsm/test/test_unit_modify_fsurdat.py | 2 +- python/ctsm/test/test_unit_subset_data.py | 4 +-- python/ctsm/test/testinputs/default_data.cfg | 12 ++++----- .../modify_fsurdat_1x1mexicocity.cfg | 14 +++++----- .../modify_fsurdat_opt_sections.cfg | 2 +- .../test/testinputs/modify_fsurdat_short.cfg | 4 +-- .../modify_fsurdat_template.cfg | 2 +- tools/site_and_regional/default_data.cfg | 12 ++++----- 13 files changed, 49 insertions(+), 54 deletions(-) diff --git a/python/ctsm/modify_input_files/fsurdat_modifier.py b/python/ctsm/modify_input_files/fsurdat_modifier.py index 492fa74230..a511fcfddc 100644 --- a/python/ctsm/modify_input_files/fsurdat_modifier.py +++ b/python/ctsm/modify_input_files/fsurdat_modifier.py @@ -110,7 +110,7 @@ def read_cfg_subgrid(config, cfg_path, numurbl=3): subgrid_settings = {} var_list = config.options(section) - valid_list = ["pct_natveg", "pct_crop", "pct_lake", "pct_glacier", "pct_wetland", "pct_urban"] + valid_list = ["pct_natveg", "pct_crop", "pct_lake", "pct_glacier", "pct_wetland", "pct_urban","pct_ocean"] varsum = 0 for var in var_list: if valid_list.count(var) == 0: diff --git a/python/ctsm/modify_input_files/modify_fsurdat.py b/python/ctsm/modify_input_files/modify_fsurdat.py index 6fa3701acc..919c42098c 100644 --- a/python/ctsm/modify_input_files/modify_fsurdat.py +++ b/python/ctsm/modify_input_files/modify_fsurdat.py @@ -264,7 +264,7 @@ def check_varlist(self, settings, allow_uppercase_vars=False): ) if len(val) != dim1: abort( - "Variable " + varname + " is of the wrong size. It should be = " + str(dim1) + "Variable " + varname + " is " + str(len(val)) + ". It should be = " + str(dim1) ) return settings_return @@ -397,8 +397,8 @@ def set_idealized(self): max_sat_area = 0 # max saturated area std_elev = 0 # standard deviation of elevation slope = 0 # mean topographic slope - pftdata_mask = 1 landfrac_pft = 1 + landfrac_mksurfdata = 1 # if pct_nat_veg had to be set to less than 100, then each special # landunit would have to receive a unique pct value rather than the # common value used here in pct_not_nat_veg = 0 @@ -415,8 +415,8 @@ def set_idealized(self): self.setvar_lev0("SLOPE", slope) self.setvar_lev0("zbedrock", zbedrock) self.setvar_lev0("SOIL_COLOR", soil_color) - self.setvar_lev0("PFTDATA_MASK", pftdata_mask) self.setvar_lev0("LANDFRAC_PFT", landfrac_pft) + self.setvar_lev0("LANDFRAC_MKSURFDATA", landfrac_mksurfdata) self.setvar_lev0("PCT_WETLAND", pct_not_nat_veg) self.setvar_lev0("PCT_CROP", pct_not_nat_veg) self.setvar_lev0("PCT_LAKE", pct_not_nat_veg) diff --git a/python/ctsm/test/test_sys_fsurdat_modifier.py b/python/ctsm/test/test_sys_fsurdat_modifier.py index 7bd57ce8af..b4559d1867 100755 --- a/python/ctsm/test/test_sys_fsurdat_modifier.py +++ b/python/ctsm/test/test_sys_fsurdat_modifier.py @@ -45,7 +45,7 @@ def setUp(self): self._testinputs_path = testinputs_path self._fsurdat_in = os.path.join( testinputs_path, - "surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc", + "surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.nc", ) self._tempdir = tempfile.mkdtemp() self._cfg_file_path = os.path.join(self._tempdir, "modify_fsurdat.cfg") @@ -76,9 +76,7 @@ def test_short_config(self): self._cfg_file_path = os.path.join(self._testinputs_path, "modify_fsurdat_short.cfg") sys.argv = ["fsurdat_modifier", self._cfg_file_path] parser = fsurdat_modifier_arg_process() - fsurdat_out = ( - "ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_out.nc" - ) + fsurdat_out = os.path.join(self._testinputs_path, "surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.out.nc") if os.path.exists(fsurdat_out): os.remove(fsurdat_out) fsurdat_modifier(parser) @@ -134,14 +132,14 @@ def test_opt_sections(self): self._cfg_file_path = os.path.join(self._testinputs_path, "modify_fsurdat_opt_sections.cfg") outfile = os.path.join( self._tempdir, - "surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_output_urban.nc", + "surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031_output_urban.nc", ) sys.argv = [ "fsurdat_modifier", self._cfg_file_path, "-i", os.path.join( - self._testinputs_path, "surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc" + self._testinputs_path, "surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.nc" ), "-o", outfile, @@ -180,12 +178,9 @@ def test_opt_sections(self): lev2_two = np.empty((2, 3, 5, 5)) lev2_two[0, :, :, :] = 200.0 lev2_two[1, :, :, :] = 100.0 - lev2_five = np.empty((5, 3, 5, 5)) - lev2_five[0, :, :, :] = 1.0 - lev2_five[1, :, :, :] = 2.0 - lev2_five[2, :, :, :] = 3.0 - lev2_five[3, :, :, :] = 4.0 - lev2_five[4, :, :, :] = 5.0 + lev2_ten = np.empty((10, 3, 5, 5)) + for x in range(10): + lev2_ten[x, :, :, :] = x + 1 lev1 = np.array( [ [ @@ -221,7 +216,7 @@ def test_opt_sections(self): np.testing.assert_array_equal(fsurdat_out_data.LAKEDEPTH, one0d * 200.0) np.testing.assert_array_equal(fsurdat_out_data.T_BUILDING_MIN, lev1) np.testing.assert_array_equal(fsurdat_out_data.ALB_ROOF_DIR, lev2_two) - np.testing.assert_array_equal(fsurdat_out_data.TK_ROOF, lev2_five) + np.testing.assert_array_equal(fsurdat_out_data.TK_ROOF, lev2_ten) def test_1x1_mexicocity(self): """ @@ -232,15 +227,15 @@ def test_1x1_mexicocity(self): ) expectfile = os.path.join( self._testinputs_path, - "surfdata_1x1_mexicocityMEX_hist_16pfts_Irrig_CMIP6_simyr2000_c221206_modified.nc", + "surfdata_1x1_mexicocityMEX_hist_16pfts_CMIP6_2000_c231103_modified.nc", ) outfile = os.path.join( self._tempdir, - "surfdata_1x1_mexicocityMEX_hist_16pfts_Irrig_CMIP6_simyr2000_c221206_modified.nc", + "surfdata_1x1_mexicocityMEX_hist_16pfts_CMIP6_2000_c231103_modified.nc", ) infile = os.path.join( self._testinputs_path, - "surfdata_1x1_mexicocityMEX_hist_16pfts_Irrig_CMIP6_simyr2000_c221206.nc", + "surfdata_1x1_mexicocityMEX_hist_16pfts_CMIP6_2000_c231103.nc", ) sys.argv = [ "fsurdat_modifier", diff --git a/python/ctsm/test/test_sys_mesh_modifier.py b/python/ctsm/test/test_sys_mesh_modifier.py index 0889a505ba..b44605db26 100755 --- a/python/ctsm/test/test_sys_mesh_modifier.py +++ b/python/ctsm/test/test_sys_mesh_modifier.py @@ -46,7 +46,7 @@ def setUp(self): testinputs_path = os.path.join(path_to_ctsm_root(), "python/ctsm/test/testinputs") fsurdat_in = os.path.join( testinputs_path, - "surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc", + "surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.nc", ) self._tempdir = tempfile.mkdtemp() self._cfg_file_path = os.path.join(self._tempdir, "modify_mesh_mask.cfg") @@ -96,8 +96,8 @@ def setUp(self): self._lon_dimname = fsurdat_in_data[self._lat_varname].dims[1] ncap2_cmd = ( - "ncap2 -A -v -s 'mod_lnd_props=PFTDATA_MASK' " - + "-A -v -s 'landmask=PFTDATA_MASK' " + "ncap2 -A -v -s 'mod_lnd_props=LANDFRAC_MKSURFDATA' " + + "-A -v -s 'landmask=LANDFRAC_MKSURFDATA' " + f"-A -v -s {self._lat_varname}={self._lat_varname} " + f"-A -v -s {self._lon_varname}={self._lon_varname} " + f"{fsurdat_in} {self._landmask_file}" diff --git a/python/ctsm/test/test_unit_fsurdat_modifier.py b/python/ctsm/test/test_unit_fsurdat_modifier.py index 0ea862a8e4..8c13e2eb19 100755 --- a/python/ctsm/test/test_unit_fsurdat_modifier.py +++ b/python/ctsm/test/test_unit_fsurdat_modifier.py @@ -44,13 +44,9 @@ def setUp(self): self._testinputs_path = testinputs_path self._fsurdat_in = os.path.join( testinputs_path, - "surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc", + "surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.nc", ) self._tempdir = tempfile.mkdtemp() - self._fsurdat_in = os.path.join( - testinputs_path, - "surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc", - ) self._fsurdat_out = os.path.join(self._tempdir, "fsurdat_out.nc") sys.argv = [ "fsurdat_modifier", @@ -133,6 +129,7 @@ def test_read_subgrid_allglacier(self): self.config.set(section, "pct_urban", "0. 0. 0.") self.config.set(section, "pct_lake", "0.") self.config.set(section, "pct_wetland", "0.") + self.config.set(section, "pct_ocean", "0.") self.config.set(section, "pct_glacier", "100.") self.config.set(section, "pct_natveg", "0.") self.config.set(section, "pct_crop", "0.") @@ -146,6 +143,7 @@ def test_read_subgrid_allspecial(self): self.config.set(section, "pct_urban", "0. 0. 0.") self.config.set(section, "pct_lake", "25.") self.config.set(section, "pct_wetland", "35.") + self.config.set(section, "pct_ocean", "0.") self.config.set(section, "pct_glacier", "40.") self.config.set(section, "pct_natveg", "0.") self.config.set(section, "pct_crop", "0.") @@ -159,6 +157,7 @@ def test_read_subgrid_allurban(self): self.config.set(section, "pct_urban", "100.0 0.0 0.0") self.config.set(section, "pct_lake", "0.") self.config.set(section, "pct_wetland", "0.") + self.config.set(section, "pct_ocean", "0.") self.config.set(section, "pct_glacier", "0.") self.config.set(section, "pct_natveg", "0.") self.config.set(section, "pct_crop", "0.") @@ -218,6 +217,7 @@ def test_subgrid_notsumtohundred(self): self.config.set(section, "pct_urban", "0. 0. 0.") self.config.set(section, "pct_lake", "0.") self.config.set(section, "pct_wetland", "0.") + self.config.set(section, "pct_ocean", "0.") self.config.set(section, "pct_glacier", "0.") self.config.set(section, "pct_natveg", "0.") self.config.set(section, "pct_crop", "0.") diff --git a/python/ctsm/test/test_unit_modify_fsurdat.py b/python/ctsm/test/test_unit_modify_fsurdat.py index a075035b73..f41563a5c3 100755 --- a/python/ctsm/test/test_unit_modify_fsurdat.py +++ b/python/ctsm/test/test_unit_modify_fsurdat.py @@ -389,7 +389,7 @@ def test_check_varlist_lists_wrongsizes(self): lev1list = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] settings = {"var_lev1": lev1list} with self.assertRaisesRegex( - SystemExit, "Variable var_lev1 is of the wrong size. It should be" + SystemExit, "Variable var_lev1 is " + str(len(lev1list)) + ". It should be" ): self.modify_fsurdat.check_varlist(settings) diff --git a/python/ctsm/test/test_unit_subset_data.py b/python/ctsm/test/test_unit_subset_data.py index fd9aef631d..3041d58897 100755 --- a/python/ctsm/test/test_unit_subset_data.py +++ b/python/ctsm/test/test_unit_subset_data.py @@ -46,7 +46,7 @@ def test_inputdata_setup_files_basic(self): files = setup_files(self.args, self.defaults, self.cesmroot) self.assertEqual( files["fsurf_in"], - "surfdata_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr2000_c190214.nc", + "surfdata_0.9x1.25_hist_16pfts_CMIP6_1850-2015_c231031.nc", "fsurf_in filename not whats expected", ) self.assertEqual( @@ -134,7 +134,7 @@ def test_check_args_outsurfdat_fails_without_overwrite(self): outfile = os.path.join( os.getcwd(), "ctsm/test/testinputs/", - "surfdata_1x1_mexicocityMEX_hist_16pfts_Irrig_CMIP6_simyr2000_c221206.nc", + "surfdata_1x1_mexicocityMEX_hist_16pfts_CMIP6_2000_c231103.nc", ) self.assertTrue(os.path.exists(outfile), str(outfile) + " outfile should exist") diff --git a/python/ctsm/test/testinputs/default_data.cfg b/python/ctsm/test/testinputs/default_data.cfg index 7e841dca54..2ec453967f 100644 --- a/python/ctsm/test/testinputs/default_data.cfg +++ b/python/ctsm/test/testinputs/default_data.cfg @@ -15,14 +15,14 @@ precname = CLMGSWP3v1.Precip tpqwname = CLMGSWP3v1.TPQW [surfdat] -dir = lnd/clm2/surfdata_map/release-clm5.0.18 -surfdat_16pft = surfdata_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr2000_c190214.nc -surfdat_78pft = surfdata_0.9x1.25_hist_78pfts_CMIP6_simyr2000_c190214.nc +dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 +surfdat_16pft = surfdata_0.9x1.25_hist_16pfts_CMIP6_1850-2015_c231031.nc +surfdat_78pft = surfdata_0.9x1.25_hist_78pfts_CMIP6_1850-2015_c231031.nc [landuse] -dir = lnd/clm2/surfdata_map/release-clm5.0.18 -landuse_16pft = landuse.timeseries_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c190214.nc -landuse_78pft = landuse.timeseries_0.9x1.25_hist_78pfts_CMIP6_simyr1850-2015_c190214.nc +dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 +landuse_16pft = landuse.timeseries_0.9x1.25_hist_16_CMIP6_1850-2015_c231031.nc +landuse_78pft = landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c231031.nc [domain] file = share/domains/domain.lnd.fv0.9x1.25_gx1v7.151020.nc diff --git a/python/ctsm/test/testinputs/modify_fsurdat_1x1mexicocity.cfg b/python/ctsm/test/testinputs/modify_fsurdat_1x1mexicocity.cfg index a854ebcc53..f9ddccfd2f 100644 --- a/python/ctsm/test/testinputs/modify_fsurdat_1x1mexicocity.cfg +++ b/python/ctsm/test/testinputs/modify_fsurdat_1x1mexicocity.cfg @@ -71,13 +71,13 @@ ALB_ROOF_DIF = 0.2 0.2 ALB_WALL_DIR = 0.25 0.25 ALB_WALL_DIF = 0.25 0.25 -# Variabls on nlevurb which is 5 -TK_ROOF = 0.20 0.93 0.93 0.03 0.16 -TK_WALL = 0.88 0.88 0.88 0.88 0.88 -TK_IMPROAD = 0.82 0.82 2.10 2.10 2.10 -CV_ROOF = 1760000.0 1500000.0 1500000.0 250000.0 870000.0 -CV_WALL = 1540000.0 1540000.0 1540000.0 1540000.0 1540000.0 -CV_IMPROAD = 1740000.0 1740000.0 2000000.0 2000000.0 2000000.0 +# Variabls on nlevurb which is 10 +TK_ROOF = 0.20 0.93 0.93 0.03 0.16 0.20 0.93 0.93 0.03 0.16 +TK_WALL = 0.88 0.88 0.88 0.88 0.88 0.88 0.88 0.88 0.88 0.88 +TK_IMPROAD = 0.82 0.82 2.10 2.10 2.10 0.82 0.82 2.10 2.10 2.10 +CV_ROOF = 1760000.0 1500000.0 1500000.0 250000.0 870000.0 1760000.0 1500000.0 1500000.0 250000.0 870000.0 +CV_WALL = 1540000.0 1540000.0 1540000.0 1540000.0 1540000.0 1540000.0 1540000.0 1540000.0 1540000.0 1540000.0 +CV_IMPROAD = 1740000.0 1740000.0 2000000.0 2000000.0 2000000.0 1740000.0 1740000.0 2000000.0 2000000.0 2000000.0 # Natural and Crop PFT's don't really need to be set, since they have zero area, but # it looks better to do so diff --git a/python/ctsm/test/testinputs/modify_fsurdat_opt_sections.cfg b/python/ctsm/test/testinputs/modify_fsurdat_opt_sections.cfg index 38e7a529f0..ea3699970d 100644 --- a/python/ctsm/test/testinputs/modify_fsurdat_opt_sections.cfg +++ b/python/ctsm/test/testinputs/modify_fsurdat_opt_sections.cfg @@ -49,4 +49,4 @@ CANYON_HWR = 200.00 150.0 100. HT_ROOF = 200.0 150.0 100. T_BUILDING_MIN = 200 150.0 100. ALB_ROOF_DIR = 200. 100. -TK_ROOF = 1. 2. 3. 4. 5. +TK_ROOF = 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. diff --git a/python/ctsm/test/testinputs/modify_fsurdat_short.cfg b/python/ctsm/test/testinputs/modify_fsurdat_short.cfg index 74c6639899..222259a251 100644 --- a/python/ctsm/test/testinputs/modify_fsurdat_short.cfg +++ b/python/ctsm/test/testinputs/modify_fsurdat_short.cfg @@ -1,7 +1,7 @@ [modify_fsurdat_basic_options] -fsurdat_in = ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc -fsurdat_out = ctsm/test/testinputs/surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_out.nc +fsurdat_in = ctsm/test/testinputs/surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.nc +fsurdat_out = ctsm/test/testinputs/surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.out.nc idealized = False process_subgrid_section = False diff --git a/tools/modify_input_files/modify_fsurdat_template.cfg b/tools/modify_input_files/modify_fsurdat_template.cfg index 3661784521..6923ee1cb9 100644 --- a/tools/modify_input_files/modify_fsurdat_template.cfg +++ b/tools/modify_input_files/modify_fsurdat_template.cfg @@ -29,8 +29,8 @@ fsurdat_out = FILL_THIS_IN # defaults, then set this to True. Hardwired values are as follows: # zbedrock = 10 # SLOPE = 0 -# PFTDATA_MASK = 1 # LANDFRAC_PFT = 1 +# LANDFRAC_MKSURFDATA = 1 # PCT_NATVEG = 100 other landunits 0 # PCT_SAND = 43 corresponds to loam # PCT_CLAY = 18 corresponds to loam diff --git a/tools/site_and_regional/default_data.cfg b/tools/site_and_regional/default_data.cfg index 7e841dca54..ba75580b9d 100644 --- a/tools/site_and_regional/default_data.cfg +++ b/tools/site_and_regional/default_data.cfg @@ -15,14 +15,14 @@ precname = CLMGSWP3v1.Precip tpqwname = CLMGSWP3v1.TPQW [surfdat] -dir = lnd/clm2/surfdata_map/release-clm5.0.18 -surfdat_16pft = surfdata_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr2000_c190214.nc -surfdat_78pft = surfdata_0.9x1.25_hist_78pfts_CMIP6_simyr2000_c190214.nc +dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 +surfdat_16pft = surfdata_0.9x1.25_hist_16pfts_CMIP6_1850-2015_c231103.nc +surfdat_78pft = surfdata_0.9x1.25_hist_78pfts_CMIP6_1850-2015_c231031.nc [landuse] -dir = lnd/clm2/surfdata_map/release-clm5.0.18 -landuse_16pft = landuse.timeseries_0.9x1.25_hist_16pfts_Irrig_CMIP6_simyr1850-2015_c190214.nc -landuse_78pft = landuse.timeseries_0.9x1.25_hist_78pfts_CMIP6_simyr1850-2015_c190214.nc +dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 +landuse_16pft = landuse.timeseries_0.9x1.25_hist_16_CMIP6_1850-2015_c231103.nc +landuse_78pft = landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c231031.nc [domain] file = share/domains/domain.lnd.fv0.9x1.25_gx1v7.151020.nc From d42b32c7d33799761d0d4ec54bef6fcee97926f9 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 7 Nov 2023 17:25:14 -0700 Subject: [PATCH 417/614] Add convert_ocean_to_land = .true. to MKSURFDATAESMF test for PASS --- cime_config/SystemTests/mksurfdataesmf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index af783850ba..d4f74788c9 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -128,4 +128,5 @@ def _modify_user_nl(self): """ append_to_user_nl_files(caseroot = self._get_caseroot(), component = "clm", - contents = "fsurdat = '{}'".format(self._fsurdat_nc)) + contents = "fsurdat = '{}'".format(self._fsurdat_nc) + "\n" + + "convert_ocean_to_land = .true.") From a0d014fae9550dd9ffbc934abd29ef16176f8208 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 7 Nov 2023 17:56:23 -0700 Subject: [PATCH 418/614] Black reformatging --- python/ctsm/modify_input_files/fsurdat_modifier.py | 10 +++++++++- python/ctsm/modify_input_files/modify_fsurdat.py | 7 ++++++- python/ctsm/test/test_sys_fsurdat_modifier.py | 4 +++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/python/ctsm/modify_input_files/fsurdat_modifier.py b/python/ctsm/modify_input_files/fsurdat_modifier.py index a511fcfddc..8f63339c2b 100644 --- a/python/ctsm/modify_input_files/fsurdat_modifier.py +++ b/python/ctsm/modify_input_files/fsurdat_modifier.py @@ -110,7 +110,15 @@ def read_cfg_subgrid(config, cfg_path, numurbl=3): subgrid_settings = {} var_list = config.options(section) - valid_list = ["pct_natveg", "pct_crop", "pct_lake", "pct_glacier", "pct_wetland", "pct_urban","pct_ocean"] + valid_list = [ + "pct_natveg", + "pct_crop", + "pct_lake", + "pct_glacier", + "pct_wetland", + "pct_urban", + "pct_ocean", + ] varsum = 0 for var in var_list: if valid_list.count(var) == 0: diff --git a/python/ctsm/modify_input_files/modify_fsurdat.py b/python/ctsm/modify_input_files/modify_fsurdat.py index 919c42098c..13495d8b10 100644 --- a/python/ctsm/modify_input_files/modify_fsurdat.py +++ b/python/ctsm/modify_input_files/modify_fsurdat.py @@ -264,7 +264,12 @@ def check_varlist(self, settings, allow_uppercase_vars=False): ) if len(val) != dim1: abort( - "Variable " + varname + " is " + str(len(val)) + ". It should be = " + str(dim1) + "Variable " + + varname + + " is " + + str(len(val)) + + ". It should be = " + + str(dim1) ) return settings_return diff --git a/python/ctsm/test/test_sys_fsurdat_modifier.py b/python/ctsm/test/test_sys_fsurdat_modifier.py index b4559d1867..ce498692ed 100755 --- a/python/ctsm/test/test_sys_fsurdat_modifier.py +++ b/python/ctsm/test/test_sys_fsurdat_modifier.py @@ -76,7 +76,9 @@ def test_short_config(self): self._cfg_file_path = os.path.join(self._testinputs_path, "modify_fsurdat_short.cfg") sys.argv = ["fsurdat_modifier", self._cfg_file_path] parser = fsurdat_modifier_arg_process() - fsurdat_out = os.path.join(self._testinputs_path, "surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.out.nc") + fsurdat_out = os.path.join( + self._testinputs_path, "surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.out.nc" + ) if os.path.exists(fsurdat_out): os.remove(fsurdat_out) fsurdat_modifier(parser) From 42e6796dc6045c6fd0bf4eacee0b48979e7ddbf4 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 7 Nov 2023 17:59:37 -0700 Subject: [PATCH 419/614] Update .git-blame-ignore-revs --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index a3795e4c6b..e30f3ada55 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -7,3 +7,4 @@ e44dc469439e02e9ee582dab274d890ebdfab104 b88e1cd1b28e3609684c79a2ec0e88f26cfc362b 51c102c5df2e0ef971b5f8eeeb477567899af63a 7dacad70e74e2ec97f6492d4e7a3cb5dd498bcd7 +a0d014fae9550dd9ffbc934abd29ef16176f8208 From f5325109cbda286d1b0c8dc5491a04a6ff499480 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 13 Nov 2023 14:59:50 -0700 Subject: [PATCH 420/614] Correct accidental line-delete from resolving conflicts --- python/ctsm/test/test_sys_fsurdat_modifier.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/ctsm/test/test_sys_fsurdat_modifier.py b/python/ctsm/test/test_sys_fsurdat_modifier.py index a1a29b9423..ce498692ed 100755 --- a/python/ctsm/test/test_sys_fsurdat_modifier.py +++ b/python/ctsm/test/test_sys_fsurdat_modifier.py @@ -45,6 +45,7 @@ def setUp(self): self._testinputs_path = testinputs_path self._fsurdat_in = os.path.join( testinputs_path, + "surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.nc", ) self._tempdir = tempfile.mkdtemp() self._cfg_file_path = os.path.join(self._tempdir, "modify_fsurdat.cfg") From 960e951f2244c84a6bcf3de1fcf8a8c667a1797f Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 13 Nov 2023 15:21:19 -0700 Subject: [PATCH 421/614] New surfdata_1x1 and 5x5 files in /testinputs --- ...urfdata_1x1_mexicocityMEX_hist_16pfts_CMIP6_2000_c231103.nc | 3 +++ ...x1_mexicocityMEX_hist_16pfts_CMIP6_2000_c231103_modified.nc | 3 +++ .../surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.nc | 3 +++ ...fdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031_modified.nc | 3 +++ ...amazon_hist_16pfts_CMIP6_2000_c231031_modified_with_crop.nc | 3 +++ 5 files changed, 15 insertions(+) create mode 100644 python/ctsm/test/testinputs/surfdata_1x1_mexicocityMEX_hist_16pfts_CMIP6_2000_c231103.nc create mode 100644 python/ctsm/test/testinputs/surfdata_1x1_mexicocityMEX_hist_16pfts_CMIP6_2000_c231103_modified.nc create mode 100644 python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.nc create mode 100644 python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031_modified.nc create mode 100644 python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031_modified_with_crop.nc diff --git a/python/ctsm/test/testinputs/surfdata_1x1_mexicocityMEX_hist_16pfts_CMIP6_2000_c231103.nc b/python/ctsm/test/testinputs/surfdata_1x1_mexicocityMEX_hist_16pfts_CMIP6_2000_c231103.nc new file mode 100644 index 0000000000..ae21f4f6f8 --- /dev/null +++ b/python/ctsm/test/testinputs/surfdata_1x1_mexicocityMEX_hist_16pfts_CMIP6_2000_c231103.nc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eee6618ad3cb7893a12570895c8e85ac70de540bc569e801ead871d00193029e +size 27908 diff --git a/python/ctsm/test/testinputs/surfdata_1x1_mexicocityMEX_hist_16pfts_CMIP6_2000_c231103_modified.nc b/python/ctsm/test/testinputs/surfdata_1x1_mexicocityMEX_hist_16pfts_CMIP6_2000_c231103_modified.nc new file mode 100644 index 0000000000..d6091aa096 --- /dev/null +++ b/python/ctsm/test/testinputs/surfdata_1x1_mexicocityMEX_hist_16pfts_CMIP6_2000_c231103_modified.nc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ad9d750e176cbc19afa709dfd05557086254570d240fa801c2e9c8b600d2f12 +size 28332 diff --git a/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.nc b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.nc new file mode 100644 index 0000000000..54b7bef1b6 --- /dev/null +++ b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.nc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0b39750baeb06add72002f0fc2540096b9876bb12d27a1c8d2ec2a5a11f83fd +size 260864 diff --git a/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031_modified.nc b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031_modified.nc new file mode 100644 index 0000000000..d2de87f751 --- /dev/null +++ b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031_modified.nc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd3aa2c1400ee44e59132fc7dd3c1f62bb654810ac0c0d67f76f092f1a62a3de +size 259264 diff --git a/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031_modified_with_crop.nc b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031_modified_with_crop.nc new file mode 100644 index 0000000000..3afe8b1803 --- /dev/null +++ b/python/ctsm/test/testinputs/surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031_modified_with_crop.nc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a7584a6344d482d5f047159d8bcc499575dcf87a1b6cd2014312f53245767d7 +size 259184 From e75853853ab1f1742b48fd2ba043e5a79193d6f1 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 15 Nov 2023 11:22:07 -0700 Subject: [PATCH 422/614] Add valid units to fsurdat variables abm and gdp --- tools/mksurfdata_esmf/src/mkfileMod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 1072c4710b..8b10436c55 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -430,10 +430,10 @@ subroutine mkfile_define_vars(pioid, dynlanduse) long_name='soil depth', units='m') call mkpio_def_spatial_var(pioid=pioid, varname='abm', xtype=PIO_INT, & - long_name='agricultural fire peak month', units='unitless') + long_name='agricultural fire peak month', units='month') call mkpio_def_spatial_var(pioid=pioid, varname='gdp', xtype=xtype, & - long_name='gdp', units='unitless') + long_name='gdp', units='k 1995US$ capita-1') call mkpio_def_spatial_var(pioid=pioid, varname='SLOPE', xtype=PIO_REAL, & long_name='mean topographic slope', units='degrees') From cecf5d9b3b3d75991fe6ca6fad8c4c7e08b913fb Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 16 Nov 2023 00:03:41 -0700 Subject: [PATCH 423/614] Remove scripts no longer needed with mksurfdata_esmf, and README documentation for it, resolves #2180 --- bld/README | 17 -- bld/listDefaultNamelist.pl | 349 ------------------------ bld/namelist_files/checkmapfiles.ncl | 236 ---------------- bld/namelist_files/createMapEntry.pl | 73 ----- bld/namelist_files/createMkSrfEntry.py | 56 ---- bld/queryDefaultNamelist.pl | 315 --------------------- bld/queryDefaultXML.pm | 161 ----------- tools/README | 3 +- tools/ncl_scripts/README | 15 - tools/ncl_scripts/getco2_historical.ncl | 196 ------------- 10 files changed, 1 insertion(+), 1420 deletions(-) delete mode 100755 bld/listDefaultNamelist.pl delete mode 100644 bld/namelist_files/checkmapfiles.ncl delete mode 100755 bld/namelist_files/createMapEntry.pl delete mode 100755 bld/namelist_files/createMkSrfEntry.py delete mode 100755 bld/queryDefaultNamelist.pl delete mode 100644 bld/queryDefaultXML.pm delete mode 100644 tools/ncl_scripts/README delete mode 100644 tools/ncl_scripts/getco2_historical.ncl diff --git a/bld/README b/bld/README index 71c663c268..ca87566ced 100644 --- a/bld/README +++ b/bld/README @@ -19,21 +19,6 @@ build-namelist --- Build the namelists needed env_run.xml --- Sample case runtime environment variables, so build-namelist can run outside of a case directory. ---------- Scripts to query namelist defaults -listDefaultNamelist.pl -- List the files needed, for a list of resolutions, - to run CLM that are currently NOT on your machine. - This file can then be used by - cime/CIME/Tools/check_input_data - to retreive them from the inputdata repository. - Setting up cases with create_newcase also does - this -- but only for the exact configuration - given. This tries to get all the files need - for several different resolutions and configurations - at once. -queryDefaultNamelist.pl - Query default namelist for settings of variables -queryDefaultXML.pm ------ Subroutines needed by queryDefaultNamelist.pl script - - --------- Test scripts directory unit_testers --- Directory of scripts to test scipts in this directory (most notably build-namelist) @@ -59,7 +44,5 @@ namelist_files/namelist_definition_drv_flds.xml --- Definition of add driver fie ---------- XML helper files namelist_files/LogMessages.pm ---- Perl module to handle log output -namelist_files/checkmapfiles.ncl -- NCL script to check that all of the mapping files are valid -namelist_files/createMapEntry.pl -- Perl script to create a map entry for the namelist_files/history_fields.xsl - Style sheet for history fields as created by script that lists all of the history fields from the source files (../src/main/findHistFields.pl) diff --git a/bld/listDefaultNamelist.pl b/bld/listDefaultNamelist.pl deleted file mode 100755 index a05618523f..0000000000 --- a/bld/listDefaultNamelist.pl +++ /dev/null @@ -1,349 +0,0 @@ -#!/usr/bin/env perl -#======================================================================= -# -# This is a script to list the missing files in your CESM inputdata area -# for a list of resolutions and model configurations. The list goes -# out to the file: clm.input_data_list. The check_input_data script -# can then be used to get this list of files from the SVN inputdata -# repository. -# -# Usage: -# -# listDefaultNamelist.pl [options] -# -# To get help on options and usage: -# -# listDefaultNamelist.pl -help -# -# To then get the files from the CESM SVN repository: -# -# ../cime/CIME/Tools/check_input_data --data-list-dir . --download -# -#======================================================================= - -use strict; -use Cwd qw(getcwd abs_path); -use Getopt::Long; -use English; -#use diagnostics; - -#----------------------------------------------------------------------------------------------- - -my $ProgName; -($ProgName = $PROGRAM_NAME) =~ s!(.*)/!!; # name of program -my $ProgDir = $1; # name of directory where program lives - -my $cwd = getcwd(); # current working directory -my $cfgdir; - -my $printTimes = 0; - -if ($ProgDir) { $cfgdir = $ProgDir; } -else { $cfgdir = $cwd; } - -#----------------------------------------------------------------------------------------------- -# Add $cfgdir to the list of paths that Perl searches for modules - -my @dirs = ( "$cfgdir", "../cime/utils/perl5lib" ); -unshift @INC, @dirs; - -require queryDefaultXML; - -# Defaults -my $cesmroot = abs_path( "$cfgdir/../"); - -# The namelist defaults file contains default values for all required namelist variables. -my @nl_defaults_files = ( "$cfgdir/namelist_files/namelist_defaults_overall.xml", - "$cfgdir/namelist_files/namelist_defaults_drv.xml", - ); -my $list = "clm.input_data_list"; -my %list_of_all_files; - -sub usage { - die <new($config_cachefile, '>') or die "can't open file: $config_cachefile"; - print $fh < - - -Specifies clm physics - -EOF - $fh->close(); -} - -#----------------------------------------------------------------------------------------------- - -sub GetListofNeededFiles { -# -# Get list of files that are needed to be copied to disk from the XML file. -# - my $inputopts_ref = shift; - my $settings_ref = shift; - my $files_ref = shift; - - my $defaults_ref = &queryDefaultXML::ReadDefaultXMLFile( $inputopts_ref, $settings_ref ); - my @keys = keys(%$defaults_ref); - my $csmdata = $$inputopts_ref{'csmdata'}; - my $printing = $$inputopts_ref{'printing'}; - foreach my $var ( @keys ) { - my $value = $$defaults_ref{$var}{'value'}; - my $isafile = $$defaults_ref{$var}{'isfile'}; - # If is a file - if ( $isafile ) { - $value =~ m#$csmdata/(.+?)/([^/]+)$#; - my $dir = $1; - my $file = $2; - - # If file is already in the list then do NOT do anything - if ( defined($list_of_all_files{"$dir/$file"} ) ) { - # Test that this file exists - } elsif ( -f "$value" ) { - print "File $value exists\n" if $printing; - $list_of_all_files{"$dir/$file"} = 1; - } else { - # If doesn't exist add it to the list of files to copy - my $cfile = $$inputopts_ref{'scpfrom'} . "$dir/$file"; - my @dfiles; - if ( defined($$files_ref{$dir}) ) { - my $dir_ref = $$files_ref{$dir}; - @dfiles = @$dir_ref; - my $match = 0; - foreach my $i ( @dfiles ) { - if ( $i eq $cfile ) { $match = 1; } - } - if ( $match == 0 ) { push( @dfiles, $cfile ); } - } else { - @dfiles = ( "$cfile" ); - } - if ( ! defined($$files_ref{$dir}) ) { - print " ADD $cfile to list to copy\n"; - } - $$files_ref{$dir} = \@dfiles; - $list_of_all_files{"$dir/$file"} = 0; - } - } - } - $printTimes++; -} - -#----------------------------------------------------------------------------------------------- - - my %opts = ( - res => undef, - silent => undef, - csmdata => "default", - list => $list, - usrdat => undef, - help => undef, - ); - - my $cmdline = "@ARGV"; - GetOptions( - "d|csmdata=s" => \$opts{'csmdata'}, - "r|res=s" => \$opts{'res'}, - "s|silent" => \$opts{'silent'}, - "u|usrdat=s" => \$opts{'usrdat'}, - "h|elp" => \$opts{'help'}, - ) or usage(); - - # Check for unparsed arguments - if (@ARGV) { - print "ERROR: unrecognized arguments: @ARGV\n"; - usage(); - } - if ( $opts{'help'} ) { - usage(); - } - # Set if should do extra printing or not (if silent mode is not set) - my $printing = 1; - if ( defined($opts{'silent'}) ) { - $printing = 0; - } - # - # Check for required arguments - # - foreach my $req ( "res", "list" ) { - if ( ! defined($opts{$req}) ) { - print "ERROR: $req NOT set and it is a required argument\n"; - usage(); - } - } - my %inputopts; - my @nl_definition_files = ( - "$cfgdir/namelist_files/namelist_definition_ctsm.xml" - ); - $inputopts{'nldef_files'} = \@nl_definition_files; - $inputopts{'empty_cfg_file'} = "config_cache.xml"; - - my $definition = Build::NamelistDefinition->new( $nl_definition_files[0] ); - foreach my $nl_defin_file ( @nl_definition_files ) { - $definition->add( "$nl_defin_file" ); - } - # Resolutions... - my @resolutions; - if ( $opts{'res'} eq "all" ) { - @resolutions = $definition->get_valid_values( "res", 'noquotes'=>1 ); - } else { - @resolutions = split( /,/, $opts{'res'} ); - } - - # Input options - &make_config_cache( "clm5_0", $inputopts{'empty_cfg_file'} ); - push @nl_defaults_files, "$cfgdir/namelist_files/namelist_defaults_ctsm.xml"; - if ( defined($opts{'usrdat'}) ) { - push @nl_defaults_files, "$cfgdir/namelist_files/namelist_defaults_usr_files.xml"; - } - $inputopts{'files'} = \@nl_defaults_files; - $inputopts{'printing'} = $printing; - $inputopts{'ProgName'} = $ProgName; - $inputopts{'cmdline'} = $cmdline; - $inputopts{'cfgdir'} = $cfgdir; - if ( $opts{'csmdata'} eq "default" && $ENV{'CSMDATA'} ne "" ) { - $opts{'csmdata'} = $ENV{'CSMDATA'}; - } - $inputopts{'csmdata'} = $opts{'csmdata'}; - $inputopts{'config'} = "noconfig"; - my %files; - # - # Loop over all resolutions asked for: 1.9x2.5, 10x15, 64x128 etc. - # - foreach my $res ( @resolutions ) { - if ( ! $definition->is_valid_value( "res", "'$res'" ) && $res ne $opts{'usrdat'} ) { - die "ERROR: Input resolution: $res is NOT a valid resolution\n"; - } - $inputopts{'hgrid'} = $res; - print "Resolution = $res\n" if $printing; - my %settings; - if ( $res eq $opts{'usrdat'} ) { - $settings{'clm_usr_name'} = $opts{'usrdat'}; - $settings{'csmdata'} = $opts{'csmdata'}; - $settings{'notest'} = 1; - } - # - # Loop for all possible land masks: USGS, gx1v6, gx3v5 etc. - # - foreach my $mask ( $definition->get_valid_values( "mask", 'noquotes'=>1 ) ) { - print "Mask = $mask \n" if $printing; - $settings{'mask'} = $mask; - # - # Loop over all possible simulation year: 1890, 2000, 2100 etc. - # - $settings{'sim_year_range'} = "constant"; - my @ssp_rcps = $definition->get_valid_values( "ssp_rcp", 'noquotes'=>1 ); - $settings{'ssp_rcp'} = $ssp_rcps[0]; -YEAR: foreach my $sim_year ( $definition->get_valid_values( "sim_year", 'noquotes'=>1 ) ) { - print "sim_year = $sim_year\n" if $printing; - $settings{'sim_year'} = $sim_year; - if ( $sim_year ne 1850 && $sim_year ne 2000 && $sim_year > 1800 ) { next YEAR; } - - my @bgcsettings = $definition->get_valid_values( "bgc_mode", 'noquotes'=>1 ); - print "bgc=@bgcsettings\n" if $printing; - # - # Loop over all possible BGC settings - # - foreach my $bgc ( @bgcsettings ) { - $settings{'bgc'} = $bgc; - my @crop_vals; - if ( $bgc =~ /^cn/ ) { - @crop_vals = ( "on", "off" ); - } else { - @crop_vals = ( "off" ); - } - $settings{'glc_nec'} = 10; - # - # Loop over all possible crop settings - # - foreach my $crop ( @crop_vals ) { - $settings{'crop'} = $crop; - if ( $crop eq "on" ) { - $settings{'maxpft'} = 78; - } else { - $settings{'maxpft'} = 17; - } - $inputopts{'namelist'} = "clm_inparm"; - &GetListofNeededFiles( \%inputopts, \%settings, \%files ); - if ( $printTimes >= 1 ) { - $inputopts{'printing'} = 0; - } - } - } - } - # - # Now do sim-year ranges - # - $settings{'bgc'} = "cn"; - $inputopts{'namelist'} = "clm_inparm"; - foreach my $sim_year_range ( $definition->get_valid_values( "sim_year_range", 'noquotes'=>1 ) ) { - $settings{'sim_year_range'} = $sim_year_range; - if ( $sim_year_range =~ /([0-9]+)-([0-9]+)/ ) { - $settings{'sim_year'} = $1; - } - # - # Loop over all possible ssp_rcp's - # - print "sim_year_range=$sim_year_range ssp_rcp=@ssp_rcps\n" if $printing; - foreach my $ssp_rcp ( @ssp_rcps ) { - $settings{'ssp_rcp'} = $ssp_rcp; - &GetListofNeededFiles( \%inputopts, \%settings, \%files ); - if ( $printTimes >= 1 ) { - $inputopts{'printing'} = 0; - } - } - } - } - } - # - # Loop over directories that need to have files copied into - # - my $hostname; - my $csmdata = $inputopts{'csmdata'}; - open( OUT, ">$list" ) || die "ERROR: trouble opening output file: $list"; - foreach my $dir ( sort(keys(%files)) ) { - if ( $dir eq "." ) { next; } - if ( $dir eq "/" ) { next; } - if ( $dir eq "\n" ) { next; } - if ( $dir eq "" ) { next; } - if ( ! defined($dir) ) { next; } - my $files_ref = $files{$dir}; - my @files = @$files_ref; - foreach my $file ( @files ) { - if ( $file !~ /\n$/ ) { $file = "$file\n"; } - print OUT "file = \$DIN_LOC_ROOT/$file"; - } - } - close( OUT ); - if ( $printing ) { - print "\n\nSuccessful\n\n" - } diff --git a/bld/namelist_files/checkmapfiles.ncl b/bld/namelist_files/checkmapfiles.ncl deleted file mode 100644 index e37100747a..0000000000 --- a/bld/namelist_files/checkmapfiles.ncl +++ /dev/null @@ -1,236 +0,0 @@ -; -; Check that the *_b values are the same between the mapping files -; at the same output resolution. -; -; Erik Kluzek -; Nov/18/2011 -; $Id$ -; $HeadURL; -; - - print( "Check that datm mapping files are consistent" ); - resolutions = (/ "128x256", "64x128", "48x96", "94x192", "0.23x0.31", "0.47x0.63", "0.9x1.25", "1.9x2.5", "2.5x3.33", "4x5", "10x15", "0.125nldas2", "5x5_amazon", "1x1_vancouverCAN", "1x1_mexicocityMEX", "1x1_asphaltjungleNJ", "1x1_brazil", "1x1_urbanc_alpha", "1x1_numaIA", "1x1_smallvilleIA", "ne4np4", "ne16np4", "ne30np4", "ne60np4", "ne120np4", "ne240np4" /); - - space = " "; - badres = 0 - badresolutions = new( (/ 1000 /), string ) - chkres = 0 - chkresolutions = new( (/ 1000 /), string ) - -procedure checkit( desc:string, maxdiff:numeric, res:string, lmask:string, eps:numeric ) -; -; check that difference is within reasonable tolerance... -; -begin - reso = res+"_"+lmask; - if ( maxdiff .gt. eps )then - print( space+space+space+desc+" are off by more than tolerance for "+reso+" resolution" ); - print( space+space+space+"maximum difference = "+maxdiff ); - if ( .not. any(badresolutions .eq. reso ) )then - badresolutions(badres) = reso; - badres = badres + 1 - end if - else - print( space+space+space+"File OK for "+desc+"!" ); - end if - if ( .not. any(chkresolutions .eq. reso ) )then - chkresolutions(chkres) = reso; - chkres = chkres + 1 - end if -end - - -function checkdims( desc:string, dsizefile1 [*]:integer, dsizefile2 [*]:integer, res:string, lmask:string ) -; -; check that dimensions are the same between the file variables -; -begin - reso = res+"_"+lmask; - if ( any( dsizefile1 .ne. dsizefile2) )then - print( space+space+space+desc+" dimensions are different for "+reso+" resolution" ); - print( space+space+space+"dim first file "+dsizefile1 ); - print( space+space+space+"dim second file "+dsizefile2 ); - if ( .not. any(badresolutions .eq. reso ) )then - badresolutions(badres) = reso; - badres = badres + 1 - end if - return( False ); - else - print( space+space+space+"File dims OK for "+desc+"!" ); - return( True ); - end if - if ( .not. any(chkresolutions .eq. reso ) )then - chkresolutions(chkres) = reso; - chkres = chkres + 1 - end if -end - -begin - - csmdata = getenv("CSMDATA"); - clmroot = getenv("CLM_ROOT"); - querynml = "bld/queryDefaultNamelist.pl -silent -justvalue -namelist clmexp"; - if ( .not. ismissing(csmdata) )then - querynml = querynml+" -csmdata "+csmdata; - end if - if ( ismissing(clmroot) )then - querynml = "../../"+querynml; - else - querynml = clmroot+"/components/clm/"+querynml; - end if - - print( "query string="+querynml ) - - - mapgrids = (/"0.5x0.5_nomask", "0.25x0.25_nomask", "0.125x0.125_nomask", "3x3min_nomask", "5x5min_nomask", "10x10min_nomask", "0.9x1.25_nomask", "1km-merge-10min_HYDRO1K-merge-nomask"/); - do i = 0, dimsizes(resolutions)-1 - res = resolutions(i); - print( "Go through maps for Resolution: "+res ); - do j = 0, dimsizes(mapgrids)-1 - grid = str_get_field( mapgrids(j), 1, "_" ); - lmask = str_get_field( mapgrids(j), 2, "_" ); - print( space+"Look for maps from Grid: "+grid+"_"+lmask); - - querynmlres = querynml+" -options frm_lmask="+lmask+",frm_hgrid="+grid+",to_hgrid="+res+",to_lmask=nomask"; - ; - ; Get map filename and open it - ; - mapfile = systemfunc( querynmlres+" -var map" ); - if ( systemfunc("test -f "+mapfile+"; echo $?" ) .ne. 0 )then - delete( mapfile ); - continue; - end if - print( space+"Use mapfile: "+mapfile ); - ncm = addfile( mapfile, "r" ); - - if ( .not. isvar("ncm0") )then - ncm0 = ncm; - else - vars = (/"yc_b", "xc_b", "area_b", "xv_b", "yv_b" /); - k = 0; - if ( checkdims( vars(k), dimsizes(ncm->$vars(k)$), dimsizes(ncm0->$vars(k)$), res, "nomask" ) )then - do k = 0, dimsizes(vars)-1 - maxdiff = max( abs(ncm->$vars(k)$ - ncm0->$vars(k)$) ); - checkit( vars(k), maxdiff, res, "nomask", 1.e-12 ); - delete( maxdiff ); - end do - var = "mask_b" - imaxdiff = max( abs(ncm->$var$ - ncm0->$var$) ); - checkit( var, imaxdiff, res, "nomask", 1.e-12 ); - delete( imaxdiff ); - end if - delete( ncm ); - end if - delete( mapfile ); - - end do - - delete( grid ); - delete( lmask ); - delete( res ); - if ( isvar("ncm0") )then - delete( ncm0 ); - end if - - end do - ; - ; go the other direction now check the _a variables - ; - mksrf_files = (/"mksrf_fvegtyp", "mksrf_fglacier", "mksrf_furbtopo", "mksrf_flai", "mksrf_fsoitex", "mksrf_fsoicol", "mksrf_ffrac", "mksrf_fmax", "mksrf_ftopo", "mksrf_firrig", "mksrf_forganic", "mksrf_flakwat", "mksrf_fwetlnd", "mksrf_furban", "mksrf_fvocef"/) - do i = 0, dimsizes(mapgrids)-1 - grid = str_get_field( mapgrids(i), 1, "_" ); - lmask = str_get_field( mapgrids(i), 2, "_" ); - print( "Grid: "+grid); - print( "Mask: "+lmask); - do j = 0, dimsizes(resolutions)-1 - res = resolutions(j); - print( "res: "+res ); - - querynmlres = querynml+" -options frm_lmask="+lmask+",frm_hgrid="+grid+",to_hgrid="+res+",to_lmask=nomask"; - ; - ; Get map filename and open it - ; - mapfile = systemfunc( querynmlres+" -var map" ); - if ( systemfunc("test -f "+mapfile+"; echo $?" ) .ne. 0 )then - delete( mapfile ); - continue; - end if - print( space+"Use mapfile: "+mapfile ); - ncm = addfile( mapfile, "r" ); - - if ( .not. isvar("ncm0") )then - ncm0 = ncm; - else - vars = (/"yc_a", "xc_a", "area_a", "xv_a", "yv_a" /); - vars2 = (/"LATIXY", "LONGXY", "AREA" /); - k = 0; - if ( checkdims( vars(k), dimsizes(ncm->$vars(k)$), dimsizes(ncm0->$vars(k)$), res, "nomask" ) )then - do k = 0, dimsizes(vars)-1 - maxdiff = max( abs(ncm->$vars(k)$ - ncm0->$vars(k)$) ); - checkit( vars(k), maxdiff, res, "nomask", 1.e-12 ); - delete( maxdiff ); - end do - end if - var = "mask_a" - imaxdiff = max( abs(ncm->$var$ - ncm0->$var$) ); - checkit( var, imaxdiff, res, "nomask", 1.e-12 ); - delete( imaxdiff ); - ; - ; Get mksurfdata input datasets - ; - do k = 0, dimsizes(mksrf_files)-1 - srffile = systemfunc( querynmlres+" -var "+mksrf_files(k) ); - if ( systemfunc("test -f "+srffile+"; echo $?" ) .ne. 0 )then - delete( srffile ); - continue; - end if - print( space+"Use srffile: "+srffile ); - ncs = addfile( srffile, "r" ); - n = 0; - if ( checkdims( vars(n), dimsizes(ncm->$vars(n)$), ndtooned(dimsizes(ncs->$vars2(n)$)), res, "nomask" ) )then - do n = 0, dimsizes(vars2)-1 - maxdiff = max( abs(ncm->$vars(n)$ - ndtooned(ncs->$vars2(n)$)) ); - checkit( vars(n), maxdiff, res, "nomask", 1.e-12 ); - delete( maxdiff ); - end do - var = "mask_a" - var2 = "LANDMASK" - imaxdiff = max( abs(ncm->$var$ - ndtooned(ncs->$var2$)) ); - checkit( var, imaxdiff, res, "nomask", 1.e-12 ); - end if - delete( ncs ); - end do - delete( ncm ); - end if - delete( mapfile ); - - end do - - if ( isvar("vars") )then - delete( vars ) - end if - if ( isvar("vars2") )then - delete( vars2 ) - end if - delete( grid ); - delete( lmask ); - delete( res ); - if ( isvar("ncm0") )then - delete( ncm0 ); - end if - - end do - if ( chkres .gt. 0 )then - print( "resolutions checked = " ); - print( chkresolutions(0:chkres-1) ); - end if - if ( badres .gt. 0 )then - print( "badresolutions = " ); - print( badresolutions(0:badres-1) ); - end if - - print( "===============================" ); - print( "Successfully went through files" ); - -end - diff --git a/bld/namelist_files/createMapEntry.pl b/bld/namelist_files/createMapEntry.pl deleted file mode 100755 index 561683bb05..0000000000 --- a/bld/namelist_files/createMapEntry.pl +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env perl -# -# July 18 2012 Muszala -# -# createMapEntry.pl - A simple script to dump a list of mappings for a specified resolution to then -# cut and paste into namelist_defaults_ctsm.xml. A better way is to write the output of this script -# to a file and then directly insert that file into namelist_defaults_ctsm.xml (using :r foo in vim for -# example). -# -# Example usage:>> ./createMapEntry.pl 1x1_brazil -# will create XML entries for maps in ../lnd/clm2/mappingdata/maps/1x1_brazil such as: -# -# lnd/clm2/mappingdata/maps/1x1_brazil/map_0.5x0.5_AVHRR_to_1x1_brazil_nomask_aave_da_c120717.nc -# -use Cwd; -use strict; -use English; -use IO::File; -use Getopt::Long; - - my $date = scalar localtime() ; - my $scriptName; - ($scriptName = $0) =~ s!(.*)/!!; # get name of script - my $cwd = getcwd(); - my $CSMDATA = "/glade/p/cesm/cseg/inputdata"; - - if ($#ARGV != 0 ) { - usage(); - exit; - } - my $grid=$ARGV[0]; - - sub usage { - die < - is the resolution to use to dump text to paste into namelist_defaults_ctsm.xml -EOF - } - - #~# set up directory paths - my $pathStub="lnd/clm2/mappingdata/maps"; - my $partialPath="$pathStub/$grid"; - my $fullPath = "$CSMDATA/$partialPath"; - - #~# open and read directory - opendir DIR, $fullPath or die "Cannot read dir! $fullPath"; - my @list = readdir DIR; - - #~# print a unique start string in the XML comments - print "\n"; - print "\n \n\n"; - - foreach my $foo ( @list ) { - next if ($foo =~ m/^\./); #~# skip anything in the directory with a leading or stand alone 'dot' - $foo =~ s/$grid/RES/; # Replace grid trying to match with RES (so underscores in the grid name don't mess up the matching) - my @tokens = split(/_/, $foo); #~# split foo name by the underscore - #~# write out lines for namelist_defaults_ctsm.xml nomask" files - my $from_mask = $tokens[2]; - if ( $from_mask =~ /nomask/ ) { - if ( $tokens[5] eq "nomask" && $tokens[4] eq "RES" ) { - print "$partialPath/$foo\n"; - } - } - } - - #~# print a unique end string in the XML comments - print "\n \n"; - closedir(DIR); - exit 0; diff --git a/bld/namelist_files/createMkSrfEntry.py b/bld/namelist_files/createMkSrfEntry.py deleted file mode 100755 index 3f12df1509..0000000000 --- a/bld/namelist_files/createMkSrfEntry.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python3 - -import os, sys - -class mksrfDataEntry_prog: - - # Class data - year_start = 850 - year_end = 1849 - ssp_rcp = "hist" - subdir = "pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012" - cdate = 171012 - desc = "histclm50_LUH2" - - def parse_cmdline_args( self ): - "Parse the command line arguments for create data entry list" - from optparse import OptionParser, OptionGroup - - parser = OptionParser( usage="%prog [options]" ) - options = OptionGroup( parser, "Options" ) - options.add_option( "-s", "--year_start", dest="year_start", default=self.year_start, \ - help="Start year" ) - options.add_option( "-f", "--year_end", dest="year_end", default=self.year_end, \ - help="End year" ) - options.add_option( "-d", "--subdir", dest="subdir", default=self.subdir, \ - help="Subdirectory" ) - options.add_option( "--cdate", dest="cdate", default=self.cdate, \ - help="Creation date" ) - options.add_option( "--desc", dest="desc", default=self.desc, \ - help="Description string" ) - parser.add_option_group(options) - (options, args) = parser.parse_args() - if len(args) != 0: - parser.error("incorrect number of arguments") - - self.year_start = options.year_start - self.year_end = options.year_end - self.subdir = options.subdir - self.cdate = options.cdate - self.desc = options.desc - - def printentry( self, year ): - "Print a single entry" - print( 'lnd/clm2/rawdata/%s/mksrf_landuse_%s_%s.c%s.nc' % (self.subdir, self.desc, year, self.cdate) ) - print( '\n' ) - -entry = mksrfDataEntry_prog() -entry.parse_cmdline_args() - -for year in range(entry.year_start, entry.year_end+1): - entry.printentry( year ) - - - - diff --git a/bld/queryDefaultNamelist.pl b/bld/queryDefaultNamelist.pl deleted file mode 100755 index 920e91eb48..0000000000 --- a/bld/queryDefaultNamelist.pl +++ /dev/null @@ -1,315 +0,0 @@ -#!/usr/bin/env perl -#======================================================================= -# -# This is a script to read the CLM namelist XML file -# -# Usage: -# -# queryDefaultNamelist.pl [options] -# -# To get help on options and usage: -# -# queryDefaultNamelist.pl -help -# -#======================================================================= - -use Cwd; -use strict; -#use diagnostics; -use Getopt::Long; -use English; - -#----------------------------------------------------------------------------------------------- - -#Figure out where configure directory is and where can use the XML/Lite module from -my $ProgName; -($ProgName = $PROGRAM_NAME) =~ s!(.*)/!!; # name of program -my $ProgDir = $1; # name of directory where program lives - -my $cwd = getcwd(); # current working directory -my $cfgdir; - -if ($ProgDir) { $cfgdir = $ProgDir; } -else { $cfgdir = $cwd; } - -#----------------------------------------------------------------------------------------------- -# Add $cfgdir to the list of paths that Perl searches for modules -my @dirs = ( "$cfgdir", - "$cfgdir/../cime/utils/perl5lib", - "$cfgdir/../../../cime/utils/perl5lib" ); -unshift @INC, @dirs; -my $result = eval "require XML::Lite"; -if ( ! defined($result) ) { - die <<"EOF"; -** Cannot find perl module \"XML/Lite.pm\" from directories: @dirs ** -EOF -} -require Build::Config; -require Build::NamelistDefinition; -require queryDefaultXML; - -# Defaults -my $namelist = "clm_inparm"; -my $config = "config_cache.xml"; - - -sub usage { - die < $namelist, - var => undef, - hgrid => undef, - config => undef, - cesm => undef, - csmdata => undef, - demand => undef, - test => undef, - onlyfiles => undef, - fileonly => undef, - silent => undef, - usrname => undef, - help => undef, - options => undef, - ); - - my $cmdline = "@ARGV"; - GetOptions( - "f|file=s" => \$opts{'file'}, - "n|namelist=s" => \$opts{'namelist'}, - "v|var=s" => \$opts{'var'}, - "r|res=s" => \$opts{'hgrid'}, - "config=s" => \$opts{'config'}, - "cesm" => \$opts{'cesm'}, - "csmdata=s" => \$opts{'csmdata'}, - "demand" => \$opts{'demand'}, - "options=s" => \$opts{'options'}, - "t|test" => \$opts{'test'}, - "onlyfiles" => \$opts{'onlyfiles'}, - "filenameonly" => \$opts{'fileonly'}, - "justvalues" => \$opts{'justvalues'}, - "usrname=s" => \$opts{'usrname'}, - "s|silent" => \$opts{'silent'}, - "h|elp" => \$opts{'help'}, - ) or usage(); - - # Check for unparsed arguments - if (@ARGV) { - print "ERROR: unrecognized arguments: @ARGV\n"; - usage(); - } - if ( $opts{'help'} ) { - usage(); - } - # Set if should do extra printing or not (if silent mode is not set) - my $printing = 1; - if ( defined($opts{'silent'}) ) { - $printing = 0; - } - # Get list of options from command-line into the settings hash - my %settings; - if ( defined($opts{'options'}) ) { - $opts{'options'} =~ s/\s//g; # Remove all white-space in options - my @optionlist = split( ",", $opts{'options'} ); - foreach my $item ( @optionlist ) { - my ($key,$value) = split( "=", $item ); - $settings{$key} = $value; - } - } - my $csmdata = ""; - if ( defined($opts{'fileonly'}) ) { - if ( ! defined($opts{'justvalues'}) ) { print "When -filenameonly option used, -justvalues is set as well\n" if $printing; } - if ( ! defined($opts{'onlyfiles'}) ) { print "When -filenameonly option used, -onlyfiles is set as well\n" if $printing; } - $opts{'justvalues'} = 1; - $opts{'onlyfiles'} = 1; - } - # List of input options - my %inputopts; - # This namelist files under the cime directories are in version 2 format and can't be read by perl code EBK 11/15/2016 - my @nl_definition_files = ("$cfgdir/namelist_files/namelist_definition_drv.xml", - "$cfgdir/namelist_files/namelist_definition_ctsm.xml" - ); - $inputopts{empty_cfg_file} = "$cfgdir/config_files/config_definition_ctsm.xml"; - $inputopts{nldef_files} = \@nl_definition_files; - $inputopts{namelist} = $opts{namelist}; - $inputopts{printing} = $printing; - $inputopts{cfgdir} = $cfgdir; - $inputopts{ProgName} = $ProgName; - $inputopts{cmdline} = $cmdline; - - my $exitearly = 0; - my $definition = Build::NamelistDefinition->new( $nl_definition_files[0] ); - foreach my $nl_defin_file ( @nl_definition_files ) { - if ( ! -f "$nl_defin_file" ) { - die "($ProgName $cmdline) ERROR:: bad namelist definition filename: $nl_defin_file.\n"; - } - $definition->add( "$nl_defin_file" ); - } - - if ( ! defined($opts{csmdata}) ) { - $inputopts{csmdata} = "default"; - } else { - $inputopts{csmdata} = $opts{csmdata}; - } - if ( defined($opts{cesm}) ) { - $inputopts{csmdata} = '$DIN_LOC_ROOT'; - } - if ( ! defined($opts{config}) ) { - $inputopts{config} = "noconfig"; - } else { - $inputopts{config} = $opts{config}; - } - if ( ! defined($opts{var}) ) { - $settings{'var'} = undef; - } elsif ( $opts{var} eq "list" ) { - print "Valid variables: " if $printing; - my @vars = $definition->get_var_names( ); - print "@vars\n"; - $exitearly = 1; - } else { - $settings{'var'} = $opts{'var'}; - } - if ( ! defined($opts{hgrid}) ) { - $inputopts{hgrid} = "any"; - } elsif ( $opts{hgrid} eq "list" ) { - print "Valid resolutions: " if $printing; - my @hgrids = $definition->get_valid_values( "res", 'noquotes'=>1 ); - print "@hgrids\n"; - $exitearly = 1; - } else { - if ( ! $definition->is_valid_value( "res", $opts{hgrid}, 'noquotes'=>1 ) ) { - if ( $opts{'hgrid'} ne $opts{'usrname'} ) { - die "($ProgName $cmdline) ERROR:: invalid resolution entered.\n"; - } - } - $inputopts{hgrid} = $opts{hgrid}; - } - # The namelist defaults file contains default values for all required namelist variables. - my @nl_defaults_files = ( "$cfgdir/namelist_files/namelist_defaults_overall.xml" ); - if ( defined($opts{'usrname'}) ) { - my $nl_defaults_file = "$cfgdir/namelist_files/namelist_defaults_usr_files.xml"; - push( @nl_defaults_files, $nl_defaults_file ); - $settings{'clm_usr_name'} = $opts{'usrname'}; - $settings{'notest'} = ! $opts{'test'}; - $settings{'csmdata'} = $inputopts{csmdata}; - } else { - my @files = ( "$cfgdir/namelist_files/namelist_defaults_ctsm.xml", - "$cfgdir/namelist_files/namelist_defaults_ctsm_tools.xml", - "$cfgdir/namelist_files/namelist_defaults_drv.xml", - "$cfgdir/namelist_files/namelist_defaults_drydep.xml", - ); - push( @nl_defaults_files, @files ); - } - if ( ! $exitearly ) { - $inputopts{files} = \@nl_defaults_files; - - my $defaults_ref = &queryDefaultXML::ReadDefaultXMLFile( \%inputopts, \%settings ); - my %defaults = %$defaults_ref; - my @keys = keys(%defaults); - if ( defined($opts{'demand'}) && ($#keys == -1) ) { - die "($ProgName $cmdline) ERROR:: demand option is set and nothing was found.\n"; - } - my $print; - foreach my $var ( @keys ) { - $print = 1; - my $value = $defaults{$var}{value}; - my $isadir = $defaults{$var}{isdir}; - my $isafile = $defaults{$var}{isfile}; - my $isastr = $defaults{$var}{isstr}; - # If onlyfiles option set do NOT print if is NOT a file - if ( defined($opts{'onlyfiles'}) && (! $isafile) ) { - $print = undef; - } - # If is a directory - if ( $isadir ) { - # Test that this directory exists - if ( defined($opts{'test'}) && defined($print) ) { - print "Test that directory $value exists\n" if $printing; - if ( ! -d "$value" ) { - die "($ProgName) ERROR:: directory $value does NOT exist!\n"; - } - } - } - # If is a file - if ( $isafile ) { - # Test that this file exists - if ( defined($opts{'test'}) && defined($print) ) { - chomp( $value ); - print "Test that file $value exists\n" if $printing; - if ( ! -f "$value" ) { - die "($ProgName) ERROR:: file $value does NOT exist!\n"; - } - } - } - # If a string - if ( (! defined($opts{'justvalues'}) ) && ($isastr) ) { - $value = "\'$value\'"; - } - # if you just want the filename -- not the full path with the directory - if ( defined($opts{'fileonly'}) ) { - $value =~ s!(.*)/!!; - } - if ( defined($print) ) { - if ( ! defined($opts{'justvalues'}) ) { - print "$var = "; - } - print "$value\n"; - } - } - } - if ( $printing && defined($opts{'test'}) ) { - print "\n\nTesting was successful\n\n" - } - diff --git a/bld/queryDefaultXML.pm b/bld/queryDefaultXML.pm deleted file mode 100644 index 85a81d8f9a..0000000000 --- a/bld/queryDefaultXML.pm +++ /dev/null @@ -1,161 +0,0 @@ -#======================================================================= -# -# This is a perl module to read in a list of namelist_default files. -# -#======================================================================= -use strict; -use Build::Config; -use Build::NamelistDefinition; -use Build::NamelistDefaults; -use Build::Namelist; - -package queryDefaultXML; - -#------------------------------------------------------------------------------- - -sub read_cfg_file -# -# Read in the configuration cache XML file on the build-time configuration -# -{ - my ($file, $empty_cfg_file, $printing, $settings_ref) = @_; - - my $cfg; - my %config; - if ( $file eq "noconfig" ) { - print "No configuration cache file to read in.\n" if $printing; - $cfg = Build::Config->new( $empty_cfg_file ); - } elsif ( -f "$file" ) { - $cfg = Build::Config->new($file); - } else { - die "Bad filename entered: $file does NOT exist or can not open it.\n"; - } - # - # Make sure variables are set to valid values - # - foreach my $key ( keys( %config ) ) { - if ( $cfg->is_valid_name( $key ) ) { - $cfg->set( $key, $config{$key} ); - } - } - foreach my $key ( $cfg->get_names( ) ) { - if ( defined($$settings_ref{$key}) ) { - if ( $cfg->is_valid_name( $key ) ) { - $cfg->set( $key, $$settings_ref{$key} ); - } - } - } - return( $cfg ); -} - -#------------------------------------------------------------------------------- - -sub ReadDefaultXMLFile { -# -# Read in the default XML file for the default namelist settings -# - my $opts_ref = shift; - my $settings_ref = shift; - - # Error check that input and opts hash has the expected variables - my $ProgName = $$opts_ref{'ProgName'}; - my $nm = "${ProgName}::ReadDefaultXMLFile"; - my @required_list = ( "files", "nldef_files", "empty_cfg_file", "config", "namelist", - "csmdata", "hgrid", "printing", "ProgName", "cmdline", - "cfgdir" ); - foreach my $var ( @required_list ) { - if ( ! defined($$opts_ref{$var}) ) { - die "ERROR($nm): Required input variable $var was not found\n"; - } - } - my $printing = $$opts_ref{'printing'}; - my $cmdline = $$opts_ref{'cmdline'}; - # Initialize some local variables - my $files_ref = $$opts_ref{'files'}; - my @files = @$files_ref; - my $nldef_ref = $$opts_ref{'nldef_files'}; - my @nl_definition_files= @$nldef_ref; - my $empty_config_file = $$opts_ref{'empty_cfg_file'}; - my $namelist = $$opts_ref{'namelist'}; - - my $cfg = read_cfg_file( $$opts_ref{'config'}, $$opts_ref{'empty_cfg_file'}, - $printing, $settings_ref ); - - # - # Set up options to send to namelist defaults object - # - my %nlopts; - foreach my $var ( keys( %$settings_ref) ) { - if ( $var ne "csmdata" ) { - $nlopts{$var} = $$settings_ref{$var}; - } - } - if ( $$opts_ref{'hgrid'} ne "any" ) { - $nlopts{'hgrid'} = $$opts_ref{'hgrid'}; - } - # - # Loop through all variables in files - # - print "($nm) Read: $files[0]\n" if $printing; - my %defaults; - my $nldefaults = Build::NamelistDefaults->new($files[0], $cfg); - for ( my $i = 1; $i <= $#files; $i++ ) { - print "($nm) Read: $files[$i]\n" if $printing; - $nldefaults->add( $files[$i] ); - } - my $definition = Build::NamelistDefinition->new( $nl_definition_files[0] ); - for ( my $i = 1; $i <= $#nl_definition_files; $i++ ) { - print "($nm) Read: $nl_definition_files[$i]\n" if $printing; - $definition->add( $nl_definition_files[$i] ); - } - if ( $$opts_ref{'csmdata'} eq "default" ) { - $$opts_ref{'csmdata'} = $nldefaults->get_value( "csmdata", \%nlopts ); - } - $nlopts{'csmdata'} = $$opts_ref{'csmdata'}; - foreach my $name ( $nldefaults->get_variable_names() ) { - my $value = $nldefaults->get_value( $name, \%nlopts ); - if ( $value eq "null" ) { next; } - if ( defined($$settings_ref{'var'}) ) { - if ( $name ne $$settings_ref{'var'} ) { next; } - } - $value =~ s/\n//g; - my $isafile = 0; - if ( $definition->is_input_pathname($name) ) { - - if ( defined($$settings_ref{'clm_usr_name'}) ) { - $value = $nldefaults->get_usr_file( $name, $definition, \%nlopts ); - } - if ( $value && ($value !~ /^\/.+$/) ) { - $value = $$opts_ref{'csmdata'} . "/" . $value; - } - $isafile = 1; - } - my $isadir = 0; - my $isastr = 0; - if ( $definition->get_str_len($name) > 0 ) { - $isastr = 1; - } - # - # If is a directory (is a file and csmdata or a var with dir in name) - # - if ( $isafile && (($name eq "csmdata") || ($name =~ /dir/)) ) { - if ( $name eq "csmdata" ) { - $value = $$opts_ref{'csmdata'}; - $isadir = 1; - } else { - $isadir = 1; - } - } - # Return hash with the results - my $group = $definition->get_group_name( $name ); - if ( $group eq $namelist && $value && (! exists($defaults{$name}{'value'})) ) { - $defaults{$name}{'value'} = $value; - $defaults{$name}{'isfile'} = $isafile; - $defaults{$name}{'isdir'} = $isadir; - $defaults{$name}{'isstr'} = $isastr; - } - } - return( \%defaults ); -} - -1 # To make use or require happy diff --git a/tools/README b/tools/README index c65e694b98..34f106069b 100644 --- a/tools/README +++ b/tools/README @@ -11,7 +11,6 @@ I. General directory structure: mkmapgrids ------- Create regular lat/lon SCRIP grid files mkprocdata_map --- Convert output unstructured grids into a 2D format that can be plotted easily - ncl_scripts ------ NCL post or pre processing scripts. site_and_regional Scripts for handling input datasets for site and regional cases. These scripts both help with creation of datasets using the @@ -80,7 +79,7 @@ II. Notes on building/running for each of the above tools: CMakeLists.txt -- Tells CMake how to build the source code Makefile -------- GNU makefile to link the program together - mkmapgrids, site_and_regional, and ncl_scripts only contain scripts so don't have the above build files. + mkmapgrids, and site_and_regional only contain scripts so don't have the above build files. Some tools have copies of files from other directories -- see the README.filecopies file for more information on this. diff --git a/tools/ncl_scripts/README b/tools/ncl_scripts/README deleted file mode 100644 index 72073f5035..0000000000 --- a/tools/ncl_scripts/README +++ /dev/null @@ -1,15 +0,0 @@ -$CTSMROOT/tools/ncl_scripts Jun/08/2018 - -CLM NCL script tools for analysis of CLM history files -- or for creation or -modification of CLM input files. - -In order to make these scripts work in the testing framework the following must -be done. - -1.) Respond to CSMDATA and CLM_ROOT as needed. -2.) Print a line with "success" after the work is completed. - -NCL Scripts available: - -getco2_historical.ncl ------- Get historical CO2 to use for input in datm8 streams - diff --git a/tools/ncl_scripts/getco2_historical.ncl b/tools/ncl_scripts/getco2_historical.ncl deleted file mode 100644 index c071fa42d6..0000000000 --- a/tools/ncl_scripts/getco2_historical.ncl +++ /dev/null @@ -1,196 +0,0 @@ -; -; Take the greenhouse gas file used by CAM for historical (and future) representations of -; greenhouse gases, and convert it to a format that can be used by streams. -; So include domain data for a single point (or latitude bands) that covers the globe, as well -; as CO2 data over those latitude bands. In the process we also discard the other -; greenhouse gases, as the datm can only pass CO2. -; -; Erik Kluzek -; Mar/03/2010 -; -begin - ; =========================================================================================================== - - - ; =========================================================================================================== - ; - ; Setup the namelist query script - ; - csmdata = getenv("CSMDATA"); - clmroot = getenv("CLM_ROOT"); - hgrid = getenv("HGRID"); ; Get horizontal grid to use from env variable - querynml = "bld/queryDefaultNamelist.pl -silent -justvalue "; - if ( .not. ismissing(csmdata) )then - querynml = querynml+" -csmdata "+csmdata; - end if - if ( ismissing(clmroot) )then - querynml = "../../"+querynml; - else - querynml = clmroot+"/"+querynml; - end if - if ( ismissing(hgrid) )then - hgrid = "lat-bands" - end if - ; - ; Get input Greenhouse gas file and open it - ; - filetype = "mkghg_bndtvghg"; - print( querynml+" -namelist clmexp -var "+filetype+" -options hgrid="+hgrid ); - ghgfile = systemfunc( querynml+" -namelist clmexp -var "+filetype+" -options hgrid="+hgrid ); - print( "Use "+filetype+" file: "+ghgfile ); - if ( systemfunc("test -f "+ghgfile+"; echo $?" ) .ne. 0 )then - print( "Input "+filetype+" file does not exist or not found: "+ghgfile ); - exit - end if - ncg = addfile( ghgfile, "r" ); - - ; - ; Get date time-stamp to put on output CO2 file - ; - sdate = systemfunc( "date +%y%m%d" ); - ldate = systemfunc( "date" ); - - sim_yr0 = ncg->date(0) / 10000; - ntime = dimsizes( ncg->date ); - sim_yr2 = ncg->date(ntime-1) / 10000; - - sim_yr_rng = "simyr_"+sim_yr0 + "-" + sim_yr2; - - cmip_vers = "_CMIP6_"; - outco2filename = "fco2_datm_"+hgrid+sim_yr_rng+cmip_vers+"c"+sdate+".nc"; - system( "/bin/rm -f "+outco2filename ); - print( "output file: "+outco2filename ); - nco = addfile( outco2filename, "c" ); - ; - ; Define dimensions - ; - if ( hgrid .eq. "lat-bands" )then - nlat = dimsizes(ncg->lat); - else - if ( hgrid .eq. "global" )then - nlat = 1 - else - print( "hgrid type can only be global or lat-bands: "+hgrid ) - exit - end if - end if - nlon = 1; - nv = 4; - dimnames = (/ "time", "lat", "lon", "nv", "bounds" /); - dsizes = (/ ntime, nlat, nlon, nv, 2 /); - is_unlim = (/ True, False, False, False, False /); - filedimdef( nco, dimnames, dsizes, is_unlim ); - ; - ; Define variables - ; - vars = (/ "lonc", "latc", "lonv", "latv", "mask", "frac", "area", "CO2" /); - units= (/ "degrees_east", "degrees_north", "degree_east", "degrees_north", "unitless", "unitless", "radians^2", "ppmv" /); - lname= (/ "Longitude of grid cell center", "Latitude of grid cell center", "Longitudes of grid cell vertices", "Latitudes of grid cell vertices", "Mask of active cells: 1=active", "Fraction of grid cell that is active", "Area of grid cell", "CO2 concentration" /); - print( "Define variables: "+vars ); - do i= 0, dimsizes(vars)-1 - if ( vars(i) .eq. "lonv" .or. vars(i) .eq. "latv" )then - filevardef ( nco, vars(i), "double", (/ "lat", "lon", "nv" /) ); - else - if ( vars(i) .eq. "CO2" )then - filevardef ( nco, vars(i), "float", (/ "time", "lat", "lon" /) ); - nco->$vars(i)$@coordinate = "latc lonc time"; - else - filevardef ( nco, vars(i), "double", (/ "lat", "lon" /) ); - end if - end if - nco->$vars(i)$@units = units(i); - nco->$vars(i)$@long_name = lname(i); - end do - filevardef ( nco, "time", "float", (/ "time" /) ); - filevardef ( nco, "time_bnds", "float", (/ "time", "bounds" /) ); - filevardef ( nco, "date", "integer", (/ "time" /) ); - varstatic = (/ "mask", "frac", "area" /); - do i = 0, dimsizes(varstatic)-1 - nco->$varstatic(i)$@coordinate = "latc lonc"; - end do - nco->lonc@bounds = "lonv"; - nco->latc@bounds = "latv"; - ; - ; Add attributes - ; - fileattdef ( nco, ncg ); - nco@history = ldate+": Convert by getco2_historical.ncl"; - nco@source = "Convert from:"+ghgfile; - nco@Version = systemfunc( "git describe" ); - filevarattdef( nco, "time", ncg->time ); - filevarattdef( nco, "date", ncg->date ); - nco->time_bnds@long_name = nco->time@long_name; - nco->time_bnds@units = nco->time@units; - nco->time_bnds@calendar = nco->time@calendar; - ; - ; Set static variables - ; - pi = 3.14159265358979323846d00; - nco->mask = 1; - nco->frac = 1.0; - if ( nlat .gt. 1 )then - nco->latc = (/ ncg->lat/); - else - nco->latc = (/ 0.0d00 /); - end if - nco->latv(nlat-1,0,0) = 90.0d00; - nco->latv(nlat-1,0,3) = 90.0d00; - if ( nlat .gt. 1 )then - nco->latv(0:nlat-2,0,0) = ( (/ ncg->lat(0:nlat-2) /) + (/ncg->lat(1:nlat-1) /) )*0.5d00 - nco->latv(0:nlat-2,0,3) = (/ nco->latv(0:nlat-2,0,0) /); - nco->latv(1:nlat-1,0,1) = (/ nco->latv(0:nlat-2,0,0) /); - nco->latv(1:nlat-1,0,2) = (/ nco->latv(1:nlat-1,0,1) /); - end if - nco->latv(0,0,1) = -90.0d00; - nco->latv(0,0,2) = -90.0d00; - nco->lonv(:,0,0) = 0.0d00; - nco->lonv(:,0,3) = 0.0d00; - nco->lonc = 180.0d00; - nco->lonv(:,0,1) = 360.0d00; - nco->lonv(:,0,2) = 360.0d00; - clkws = gc_clkwise( nco->latv, nco->lonv ); - if ( any(clkws .eq. False) )then - print( "Some varticies are NOT clockwise" ); - exit - end if - ; EBK -- NOTE The NCL function wasn't giving me the correct answer so I used the mathmatical expression - ;nco->area = dble2flt( gc_qarea( nco->latv, nco->lonv ) ); - conv2rad = pi/180.0d00 - nco->area(:,0) = 2.0d00*pi*abs( sin((/nco->latv(:,0,0)/)*conv2rad) - sin((/nco->latv(:,0,1)/)*conv2rad) ); - if ( abs(sum(nco->area) - 4.0d00*pi) .gt. 1.d-14 )then - print( "Area of globe does not sum to 4*pi as expected" ); - exit - end if - ; - ; Time and date - ; - nco->date = (/ ncg->date /); - nco->time = (/ ncg->time /); - nco->time_bnds = (/ ncg->time_bnds /); - nco->date@comment = "This variable is NOT used when read by datm, the time coordinate is used"; - ; - ; CO2 - ; - print( "Copy CO2 for "+ntime+" time samples of data" ); - if ( nlat .gt. 1 )then - do y = 0, nlat-1 - print( "latitude: "+ nco->latc(y,0) ); - nco->CO2(:,y,0) = (/ ncg->CO2_LBC(:,y) /) * 1.e6; - end do - else - ; make sure all latitudes on file are the same for each time - do itime = 0, ntime-1 - if ( max(ncg->CO2_LBC(itime,:)) .ne. min(ncg->CO2_LBC(itime,:)) )then - print( "Global average, but latitudes are NOT constant" ); - exit - end if - end do - nco->CO2(:,0,0) = (/ ncg->CO2_LBC(:,0) /) * 1.e6; - end if - print( "Average Global First CO2 ppmv value: Date="+nco->date(0)+" CO2="+avg(nco->CO2(0,:,0) ) ); - print( "Average Global Last CO2 ppmv value: Date="+nco->date(ntime-1)+" CO2="+avg(nco->CO2(ntime-1,:,0)) ); - - print( "================================================================================================" ); - print( "Successfully created output historical CO2 file: "+outco2filename); - -end From 5220301d6446187d3063c409a4ef068a45597de4 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 16 Nov 2023 00:07:43 -0700 Subject: [PATCH 424/614] Remove res and hgrid from namelist definition, this is no longer needed fixes #2179 and #9 --- bld/namelist_files/namelist_definition_ctsm.xml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index ddc0215582..daf07cea8a 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -1981,13 +1981,6 @@ Mapping file to go from one resolution/land-mask to another resolution/land-mask Land mask description for mksurfdata input files
      - -Horizontal grid resolutions for mksurfdata input files - - - @@ -2026,13 +2019,6 @@ CLM run type. 'branch' is a restart run in which properties of the output history files may be changed.
      - -Horizontal resolutions -Note: 0.25x0.25, 0.5x0.5, 5x5min, 10x10min, 3x3min, 1km-merge-10min and 0.33x0.33 are only used for CLM toolsI - - From d8ceaed16be8ad1362a27ef22cca7df7047fcbcb Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 10 Jan 2024 19:00:24 -0700 Subject: [PATCH 425/614] Fix unit test --- python/ctsm/test/test_unit_modify_fsurdat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ctsm/test/test_unit_modify_fsurdat.py b/python/ctsm/test/test_unit_modify_fsurdat.py index 59c433453c..8a283e7361 100755 --- a/python/ctsm/test/test_unit_modify_fsurdat.py +++ b/python/ctsm/test/test_unit_modify_fsurdat.py @@ -389,7 +389,7 @@ def test_check_varlist_lists_wrongsizes(self): lev1list = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] settings = {"var_lev1": lev1list} with self.assertRaisesRegex( - SystemExit, "Variable var_lev1 is " + str(len(lev1list)) + ". It should be" + SystemExit, " Variable var_lev1 is 8 is of the wrong size. It should be = 9 in input settings dictionary" ): self.modify_fsurdat.check_varlist(settings) From aa04d1f7d86cc2503b98b7e2b2d84dbfff6c316b Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 10 Jan 2024 19:03:03 -0700 Subject: [PATCH 426/614] black format --- python/ctsm/test/test_unit_modify_fsurdat.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/ctsm/test/test_unit_modify_fsurdat.py b/python/ctsm/test/test_unit_modify_fsurdat.py index 8a283e7361..3b43e29a04 100755 --- a/python/ctsm/test/test_unit_modify_fsurdat.py +++ b/python/ctsm/test/test_unit_modify_fsurdat.py @@ -389,7 +389,8 @@ def test_check_varlist_lists_wrongsizes(self): lev1list = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] settings = {"var_lev1": lev1list} with self.assertRaisesRegex( - SystemExit, " Variable var_lev1 is 8 is of the wrong size. It should be = 9 in input settings dictionary" + SystemExit, + " Variable var_lev1 is 8 is of the wrong size. It should be = 9 in input settings dictionary", ): self.modify_fsurdat.check_varlist(settings) From 14aebcaa5100c429457ee5c26dcc43048ce2fdca Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 10 Jan 2024 19:03:59 -0700 Subject: [PATCH 427/614] Add black reformat to ignore --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index b44e651781..db8e5c29f0 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -13,3 +13,4 @@ b565b55ce7a9f8d812a573d716a5fd3d78cfea81 fdf72cd011e2ba318987a1e100efc5a1847c9d04 de9a30bfbbec36f9dcacc4380005ab596da47af4 cda0cf1412212e6f4363e6e8eb39f74c944b454d` +aa04d1f7d86cc2503b98b7e2b2d84dbfff6c316b From 69c5866d3a61744960a7a951b8038fe8aabaa5df Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 10 Jan 2024 19:49:35 -0700 Subject: [PATCH 428/614] Fix testinput path --- python/ctsm/test/test_sys_mesh_modifier.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ctsm/test/test_sys_mesh_modifier.py b/python/ctsm/test/test_sys_mesh_modifier.py index a52394294a..ed0ef8d329 100755 --- a/python/ctsm/test/test_sys_mesh_modifier.py +++ b/python/ctsm/test/test_sys_mesh_modifier.py @@ -43,9 +43,9 @@ def setUp(self): self._cfg_template_path = os.path.join( path_to_ctsm_root(), "tools/modify_input_files/modify_mesh_template.cfg" ) - testinputs_path = os.path.join(path_to_ctsm_root(), "python/ctsm/test/testinputs") + self.testinputs_path = os.path.join(path_to_ctsm_root(), "python/ctsm/test/testinputs") fsurdat_in = os.path.join( - testinputs_path, + self.testinputs_path, "surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.nc", ) self._tempdir = tempfile.mkdtemp() From 59d45d0facc88e3a39d609a627b445ca7f031706 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 10 Jan 2024 21:49:12 -0700 Subject: [PATCH 429/614] Be sure to save the original directory and change it it before deleting the temp one, which allows all tests to work --- python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py | 2 ++ python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py | 2 ++ python/ctsm/test/test_sys_gen_mksurfdata_namelist.py | 2 ++ python/ctsm/test/test_sys_lilac_build_ctsm.py | 5 +++++ 4 files changed, 11 insertions(+) diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py index 6245e2de86..c7f2df5d0a 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py @@ -25,6 +25,7 @@ class TestSysGenMkSurfJSMulti(unittest.TestCase): def setUp(self): """Setp temporary directory to make the files in""" + self._original_wd = os.getcwd() self._tempdir = tempfile.mkdtemp() os.chdir(self._tempdir) self.outfile = "jobscript.sh" @@ -43,6 +44,7 @@ def tearDown(self): """ Remove temporary directory """ + os.chdir(self._original_wd) shutil.rmtree(self._tempdir, ignore_errors=True) def createJS(self, nodes, tasks_per_node, scenario, option_list=[]): diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py index 25cdf00131..5913142a68 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py @@ -25,6 +25,7 @@ class TestSysGenMkSurfJSSingle(unittest.TestCase): def setUp(self): """Setp temporary directory to make the files in""" + self._original_wd = os.getcwd() self._tempdir = tempfile.mkdtemp() os.chdir(self._tempdir) self.outfile = "jobscript.sh" @@ -46,6 +47,7 @@ def tearDown(self): """ Remove temporary directory """ + os.chdir(self._original_wd) shutil.rmtree(self._tempdir, ignore_errors=True) def createJS(self, nodes, tasks_per_node, option_list=[]): diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py b/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py index 575a2d4bbd..29745e9d80 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_namelist.py @@ -27,6 +27,7 @@ def setUp(self): """Setp temporary directory to make the files in""" testinputs_path = os.path.join(path_to_ctsm_root(), "python/ctsm/test/testinputs") self._testinputs_path = testinputs_path + self._original_wd = os.getcwd() self._tempdir = tempfile.mkdtemp() os.chdir(self._tempdir) self.outfile = "surfdata.namelist" @@ -40,6 +41,7 @@ def tearDown(self): """ Remove temporary directory """ + os.chdir(self._original_wd) shutil.rmtree(self._tempdir, ignore_errors=True) def test_simple_namelist(self): diff --git a/python/ctsm/test/test_sys_lilac_build_ctsm.py b/python/ctsm/test/test_sys_lilac_build_ctsm.py index d773749bf7..9fcafd0118 100755 --- a/python/ctsm/test/test_sys_lilac_build_ctsm.py +++ b/python/ctsm/test/test_sys_lilac_build_ctsm.py @@ -41,7 +41,12 @@ def setUp(self): else: self._ncarhost = None + self._original_wd = os.getcwd() + os.chdir(self._tempdir) + def tearDown(self): + """tear down""" + os.chdir(self._original_wd) shutil.rmtree(self._tempdir, ignore_errors=True) if self._ncarhost is not None: os.environ["NCAR_HOST"] = self._ncarhost From 4d77e89ab61fc167d4ad840338d451498cfdac47 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 10 Jan 2024 22:24:39 -0700 Subject: [PATCH 430/614] Add PCT_OCEAN to config files so that the all-subset creation will all work --- tools/mksurfdata_esmf/default_data_1850.cfg | 4 ++-- tools/mksurfdata_esmf/modify_1x1_mexicocityMEX.cfg | 1 + tools/mksurfdata_esmf/modify_1x1_urbanc_alpha.cfg | 1 + tools/mksurfdata_esmf/modify_1x1_vancouverCAN.cfg | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/default_data_1850.cfg b/tools/mksurfdata_esmf/default_data_1850.cfg index fe005fc1c2..e05c937b86 100644 --- a/tools/mksurfdata_esmf/default_data_1850.cfg +++ b/tools/mksurfdata_esmf/default_data_1850.cfg @@ -16,11 +16,11 @@ tpqwname = CLMGSWP3v1.TPQW [surfdat] dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -surfdat_78pft = surfdata_0.9x1.25_hist_78pfts_CMIP6_1850_c230517.nc +surfdat_78pft = surfdata_0.9x1.25_hist_78pfts_CMIP6_1850-2015_c231031.nc [landuse] dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -landuse_78pft = landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c230601.nc +landuse_78pft = landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c231031.nc [domain] file = share/domains/domain.lnd.fv0.9x1.25_gx1v7.151020.nc diff --git a/tools/mksurfdata_esmf/modify_1x1_mexicocityMEX.cfg b/tools/mksurfdata_esmf/modify_1x1_mexicocityMEX.cfg index d1e84961d4..38f1702959 100644 --- a/tools/mksurfdata_esmf/modify_1x1_mexicocityMEX.cfg +++ b/tools/mksurfdata_esmf/modify_1x1_mexicocityMEX.cfg @@ -82,6 +82,7 @@ PCT_NATVEG= 0.0 PCT_GLACIER= 0.0 PCT_WETLAND= 0.0 PCT_LAKE = 0.0 +PCT_OCEAN = 0.0 # Section with a list of variables to prcoess [modify_fsurdat_variable_list] diff --git a/tools/mksurfdata_esmf/modify_1x1_urbanc_alpha.cfg b/tools/mksurfdata_esmf/modify_1x1_urbanc_alpha.cfg index 09dffcbe66..bd87addd09 100644 --- a/tools/mksurfdata_esmf/modify_1x1_urbanc_alpha.cfg +++ b/tools/mksurfdata_esmf/modify_1x1_urbanc_alpha.cfg @@ -82,6 +82,7 @@ PCT_NATVEG= 0.0 PCT_GLACIER= 0.0 PCT_WETLAND= 0.0 PCT_LAKE = 0.0 +PCT_OCEAN = 0.0 # Section with a list of variables to prcoess [modify_fsurdat_variable_list] diff --git a/tools/mksurfdata_esmf/modify_1x1_vancouverCAN.cfg b/tools/mksurfdata_esmf/modify_1x1_vancouverCAN.cfg index 8cc4b22e1c..c587f0f183 100644 --- a/tools/mksurfdata_esmf/modify_1x1_vancouverCAN.cfg +++ b/tools/mksurfdata_esmf/modify_1x1_vancouverCAN.cfg @@ -82,6 +82,7 @@ PCT_NATVEG= 0.0 PCT_GLACIER= 0.0 PCT_WETLAND= 0.0 PCT_LAKE = 0.0 +PCT_OCEAN = 0.0 # Section with a list of variables to prcoess [modify_fsurdat_variable_list] From f9e0291326e603da940913ecce882591964b284e Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 12 Jan 2024 16:32:25 -0700 Subject: [PATCH 431/614] Add modify_smallville.sh for generating landuse.timeseries...smallville This generates files for dynLakes, dynUrban, and dynPft tests. --- tools/modify_input_files/modify_smallville.sh | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100755 tools/modify_input_files/modify_smallville.sh diff --git a/tools/modify_input_files/modify_smallville.sh b/tools/modify_input_files/modify_smallville.sh new file mode 100755 index 0000000000..1205cc23e3 --- /dev/null +++ b/tools/modify_input_files/modify_smallville.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Script that prepares landuse files for smallvilleIA. +# Load the nco module and run the script in the ctsm_pylib environment: +module load nco +module load conda +conda activate ctsm_pylib + +# Subset a global landuse file with 78 pfts, i.e. with crops +../site_and_regional/subset_data point --lat 40.6878 --lon 267.0228 --site 1x1_smallvilleIA --create-surface --create-landuse --crop + +# Trim the file to just the years 1850-1855 +ncks -d time,0,5 subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-2015_c240103.nc subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-1855_c240103.nc + +# Replace all values in the LAKE and CROP variables +ncap2 -s "PCT_LAKE=array(0.,0.,PCT_CROP); PCT_LAKE={0.,50.,25.,25.,25.,25.} ; PCT_LAKE_MAX=array(50.,50.,PCT_CROP_MAX); PCT_CROP=array(0.,0.,PCT_LAKE); PCT_CROP={0.,25.,12.,12.,12.,12.}; PCT_CROP_MAX=array(25.,25.,PCT_LAKE_MAX)" subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-1855_c240103.nc subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynLakes_c240103.nc + +# Replace all values in the URBAN and CROP variables +ncap2 -s "PCT_URBAN=array(0.,0.,PCT_URBAN); PCT_URBAN={0.,0.,0.,20.,15.,0.,10.,8.,0.,10.,8.,0.,10.,8.,0.,10.,8.,0.} ; PCT_URBAN_MAX=array(0.,0.,PCT_URBAN_MAX); PCT_URBAN_MAX={20.,15.,0.}; PCT_CROP=array(0.,0.,PCT_LAKE); PCT_CROP={0.,25.,12.,12.,12.,12.}; PCT_CROP_MAX=array(25.,25.,PCT_LAKE_MAX)" subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-1855_c240103.nc subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynUrban_c240103.nc + +# Update values in the pft, cft, harvest, and grazing variables as posted here: +# https://github.com/ESCOMP/CTSM/issues/1673#issuecomment-1879156989 +ncap2 -s "PCT_NAT_PFT=array(0.,0.,PCT_NAT_PFT); PCT_NAT_PFT={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,100.,0.,100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,50.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,50.,0.,25.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,75.,0.} ; PCT_NAT_PFT_MAX=array(0.,0.,PCT_NAT_PFT_MAX); PCT_NAT_PFT_MAX={100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,100.,0.}; PCT_CFT=array(0.,0.,PCT_CFT); PCT_CFT={100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,91.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,91.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,2.,4.,4.,6.,6.,8.,8.,10.,10.,42.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,4.,4.,4.,4.,4.,4.,4.,4.,4.,64.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.}; PCT_CFT_MAX=array(0.,0.,PCT_CFT_MAX); PCT_CFT_MAX={100.,2.,2.,3.,3.,4.,4.,5.,5.,91.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.}; PCT_CROP=array(0.,0.,PCT_CROP); PCT_CROP={0.,0.,100.,100.,50.,25.}; PCT_CROP_MAX=array(100.,100.,PCT_CROP_MAX); HARVEST_SH1=array(0.,0.,HARVEST_SH1); HARVEST_SH1={0.,0.,0.,0.,0.,0.}; HARVEST_SH2=array(0.,0.,HARVEST_SH2); HARVEST_SH2={0.,0.,0.,0.,0.,0.}; HARVEST_SH3=array(0.,0.,HARVEST_SH3); HARVEST_SH3={0.,0.,0.,0.,0.,0.}; HARVEST_VH1=array(0.,0.,HARVEST_VH1); HARVEST_VH1={0.,0.,0.,0.,0.,0.}; HARVEST_VH2=array(0.,0.,HARVEST_VH2); HARVEST_VH2={0.,0.,0.,0.,0.,0.}; GRAZING=array(0.,0.,GRAZING); GRAZING={0.,0.,0.,0.,0.,0.}" subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-1855_c240103.nc subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynPft_c240103.nc + +exit From 79e6ab8aa4056e62e156c49d55692b2162dfa10d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 12 Jan 2024 17:37:54 -0700 Subject: [PATCH 432/614] Update references to smallville fsurdat/landuse files; remove .ncl file --- bld/namelist_files/namelist_defaults_ctsm.xml | 4 +- .../smallville_dynlakes_monthly/user_nl_clm | 8 ++- .../modify_smallville_with_dynurban.ncl | 70 ------------------- .../smallville_dynurban_monthly/user_nl_clm | 12 ++-- 4 files changed, 12 insertions(+), 82 deletions(-) delete mode 100644 cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/modify_smallville_with_dynurban.ncl diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index d2f16d8ca7..d250289687 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1314,7 +1314,7 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_1850_c230517.n lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_1850_c230517.nc -/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_1850_c230726.nc +/glade/campaign/cesm/cesmdata/inputdata/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_1850-2015_c240103.nc /glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_numaIA_hist_78pfts_CMIP6_1850_c230726.nc @@ -1426,7 +1426,7 @@ use_crop=".true.">lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_mpasa1 lnd/clm2/surfdata_map/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_c160127.nc + use_crop=".true." >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-1855_dynPft_c240103.nc diff --git a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm index 2ae2da1919..d2a832c4e0 100644 --- a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm @@ -1,8 +1,10 @@ do_transient_lakes = .true. -! This file was created with the following command: -! ncap2 -s 'PCT_LAKE=array(0.0,0.0,PCT_CROP); PCT_LAKE={0.,50.,25.,25.,25.,25.}; PCT_LAKE_MAX=array(50.,0.,AREA); PCT_CROP=array(0.0,0.0,PCT_LAKE); PCT_CROP={0.,25.,12.,12.,12.,12.}' landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_c160127.nc landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_dynLakes_c200928.nc +! The fsurdat and flanduse_timeseries files were created with the following script: +! tools/modify_input_files/modify_smallville.sh + ! Key points are that lake area starts as 0, increases after the first year, then decreases after the second year. ! PCT_CROP is also changed so that PCT_LAKE + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_LAKE in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.) ! Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid. -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_dynLakes_c200928.nc' +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynLakes_c240103.nc' +fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_1850-2015_c240103.nc' diff --git a/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/modify_smallville_with_dynurban.ncl b/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/modify_smallville_with_dynurban.ncl deleted file mode 100644 index 15ec0469be..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/modify_smallville_with_dynurban.ncl +++ /dev/null @@ -1,70 +0,0 @@ -; NCL script -; modify_smallville_with_dynurban.ncl -; Keith Oleson, Dec 2021 -; Feb 23, 2022: Change HASURBAN to PCT_URBAN_MAX. The output file date has been updated from -; c211206 to c220223. -; Purpose is to create a transient landuse file for the smallville grid for dynamic urban testing -; ERS_Lm25.1x1_smallvilleIA.IHistClm50BgcCropQianRs.cheyenne_gnu.clm-smallville_dynurban_monthly -;************************************** - -load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" -load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" -load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" -load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" - -begin - - print ("=========================================") - print ("Start Time: "+systemfunc("date") ) - print ("=========================================") - - infile = "/glade/p/cgd/tss/people/oleson/modify_surfdata/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_c160127.nc" - outfile = "/glade/p/cgd/tss/people/oleson/modify_surfdata/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_dynUrban_c220223.nc" - - system("cp " + infile + " " + outfile) - - outf = addfile(outfile,"w") - - numurbl = 3 - - pct_crop = outf->PCT_CROP - printVarSummary(pct_crop) - pct_urban = new((/dimsizes(pct_crop(:,0,0)),numurbl,dimsizes(pct_crop(0,:,0)),dimsizes(pct_crop(0,0,:))/),double,"No_FillValue") - pct_urban!0 = "time" - pct_urban&time = pct_crop&time - pct_urban!1 = "numurbl" - pct_urban!2 = pct_crop!1 - pct_urban!3 = pct_crop!2 - pct_urban@long_name = "percent urban for each density type (tbd, hd, md)" - pct_urban@units = "unitless" - printVarSummary(pct_urban) - - pct_urban(:,0,0,0) = (/0.d,20.d,10.d,10.d,10.d,10.d/) - pct_urban(:,1,0,0) = (/0.d,15.d, 8.d, 8.d, 8.d, 8.d/) -;pct_urban(:,2,0,0) = (/0.d,10.d, 5.d, 5.d, 5.d, 5.d/) - pct_urban(:,2,0,0) = (/0.d, 0.d, 0.d, 0.d, 0.d, 0.d/) - - pct_urban_max = new((/numurbl,dimsizes(pct_crop(0,:,0)),dimsizes(pct_crop(0,0,:))/),double,"No_FillValue") - pct_urban_max!0 = pct_urban!1 - pct_urban_max!1 = pct_urban!2 - pct_urban_max!2 = pct_urban!3 - pct_urban_max(0,:,:) = max(pct_urban(:,0,0,0)) - pct_urban_max(1,:,:) = max(pct_urban(:,1,0,0)) - pct_urban_max(2,:,:) = max(pct_urban(:,2,0,0)) - printVarSummary(pct_urban_max) - pct_urban_max@units = "unitless" - pct_urban_max@long_name = "maximum percent urban for each density type (tbd, hd, md)" - - pct_crop(:,0,0) = (/0.,25.,12.,12.,12.,12./) - - outf->PCT_URBAN_MAX = pct_urban_max - outf->PCT_URBAN = pct_urban - outf->PCT_CROP = pct_crop - - outf@history = "This file was created with the following NCL script: /glade/p/cgd/tss/people/oleson/modify_surfdata/modify_smallville_with_dynurban.ncl. The file used as a template is: /glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_c160127.nc. Key points are that urban area starts as 0, increases after the first year, then decreases after the second year. Medium density urban is set to zero to test the memory-saving behavior of PCT_URBAN_MAX. PCT_CROP is also changed so that PCT_URBAN + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_URBAN in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.). Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid." - - print ("=========================================") - print ("Finish Time: "+systemfunc("date") ) - print ("=========================================") - -end diff --git a/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm index 69a78ee17d..96bc152078 100644 --- a/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm @@ -1,13 +1,11 @@ do_transient_urban = .true. -! The flanduse_timeseries file was created with the following NCL script (a copy of this script is in cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly): -! /glade/p/cgd/tss/people/oleson/modify_surfdata/modify_smallville_with_dynurban.ncl -! The file used as a template is: -! /glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_c160127.nc +! The fsurdat and flanduse_timeseries files were created with the following script: +! tools/modify_input_files/modify_smallville.sh + ! Key points are that urban area starts as 0, increases after the first year, then decreases after the second year. ! Medium density urban is set to zero to test the memory-saving behavior of PCT_URBAN_MAX. ! PCT_CROP is also changed so that PCT_URBAN + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_URBAN in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.) ! Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid. -! Feb 23, 2022: Use updated file with HASURBAN replaced by PCT_URBAN_MAX -!flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_dynUrban_c220223.nc' -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_dynUrban_c220223.nc' +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynUrban_c240103.nc' +fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_1850-2015_c240103.nc' From 1b6ac0e2cd06013de20d1fdcfc7b9b618f625240 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 12 Jan 2024 19:10:00 -0700 Subject: [PATCH 433/614] Update mksurfdata_esmf/Makefile to work with modify_smallville.sh Tested: modify_smallville.sh Not tested: Makefile --- tools/mksurfdata_esmf/Makefile | 21 ++++++++----------- tools/modify_input_files/modify_smallville.sh | 17 ++++++++------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index 60b3bb32b2..c6c55a7e47 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -46,6 +46,7 @@ SUBSETDATA_1X1_SMALL := --lat 40.6878 --lon 267.0228 --site 1x1_smallvilleIA \ --pctpft 6.5 1.5 1.6 1.7 1.8 1.9 1.5 1.6 1.7 1.8 1.9 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 # NOTE: The 1850 smallvilleIA site is constructed to start with 100% natural vegetation, so we can test transition to crops SUBSETDATA_1X1_SMALL1850 := --lat 40.6878 --lon 267.0228 --site 1x1_smallvilleIA --dompft 13 --pctpft 100 +SUBSETDATA_1X1_SMALLTRANSIENT := --lat 40.6878 --lon 267.0228 --site 1x1_smallvilleIA MEXICOCITY_TMP_FNAME := surfdata_1x1_mexicocityMEX_hist_2000_78pfts.nc MEXICOCITY_FNAME := surfdata_1x1_mexicocityMEX_hist_2000_78pfts_c$(CDATE).nc @@ -82,7 +83,7 @@ CROP = \ crop-global-1850-ne16np4 \ crop-global-1850-ne120np4 \ crop-global-future -all : standard tropics crop urban landuse-timeseries all-subset +all : standard tropics crop urban all-subset all-subset : \ 1x1_brazil-tropics-present \ @@ -92,6 +93,7 @@ all-subset : \ crop-numa-historical \ crop-smallville \ crop-smallville-historical \ + crop-smallville-transient \ urban-present urban-alpha DEBUG: @@ -205,6 +207,12 @@ crop-smallville : FORCE crop-smallville-historical : FORCE $(SUBSETDATA_POINT) --create-surface $(SUBSETDATA_1X1_SMALL1850) --cfg-file default_data_1850.cfg +# Note (slevis): The next line makes the landuse.timeseries from 1850 to 2015, so also run +# modify_smallville.sh to generate three modified landuse.timeseries files needed for testing. +crop-smallville-transient : FORCE + $(SUBSETDATA_POINT) --create-landuse $(SUBSETDATA_1X1_SMALLTRANSIENT) +../modify_input_files/modify_smallville.sh + # # Crop with future scenarios # @@ -311,17 +319,6 @@ urban-alpha : FORCE $(MODIFYSURF) modify_1x1_urbanc_alpha.cfg -i $(URBALPHA_TMP2_FNAME) -o $(URBALPHA_FNAME) $(RM) $(URBALPHA_TMP_FNAME) $(URBALPHA_TMP2_FNAME) -# -# landuse timeseries with subset data -# -landuse-timeseries : landuse-timeseries-smallville -# NOTE: TODO: This needs to be chagned to use subset_data when transient configurations are resolved (see Issue #1673 -landuse-timeseries-smallville : FORCE -# $(MKSURFDATA) -no_surfdata -glc_nec 10 -y 1850-1855 -r 1x1_smallvilleIA \ -# -pft_idx 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78 \ -# -pft_frc 6.5,1.5,1.6,1.7,1.8,1.9,1.5,1.6,1.7,1.8,1.9,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5 \ -# -dynpft single_point_dynpft_files/landuse_timeseries_smallvilleIA_hist_simyr1850-1855.txt \ -# $(BACKGROUND) # # clean up the working directory by removing generated files diff --git a/tools/modify_input_files/modify_smallville.sh b/tools/modify_input_files/modify_smallville.sh index 1205cc23e3..8f1ab8384b 100755 --- a/tools/modify_input_files/modify_smallville.sh +++ b/tools/modify_input_files/modify_smallville.sh @@ -3,23 +3,24 @@ # Script that prepares landuse files for smallvilleIA. # Load the nco module and run the script in the ctsm_pylib environment: module load nco -module load conda -conda activate ctsm_pylib -# Subset a global landuse file with 78 pfts, i.e. with crops -../site_and_regional/subset_data point --lat 40.6878 --lon 267.0228 --site 1x1_smallvilleIA --create-surface --create-landuse --crop +file_to_2015="subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-2015_c$(date +%y%m%d).nc" +file_to_1855="subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-1855_c$(date +%y%m%d).nc" +file_lake="subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynLakes_c$(date +%y%m%d).nc" +file_urban="subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynUrban_c$(date +%y%m%d).nc" +file_pft="subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynPft_c$(date +%y%m%d).nc" # Trim the file to just the years 1850-1855 -ncks -d time,0,5 subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-2015_c240103.nc subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-1855_c240103.nc +ncks -d time,0,5 $file_to_2015 $file_to_1855 # Replace all values in the LAKE and CROP variables -ncap2 -s "PCT_LAKE=array(0.,0.,PCT_CROP); PCT_LAKE={0.,50.,25.,25.,25.,25.} ; PCT_LAKE_MAX=array(50.,50.,PCT_CROP_MAX); PCT_CROP=array(0.,0.,PCT_LAKE); PCT_CROP={0.,25.,12.,12.,12.,12.}; PCT_CROP_MAX=array(25.,25.,PCT_LAKE_MAX)" subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-1855_c240103.nc subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynLakes_c240103.nc +ncap2 -s "PCT_LAKE=array(0.,0.,PCT_CROP); PCT_LAKE={0.,50.,25.,25.,25.,25.} ; PCT_LAKE_MAX=array(50.,50.,PCT_CROP_MAX); PCT_CROP=array(0.,0.,PCT_LAKE); PCT_CROP={0.,25.,12.,12.,12.,12.}; PCT_CROP_MAX=array(25.,25.,PCT_LAKE_MAX)" $file_to_1855 $file_lake # Replace all values in the URBAN and CROP variables -ncap2 -s "PCT_URBAN=array(0.,0.,PCT_URBAN); PCT_URBAN={0.,0.,0.,20.,15.,0.,10.,8.,0.,10.,8.,0.,10.,8.,0.,10.,8.,0.} ; PCT_URBAN_MAX=array(0.,0.,PCT_URBAN_MAX); PCT_URBAN_MAX={20.,15.,0.}; PCT_CROP=array(0.,0.,PCT_LAKE); PCT_CROP={0.,25.,12.,12.,12.,12.}; PCT_CROP_MAX=array(25.,25.,PCT_LAKE_MAX)" subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-1855_c240103.nc subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynUrban_c240103.nc +ncap2 -s "PCT_URBAN=array(0.,0.,PCT_URBAN); PCT_URBAN={0.,0.,0.,20.,15.,0.,10.,8.,0.,10.,8.,0.,10.,8.,0.,10.,8.,0.} ; PCT_URBAN_MAX=array(0.,0.,PCT_URBAN_MAX); PCT_URBAN_MAX={20.,15.,0.}; PCT_CROP=array(0.,0.,PCT_LAKE); PCT_CROP={0.,25.,12.,12.,12.,12.}; PCT_CROP_MAX=array(25.,25.,PCT_LAKE_MAX)" $file_to_1855 $file_urban # Update values in the pft, cft, harvest, and grazing variables as posted here: # https://github.com/ESCOMP/CTSM/issues/1673#issuecomment-1879156989 -ncap2 -s "PCT_NAT_PFT=array(0.,0.,PCT_NAT_PFT); PCT_NAT_PFT={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,100.,0.,100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,50.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,50.,0.,25.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,75.,0.} ; PCT_NAT_PFT_MAX=array(0.,0.,PCT_NAT_PFT_MAX); PCT_NAT_PFT_MAX={100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,100.,0.}; PCT_CFT=array(0.,0.,PCT_CFT); PCT_CFT={100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,91.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,91.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,2.,4.,4.,6.,6.,8.,8.,10.,10.,42.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,4.,4.,4.,4.,4.,4.,4.,4.,4.,64.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.}; PCT_CFT_MAX=array(0.,0.,PCT_CFT_MAX); PCT_CFT_MAX={100.,2.,2.,3.,3.,4.,4.,5.,5.,91.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.}; PCT_CROP=array(0.,0.,PCT_CROP); PCT_CROP={0.,0.,100.,100.,50.,25.}; PCT_CROP_MAX=array(100.,100.,PCT_CROP_MAX); HARVEST_SH1=array(0.,0.,HARVEST_SH1); HARVEST_SH1={0.,0.,0.,0.,0.,0.}; HARVEST_SH2=array(0.,0.,HARVEST_SH2); HARVEST_SH2={0.,0.,0.,0.,0.,0.}; HARVEST_SH3=array(0.,0.,HARVEST_SH3); HARVEST_SH3={0.,0.,0.,0.,0.,0.}; HARVEST_VH1=array(0.,0.,HARVEST_VH1); HARVEST_VH1={0.,0.,0.,0.,0.,0.}; HARVEST_VH2=array(0.,0.,HARVEST_VH2); HARVEST_VH2={0.,0.,0.,0.,0.,0.}; GRAZING=array(0.,0.,GRAZING); GRAZING={0.,0.,0.,0.,0.,0.}" subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-1855_c240103.nc subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynPft_c240103.nc +ncap2 -s "PCT_NAT_PFT=array(0.,0.,PCT_NAT_PFT); PCT_NAT_PFT={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,100.,0.,100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,50.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,50.,0.,25.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,75.,0.} ; PCT_NAT_PFT_MAX=array(0.,0.,PCT_NAT_PFT_MAX); PCT_NAT_PFT_MAX={100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,100.,0.}; PCT_CFT=array(0.,0.,PCT_CFT); PCT_CFT={100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,100.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,91.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,91.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,2.,4.,4.,6.,6.,8.,8.,10.,10.,42.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,4.,4.,4.,4.,4.,4.,4.,4.,4.,64.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.}; PCT_CFT_MAX=array(0.,0.,PCT_CFT_MAX); PCT_CFT_MAX={100.,2.,2.,3.,3.,4.,4.,5.,5.,91.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.}; PCT_CROP=array(0.,0.,PCT_CROP); PCT_CROP={0.,0.,100.,100.,50.,25.}; PCT_CROP_MAX=array(100.,100.,PCT_CROP_MAX); HARVEST_SH1=array(0.,0.,HARVEST_SH1); HARVEST_SH1={0.,0.,0.,0.,0.,0.}; HARVEST_SH2=array(0.,0.,HARVEST_SH2); HARVEST_SH2={0.,0.,0.,0.,0.,0.}; HARVEST_SH3=array(0.,0.,HARVEST_SH3); HARVEST_SH3={0.,0.,0.,0.,0.,0.}; HARVEST_VH1=array(0.,0.,HARVEST_VH1); HARVEST_VH1={0.,0.,0.,0.,0.,0.}; HARVEST_VH2=array(0.,0.,HARVEST_VH2); HARVEST_VH2={0.,0.,0.,0.,0.,0.}; GRAZING=array(0.,0.,GRAZING); GRAZING={0.,0.,0.,0.,0.,0.}" $file_to_1855 $file_pft exit From 0739abcfa61ba161d87900c8f58f37117a3a4268 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 16 Jan 2024 15:02:52 -0700 Subject: [PATCH 434/614] Rm fsurdat from two user_nl_clm files because default should suffice --- .../testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm | 1 - .../testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm | 1 - 2 files changed, 2 deletions(-) diff --git a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm index d2a832c4e0..21cdd7d89d 100644 --- a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm @@ -7,4 +7,3 @@ do_transient_lakes = .true. ! PCT_CROP is also changed so that PCT_LAKE + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_LAKE in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.) ! Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid. flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynLakes_c240103.nc' -fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_1850-2015_c240103.nc' diff --git a/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm index 96bc152078..adc8364e67 100644 --- a/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm @@ -8,4 +8,3 @@ do_transient_urban = .true. ! PCT_CROP is also changed so that PCT_URBAN + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_URBAN in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.) ! Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid. flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynUrban_c240103.nc' -fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_1850-2015_c240103.nc' From ba757433ec7bf75238b4b54ef67da2b506faefd9 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 16 Jan 2024 15:05:32 -0700 Subject: [PATCH 435/614] Bug-fix of a typo unrelated to this PR that just needs to get in --- tools/mksurfdata_esmf/src/mksurfdata.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index abad3c39d4..35ff1807cd 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -1374,7 +1374,7 @@ subroutine normalize_and_check_landuse(ns_o) if (abs(suma - 100._r8) > tol_loose) then write(ndiag,*) subname, ' ERROR: landunits do not sum to 100%' write(ndiag,*) 'n, suma, pctlak, pctwet, pctgla, pcturb, pctnatveg, pctcrop, pctocn = ' - write(ndiag6,*) n, suma, pctlak(n), pctwet(n), pctgla(n), pcturb(n), & + write(ndiag,*) n, suma, pctlak(n), pctwet(n), pctgla(n), pcturb(n), & pctnatpft(n)%get_pct_l2g(), pctcft(n)%get_pct_l2g(), pctocn(n) flush(ndiag) call shr_sys_abort() From 38e6645f9554d3a2c874ec5775b7ac8a636ccf35 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 16 Jan 2024 16:14:12 -0700 Subject: [PATCH 436/614] Make error msg more helpful when PCT_OCEAN not present --- src/main/surfrdMod.F90 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/surfrdMod.F90 b/src/main/surfrdMod.F90 index bbd4639828..fea4e63682 100644 --- a/src/main/surfrdMod.F90 +++ b/src/main/surfrdMod.F90 @@ -416,7 +416,9 @@ subroutine surfrd_special(begg, endg, ncid, ns) call ncd_io(ncid=ncid, varname='PCT_OCEAN', flag='read', data=pctocn, & dim1name=grlnd, readvar=readvar) - if (.not. readvar) call endrun( msg=' ERROR: PCT_OCEAN NOT on surfdata file'//errMsg(sourcefile, __LINE__)) + if (.not. readvar) call endrun( msg= & + ' ERROR: PCT_OCEAN NOT on surfdata file but required when running ctsm5.2 or newer; ' // & + ' you are advised to generate a new surfdata file using the mksurfdata_esmf tool ' // errMsg(sourcefile, __LINE__)) call ncd_io(ncid=ncid, varname='PCT_WETLAND', flag='read', data=pctwet, & dim1name=grlnd, readvar=readvar) From cb7818015fedefa429ee6f98e7f3e2b6bc03ceb4 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 18 Jan 2024 02:04:57 -0700 Subject: [PATCH 437/614] Modify ctsm_sci testlist so that it's handling the datasets according to the Grids in CESM3 document, also remove the cheyenne ctsm_sci tests --- cime_config/testdefs/testlist_clm.xml | 340 ++++++++------------------ 1 file changed, 101 insertions(+), 239 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 1ea68e495a..ef5cac6f07 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -32,19 +32,8 @@ - - - - - - - - - - - @@ -54,7 +43,6 @@ - @@ -138,65 +126,54 @@ - + - - - + + - + - - - - - - - - - - - - + + - + - + - + - + - + - + - + - + - + @@ -205,7 +182,7 @@ - + @@ -214,29 +191,38 @@ - + - + - + - + - + - + + + + + + + + + + @@ -269,7 +255,6 @@ - @@ -279,7 +264,6 @@ - @@ -289,7 +273,6 @@ - @@ -299,7 +282,6 @@ - @@ -310,7 +292,7 @@ - + @@ -319,7 +301,7 @@ - + @@ -374,7 +356,6 @@ - @@ -382,15 +363,6 @@ - - - - - - - - - @@ -481,7 +453,6 @@ - @@ -558,7 +529,6 @@ - @@ -568,7 +538,6 @@ - @@ -579,7 +548,7 @@ - + @@ -588,7 +557,7 @@ - + @@ -605,16 +574,7 @@ - - - - - - - - - - + @@ -623,35 +583,17 @@ - + - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + + --> - - - - - - - - - - + @@ -706,25 +639,16 @@ - - - - - - - - - - + - + - + @@ -733,7 +657,7 @@ - + @@ -742,61 +666,25 @@ - + - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -805,22 +693,13 @@ - + - - - - - - - - - @@ -833,7 +712,6 @@ - @@ -843,7 +721,6 @@ - @@ -854,7 +731,7 @@ - + @@ -863,7 +740,7 @@ - + @@ -933,7 +810,6 @@ - @@ -972,7 +848,6 @@ - @@ -982,7 +857,6 @@ - @@ -1297,7 +1171,6 @@ - @@ -1323,7 +1196,6 @@ - @@ -1333,7 +1205,6 @@ - @@ -1385,7 +1256,6 @@ - @@ -1395,7 +1265,6 @@ - @@ -1485,7 +1354,6 @@ - @@ -1495,7 +1363,6 @@ - @@ -1505,7 +1372,6 @@ - @@ -1515,7 +1381,6 @@ - @@ -1534,7 +1399,6 @@ - @@ -1544,7 +1408,6 @@ - @@ -1595,7 +1458,6 @@ - @@ -1786,9 +1648,8 @@ - + - @@ -2079,7 +1940,7 @@ - + @@ -2224,16 +2085,14 @@ - - + - @@ -2242,9 +2101,8 @@ (no need to run this high core count test with every tag, but include it in the less frequent ctsm_sci testing)" - + - @@ -2252,9 +2110,8 @@ - + - @@ -2262,9 +2119,8 @@ - + - @@ -2275,7 +2131,6 @@ - @@ -2285,7 +2140,6 @@ - @@ -2296,7 +2150,7 @@ - + @@ -2305,7 +2159,7 @@ - + @@ -2489,9 +2343,9 @@ - + @@ -2675,7 +2529,6 @@ - @@ -2737,46 +2590,59 @@ - + - - - - + - + - + - + - - + - + - + + + + + + + + + + + + + + + + + + + - - + @@ -2821,7 +2687,7 @@ - + @@ -2878,7 +2744,6 @@ - @@ -3489,8 +3354,8 @@ - + @@ -3640,7 +3505,6 @@ - @@ -3685,13 +3549,12 @@ - - - - - - + + + + + @@ -3859,7 +3722,6 @@ - From 3bcc337568aa493442c31915eb66abde7a663eb2 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 19 Jan 2024 10:59:52 -0700 Subject: [PATCH 438/614] Update tests, namelist defaults and tests for supported grids Update the ctsm_sci test list to test the grids in the supported grids for CESM3 document. https://docs.google.com/spreadsheets/d/1Osq56e423CF107zhoNQ0VS7-iH_JXLF9AtCvBdXyfJ4 Update the namalist defaults to the supported grids. Some files that don't exist have a _cXXXXXX.nc ending on them. Get the namelist unit tester to test all the supported grids. --- bld/CLMBuildNamelist.pm | 27 +- bld/namelist_files/namelist_defaults_ctsm.xml | 419 ++++++------------ bld/unit_testers/build-namelist_test.pl | 115 +++-- 3 files changed, 227 insertions(+), 334 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index e752a9df25..128b794c83 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -1959,9 +1959,12 @@ sub setup_logic_irrigate { 'use_crop'=>$nl_flags->{'use_crop'}, 'use_cndv'=>$nl_flags->{'use_cndv'}, 'sim_year'=>$nl_flags->{'sim_year'}, 'sim_year_range'=>$nl_flags->{'sim_year_range'}, ); if ( &value_is_true($nl->get_value('irrigate') ) ) { - $nl_flags->{'irrigate'} = ".true." + $nl_flags->{'irrigate'} = ".true."; + if ( $nl_flags->{'sim_year'} eq "PtVg" ) { + $log->fatal_error("irrigate=TRUE does NOT make sense with the Potential Vegetation dataset, leave irrigate=FALSE"); + } } else { - $nl_flags->{'irrigate'} = ".false." + $nl_flags->{'irrigate'} = ".false."; } } @@ -2359,17 +2362,15 @@ sub setup_logic_demand { if ( $item eq "finidat" ) { $log->fatal_error( "Do NOT put findat in the clm_demand list, set the clm_start_type=startup so initial conditions are required"); } - # For landuse.timeseries try with crop and irrigate on first, if found use it, otherwise try with exact settings + # For landuse.timeseries try with crop on first eise try with exact settings # Logic for this is identical for fsurdat if ( $item eq "flanduse_timeseries" ) { - $settings{'irrigate'} = ".true."; $settings{'use_crop'} = ".true."; $settings{'nofail'} = 1; } add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $item, %settings ); if ( $item eq "flanduse_timeseries" ) { $settings{'nofail'} = 0; - $settings{'irrigate'} = $nl_flags->{'irrigate'}; $settings{'use_crop'} = $nl_flags->{'use_crop'}; if ( ! defined($nl->get_value( $item )) ) { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $item, %settings ); @@ -2412,8 +2413,8 @@ sub setup_logic_surface_dataset { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, 'hgrid'=>$nl_flags->{'res'}, 'ssp_rcp'=>$nl_flags->{'ssp_rcp'}, 'neon'=>$nl_flags->{'neon'}, 'neonsite'=>$nl_flags->{'neonsite'}, - 'sim_year'=>$nl_flags->{'sim_year'}, 'irrigate'=>".true.", 'use_vichydro'=>$nl_flags->{'use_vichydro'}, - 'use_crop'=>".true.", 'glc_nec'=>$nl_flags->{'glc_nec'}, 'use_fates'=>$nl_flags->{'use_fates'}, 'nofail'=>1); + 'sim_year'=>$nl_flags->{'sim_year'}, 'use_vichydro'=>$nl_flags->{'use_vichydro'}, + 'use_crop'=>".true.", 'use_fates'=>$nl_flags->{'use_fates'}, 'nofail'=>1); } # If didn't find the crop version check for the exact match my $fsurdat = $nl->get_value($var); @@ -2423,17 +2424,9 @@ sub setup_logic_surface_dataset { } add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, 'hgrid'=>$nl_flags->{'res'}, 'ssp_rcp'=>$nl_flags->{'ssp_rcp'}, 'use_vichydro'=>$nl_flags->{'use_vichydro'}, - 'sim_year'=>$nl_flags->{'sim_year'}, 'irrigate'=>$nl_flags->{'irrigate'}, 'use_fates'=>$nl_flags->{'use_fates'}, - 'neon'=>$nl_flags->{'neon'}, 'neonsite'=>$nl_flags->{'neonsite'}, - 'use_crop'=>$nl_flags->{'use_crop'}, 'glc_nec'=>$nl_flags->{'glc_nec'}, 'nofail'=>1 ); - if ( ! defined($fsurdat) ) { - $log->verbose_message( "Exact match of $var NOT found, searching for version with irrigate true" ); - } - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, - 'hgrid'=>$nl_flags->{'res'}, 'ssp_rcp'=>$nl_flags->{'ssp_rcp'}, 'use_vichydro'=>$nl_flags->{'use_vichydro'}, - 'sim_year'=>$nl_flags->{'sim_year'}, 'irrigate'=>".true.", 'use_fates'=>$nl_flags->{'use_fates'}, + 'sim_year'=>$nl_flags->{'sim_year'}, 'use_fates'=>$nl_flags->{'use_fates'}, 'neon'=>$nl_flags->{'neon'}, 'neonsite'=>$nl_flags->{'neonsite'}, - 'use_crop'=>$nl_flags->{'use_crop'}, 'glc_nec'=>$nl_flags->{'glc_nec'} ); + 'use_crop'=>$nl_flags->{'use_crop'} ); } # # Expand the XML variables for NEON cases so that NEONSITE will be used diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 53814769ce..f3be69eafe 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1215,124 +1215,129 @@ attributes from the config_cache.xml file (with keys converted to upper-case). - + + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_16pfts_CMIP6_2000_c230517.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_16pfts_CMIP6_2000_c230517.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_16pfts_CMIP6_2000_c230517.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_16pfts_CMIP6_2000_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_16pfts_CMIP6_2000_c230530.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_16pfts_CMIP6_2000_c230517.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_16pfts_CMIP6_2000_c230517.nc + + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_16pfts_CMIP6_2000_c230530.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_2000_16pfts_cXXXXXX.nc + + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_5x5_amazon_hist_2000_16pfts_2000_cXXXXXX.nc - + + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_78pfts_CMIP6_2000_c230517.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_78pfts_CMIP6_2000_c230517.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_2000_c230517.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_78pfts_CMIP6_2000_c231026.nc + + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc + + + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_78pfts_CMIP6_2000_c230517.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_78pfts_CMIP6_2000_c230517.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_78pfts_CMIP6_2000_c230517.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4_hist_78pfts_CMIP6_2000_c230517.nc - + + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.125nldas2_hist_16pfts_CMIP6_2000_c230517.nc - -/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_brazil_hist_78pfts_CMIP6_2000_c230726.nc - - - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc - - lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_360x720_78pfts_CMIP6_2000_cXXXXX.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_78pfts_CMIP6_2000_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_78pfts_CMIP6_2000_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_78pfts_CMIP6_2000_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_2000_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_2000_c230517.nc + -/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_numaIA_hist_78pfts_CMIP6_2000_c230726.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_numaIA_hist_78pfts_CMIP6_2000_c231026.nc -/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_2000_c230726.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_2000_c231026.nc -lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa480_hist_78pfts_CMIP6_simyr2000_c211110.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa480_hist_2000_78pfts_c231103.nc -lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa120_hist_78pfts_CMIP6_simyr2000_c211108.nc -> -lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa60_hist_2000_16pfts_simyr2000_c211110.nc - -lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa30_hist_78pfts_CMIP6_simyr2000_c211111.nc - -lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa15_hist_78pfts_CMIP6_simyr2000_c211111.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa120_hist_2000_78pfts_c231026.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa60_hist_2000_16pfts_c231103.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15_hist_2000_16pfts_c231026.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15-conus_hist_2000_16pfts_c231026.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa3p75_hist_2000_16pfts_c231026.nc -lnd/clm2/surfdata_map/ctsm5.1.dev120//surfdata_ne3np4.pg3_hist_78pfts_CMIP6_simyr2000_c230405.nc - -lnd/clm2/surfdata_map/ctsm5.1.dev120/surfdata_ne5np4.pg3_hist_78pfts_CMIP6_simyr2000_c230405.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_2000_78pfts_c231103.nc -lnd/clm2/surfdata_map/ctsm5.1.dev120/surfdata_ne16np4.pg3_hist_78pfts_CMIP6_simyr2000_c230405.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4.pg3_hist_2000_78pfts_c231103.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_78pfts_CMIP6_2000_c230517.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_78pfts_CMIP6_2000_c230517.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_78pfts_CMIP6_2000_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4_hist_78pfts_CMIP6_2000_c230517.nc - -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne120np4.pg2_hist_78pfts_CMIP6_simyr2000_c200426.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4.pg3_hist_78pfts_CMIP6_2000_c230517.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x8_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x4_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTIC.ne30x4_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4CONUS.ne30x8_hist_78pfts_CMIP6_2000_c230517.nc -/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_vancouverCAN_hist_78pfts_CMIP6_simyr2000_c230726.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_vancouverCAN_hist_2000_78pfts_c240110.nc -/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_mexicocityMEX_hist_78pfts_CMIP6_simyr2000_c230726.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_mexicocityMEX_hist_2000_78pfts_c240110.nc -/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_urbanc_alpha_hist_78pfts_CMIP6_simyr2000_c230825.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_urbanc_alpha_hist_2000_78pfts_c240110.nc - + - + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_360x720_78pfts_CMIP6_1850_cXXXXX.nc + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_78pfts_CMIP6_1850_c230517.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_78pfts_CMIP6_1850_c230517.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_1850_c230517.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa480_hist_78pfts_CMIP6_simyr1850_c211110.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa480_hist_1850_78pfts_c231103.nc -lnd/clm2/surfdata_map/ctsm5.1.dev052/surfdata_mpasa120_hist_78pfts_CMIP6_simyr1850_c211108.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa120_hist_1850_78pfts_c231026.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_78pfts_CMIP6_1850_c230517.nc @@ -1356,289 +1361,157 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_1850_c230517.n lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_1850_c230517.nc -/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_1850_c230726.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_1850_c231026.nc -/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_numaIA_hist_78pfts_CMIP6_1850_c230726.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/ssurfdata_1x1_numaIA_hist_78pfts_CMIP6_1850_c240110.nc -/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_brazil_hist_78pfts_CMIP6_1850_c230726.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_78pfts_CMIP6_1850_c231026.nc -lnd/clm2/surfdata_map/ctsm5.1.dev120/surfdata_ne3np4.pg3_hist_78pfts_CMIP6_simyr1850_c230405.nc - -lnd/clm2/surfdata_map/ctsm5.1.dev120/surfdata_ne5np4.pg3_hist_78pfts_CMIP6_simyr1850_c230405.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c231103.nc -lnd/clm2/surfdata_map/ctsm5.1.dev120/surfdata_ne16np4.pg3_hist_78pfts_CMIP6_simyr1850_c230405.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4.pg3_hist_1850_78pfts_c231103.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_78pfts_CMIP6_1850_c230517.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_78pfts_CMIP6_1850_c230517.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_78pfts_CMIP6_1850_c230517.nc - -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne120np4_hist_78pfts_CMIP6_simyr1850_c200427.nc - -lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne120np4.pg2_hist_78pfts_CMIP6_simyr1850_c200426.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4.pg3_hist_78pfts_CMIP6_1850_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x8_hist_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x8_hist_1850_78pfts_c231103.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTIC.ne30x4_hist_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTIC.ne30x4_hist_78pfts_CMIP6_2000_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4CONUS.ne30x8_hist_1850_78pfts_c231103.nc -lnd/clm2/surfdata_map/surfdata_0.9x1.25_hist_16pfts_nourb_CMIP6_simyrPtVg_c181114.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_PtVeg_nourb_16pfts_cXXXXXX.nc -lnd/clm2/surfdata_map/NEON/16PFT_mixed/surfdata_1x1_NEON_${NEONSITE}_hist_16pfts_Irrig_CMIP6_simyr2000_c230120.nc +lnd/clm2/surfdata_esmf/NEON/16PFT_mixed/surfdata_1x1_NEON_${NEONSITE}_hist_2000_16pfts_cXXXXXX.nc -lnd/clm2/surfdata_map/NEON/surfdata_1x1_NEON_${NEONSITE}_hist_78pfts_CMIP6_simyr2000_c230601.nc +lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_${NEONSITE}_hist_2000_78pfts_cXXXXXX.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c230601.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c230601.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_hist_78_CMIP6_1850-2015_c230601.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_hist_78_CMIP6_1850-2015_c230601.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2015_c230601.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2015_c230601.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c231103.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP2-4.5_1850-2100_78_c231103.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_4x5_SSP2-4.5_1850-2100_16pfts_cXXXXXX.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_4x5_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_360x720cru_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np.pg3_SSP2-4.5_78pfts_CMIP6_1850-2100_cXXXXXX.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_brazil_hist_78_CMIP6_1850-2015_c240110.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_numaIA_hist_1850-2015_78pfts_cXXXXXX.nc - +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_mpasa120_SSP2-4.5_1850-2100_78pfts_c231026.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c230601.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_hist_78_CMIP6_1850-2015_c230601.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2015_c230601.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne3np4.pg3_SSP2-4.5_1850-2100_78pfts_c231027.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne16np4.pg3_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np.pg3_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc -/glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/landuse.timeseries_1x1_brazil_hist_78_CMIP6_1850-2015_c230726.nc - -lnd/clm2/surfdata_map/landuse.timeseries_1x1_numaIA_hist_78pfts_CMIP6_simyr1850-2015_c170917.nc - -lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_mpasa480_hist_78pfts_CMIP6_simyr1850-2015_c211110.nc -lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_mpasa240_hist_78pfts_CMIP6_simyr1850-2015_c211115.nc -lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_mpasa120_hist_78pfts_CMIP6_simyr1850-2015_c211108.nc -lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_mpasa60_hist_78pfts_CMIP6_simyr1850-2015_c211110.nc -lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_mpasa30_hist_78pfts_CMIP6_simyr1850-2015_c211111.nc -lnd/clm2/surfdata_map/ctsm5.1.dev052/landuse.timeseries_mpasa15_hist_78pfts_CMIP6_simyr1850-2015_c211111.nc - -lnd/clm2/surfdata_map/ctsm5.1.dev120/landuse.timeseries_ne3np4.pg3_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c230405.nc -lnd/clm2/surfdata_map/ctsm5.1.dev120/landuse.timeseries_ne5np4.pg3_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c230405.nc -lnd/clm2/surfdata_map/ctsm5.1.dev120/landuse.timeseries_ne16np4.pg3_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c230405.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np4_SSP5-8.5_78_CMIP6_1850-2100_c230530.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne0np4.ARCTICGRIS.ne30x8_SSP5-8.5_78_CMIP6_1850-2100_c230530. -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne0np4.ARCTIC.ne30x4_SSP5-8.5_78_CMIP6_1850-2100_c230530.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne0np4CONUS.ne30x8_SSP5-8.5_78_CMIP6_1850-2100_c230530.nc - -lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_C24_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200317.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_C96_SSP5-8.5_78_CMIP6_1850-2100_c230621.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_C96_SSP2-4.5_1850-2100_78pfts_c231026.nc lnd/clm2/surfdata_map/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_c160127.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-1855_c240103.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP5-8.5_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP5-8.5_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP5-8.5_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_C24_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200317.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_C96_SSP5-8.5_78_CMIP6_1850-2100_c230621.nc - -lnd/clm2/surfdata_map/ctsm5.1.dev120/landuse.timeseries_ne3np4.pg3_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c230405.nc -lnd/clm2/surfdata_map/ctsm5.1.dev120/landuse.timeseries_ne5np4.pg3_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c230405.nc -lnd/clm2/surfdata_map/ctsm5.1.dev120/landuse.timeseries_ne16np4.pg3_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c230405.nc -lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_ne30np4_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200426.nc -lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_ne30np4.pg2_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200426.nc -lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_ne30np4.pg3_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200426.nc -lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_ne0np4.ARCTICGRIS.ne30x8_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200426.nc -lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_ne0np4.ARCTIC.ne30x4_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200426.nc -lnd/clm2/surfdata_map/release-clm5.0.30/landuse.timeseries_ne0np4.CONUS.ne30x8_SSP5-8.5_78pfts_CMIP6_simyr1850-2100_c200426.nc - lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP1-2.6_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP1-2.6_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP1-2.6_78_CMIP6_1850-2100_c230517.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP1-2.6_1850-2100_78pfts_c231103.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c231103.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP2-4.5_1850-2100_78_c231103.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_4x5_SSP2-4.5_1850-2100_16pfts_cXXXXXX.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_4x5_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_360x720cru_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_brazil_hist_78_CMIP6_1850-2015_c240110.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_numaIA_hist_1850-2015_78pfts_cXXXXXX.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_mpasa120_SSP2-4.5_1850-2100_78pfts_c231026.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne3np4.pg3_SSP2-4.5_1850-2100_78pfts_c231027.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne16np4.pg3_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np.pg3_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_C96_SSP2-4.5_1850-2100_78pfts_c231026.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP3-7.0_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP3-7.0_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP3-7.0_78_CMIP6_1850-2100_c230517.nc - - -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP4-3.4_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP4-3.4_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP4-3.4_78_CMIP6_1850-2100_c230517.nc - - -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP1-1.9_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP1-1.9_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP1-1.9_78_CMIP6_1850-2100_c230517.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP3-7.0_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP4-6.0_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP4-6.0_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP4-6.0_78_CMIP6_1850-2100_c230517.nc - - -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP5-3.4_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP5-3.4_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP5-3.4_78_CMIP6_1850-2100_c230517.nc - - +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP4-6.0_78_CMIP6_1850-2100_c230517.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP5-8.5_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP5-8.5_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP5-8.5_78_CMIP6_1850-2100_c230517.nc - - -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP1-2.6_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP1-2.6_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP1-2.6_78_CMIP6_1850-2100_c230517.nc - - -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc - - -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP3-7.0_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP3-7.0_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP3-7.0_78_CMIP6_1850-2100_c230517.nc - - -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP4-3.4_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP4-3.4_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP4-3.4_78_CMIP6_1850-2100_c230517.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP5-8.5_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP1-1.9_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP1-1.9_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP1-1.9_78_CMIP6_1850-2100_c230517.nc + - -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP4-6.0_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP4-6.0_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP4-6.0_78_CMIP6_1850-2100_c230517.nc + + -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP5-3.4_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP5-3.4_78_CMIP6_1850-2100_c230517.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP5-3.4_78_CMIP6_1850-2100_c230517.nc + diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index f04ec56fbe..644e28a002 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,10 +163,10 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 2466; +my $ntests = 2815; if ( defined($opts{'compare'}) ) { - $ntests += 1701; + $ntests += 1965; } plan( tests=>$ntests ); @@ -322,7 +322,7 @@ sub cat_and_create_namelistinfile { # configuration, structure, irrigate, verbose, clm_demand, ssp_rcp, test, sim_year, use_case foreach my $options ( "-res 0.9x1.25 -configuration nwp", "-res 0.9x1.25 -structure fast", - "-res 0.9x1.25 -namelist '&a irrigate=.true./'", "-res 0.9x1.25 -verbose", "-res 0.9x1.25 -ssp_rcp SSP4-2.5", "-res 0.9x1.25 -test", "-res 0.9x1.25 -sim_year 1850", + "-res 0.9x1.25 -namelist '&a irrigate=.true./'", "-res 0.9x1.25 -verbose", "-res 0.9x1.25 -ssp_rcp SSP2-4.5", "-res 0.9x1.25 -test", "-res 0.9x1.25 -sim_year 1850", "-res 0.9x1.25 -namelist '&a use_lai_streams=.true.,use_soil_moisture_streams=.true./'", "-res 0.9x1.25 -namelist '&a use_excess_ice=.true. use_excess_ice_streams=.true./'", "-res 0.9x1.25 -namelist '&a use_excess_ice=.true. use_excess_ice_streams=.false./'", @@ -425,17 +425,17 @@ sub cat_and_create_namelistinfile { $mode = "-phys $phys"; &make_config_cache($phys); foreach my $options ( - "-res ne0np4.ARCTIC.ne30x4 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam6.0", - "-res ne0np4.ARCTICGRIS.ne30x8 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam6.0", + "-res ne0np4.ARCTIC.ne30x4 -bgc sp -use_case 2000_control -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam6.0", + "-res ne0np4.ARCTICGRIS.ne30x8 -bgc sp -use_case 1850_control -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam6.0", "-res 1.9x2.5 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam6.0", "-res 0.9x1.25 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam6.0", "-res 0.9x1.25 -bgc bgc -crop -use_case 20thC_transient -namelist '&a start_ymd=19500101/' -lnd_tuning_mode ${phys}_cam6.0", - "-res ne0np4CONUS.ne30x8 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=20130101/' -lnd_tuning_mode ${phys}_cam6.0", + "-res ne0np4CONUS.ne30x8 -bgc sp -use_case 2000_control -namelist '&a start_ymd=20130101/' -lnd_tuning_mode ${phys}_cam6.0", "-res 1.9x2.5 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=20030101/' -lnd_tuning_mode ${phys}_cam6.0", "-res 1.9x2.5 -bgc sp -use_case 2010_control -namelist '&a start_ymd=20100101/' -lnd_tuning_mode ${phys}_cam6.0", "-res 1x1_brazil -bgc fates -no-megan -use_case 2000_control -lnd_tuning_mode ${phys}_CRUv7", - "-res C192 -bgc sp -use_case 2010_control -namelist '&a start_ymd=20100101/' -lnd_tuning_mode ${phys}_cam6.0", - "-res ne0np4.ARCTIC.ne30x4 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=20130101/' -lnd_tuning_mode ${phys}_cam6.0", + "-res C96 -bgc sp -use_case 2010_control -namelist '&a start_ymd=20100101/' -lnd_tuning_mode ${phys}_cam6.0", + "-res ne0np4.ARCTIC.ne30x4 -bgc sp -use_case 2000_control -namelist '&a start_ymd=20130101/' -lnd_tuning_mode ${phys}_cam6.0", ) { &make_env_run(); eval{ system( "$bldnml -envxml_dir . $options > $tempfile 2>&1 " ); }; @@ -1345,49 +1345,57 @@ sub cat_and_create_namelistinfile { $mode = "-phys $phys"; &make_config_cache($phys); -print "\n==================================================\n"; -print "Test ALL resolutions that have surface datasets with SP\n"; -print "==================================================\n"; +print "\n========================================================================\n"; +print "Test ALL resolutions that have surface datasets with SP for 1850 and 2000\n"; +print "========================================================================\n"; # Check for ALL resolutions with CLM50SP -my @resolutions = ( "1x1_brazil", "1x1_mexicocityMEX", "1x1_vancouverCAN", "1x1_urbanc_alpha", "5x5_amazon", "360x720cru", "0.125x0.125", "0.125nldas2", "10x15", "4x5", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne5np4.pg2", "ne16np4", "ne30np4", "ne30np4.pg3", "ne120np4.pg3", "ne0np4CONUS.ne30x8", "ne0np4.ARCTIC.ne30x4", "ne0np4.ARCTICGRIS.ne30x8", "C24", "C48", "C96", "mpasa480", "mpasa120" ); +my @resolutions = ( "1x1_brazil", "1x1_mexicocityMEX", "1x1_vancouverCAN", "1x1_urbanc_alpha", "5x5_amazon", "360x720cru", "0.125nldas2", "10x15", "4x5", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne16np4.pg3", "ne30np4", "ne30np4.pg2", "ne30np4.pg3", "ne120np4.pg3", "ne0np4CONUS.ne30x8", "ne0np4.ARCTIC.ne30x4", "ne0np4.ARCTICGRIS.ne30x8", "C96", "mpasa480", "mpasa120", "mpasa60", "mpasa15", "mpasa15-conus", "mpasa3p75" ); +my @only2000_resolutions = ( "1x1_brazil", "1x1_mexicocityMEX", "1x1_vancouverCAN", "1x1_urbanc_alpha", "5x5_amazon", "0.125nldas2", "mpasa60", "mpasa15", "mpasa15-conus", "mpasa3p75" ); my @regional; foreach my $res ( @resolutions ) { chomp($res); print "=== Test $res === \n"; - my $options = "-res $res -bgc sp -envxml_dir ."; + foreach my $use_case ( "1850_control", "2000_control" ) { + # Skip resolutions that only have 2000 versions + if ( ($use_case eq "1850_control") && ($res ~~ @only2000_resolutions) ) { + next; + } + print "=== Test $use_case === \n"; + my $options = "-res $res -bgc sp -envxml_dir . --use_case $use_case"; - &make_env_run(); - eval{ system( "$bldnml $options > $tempfile 2>&1 " ); }; - is( $@, '', "$options" ); + &make_env_run(); + eval{ system( "$bldnml $options > $tempfile 2>&1 " ); }; + is( $@, '', "$options" ); - $cfiles->checkfilesexist( "$options", $mode ); + $cfiles->checkfilesexist( "$options", $mode ); - $cfiles->shownmldiff( "default", "standard" ); - if ( defined($opts{'compare'}) ) { - $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode ); - $cfiles->dodiffonfile( "$real_par_file", "$options", $mode ); - $cfiles->comparefiles( "$options", $mode, $opts{'compare'} ); - } + $cfiles->shownmldiff( "default", "standard" ); + if ( defined($opts{'compare'}) ) { + $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode ); + $cfiles->dodiffonfile( "$real_par_file", "$options", $mode ); + $cfiles->comparefiles( "$options", $mode, $opts{'compare'} ); + } - if ( defined($opts{'generate'}) ) { - $cfiles->copyfiles( "$options", $mode ); + if ( defined($opts{'generate'}) ) { + $cfiles->copyfiles( "$options", $mode ); + } + &cleanup(); print "\n"; } - &cleanup(); print "\n"; } print "\n==================================================\n"; -print " Test important resolutions for BGC\n"; +print " Test important resolutions for BGC and historical\n"; print "==================================================\n"; -my @resolutions = ( "4x5", "10x15", "ne120np4.pg3", "ne30np4", "ne30np4.pg3", "ne16np4", "ne3np4.pg3", "1.9x2.5", "0.9x1.25", "C96", "mpasa120", "mpasa480" ); +my @resolutions = ( "4x5", "10x15", "360x720cru", "ne30np4.pg3", "ne3np4.pg3", "1.9x2.5", "0.9x1.25", "C96", "mpasa120" ); my @regional; my $nlbgcmode = "bgc"; my $mode = "$phys-$nlbgcmode"; foreach my $res ( @resolutions ) { chomp($res); print "=== Test $res === \n"; - my $options = "-res $res -envxml_dir . -bgc $nlbgcmode"; + my $options = "-res $res -envxml_dir . -bgc $nlbgcmode --use_case 20thC_transient"; &make_env_run(); eval{ system( "$bldnml $options > $tempfile 2>&1 " ); }; @@ -1408,7 +1416,7 @@ sub cat_and_create_namelistinfile { } print "\n==================================================\n"; -print " Test all use-cases \n"; +print " Rest all use-cases \n"; print "==================================================\n"; # Run over all use-cases... @@ -1511,7 +1519,7 @@ sub cat_and_create_namelistinfile { } } # Transient 20th Century simulations -my @tran_res = ( "0.9x1.25", "1.9x2.5", "ne30np4", "10x15" ); +my @tran_res = ( "0.9x1.25", "1.9x2.5", "ne30np4.pg3", "10x15" ); my $usecase = "20thC_transient"; my $GLC_NEC = 10; foreach my $res ( @tran_res ) { @@ -1532,14 +1540,9 @@ sub cat_and_create_namelistinfile { &cleanup(); } # Transient ssp_rcp scenarios that work -my @tran_res = ( "4x5", "0.9x1.25", "1.9x2.5", "10x15", "ne3np4.pg3", "ne30np4", "ne30np4.pg2", "C96", "mpasa120" ); -foreach my $usecase ( "1850_control", "1850-2100_SSP2-4.5_transient" ) { - my $startymd = undef; - if ( $usecase eq "1850_control") { - $startymd = 18500101; - } else { - $startymd = 20150101; - } +my @tran_res = ( "4x5", "0.9x1.25", "1.9x2.5", "10x15", "360x720cru", "ne3np4.pg3", "ne16np4.pg3", "ne30np4.pg3", "C96", "mpasa120" ); +foreach my $usecase ( "1850-2100_SSP2-4.5_transient" ) { + my $startymd = 20150101; foreach my $res ( @tran_res ) { $options = "-res $res -bgc bgc -crop -use_case $usecase -envxml_dir . -namelist '&a start_ymd=$startymd/'"; &make_env_run(); @@ -1562,14 +1565,38 @@ sub cat_and_create_namelistinfile { # # End loop over versions # +# +# Test ALL SSP's for f09... +# +$phys = "clm5_1"; +$mode = "-phys $phys"; +&make_config_cache($phys); +my $res = "0.9x1.25"; +foreach my $usecase ( "1850-2100_SSP5-8.5_transient", "1850-2100_SSP2-4.5_transient", "1850-2100_SSP1-2.6_transient", "1850-2100_SSP3-7.0_transient" ) { + $options = "-res $res -bgc bgc -crop -use_case $usecase -envxml_dir . -namelist '&a start_ymd=20150101/'"; + &make_env_run(); + eval{ system( "$bldnml $options > $tempfile 2>&1 " ); }; + is( $@, '', "$options" ); + $cfiles->checkfilesexist( "$options", $mode ); + $cfiles->shownmldiff( "default", "standard" ); + if ( defined($opts{'compare'}) ) { + $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode ); + $cfiles->dodiffonfile( "$real_par_file", "$options", $mode ); + $cfiles->comparefiles( "$options", $mode, $opts{'compare'} ); + } + if ( defined($opts{'generate'}) ) { + $cfiles->copyfiles( "$options", $mode ); + } + &cleanup(); +} -# The SSP's that fail... +# The SSP's that fail because of missing ndep files... $phys = "clm5_0"; $mode = "-phys $phys"; &make_config_cache($phys); my $res = "0.9x1.25"; -foreach my $usecase ( "1850-2100_SSP4-3.4_transient", "1850-2100_SSP5-3.4_transient", "1850-2100_SSP1-1.9_transient", - "1850-2100_SSP4-6.0_transient", "1850-2100_SSP5-8.5_transient", "1850-2100_SSP1-2.6_transient", "1850-2100_SSP3-7.0_transient" ) { +foreach my $usecase ( "1850-2100_SSP5-3.4_transient", "1850-2100_SSP4-3.4", "1850-2100_SSP1-1.9_transient", + "1850-2100_SSP4-6.0_transient" ) { $options = "-res $res -bgc bgc -crop -use_case $usecase -envxml_dir . -namelist '&a start_ymd=20150101/'"; &make_env_run(); eval{ system( "$bldnml $options > $tempfile 2>&1 " ); }; @@ -1589,7 +1616,7 @@ sub cat_and_create_namelistinfile { "-bgc bgc -clm_demand flanduse_timeseries -sim_year 1850-2000 -namelist '&a start_ymd=18500101/'", "-bgc bgc -envxml_dir . -namelist '&a use_c13=.true.,use_c14=.true.,use_c14_bombspike=.true./'" ); foreach my $clmopts ( @clmoptions ) { - my @clmres = ( "10x15", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne30np4", "C96", "mpasa120" ); + my @clmres = ( "10x15", "4x5", "360x720cru", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne16np4.pg3", "ne30np4.pg3", "C96", "mpasa120" ); foreach my $res ( @clmres ) { $options = "-res $res -envxml_dir . "; &make_env_run( ); @@ -1610,7 +1637,7 @@ sub cat_and_create_namelistinfile { my @clmoptions = ( "-bgc bgc -envxml_dir .", "-bgc sp -envxml_dir .", ); foreach my $clmopts ( @clmoptions ) { - my @clmres = ( "ne16np4" ); + my @clmres = ( "ne16np4.pg3" ); foreach my $res ( @clmres ) { $options = "-res $res -envxml_dir . "; &make_env_run( ); From 6c6f57e948bfa31e60b383536cc21663fedb8b70 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 19 Jan 2024 11:08:29 -0700 Subject: [PATCH 439/614] Run through black --- cime_config/SystemTests/mksurfdataesmf.py | 83 +++++++++++++---------- 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 57885a193e..12f904ae72 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -20,8 +20,8 @@ logger = logging.getLogger(__name__) -class MKSURFDATAESMF(SystemTestsCommon): +class MKSURFDATAESMF(SystemTestsCommon): def __init__(self, case): """ initialize an object interface to the SMS system test @@ -29,20 +29,22 @@ def __init__(self, case): SystemTestsCommon.__init__(self, case) # Paths and strings needed throughout - ctsm_root = self._case.get_value('COMP_ROOT_DIR_LND') - self._tool_path = os.path.join(ctsm_root, 'tools/mksurfdata_esmf') - self._tool_bld = os.path.join(self._get_caseroot(), 'tool_bld') + ctsm_root = self._case.get_value("COMP_ROOT_DIR_LND") + self._tool_path = os.path.join(ctsm_root, "tools/mksurfdata_esmf") + self._tool_bld = os.path.join(self._get_caseroot(), "tool_bld") time_stamp = datetime.today().strftime("%y%m%d") - self._res = '10x15' # see important comment in script's docstring - self._model_yr = '1850' - self._jobscript = os.path.join(self._get_caseroot(), - 'mksurfdata_jobscript_single') - self._fsurdat_namelist = os.path.join(self._get_caseroot(), - f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.namelist') - self._fsurdat_nc = os.path.join(self._get_caseroot(), - f'surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.nc') - self._TestStatus_log_path = os.path.join(self._get_caseroot(), - 'TestStatus.log') + self._res = "10x15" # see important comment in script's docstring + self._model_yr = "1850" + self._jobscript = os.path.join(self._get_caseroot(), "mksurfdata_jobscript_single") + self._fsurdat_namelist = os.path.join( + self._get_caseroot(), + f"surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.namelist", + ) + self._fsurdat_nc = os.path.join( + self._get_caseroot(), + f"surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.nc", + ) + self._TestStatus_log_path = os.path.join(self._get_caseroot(), "TestStatus.log") def build_phase(self, sharedlib_only=False, model_only=False): """ @@ -58,24 +60,25 @@ def build_phase(self, sharedlib_only=False, model_only=False): # if the test stops and gets restarted. if sharedlib_only: # Paths and strings - build_script_path = os.path.join(self._tool_path, - 'gen_mksurfdata_build.sh') - nml_script_path = os.path.join(self._tool_path, - 'gen_mksurfdata_namelist') - gen_jobscript_path = os.path.join(self._tool_path, - 'gen_mksurfdata_jobscript_single') - gen_mksurfdata_namelist = f'{nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}' - gen_mksurfdata_jobscript = f'{gen_jobscript_path} --number-of-nodes 12 --tasks-per-node 12 --namelist-file {self._fsurdat_namelist}' + build_script_path = os.path.join(self._tool_path, "gen_mksurfdata_build.sh") + nml_script_path = os.path.join(self._tool_path, "gen_mksurfdata_namelist") + gen_jobscript_path = os.path.join(self._tool_path, "gen_mksurfdata_jobscript_single") + gen_mksurfdata_namelist = f"{nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}" + gen_mksurfdata_jobscript = f"{gen_jobscript_path} --number-of-nodes 12 --tasks-per-node 12 --namelist-file {self._fsurdat_namelist}" # Rm tool_bld and build executable that will generate fsurdat try: - subprocess.check_call(f'rm -rf {self._tool_bld}', shell=True) + subprocess.check_call(f"rm -rf {self._tool_bld}", shell=True) except subprocess.CalledProcessError as e: - sys.exit(f'{e} ERROR REMOVING {self._tool_bld}. DETAILS IN {self._TestStatus_log_path}') + sys.exit( + f"{e} ERROR REMOVING {self._tool_bld}. DETAILS IN {self._TestStatus_log_path}" + ) try: - subprocess.check_call(f'{build_script_path} --blddir {self._tool_bld}', shell=True) + subprocess.check_call(f"{build_script_path} --blddir {self._tool_bld}", shell=True) except subprocess.CalledProcessError as e: - sys.exit(f'{e} ERROR RUNNING {build_script_path}. DETAILS IN {self._TestStatus_log_path}') + sys.exit( + f"{e} ERROR RUNNING {build_script_path}. DETAILS IN {self._TestStatus_log_path}" + ) # Generate namelist for generating fsurdat (rm namelist if exists) if os.path.exists(self._fsurdat_namelist): @@ -83,7 +86,9 @@ def build_phase(self, sharedlib_only=False, model_only=False): try: subprocess.check_call(gen_mksurfdata_namelist, shell=True) except subprocess.CalledProcessError as e: - sys.exit(f'{e} ERROR RUNNING {gen_mksurfdata_namelist}. DETAILS IN {self._TestStatus_log_path}') + sys.exit( + f"{e} ERROR RUNNING {gen_mksurfdata_namelist}. DETAILS IN {self._TestStatus_log_path}" + ) # Generate jobscript that will run the executable if os.path.exists(self._jobscript): @@ -91,16 +96,17 @@ def build_phase(self, sharedlib_only=False, model_only=False): try: subprocess.check_call(gen_mksurfdata_jobscript, shell=True) except subprocess.CalledProcessError as e: - sys.exit(f'{e} ERROR RUNNING {gen_mksurfdata_jobscript}. DETAILS IN {self._TestStatus_log_path}') + sys.exit( + f"{e} ERROR RUNNING {gen_mksurfdata_jobscript}. DETAILS IN {self._TestStatus_log_path}" + ) # Change self._jobscript to an executable file - subprocess.check_call(f'chmod a+x {self._jobscript}', shell=True) + subprocess.check_call(f"chmod a+x {self._jobscript}", shell=True) # Call this step only once even if the test stops and gets restarted. - if not os.path.exists(os.path.join(self._get_caseroot(), - 'done_MKSURFDATAESMF_setup.txt')): + if not os.path.exists(os.path.join(self._get_caseroot(), "done_MKSURFDATAESMF_setup.txt")): # Modify user_nl_clm to point to the generated fsurdat self._modify_user_nl() - with open('done_MKSURFDATAESMF_setup.txt', 'w') as fp: + with open("done_MKSURFDATAESMF_setup.txt", "w") as fp: pass self.build_indv(sharedlib_only=sharedlib_only, model_only=model_only) @@ -117,7 +123,7 @@ def run_phase(self): try: subprocess.check_call(self._jobscript, shell=True) except subprocess.CalledProcessError as e: - sys.exit(f'{e} ERROR RUNNING {self._jobscript}; details in {self._TestStatus_log_path}') + sys.exit(f"{e} ERROR RUNNING {self._jobscript}; details in {self._TestStatus_log_path}") # Submit CTSM run that uses fsurdat just generated self.run_indv() @@ -126,7 +132,10 @@ def _modify_user_nl(self): """ Modify user_nl_clm to point to the generated fsurdat """ - append_to_user_nl_files(caseroot = self._get_caseroot(), - component = "clm", - contents = "fsurdat = '{}'".format(self._fsurdat_nc) + "\n" + - "convert_ocean_to_land = .true.") + append_to_user_nl_files( + caseroot=self._get_caseroot(), + component="clm", + contents="fsurdat = '{}'".format(self._fsurdat_nc) + + "\n" + + "convert_ocean_to_land = .true.", + ) From cdc88ba65e36fcf3b08859228932143642cedab2 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 19 Jan 2024 11:09:20 -0700 Subject: [PATCH 440/614] Add black format to git blame list --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 3726528b67..f058c15639 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -36,3 +36,4 @@ fdf72cd011e2ba318987a1e100efc5a1847c9d04 de9a30bfbbec36f9dcacc4380005ab596da47af4 cda0cf1412212e6f4363e6e8eb39f74c944b454d` aa04d1f7d86cc2503b98b7e2b2d84dbfff6c316b +6c6f57e948bfa31e60b383536cc21663fedb8b70 From 4deab5b6a8469115f5e7d2eef894522f02ab5641 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 19 Jan 2024 15:23:46 -0700 Subject: [PATCH 441/614] Updates to the Makefile (not tested, yet) --- tools/mksurfdata_esmf/Makefile | 47 +++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index c6c55a7e47..b1c2a79b48 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -1,12 +1,15 @@ # -*- mode:Makefile -*- # # To generate all surface data sets, run: -# make -f Makefile.data all +# make all +# +# To generate all surface data sets that use subset_data to be generated: +# make all-subset # # To generate a single dataset, run make with the name of the rule you # want to build. For example, to generate the crop data set for 1x1_numaIA: # -# make -f Makefile.data crop-numa +# make crop-numa # # NOTE: The default behavior is to parallelize data set creation using # the batch system by submitting jobs to the batch queue (on cheyenne). @@ -76,25 +79,27 @@ TROPICS = \ CROP = \ crop-global-present \ crop-global-present-low-res \ - crop-global-present-ne16np4 \ - crop-global-present-ne120np4 \ + crop-global-present-ne16pg3.np4 \ + crop-global-present-ne120pg3.np4 \ crop-global-1850 \ crop-global-1850-low-res \ - crop-global-1850-ne16np4 \ - crop-global-1850-ne120np4 \ + crop-global-1850-ne16pg3.np4 \ + crop-global-1850-ne120pg3.np4 \ crop-global-future -all : standard tropics crop urban all-subset +all : standard tropics crop all-subset +# These are all the surface datasets generated by subset_data +# This runs interactively and does not send jobs to the batch queue all-subset : \ 1x1_brazil-tropics-present \ - crop-tropics-historical \ - crop-tropics-transient \ + 1x1_brazil-tropics-historical \ + 1x1_brazil-tropics-transient \ crop-numa-present \ crop-numa-historical \ crop-smallville \ crop-smallville-historical \ crop-smallville-transient \ - urban-present urban-alpha + urban DEBUG: @echo "HOST := $(HOST)" @@ -144,10 +149,10 @@ crop-tropics-present : FORCE 1x1_brazil-tropics-present : FORCE $(SUBSETDATA_POINT_ALLLU) --create-surface $(SUBSETDATA_1X1_BRAZIL) -crop-tropics-historical : FORCE +1x1_brazil-tropics-historical : FORCE $(SUBSETDATA_POINT_ALLLU) --create-surface $(SUBSETDATA_1X1_BRAZIL) --cfg-file default_data_1850.cfg -crop-tropics-transient : FORCE +1x1_brazil-tropics-transient : FORCE $(SUBSETDATA_POINT_ALLLU) --create-landuse $(SUBSETDATA_1X1_BRAZIL) # @@ -163,11 +168,11 @@ crop-global-present-low-res : FORCE $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -crop-global-present-ne16np4 : FORCE +crop-global-present-ne16pg3.np4 : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -crop-global-present-ne120np4 : FORCE +crop-global-present-ne120pg3.np4 : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh @@ -179,11 +184,11 @@ crop-global-1850-low-res : FORCE $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -crop-global-1850-ne16np4 : FORCE +crop-global-1850-ne16pg3.np4 : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -crop-global-1850-ne120np4 : FORCE +crop-global-1850-ne120pg3.np4 : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh @@ -219,9 +224,9 @@ crop-smallville-transient : FORCE crop-global-future : crop-global-SSP1-1.9-f09 crop-global-SSP1-2.6-f09 crop-global-SSP2-4.5 crop-global-SSP2-4.5-low-res \ crop-global-SSP3-7.0-f09 crop-global-SSP4-3.4-f09 crop-global-SSP4-6.0-f09 crop-global-SSP5-8.5-f09 -crop-global-SSP2-4.5-low-res : crop-global-SSP2-4.5-f10 crop-global-SSP2-4.5-ne3 +crop-global-SSP2-4.5-low-res : crop-global-SSP2-4.5-f10 crop-global-SSP2-4.5-ne3pg3.np4 crop-global-SSP2-4.5 : crop-global-SSP2-4.5-f19 crop-global-SSP2-4.5-f09 crop-global-SSP2-4.5-f45 \ - crop-global-SSP2-4.5-hcru crop-global-SSP2-4.5-ne16 crop-global-SSP2-4.5-ne30 \ + crop-global-SSP2-4.5-hcru crop-global-SSP2-4.5-ne16pg3.np4 crop-global-SSP2-4.5-ne30pg3.np4 \ crop-global-SSP2-4.5-C96 crop-global-SSP2-4.5-mpasa120 crop-global-SSP1-1.9-f09 : FORCE @@ -248,11 +253,11 @@ crop-global-SSP2-4.5-hcru : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh -crop-global-SSP2-4.5-ne16 : FORCE +crop-global-SSP2-4.5-ne16pg3.np4 : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh -crop-global-SSP2-4.5-ne30 : FORCE +crop-global-SSP2-4.5-ne30pg3.np4 : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh @@ -268,7 +273,7 @@ crop-global-SSP2-4.5-f10 : FORCE $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh -crop-global-SSP2-4.5-ne3 : FORCE +crop-global-SSP2-4.5-ne3pg3.np4 : FORCE $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh From 730e976695e8924862dc69f8618232876a4bff0d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 19 Jan 2024 15:29:03 -0700 Subject: [PATCH 442/614] Revisions from code review with Erik --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- tools/mksurfdata_esmf/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index d250289687..f423f23d95 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1314,7 +1314,7 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_1850_c230517.n lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_1850_c230517.nc -/glade/campaign/cesm/cesmdata/inputdata/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_1850-2015_c240103.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_1850-2015_c240103.nc /glade/work/erik/ctsm_worktrees/ctsm5.2.mksurfdata/tools/mksurfdata_esmf/surfdata_1x1_numaIA_hist_78pfts_CMIP6_1850_c230726.nc diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index b1c2a79b48..8e08f63515 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -216,7 +216,7 @@ crop-smallville-historical : FORCE # modify_smallville.sh to generate three modified landuse.timeseries files needed for testing. crop-smallville-transient : FORCE $(SUBSETDATA_POINT) --create-landuse $(SUBSETDATA_1X1_SMALLTRANSIENT) -../modify_input_files/modify_smallville.sh + ../modify_input_files/modify_smallville.sh # # Crop with future scenarios From 2bfad308862b93fddbb63169f29f967c27f44256 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 23 Jan 2024 16:57:41 -0700 Subject: [PATCH 443/614] Updates for "make all-subset" to complete successfully --- .../toolchain/gen_mksurfdata_jobscript_multi.py | 8 +------- tools/mksurfdata_esmf/Makefile | 16 +++++++++++----- tools/modify_input_files/modify_smallville.sh | 13 ++++++++----- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 148e5c2c35..ffecdca9be 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -152,13 +152,7 @@ def main(): # -------------------------- # Determine target list # -------------------------- - target_list = [] - if scenario == "crop": - target_list = ["crop-global-present", "crop-global-1850"] - elif scenario == "tropics": - target_list = ["crop-tropics-present"] - else: - target_list = [scenario] + target_list = [scenario] # -------------------------- # Error checking diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index 8e08f63515..9b6ee9a296 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -1,5 +1,8 @@ # -*- mode:Makefile -*- # +# Before running "make" start with +# module load nco +# # To generate all surface data sets, run: # make all # @@ -14,6 +17,13 @@ # NOTE: The default behavior is to parallelize data set creation using # the batch system by submitting jobs to the batch queue (on cheyenne). # +# In all cases where "--scenario $@" appears, the code executes the +# recipe for the specific target/scenario that it finds in +# ../../python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +# There are a few grids mentioned explicitly here in the Makefile and +# many others that only appear in the gen_mksurfdata_jobscript_multi.py +# Look for resolutions or groups of resolutions in that python code. +# # Set up special characters null := @@ -73,9 +83,6 @@ STANDARD = \ ULTRA_HIRES = \ global-present-ultra-hi-res -TROPICS = \ - crop-tropics-present - CROP = \ crop-global-present \ crop-global-present-low-res \ @@ -86,7 +93,7 @@ CROP = \ crop-global-1850-ne16pg3.np4 \ crop-global-1850-ne120pg3.np4 \ crop-global-future -all : standard tropics crop all-subset +all : standard crop all-subset crop-tropics-present # These are all the surface datasets generated by subset_data # This runs interactively and does not send jobs to the batch queue @@ -140,7 +147,6 @@ global-present-ultra-hi-res : FORCE # # tropics # -tropics : $(TROPICS) crop-tropics-present : FORCE $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 diff --git a/tools/modify_input_files/modify_smallville.sh b/tools/modify_input_files/modify_smallville.sh index 8f1ab8384b..f61231e67c 100755 --- a/tools/modify_input_files/modify_smallville.sh +++ b/tools/modify_input_files/modify_smallville.sh @@ -4,11 +4,14 @@ # Load the nco module and run the script in the ctsm_pylib environment: module load nco -file_to_2015="subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-2015_c$(date +%y%m%d).nc" -file_to_1855="subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-1855_c$(date +%y%m%d).nc" -file_lake="subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynLakes_c$(date +%y%m%d).nc" -file_urban="subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynUrban_c$(date +%y%m%d).nc" -file_pft="subset_data_single_point/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynPft_c$(date +%y%m%d).nc" +# This script runs from the mksurfdata_esmf/Makefile. +# When running standalone, it may need "subset_data_single_point/" in front +# of each landuse.timeseries file name. + file_to_2015="landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-2015_c$(date +%y%m%d).nc" + file_to_1855="landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-1855_c$(date +%y%m%d).nc" + file_lake="landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynLakes_c$(date +%y%m%d).nc" + file_urban="landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynUrban_c$(date +%y%m%d).nc" + file_pft="landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynPft_c$(date +%y%m%d).nc" # Trim the file to just the years 1850-1855 ncks -d time,0,5 $file_to_2015 $file_to_1855 From 4be83a7bf9824e4528b3694d1bb94c48e661e904 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 24 Jan 2024 18:30:21 -0700 Subject: [PATCH 444/614] Add potveg to the list of files created --- python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 5 +++++ tools/mksurfdata_esmf/Makefile | 1 + 2 files changed, 6 insertions(+) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index ffecdca9be..d0105c11d8 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -12,6 +12,7 @@ from ctsm.utils import abort valid_scenarios = [ + "global-potveg", "global-present", "global-present-low-res", "global-present-ultra-hi-res", @@ -196,6 +197,10 @@ def main(): # Determine commands for each target list # -------------------------- dataset_dict = { + "global-potveg": ( + "--start-year 1850 --end-year 1850 --nocrop --potveg --res", + "f09", + ), "global-present": ( "--start-year 2000 --end-year 2000 --nocrop --vic --res", "standard_res_no_crop", diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index 9b6ee9a296..fcc09ec338 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -76,6 +76,7 @@ SUBSETDATA_1X1_URBALPHA := --lat -37.7308 --lon 0 --site 1x1_urbanc_alpha --o # low-res is for low resolutions for testing # nldas is for NWP working with WRF STANDARD = \ + global-potveg \ global-present \ global-present-low-res \ global-present-nldas From 83fb3bada420b5cfedb80ab489678a20ac1678f2 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 25 Jan 2024 14:46:20 -0700 Subject: [PATCH 445/614] Updates for generating all necessary fsurdat/landuse files --- .../gen_mksurfdata_jobscript_multi.py | 114 ++++++++++-------- tools/mksurfdata_esmf/Makefile | 105 +++++++++++----- 2 files changed, 140 insertions(+), 79 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index d0105c11d8..e3e0842068 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -16,38 +16,40 @@ "global-present", "global-present-low-res", "global-present-ultra-hi-res", - "global-present-nldas", - "global-hist-4x5", "crop-tropics-present", "crop", "crop-global-present", "crop-global-present-low-res", - "crop-global-present-ne16np4", - "crop-global-present-ne120np4", - "crop-global-present-0.125", + "crop-global-present-ne16", + "crop-global-present-ne30", + "crop-global-present-ne120", + "crop-global-present-nldas", "crop-global-1850", "crop-global-1850-low-res", - "crop-global-1850-ne16np4", - "crop-global-1850-ne120np4", + "crop-global-1850-ne16", + "crop-global-1850-ne30", + "crop-global-1850-ne120", "crop-global-hist", - "crop-global-future", + "crop-global-hist-low-res", + "crop-global-hist-ne16", + "crop-global-hist-ne30", + "crop-global-hist-ne120", + "crop-global-SSP1-1.9-f09", "crop-global-SSP1-2.6-f09", - "crop-global-SSP3-7.0-f09", - "crop-global-SSP5-3.4-f09", "crop-global-SSP2-4.5-f09", "crop-global-SSP2-4.5-f19", "crop-global-SSP2-4.5-f10", "crop-global-SSP2-4.5-f45", "crop-global-SSP2-4.5-ne3", - "crop-global-SSP2-4.5-ne30", "crop-global-SSP2-4.5-ne16", + "crop-global-SSP2-4.5-ne30", "crop-global-SSP2-4.5-hcru", "crop-global-SSP2-4.5-C96", "crop-global-SSP2-4.5-mpasa120", - "crop-global-SSP2-4.5-hi-res", - "crop-global-SSP1-1.9-f09", + "crop-global-SSP3-7.0-f09", "crop-global-SSP4-3.4-f09", "crop-global-SSP4-6.0-f09", + "crop-global-SSP5-3.4-f09", "crop-global-SSP5-8.5-f09", ] @@ -165,7 +167,7 @@ def main(): # Determine resolution sets that are referenced in commands # -------------------------- resolution_dict = { - "standard_res_no_crop": ["0.9x1.25", "1.9x2.5", "mpasa60"], + "standard_res_no_crop": ["0.9x1.25", "1.9x2.5", "mpasa60", "mpasa60-3conus", "mpasa60-3centralUS"], "f09": ["0.9x1.25"], "f19": ["1.9x2.5"], "hcru": ["360x720cru"], @@ -173,20 +175,18 @@ def main(): "mpasa120": ["mpasa120"], "f10": ["10x15"], "f45": ["4x5"], - "ne3": ["ne3np4.pg3"], - "ne16": ["ne16np4.pg3"], - "ne30": ["ne30np4.pg3"], - "low_res_no_crop": ["10x15"], + "low_res_no_crop": ["10x15", "4x5"], "ultra_hi_res_no_crop": ["mpasa15", "mpasa15-3conus", "mpasa3p75"], - "low_res_all": ["10x15", "ne3np4.pg3"], - "hi_res_all": ["ne120np4.pg3"], - "standard_res": ["360x720cru", "0.9x1.25", "1.9x2.5", "C96", "ne30np4.pg3", "mpasa120"], - "low_res": ["10x15", "4x5", "ne3np4.pg3", "mpasa480"], + "standard_res": ["360x720cru", "0.9x1.25", "1.9x2.5", "C96", "mpasa120"], + "low_res": ["10x15", "4x5", "ne3pg3.np4", "mpasa480"], "nldas_res": ["0.125nldas2"], - "5x5_amazon_res": ["5x5_amazon"], - "ne16np4_res": ["ne16np4.pg3"], - "ne120np4_res": [ - "ne120np4.pg3", + "vic_res": ["0.9x1.25", "1.9x2.5", "10x15"], + "5x5_amazon": ["5x5_amazon"], + "ne3": ["ne3pg3.np4"], + "ne16": ["ne16pg3.np4"], + "ne30": ["ne30pg3.np4", "ne30pg2.np4", "ne30.np4"], + "ne120": [ + "ne120pg3.np4", "ne0np4.ARCTICGRIS.ne30x8", "ne0np4.ARCTIC.ne30x4", "ne0np4CONUS.ne30x8", @@ -197,29 +197,29 @@ def main(): # Determine commands for each target list # -------------------------- dataset_dict = { + "global-vic": ( + "--start-year 2000 --end-year 2000 --nocrop --vic --res", + "vic_res", + ), "global-potveg": ( "--start-year 1850 --end-year 1850 --nocrop --potveg --res", "f09", ), "global-present": ( - "--start-year 2000 --end-year 2000 --nocrop --vic --res", + "--start-year 2000 --end-year 2000 --nocrop --res", "standard_res_no_crop", ), "global-present-low-res": ( - "--start-year 2000 --end-year 2000 --nocrop --vic --res", + "--start-year 2000 --end-year 2000 --nocrop --res", "low_res_no_crop", ), "global-present-ultra-hi-res": ( "--start-year 2000 --end-year 2000 --nocrop --res", "ultra_hi_res_no_crop", ), - "global-present-nldas": ( - "--start-year 2000 --end-year 2000 --nocrop --vic --res", - "nldas_res", - ), "crop-tropics-present": ( "--start-year 2000 --end-year 2000 --res", - "5x5_amazon_res", + "5x5_amazon", ), "crop-global-present": ( "--start-year 2000 --end-year 2000 --res", @@ -229,16 +229,20 @@ def main(): "--start-year 2000 --end-year 2000 --res", "low_res", ), - "crop-global-present-ne16np4": ( + "crop-global-present-ne16": ( "--start-year 2000 --end-year 2000 --res", - "ne16np4_res", + "ne16", ), - "crop-global-present-ne120np4": ( + "crop-global-present-ne30": ( "--start-year 2000 --end-year 2000 --res", - "ne120np4_res", + "ne30", ), - "crop-global-present-0.125": ( - "--start-year 2000 --end-year 2000 --hirespft --res", + "crop-global-present-ne120": ( + "--start-year 2000 --end-year 2000 --res", + "ne120", + ), + "crop-global-present-nldas": ( + "--start-year 2000 --end-year 2000 --res", # TODO slevis: --hirespft uses old data for now, so keep out "nldas_res", ), "crop-global-1850": ( @@ -249,18 +253,38 @@ def main(): "--start-year 1850 --end-year 1850 --res", "low_res", ), - "crop-global-1850-ne16np4": ( + "crop-global-1850-ne16": ( "--start-year 1850 --end-year 1850 --res", - "ne16np4_res", + "ne16", ), - "crop-global-1850-ne120np4": ( + "crop-global-1850-ne30": ( "--start-year 1850 --end-year 1850 --res", - "ne120np4_res", + "ne30", + ), + "crop-global-1850-ne120": ( + "--start-year 1850 --end-year 1850 --res", + "ne120", ), "crop-global-hist": ( "--start-year 1850 --end-year 2015 --nosurfdata --res", "standard_res", ), + "crop-global-hist-low-res": ( + "--start-year 1850 --end-year 2015 --nosurfdata --res", + "low_res", + ), + "crop-global-hist-ne16": ( + "--start-year 1850 --end-year 2015 --nosurfdata --res", + "ne16_res", + ), + "crop-global-hist-ne30": ( + "--start-year 1850 --end-year 2015 --nosurfdata --res", + "ne30", + ), + "crop-global-hist-ne120": ( + "--start-year 1850 --end-year 2015 --nosurfdata --res", + "ne120", + ), "crop-global-SSP1-1.9-f09": ( "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-1.9 --res", "f09", @@ -305,10 +329,6 @@ def main(): "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", "mpasa120", ), - "crop-global-SSP2-4.5-hi-res": ( - "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", - "hi_res_all", - ), "crop-global-SSP3-7.0-f09": ( "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP3-7.0 --res", "f09", diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index fcc09ec338..6d5228431c 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -75,11 +75,12 @@ SUBSETDATA_1X1_URBALPHA := --lat -37.7308 --lon 0 --site 1x1_urbanc_alpha --o # ne120np4 and hi-res are for high resolution, ne16np4 is for mid-resolution testing # low-res is for low resolutions for testing # nldas is for NWP working with WRF +# STANDARD means no crop, so 16 pfts STANDARD = \ + global-vic \ global-potveg \ global-present \ global-present-low-res \ - global-present-nldas ULTRA_HIRES = \ global-present-ultra-hi-res @@ -87,14 +88,21 @@ ULTRA_HIRES = \ CROP = \ crop-global-present \ crop-global-present-low-res \ - crop-global-present-ne16pg3.np4 \ - crop-global-present-ne120pg3.np4 \ + crop-global-present-ne16 \ + crop-global-present-ne120 \ + crop-global-present-nldas \ crop-global-1850 \ crop-global-1850-low-res \ - crop-global-1850-ne16pg3.np4 \ - crop-global-1850-ne120pg3.np4 \ - crop-global-future -all : standard crop all-subset crop-tropics-present + crop-global-1850-ne16 \ + crop-global-1850-ne120 \ + crop-global-hist \ + crop-global-hist-low-res \ + crop-global-hist-ne16 \ + crop-global-hist-ne120 \ + crop-global-future \ + +# TODO slevis: ultra-hires temporary to complete ctsm5.2 data generation +all : standard crop all-subset crop-tropics-present ultra-hires # These are all the surface datasets generated by subset_data # This runs interactively and does not send jobs to the batch queue @@ -124,18 +132,22 @@ DEBUG: # standard : $(STANDARD) -global-present : FORCE +global-vic : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -global-present-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 +global-potveg : FORCE + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -global-present-nldas : FORCE +global-present : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh +global-present-low-res : FORCE + $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + # # Ultra high resolutions (Don't do by default user should select this by hand) # @@ -175,11 +187,15 @@ crop-global-present-low-res : FORCE $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -crop-global-present-ne16pg3.np4 : FORCE +crop-global-present-ne16 : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -crop-global-present-ne120pg3.np4 : FORCE +crop-global-present-ne120 : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + +crop-global-present-nldas : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh @@ -191,15 +207,27 @@ crop-global-1850-low-res : FORCE $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -crop-global-1850-ne16pg3.np4 : FORCE +crop-global-1850-ne16 : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -crop-global-1850-ne120pg3.np4 : FORCE +crop-global-1850-ne120 : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -crop-global-present-0.125 : FORCE +crop-global-hist : FORCE + $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + +crop-global-hist-low-res : FORCE + $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + +crop-global-hist-ne16 : FORCE + $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + +crop-global-hist-ne120 : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh @@ -228,13 +256,26 @@ crop-smallville-transient : FORCE # # Crop with future scenarios # -crop-global-future : crop-global-SSP1-1.9-f09 crop-global-SSP1-2.6-f09 crop-global-SSP2-4.5 crop-global-SSP2-4.5-low-res \ - crop-global-SSP3-7.0-f09 crop-global-SSP4-3.4-f09 crop-global-SSP4-6.0-f09 crop-global-SSP5-8.5-f09 -crop-global-SSP2-4.5-low-res : crop-global-SSP2-4.5-f10 crop-global-SSP2-4.5-ne3pg3.np4 -crop-global-SSP2-4.5 : crop-global-SSP2-4.5-f19 crop-global-SSP2-4.5-f09 crop-global-SSP2-4.5-f45 \ - crop-global-SSP2-4.5-hcru crop-global-SSP2-4.5-ne16pg3.np4 crop-global-SSP2-4.5-ne30pg3.np4 \ - crop-global-SSP2-4.5-C96 crop-global-SSP2-4.5-mpasa120 +crop-global-future : crop-global-SSP1-1.9-f09 \ + crop-global-SSP1-2.6-f09 \ + crop-global-SSP2-4.5 \ + crop-global-SSP2-4.5-low-res \ + crop-global-SSP3-7.0-f09 \ + crop-global-SSP4-3.4-f09 \ + crop-global-SSP4-6.0-f09 \ + crop-global-SSP5-8.5-f09 + +crop-global-SSP2-4.5-low-res : crop-global-SSP2-4.5-f10 \ + crop-global-SSP2-4.5-f45 \ + crop-global-SSP2-4.5-ne3 +crop-global-SSP2-4.5 : crop-global-SSP2-4.5-f09 \ + crop-global-SSP2-4.5-f19 \ + crop-global-SSP2-4.5-hcru \ + crop-global-SSP2-4.5-ne16 \ + crop-global-SSP2-4.5-ne30 \ + crop-global-SSP2-4.5-C96 \ + crop-global-SSP2-4.5-mpasa120 crop-global-SSP1-1.9-f09 : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 @@ -252,6 +293,10 @@ crop-global-SSP2-4.5-f19 : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh +crop-global-SSP2-4.5-f10 : FORCE + $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh + crop-global-SSP2-4.5-f45 : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh @@ -260,11 +305,15 @@ crop-global-SSP2-4.5-hcru : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh -crop-global-SSP2-4.5-ne16pg3.np4 : FORCE +crop-global-SSP2-4.5-ne3 : FORCE + $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(BATCHJOBS) $@.sh + +crop-global-SSP2-4.5-ne16 : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh -crop-global-SSP2-4.5-ne30pg3.np4 : FORCE +crop-global-SSP2-4.5-ne30 : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh @@ -276,14 +325,6 @@ crop-global-SSP2-4.5-mpasa120 : FORCE $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh -crop-global-SSP2-4.5-f10 : FORCE - $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 - $(BATCHJOBS) $@.sh - -crop-global-SSP2-4.5-ne3pg3.np4 : FORCE - $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 - $(BATCHJOBS) $@.sh - # Don't do the high-resolution cases by default... crop-global-SSP2-4.5-hi-res : FORCE $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 From 5638af2e8cb269c7d67d75c50e3521b2ddc788a0 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 25 Jan 2024 14:56:40 -0700 Subject: [PATCH 446/614] Renamed an fsurdat according to a pending TODO --- bld/namelist_files/namelist_defaults_ctsm.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index a460415c87..a30161090d 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1361,8 +1361,7 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_1850_c230517.n lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_1850_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_1850-2015_c240103.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_1850_c240103.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/ssurfdata_1x1_numaIA_hist_78pfts_CMIP6_1850_c240110.nc From 78a533c883069941cf960a926c7d2587beddb28b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 25 Jan 2024 15:22:37 -0700 Subject: [PATCH 447/614] One-line addition to ...jobscript_multi.py --- python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index e3e0842068..d201b1b127 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -12,6 +12,7 @@ from ctsm.utils import abort valid_scenarios = [ + "global-vic", "global-potveg", "global-present", "global-present-low-res", From 9a1403995e4b3918b5bee23aa7cf5acccac62493 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 26 Jan 2024 09:32:51 -0700 Subject: [PATCH 448/614] Updates for --vic option --- .../ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 10 ++-------- tools/mksurfdata_esmf/Makefile | 9 ++------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index d201b1b127..8cd510a458 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -12,7 +12,6 @@ from ctsm.utils import abort valid_scenarios = [ - "global-vic", "global-potveg", "global-present", "global-present-low-res", @@ -181,7 +180,6 @@ def main(): "standard_res": ["360x720cru", "0.9x1.25", "1.9x2.5", "C96", "mpasa120"], "low_res": ["10x15", "4x5", "ne3pg3.np4", "mpasa480"], "nldas_res": ["0.125nldas2"], - "vic_res": ["0.9x1.25", "1.9x2.5", "10x15"], "5x5_amazon": ["5x5_amazon"], "ne3": ["ne3pg3.np4"], "ne16": ["ne16pg3.np4"], @@ -198,10 +196,6 @@ def main(): # Determine commands for each target list # -------------------------- dataset_dict = { - "global-vic": ( - "--start-year 2000 --end-year 2000 --nocrop --vic --res", - "vic_res", - ), "global-potveg": ( "--start-year 1850 --end-year 1850 --nocrop --potveg --res", "f09", @@ -223,11 +217,11 @@ def main(): "5x5_amazon", ), "crop-global-present": ( - "--start-year 2000 --end-year 2000 --res", + "--start-year 2000 --end-year 2000 --vic --res", "standard_res", ), "crop-global-present-low-res": ( - "--start-year 2000 --end-year 2000 --res", + "--start-year 2000 --end-year 2000 --vic --res", "low_res", ), "crop-global-present-ne16": ( diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index 6d5228431c..d9015f8a97 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -1,7 +1,7 @@ # -*- mode:Makefile -*- # -# Before running "make" start with -# module load nco +# Before running "make urban-alpha" or any target that includes it, +# execute "module load nco" first. # # To generate all surface data sets, run: # make all @@ -77,7 +77,6 @@ SUBSETDATA_1X1_URBALPHA := --lat -37.7308 --lon 0 --site 1x1_urbanc_alpha --o # nldas is for NWP working with WRF # STANDARD means no crop, so 16 pfts STANDARD = \ - global-vic \ global-potveg \ global-present \ global-present-low-res \ @@ -132,10 +131,6 @@ DEBUG: # standard : $(STANDARD) -global-vic : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 - $(BATCHJOBS) $@.sh - global-potveg : FORCE $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh From 342ca02810ae539330f73cb1f237833f38fb64ee Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 26 Jan 2024 11:07:29 -0700 Subject: [PATCH 449/614] Mods suggested by @fang-bowen that fix the mksurdata_esmf build step --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 8 ++------ tools/mksurfdata_esmf/src/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index 90b94f6471..e9d0fcfb23 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -32,22 +32,18 @@ blddir=$cwd/tool_bld # may overwrite this default with command-line option (bel # May overwrite this default with command-line option --machine hostname=`hostname --short` case $hostname in - ##cheyenne - cheyenne* | r* ) - export MACH="cheyenne" + derecho* | r* ) + export MACH="derecho" pio_iotype=1 ;; - ##casper casper* ) export MACH="casper" pio_iotype=1 ;; - ##izumi izumi*) export MACH="izumi" pio_iotype=2 ;; - ##Hobart hobart*) export MACH="hobart" pio_iotype=2 diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index 7d845d27bf..2be063b976 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -50,8 +50,8 @@ set_property(TARGET pnetcdf PROPERTY IMPORTED_LOCATION $ENV{PNETCDF}) add_library(pioc STATIC IMPORTED) add_library(piof STATIC IMPORTED) -set_property(TARGET pioc PROPERTY IMPORTED_LOCATION $ENV{PIO}/lib/libpioc.a) -set_property(TARGET piof PROPERTY IMPORTED_LOCATION $ENV{PIO}/lib/libpiof.a) +set_property(TARGET pioc PROPERTY IMPORTED_LOCATION $ENV{PIO}/lib/libpioc.so) +set_property(TARGET piof PROPERTY IMPORTED_LOCATION $ENV{PIO}/lib/libpiof.so) add_executable(mksurfdata ${SRCFILES}) target_link_libraries(mksurfdata PRIVATE esmf piof pioc) target_include_directories (mksurfdata PRIVATE ${ESMF_F90COMPILEPATHS}) From 049ee01e7dfbd5b708ccbe0c7cb7c3da197bc226 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 26 Jan 2024 13:04:14 -0700 Subject: [PATCH 450/614] Updates to the MKSURFDATAESMF test --- cime_config/testdefs/testlist_clm.xml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index ef5cac6f07..6dfa8b7372 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -3571,18 +3571,24 @@ - + - + + + + + + + From 159a97781e67cd9ecea92bb60398ae56fb09687e Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 26 Jan 2024 15:08:59 -0700 Subject: [PATCH 451/614] Updates for mksurfdata_esmf to work as advertised --- .../gen_mksurfdata_jobscript_multi.py | 12 +++++------ .../gen_mksurfdata_jobscript_single.py | 20 +++++++++---------- tools/mksurfdata_esmf/README | 12 ++++------- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 8cd510a458..ca4ea6e12a 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -76,7 +76,7 @@ def get_parser(): action="store", dest="account", required=False, - default="P93300606", + default="P93300641", ) parser.add_argument( "--bld-path", @@ -87,18 +87,18 @@ def get_parser(): ) parser.add_argument( "--number-of-nodes", - help="""number of cheyenne nodes requested (required)""", + help="""number of derecho nodes requested (required)""", action="store", dest="number_of_nodes", required=True, ) parser.add_argument( "--tasks-per-node", - help="""number of mpi tasks per node for cheyenne requested (default is 12)""", + help="""number of mpi tasks per node for derecho requested""", action="store", dest="tasks_per_node", required=False, - default="12", + default="128", ) parser.add_argument( "--walltime", @@ -114,7 +114,7 @@ def get_parser(): action="store", dest="queue", required=False, - default="regular", + default="main", ) parser.add_argument( "--scenario", @@ -126,7 +126,7 @@ def get_parser(): ) parser.add_argument( "--jobscript-file", - help="""output jobscript file to be submitted on cheyenne + help="""output jobscript file to be submitted with qsub [default: %(default)s]""", action="store", dest="jobscript_file", diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index bdb2c0fdcb..9b7c278058 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -38,11 +38,11 @@ def get_parser(): action="store", dest="account", required=False, - default="P93300606", + default="P93300641", ) parser.add_argument( "--number-of-nodes", - help="""number of cheyenne nodes requested (required)""", + help="""number of derecho nodes requested (required)""", action="store", dest="number_of_nodes", type=int, @@ -57,7 +57,7 @@ def get_parser(): ) parser.add_argument( "--tasks-per-node", - help="""number of mpi tasks per node for cheyenne requested (required)""", + help="""number of mpi tasks per node for derecho requested (required)""", action="store", dest="tasks_per_node", type=int, @@ -65,15 +65,15 @@ def get_parser(): ) parser.add_argument( "--machine", - help="""currently this recognizes cheyenne, casper, izumi (default + help="""currently this recognizes derecho, casper, izumi (default %(default)s); this needs to be a cime machine, i.e. a machine that has been ported to cime where you can build a cime model; for details see the README in this directory""", action="store", dest="machine", required=False, - choices=["cheyenne", "casper", "izumi"], - default="cheyenne", + choices=["derecho", "casper", "izumi"], + default="derecho", ) parser.add_argument( "--namelist-file", @@ -84,11 +84,11 @@ def get_parser(): ) parser.add_argument( "--jobscript-file", - help="""output jobscript file to be submitted on cheyenne (default: %(default)s)""", + help="""output jobscript file to be submitted with qsub (default: %(default)s)""", action="store", dest="jobscript_file", required=False, - default="mksurfdata_jobscript_single.sh", + default="mksurfdata_jobscript_single", ) return parser @@ -124,11 +124,11 @@ def main(): runfile.write("#PBS -j oe \n") runfile.write("#PBS -k eod \n") runfile.write("#PBS -S /bin/bash \n") - if machine == "cheyenne": + if machine == "derecho": attribs = {"mpilib": "default"} runfile.write("#PBS -l walltime=30:00 \n") runfile.write(f"#PBS -A {account} \n") - runfile.write("#PBS -q regular \n") + runfile.write("#PBS -q main \n") runfile.write( f"#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node} \n" ) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 77b5025740..7a3a8a0962 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -8,6 +8,7 @@ as a mesh file is available for the grid. The subset_data tool allows users to make fsurdat files from existing fsurdat files when a mesh file is unavailable. Generally, users should consider the subset_data tool for generating regional and single-point fsurdat files. + =================== Build Requirements: =================== @@ -58,7 +59,7 @@ Building the executable (working in tools/mksurfdata_esmf) # Before starting, be sure that you have run > ./manage_externals/checkout_externals -# because without it I have come across strange behavior, such as transient +# because without it we have come across strange behavior, such as transient # file generation (1850-2015) that aborts in the 1870s for no apparent reason. > ./gen_mksurfdata_build.sh # For machines with a cime build # Note: The pio_iotype value gets set and written to a simple .txt file @@ -86,7 +87,7 @@ Running for a single submission: # ./gen_mksurfdata_namelist finds all files. # to generate your target jobscript (again --help for instructions): -> ./gen_mksurfdata_jobscript_single --number-of-nodes 24 --tasks-per-node 12 --namelist-file target.namelist +> ./gen_mksurfdata_jobscript_single --number-of-nodes 2 --tasks-per-node 128 --namelist-file target.namelist > qsub mksurfdata_jobscript_single # Read note about regional grids below. @@ -95,10 +96,8 @@ Running for the generation of multiple datasets ======================= # Work in the ctsm_pylib environment, as explained in earlier section. # gen_mksurfdata_jobscript_multi runs ./gen_mksurfdata_namelist for you -# The regional grid 5x5_amazon may fail with 24 nodes. -# Task geometry that worked: #PBS -l select=4:ncpus=36:mpiprocs=4 > ./gen_mksurfdata_jobscript_multi --help -> ./gen_mksurfdata_jobscript_multi --number-of-nodes 24 --scenario all +> ./gen_mksurfdata_jobscript_multi --number-of-nodes 2 --scenario global-present > qsub mksurfdata_jobscript_multi ================ @@ -108,14 +107,11 @@ NOTES ------------------------------------ slevis HAS LISTED ISSUES ENCOUNTERED ------------------------------------ -REMEMBER TO compare against existing fsurdat files in -/glade/p/cesmdata/cseg/inputdata/lnd/clm2/surfdata_map/release-clm5.0.18 0) New 30-sec raw data for soil texture fails. Try requesting more mem. 1) Soil color & texture and ag fire peak month outputs too high in .log TODO? Change frac_o from always 1. 2) Pct lake has chged in the .log bc the old diagnostic omitted mask_i frac_o 3) Slope, stddev have chged in the .log bc the old diag. used frac_o -4) 1x1_brazil min number-of-nodes tested: 4; 10x15 min tested: 3 -------------------------------------- ALL raw dataset .nc FILES MUST BE cdf5 From 7bb22e1639de3ff53651a54216f12467c58d7dbe Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 26 Jan 2024 15:28:01 -0700 Subject: [PATCH 452/614] Update number-of-nodes requested by the Makefile --- tools/mksurfdata_esmf/Makefile | 70 +++++++++++++++++----------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index d9015f8a97..ab4df7d2b2 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -132,15 +132,15 @@ DEBUG: standard : $(STANDARD) global-potveg : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 3 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh global-present : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 3 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh global-present-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh # @@ -149,7 +149,7 @@ global-present-low-res : FORCE ultra_hires : $(ULTRA_HIRES) global-present-ultra-hi-res : FORCE - $(MKSURFDATA) --number-of-nodes 200 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 50 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh # @@ -157,7 +157,7 @@ global-present-ultra-hi-res : FORCE # crop-tropics-present : FORCE - $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh 1x1_brazil-tropics-present : FORCE @@ -175,55 +175,55 @@ crop-tropics-present : FORCE crop : $(CROP) crop-global-present : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-present-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-present-ne16 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-present-ne120 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-present-nldas : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-1850 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-1850-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-1850-ne16 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-1850-ne120 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-hist : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-hist-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-hist-ne16 : FORCE - $(MKSURFDATA) --number-of-nodes 24 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-hist-ne120 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-numa-present : FORCE @@ -273,72 +273,72 @@ crop-global-SSP2-4.5 : crop-global-SSP2-4.5-f09 \ crop-global-SSP2-4.5-mpasa120 crop-global-SSP1-1.9-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP1-2.6-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f19 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f10 : FORCE - $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f45 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-hcru : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-ne3 : FORCE - $(MKSURFDATA) --number-of-nodes 10 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-ne16 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-ne30 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-C96 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-mpasa120 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh # Don't do the high-resolution cases by default... crop-global-SSP2-4.5-hi-res : FORCE - $(MKSURFDATA) --number-of-nodes 96 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP3-7.0-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP4-3.4-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP4-6.0-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP5-8.5-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 48 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh # From 085be209745887216712667bd572e0402d6743b9 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 26 Jan 2024 16:17:12 -0700 Subject: [PATCH 453/614] Mods towards getting the Makefile to work (after first attempt) --- python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 7 +++++-- tools/mksurfdata_esmf/README | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index ca4ea6e12a..ed3dd5d179 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -165,9 +165,12 @@ def main(): abort("Input scenario is NOT in valid_scenarios") # -------------------------- # Determine resolution sets that are referenced in commands + # TODO slevis: When new resolutions become supported in ccs_config, the + # first entry will change to + # "standard_res_no_crop": ["0.9x1.25", "1.9x2.5", "mpasa60", "mpasa60-3conus", "mpasa60-3centralUS"], # -------------------------- resolution_dict = { - "standard_res_no_crop": ["0.9x1.25", "1.9x2.5", "mpasa60", "mpasa60-3conus", "mpasa60-3centralUS"], + "standard_res_no_crop": ["0.9x1.25", "1.9x2.5", "mpasa60"], "f09": ["0.9x1.25"], "f19": ["1.9x2.5"], "hcru": ["360x720cru"], @@ -415,7 +418,7 @@ def main(): sys.argv = [x for x in command.split(" ") if x] main_nml() print(f"generated namelist {namelist}") - output = f'time mpiexec_mpt -p "%g:" -np {n_p} {mksurfdata} < {namelist}' + output = f'time mpiexec_mpt {mksurfdata} < {namelist}' runfile.write(f"{output} \n") check = f"if [ $? != 0 ]; then echo 'Error running resolution {res}'; exit -4; fi" runfile.write(f"{check} \n") diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 7a3a8a0962..7aa5c92588 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -99,6 +99,10 @@ Running for the generation of multiple datasets > ./gen_mksurfdata_jobscript_multi --help > ./gen_mksurfdata_jobscript_multi --number-of-nodes 2 --scenario global-present > qsub mksurfdata_jobscript_multi +# If you are looking to generate all (or a large number of) the datasets or the +# single-point (1x1) datasets, you are best off using the Makefile. For example +> make all # ...or +> make all-subset ================ NOTES From db2820cfa4b504c05b8d3fde1756dd8cc7f3ddf1 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 26 Jan 2024 16:24:29 -0700 Subject: [PATCH 454/614] Mods towards getting the Makefile to work (after 2nd attempt) --- .../ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index ed3dd5d179..0e469ad4fc 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -181,14 +181,14 @@ def main(): "low_res_no_crop": ["10x15", "4x5"], "ultra_hi_res_no_crop": ["mpasa15", "mpasa15-3conus", "mpasa3p75"], "standard_res": ["360x720cru", "0.9x1.25", "1.9x2.5", "C96", "mpasa120"], - "low_res": ["10x15", "4x5", "ne3pg3.np4", "mpasa480"], + "low_res": ["10x15", "4x5", "ne3np4.pg3", "mpasa480"], "nldas_res": ["0.125nldas2"], "5x5_amazon": ["5x5_amazon"], - "ne3": ["ne3pg3.np4"], - "ne16": ["ne16pg3.np4"], - "ne30": ["ne30pg3.np4", "ne30pg2.np4", "ne30.np4"], + "ne3": ["ne3np4.pg3"], + "ne16": ["ne16np4.pg3"], + "ne30": ["ne30np4.pg3", "ne30.np4pg2", "ne30np4"], "ne120": [ - "ne120pg3.np4", + "ne120np4.pg3", "ne0np4.ARCTICGRIS.ne30x8", "ne0np4.ARCTIC.ne30x4", "ne0np4CONUS.ne30x8", From fdff5d64ef3324b27e77d12a51353898f4805704 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 26 Jan 2024 16:28:38 -0700 Subject: [PATCH 455/614] Mods towards getting the Makefile to work (2b) --- python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 0e469ad4fc..3664a63bef 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -418,7 +418,7 @@ def main(): sys.argv = [x for x in command.split(" ") if x] main_nml() print(f"generated namelist {namelist}") - output = f'time mpiexec_mpt {mksurfdata} < {namelist}' + output = f'time mpiexec {mksurfdata} < {namelist}' runfile.write(f"{output} \n") check = f"if [ $? != 0 ]; then echo 'Error running resolution {res}'; exit -4; fi" runfile.write(f"{check} \n") From f3cc3d5ffbb6ffc7305f613bfc9f2b720d547bb6 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 26 Jan 2024 16:36:41 -0700 Subject: [PATCH 456/614] Mods towards getting the Makefile to work (after 3rd attempt) --- python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 3664a63bef..7b26c69a94 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -273,7 +273,7 @@ def main(): ), "crop-global-hist-ne16": ( "--start-year 1850 --end-year 2015 --nosurfdata --res", - "ne16_res", + "ne16", ), "crop-global-hist-ne30": ( "--start-year 1850 --end-year 2015 --nosurfdata --res", From 726531eae55aed1cc1422d6c9cfcca4d68ce680c Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 26 Jan 2024 17:24:03 -0700 Subject: [PATCH 457/614] Mods towards getting the Makefile to work (after 4th attempt) --- .../gen_mksurfdata_jobscript_multi.py | 4 ++-- tools/mksurfdata_esmf/Makefile | 22 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 7b26c69a94..1e7e5d1313 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -186,7 +186,7 @@ def main(): "5x5_amazon": ["5x5_amazon"], "ne3": ["ne3np4.pg3"], "ne16": ["ne16np4.pg3"], - "ne30": ["ne30np4.pg3", "ne30.np4pg2", "ne30np4"], + "ne30": ["ne30np4.pg3", "ne30np4.pg2", "ne30np4"], "ne120": [ "ne120np4.pg3", "ne0np4.ARCTICGRIS.ne30x8", @@ -418,7 +418,7 @@ def main(): sys.argv = [x for x in command.split(" ") if x] main_nml() print(f"generated namelist {namelist}") - output = f'time mpiexec {mksurfdata} < {namelist}' + output = f"time mpiexec {mksurfdata} < {namelist}" runfile.write(f"{output} \n") check = f"if [ $? != 0 ]; then echo 'Error running resolution {res}'; exit -4; fi" runfile.write(f"{check} \n") diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index ab4df7d2b2..51a68b3c7d 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -132,15 +132,15 @@ DEBUG: standard : $(STANDARD) global-potveg : FORCE - $(MKSURFDATA) --number-of-nodes 3 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh global-present : FORCE - $(MKSURFDATA) --number-of-nodes 3 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh global-present-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh # @@ -179,11 +179,11 @@ crop-global-present : FORCE $(BATCHJOBS) $@.sh crop-global-present-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-present-ne16 : FORCE - $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-present-ne120 : FORCE @@ -199,11 +199,11 @@ crop-global-1850 : FORCE $(BATCHJOBS) $@.sh crop-global-1850-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-1850-ne16 : FORCE - $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-1850-ne120 : FORCE @@ -215,11 +215,11 @@ crop-global-hist : FORCE $(BATCHJOBS) $@.sh crop-global-hist-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-hist-ne16 : FORCE - $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-hist-ne120 : FORCE @@ -289,7 +289,7 @@ crop-global-SSP2-4.5-f19 : FORCE $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f10 : FORCE - $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f45 : FORCE @@ -301,7 +301,7 @@ crop-global-SSP2-4.5-hcru : FORCE $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-ne3 : FORCE - $(MKSURFDATA) --number-of-nodes 2 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-ne16 : FORCE From 5a64daf78f026a02e6f82465fcd351fe62c4e0e8 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 26 Jan 2024 18:12:10 -0700 Subject: [PATCH 458/614] Mods towards getting the Makefile to work (after 5th attempt) --- .../gen_mksurfdata_jobscript_multi.py | 4 +++ tools/mksurfdata_esmf/Makefile | 32 +++++++++---------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 1e7e5d1313..d0a8056e7e 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -307,6 +307,10 @@ def main(): "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", "f10", ), + "crop-global-SSP2-4.5-f45": ( + "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", + "f45", + ), "crop-global-SSP2-4.5-ne3": ( "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP2-4.5 --res", "ne3", diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index 51a68b3c7d..747b2c17a7 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -140,7 +140,7 @@ global-present : FORCE $(BATCHJOBS) $@.sh global-present-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh # @@ -179,7 +179,7 @@ crop-global-present : FORCE $(BATCHJOBS) $@.sh crop-global-present-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-present-ne16 : FORCE @@ -187,7 +187,7 @@ crop-global-present-ne16 : FORCE $(BATCHJOBS) $@.sh crop-global-present-ne120 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-present-nldas : FORCE @@ -199,7 +199,7 @@ crop-global-1850 : FORCE $(BATCHJOBS) $@.sh crop-global-1850-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-1850-ne16 : FORCE @@ -207,7 +207,7 @@ crop-global-1850-ne16 : FORCE $(BATCHJOBS) $@.sh crop-global-1850-ne120 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-hist : FORCE @@ -215,7 +215,7 @@ crop-global-hist : FORCE $(BATCHJOBS) $@.sh crop-global-hist-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-hist-ne16 : FORCE @@ -223,7 +223,7 @@ crop-global-hist-ne16 : FORCE $(BATCHJOBS) $@.sh crop-global-hist-ne120 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-numa-present : FORCE @@ -273,15 +273,15 @@ crop-global-SSP2-4.5 : crop-global-SSP2-4.5-f09 \ crop-global-SSP2-4.5-mpasa120 crop-global-SSP1-1.9-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP1-2.6-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f19 : FORCE @@ -289,11 +289,11 @@ crop-global-SSP2-4.5-f19 : FORCE $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f10 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f45 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-hcru : FORCE @@ -326,19 +326,19 @@ crop-global-SSP2-4.5-hi-res : FORCE $(BATCHJOBS) $@.sh crop-global-SSP3-7.0-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP4-3.4-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP4-6.0-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh crop-global-SSP5-8.5-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 $(BATCHJOBS) $@.sh # From f56473b0b29936ff40c29c0231546d63f9b9a111 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 26 Jan 2024 18:43:43 -0700 Subject: [PATCH 459/614] Mods towards getting the Makefile to work (after 6th attempt) "make all" now reaches the end successfully. This does not mean that all datasets get generated successfully, yet. --- tools/mksurfdata_esmf/Makefile | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index 747b2c17a7..e3335f8600 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -81,9 +81,6 @@ STANDARD = \ global-present \ global-present-low-res \ -ULTRA_HIRES = \ - global-present-ultra-hi-res - CROP = \ crop-global-present \ crop-global-present-low-res \ @@ -100,8 +97,10 @@ CROP = \ crop-global-hist-ne120 \ crop-global-future \ -# TODO slevis: ultra-hires temporary to complete ctsm5.2 data generation -all : standard crop all-subset crop-tropics-present ultra-hires +# TODO slevis: ultra-hi-res is temporary while completing ctsm5.2 data generation +# Start with all-subset because user is bound to forget to run +# module load nco before submitting +all : all-subset standard crop crop-tropics-present global-present-ultra-hi-res # These are all the surface datasets generated by subset_data # This runs interactively and does not send jobs to the batch queue @@ -146,8 +145,6 @@ global-present-low-res : FORCE # # Ultra high resolutions (Don't do by default user should select this by hand) # -ultra_hires : $(ULTRA_HIRES) - global-present-ultra-hi-res : FORCE $(MKSURFDATA) --number-of-nodes 50 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh From abea47145f2ceb18f52fd0cfa9a187b1f044231e Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 29 Jan 2024 18:39:39 -0700 Subject: [PATCH 460/614] Updates to help generate all fsurdat/landuse files without crashes --- .../gen_mksurfdata_jobscript_multi.py | 8 +-- tools/mksurfdata_esmf/Makefile | 50 +++++++++---------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index d0a8056e7e..a2b6fde16b 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -178,20 +178,20 @@ def main(): "mpasa120": ["mpasa120"], "f10": ["10x15"], "f45": ["4x5"], - "low_res_no_crop": ["10x15", "4x5"], + "low_res_no_crop": ["4x5", "10x15"], "ultra_hi_res_no_crop": ["mpasa15", "mpasa15-3conus", "mpasa3p75"], "standard_res": ["360x720cru", "0.9x1.25", "1.9x2.5", "C96", "mpasa120"], - "low_res": ["10x15", "4x5", "ne3np4.pg3", "mpasa480"], + "low_res": ["4x5", "10x15", "ne3np4.pg3", "mpasa480"], "nldas_res": ["0.125nldas2"], "5x5_amazon": ["5x5_amazon"], "ne3": ["ne3np4.pg3"], "ne16": ["ne16np4.pg3"], "ne30": ["ne30np4.pg3", "ne30np4.pg2", "ne30np4"], "ne120": [ - "ne120np4.pg3", "ne0np4.ARCTICGRIS.ne30x8", "ne0np4.ARCTIC.ne30x4", "ne0np4CONUS.ne30x8", + "ne120np4.pg3", ], } @@ -390,7 +390,7 @@ def main(): runfile.write(f"#PBS -q {queue} \n") runfile.write(f"#PBS -l walltime={walltime} \n") runfile.write( - f"#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node}:mem=109GB \n" + f"#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node}:mem=218GB \n" ) runfile.write( f"# This is a batch script to run a set of resolutions for mksurfdata_esmf {scenario} \n" diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index e3335f8600..99f599af7b 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -139,7 +139,7 @@ global-present : FORCE $(BATCHJOBS) $@.sh global-present-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 1 --tasks-per-node 64 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh # @@ -154,7 +154,7 @@ global-present-ultra-hi-res : FORCE # crop-tropics-present : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 1 --tasks-per-node 5 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh 1x1_brazil-tropics-present : FORCE @@ -176,7 +176,7 @@ crop-global-present : FORCE $(BATCHJOBS) $@.sh crop-global-present-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 1 --tasks-per-node 64 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-present-ne16 : FORCE @@ -184,7 +184,7 @@ crop-global-present-ne16 : FORCE $(BATCHJOBS) $@.sh crop-global-present-ne120 : FORCE - $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-present-nldas : FORCE @@ -196,7 +196,7 @@ crop-global-1850 : FORCE $(BATCHJOBS) $@.sh crop-global-1850-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 1 --tasks-per-node 64 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-1850-ne16 : FORCE @@ -204,7 +204,7 @@ crop-global-1850-ne16 : FORCE $(BATCHJOBS) $@.sh crop-global-1850-ne120 : FORCE - $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-hist : FORCE @@ -212,7 +212,7 @@ crop-global-hist : FORCE $(BATCHJOBS) $@.sh crop-global-hist-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 1 --tasks-per-node 64 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-hist-ne16 : FORCE @@ -220,7 +220,7 @@ crop-global-hist-ne16 : FORCE $(BATCHJOBS) $@.sh crop-global-hist-ne120 : FORCE - $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-numa-present : FORCE @@ -270,72 +270,72 @@ crop-global-SSP2-4.5 : crop-global-SSP2-4.5-f09 \ crop-global-SSP2-4.5-mpasa120 crop-global-SSP1-1.9-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP1-2.6-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f19 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f10 : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 1 --tasks-per-node 32 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f45 : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 1 --tasks-per-node 64 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-hcru : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-ne3 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-ne16 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-ne30 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-C96 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-mpasa120 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh # Don't do the high-resolution cases by default... crop-global-SSP2-4.5-hi-res : FORCE - $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP3-7.0-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP4-3.4-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP4-6.0-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP5-8.5-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 6 --scenario $@ --jobscript-file $@.sh --walltime 02:00:00 + $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh # From 45e80c74c708845d89a56b6792d3339eff8a68ae Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 30 Jan 2024 16:28:38 -0700 Subject: [PATCH 461/614] Updates to generate fsurdat/landuse files faster --- .../gen_mksurfdata_jobscript_multi.py | 13 ++++- tools/mksurfdata_esmf/Makefile | 48 +++++++++++-------- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index a2b6fde16b..b37b3246fc 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -23,12 +23,14 @@ "crop-global-present-ne16", "crop-global-present-ne30", "crop-global-present-ne120", + "crop-global-present-mpasa480", "crop-global-present-nldas", "crop-global-1850", "crop-global-1850-low-res", "crop-global-1850-ne16", "crop-global-1850-ne30", "crop-global-1850-ne120", + "crop-global-1850-mpasa480", "crop-global-hist", "crop-global-hist-low-res", "crop-global-hist-ne16", @@ -181,7 +183,8 @@ def main(): "low_res_no_crop": ["4x5", "10x15"], "ultra_hi_res_no_crop": ["mpasa15", "mpasa15-3conus", "mpasa3p75"], "standard_res": ["360x720cru", "0.9x1.25", "1.9x2.5", "C96", "mpasa120"], - "low_res": ["4x5", "10x15", "ne3np4.pg3", "mpasa480"], + "low_res": ["4x5", "10x15", "ne3np4.pg3"], + "mpasa480": ["mpasa480"], "nldas_res": ["0.125nldas2"], "5x5_amazon": ["5x5_amazon"], "ne3": ["ne3np4.pg3"], @@ -239,6 +242,10 @@ def main(): "--start-year 2000 --end-year 2000 --res", "ne120", ), + "crop-global-present-mpasa480": ( + "--start-year 2000 --end-year 2000 --res", + "mpasa480", + ), "crop-global-present-nldas": ( "--start-year 2000 --end-year 2000 --res", # TODO slevis: --hirespft uses old data for now, so keep out "nldas_res", @@ -263,6 +270,10 @@ def main(): "--start-year 1850 --end-year 1850 --res", "ne120", ), + "crop-global-1850-mpasa480": ( + "--start-year 1850 --end-year 1850 --res", + "mpasa480", + ), "crop-global-hist": ( "--start-year 1850 --end-year 2015 --nosurfdata --res", "standard_res", diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index 99f599af7b..6a44d96f6d 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -86,11 +86,13 @@ CROP = \ crop-global-present-low-res \ crop-global-present-ne16 \ crop-global-present-ne120 \ + crop-global-present-mpasa480 \ crop-global-present-nldas \ crop-global-1850 \ crop-global-1850-low-res \ crop-global-1850-ne16 \ crop-global-1850-ne120 \ + crop-global-1850-mpasa480 \ crop-global-hist \ crop-global-hist-low-res \ crop-global-hist-ne16 \ @@ -98,8 +100,8 @@ CROP = \ crop-global-future \ # TODO slevis: ultra-hi-res is temporary while completing ctsm5.2 data generation -# Start with all-subset because user is bound to forget to run -# module load nco before submitting +# Start all with all-subset because user is bound to forget to first run +# module load nco all : all-subset standard crop crop-tropics-present global-present-ultra-hi-res # These are all the surface datasets generated by subset_data @@ -187,6 +189,10 @@ crop-global-present-ne120 : FORCE $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh +crop-global-present-mpasa480 : FORCE + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + crop-global-present-nldas : FORCE $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh @@ -207,12 +213,16 @@ crop-global-1850-ne120 : FORCE $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh +crop-global-1850-mpasa480 : FORCE + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + crop-global-hist : FORCE $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh crop-global-hist-low-res : FORCE - $(MKSURFDATA) --number-of-nodes 1 --tasks-per-node 64 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 14 --tasks-per-node 32 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-hist-ne16 : FORCE @@ -270,51 +280,51 @@ crop-global-SSP2-4.5 : crop-global-SSP2-4.5-f09 \ crop-global-SSP2-4.5-mpasa120 crop-global-SSP1-1.9-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 9 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP1-2.6-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 9 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 9 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f19 : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 8 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f10 : FORCE - $(MKSURFDATA) --number-of-nodes 1 --tasks-per-node 32 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 14 --tasks-per-node 32 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f45 : FORCE - $(MKSURFDATA) --number-of-nodes 1 --tasks-per-node 64 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 14 --tasks-per-node 32 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-hcru : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 72 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-ne3 : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 14 --tasks-per-node 32 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-ne16 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 8 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-ne30 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 9 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-C96 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 9 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-mpasa120 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 9 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh # Don't do the high-resolution cases by default... @@ -323,19 +333,19 @@ crop-global-SSP2-4.5-hi-res : FORCE $(BATCHJOBS) $@.sh crop-global-SSP3-7.0-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 9 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP4-3.4-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 9 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP4-6.0-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 9 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP5-8.5-f09 : FORCE - $(MKSURFDATA) --number-of-nodes 1 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 9 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh # From e7e788fa1e468eb3b46028e43db0e0e4db35fd4c Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 31 Jan 2024 13:11:37 -0700 Subject: [PATCH 462/614] Fix latest failure --- tools/mksurfdata_esmf/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index 6a44d96f6d..f5f84a97cf 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -296,7 +296,7 @@ crop-global-SSP2-4.5-f19 : FORCE $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f10 : FORCE - $(MKSURFDATA) --number-of-nodes 14 --tasks-per-node 32 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 + $(MKSURFDATA) --number-of-nodes 8 --tasks-per-node 16 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-SSP2-4.5-f45 : FORCE From 60ab6d38beb2e78c59cbf42d66bec6c5ce1f26de Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 31 Jan 2024 19:16:22 -0700 Subject: [PATCH 463/614] Updates to get missing files generated --- .../gen_mksurfdata_jobscript_multi.py | 5 --- tools/mksurfdata_esmf/Makefile | 36 +++++++++++-------- tools/site_and_regional/default_data.cfg | 8 ++--- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index b37b3246fc..fea144da25 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -35,7 +35,6 @@ "crop-global-hist-low-res", "crop-global-hist-ne16", "crop-global-hist-ne30", - "crop-global-hist-ne120", "crop-global-SSP1-1.9-f09", "crop-global-SSP1-2.6-f09", "crop-global-SSP2-4.5-f09", @@ -290,10 +289,6 @@ def main(): "--start-year 1850 --end-year 2015 --nosurfdata --res", "ne30", ), - "crop-global-hist-ne120": ( - "--start-year 1850 --end-year 2015 --nosurfdata --res", - "ne120", - ), "crop-global-SSP1-1.9-f09": ( "--start-year 1850 --end-year 2100 --nosurfdata --ssp-rcp SSP1-1.9 --res", "f09", diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index f5f84a97cf..6f5bc6e8e6 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -85,18 +85,20 @@ CROP = \ crop-global-present \ crop-global-present-low-res \ crop-global-present-ne16 \ + crop-global-present-ne30 \ crop-global-present-ne120 \ crop-global-present-mpasa480 \ crop-global-present-nldas \ crop-global-1850 \ crop-global-1850-low-res \ crop-global-1850-ne16 \ + crop-global-1850-ne30 \ crop-global-1850-ne120 \ crop-global-1850-mpasa480 \ crop-global-hist \ crop-global-hist-low-res \ crop-global-hist-ne16 \ - crop-global-hist-ne120 \ + crop-global-hist-ne30 \ crop-global-future \ # TODO slevis: ultra-hi-res is temporary while completing ctsm5.2 data generation @@ -107,10 +109,9 @@ all : all-subset standard crop crop-tropics-present global-present-ultra-hi-res # These are all the surface datasets generated by subset_data # This runs interactively and does not send jobs to the batch queue all-subset : \ - 1x1_brazil-tropics-present \ + 1x1_brazil-tropics-1850 \ 1x1_brazil-tropics-historical \ - 1x1_brazil-tropics-transient \ - crop-numa-present \ + crop-numa-1850 \ crop-numa-historical \ crop-smallville \ crop-smallville-historical \ @@ -159,14 +160,11 @@ crop-tropics-present : FORCE $(MKSURFDATA) --number-of-nodes 1 --tasks-per-node 5 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -1x1_brazil-tropics-present : FORCE +1x1_brazil-tropics-1850 : FORCE $(SUBSETDATA_POINT_ALLLU) --create-surface $(SUBSETDATA_1X1_BRAZIL) 1x1_brazil-tropics-historical : FORCE - $(SUBSETDATA_POINT_ALLLU) --create-surface $(SUBSETDATA_1X1_BRAZIL) --cfg-file default_data_1850.cfg - -1x1_brazil-tropics-transient : FORCE - $(SUBSETDATA_POINT_ALLLU) --create-landuse $(SUBSETDATA_1X1_BRAZIL) + $(SUBSETDATA_POINT_ALLLU) --create-landuse $(SUBSETDATA_1X1_BRAZIL) --cfg-file default_data_1850.cfg # # crop @@ -185,6 +183,10 @@ crop-global-present-ne16 : FORCE $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh +crop-global-present-ne30 : FORCE + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + crop-global-present-ne120 : FORCE $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh @@ -209,6 +211,10 @@ crop-global-1850-ne16 : FORCE $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh +crop-global-1850-ne30 : FORCE + $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(BATCHJOBS) $@.sh + crop-global-1850-ne120 : FORCE $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh @@ -218,7 +224,7 @@ crop-global-1850-mpasa480 : FORCE $(BATCHJOBS) $@.sh crop-global-hist : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 72 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh crop-global-hist-low-res : FORCE @@ -226,18 +232,18 @@ crop-global-hist-low-res : FORCE $(BATCHJOBS) $@.sh crop-global-hist-ne16 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 + $(MKSURFDATA) --number-of-nodes 9 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh -crop-global-hist-ne120 : FORCE - $(MKSURFDATA) --number-of-nodes 4 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 +crop-global-hist-ne30 : FORCE + $(MKSURFDATA) --number-of-nodes 9 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh -crop-numa-present : FORCE +crop-numa-1850 : FORCE $(SUBSETDATA_POINT_ALLLU) --create-surface $(SUBSETDATA_1X1_NUMAIA) crop-numa-historical : FORCE - $(SUBSETDATA_POINT_ALLLU) --create-surface $(SUBSETDATA_1X1_NUMAIA) --cfg-file default_data_1850.cfg + $(SUBSETDATA_POINT_ALLLU) --create-landuse $(SUBSETDATA_1X1_NUMAIA) --cfg-file default_data_1850.cfg crop-smallville : FORCE $(SUBSETDATA_POINT) --create-surface $(SUBSETDATA_1X1_SMALL) diff --git a/tools/site_and_regional/default_data.cfg b/tools/site_and_regional/default_data.cfg index 3a25d776a2..d9ad4b7d1c 100644 --- a/tools/site_and_regional/default_data.cfg +++ b/tools/site_and_regional/default_data.cfg @@ -16,13 +16,13 @@ tpqwname = CLMGSWP3v1.TPQW [surfdat] dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -surfdat_16pft = surfdata_0.9x1.25_hist_16pfts_CMIP6_1850-2015_c231103.nc -surfdat_78pft = surfdata_0.9x1.25_hist_78pfts_CMIP6_1850-2015_c231031.nc +surfdat_16pft = surfdata_0.9x1.25_hist_1850_16pfts_c240130.nc +surfdat_78pft = surfdata_0.9x1.25_hist_1850_78pfts_c240130.nc [landuse] dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -landuse_16pft = landuse.timeseries_0.9x1.25_hist_16_CMIP6_1850-2015_c231103.nc -landuse_78pft = landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c231031.nc +landuse_16pft = landuse.timeseries_0.9x1.25_hist_1850-2015_78_c240131.nc +landuse_78pft = landuse.timeseries_0.9x1.25_hist_1850-2015_78_c240131.nc [domain] file = share/domains/domain.lnd.fv0.9x1.25_gx1v7.151020.nc From 2a7d6f95a3c80f2f48faea3c1c6b1e1adf32387c Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 1 Feb 2024 18:33:07 -0700 Subject: [PATCH 464/614] Accounting for fsurdat/landuse filename changes throughout Reran the Makefile for all-subset and it worked. Ran the Python unit tests: PASS Ran the Python sys tests: Expected ERROR: test_one_site (test.test_sys_run_neon.TestSysRunNeon) Could not find all inputdata on any server --- .../README | 28 +++------- .../user_nl_clm | 4 +- .../clm/f09_dec1990Start_GU_LULCC/user_nl_clm | 4 +- .../NEON/FATES/defaults/user_nl_clm | 2 +- .../usermods_dirs/NEON/defaults/user_nl_clm | 2 +- lilac/bld_templates/mosart_in | 2 +- .../modify_singlept_site_neon.py | 6 +-- python/ctsm/subset_data.py | 2 +- .../test/test_sys_regrid_ggcmi_shdates.py | 2 +- python/ctsm/test/test_unit_subset_data.py | 4 +- .../ctsm/test/test_unit_utils_import_coord.py | 2 +- ...default_data.cfg => default_data_2000.cfg} | 8 +-- .../mksurfdata_esmf_bld/.env_mach_specific.sh | 5 +- .../mksurfdata_esmf_bld/env_mach_specific.xml | 52 +++++++++---------- .../ctsm/toolchain/gen_mksurfdata_namelist.py | 2 +- tools/contrib/run_clmtowers | 8 +-- tools/mksurfdata_esmf/Makefile | 43 +++++++-------- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 2 +- tools/modify_input_files/modify_smallville.sh | 10 ++-- ...default_data.cfg => default_data_1850.cfg} | 7 ++- tools/site_and_regional/default_data_2000.cfg | 28 ++++++++++ 21 files changed, 114 insertions(+), 109 deletions(-) rename python/ctsm/test/testinputs/{default_data.cfg => default_data_2000.cfg} (67%) rename tools/site_and_regional/{default_data.cfg => default_data_1850.cfg} (69%) create mode 100644 tools/site_and_regional/default_data_2000.cfg diff --git a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README index 68b1c6c106..32af224ce2 100644 --- a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README +++ b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README @@ -9,30 +9,16 @@ bld/namelist_files/namelist_defaults_ctsm.xml the following two files used in this test are default files for the following options: -fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_1850_c230517.nc' +fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_1850_78pfts_c240130.nc' hgrid="10x15" sim_year="1850" use_crop=".false." irrigate=".true." hgrid="10x15" sim_year="1850" use_crop=".true." -<<<<<<< HEAD -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2015_c230601.nc' -hgrid="10x15" sim_year_range="1850-2000" irrigate=".true." use_vichydro=".true." -hgrid="10x15" sim_year_range="1850-2000" irrigate=".true." -hgrid="10x15" sim_year_range="1850-2000" use_vichydro=".false." -||||||| 576f14d5b -flanduse_timeseries = '/glade/p/cesmdata/cseg/inputdata/lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc' -hgrid="10x15" sim_year_range="1850-2000" use_crop=".true." -hgrid="10x15" rcp="8.5" sim_year_range="1850-2100" use_crop=".true." -hgrid="10x15" rcp="6" sim_year_range="1850-2100" use_crop=".true." -hgrid="10x15" rcp="4.5" sim_year_range="1850-2100" use_crop=".true." -hgrid="10x15" rcp="2.6" sim_year_range="1850-2100" use_crop=".true." -======= -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/landuse.timeseries_10x15_hist_78pfts_CMIP6_simyr1850-2015_c170824.nc' -hgrid="10x15" sim_year_range="1850-2000" use_crop=".true." -hgrid="10x15" rcp="8.5" sim_year_range="1850-2100" use_crop=".true." -hgrid="10x15" rcp="6" sim_year_range="1850-2100" use_crop=".true." -hgrid="10x15" rcp="4.5" sim_year_range="1850-2100" use_crop=".true." -hgrid="10x15" rcp="2.6" sim_year_range="1850-2100" use_crop=".true." ->>>>>>> ctsm5.1.dev163 +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_1850-2100_78pfts_c240131.nc' +-hgrid="10x15" sim_year_range="1850-2000" use_crop=".true." +-hgrid="10x15" rcp="8.5" sim_year_range="1850-2100" use_crop=".true." +-hgrid="10x15" rcp="6" sim_year_range="1850-2100" use_crop=".true." +-hgrid="10x15" rcp="4.5" sim_year_range="1850-2100" use_crop=".true." +-hgrid="10x15" rcp="2.6" sim_year_range="1850-2100" use_crop=".true." This test includes the settings of the decStart test so as to also test the end-of-year transition since it's an IHist case and transient vegetation gets diff --git a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm index 0bd2a29688..9778d139b4 100644 --- a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm @@ -1,2 +1,2 @@ -fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_1850_c230517.nc' -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_hist_78_CMIP6_1850-2015_c230601.nc' +fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_1850_78pfts_c240130.nc' +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_1850-2100_78pfts_c240131.nc' diff --git a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm index 3b8eeaf33e..49b9f30104 100644 --- a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm @@ -1,5 +1,5 @@ ! Specify a dataset that has non-zero Gross Unrepresented Land Use change fields on it ! And turn it on - flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c230601.nc' - fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_78pfts_CMIP6_1850_c230517.nc' + flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc' + fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_1850_78pfts_c240130.nc' do_grossunrep = .true. diff --git a/cime_config/usermods_dirs/NEON/FATES/defaults/user_nl_clm b/cime_config/usermods_dirs/NEON/FATES/defaults/user_nl_clm index 2a6b4d76d5..68127bcb59 100644 --- a/cime_config/usermods_dirs/NEON/FATES/defaults/user_nl_clm +++ b/cime_config/usermods_dirs/NEON/FATES/defaults/user_nl_clm @@ -19,7 +19,7 @@ !---------------------------------------------------------------------------------- flanduse_timeseries = ' ' ! This isn't needed for a non transient case, but will be once we start using transient compsets -fsurdat = "$DIN_LOC_ROOT/lnd/clm2/surfdata_map/NEON/16PFT_mixed/surfdata_1x1_NEON_${NEONSITE}_hist_16pfts_Irrig_CMIP6_simyr2000_c230120.nc" +fsurdat = "$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/NEON/16PFT_mixed/surfdata_1x1_NEON_${NEONSITE}_hist_2000_16pfts_cXXXXXX.nc" ! h1 output stream hist_fincl2 = 'FATES_AUTORESP','FCEV','FCTR','FGEV','FIRA','FSA','FSH','FATES_GPP','FATES_GPP_PF','H2OSOI', diff --git a/cime_config/usermods_dirs/NEON/defaults/user_nl_clm b/cime_config/usermods_dirs/NEON/defaults/user_nl_clm index 419ff0314c..967eac5a1a 100644 --- a/cime_config/usermods_dirs/NEON/defaults/user_nl_clm +++ b/cime_config/usermods_dirs/NEON/defaults/user_nl_clm @@ -19,7 +19,7 @@ !---------------------------------------------------------------------------------- flanduse_timeseries = ' ' ! This isn't needed for a non transient case, but will be once we start using transient compsets -fsurdat = "$DIN_LOC_ROOT/lnd/clm2/surfdata_map/NEON/surfdata_1x1_NEON_${NEONSITE}_hist_78pfts_CMIP6_simyr2000_c230601.nc" +fsurdat = "$DIN_LOC_ROOT/lnd/clm2/surfdata_map/NEON/surfdata_1x1_NEON_${NEONSITE}_hist_2000_78pfts_cXXXXXX.nc" ! h1 output stream hist_fincl2 = 'AR','ELAI','FCEV','FCTR','FGEV','FIRA','FSA','FSH','GPP','H2OSOI', diff --git a/lilac/bld_templates/mosart_in b/lilac/bld_templates/mosart_in index 833e4f10f8..091ec69285 100644 --- a/lilac/bld_templates/mosart_in +++ b/lilac/bld_templates/mosart_in @@ -5,7 +5,7 @@ do_rtm = .true. do_rtmflood = .false. finidat_rtm = " " - frivinp_rtm = "/glade/p/cesmdata/cseg/inputdata/rof/mosart/MOSART_routing_Global_0.5x0.5_c170601.nc" + frivinp_rtm = "/glade/campaign/cesm/cesmdata/cseg/inputdata/rof/mosart/MOSART_routing_Global_0.5x0.5_c170601.nc" ice_runoff = .true. qgwl_runoff_option = "threshold" rtmhist_fexcl1 = "" diff --git a/python/ctsm/site_and_regional/modify_singlept_site_neon.py b/python/ctsm/site_and_regional/modify_singlept_site_neon.py index ae1318e2f8..861e95d00f 100755 --- a/python/ctsm/site_and_regional/modify_singlept_site_neon.py +++ b/python/ctsm/site_and_regional/modify_singlept_site_neon.py @@ -89,7 +89,7 @@ def get_parser(): dest="surf_dir", type=str, required=False, - default="/glade/scratch/" + myname + "/single_point/", + default="/glade/derecho/scratch/" + myname + "/single_point/", ) parser.add_argument( "--out_dir", @@ -101,7 +101,7 @@ def get_parser(): dest="out_dir", type=str, required=False, - default="/glade/scratch/" + myname + "/single_point_neon_updated/", + default="/glade/derecho/scratch/" + myname + "/single_point_neon_updated/", ) parser.add_argument( "--inputdata-dir", @@ -113,7 +113,7 @@ def get_parser(): dest="inputdatadir", type=str, required=False, - default="/glade/p/cesmdata/cseg/inputdata", + default="/glade/campaign/cesm/cesmdata/cseg/inputdata", ) parser.add_argument( "-d", diff --git a/python/ctsm/subset_data.py b/python/ctsm/subset_data.py index 030cea2247..01053f6e1f 100644 --- a/python/ctsm/subset_data.py +++ b/python/ctsm/subset_data.py @@ -76,7 +76,7 @@ process_logging_args, ) -DEFAULTS_CONFIG = "tools/site_and_regional/default_data.cfg" +DEFAULTS_CONFIG = "tools/site_and_regional/default_data_2000.cfg" logger = logging.getLogger(__name__) diff --git a/python/ctsm/test/test_sys_regrid_ggcmi_shdates.py b/python/ctsm/test/test_sys_regrid_ggcmi_shdates.py index 7521ef09a5..4853a140c5 100755 --- a/python/ctsm/test/test_sys_regrid_ggcmi_shdates.py +++ b/python/ctsm/test/test_sys_regrid_ggcmi_shdates.py @@ -53,7 +53,7 @@ def setUp(self): # What is the complete set of input arguments (including script name)? regrid_template_file = os.path.join( - testinputs_path, "surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214.nc" + testinputs_path, "surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.nc" ) self._function_call_list = [ "regrid_ggcmi_shdates", diff --git a/python/ctsm/test/test_unit_subset_data.py b/python/ctsm/test/test_unit_subset_data.py index 37a7f84672..e5e5273596 100755 --- a/python/ctsm/test/test_unit_subset_data.py +++ b/python/ctsm/test/test_unit_subset_data.py @@ -31,7 +31,7 @@ class TestSubsetData(unittest.TestCase): def setUp(self): sys.argv = ["subset_data", "point", "--create-surface"] - DEFAULTS_FILE = os.path.join(os.getcwd(), "ctsm/test/testinputs/default_data.cfg") + DEFAULTS_FILE = os.path.join(os.getcwd(), "ctsm/test/testinputs/default_data_2000.cfg") self.parser = get_parser() self.args = self.parser.parse_args() self.cesmroot = path_to_ctsm_root() @@ -46,7 +46,7 @@ def test_inputdata_setup_files_basic(self): files = setup_files(self.args, self.defaults, self.cesmroot) self.assertEqual( files["fsurf_in"], - "surfdata_0.9x1.25_hist_16pfts_CMIP6_1850-2015_c231031.nc", + "surfdata_0.9x1.25_hist_2000_16pfts_c240130.nc", "fsurf_in filename not whats expected", ) self.assertEqual( diff --git a/python/ctsm/test/test_unit_utils_import_coord.py b/python/ctsm/test/test_unit_utils_import_coord.py index b7ec8f90ec..8e01f30c6e 100755 --- a/python/ctsm/test/test_unit_utils_import_coord.py +++ b/python/ctsm/test/test_unit_utils_import_coord.py @@ -46,7 +46,7 @@ def setUp(self): ) self._2d_lonlat_file = os.path.join( self._testinputs_path, - "surfdata_5x5_amazon_16pfts_Irrig_CMIP6_simyr2000_c171214_modified.nc", + "surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031_modified.nc", ) def tearDown(self): diff --git a/python/ctsm/test/testinputs/default_data.cfg b/python/ctsm/test/testinputs/default_data_2000.cfg similarity index 67% rename from python/ctsm/test/testinputs/default_data.cfg rename to python/ctsm/test/testinputs/default_data_2000.cfg index 07557f271a..cfef3c5a5e 100644 --- a/python/ctsm/test/testinputs/default_data.cfg +++ b/python/ctsm/test/testinputs/default_data_2000.cfg @@ -16,13 +16,13 @@ tpqwname = CLMGSWP3v1.TPQW [surfdat] dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -surfdat_16pft = surfdata_0.9x1.25_hist_16pfts_CMIP6_1850-2015_c231031.nc -surfdat_78pft = surfdata_0.9x1.25_hist_78pfts_CMIP6_1850-2015_c231031.nc +surfdat_16pft = surfdata_0.9x1.25_hist_2000_16pfts_c240130.nc +surfdat_78pft = surfdata_0.9x1.25_hist_2000_78pfts_c240130.nc [landuse] dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -landuse_16pft = landuse.timeseries_0.9x1.25_hist_16_CMIP6_1850-2015_c231031.nc -landuse_78pft = landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c231031.nc +landuse_16pft = landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc +landuse_78pft = landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc [domain] file = share/domains/domain.lnd.fv0.9x1.25_gx1v7.151020.nc diff --git a/python/ctsm/test/testinputs/mksurfdata_esmf_bld/.env_mach_specific.sh b/python/ctsm/test/testinputs/mksurfdata_esmf_bld/.env_mach_specific.sh index 7b797d907a..da0dc4f1bd 100644 --- a/python/ctsm/test/testinputs/mksurfdata_esmf_bld/.env_mach_specific.sh +++ b/python/ctsm/test/testinputs/mksurfdata_esmf_bld/.env_mach_specific.sh @@ -5,13 +5,12 @@ . /glade/u/apps/ch/opt/lmod/7.5.3/lmod/lmod/init/sh module purge module load ncarenv/1.3 python/3.7.9 cmake/3.22.0 intel/19.1.1 esmf_libs mkl -module use /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ +module use /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ module load esmf-8.4.1b02-ncdfio-mpt-O mpt/2.25 netcdf-mpi/4.9.0 pnetcdf/1.12.3 ncarcompilers/0.5.0 pio/2.5.10 export OMP_STACKSIZE=1024M -export TMPDIR=/glade/scratch/erik +export TMPDIR=/glade/derecho/scratch/erik export MPI_TYPE_DEPTH=16 export MPI_USE_ARRAY=None -export TMPDIR=/glade/scratch/erik export COMPILER=intel export MPILIB=mpt export DEBUG=FALSE diff --git a/python/ctsm/test/testinputs/mksurfdata_esmf_bld/env_mach_specific.xml b/python/ctsm/test/testinputs/mksurfdata_esmf_bld/env_mach_specific.xml index a718f1e2a5..0284ee1952 100644 --- a/python/ctsm/test/testinputs/mksurfdata_esmf_bld/env_mach_specific.xml +++ b/python/ctsm/test/testinputs/mksurfdata_esmf_bld/env_mach_specific.xml @@ -46,102 +46,102 @@ nvhpc/22.2 - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ esmf-8.4.1b02-ncdfio-mpt-g - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ esmf-8.4.1b02-ncdfio-mpt-O - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ esmf-8.4.1b02-ncdfio-openmpi-g - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ esmf-8.4.1b02-ncdfio-openmpi-O mpi-serial/2.3.0 - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ esmf-8.4.1b02-ncdfio-mpiuni-g - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/19.1.1/ esmf-8.4.1b02-ncdfio-mpiuni-O - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ esmf-8.4.1b02-ncdfio-mpt-g - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ esmf-8.4.1b02-ncdfio-mpt-O - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ esmf-8.4.1b02-ncdfio-openmpi-g - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ esmf-8.4.1b02-ncdfio-openmpi-O - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ esmf-8.4.1b02-ncdfio-mpiuni-g - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/gnu/10.1.0/ esmf-8.4.1b02-ncdfio-mpiuni-O - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ esmf-8.2.0b23-ncdfio-mpt-g - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ esmf-8.2.0b23-ncdfio-mpt-O - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 esmf-8.4.1b02-ncdfio-mpt-O - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 esmf-8.4.1b02-ncdfio-mpt-g - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 esmf-8.4.1b02-ncdfio-openmpi-O - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 esmf-8.4.1b02-ncdfio-openmpi-g - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ esmf-8.2.0b23-ncdfio-openmpi-g - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ esmf-8.2.0b23-ncdfio-openmpi-O - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ esmf-8.2.0b23-ncdfio-mpiuni-g - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/pgi/20.4/ esmf-8.2.0b23-ncdfio-mpiuni-O - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 esmf-8.4.1.b01-ncdfio-mpiuni-O - /glade/p/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 + /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/nvhpc/22.2 esmf-8.4.1b02-ncdfio-mpiuni-O @@ -207,7 +207,7 @@ 1024M - /glade/scratch/$USER + /glade/derecho/scratch/$USER 16 @@ -224,7 +224,7 @@ false - /glade/scratch/$USER + /glade/derecho/scratch/$USER -1 diff --git a/python/ctsm/toolchain/gen_mksurfdata_namelist.py b/python/ctsm/toolchain/gen_mksurfdata_namelist.py index 7893205763..3532429589 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_namelist.py +++ b/python/ctsm/toolchain/gen_mksurfdata_namelist.py @@ -164,7 +164,7 @@ def get_parser(): """, action="store", dest="input_path", - default="/glade/p/cesm/cseg/inputdata/", + default="/glade/campaign/cesm/cesmdata/inputdata/", ) parser.add_argument( "--vic", diff --git a/tools/contrib/run_clmtowers b/tools/contrib/run_clmtowers index 59b276260f..e4dd2519ff 100755 --- a/tools/contrib/run_clmtowers +++ b/tools/contrib/run_clmtowers @@ -48,13 +48,13 @@ else endif # Set location of your run directories -set rundata = /glade/scratch/oleson +set rundata = /glade/derecho/scratch/oleson # Set the location of your CLM tag set Clm_Tag_Dir = /glade/work/oleson/release-clm5.0.12 # Set the location of your surface datasets and shell commands that were generated by PTCLM. # This will not necessarily be in the same location as the CLM tag that you are running above -#set User_Mods_Dir = /glade/scratch/oleson/release-clm5.0.12 # This is my version for SP simulations -set User_Mods_Dir = /glade/scratch/oleson/release-clm5.0.12.BGC # This is my version for BGC simulations +#set User_Mods_Dir = /glade/derecho/scratch/oleson/release-clm5.0.12 # This is my version for SP simulations +set User_Mods_Dir = /glade/derecho/scratch/oleson/release-clm5.0.12.BGC # This is my version for BGC simulations # What sites to run? # These are the sites that can be evaluated with some combination of level 2 data and synthesis (gap-filled) data @@ -149,7 +149,7 @@ echo $sourcemods # Set some namelist options if required # If you set any of these you will need to also set them below (search on namelist_opts) -#set namelist_opts1 = "paramfile='/glade/p/cgd/tss/people/oleson/modify_param/CLM5_SP_ens_dec_5D_mcalib_psi50BET3_BETKr9_Cropkrmax5e-10_calmbboptleafcn.nc'" +#set namelist_opts1 = "paramfile='/glade/campaign/cgd/tss/people/oleson/modify_param/CLM5_SP_ens_dec_5D_mcalib_psi50BET3_BETKr9_Cropkrmax5e-10_calmbboptleafcn.nc'" #set namelist_opts2 = "baseflow_scalar= 0.001d00" # BGC #set namelist_opts3 = "pot_hmn_ign_counts_alpha= 0.012d00" diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index 6f5bc6e8e6..a0d5fa5445 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -95,27 +95,23 @@ CROP = \ crop-global-1850-ne30 \ crop-global-1850-ne120 \ crop-global-1850-mpasa480 \ - crop-global-hist \ - crop-global-hist-low-res \ - crop-global-hist-ne16 \ - crop-global-hist-ne30 \ crop-global-future \ -# TODO slevis: ultra-hi-res is temporary while completing ctsm5.2 data generation # Start all with all-subset because user is bound to forget to first run # module load nco -all : all-subset standard crop crop-tropics-present global-present-ultra-hi-res +# Usually, include global-present-ultra-hi-res temporarily while +# generating datasets for a new release +all : all-subset standard crop crop-tropics-present # These are all the surface datasets generated by subset_data # This runs interactively and does not send jobs to the batch queue all-subset : \ - 1x1_brazil-tropics-1850 \ - 1x1_brazil-tropics-historical \ - crop-numa-1850 \ - crop-numa-historical \ - crop-smallville \ - crop-smallville-historical \ - crop-smallville-transient \ + 1x1_brazil-present \ + 1x1_brazil-transient \ + 1x1-numa-present \ + 1x1-smallville-present \ + 1x1-smallville-1850 \ + 1x1-smallville-transient \ urban DEBUG: @@ -160,11 +156,11 @@ crop-tropics-present : FORCE $(MKSURFDATA) --number-of-nodes 1 --tasks-per-node 5 --scenario $@ --jobscript-file $@.sh --walltime 01:00:00 $(BATCHJOBS) $@.sh -1x1_brazil-tropics-1850 : FORCE +1x1_brazil-present : FORCE $(SUBSETDATA_POINT_ALLLU) --create-surface $(SUBSETDATA_1X1_BRAZIL) -1x1_brazil-tropics-historical : FORCE - $(SUBSETDATA_POINT_ALLLU) --create-landuse $(SUBSETDATA_1X1_BRAZIL) --cfg-file default_data_1850.cfg +1x1_brazil-transient : FORCE + $(SUBSETDATA_POINT_ALLLU) --create-surface --create-landuse $(SUBSETDATA_1X1_BRAZIL) --cfg-file ../site_and_regional/default_data_1850.cfg # # crop @@ -239,25 +235,22 @@ crop-global-hist-ne30 : FORCE $(MKSURFDATA) --number-of-nodes 9 --scenario $@ --jobscript-file $@.sh --walltime 12:00:00 $(BATCHJOBS) $@.sh -crop-numa-1850 : FORCE +1x1-numa-present : FORCE $(SUBSETDATA_POINT_ALLLU) --create-surface $(SUBSETDATA_1X1_NUMAIA) -crop-numa-historical : FORCE - $(SUBSETDATA_POINT_ALLLU) --create-landuse $(SUBSETDATA_1X1_NUMAIA) --cfg-file default_data_1850.cfg - -crop-smallville : FORCE +1x1-smallville-present : FORCE $(SUBSETDATA_POINT) --create-surface $(SUBSETDATA_1X1_SMALL) # Note that the smallville 1850 dataset is entirely natural vegetation. This # facilitates testing a transient case that starts with no crop, and then later # adds crop (to make sure that it works properly to add crop in a grid cell # where there used to be no crop). -crop-smallville-historical : FORCE - $(SUBSETDATA_POINT) --create-surface $(SUBSETDATA_1X1_SMALL1850) --cfg-file default_data_1850.cfg +1x1-smallville-1850 : FORCE + $(SUBSETDATA_POINT) --create-surface $(SUBSETDATA_1X1_SMALL1850) --cfg-file ../site_and_regional/default_data_1850.cfg # Note (slevis): The next line makes the landuse.timeseries from 1850 to 2015, so also run # modify_smallville.sh to generate three modified landuse.timeseries files needed for testing. -crop-smallville-transient : FORCE +1x1-smallville-transient : FORCE $(SUBSETDATA_POINT) --create-landuse $(SUBSETDATA_1X1_SMALLTRANSIENT) ../modify_input_files/modify_smallville.sh @@ -372,7 +365,7 @@ vancouver : FORCE $(RM) $(VANCOUVER_TMP_FNAME) # NOTE(bja, 2015-01) skip abort on invalid data necessary as of 2015-01. See -# /glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 +# /glade/campaign/cesm/cesmdata/inputdata/lnd/clm2/surfdata_map/README_c141219 urban-alpha : FORCE $(SUBSETDATA_POINT_URBAN) --create-surface $(SUBSETDATA_1X1_URBALPHA) # Set number of nlevurb dimension to 4 for this site diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index 05ec0cafe5..df4bfd43ba 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -796,7 +796,7 @@ subroutine lookup_and_check_err(pioid, varname, fill_val, check_invalid, & write(6,*) 'urban_classes_gcell_o(n,k): ', urban_classes_gcell_o(n,k) if (.not. urban_skip_abort_on_invalid_data_check) then ! NOTE(bja, 2015-01) added to work around a ?bug? noted in - ! /glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/README_c141219 + ! /glade/campaign/cesm/cesmdata/inputdata/lnd/clm2/surfdata_map/README_c141219 call shr_sys_abort() end if end if diff --git a/tools/modify_input_files/modify_smallville.sh b/tools/modify_input_files/modify_smallville.sh index f61231e67c..b88ac32ae9 100755 --- a/tools/modify_input_files/modify_smallville.sh +++ b/tools/modify_input_files/modify_smallville.sh @@ -7,11 +7,11 @@ module load nco # This script runs from the mksurfdata_esmf/Makefile. # When running standalone, it may need "subset_data_single_point/" in front # of each landuse.timeseries file name. - file_to_2015="landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-2015_c$(date +%y%m%d).nc" - file_to_1855="landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-1855_c$(date +%y%m%d).nc" - file_lake="landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynLakes_c$(date +%y%m%d).nc" - file_urban="landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynUrban_c$(date +%y%m%d).nc" - file_pft="landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynPft_c$(date +%y%m%d).nc" + file_to_2015="landuse.timeseries_1x1_smallvilleIA_hist_1850-2015_78pfts_c$(date +%y%m%d).nc" + file_to_1855="landuse.timeseries_1x1_smallvilleIA_hist_1850-1855_78pfts_c$(date +%y%m%d).nc" + file_lake="landuse.timeseries_1x1_smallvilleIA_hist_1850-1855_78pfts_dynLakes_c$(date +%y%m%d).nc" + file_urban="landuse.timeseries_1x1_smallvilleIA_hist_1850-1855_78pfts_dynUrban_c$(date +%y%m%d).nc" + file_pft="landuse.timeseries_1x1_smallvilleIA_hist_1850-1855_78pfts_dynPft_c$(date +%y%m%d).nc" # Trim the file to just the years 1850-1855 ncks -d time,0,5 $file_to_2015 $file_to_1855 diff --git a/tools/site_and_regional/default_data.cfg b/tools/site_and_regional/default_data_1850.cfg similarity index 69% rename from tools/site_and_regional/default_data.cfg rename to tools/site_and_regional/default_data_1850.cfg index d9ad4b7d1c..f631c87e4c 100644 --- a/tools/site_and_regional/default_data.cfg +++ b/tools/site_and_regional/default_data_1850.cfg @@ -1,5 +1,5 @@ [main] -clmforcingindir = /glade/campaign/cesm/cesmdata/cseg/inputdata +clmforcingindir = /glade/campaign/cesm/cesmdata/inputdata [datm_gswp3] dir = atm/datm7/atm_forcing.datm7.GSWP3.0.5d.v1.c170516 @@ -16,13 +16,12 @@ tpqwname = CLMGSWP3v1.TPQW [surfdat] dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -surfdat_16pft = surfdata_0.9x1.25_hist_1850_16pfts_c240130.nc surfdat_78pft = surfdata_0.9x1.25_hist_1850_78pfts_c240130.nc [landuse] dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -landuse_16pft = landuse.timeseries_0.9x1.25_hist_1850-2015_78_c240131.nc -landuse_78pft = landuse.timeseries_0.9x1.25_hist_1850-2015_78_c240131.nc +landuse_78pft = landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc [domain] file = share/domains/domain.lnd.fv0.9x1.25_gx1v7.151020.nc + diff --git a/tools/site_and_regional/default_data_2000.cfg b/tools/site_and_regional/default_data_2000.cfg new file mode 100644 index 0000000000..cfef3c5a5e --- /dev/null +++ b/tools/site_and_regional/default_data_2000.cfg @@ -0,0 +1,28 @@ +[main] +clmforcingindir = /glade/campaign/cesm/cesmdata/cseg/inputdata + +[datm_gswp3] +dir = atm/datm7/atm_forcing.datm7.GSWP3.0.5d.v1.c170516 +domain = domain.lnd.360x720_gswp3.0v1.c170606.nc +solardir = Solar +precdir = Precip +tpqwdir = TPHWL +solartag = clmforc.GSWP3.c2011.0.5x0.5.Solr. +prectag = clmforc.GSWP3.c2011.0.5x0.5.Prec. +tpqwtag = clmforc.GSWP3.c2011.0.5x0.5.TPQWL. +solarname = CLMGSWP3v1.Solar +precname = CLMGSWP3v1.Precip +tpqwname = CLMGSWP3v1.TPQW + +[surfdat] +dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 +surfdat_16pft = surfdata_0.9x1.25_hist_2000_16pfts_c240130.nc +surfdat_78pft = surfdata_0.9x1.25_hist_2000_78pfts_c240130.nc + +[landuse] +dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 +landuse_16pft = landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc +landuse_78pft = landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc + +[domain] +file = share/domains/domain.lnd.fv0.9x1.25_gx1v7.151020.nc From 137ac058f862249f8742cb5edf5b15fc1685d827 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 2 Feb 2024 13:40:04 -0700 Subject: [PATCH 465/614] Correct the automated naming of landuse/fsurdat files --- python/ctsm/toolchain/gen_mksurfdata_namelist.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_namelist.py b/python/ctsm/toolchain/gen_mksurfdata_namelist.py index 3532429589..9d6eecbc9d 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_namelist.py +++ b/python/ctsm/toolchain/gen_mksurfdata_namelist.py @@ -598,7 +598,10 @@ def main(): time_stamp = datetime.today().strftime("%y%m%d") if ssp_rcp == "none": - ssp_rcp_name = "hist" + if pft_years == "PtVg": + ssp_rcp_name = "PtVeg_nourb" + else: + ssp_rcp_name = "hist" else: ssp_rcp_name = ssp_rcp if int(end_year) == int(start_year): @@ -606,7 +609,7 @@ def main(): else: fdyndat = ( f"landuse.timeseries_{res}_{ssp_rcp_name}" - f"_{start_year}-{end_year}_{num_pft}_c{time_stamp}.nc" + f"_{start_year}-{end_year}_{num_pft}pfts_c{time_stamp}.nc" ) prefix = f"surfdata_{res}_{ssp_rcp_name}_{start_year}_{num_pft}pfts_c{time_stamp}." @@ -632,7 +635,7 @@ def main(): gitdescribe = subprocess.check_output("git describe", shell=True).strip() gitdescribe = gitdescribe.decode("utf-8") - # The below two overrides are only used for testing an validation + # The below two overrides are only used for testing and validation # it takes a long time to generate the mapping files # from 1km to the following two resolutions since the output mesh has so few points if res == "10x15": From 741900c09a62429e82bd7a9ca55bf5db43e99090 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 2 Feb 2024 16:10:33 -0700 Subject: [PATCH 466/614] Updates from review with Erik --- .../smallville_dynlakes_monthly/user_nl_clm | 2 +- .../smallville_dynurban_monthly/user_nl_clm | 2 +- python/ctsm/test/test_unit_subset_data.py | 2 +- .../test/testinputs/default_data_2000.cfg | 28 ------------------- 4 files changed, 3 insertions(+), 31 deletions(-) delete mode 100644 python/ctsm/test/testinputs/default_data_2000.cfg diff --git a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm index 21cdd7d89d..5c650032b7 100644 --- a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm @@ -6,4 +6,4 @@ do_transient_lakes = .true. ! Key points are that lake area starts as 0, increases after the first year, then decreases after the second year. ! PCT_CROP is also changed so that PCT_LAKE + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_LAKE in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.) ! Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid. -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynLakes_c240103.nc' +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_hist_1850-1855_78pfts_dynLakes_c240201.nc' diff --git a/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm index adc8364e67..234b4d485f 100644 --- a/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm @@ -7,4 +7,4 @@ do_transient_urban = .true. ! Medium density urban is set to zero to test the memory-saving behavior of PCT_URBAN_MAX. ! PCT_CROP is also changed so that PCT_URBAN + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_URBAN in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.) ! Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid. -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_1850-1855_dynUrban_c240103.nc' +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_hist_1850-1855_78pfts_dynUrban_c240201.nc' diff --git a/python/ctsm/test/test_unit_subset_data.py b/python/ctsm/test/test_unit_subset_data.py index e5e5273596..5f71d85de5 100755 --- a/python/ctsm/test/test_unit_subset_data.py +++ b/python/ctsm/test/test_unit_subset_data.py @@ -31,7 +31,7 @@ class TestSubsetData(unittest.TestCase): def setUp(self): sys.argv = ["subset_data", "point", "--create-surface"] - DEFAULTS_FILE = os.path.join(os.getcwd(), "ctsm/test/testinputs/default_data_2000.cfg") + DEFAULTS_FILE = os.path.join(os.getcwd(), "../tools/site_and_regional/default_data_2000.cfg") self.parser = get_parser() self.args = self.parser.parse_args() self.cesmroot = path_to_ctsm_root() diff --git a/python/ctsm/test/testinputs/default_data_2000.cfg b/python/ctsm/test/testinputs/default_data_2000.cfg deleted file mode 100644 index cfef3c5a5e..0000000000 --- a/python/ctsm/test/testinputs/default_data_2000.cfg +++ /dev/null @@ -1,28 +0,0 @@ -[main] -clmforcingindir = /glade/campaign/cesm/cesmdata/cseg/inputdata - -[datm_gswp3] -dir = atm/datm7/atm_forcing.datm7.GSWP3.0.5d.v1.c170516 -domain = domain.lnd.360x720_gswp3.0v1.c170606.nc -solardir = Solar -precdir = Precip -tpqwdir = TPHWL -solartag = clmforc.GSWP3.c2011.0.5x0.5.Solr. -prectag = clmforc.GSWP3.c2011.0.5x0.5.Prec. -tpqwtag = clmforc.GSWP3.c2011.0.5x0.5.TPQWL. -solarname = CLMGSWP3v1.Solar -precname = CLMGSWP3v1.Precip -tpqwname = CLMGSWP3v1.TPQW - -[surfdat] -dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -surfdat_16pft = surfdata_0.9x1.25_hist_2000_16pfts_c240130.nc -surfdat_78pft = surfdata_0.9x1.25_hist_2000_78pfts_c240130.nc - -[landuse] -dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -landuse_16pft = landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc -landuse_78pft = landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc - -[domain] -file = share/domains/domain.lnd.fv0.9x1.25_gx1v7.151020.nc From 859f4e0404ddcb0e78cd2198ccc1327115a39ed0 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 2 Feb 2024 16:11:01 -0700 Subject: [PATCH 467/614] Updated namelist_defaults_ctsm.xml --- bld/namelist_files/namelist_defaults_ctsm.xml | 230 ++++++++---------- 1 file changed, 97 insertions(+), 133 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index a30161090d..1eceb7791c 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1217,182 +1217,152 @@ attributes from the config_cache.xml file (with keys converted to upper-case). -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_16pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_2000_16pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_16pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_2000_16pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_16pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_2000_16pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_16pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_2000_16pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_16pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_2000_16pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_16pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_2000_16pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_16pfts_CMIP6_2000_c230530.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_2000_16pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_2000_16pfts_cXXXXXX.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_5x5_amazon_hist_2000_16pfts_2000_cXXXXXX.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_5x5_amazon_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_2000_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_78pfts_CMIP6_2000_c231026.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_2000_78pfts_cXXXXXX.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_5x5_amazon_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_2000_78pfts_c240131.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_2000_78pfts_c240131.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_78pfts_CMIP6_2000_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_2000_78pfts_c240131.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4.pg3_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.125nldas2_hist_16pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.125nldas2_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_360x720_78pfts_CMIP6_2000_cXXXXX.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_360x720cru_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_numaIA_hist_78pfts_CMIP6_2000_c231026.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_numaIA_hist_2000_78pfts_cXXXXXX.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_2000_c231026.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_2000_78pfts_cXXXXXX.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa480_hist_2000_78pfts_c231103.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa480_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa120_hist_2000_78pfts_c231026.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa120_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa60_hist_2000_16pfts_c231103.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa60_hist_2000_16pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15_hist_2000_16pfts_c231026.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15-conus_hist_2000_16pfts_c231026.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15_hist_2000_16pfts_c240130.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15-3conus_hist_2000_16pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa3p75_hist_2000_16pfts_c231026.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa3p75_hist_2000_16pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_2000_78pfts_c231103.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4.pg3_hist_2000_78pfts_c231103.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_78pfts_CMIP6_2000_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_78pfts_CMIP6_2000_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4.pg3_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4.pg3_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x8_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x8_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTIC.ne30x4_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTIC.ne30x4_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4CONUS.ne30x8_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4CONUS.ne30x8_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_vancouverCAN_hist_2000_78pfts_c240110.nc - +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_vancouverCAN_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_mexicocityMEX_hist_2000_78pfts_c240110.nc - +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_mexicocityMEX_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_urbanc_alpha_hist_2000_78pfts_c240110.nc - +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_urbanc_alpha_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_360x720_78pfts_CMIP6_1850_cXXXXX.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_360x720cru_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa480_hist_1850_78pfts_c231103.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa480_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa120_hist_1850_78pfts_c231026.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa120_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_1850_78pfts_c240131.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_1850_78pfts_c240131.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_1850_78pfts_c240131.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c231006.nc - - +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_78pfts_CMIP6_1850_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_78pfts_CMIP6_1850_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_78pfts_CMIP6_1850_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_78pfts_CMIP6_1850_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_78pfts_CMIP6_1850_c240103.nc - +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_1850_78pfts_c240131.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/ssurfdata_1x1_numaIA_hist_78pfts_CMIP6_1850_c240110.nc - +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_numaIA_hist_1850_78pfts_c240131.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_78pfts_CMIP6_1850_c231026.nc - +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_1850_78pfts_c240131.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c231103.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4.pg3_hist_1850_78pfts_c231103.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_78pfts_CMIP6_1850_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_78pfts_CMIP6_1850_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4.pg3_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4.pg3_hist_78pfts_CMIP6_1850_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4.pg3_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x8_hist_1850_78pfts_c231103.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x8_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTIC.ne30x4_hist_78pfts_CMIP6_2000_c230517.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTIC.ne30x4_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4CONUS.ne30x8_hist_1850_78pfts_c231103.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4CONUS.ne30x8_hist_1850_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_PtVeg_nourb_16pfts_cXXXXXX.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_PtVeg_nourb_16pfts_c240130.nc @@ -1414,95 +1384,89 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c --> lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c231103.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP2-4.5_1850-2100_78_c231103.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_4x5_SSP2-4.5_1850-2100_16pfts_cXXXXXX.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_4x5_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP2-4.5_1850-2100_78pfts_c240130.nc + + +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_4x5_SSP2-4.5_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_1850-2100_78pfts_c240131.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_360x720cru_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_360x720cru_SSP2-4.5_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_brazil_hist_78_CMIP6_1850-2015_c240110.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_numaIA_hist_1850-2015_78pfts_cXXXXXX.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_brazil_SSP2-4.5_1850-2100_78pfts_c240201.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_mpasa120_SSP2-4.5_1850-2100_78pfts_c231026.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_mpasa120_SSP2-4.5_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne3np4.pg3_SSP2-4.5_1850-2100_78pfts_c231027.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne3np4.pg3_SSP2-4.5_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne16np4.pg3_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne16np4.pg3_SSP2-4.5_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np.pg3_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np4.pg3_SSP2-4.5_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_C96_SSP2-4.5_1850-2100_78pfts_c231026.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_C96_SSP2-4.5_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_hist_78_CMIP6_1850-1855_c240103.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_hist_1850-1855_78pfts_c240201.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP1-2.6_1850-2100_78pfts_c231103.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP1-2.6_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c231103.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP2-4.5_1850-2100_78_c231103.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_4x5_SSP2-4.5_1850-2100_16pfts_cXXXXXX.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_4x5_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_78_CMIP6_1850-2100_c230517.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_360x720cru_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP2-4.5_1850-2100_78pfts_c240130.nc + + +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_4x5_SSP2-4.5_1850-2100_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_1850-2100_78pfts_c240131.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_360x720cru_SSP2-4.5_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_brazil_hist_78_CMIP6_1850-2015_c240110.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_numaIA_hist_1850-2015_78pfts_cXXXXXX.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_brazil_SSP2-4.5_1850-2100_78pfts_c240201.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_mpasa120_SSP2-4.5_1850-2100_78pfts_c231026.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_mpasa120_SSP2-4.5_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne3np4.pg3_SSP2-4.5_1850-2100_78pfts_c231027.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne3np4.pg3_SSP2-4.5_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne16np4.pg3_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne16np4.pg3_SSP2-4.5_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np.pg3_SSP2-4.5_1850-2100_78pfts_cXXXXXX.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np4.pg3_SSP2-4.5_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_C96_SSP2-4.5_1850-2100_78pfts_c231026.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_C96_SSP2-4.5_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP3-7.0_78_CMIP6_1850-2100_c230517.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP3-7.0_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP4-6.0_78_CMIP6_1850-2100_c230517.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP4-6.0_1850-2100_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP5-8.5_78_CMIP6_1850-2100_c230517.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP5-8.5_1850-2100_78pfts_c240130.nc From c0b4782bb27278323d5f37bf3c8a7d7c3ceb9f35 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 2 Feb 2024 17:10:53 -0700 Subject: [PATCH 468/614] Second pass at namelist_defaults_ctsm.xml --- bld/namelist_files/namelist_defaults_ctsm.xml | 70 ++++++++----------- python/ctsm/test/test_unit_subset_data.py | 4 +- 2 files changed, 33 insertions(+), 41 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 1eceb7791c..5944014372 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1215,41 +1215,46 @@ attributes from the config_cache.xml file (with keys converted to upper-case). - - + + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_2000_16pfts_c240130.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_2000_16pfts_c240130.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_2000_16pfts_c240130.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_2000_16pfts_c240130.nc - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_2000_16pfts_c240130.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_2000_16pfts_c240130.nc - lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_2000_16pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_2000_16pfts_cXXXXXX.nc - - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_5x5_amazon_hist_2000_78pfts_c240130.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa60_hist_2000_16pfts_c240130.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15_hist_2000_16pfts_c240130.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15-3conus_hist_2000_16pfts_c240130.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa3p75_hist_2000_16pfts_c240130.nc - + + + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_2000_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_2000_78pfts_c240130.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_2000_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_2000_78pfts_c240130.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_2000_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_2000_78pfts_c240130.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_2000_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_2000_78pfts_cXXXXXX.nc - - + + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_2000_78pfts_c240201.nc + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_5x5_amazon_hist_2000_78pfts_c240130.nc @@ -1262,8 +1267,7 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_2000_78pfts_c240131.n lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4.pg3_hist_2000_78pfts_c240130.nc - - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.125nldas2_hist_2000_78pfts_c240130.nc @@ -1272,24 +1276,13 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_360x720cru_hist_2000_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_2000_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_numaIA_hist_2000_78pfts_cXXXXXX.nc - - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_2000_78pfts_cXXXXXX.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_numaIA_hist_2000_78pfts_c240201.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa480_hist_2000_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa120_hist_2000_78pfts_c240130.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa60_hist_2000_16pfts_c240130.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15_hist_2000_16pfts_c240130.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15-3conus_hist_2000_16pfts_c240130.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa3p75_hist_2000_16pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_2000_78pfts_c240130.nc @@ -1341,10 +1334,7 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_1850_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_1850_78pfts_c240131.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_numaIA_hist_1850_78pfts_c240131.nc - - + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_1850_78pfts_c240131.nc @@ -1361,7 +1351,7 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTIC.ne30x4_hist_1850_78pfts_ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4CONUS.ne30x8_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_PtVeg_nourb_16pfts_c240130.nc diff --git a/python/ctsm/test/test_unit_subset_data.py b/python/ctsm/test/test_unit_subset_data.py index 5f71d85de5..29271f6c8a 100755 --- a/python/ctsm/test/test_unit_subset_data.py +++ b/python/ctsm/test/test_unit_subset_data.py @@ -31,7 +31,9 @@ class TestSubsetData(unittest.TestCase): def setUp(self): sys.argv = ["subset_data", "point", "--create-surface"] - DEFAULTS_FILE = os.path.join(os.getcwd(), "../tools/site_and_regional/default_data_2000.cfg") + DEFAULTS_FILE = os.path.join( + os.getcwd(), "../tools/site_and_regional/default_data_2000.cfg" + ) self.parser = get_parser() self.args = self.parser.parse_args() self.cesmroot = path_to_ctsm_root() From b7b433e1ea723cfa5fb0a7b260eedbba9a92f3d9 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 2 Feb 2024 18:28:16 -0700 Subject: [PATCH 469/614] Update build-namelist_test.pl based on new available datasets --- bld/unit_testers/build-namelist_test.pl | 31 +++++++++++++++++++------ 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 644e28a002..1da3aa15f2 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,10 +163,10 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 2815; +my $ntests = 2587; if ( defined($opts{'compare'}) ) { - $ntests += 1965; + $ntests += 1737; } plan( tests=>$ntests ); @@ -433,7 +433,7 @@ sub cat_and_create_namelistinfile { "-res ne0np4CONUS.ne30x8 -bgc sp -use_case 2000_control -namelist '&a start_ymd=20130101/' -lnd_tuning_mode ${phys}_cam6.0", "-res 1.9x2.5 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=20030101/' -lnd_tuning_mode ${phys}_cam6.0", "-res 1.9x2.5 -bgc sp -use_case 2010_control -namelist '&a start_ymd=20100101/' -lnd_tuning_mode ${phys}_cam6.0", - "-res 1x1_brazil -bgc fates -no-megan -use_case 2000_control -lnd_tuning_mode ${phys}_CRUv7", + "-res 1x1_brazil -no-megan -use_case 2000_control -lnd_tuning_mode ${phys}_CRUv7", "-res C96 -bgc sp -use_case 2010_control -namelist '&a start_ymd=20100101/' -lnd_tuning_mode ${phys}_cam6.0", "-res ne0np4.ARCTIC.ne30x4 -bgc sp -use_case 2000_control -namelist '&a start_ymd=20130101/' -lnd_tuning_mode ${phys}_cam6.0", ) { @@ -1350,8 +1350,8 @@ sub cat_and_create_namelistinfile { print "========================================================================\n"; # Check for ALL resolutions with CLM50SP -my @resolutions = ( "1x1_brazil", "1x1_mexicocityMEX", "1x1_vancouverCAN", "1x1_urbanc_alpha", "5x5_amazon", "360x720cru", "0.125nldas2", "10x15", "4x5", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne16np4.pg3", "ne30np4", "ne30np4.pg2", "ne30np4.pg3", "ne120np4.pg3", "ne0np4CONUS.ne30x8", "ne0np4.ARCTIC.ne30x4", "ne0np4.ARCTICGRIS.ne30x8", "C96", "mpasa480", "mpasa120", "mpasa60", "mpasa15", "mpasa15-conus", "mpasa3p75" ); -my @only2000_resolutions = ( "1x1_brazil", "1x1_mexicocityMEX", "1x1_vancouverCAN", "1x1_urbanc_alpha", "5x5_amazon", "0.125nldas2", "mpasa60", "mpasa15", "mpasa15-conus", "mpasa3p75" ); +my @resolutions = ( "360x720cru", "10x15", "4x5", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne16np4.pg3", "ne30np4", "ne30np4.pg2", "ne30np4.pg3", "ne120np4.pg3", "ne0np4CONUS.ne30x8", "ne0np4.ARCTIC.ne30x4", "ne0np4.ARCTICGRIS.ne30x8", "C96", "mpasa480", "mpasa120" ); +my @only2000_resolutions = ( "1x1_numaIA", "1x1_brazil", "1x1_mexicocityMEX", "1x1_vancouverCAN", "1x1_urbanc_alpha", "5x5_amazon", "0.125nldas2", "mpasa60", "mpasa15", "mpasa15-conus", "mpasa3p75" ); my @regional; foreach my $res ( @resolutions ) { chomp($res); @@ -1449,7 +1449,24 @@ sub cat_and_create_namelistinfile { print "==================================================\n"; # Check for crop resolutions -my @crop_res = ( "1x1_numaIA", "1x1_smallvilleIA", "4x5", "10x15", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne30np4", "ne30np4.pg3", "C96", "mpasa120" ); +my $crop1850_res = "1x1_smallvilleIA"; +$options = "-bgc bgc -crop -res $crop1850_res -use_case 1850_control -envxml_dir ."; +&make_env_run(); +eval{ system( "$bldnml $options > $tempfile 2>&1 " ); }; +is( $@, '', "$options" ); +$cfiles->checkfilesexist( "$options", $mode ); +$cfiles->shownmldiff( "default", "standard" ); +if ( defined($opts{'compare'}) ) { + $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode ); + $cfiles->dodiffonfile( "$real_par_file", "$options", $mode ); + $cfiles->comparefiles( "$options", $mode, $opts{'compare'} ); +} +if ( defined($opts{'generate'}) ) { + $cfiles->copyfiles( "$options", $mode ); +} +&cleanup(); + +my @crop_res = ( "1x1_numaIA", "4x5", "10x15", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne30np4", "ne30np4.pg3", "C96", "mpasa120" ); foreach my $res ( @crop_res ) { $options = "-bgc bgc -crop -res $res -envxml_dir ."; &make_env_run(); @@ -1673,7 +1690,7 @@ sub cat_and_create_namelistinfile { &cleanup(); # Run FATES mode for several resolutions and configurations my $clmoptions = "-bgc fates -envxml_dir . -no-megan"; - my @clmres = ( "1x1_brazil", "5x5_amazon", "4x5", "1.9x2.5" ); + my @clmres = ( "4x5", "1.9x2.5" ); foreach my $res ( @clmres ) { $options = "-res $res -clm_start_type cold"; my @edoptions = ( "-use_case 2000_control", From 831c1aaa90917d7bbb103acacd549bda6a78408a Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Sun, 4 Feb 2024 13:50:00 -0700 Subject: [PATCH 470/614] Update time stamp of several 1x1 files in namelist_defaults_ctsm.xml --- bld/namelist_files/namelist_defaults_ctsm.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 5944014372..6de094fd63 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1297,11 +1297,11 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4CONUS.ne30x8_hist_2000_78pfts_c2 -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_vancouverCAN_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_vancouverCAN_hist_2000_78pfts_c240201.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_mexicocityMEX_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_mexicocityMEX_hist_2000_78pfts_c240201.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_urbanc_alpha_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_urbanc_alpha_hist_2000_78pfts_c240201.nc @@ -1333,9 +1333,9 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_1850_78pfts_c240130.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_1850_78pfts_c240131.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_1850_78pfts_c240201.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_1850_78pfts_c240131.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_1850_78pfts_c240201.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c240130.nc From 365ac278fdb23a11348d7807792edc375736ced4 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Sun, 4 Feb 2024 15:43:36 -0700 Subject: [PATCH 471/614] Make convert_ocean_to_land = .true. the default and improve error msg --- bld/namelist_files/namelist_defaults_ctsm.xml | 3 +-- src/main/subgridWeightsMod.F90 | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 6de094fd63..d1083213b5 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1865,8 +1865,7 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c .false. -.false. -.true. +.true. .false. .true. diff --git a/src/main/subgridWeightsMod.F90 b/src/main/subgridWeightsMod.F90 index 94c7fec504..45e7d32306 100644 --- a/src/main/subgridWeightsMod.F90 +++ b/src/main/subgridWeightsMod.F90 @@ -696,6 +696,10 @@ subroutine check_weights (bounds, active_only) write(iulog,*) 'The matching input grid cell had some non-zero-weight subgrid type' write(iulog,*) 'that is not present in memory in the new run.' write(iulog,*) ' ' + write(iulog,*) 'If you are using a ctsm5.2 or later fsurdat file containing' + write(iulog,*) 'PCT_OCEAN > 0, then you may solve the error by setting' + write(iulog,*) 'convert_ocean_to_land = .true.' + write(iulog,*) ' ' call endrun(msg=errMsg(sourcefile, __LINE__)) end if From 6ea25a7f42b08aa6873c5c909492518a9c286197 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Sun, 4 Feb 2024 17:48:43 -0700 Subject: [PATCH 472/614] Update testlist with tests needed in ctsm_sci test-suite --- cime_config/testdefs/testlist_clm.xml | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 6dfa8b7372..2a672b784b 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -13,8 +13,8 @@ - + @@ -471,8 +471,8 @@ - + @@ -590,10 +590,9 @@ - From e5617d0714491ab76c8acf65d3c921b083f1e725 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Sun, 4 Feb 2024 19:45:08 -0700 Subject: [PATCH 473/614] Changes toward getting the MKSURFDATAESMF test to work --- cime_config/SystemTests/mksurfdataesmf.py | 6 +++--- cime_config/testdefs/testlist_clm.xml | 2 +- python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 12f904ae72..4e9800024e 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -38,11 +38,11 @@ def __init__(self, case): self._jobscript = os.path.join(self._get_caseroot(), "mksurfdata_jobscript_single") self._fsurdat_namelist = os.path.join( self._get_caseroot(), - f"surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.namelist", + f"surfdata_{self._res}_hist_{self._model_yr}_78pfts_c{time_stamp}.namelist", ) self._fsurdat_nc = os.path.join( self._get_caseroot(), - f"surfdata_{self._res}_hist_78pfts_CMIP6_{self._model_yr}_c{time_stamp}.nc", + f"surfdata_{self._res}_hist_{self._model_yr}_78pfts_c{time_stamp}.nc", ) self._TestStatus_log_path = os.path.join(self._get_caseroot(), "TestStatus.log") @@ -64,7 +64,7 @@ def build_phase(self, sharedlib_only=False, model_only=False): nml_script_path = os.path.join(self._tool_path, "gen_mksurfdata_namelist") gen_jobscript_path = os.path.join(self._tool_path, "gen_mksurfdata_jobscript_single") gen_mksurfdata_namelist = f"{nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}" - gen_mksurfdata_jobscript = f"{gen_jobscript_path} --number-of-nodes 12 --tasks-per-node 12 --namelist-file {self._fsurdat_namelist}" + gen_mksurfdata_jobscript = f"{gen_jobscript_path} --number-of-nodes 1 --tasks-per-node 64 --namelist-file {self._fsurdat_namelist}" # Rm tool_bld and build executable that will generate fsurdat try: diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 2a672b784b..eaa7fc7324 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -3558,7 +3558,7 @@ - + diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 9b7c278058..e0d6c32fee 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -126,7 +126,7 @@ def main(): runfile.write("#PBS -S /bin/bash \n") if machine == "derecho": attribs = {"mpilib": "default"} - runfile.write("#PBS -l walltime=30:00 \n") + runfile.write("#PBS -l walltime=59:00 \n") runfile.write(f"#PBS -A {account} \n") runfile.write("#PBS -q main \n") runfile.write( From c5786a37f7b9fc19935f7ed0b2e86949de105959 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 5 Feb 2024 10:47:00 -0700 Subject: [PATCH 474/614] Remove ctsm_sci tests that run with clm45 --- cime_config/testdefs/testlist_clm.xml | 90 --------------------------- 1 file changed, 90 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index eaa7fc7324..4bfe8cc12c 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -32,24 +32,6 @@ - - - - - - - - - - - - - - - - - - @@ -1243,24 +1225,6 @@ - - - - - - - - - - - - - - - - - - @@ -1341,42 +1305,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1386,24 +1314,6 @@ - - - - - - - - - - - - - - - - - - From 4e1098b79fd748247613f80cf79b9c3e6b5541c1 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 5 Feb 2024 11:29:49 -0700 Subject: [PATCH 475/614] Correction that I hope will fix this test failure PEND SMS_D_Lm1_Mmpi-serial.CLM_USRDAT.I1PtClm50SpRs.derecho_gnu.clm-USUMB_nuopc SHAREDLIB_BUILD --- cime_config/buildnml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/buildnml b/cime_config/buildnml index 99ff61bc5d..69952c3968 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -85,7 +85,7 @@ def buildnml(case, caseroot, compname): "clm4_5_QIAN": "clm4_5_CRUv7", "clm4_5_NLDAS2": "clm4_5_CRUv7", "clm4_5_ERA5": "clm4_5_CRUv7", - "clm5_0_1PT": "clm5_0_GSWP3", + "clm5_0_1PT": "clm5_0_GSWP3v1", "clm5_0_QIAN": "clm5_0_GSWP3v1", "clm5_0_NLDAS2": "clm5_0_GSWP3v1", "clm5_0_ERA5": "clm5_0_GSWP3v1", From 6e072290a1a0e198c5dec94e3d060a5908361390 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 5 Feb 2024 16:45:29 -0700 Subject: [PATCH 476/614] Corrections based on ctsm_sci failures --- cime_config/testdefs/testlist_clm.xml | 20 ++++++------------- .../include_user_mods | 2 +- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 4bfe8cc12c..ffdb1374e8 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -14,7 +14,7 @@ - + @@ -189,7 +189,7 @@ - + @@ -549,6 +549,7 @@ + @@ -599,15 +600,6 @@ - - - - - - - - - @@ -653,7 +645,7 @@ - + @@ -662,7 +654,7 @@ - + @@ -1547,7 +1539,7 @@ - + diff --git a/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_1979Start/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_1979Start/include_user_mods index 1c3eece35d..aa76c52034 100644 --- a/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_1979Start/include_user_mods +++ b/cime_config/testdefs/testmods_dirs/clm/clm51cam6LndTuningMode_1979Start/include_user_mods @@ -1 +1 @@ -../clm50cam6LndTuningMode +../clm51cam6LndTuningMode From 73fd801c93d377e75cc4b17905fa01af6e00996f Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 6 Feb 2024 12:13:22 -0700 Subject: [PATCH 477/614] Corrections to testlist_clm.xml for izumi aux_clm suite --- cime_config/testdefs/testlist_clm.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index ffdb1374e8..272b732043 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -1668,7 +1668,7 @@ - + @@ -1677,7 +1677,7 @@ - + From e196a1efd56dd29126a2ef179174f42a1be03f55 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 6 Feb 2024 13:02:31 -0700 Subject: [PATCH 478/614] Correction to the previous commit's compsets --- cime_config/testdefs/testlist_clm.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 272b732043..18f5e60bbe 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -1668,7 +1668,7 @@ - + @@ -1677,7 +1677,7 @@ - + From c40bacd19387f8912d859855b5853d100223131d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 6 Feb 2024 18:09:11 -0700 Subject: [PATCH 479/614] Updates to modify_singlept_site_neon.py to generate 5.2 fsurdat files --- .../site_and_regional/modify_singlept_site_neon.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/ctsm/site_and_regional/modify_singlept_site_neon.py b/python/ctsm/site_and_regional/modify_singlept_site_neon.py index 861e95d00f..db4a942c20 100755 --- a/python/ctsm/site_and_regional/modify_singlept_site_neon.py +++ b/python/ctsm/site_and_regional/modify_singlept_site_neon.py @@ -56,10 +56,10 @@ # -- valid neon sites -valid_neon_sites = glob.glob( +valid = glob.glob( os.path.join(path_to_ctsm_root(), "cime_config", "usermods_dirs", "NEON", "[!d]*") ) - +valid_neon_sites = [x[-4:] for x in valid] # last 4 letters in each string def get_parser(): """ @@ -220,9 +220,9 @@ def find_surffile(surf_dir, site_name, pft_16): """ if pft_16: - sf_name = "surfdata_1x1_NEON_" + site_name + "*hist_16pfts_Irrig_CMIP6_simyr2000_*.nc" + sf_name = "surfdata_1x1_NEON_" + site_name + "*hist_2000_16pfts*.nc" else: - sf_name = "surfdata_1x1_NEON_" + site_name + "*hist_78pfts_CMIP6_simyr2000_*.nc" + sf_name = "surfdata_1x1_NEON_" + site_name + "*hist_2000_78pfts*.nc" print(os.path.join(surf_dir, sf_name)) surf_file = sorted(glob.glob(os.path.join(surf_dir, sf_name))) @@ -279,7 +279,7 @@ def find_soil_structure(args, surf_file): # print (f_1.attrs["Soil_texture_raw_data_file_name"]) clm_input_dir = os.path.join(args.inputdatadir, "lnd/clm2/rawdata/") - surf_soildepth_file = os.path.join(clm_input_dir, f_1.attrs["Soil_texture_raw_data_file_name"]) + surf_soildepth_file = os.path.join(clm_input_dir, f_1.attrs["soil_texture_lookup_raw_data_file_name"]) if os.path.exists(surf_soildepth_file): print( From 7d4a5d8b6cff6e7f8242e54144b76ff9f6423edf Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 6 Feb 2024 18:24:20 -0700 Subject: [PATCH 480/614] Updates to NEON fsurdat file names in namelist_defaults and elsewhere --- bld/namelist_files/namelist_defaults_ctsm.xml | 4 ++-- cime_config/usermods_dirs/NEON/FATES/defaults/user_nl_clm | 2 +- cime_config/usermods_dirs/NEON/defaults/user_nl_clm | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index d1083213b5..cbf201648e 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1356,9 +1356,9 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4CONUS.ne30x8_hist_1850_78pfts_c2 -lnd/clm2/surfdata_esmf/NEON/16PFT_mixed/surfdata_1x1_NEON_${NEONSITE}_hist_2000_16pfts_cXXXXXX.nc +lnd/clm2/surfdata_esmf/NEON/16PFT_mixed/surfdata_1x1_NEON_${NEONSITE}_hist_2000_16pfts_c240206.nc -lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_${NEONSITE}_hist_2000_78pfts_cXXXXXX.nc +lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_${NEONSITE}_hist_2000_78pfts_c240206.nc hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. @@ -1008,14 +1003,6 @@ attributes from the config_cache.xml file (with keys converted to upper-case). >lnd/clm2/initdata_map/clmi.I1850Clm50BgcCrop-ciso.1366-01-01.0.9x1.25_gx1v7_simyr1850_c200428.nc -lnd/clm2/initdata_map/clmi.B1850Clm50BgcCrop.0161-01-01.0.9x1.25_gx1v7_simyr1850_c200729.nc - - - Date: Fri, 9 Feb 2024 10:30:44 -0700 Subject: [PATCH 483/614] Remove USUMB test and testmods as obsolete --- cime_config/testdefs/testlist_clm.xml | 14 -------------- .../clm/USUMB_mct/include_user_mods | 1 - .../testmods_dirs/clm/USUMB_mct/shell_commands | 18 ------------------ .../testmods_dirs/clm/USUMB_mct/user_nl_clm | 4 ---- .../clm/USUMB_nuopc/include_user_mods | 1 - .../clm/USUMB_nuopc/shell_commands | 15 --------------- .../testmods_dirs/clm/USUMB_nuopc/user_nl_clm | 4 ---- 7 files changed, 57 deletions(-) delete mode 100644 cime_config/testdefs/testmods_dirs/clm/USUMB_mct/include_user_mods delete mode 100755 cime_config/testdefs/testmods_dirs/clm/USUMB_mct/shell_commands delete mode 100644 cime_config/testdefs/testmods_dirs/clm/USUMB_mct/user_nl_clm delete mode 100644 cime_config/testdefs/testmods_dirs/clm/USUMB_nuopc/include_user_mods delete mode 100755 cime_config/testdefs/testmods_dirs/clm/USUMB_nuopc/shell_commands delete mode 100644 cime_config/testdefs/testmods_dirs/clm/USUMB_nuopc/user_nl_clm diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 18f5e60bbe..f224b4062a 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -2346,20 +2346,6 @@ - - - - - - - - - - - - - - diff --git a/cime_config/testdefs/testmods_dirs/clm/USUMB_mct/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/USUMB_mct/include_user_mods deleted file mode 100644 index 3e31b09d16..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/USUMB_mct/include_user_mods +++ /dev/null @@ -1 +0,0 @@ -../CLM1PTStartDate diff --git a/cime_config/testdefs/testmods_dirs/clm/USUMB_mct/shell_commands b/cime_config/testdefs/testmods_dirs/clm/USUMB_mct/shell_commands deleted file mode 100755 index e410197c3d..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/USUMB_mct/shell_commands +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# shell commands to execute xmlchange commands written by PTCLMmkdata: which is now unsupported -./xmlchange CLM_USRDAT_NAME=1x1pt_US-UMB -./xmlchange DATM_CLMNCEP_YR_START=1999 -./xmlchange DATM_CLMNCEP_YR_END=2006 -# Comment this out if NINST_LND is greater than 1 (see: http://bugs.cgd.ucar.edu/show_bug.cgi?id=2521) -./xmlchange MPILIB=mpi-serial -./xmlchange ATM_DOMAIN_PATH='$DIN_LOC_ROOT/lnd/clm2/PTCLMmydatafiles.c171024/1x1pt_US-UMB' -./xmlchange LND_DOMAIN_PATH='$DIN_LOC_ROOT/lnd/clm2/PTCLMmydatafiles.c171024/1x1pt_US-UMB' -./xmlchange ATM_DOMAIN_FILE=domain.lnd.1x1pt_US-UMB_navy.171024.nc -./xmlchange LND_DOMAIN_FILE=domain.lnd.1x1pt_US-UMB_navy.171024.nc -./xmlchange --append CLM_BLDNML_OPTS='-mask navy -no-crop' -./xmlchange CALENDAR=GREGORIAN -./xmlchange DOUT_S=FALSE -./xmlchange ATM_NCPL=24 -./xmlchange RUN_STARTDATE=1999-01-01 -./xmlchange DATM_CLMNCEP_YR_ALIGN=1999 -./xmlchange DIN_LOC_ROOT_CLMFORC='$DIN_LOC_ROOT/lnd/clm2/PTCLMmydatafiles.c171024' diff --git a/cime_config/testdefs/testmods_dirs/clm/USUMB_mct/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/USUMB_mct/user_nl_clm deleted file mode 100644 index 8bb7848d49..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/USUMB_mct/user_nl_clm +++ /dev/null @@ -1,4 +0,0 @@ -! user_nl_clm namelist options written by PTCLMmkdata, which is no longer available - fsurdat = '$DIN_LOC_ROOT/lnd/clm2/PTCLMmydatafiles.c171024/1x1pt_US-UMB/surfdata_1x1pt_US-UMB_16pfts_Irrig_CMIP6_simyr2000_c171024.nc' - hist_nhtfrq = 0 - hist_mfilt = 1200 diff --git a/cime_config/testdefs/testmods_dirs/clm/USUMB_nuopc/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/USUMB_nuopc/include_user_mods deleted file mode 100644 index 3e31b09d16..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/USUMB_nuopc/include_user_mods +++ /dev/null @@ -1 +0,0 @@ -../CLM1PTStartDate diff --git a/cime_config/testdefs/testmods_dirs/clm/USUMB_nuopc/shell_commands b/cime_config/testdefs/testmods_dirs/clm/USUMB_nuopc/shell_commands deleted file mode 100755 index 43fe16a192..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/USUMB_nuopc/shell_commands +++ /dev/null @@ -1,15 +0,0 @@ -# shell commands to execute xmlchange commands written by PTCLMmkdata: which is now unsupported -./xmlchange CLM_USRDAT_NAME=1x1pt_US-UMB -./xmlchange DATM_YR_START=1999 -./xmlchange DATM_YR_END=2006 -# Comment this out if NINST_LND is greater than 1 (see: http://bugs.cgd.ucar.edu/show_bug.cgi?id=2521) -./xmlchange MPILIB=mpi-serial -./xmlchange --append CLM_BLDNML_OPTS='-mask navy -no-crop' -./xmlchange CALENDAR=GREGORIAN -./xmlchange DOUT_S=FALSE -./xmlchange ATM_NCPL=24 -./xmlchange RUN_STARTDATE=1999-01-01 -./xmlchange DATM_YR_ALIGN=1999 -./xmlchange DIN_LOC_ROOT_CLMFORC='$DIN_LOC_ROOT/lnd/clm2/PTCLMmydatafiles.c171024' -./xmlchange PTS_LON=275.2862 -./xmlchange PTS_LAT=45.5598 diff --git a/cime_config/testdefs/testmods_dirs/clm/USUMB_nuopc/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/USUMB_nuopc/user_nl_clm deleted file mode 100644 index 8bb7848d49..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/USUMB_nuopc/user_nl_clm +++ /dev/null @@ -1,4 +0,0 @@ -! user_nl_clm namelist options written by PTCLMmkdata, which is no longer available - fsurdat = '$DIN_LOC_ROOT/lnd/clm2/PTCLMmydatafiles.c171024/1x1pt_US-UMB/surfdata_1x1pt_US-UMB_16pfts_Irrig_CMIP6_simyr2000_c171024.nc' - hist_nhtfrq = 0 - hist_mfilt = 1200 From 1692b65005aaf1cd2fadb07fa2ccafd31dda5c1e Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 9 Feb 2024 13:30:35 -0700 Subject: [PATCH 484/614] Correct references to mpasa15-3 grid and fix RXCROPMATURITY test --- bld/namelist_files/namelist_defaults_ctsm.xml | 4 ++-- bld/unit_testers/build-namelist_test.pl | 2 +- cime_config/SystemTests/rxcropmaturity.py | 1 + cime_config/testdefs/testlist_clm.xml | 2 +- python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 89a6ec551c..c46a86f92c 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1215,8 +1215,8 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_2000_16pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15_hist_2000_16pfts_c240130.nc - -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15-3conus_hist_2000_16pfts_c240130.nc + +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15-3_hist_2000_16pfts_c240130.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa3p75_hist_2000_16pfts_c240130.nc diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 1da3aa15f2..a393e6f56b 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -1351,7 +1351,7 @@ sub cat_and_create_namelistinfile { # Check for ALL resolutions with CLM50SP my @resolutions = ( "360x720cru", "10x15", "4x5", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne16np4.pg3", "ne30np4", "ne30np4.pg2", "ne30np4.pg3", "ne120np4.pg3", "ne0np4CONUS.ne30x8", "ne0np4.ARCTIC.ne30x4", "ne0np4.ARCTICGRIS.ne30x8", "C96", "mpasa480", "mpasa120" ); -my @only2000_resolutions = ( "1x1_numaIA", "1x1_brazil", "1x1_mexicocityMEX", "1x1_vancouverCAN", "1x1_urbanc_alpha", "5x5_amazon", "0.125nldas2", "mpasa60", "mpasa15", "mpasa15-conus", "mpasa3p75" ); +my @only2000_resolutions = ( "1x1_numaIA", "1x1_brazil", "1x1_mexicocityMEX", "1x1_vancouverCAN", "1x1_urbanc_alpha", "5x5_amazon", "0.125nldas2", "mpasa60", "mpasa15", "mpasa15-3", "mpasa3p75" ); my @regional; foreach my $res ( @resolutions ) { chomp($res); diff --git a/cime_config/SystemTests/rxcropmaturity.py b/cime_config/SystemTests/rxcropmaturity.py index 5d3b07bfbf..acb63bb000 100644 --- a/cime_config/SystemTests/rxcropmaturity.py +++ b/cime_config/SystemTests/rxcropmaturity.py @@ -328,6 +328,7 @@ def _create_config_file_evenlysplitcrop(self): cfg_out.write("PCT_GLACIER = 0.0\n") cfg_out.write("PCT_WETLAND = 0.0\n") cfg_out.write("PCT_LAKE = 0.0\n") + cfg_out.write("PCT_OCEAN = 0.0\n") cfg_out.write("PCT_URBAN = 0.0 0.0 0.0\n") def _run_check_rxboth_run(self): diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index f224b4062a..a49af9dcf4 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -189,7 +189,7 @@ - + diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index fea144da25..5aece9d290 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -180,7 +180,7 @@ def main(): "f10": ["10x15"], "f45": ["4x5"], "low_res_no_crop": ["4x5", "10x15"], - "ultra_hi_res_no_crop": ["mpasa15", "mpasa15-3conus", "mpasa3p75"], + "ultra_hi_res_no_crop": ["mpasa15", "mpasa15-3", "mpasa3p75"], "standard_res": ["360x720cru", "0.9x1.25", "1.9x2.5", "C96", "mpasa120"], "low_res": ["4x5", "10x15", "ne3np4.pg3"], "mpasa480": ["mpasa480"], From 22bebe778b6c9c3d3c60c2b70e8d1b5767a32000 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 9 Feb 2024 13:39:36 -0700 Subject: [PATCH 485/614] Change two intel tests to gnu to get around issue 130... https://github.com/ESMCI/ccs_config_cesm/issues/130 --- cime_config/testdefs/testlist_clm.xml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index a49af9dcf4..8073422fd3 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -2234,9 +2234,7 @@ - - - + @@ -2630,8 +2628,7 @@ - - + From 34012d3ae6992daed1df6690c12339dbbdfb821d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 9 Feb 2024 19:49:20 -0700 Subject: [PATCH 486/614] PE layout that worked for hcru & remove ssp4 test --- cime_config/testdefs/testlist_clm.xml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 8073422fd3..aaa2dab847 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -108,7 +108,7 @@ - + @@ -2502,15 +2502,6 @@ - - - - - - - - - From b72fc24c5255e236796cb381f46a6792acfe6ad8 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 12 Feb 2024 10:42:18 -0700 Subject: [PATCH 487/614] Use P36x128 for the two mpasa15 grids --- cime_config/testdefs/testlist_clm.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index aaa2dab847..8a27ec31d1 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -180,7 +180,7 @@ - + @@ -189,7 +189,7 @@ - + From 1f4611fb7ac77410e25c92de85f1859e1ca6488a Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 13 Feb 2024 16:09:00 -0700 Subject: [PATCH 488/614] Adding SMS_Ld12_Mmpi-serial.1x1_urbanc_alpha... to the expected fails I found no evidence of this test having been run before when serching in /glade/campaign/cgd/tss/ctsm_baselines/ The test's datm.streams.xml lists 16 files of which only two exist in the corresponding datm directory (whether I look in /glade/campaign or /glade/p), so this test possibly never worked. --- cime_config/testdefs/ExpectedTestFails.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index a24299855e..174829a41e 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -28,6 +28,14 @@ --> + + + + FAIL + Not opened yet but first posted here: https://github.com/ESCOMP/CTSM/pull/2318#discussion_r1484696000 + + + From 494ad7c93a778c3c9e4eb14cf6f530ca82619765 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 15 Feb 2024 12:23:25 -0700 Subject: [PATCH 489/614] Updating expected failures (+ adding an unrelated comment) --- cime_config/testdefs/ExpectedTestFails.xml | 18 +++++++++--------- src/biogeochem/CNDVEstablishmentMod.F90 | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index 174829a41e..d1ccd918a7 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -29,6 +29,13 @@ + + + FAIL + #2370 + + + FAIL @@ -179,17 +186,10 @@ - - - PEND - #1045 - - - - PEND - #1045 + RUN + #2261 diff --git a/src/biogeochem/CNDVEstablishmentMod.F90 b/src/biogeochem/CNDVEstablishmentMod.F90 index 461b01b869..9606b7bbe2 100644 --- a/src/biogeochem/CNDVEstablishmentMod.F90 +++ b/src/biogeochem/CNDVEstablishmentMod.F90 @@ -55,6 +55,7 @@ subroutine Establishment(bounds, & ! ! !LOCAL VARIABLES: integer :: g,l,c,p,m ! indices + ! TODO slevis: Is begg - endg backwards in the next line? integer :: fn, filterg(bounds%begg-bounds%endg+1) ! local gridcell filter for error check ! ! gridcell level variables From dee1224b98d22df540cbe2291abc5c6a96119261 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 16 Feb 2024 18:45:12 -0700 Subject: [PATCH 490/614] Correct a typo in .git-blame-ignore-revs --- .git-blame-ignore-revs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 5061dcea0e..887d27c308 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -35,6 +35,6 @@ c7b7ca1d94ac19abb9ecea9fb5b712ddbdd6645d b565b55ce7a9f8d812a573d716a5fd3d78cfea81 fdf72cd011e2ba318987a1e100efc5a1847c9d04 de9a30bfbbec36f9dcacc4380005ab596da47af4 -cda0cf1412212e6f4363e6e8eb39f74c944b454d` +cda0cf1412212e6f4363e6e8eb39f74c944b454d aa04d1f7d86cc2503b98b7e2b2d84dbfff6c316b 6c6f57e948bfa31e60b383536cc21663fedb8b70 From f1e6c9960571b110c2b9fa629ff00655b7fc015e Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 16 Feb 2024 19:38:07 -0700 Subject: [PATCH 491/614] File name corrections --- tools/modify_input_files/modify_smallville.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/modify_input_files/modify_smallville.sh b/tools/modify_input_files/modify_smallville.sh index b88ac32ae9..4dc7c58e9b 100755 --- a/tools/modify_input_files/modify_smallville.sh +++ b/tools/modify_input_files/modify_smallville.sh @@ -7,14 +7,14 @@ module load nco # This script runs from the mksurfdata_esmf/Makefile. # When running standalone, it may need "subset_data_single_point/" in front # of each landuse.timeseries file name. - file_to_2015="landuse.timeseries_1x1_smallvilleIA_hist_1850-2015_78pfts_c$(date +%y%m%d).nc" - file_to_1855="landuse.timeseries_1x1_smallvilleIA_hist_1850-1855_78pfts_c$(date +%y%m%d).nc" - file_lake="landuse.timeseries_1x1_smallvilleIA_hist_1850-1855_78pfts_dynLakes_c$(date +%y%m%d).nc" - file_urban="landuse.timeseries_1x1_smallvilleIA_hist_1850-1855_78pfts_dynUrban_c$(date +%y%m%d).nc" - file_pft="landuse.timeseries_1x1_smallvilleIA_hist_1850-1855_78pfts_dynPft_c$(date +%y%m%d).nc" + file_to_2100="landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-2100_78pfts_c$(date +%y%m%d).nc" + file_to_1855="landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_c$(date +%y%m%d).nc" + file_lake="landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_dynLakes_c$(date +%y%m%d).nc" + file_urban="landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_dynUrban_c$(date +%y%m%d).nc" + file_pft="landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_dynPft_c$(date +%y%m%d).nc" # Trim the file to just the years 1850-1855 -ncks -d time,0,5 $file_to_2015 $file_to_1855 +ncks -d time,0,5 $file_to_2100 $file_to_1855 # Replace all values in the LAKE and CROP variables ncap2 -s "PCT_LAKE=array(0.,0.,PCT_CROP); PCT_LAKE={0.,50.,25.,25.,25.,25.} ; PCT_LAKE_MAX=array(50.,50.,PCT_CROP_MAX); PCT_CROP=array(0.,0.,PCT_LAKE); PCT_CROP={0.,25.,12.,12.,12.,12.}; PCT_CROP_MAX=array(25.,25.,PCT_LAKE_MAX)" $file_to_1855 $file_lake From 25fa3514ffbb823f15a1376d3a02dfe8585b7bee Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 20 Feb 2024 17:42:04 -0700 Subject: [PATCH 492/614] Update namelist_defaults_ctsm.xml and other files with ctsm5.2 datasets --- bld/namelist_files/namelist_defaults_ctsm.xml | 168 +++++++++--------- .../README | 4 +- .../user_nl_clm | 4 +- .../clm/f09_dec1990Start_GU_LULCC/user_nl_clm | 4 +- .../smallville_dynlakes_monthly/user_nl_clm | 2 +- .../smallville_dynurban_monthly/user_nl_clm | 2 +- python/ctsm/test/test_unit_subset_data.py | 2 +- tools/site_and_regional/default_data_1850.cfg | 4 +- tools/site_and_regional/default_data_2000.cfg | 8 +- 9 files changed, 99 insertions(+), 99 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 04588ac66a..b80fad1d45 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1206,142 +1206,142 @@ attributes from the config_cache.xml file (with keys converted to upper-case). -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_2000_16pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_2000_16pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_2000_16pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_2000_16pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_2000_16pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_2000_16pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_2000_16pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_2000_16pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa60_hist_2000_16pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa60_hist_2000_16pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15_hist_2000_16pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15_hist_2000_16pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15-3_hist_2000_16pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15-3_hist_2000_16pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa3p75_hist_2000_16pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa3p75_hist_2000_16pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_2000_78pfts_c240201.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_5x5_amazon_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_5x5_amazon_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_2000_78pfts_c240131.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_2000_78pfts_c240131.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_2000_78pfts_c240131.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4.pg3_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4.pg3_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.125nldas2_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.125nldas2_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_360x720cru_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_360x720cru_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_numaIA_hist_2000_78pfts_c240201.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_numaIA_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa480_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa480_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa120_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa120_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4.pg3_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4.pg3_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x8_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x8_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTIC.ne30x4_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTIC.ne30x4_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4CONUS.ne30x8_hist_2000_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4CONUS.ne30x8_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_vancouverCAN_hist_2000_78pfts_c240201.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_vancouverCAN_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_mexicocityMEX_hist_2000_78pfts_c240201.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_mexicocityMEX_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_urbanc_alpha_hist_2000_78pfts_c240201.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_urbanc_alpha_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_360x720cru_hist_1850_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_360x720cru_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_1850_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_1850_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1.9x2.5_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_1850_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_1850_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa480_hist_1850_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa480_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa120_hist_1850_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa120_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_1850_78pfts_c240131.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_1850_78pfts_c240131.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg2_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_1850_78pfts_c240131.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne30np4.pg3_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_1850_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_1850_78pfts_c240201.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_1850_78pfts_c240201.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4.pg3_hist_1850_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne16np4.pg3_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4.pg3_hist_1850_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne120np4.pg3_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x8_hist_1850_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTICGRIS.ne30x8_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTIC.ne30x4_hist_1850_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4.ARCTIC.ne30x4_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4CONUS.ne30x8_hist_1850_78pfts_c240130.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4CONUS.ne30x8_hist_1850_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_PtVeg_nourb_16pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_PtVeg_nourb_1850_16pfts_c240216.nc @@ -1363,89 +1363,89 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c --> lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP2-4.5_1850-2100_78pfts_c240130.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_4x5_SSP2-4.5_1850-2100_78pfts_c240130.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_4x5_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_1850-2100_78pfts_c240131.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_360x720cru_SSP2-4.5_1850-2100_78pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_360x720cru_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_brazil_SSP2-4.5_1850-2100_78pfts_c240201.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_brazil_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_mpasa120_SSP2-4.5_1850-2100_78pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_mpasa120_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne3np4.pg3_SSP2-4.5_1850-2100_78pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne3np4.pg3_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne16np4.pg3_SSP2-4.5_1850-2100_78pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne16np4.pg3_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np4.pg3_SSP2-4.5_1850-2100_78pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np4.pg3_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_C96_SSP2-4.5_1850-2100_78pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_C96_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_hist_1850-1855_78pfts_c240201.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP1-2.6_1850-2100_78pfts_c240130.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP1-2.6_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP2-4.5_1850-2100_78pfts_c240130.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1.9x2.5_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_4x5_SSP2-4.5_1850-2100_78pfts_c240130.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_4x5_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_1850-2100_78pfts_c240131.nc + >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_360x720cru_SSP2-4.5_1850-2100_78pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_360x720cru_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_brazil_SSP2-4.5_1850-2100_78pfts_c240201.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_brazil_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_mpasa120_SSP2-4.5_1850-2100_78pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_mpasa120_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne3np4.pg3_SSP2-4.5_1850-2100_78pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne3np4.pg3_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne16np4.pg3_SSP2-4.5_1850-2100_78pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne16np4.pg3_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np4.pg3_SSP2-4.5_1850-2100_78pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_ne30np4.pg3_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_C96_SSP2-4.5_1850-2100_78pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_C96_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP3-7.0_1850-2100_78pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP3-7.0_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP4-6.0_1850-2100_78pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP4-6.0_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP5-8.5_1850-2100_78pfts_c240130.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP5-8.5_1850-2100_78pfts_c240216.nc diff --git a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README index 32af224ce2..dbd0696317 100644 --- a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README +++ b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/README @@ -9,11 +9,11 @@ bld/namelist_files/namelist_defaults_ctsm.xml the following two files used in this test are default files for the following options: -fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_1850_78pfts_c240130.nc' +fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_1850_78pfts_c240216.nc' hgrid="10x15" sim_year="1850" use_crop=".false." irrigate=".true." hgrid="10x15" sim_year="1850" use_crop=".true." -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_1850-2100_78pfts_c240131.nc' +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_1850-2100_78pfts_c240216.nc' -hgrid="10x15" sim_year_range="1850-2000" use_crop=".true." -hgrid="10x15" rcp="8.5" sim_year_range="1850-2100" use_crop=".true." -hgrid="10x15" rcp="6" sim_year_range="1850-2100" use_crop=".true." diff --git a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm index 9778d139b4..d7be01280b 100644 --- a/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/collapse_pfts_78_to_16_decStart_f10/user_nl_clm @@ -1,2 +1,2 @@ -fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_1850_78pfts_c240130.nc' -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_1850-2100_78pfts_c240131.nc' +fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_10x15_hist_1850_78pfts_c240216.nc' +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_10x15_SSP2-4.5_1850-2100_78pfts_c240216.nc' diff --git a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm index 49b9f30104..0dbc0b4942 100644 --- a/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/f09_dec1990Start_GU_LULCC/user_nl_clm @@ -1,5 +1,5 @@ ! Specify a dataset that has non-zero Gross Unrepresented Land Use change fields on it ! And turn it on - flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc' - fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_1850_78pfts_c240130.nc' + flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240216.nc' + fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_0.9x1.25_hist_1850_78pfts_c240216.nc' do_grossunrep = .true. diff --git a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm index 5c650032b7..ac5ae1f67a 100644 --- a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm @@ -6,4 +6,4 @@ do_transient_lakes = .true. ! Key points are that lake area starts as 0, increases after the first year, then decreases after the second year. ! PCT_CROP is also changed so that PCT_LAKE + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_LAKE in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.) ! Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid. -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_hist_1850-1855_78pfts_dynLakes_c240201.nc' +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_dynLakes_c240216.nc' diff --git a/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm index 234b4d485f..51bb1193eb 100644 --- a/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm @@ -7,4 +7,4 @@ do_transient_urban = .true. ! Medium density urban is set to zero to test the memory-saving behavior of PCT_URBAN_MAX. ! PCT_CROP is also changed so that PCT_URBAN + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_URBAN in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.) ! Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid. -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_hist_1850-1855_78pfts_dynUrban_c240201.nc' +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_dynUrban_c240216.nc' diff --git a/python/ctsm/test/test_unit_subset_data.py b/python/ctsm/test/test_unit_subset_data.py index 29271f6c8a..1994a29102 100755 --- a/python/ctsm/test/test_unit_subset_data.py +++ b/python/ctsm/test/test_unit_subset_data.py @@ -48,7 +48,7 @@ def test_inputdata_setup_files_basic(self): files = setup_files(self.args, self.defaults, self.cesmroot) self.assertEqual( files["fsurf_in"], - "surfdata_0.9x1.25_hist_2000_16pfts_c240130.nc", + "surfdata_0.9x1.25_hist_2000_16pfts_c240216.nc", "fsurf_in filename not whats expected", ) self.assertEqual( diff --git a/tools/site_and_regional/default_data_1850.cfg b/tools/site_and_regional/default_data_1850.cfg index f631c87e4c..47cb71ee87 100644 --- a/tools/site_and_regional/default_data_1850.cfg +++ b/tools/site_and_regional/default_data_1850.cfg @@ -16,11 +16,11 @@ tpqwname = CLMGSWP3v1.TPQW [surfdat] dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -surfdat_78pft = surfdata_0.9x1.25_hist_1850_78pfts_c240130.nc +surfdat_78pft = surfdata_0.9x1.25_hist_1850_78pfts_c240216.nc [landuse] dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -landuse_78pft = landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc +landuse_78pft = landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240216.nc [domain] file = share/domains/domain.lnd.fv0.9x1.25_gx1v7.151020.nc diff --git a/tools/site_and_regional/default_data_2000.cfg b/tools/site_and_regional/default_data_2000.cfg index cfef3c5a5e..0ba7f8758b 100644 --- a/tools/site_and_regional/default_data_2000.cfg +++ b/tools/site_and_regional/default_data_2000.cfg @@ -16,13 +16,13 @@ tpqwname = CLMGSWP3v1.TPQW [surfdat] dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -surfdat_16pft = surfdata_0.9x1.25_hist_2000_16pfts_c240130.nc -surfdat_78pft = surfdata_0.9x1.25_hist_2000_78pfts_c240130.nc +surfdat_16pft = surfdata_0.9x1.25_hist_2000_16pfts_c240216.nc +surfdat_78pft = surfdata_0.9x1.25_hist_2000_78pfts_c240216.nc [landuse] dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -landuse_16pft = landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc -landuse_78pft = landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240130.nc +landuse_16pft = landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240216.nc +landuse_78pft = landuse.timeseries_0.9x1.25_SSP2-4.5_1850-2100_78pfts_c240216.nc [domain] file = share/domains/domain.lnd.fv0.9x1.25_gx1v7.151020.nc From 8fb79c3e2d186aefd9ee10cf6351e84488d6ce17 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 21 Feb 2024 14:43:50 -0700 Subject: [PATCH 493/614] New update to fsurdat/lanuse paths for 1x1_ cases --- bld/namelist_files/namelist_defaults_ctsm.xml | 20 +++++++++---------- .../smallville_dynlakes_monthly/user_nl_clm | 2 +- .../smallville_dynurban_monthly/user_nl_clm | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index b80fad1d45..1ac0f243f0 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1242,7 +1242,7 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_2000_78pfts_c240216.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_2000_78pfts_c240221.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_5x5_amazon_hist_2000_78pfts_c240216.nc @@ -1265,7 +1265,7 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_360x720cru_hist_2000_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_2000_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_numaIA_hist_2000_78pfts_c240216.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_numaIA_hist_2000_78pfts_c240221.nc @@ -1286,11 +1286,11 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne0np4CONUS.ne30x8_hist_2000_78pfts_c2 -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_vancouverCAN_hist_2000_78pfts_c240216.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_vancouverCAN_hist_2000_78pfts_c240221.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_mexicocityMEX_hist_2000_78pfts_c240216.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_mexicocityMEX_hist_2000_78pfts_c240221.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_urbanc_alpha_hist_2000_78pfts_c240216.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_urbanc_alpha_hist_2000_78pfts_c240221.nc @@ -1322,9 +1322,9 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_1850_78pfts_c240216.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_1850_78pfts_c240216.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_1850_78pfts_c240221.nc -lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_1850_78pfts_c240216.nc +lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_1850_78pfts_c240221.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c240216.nc @@ -1377,7 +1377,7 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_360x720cru_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_brazil_SSP2-4.5_1850-2100_78pfts_c240216.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_brazil_SSP2-4.5_1850-2100_78pfts_c240221.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_mpasa120_SSP2-4.5_1850-2100_78pfts_c240216.nc @@ -1396,7 +1396,7 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_c240216.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_c240221.nc @@ -1420,7 +1420,7 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c >lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_360x720cru_SSP2-4.5_1850-2100_78pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_brazil_SSP2-4.5_1850-2100_78pfts_c240216.nc +>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_brazil_SSP2-4.5_1850-2100_78pfts_c240221.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_mpasa120_SSP2-4.5_1850-2100_78pfts_c240216.nc diff --git a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm index ac5ae1f67a..cff8860bc8 100644 --- a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm @@ -6,4 +6,4 @@ do_transient_lakes = .true. ! Key points are that lake area starts as 0, increases after the first year, then decreases after the second year. ! PCT_CROP is also changed so that PCT_LAKE + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_LAKE in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.) ! Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid. -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_dynLakes_c240216.nc' +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_dynLakes_c240221.nc' diff --git a/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm index 51bb1193eb..e9d7fb0e49 100644 --- a/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm @@ -7,4 +7,4 @@ do_transient_urban = .true. ! Medium density urban is set to zero to test the memory-saving behavior of PCT_URBAN_MAX. ! PCT_CROP is also changed so that PCT_URBAN + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_URBAN in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.) ! Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid. -flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_dynUrban_c240216.nc' +flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_dynUrban_c240221.nc' From bf9778e1a1f87d1af2ff198df5e1085f55fe62cb Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 23 Feb 2024 13:33:21 -0700 Subject: [PATCH 494/614] Delete or comment out instances of mpasa15-3* --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 ++ bld/unit_testers/build-namelist_test.pl | 2 +- cime_config/testdefs/testlist_clm.xml | 2 ++ python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 1ac0f243f0..11ce75f68d 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -1217,8 +1217,10 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_4x5_hist_2000_16pfts_c240216.nc lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa15_hist_2000_16pfts_c240216.nc + lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_mpasa3p75_hist_2000_16pfts_c240216.nc diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index a393e6f56b..51488b68cb 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -1351,7 +1351,7 @@ sub cat_and_create_namelistinfile { # Check for ALL resolutions with CLM50SP my @resolutions = ( "360x720cru", "10x15", "4x5", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne16np4.pg3", "ne30np4", "ne30np4.pg2", "ne30np4.pg3", "ne120np4.pg3", "ne0np4CONUS.ne30x8", "ne0np4.ARCTIC.ne30x4", "ne0np4.ARCTICGRIS.ne30x8", "C96", "mpasa480", "mpasa120" ); -my @only2000_resolutions = ( "1x1_numaIA", "1x1_brazil", "1x1_mexicocityMEX", "1x1_vancouverCAN", "1x1_urbanc_alpha", "5x5_amazon", "0.125nldas2", "mpasa60", "mpasa15", "mpasa15-3", "mpasa3p75" ); +my @only2000_resolutions = ( "1x1_numaIA", "1x1_brazil", "1x1_mexicocityMEX", "1x1_vancouverCAN", "1x1_urbanc_alpha", "5x5_amazon", "0.125nldas2", "mpasa60", "mpasa15", "mpasa3p75" ); my @regional; foreach my $res ( @resolutions ) { chomp($res); diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 74db2a0183..01f05644d5 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -189,6 +189,7 @@ + diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 5aece9d290..9b39f0e829 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -180,7 +180,7 @@ def main(): "f10": ["10x15"], "f45": ["4x5"], "low_res_no_crop": ["4x5", "10x15"], - "ultra_hi_res_no_crop": ["mpasa15", "mpasa15-3", "mpasa3p75"], + "ultra_hi_res_no_crop": ["mpasa15", "mpasa3p75"], "standard_res": ["360x720cru", "0.9x1.25", "1.9x2.5", "C96", "mpasa120"], "low_res": ["4x5", "10x15", "ne3np4.pg3"], "mpasa480": ["mpasa480"], From c70c969600a1b5fa902329423bb4e2125ca71b6b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 23 Feb 2024 14:17:20 -0700 Subject: [PATCH 495/614] Add check_dynpft_consistency = .false. to smallville hist tests I will open a corresponding issue. --- .../testdefs/testmods_dirs/clm/cropMonthOutput/user_nl_clm | 5 +++++ .../testmods_dirs/clm/decStart1851_noinitial/user_nl_clm | 4 ++++ .../clm/smallville_dynlakes_monthly/user_nl_clm | 5 +++++ .../clm/smallville_dynurban_monthly/user_nl_clm | 5 +++++ 4 files changed, 19 insertions(+) create mode 100644 cime_config/testdefs/testmods_dirs/clm/decStart1851_noinitial/user_nl_clm diff --git a/cime_config/testdefs/testmods_dirs/clm/cropMonthOutput/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/cropMonthOutput/user_nl_clm index ae4284da6b..8f779ed011 100644 --- a/cime_config/testdefs/testmods_dirs/clm/cropMonthOutput/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/cropMonthOutput/user_nl_clm @@ -1,2 +1,7 @@ hist_nhtfrq = 0,-240,17520 hist_mfilt = 1,1,1 + +! NOTE slevis (2024/2/23) Adding option for tests to pass. In the long term +! ensure that subset_data generates fsurdat and landuse files consistent with +! each other. +check_dynpft_consistency = .false. diff --git a/cime_config/testdefs/testmods_dirs/clm/decStart1851_noinitial/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/decStart1851_noinitial/user_nl_clm new file mode 100644 index 0000000000..78c8d17566 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/decStart1851_noinitial/user_nl_clm @@ -0,0 +1,4 @@ +! NOTE slevis (2024/2/23) Adding option for tests to pass. In the long term +! ensure that subset_data generates fsurdat and landuse files consistent with +! each other. +check_dynpft_consistency = .false. diff --git a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm index cff8860bc8..c86418dabd 100644 --- a/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/smallville_dynlakes_monthly/user_nl_clm @@ -7,3 +7,8 @@ do_transient_lakes = .true. ! PCT_CROP is also changed so that PCT_LAKE + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_LAKE in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.) ! Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid. flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_dynLakes_c240221.nc' + +! NOTE slevis (2024/2/23) Adding option for tests to pass. In the long term +! ensure that subset_data generates fsurdat and landuse files consistent with +! each other. +check_dynpft_consistency = .false. diff --git a/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm index e9d7fb0e49..a5bdb76ac3 100644 --- a/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly/user_nl_clm @@ -8,3 +8,8 @@ do_transient_urban = .true. ! PCT_CROP is also changed so that PCT_URBAN + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_URBAN in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.) ! Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid. flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_dynUrban_c240221.nc' + +! NOTE slevis (2024/2/23) Adding option for tests to pass. In the long term +! ensure that subset_data generates fsurdat and landuse files consistent with +! each other. +check_dynpft_consistency = .false. From 148f65e0556f862b3f18918a1eb783c1f6e81bbc Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 23 Feb 2024 14:52:14 -0700 Subject: [PATCH 496/614] Correct run status of an expected failure --- cime_config/testdefs/ExpectedTestFails.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index 8768f027ac..d3a5a4066c 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -194,8 +194,8 @@ - - RUN + + FAIL #2261 From bee02c576946bb79f3d04fea012e957518524ff7 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 23 Feb 2024 16:14:25 -0700 Subject: [PATCH 497/614] New finidat files for tests to pass without use_init_interp = .true. --- bld/namelist_files/namelist_defaults_ctsm.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 11ce75f68d..ad4696d6d4 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -965,7 +965,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ic_ymd="18500101" sim_year="1850" do_transient_pfts=".false." ic_tod="0" glc_nec="10" use_crop=".true." irrigate=".false." lnd_tuning_mode="clm5_0_GSWP3v1" ->lnd/clm2/initdata_map/clmi.I1850Clm50BgcCrop-ciso.1366-01-01.0.9x1.25_gx1v7_simyr1850_c200428.nc +>lnd/clm2/initdata_map/clmi.I1850Clm50BgcCrop-ciso.1366-01-01.0.9x1.25_gx1v7_simyr1850_c240223.nc @@ -1002,7 +1002,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ic_ymd="18500101" sim_year="1850" do_transient_pfts=".false." ic_tod="0" glc_nec="10" use_crop=".true." irrigate=".false." lnd_tuning_mode="clm5_1_GSWP3v1" ->lnd/clm2/initdata_map/clmi.I1850Clm50BgcCrop-ciso.1366-01-01.0.9x1.25_gx1v7_simyr1850_c200428.nc +>lnd/clm2/initdata_map/clmi.I1850Clm50BgcCrop-ciso.1366-01-01.0.9x1.25_gx1v7_simyr1850_c240223.nc @@ -1023,7 +1023,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ic_ymd="20110101" sim_year="2000" do_transient_pfts=".false." ic_tod="0" glc_nec="10" use_crop=".true." irrigate=".true." lnd_tuning_mode="clm4_5_GSWP3v1" ->lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c190312.nc +>lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc @@ -1031,7 +1031,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ic_ymd="20110101" sim_year="2000" do_transient_pfts=".false." ic_tod="0" glc_nec="10" use_crop=".true." irrigate=".true." lnd_tuning_mode="clm4_5_CRUv7" ->lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c190312.nc +>lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc @@ -1039,13 +1039,13 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ic_ymd="20110101" sim_year="2000" do_transient_pfts=".false." ic_tod="0" glc_nec="10" use_crop=".true." irrigate=".true." lnd_tuning_mode="clm5_0_GSWP3v1" ->lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c190312.nc +>lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c190312.nc +>lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc @@ -1054,7 +1054,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ic_ymd="20110101" sim_year="2000" do_transient_pfts=".false." ic_tod="0" glc_nec="10" use_crop=".true." irrigate=".true." lnd_tuning_mode="clm5_0_CRUv7" ->lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c190312.nc +>lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc From 52f7858905b3086025814cfcbfb02671fb029f71 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 23 Feb 2024 17:31:06 -0700 Subject: [PATCH 498/614] New finidat for another test to pass without use_init_interp = .true. --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index ad4696d6d4..a390acf4ef 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -973,7 +973,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ic_ymd="18500101" sim_year="1850" do_transient_pfts=".false." ic_tod="0" glc_nec="10" use_crop=".true." irrigate=".false." lnd_tuning_mode="clm5_0_CRUv7" ->lnd/clm2/initdata_map/clmi.I1850Clm50BgcCropCru-ciso.1526-01-01.0.9x1.25_gx1v7_simyr1850_c200728.nc +>lnd/clm2/initdata_map/clmi.I1850Clm50BgcCropCru-ciso.1526-01-01.0.9x1.25_gx1v7_simyr1850_c240223.nc From 1a504a6c5d3dd381cd246abbdc252e9271d98f3f Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 23 Feb 2024 17:32:29 -0700 Subject: [PATCH 499/614] Correct run status of another expected failure --- cime_config/testdefs/ExpectedTestFails.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index d3a5a4066c..23c9db4b7b 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -29,9 +29,9 @@ - + - FAIL + PEND #2370 From 7ff68c69436f5fa396ff1206fd1638f199709fb9 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 23 Feb 2024 18:34:47 -0700 Subject: [PATCH 500/614] Use same PE layout for both hcru_hcru tests in ctsm_sci --- cime_config/testdefs/testlist_clm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 01f05644d5..ae41b298eb 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -117,7 +117,7 @@ - + From c92cd77caa5daddd99b219e8ed8cb257b10a0eea Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 1 Mar 2024 18:05:38 -0700 Subject: [PATCH 501/614] Revisions from Keith Oleson's review --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml | 6 ++++-- tools/mksurfdata_esmf/src/mkvarpar.F90 | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index d54f3a5ae7..6ad82d6ea4 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -237,6 +237,7 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_1850.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_1850_cdf5_c20220910.nc + lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230226/mksrf_landuse_ctsm52_histLUH2_2000.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc @@ -250,6 +251,7 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_2005.cdf5.c20220325.nc lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_2005_cdf5_c20220910.nc + lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_2005.cdf5.c190119.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc @@ -262,7 +264,7 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1850.c20230226/mksrf_landuse_ctsm52_histLUH2_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_1850.cdf5.c20220325.nc - lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_1850_cdf5_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_1850_cdf5_c20220910.nc @@ -290,7 +292,7 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2100-2300.c20230226/mksrf_landuse_ctsm52_SSP1-2.6_%y.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_2100.cdf5.c20220325.nc - lnd/clm2/rawdata/gao_oneill_urban/ssp5/urban_properties_GaoOneil_05deg_ThreeClass_ssp5_2100_cdf5_c20220910.nc + lnd/clm2/rawdata/gao_oneill_urban/ssp1/urban_properties_GaoOneil_05deg_ThreeClass_ssp1_2100_cdf5_c20220910.nc
      diff --git a/tools/mksurfdata_esmf/src/mkvarpar.F90 b/tools/mksurfdata_esmf/src/mkvarpar.F90 index 28487babba..38176d1e88 100644 --- a/tools/mksurfdata_esmf/src/mkvarpar.F90 +++ b/tools/mksurfdata_esmf/src/mkvarpar.F90 @@ -16,7 +16,7 @@ module mkvarpar integer, parameter :: noveg = 0 ! value for non-vegetated pft integer, parameter :: numsolar = 2 ! number of solar types (Direct,Diffuse) integer, parameter :: numrad = 2 ! number of solar bands (VIS,NIR) - real(r8),parameter :: elev_thresh = 2600._r8 ! elevation threshold for screening urban areas - real(r8),parameter :: re = SHR_CONST_REARTH*0.001 + real(r8),parameter :: elev_thresh = 2600._r8 ! elevation threshold for screening urban areas (m) + real(r8),parameter :: re = SHR_CONST_REARTH * 0.001 ! radius of earth (km) end module mkvarpar From fed2967cbc9a6d205eae4043c9305991c94f5e5e Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 8 Mar 2024 19:23:28 -0700 Subject: [PATCH 502/614] Initial pass at swapping clm5_1 physics for clm6_0, in some places like namelists it needs clm5_1 and clm6_0, and others like most of the testing the Clm60 just replace Clm51 --- bld/CLMBuildNamelist.pm | 1 - bld/config_files/clm_phys_vers.pm | 4 +- bld/config_files/config_definition_ctsm.xml | 4 +- bld/namelist_files/namelist_defaults_ctsm.xml | 282 +++++++++++++++++- bld/unit_testers/build-namelist_test.pl | 53 ++-- cime_config/buildnml | 10 +- cime_config/config_component.xml | 17 +- lilac/bld_templates/ctsm_template.cfg | 2 +- python/ctsm/lilac_make_runtime_inputs.py | 4 +- 9 files changed, 331 insertions(+), 46 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 3e553b1324..fc4918c630 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -4013,7 +4013,6 @@ sub setup_logic_megan { #------------------------------------------------------------------------------- sub setup_logic_soilm_streams { - # prescribed soil moisture streams require clm4_5/clm5_0/clm5_1 my ($opts, $nl_flags, $definition, $defaults, $nl, $physv) = @_; add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_soil_moisture_streams'); diff --git a/bld/config_files/clm_phys_vers.pm b/bld/config_files/clm_phys_vers.pm index 3e4de9c610..9ab79ee8b0 100755 --- a/bld/config_files/clm_phys_vers.pm +++ b/bld/config_files/clm_phys_vers.pm @@ -28,7 +28,7 @@ use bigint; #use warnings; #use diagnostics; -my @version_strings = ("clm4_5", "clm5_0", "clm5_1"); +my @version_strings = ("clm4_5", "clm5_0", "clm5_1", "clm6_0"); #------------------------------------------------------------------------------- @@ -88,7 +88,7 @@ if ( ! defined(caller) && $#ARGV == -1 ) { sub testit { print "unit tester\n"; my %lastv; - my @vers_list = ( "clm4_5", "clm5_0", "clm5_1" ); + my @vers_list = ( "clm4_5", "clm5_0", "clm5_1", "clm6_0" ); foreach my $vers ( @vers_list ) { my $phys = config_files::clm_phys_vers->new($vers); isa_ok($phys, "config_files::clm_phys_vers", "created clm_phys_vers object"); diff --git a/bld/config_files/config_definition_ctsm.xml b/bld/config_files/config_definition_ctsm.xml index 06263c6d19..dfe6378f17 100644 --- a/bld/config_files/config_definition_ctsm.xml +++ b/bld/config_files/config_definition_ctsm.xml @@ -5,10 +5,10 @@ -Specifies either clm4_5, clm5_0, or clm5_1 physics +Specifies either clm4_5, clm5_0, clm5_1 (deprecated), or clm6_0 physics clm4_5_CRUv7 clm5_0_cam6.0 clm5_1_GSWP3v1 +clm6_0_GSWP3v1 +clm2 clm2 clm2 clm2 @@ -48,12 +50,12 @@ attributes from the config_cache.xml file (with keys converted to upper-case). off +2 2 2 1 +2 2 -2 -2 2 1 0 @@ -84,27 +86,32 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 20 +.false. .false. .false. .false. +.true. .true. .true. .false. +2 2 2 1 0 +.true. .true. .true. .false. +Medlyn2011 Medlyn2011 Medlyn2011 Ball-Berry1987 @@ -127,6 +134,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). lnd/clm2/isotopes/atm_delta_C14_CMIP6_SSP5B_3x1_global_1850-2100_yearly_c181209.nc +.true. +.false. .true. .false. .true. @@ -149,19 +158,23 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ALL +0.50,0.30 0.50,0.30 0.50,0.30 0.60,0.40 +ON_WASTEHEAT ON_WASTEHEAT ON_WASTEHEAT ON +1 1 1 0 +FAST FAST FAST NONE @@ -173,12 +186,17 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .true. .false. .false. +.false. 4SL_2m +20SL_8.5m 20SL_8.5m 20SL_8.5m 10SL_3.5m +.false. +.false. +.true. .false. .false. .true. @@ -188,20 +206,25 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .false. +1 1 1 0 +1 1 1 1 +1 1 1 0 +1.d-2 +0.001d00 1.d-2 0.001d00 1.d-2 @@ -213,10 +236,13 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 2.0d00 2.0d00 0.5d00 -0.5d00 -2.0d00 +0.5d00 +2.0d00 +0.5d00 +2.0d00 +.true. .true. .true. .false. @@ -248,12 +274,17 @@ attributes from the config_cache.xml file (with keys converted to upper-case). -2. 0. +-2. +0. + .false. .true. .true. +.true. +li2021gswpfrc li2021gswpfrc li2016crufrc li2014qianfrc @@ -281,6 +312,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). >20.0d00 20.0d00 +20.0d00 80.0d00 0.85d00 0.98d00 @@ -294,6 +327,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). >0.008d00 0.008d00 +0.008d00 0.17d-3 1.6d-4 0.33d00 @@ -318,10 +353,13 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 0.28d00 +.false. .false. .false. .true. +.true. +.false. .true. .false. .false. @@ -331,6 +369,10 @@ attributes from the config_cache.xml file (with keys converted to upper-case). +.true. +1.0 +0.05 + .true. 1.0 0.05 @@ -347,10 +389,12 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 0 1 1 +1 1 1 1 +1 4 2 @@ -371,12 +415,14 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 14400 -3400. 0.6 +1.0 1.0 1.0 0.5 0.1 +.false. .false. .false. .false. @@ -389,6 +435,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .true. +12 +5 12 5 12 @@ -397,6 +445,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). +10000.0 +5000.0 10000.0 5000.0 10000.0 @@ -410,23 +460,28 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 0.02d00 0.05d00 +2000. 2000. 2000. 1.e30 +10.0d00 10.0d00 10.0d00 10.0 +.true. .true. .true. .false. +'Vionnet2012' 'Vionnet2012' 'Vionnet2012' 'Anderson1976' +'Slater2017' 'Slater2017' 'Slater2017' 'TruncatedAnderson1976' @@ -434,6 +489,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 100.d00 175.d00 175.d00 +175.d00 0.08d00 @@ -480,6 +536,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). simplicity, we tie the defaults for both of these options to the overall CLM phys version, rather than having some intermediate option that controls the defaults for both h2osno_max and glc_snow_persistence_max_days. --> +0 0 0 7300 @@ -488,6 +545,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). +lnd/clm2/paramdata/ctsm51_params.c240207b.nc lnd/clm2/paramdata/ctsm51_params.c240207b.nc lnd/clm2/paramdata/clm50_params.c240207b.nc lnd/clm2/paramdata/clm45_params.c240207b.nc @@ -503,6 +561,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ZengWang2007 +Meier2022 Meier2022 .true. @@ -511,6 +570,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). +.true. +.false. .true. .false. .true. @@ -518,6 +579,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .false. +.true. +.false. .true. .false. .true. @@ -546,7 +609,9 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .true. .true. .true. +.true. +0.17 0.17 0.17 @@ -557,9 +622,11 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .false. .true. .true. +.true. 0.d+0 0.5d00 +0.5d00 constant @@ -569,13 +636,19 @@ attributes from the config_cache.xml file (with keys converted to upper-case). varytropicsbylat 12.0d00 0.4d00 +varytropicsbylat +12.0d00 +0.4d00 +3.d00 3.d00 3.d00 1.d00 .true. +DependsOnLat +.true. DependsOnLat .false. Constant @@ -586,6 +659,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .false. .true. .true. +.true. .true. @@ -597,6 +671,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .false. .false. .false. +.false. .false. @@ -604,15 +679,21 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .true. .false. .true. +.false. +.true. +1.d-9 1.d-9 1.d-9 1.d-8 + +-6.d+1 -6.d+1 --6.d+0 -6.d+1 --6.d+0 -6.d+2 + +-6.d+0 +-6.d+0 -6.d+1 @@ -631,6 +712,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .false. .true. .true. +.true. @@ -685,7 +767,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). - + .true. .true. + + +.true. +.true. +.true. +.true. + +.true. + + +.true. + .true. .true. +.true. .true. .true. @@ -773,6 +876,21 @@ attributes from the config_cache.xml file (with keys converted to upper-case). >hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.false. glc_nec=10 do_transient_pfts=.false. + + +hgrid=0.9x1.25 maxpft=17 mask=gx1v7 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false. + + +hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.false. glc_nec=10 do_transient_pfts=.false. + + + +hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.false. glc_nec=10 do_transient_pfts=.false. + + hgrid=1.9x2.5 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. @@ -789,7 +907,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). hgrid=1.9x2.5 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. -hgrid=1.9x2.5 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. @@ -800,6 +918,10 @@ attributes from the config_cache.xml file (with keys converted to upper-case). hgrid=1.9x2.5 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. + +hgrid=1.9x2.5 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. + hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. + +hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false. + + lnd/clm2/initdata_map/clmi.B1850Clm50BgcCrop.0161-01-01.0.9x1.25_gx1v7_simyr1850_c200729.nc + +lnd/clm2/initdata_map/clmi.I1850Clm50Sp.0181-01-01.0.9x1.25_gx1v7_simyr1850_c200806.nc + +lnd/clm2/initdata_map/clmi.I1850Clm50BgcCrop-ciso.1366-01-01.0.9x1.25_gx1v7_simyr1850_c240223.nc + + + +lnd/clm2/initdata_map/clmi.B1850Clm50BgcCrop.0161-01-01.0.9x1.25_gx1v7_simyr1850_c200729.nc + + @@ -1134,6 +1289,13 @@ attributes from the config_cache.xml file (with keys converted to upper-case). >lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.0.9x1.25_gx1v7_simyr2000_c200728.nc +lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.0.9x1.25_gx1v7_simyr2000_c200728.nc + + lnd/clm2/initdata_map/clmi.FHISTSp.2013-01-01.ne0CONUSne30x8_mt12_simyr2013_c200806.nc + +lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.0.9x1.25_gx1v7_simyr1979_c200806.nc + + +lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.1.9x2.5_gx1v7_simyr1979_c200806.nc + + + +lnd/clm2/initdata_map/clmi.FHISTSp.1979-01-01.ARCTIC_ne30x4_mt12_simyr1979_c200806.nc + + + +lnd/clm2/initdata_map/clmi.FHISTSp.1979-01-01.ARCTICGRIS_ne30x8_mt12_simyr1979_c200806.nc + + + +lnd/clm2/initdata_map/clmi.F2000.2000-01-01.ne120pg3_mt13_simyr2000_c200728.nc + + + +lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.0.9x1.25_gx1v7_simyr2000_c200728.nc + + + +lnd/clm2/initdata_map/clmi.BHISTSp.2000-01-01.1.9x2.5_gx1v7_simyr2003_c200807.nc + + + + +lnd/clm2/initdata_map/clmi.FHISTSp.2013-01-01.ne0CONUSne30x8_mt12_simyr2013_c200806.nc + + @@ -1480,6 +1706,7 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c >lnd/clm2/surfdata_map/fates-sci.1.68.3_api.31.0.0_tools.1.0.1/LUH2_states_transitions_management.timeseries_4x5_hist_simyr1850-2015_c231101.nc +.true. .true. .true. .false. @@ -1490,14 +1717,17 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c 0.83d-06 +0.015d00 0.015d00 0.015d00 0.015d00 +100.d00 100.d00 100.d00 20.d00 +1.d00 1.d00 1.d00 1.d00 @@ -1511,6 +1741,7 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c lnd/clm2/snicardata/snicar_optics_480bnd_c012422.nc lnd/clm2/snicardata/snicar_optics_5bnd_c013122.nc +hexagonal_plate hexagonal_plate sphere sphere @@ -1532,10 +1763,16 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c 2101 2015 +2015 2015 2101 2015 +2015 +2015 +2101 +2015 + 2018 2018 @@ -1557,6 +1794,7 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c 2000 2000 +lnd/clm2/ndepdata/fndep_clm_hist_b.e21.BWHIST.f09_g17.CMIP6-historical-WACCM.ensmean_1849-2015_monthly_0.9x1.25_c180926.nc lnd/clm2/ndepdata/fndep_clm_hist_b.e21.BWHIST.f09_g17.CMIP6-historical-WACCM.ensmean_1849-2015_monthly_0.9x1.25_c180926.nc lnd/clm2/ndepdata/fndep_clm_hist_b.e21.BWHIST.f09_g17.CMIP6-historical-WACCM.ensmean_1849-2015_monthly_0.9x1.25_c180926.nc lnd/clm2/ndepdata/fndep_clm_hist_b.e21.BWHIST.f09_g17.CMIP6-historical-WACCM.ensmean_1849-2015_monthly_0.9x1.25_c180926.nc @@ -1565,6 +1803,15 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c share/meshes/fv0.9x1.25_141008_polemod_ESMFmesh.nc +lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP5-8.5-WACCM_1849-2101_monthly_c191007.nc +lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP1-2.6-WACCM_1849-2101_monthly_c191007.nc +lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP2-4.5-WACCM_1849-2101_monthly_c191007.nc +lnd/clm2/ndepdata/fndep_clm_SSP370_b.e21.BWSSP370cmip6.f09_g17.CMIP6-SSP3-7.0-WACCM.002_1849-2101_monthly_0.9x1.25_c211216.nc + lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP5-8.5-WACCM_1849-2101_monthly_c191007.nc lnd/clm2/ndepdata/fndep_clm_SSP370_b.e21.BWSSP370cmip6.f09_g17.CMIP6-SSP3-7.0-WACCM.002_1849-2101_monthly_0.9x1.25_c211216.nc +cycle +NDEP_month + cycle NDEP_month @@ -1659,6 +1909,7 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c 94x192 94x192 360x720 +360x720 none none none @@ -1703,6 +1954,10 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c 2100 2015 +2015 +2100 +2015 + 2018 2018 @@ -1802,6 +2057,10 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c nn +2015 +2106 +2015 + 2015 2106 2015 @@ -1838,6 +2097,11 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c 1850 2106 +lnd/clm2/urbandata/CTSM52_tbuildmax_OlesonFeddema_2020_0.9x1.25_simyr1849-2106_c200605.nc +lnd/clm2/urbandata/CLM50_tbuildmax_Oleson_2016_0.9x1_ESMFmesh_cdf5_100621.nc + lnd/clm2/urbandata/CTSM52_tbuildmax_OlesonFeddema_2020_0.9x1.25_simyr1849-2106_c200605.nc +TWS_inversion TWS_inversion TWS_inversion ZWT_inversion @@ -1993,6 +2258,7 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c off +low low .false. diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 19b6d8d6a4..3613574ce3 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -78,7 +78,7 @@ sub make_config_cache { -Specifies clm physics +Specifies clm physics EOF $fh->close(); @@ -370,7 +370,7 @@ sub cat_and_create_namelistinfile { print "\n===============================================================================\n"; print "Test the NEON sites\n"; print "=================================================================================\n"; -my $phys = "clm5_1"; +my $phys = "clm6_0"; $mode = "-phys $phys"; &make_config_cache($phys); my $neondir = "../../cime_config/usermods_dirs/NEON"; @@ -582,7 +582,7 @@ sub cat_and_create_namelistinfile { "onset_threh w SP" =>{ options=>" -envxml_dir . -bgc sp", namelst=>"onset_thresh_depends_on_veg=.true.", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "dribble_crphrv w/o CN" =>{ options=>" -envxml_dir . -bgc sp", namelst=>"dribble_crophrv_xsmrpool_2atm=.true.", @@ -722,7 +722,7 @@ sub cat_and_create_namelistinfile { "NEONlightresButGlobal" =>{ options=>"--res 4x5 --bgc bgc --envxml_dir . --light_res 106x740", namelst=>"", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "spno-fire" =>{ options=>"-bgc sp -envxml_dir . -use_case 2000_control", namelst=>"fire_method='nofire'", @@ -912,27 +912,27 @@ sub cat_and_create_namelistinfile { "lnd_frac set to UNSET" =>{ options=>"-driver mct -lnd_frac UNSET -envxml_dir .", namelst=>"", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "lnd_frac set but nuopc" =>{ options=>"-driver nuopc -lnd_frac $DOMFILE -envxml_dir .", namelst=>"", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "lnd_frac not set but lilac"=>{ options=>"-driver nuopc -lilac -envxml_dir . -lnd_frac UNSET", namelst=>"fsurdat='surfdata.nc'", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "fatmlndfrc set but nuopc" =>{ options=>"-driver nuopc -envxml_dir .", namelst=>"fatmlndfrc='frac.nc'", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "force_send but not nuopc" =>{ options=>"-driver mct -lnd_frac $DOMFILE -envxml_dir .", namelst=>"force_send_to_atm = .false.", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "branch but NO nrevsn" =>{ options=>"-clm_start_type branch -envxml_dir .", namelst=>"", @@ -972,7 +972,7 @@ sub cat_and_create_namelistinfile { "useFATESWcrop" =>{ options=>"-bgc fates -envxml_dir . -no-megan -crop", namelst=>"", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "useFATESWcreatecrop" =>{ options=>"-bgc fates -envxml_dir . -no-megan", namelst=>"create_crop_landunit=.true.", @@ -987,37 +987,37 @@ sub cat_and_create_namelistinfile { "useFATESWbMH" =>{ options=>"-bgc fates -envxml_dir . -no-megan", namelst=>"use_biomass_heat_storage=.true.", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "FireNoneButFATESfireon" =>{ options=>"-bgc fates -envxml_dir . -no-megan -light_res none", namelst=>"fates_spitfire_mode=4", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "FATESwspitfireOffLigtOn" =>{ options=>"-bgc fates -envxml_dir . -no-megan -light_res 360x720", namelst=>"fates_spitfire_mode=0", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "useFATESWluna" =>{ options=>"--bgc fates --envxml_dir . --no-megan", namelst=>"use_luna=TRUE", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "useFATESWfun" =>{ options=>"--bgc fates --envxml_dir . --no-megan", namelst=>"use_fun=TRUE", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "useFATESWOsuplnitro" =>{ options=>"--bgc fates --envxml_dir . --no-megan", namelst=>"suplnitro='NONE'", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "FireNoneButBGCfireon" =>{ options=>"-bgc bgc -envxml_dir . -light_res none", namelst=>"fire_method='li2021gswpfrc'", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "createcropFalse" =>{ options=>"-bgc bgc -envxml_dir . -no-megan", namelst=>"create_crop_landunit=.false.", @@ -1278,7 +1278,7 @@ sub cat_and_create_namelistinfile { "methane off W nitrif_denit"=>{ options=>"-bgc bgc -envxml_dir .", namelst=>"use_nitrif_denitrif=.true.,use_lch4=.false.", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "soilm_stream w transient" =>{ options=>"-res 0.9x1.25 -envxml_dir . -use_case 20thC_transient", namelst=>"use_soil_moisture_streams=T,soilm_tintalgo='linear'", @@ -1298,12 +1298,12 @@ sub cat_and_create_namelistinfile { "FUN_wo_flexCN" =>{ options=>"-envxml_dir . -bgc bgc", namelst=>"use_fun=.true.,use_flexiblecn=.false.", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, "NotNEONbutNEONlightres" =>{ options=>"--res CLM_USRDAT --clm_usr_name regional --envxml_dir . --bgc bgc --light_res 106x174", namelst=>"fsurdat='build-namelist_test.pl'", GLC_TWO_WAY_COUPLING=>"FALSE", - phys=>"clm5_1", + phys=>"clm6_0", }, ); foreach my $key ( keys(%warntest) ) { @@ -1326,7 +1326,7 @@ sub cat_and_create_namelistinfile { # # Loop over all physics versions # -foreach my $phys ( "clm4_5", "clm5_0", "clm5_1" ) { +foreach my $phys ( "clm4_5", "clm5_0", "clm5_1", "clm6_0" ) { $mode = "-phys $phys"; &make_config_cache($phys); @@ -1570,7 +1570,7 @@ sub cat_and_create_namelistinfile { # # Test ALL SSP's for f09... # -$phys = "clm5_1"; +$phys = "clm6_0"; $mode = "-phys $phys"; &make_config_cache($phys); my $res = "0.9x1.25"; @@ -1607,10 +1607,10 @@ sub cat_and_create_namelistinfile { } print "\n==================================================\n"; -print "Test clm4.5/clm5.0/clm5_1 resolutions \n"; +print "Test clm4.5/clm5.0/clm5_1/clm6_0 resolutions \n"; print "==================================================\n"; -foreach my $phys ( "clm4_5", 'clm5_0', 'clm5_1' ) { +foreach my $phys ( "clm4_5", 'clm5_0', 'clm5_1', "clm6_0" ) { my $mode = "-phys $phys"; &make_config_cache($phys); my @clmoptions = ( "-bgc bgc -envxml_dir .", "-bgc bgc -envxml_dir . -clm_accelerated_spinup=on", "-bgc bgc -envxml_dir . -light_res 360x720", @@ -1710,7 +1710,7 @@ sub cat_and_create_namelistinfile { my $res = "0.9x1.25"; my $mask = "gx1v7"; my $simyr = "1850"; -foreach my $phys ( "clm4_5", 'clm5_0', 'clm5_1' ) { +foreach my $phys ( "clm4_5", 'clm5_0', 'clm5_1', 'clm6_0' ) { my $mode = "-phys $phys"; &make_config_cache($phys); my @forclist = (); @@ -1721,6 +1721,9 @@ sub cat_and_create_namelistinfile { if ( $lndtuningmode eq "clm5_1_CRUv7" ) { next; } + if ( $lndtuningmode eq "clm6_0_CRUv7" ) { + next; + } my $clmoptions = "-res $res -mask $mask -sim_year $simyr -envxml_dir . -lnd_tuning_mod $lndtuningmode -bgc $bgc"; &make_env_run( ); eval{ system( "$bldnml $clmoptions > $tempfile 2>&1 " ); }; diff --git a/cime_config/buildnml b/cime_config/buildnml index 69952c3968..481319c803 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -23,7 +23,7 @@ _config_cache_template = """ -Specifies CTSM physics +Specifies CTSM physics """ @@ -94,6 +94,11 @@ def buildnml(case, caseroot, compname): "clm5_1_NLDAS2": "clm5_1_GSWP3v1", "clm5_1_ERA5": "clm5_1_GSWP3v1", "clm5_1_CRUv7": "clm5_1_GSWP3v1", + "clm6_0_1PT": "clm6_0_GSWP3v1", + "clm6_0_QIAN": "clm6_0_GSWP3v1", + "clm6_0_NLDAS2": "clm6_0_GSWP3v1", + "clm6_0_ERA5": "clm6_0_GSWP3v1", + "clm6_0_CRUv7": "clm6_0_GSWP3v1", } for mode, closest in closest_tuning.items(): if lnd_tuning_mode == mode: @@ -110,7 +115,7 @@ def buildnml(case, caseroot, compname): ) lnd_tuning_mode = closest - tuning_based_on = {"clm5_1_GSWP3v1": "clm5_0_GSWP3v1", "clm5_1_cam6.0": "clm5_0_cam6.0"} + tuning_based_on = {"clm6_0_GSWP3v1": "clm5_0_GSWP3v1", "clm5_1_GSWP3v1": "clm5_0_GSWP3v1", "clm6_0_cam6.0": "clm5_0_cam6.0", "clm5_1_cam6.0": "clm5_0_cam6.0"} for mode, based_on in tuning_based_on.items(): if lnd_tuning_mode == mode: logger.warning( @@ -392,4 +397,3 @@ def _main_func(): if __name__ == "__main__": - _main_func() diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index fac3d15f85..d5f472fae2 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -74,7 +74,7 @@ UNSET - clm5_0_cam6.0,clm5_0_GSWP3v1,clm5_0_CRUv7,clm5_0_QIAN,clm5_0_1PT,clm5_0_NLDAS2,clm5_0_ERA5,clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_QIAN,clm4_5_cam6.0,clm4_5_1PT,clm4_5_NLDAS2,clm4_5_ERA5,clm5_1_CRUv7,clm5_1_GSWP3v1,clm5_1_cam6.0,clm5_1_QIAN,clm5_1_1PT,clm5_1_NLDAS2,clm5_1_ERA5 + clm5_0_cam6.0,clm5_0_GSWP3v1,clm5_0_CRUv7,clm5_0_QIAN,clm5_0_1PT,clm5_0_NLDAS2,clm5_0_ERA5,clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_QIAN,clm4_5_cam6.0,clm4_5_1PT,clm4_5_NLDAS2,clm4_5_ERA5,clm5_1_CRUv7,clm5_1_GSWP3v1,clm5_1_cam6.0,clm5_1_QIAN,clm5_1_1PT,clm5_1_NLDAS2,clm5_1_ERA5,clm6_0_CRUv7,clm6_0_GSWP3v1,clm6_0_cam6.0,clm6_0_QIAN,clm6_0_1PT,clm6_0_NLDAS2,clm6_0_ERA5 @@ -113,6 +113,18 @@ clm5_1_1PT clm5_1_NLDAS2 clm5_1_ERA5 + + clm6_0_CRUv7 + clm6_0_CRUv7 + clm6_0_GSWP3v1 + clm6_0_GSWP3v1 + clm6_0_cam6.0 + clm6_0_cam6.0 + clm6_0_QIAN + clm6_0_QIAN + clm6_0_1PT + clm6_0_NLDAS2 + clm6_0_ERA5 INVALID_DATM_FORCING_FOR_RUNNING_CTSM INVALID_DATM_FORCING_FOR_RUNNING_CTSM @@ -123,7 +135,7 @@ char - clm4_5,clm5_0,clm5_1 + clm4_5,clm5_0,clm5_1,clm6_0 - clm5_1_CRUv7 - clm5_1_CRUv7 clm5_1_GSWP3v1 clm5_1_GSWP3v1 clm5_1_cam6.0 clm5_1_cam6.0 - clm5_1_QIAN - clm5_1_QIAN - clm5_1_1PT - clm5_1_NLDAS2 - clm5_1_ERA5 - clm6_0_CRUv7 - clm6_0_CRUv7 - clm6_0_GSWP3v1 - clm6_0_GSWP3v1 - clm6_0_cam6.0 - clm6_0_cam6.0 - clm6_0_QIAN - clm6_0_QIAN - clm6_0_1PT - clm6_0_NLDAS2 - clm6_0_ERA5 + clm6_0_CRUv7 + clm6_0_CRUv7 + clm6_0_GSWP3v1 + clm6_0_GSWP3v1 + clm6_0_cam6.0 + clm6_0_cam6.0 + clm6_0_QIAN + clm6_0_QIAN + clm6_0_1PT + clm6_0_NLDAS2 + clm6_0_ERA5 INVALID_DATM_FORCING_FOR_RUNNING_CTSM INVALID_DATM_FORCING_FOR_RUNNING_CTSM @@ -194,6 +188,7 @@ 2010_control 2000_control 1850_control + 1850_noanthro_control 1850_noanthro_control 20thC_transient 1850-2100_SSP5-8.5_transient @@ -335,8 +330,9 @@ - $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/cmip6_deck + $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/fates_sp $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/fates_sp + $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/cmip6_deck $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/cmip6_nociso_deck $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/cmip6_waccm_deck $COMP_ROOT_DIR_LND/cime_config/usermods_dirs/cmip6_waccm_nociso_deck diff --git a/cime_config/config_compsets.xml b/cime_config/config_compsets.xml index ee7546fdaf..2de911da86 100644 --- a/cime_config/config_compsets.xml +++ b/cime_config/config_compsets.xml @@ -13,8 +13,8 @@ TIME_ATM[%phys]_LND[%phys]_ICE[%phys]_OCN[%phys]_ROF[%phys]_GLC[%phys]_WAV[%phys][_BGC%phys] Where for the CAM specific compsets below the following is supported TIME = Time period (e.g. 2000, HIST, SSP585...) - ATM = [CAM40, CAM50, CAM55] - LND = [CLM45, CLM50, CLM51, SLND] + ATM = [CAM40, CAM50, CAM60] + LND = [CLM45, CLM50, CLM51, CLM60, SLND] ICE = [CICE, DICE, SICE] OCN = [DOCN, ,AQUAP, SOCN] ROF = [RTM, SROF] @@ -37,28 +37,28 @@ - I1PtClm51Bgc - 2000_DATM%1PT_CLM51%BGC_SICE_SOCN_SROF_SGLC_SWAV + I1PtClm60Bgc + 2000_DATM%1PT_CLM60%BGC_SICE_SOCN_SROF_SGLC_SWAV - I1PtClm51Fates - 2000_DATM%1PT_CLM51%FATES_SICE_SOCN_SROF_SGLC_SWAV + I1PtClm60Fates + 2000_DATM%1PT_CLM60%FATES_SICE_SOCN_SROF_SGLC_SWAV - IHist1PtClm51Bgc - HIST_DATM%1PT_CLM51%BGC_SICE_SOCN_SROF_SGLC_SWAV + IHist1PtClm60Bgc + HIST_DATM%1PT_CLM60%BGC_SICE_SOCN_SROF_SGLC_SWAV - IHist1PtClm51Fates - HIST_DATM%1PT_CLM51%FATES_SICE_SOCN_SROF_SGLC_SWAV + IHist1PtClm60Fates + HIST_DATM%1PT_CLM60%FATES_SICE_SOCN_SROF_SGLC_SWAV - I1PtClm51SpRs - 2000_DATM%1PT_CLM51%SP_SICE_SOCN_SROF_SGLC_SWAV + I1PtClm60SpRs + 2000_DATM%1PT_CLM60%SP_SICE_SOCN_SROF_SGLC_SWAV @@ -84,19 +84,19 @@ 2000_DATM%GSWP3v1_CLM50%SP_SICE_SOCN_SROF_SGLC_SWAV - I2000Clm51SpRs - 2000_DATM%GSWP3v1_CLM51%SP_SICE_SOCN_SROF_SGLC_SWAV + I2000Clm60SpRs + 2000_DATM%GSWP3v1_CLM60%SP_SICE_SOCN_SROF_SGLC_SWAV - I2000Clm51Sp - 2000_DATM%GSWP3v1_CLM51%SP_SICE_SOCN_MOSART_SGLC_SWAV + I2000Clm60Sp + 2000_DATM%GSWP3v1_CLM60%SP_SICE_SOCN_MOSART_SGLC_SWAV - I2000Clm51SpRs - 2000_DATM%GSWP3v1_CLM51%SP_SICE_SOCN_SROF_SGLC_SWAV + I2000Clm60SpRs + 2000_DATM%GSWP3v1_CLM60%SP_SICE_SOCN_SROF_SGLC_SWAV @@ -132,13 +132,13 @@ - I2000Clm51BgcCrop - 2000_DATM%GSWP3v1_CLM51%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV + I2000Clm60BgcCrop + 2000_DATM%GSWP3v1_CLM60%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV - I2000Clm51Bgc - 2000_DATM%GSWP3v1_CLM51%BGC_SICE_SOCN_MOSART_SGLC_SWAV + I2000Clm60Bgc + 2000_DATM%GSWP3v1_CLM60%BGC_SICE_SOCN_MOSART_SGLC_SWAV @@ -157,8 +157,8 @@ - I1850Clm51SpCru - 1850_DATM%CRUv7_CLM51%SP_SICE_SOCN_MOSART_SGLC_SWAV + I1850Clm60SpCru + 1850_DATM%CRUv7_CLM60%SP_SICE_SOCN_MOSART_SGLC_SWAV @@ -169,18 +169,24 @@ - I1850Clm51BgcCrop - 1850_DATM%GSWP3v1_CLM51%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV + I1850Clm60BgcCrop + 1850_DATM%GSWP3v1_CLM60%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV + - I1850Clm51Sp - 1850_DATM%GSWP3v1_CLM51%SP_SICE_SOCN_MOSART_SGLC_SWAV + I1850Clm60BgcCrop + 1850_DATM%GSWP3v1_CLM60%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV - I1850Clm51Bgc - 1850_DATM%GSWP3v1_CLM51%BGC_SICE_SOCN_MOSART_SGLC_SWAV + I1850Clm60Sp + 1850_DATM%GSWP3v1_CLM60%SP_SICE_SOCN_MOSART_SGLC_SWAV + + + + I1850Clm60Bgc + 1850_DATM%GSWP3v1_CLM60%BGC_SICE_SOCN_MOSART_SGLC_SWAV @@ -208,16 +214,16 @@ - I1850Clm51BgcCropCru - 1850_DATM%CRUv7_CLM51%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV + I1850Clm60BgcCropCru + 1850_DATM%CRUv7_CLM60%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV - I2000Clm51BgcCropQianRs - 2000_DATM%QIA_CLM51%BGC-CROP_SICE_SOCN_SROF_SGLC_SWAV + I2000Clm60BgcCropQianRs + 2000_DATM%QIA_CLM60%BGC-CROP_SICE_SOCN_SROF_SGLC_SWAV I2000Clm50BgcCropQianRs @@ -245,8 +251,8 @@ - I2000Clm51Fates - 2000_DATM%GSWP3v1_CLM51%FATES_SICE_SOCN_MOSART_SGLC_SWAV + I2000Clm60Fates + 2000_DATM%GSWP3v1_CLM60%FATES_SICE_SOCN_MOSART_SGLC_SWAV I2000Clm50Fates @@ -257,12 +263,12 @@ 2000_DATM%CRUv7_CLM50%FATES_SICE_SOCN_SROF_SGLC_SWAV - I2000Clm51FatesSpCruRsGs - 2000_DATM%CRUv7_CLM51%FATES-SP_SICE_SOCN_SROF_SGLC_SWAV + I2000Clm60FatesSpCruRsGs + 2000_DATM%CRUv7_CLM60%FATES-SP_SICE_SOCN_SROF_SGLC_SWAV - I2000Clm51FatesSpRsGs - 2000_DATM%GSWP3v1_CLM51%FATES-SP_SICE_SOCN_SROF_SGLC_SWAV + I2000Clm60FatesSpRsGs + 2000_DATM%GSWP3v1_CLM60%FATES-SP_SICE_SOCN_SROF_SGLC_SWAV I2000Clm50FatesCru @@ -274,8 +280,8 @@ 2000_DATM%GSWP3v1_CLM50%FATES_SICE_SOCN_SROF_SGLC_SWAV - I2000Clm51FatesRs - 2000_DATM%GSWP3v1_CLM51%FATES_SICE_SOCN_SROF_SGLC_SWAV + I2000Clm60FatesRs + 2000_DATM%GSWP3v1_CLM60%FATES_SICE_SOCN_SROF_SGLC_SWAV @@ -283,6 +289,16 @@ 1850_DATM%GSWP3v1_CLM50%BGC_SICE_SOCN_MOSART_SGLC_SWAV + + I1850Clm60BgcNoAnthro + 1850_DATM%GSWP3v1_CLM60%BGC-NOANTHRO_SICE_SOCN_MOSART_SGLC_SWAV + + + + I1850Clm60SpNoAnthro + 1850_DATM%GSWP3v1_CLM60%SP-NOANTHRO_SICE_SOCN_MOSART_SGLC_SWAV + + I1850Clm50BgcNoAnthro 1850_DATM%GSWP3v1_CLM50%BGC-NOANTHRO_SICE_SOCN_MOSART_SGLC_SWAV @@ -293,6 +309,7 @@ 1850_DATM%GSWP3v1_CLM50%SP-NOANTHRO_SICE_SOCN_MOSART_SGLC_SWAV + IHistClm50BgcCrop HIST_DATM%GSWP3v1_CLM50%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV @@ -301,28 +318,34 @@ - I1850Clm51SpNoAnthro - 1850_DATM%GSWP3v1_CLM51%SP-NOANTHRO_SICE_SOCN_MOSART_SGLC_SWAV + I1850Clm60SpNoAnthro + 1850_DATM%GSWP3v1_CLM60%SP-NOANTHRO_SICE_SOCN_MOSART_SGLC_SWAV + + IHistClm60Sp + HIST_DATM%GSWP3v1_CLM60%SP_SICE_SOCN_MOSART_SGLC_SWAV + + + IHistClm51Sp HIST_DATM%GSWP3v1_CLM51%SP_SICE_SOCN_MOSART_SGLC_SWAV - IHistClm51SpRs - HIST_DATM%GSWP3v1_CLM51%SP_SICE_SOCN_SROF_SGLC_SWAV + IHistClm60SpRs + HIST_DATM%GSWP3v1_CLM60%SP_SICE_SOCN_SROF_SGLC_SWAV - IHistClm51Bgc - HIST_DATM%GSWP3v1_CLM51%BGC_SICE_SOCN_MOSART_SGLC_SWAV + IHistClm60Bgc + HIST_DATM%GSWP3v1_CLM60%BGC_SICE_SOCN_MOSART_SGLC_SWAV - IHistClm51BgcCrop - HIST_DATM%GSWP3v1_CLM51%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV + IHistClm60BgcCrop + HIST_DATM%GSWP3v1_CLM60%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV @@ -340,8 +363,8 @@ - IHistClm51SpCru - HIST_DATM%CRUv7_CLM51%SP_SICE_SOCN_MOSART_SGLC_SWAV + IHistClm60SpCru + HIST_DATM%CRUv7_CLM60%SP_SICE_SOCN_MOSART_SGLC_SWAV @@ -363,8 +386,8 @@ - IHistClm51BgcQianRs - HIST_DATM%QIA_CLM51%BGC_SICE_SOCN_SROF_SGLC_SWAV + IHistClm60BgcQianRs + HIST_DATM%QIA_CLM60%BGC_SICE_SOCN_SROF_SGLC_SWAV - ISSP585Clm51BgcCrop - SSP585_DATM%GSWP3v1_CLM51%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV + ISSP585Clm60BgcCrop + SSP585_DATM%GSWP3v1_CLM60%BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV @@ -425,8 +448,8 @@ HIST_DATM%QIA_CLM50%BGC-CROP_SICE_SOCN_SROF_SGLC_SWAV - IHistClm51BgcCropQianRs - HIST_DATM%QIA_CLM51%BGC-CROP_SICE_SOCN_SROF_SGLC_SWAV + IHistClm60BgcCropQianRs + HIST_DATM%QIA_CLM60%BGC-CROP_SICE_SOCN_SROF_SGLC_SWAV @@ -605,6 +628,11 @@ + + I1850Clm60BgcCropG + 1850_DATM%GSWP3v1_CLM60%BGC-CROP_SICE_SOCN_MOSART_CISM2%GRIS-EVOLVE_SWAV + + I1850Clm51BgcCropG 1850_DATM%GSWP3v1_CLM51%BGC-CROP_SICE_SOCN_MOSART_CISM2%GRIS-EVOLVE_SWAV @@ -618,8 +646,8 @@ - I1850Clm51SpRs - 1850_DATM%GSWP3v1_CLM51%SP_SICE_SOCN_SROF_SGLC_SWAV + I1850Clm60SpRs + 1850_DATM%GSWP3v1_CLM60%SP_SICE_SOCN_SROF_SGLC_SWAV diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 2cc9412ead..ecb9d5b570 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -11,7 +11,7 @@ aux_cime_baselines: CESM cime baselines --> - + @@ -43,7 +43,7 @@ - + @@ -53,7 +53,18 @@ - + + + + + + + + + + + + @@ -62,7 +73,7 @@ - + @@ -71,7 +82,7 @@ - + @@ -80,7 +91,7 @@ - + @@ -90,7 +101,7 @@ - + @@ -99,7 +110,7 @@ - + @@ -108,7 +119,7 @@ - + @@ -117,7 +128,7 @@ - + @@ -126,7 +137,7 @@ - + @@ -135,7 +146,7 @@ - + @@ -144,7 +155,7 @@ - + @@ -153,7 +164,7 @@ - + @@ -162,7 +173,7 @@ - + @@ -171,7 +182,7 @@ - + @@ -180,7 +191,7 @@ - + @@ -190,7 +201,7 @@ - + @@ -274,7 +285,7 @@ - + @@ -283,7 +294,7 @@ - + @@ -329,7 +340,7 @@ - + @@ -338,7 +349,7 @@ - + @@ -435,7 +446,7 @@ - + @@ -444,7 +455,7 @@ - + @@ -453,7 +464,7 @@ - + @@ -462,7 +473,7 @@ - + @@ -471,7 +482,7 @@ - + @@ -530,7 +541,7 @@ - + @@ -539,7 +550,7 @@ - + @@ -557,7 +568,7 @@ - + @@ -566,7 +577,7 @@ - + @@ -575,7 +586,7 @@ - + @@ -584,7 +595,7 @@ - + @@ -593,7 +604,7 @@ - + @@ -602,7 +613,7 @@ - + @@ -611,7 +622,7 @@ - + @@ -620,7 +631,7 @@ - + @@ -629,7 +640,7 @@ - + @@ -638,7 +649,7 @@ - + @@ -647,7 +658,7 @@ - + @@ -656,7 +667,7 @@ - + @@ -694,7 +705,7 @@ - + @@ -703,7 +714,7 @@ - + @@ -752,14 +763,14 @@ - + - + @@ -801,14 +812,25 @@ - + - + + + + + + + + + + + + @@ -829,7 +851,7 @@ - + @@ -837,7 +859,7 @@ - + @@ -846,7 +868,7 @@ - + @@ -855,7 +877,7 @@ - + @@ -864,7 +886,7 @@ - + @@ -921,7 +943,7 @@ - + @@ -929,7 +951,7 @@ - + @@ -937,7 +959,7 @@ - + @@ -946,7 +968,7 @@ - + @@ -955,7 +977,7 @@ - + @@ -1057,7 +1079,7 @@ - + @@ -1066,7 +1088,7 @@ - + @@ -1105,7 +1127,7 @@ - + @@ -1308,7 +1330,7 @@ - + @@ -1318,7 +1340,7 @@ - + @@ -1402,7 +1424,7 @@ - + @@ -1411,7 +1433,7 @@ - + @@ -1541,7 +1563,7 @@ - + @@ -1753,7 +1775,7 @@ - + @@ -1762,7 +1784,7 @@ - + @@ -1789,17 +1811,17 @@ - + - + - + @@ -1808,17 +1830,17 @@ - + - + - + @@ -1831,7 +1853,7 @@ - + @@ -1870,7 +1892,7 @@ - + @@ -1880,7 +1902,7 @@ - + @@ -1914,7 +1936,7 @@ - + @@ -1954,7 +1976,7 @@ - + @@ -1984,7 +2006,7 @@ - + @@ -1994,7 +2016,7 @@ (no need to run this high core count test with every tag, but include it in the less frequent ctsm_sci testing)" - + @@ -2003,7 +2025,7 @@ - + @@ -2012,7 +2034,7 @@ - + @@ -2041,7 +2063,7 @@ - + @@ -2050,7 +2072,7 @@ - + @@ -2099,7 +2121,7 @@ - + @@ -2234,7 +2256,7 @@ - + @@ -2246,7 +2268,7 @@ - + @@ -2300,7 +2322,7 @@ - + @@ -2312,7 +2334,7 @@ - + + valid_values="clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_cam6.0,clm5_0_cam6.0,clm5_0_CRUv7,clm5_0_GSWP3v1,clm5_1_GSWP3v1,clm5_1_cam6.0,clm6_0_GSWP3v1,clm6_0_cam6.0"> General configuration of model version and atmospheric forcing to tune the model to run under. This sets the model to run with constants and initial conditions that were set to run well under the configuration of model version and atmospheric forcing. To run well constants would need to be changed From 8f3d90dbce493184cf238f80c4eee9555ed89f6d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 13 Mar 2024 10:37:22 -0600 Subject: [PATCH 508/614] Fix two errors that @slevis-lmwg found --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- .../testmods_dirs/clm/clm60cam6LndTuningMode/shell_commands | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 4ee210c4aa..44d8ca7d8a 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -312,7 +312,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). >20.0d00 20.0d00 -20.0d00 80.0d00 0.85d00 diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode/shell_commands b/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode/shell_commands index cf39cca1c0..e81a241e64 100644 --- a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode/shell_commands +++ b/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode/shell_commands @@ -1,5 +1,5 @@ #!/bin/bash -./xmlchange LND_TUNING_MODE="clm5_1_cam6.0" +./xmlchange LND_TUNING_MODE="clm6_0_cam6.0" ./xmlchange ROF_NCPL='$ATM_NCPL' From dd864df6699acf6ce9bd00925c2afc5cd58ffb61 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 13 Mar 2024 15:50:40 -0600 Subject: [PATCH 509/614] Correct the PtVg sections of gen_mksurfdata_namelist.xml --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 6ad82d6ea4..739ca5446b 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -110,10 +110,6 @@ lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc - - lnd/clm2/rawdata/mksrf_urban_0.05x0.05_zerourbanpct.cdf5.c181014.nc - lnd/clm2/mappingdata/grids/UNSTRUCTgrid_3x3min_nomask_cdf5_c200129.nc -
      @@ -228,7 +224,7 @@ version of the raw dataset will probably go away. lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.noanthro.c20230226/mksrf_landuse_ctsm52_noanthroLUH2_1.c20230226.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.25x0.25_nomask_cdf5_c200129.nc lnd/clm2/rawdata/lake_area/mksurf_lake_0.05x0.05_hist_clm5_hydrolakes_1850.cdf5.c20220325.nc - lnd/clm2/rawdata/gao_oneill_urban/historical/urban_properties_GaoOneil_05deg_ThreeClass_1850_cdf5_c20220910.nc + lnd/clm2/rawdata/mksrf_urban_0.05x0.05_zerourbanpct.cdf5.c181014.nc
      From 4e10b809184560fddcd992591fcf5504156f9f8f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 13 Mar 2024 17:50:10 -0600 Subject: [PATCH 510/614] Remove namaelist defaults for tools --- bld/README | 1 - 1 file changed, 1 deletion(-) diff --git a/bld/README b/bld/README index ca87566ced..1e9517b189 100644 --- a/bld/README +++ b/bld/README @@ -25,7 +25,6 @@ unit_testers --- Directory of scripts to test scipts in this directory ---------- XML Files describing namelists in namelist_files namelist_files/namelist_defaults_ctsm.xml --------- List of default values for the ctsm namelist -namelist_files/namelist_defaults_ctsm_tools.xml --- List of default values for the ctsm tools namelist_files/namelist_defaults_overall.xml ------ List of default values for overall settings namelist_files/namelist_defaults_usr_files.xml ---- List of default values for the user-files namelist_files/namelist_definition_ctsm.xml -------- Definition of all namelist items for ctsm From 4f406221c0912f40e2e1b76aa0bea865b7aac99f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 13 Mar 2024 17:50:30 -0600 Subject: [PATCH 511/614] Remove namaelist defaults for tools --- .../namelist_defaults_ctsm_tools.xml | 7427 ----------------- 1 file changed, 7427 deletions(-) delete mode 100644 bld/namelist_files/namelist_defaults_ctsm_tools.xml diff --git a/bld/namelist_files/namelist_defaults_ctsm_tools.xml b/bld/namelist_files/namelist_defaults_ctsm_tools.xml deleted file mode 100644 index ff309c6fc9..0000000000 --- a/bld/namelist_files/namelist_defaults_ctsm_tools.xml +++ /dev/null @@ -1,7427 +0,0 @@ - - - - - - - - - - - - -none -SCRIP - - -lnd/clm2/mappingdata/grids/SCRIPgrid_0.23x0.31_nomask_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_0.47x0.63_nomask_c170914.nc -lnd/clm2/mappingdata/grids/0.9x1.25_c110307.nc -lnd/clm2/mappingdata/grids/1.9x2.5_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_2.5x3.33_nomask_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_4x5_nomask_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_10x15_nomask_c110308.nc - - -lnd/clm2/mappingdata/grids/SCRIPgrid_512x1024_nomask_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_128x256_nomask_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_94x192_nomask_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_64x128_nomask_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_48x96_nomask_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_32x64_nomask_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_8x16_nomask_c110308.nc - - -atm/cam/coords/C384_SCRIP_desc.181018.nc -atm/cam/coords/C192_SCRIP_desc.181018.nc -atm/cam/coords/C96_SCRIP_desc.181018.nc -atm/cam/coords/C48_SCRIP_desc.181018.nc -atm/cam/coords/C24_SCRIP_desc.181018.nc - - -lnd/clm2/mappingdata/grids/SCRIPgrid_ne240np4_nomask_c091227.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_ne120np4_nomask_c101123.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_ne60np4_nomask_c100408.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_ne30np4_nomask_c101123.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_ne16np4_nomask_c110512.nc - -atm/cam/coords/ne30pg2_scrip_c170608.nc -atm/cam/coords/ne30pg3_scrip_170604.nc -atm/cam/coords/ne120pg2_scrip_c170629.nc -atm/cam/coords/ne120pg3_scrip_c170628.nc - - -atm/cam/coords/ne0CONUSne30x8_scrip_c200107.nc -atm/cam/coords/ne0ARCTICGRISne30x8_scrip_c191209.nc -atm/cam/coords/ne0ARCTICne30x4_scrip_c191212.nc - - -lnd/clm2/mappingdata/grids/SCRIPgrid_0.125x0.125_nomask_c140702.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_0.33x0.33_navy_c111207.nc - -lnd/clm2/mappingdata/grids/SCRIPgrid_360x720_nomask_c120830.nc - -lnd/clm2/mappingdata/grids/SCRIPgrid_0.5x0.5_nomask_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_0.25x0.25_nomask_c200309.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_5x5min_nomask_c200309.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_10x10min_nomask_c110228.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_3x3min_nomask_c200309.nc -64bit_offset - - - - -lnd/clm2/mappingdata/grids/UGRID_1km-merge-10min_HYDRO1K-merge-nomask_c130402.nc -netcdf4 -UGRID -landmesh - - -lnd/clm2/mappingdata/grids/SCRIPgrid_0.125nldas2_nomask_c190328.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_1x1pt_brazil_nomask_c20211211.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_1x1pt_mexicocityMEX_nomask_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_1x1pt_numaIA_nomask_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_1x1pt_smallvilleIA_nomask_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_1x1pt_urbanc_alpha_nomask_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_1x1pt_vancouverCAN_nomask_c110308.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_5x5pt_amazon_nomask_c110308.nc - - -lnd/clm2/mappingdata/grids/SCRIPgrid_0.33x0.33_navy_c111207.nc -lnd/clm2/mappingdata/grids/SCRIPgrid_5x5_amazon_navy_c111207.nc -/glade/proj3/cseg/mapping/grids/gx1v6_090205.nc -/glade/proj3/cseg/mapping/grids/gx3v7_090903.nc -/glade/proj3/cseg/mapping/grids/tx1v1_090122.nc -/glade/proj3/cseg/mapping/grids/tx0.1v2_090127.nc - - - - - -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -nomask -HYDRO1K-merge-nomask -nomask - - -3x3min -0.5x0.5 -0.5x0.5 -0.25x0.25 -3x3min -0.25x0.25 -3x3min -0.25x0.25 -3x3min -0.25x0.25 -3x3min -5x5min -3x3min -10x10min -0.125x0.125 -5x5min -10x10min -5x5min -0.5x0.5 -0.5x0.5 -5x5min -0.5x0.5 -1km-merge-10min -0.9x1.25 - - -mksrf_flakwat -mksrf_fwetlnd -mksrf_fvocef -mksrf_flai -mksrf_fvegtyp -mksrf_fvegtyp -mksrf_furban -mksrf_fsoicol -mksrf_forganic -mksrf_fglacier -mksrf_fglacierregion -mksrf_fmax -mksrf_furbtopo -mksrf_fsoitex -mksrf_fgdp -mksrf_fpeat -mksrf_fsoildepth -mksrf_fabm -mksrf_ftopostats -mksrf_fvic - - -lnd/clm2/rawdata/mksrf_navyoro_20min.c010129.nc - - - -lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_lai_histclm52deg005_earthstatmirca_2005.c190119.nc - - -lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.c170413.nc - - - -lnd/clm2/rawdata/mksrf_irrig_2160x4320_simyr2000.c110527.nc - -lnd/clm2/rawdata/mksrf_soitex.10level.c010119.nc - -lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_soilcolor_histclm52deg005_earthstatmirca_2005.c190116.nc - - -lnd/clm2/rawdata/pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_soilcolor_CMIP6_simyr2005.c170623.nc - -lnd/clm2/rawdata/mksrf_organic_10level_5x5min_ISRIC-WISE-NCSCD_nlev7_c120830.nc - -lnd/clm2/rawdata/mksrf_fmax_0.125x0.125_c200220.nc - - -lnd/clm2/rawdata/mksrf_LakePnDepth_3x3min_simyr2004_csplk_c151015.nc - -lnd/clm2/rawdata/mksrf_lanwat.050425.nc - - -lnd/clm2/rawdata/mksrf_vocef_0.5x0.5_simyr2000.c110531.nc - - -lnd/clm2/rawdata/mksrf_urban_0.05x0.05_simyr2000.c120621.nc - -lnd/clm2/rawdata/mksrf_urban_0.05x0.05_zerourbanpct.c181014.nc - - - -lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000.c120926.nc -lnd/clm2/rawdata/mksrf_glacier_3x3min_simyr2000_mergeGreenland.c120921.nc - - -lnd/clm2/rawdata/mksrf_GlacierRegion_10x10min_nomask_c191120.nc - - -lnd/clm2/rawdata/mksrf_topo.10min.c191120.nc - - -lnd/clm2/rawdata/mksrf_gdp_0.5x0.5_AVHRR_simyr2000.c130228.nc -lnd/clm2/rawdata/mksrf_gdp_0.5x0_zerogdp.c200413.nc - -lnd/clm2/rawdata/mksrf_peatf_0.5x0.5_AVHRR_simyr2000.c130228.nc - -lnd/clm2/rawdata/mksf_soilthk_5x5min_ORNL-Soil_simyr1900-2015_c170630.nc - -lnd/clm2/rawdata/mksrf_abm_0.5x0.5_AVHRR_simyr2000.c130201.nc -lnd/clm2/rawdata/mksrf_abm_0.5x0.5_missingabm.c200413.nc - - -lnd/clm2/rawdata/mksrf_topostats_1km-merge-10min_HYDRO1K-merge-nomask_simyr2000.c130402.nc - -lnd/clm2/rawdata/mksrf_vic_0.9x1.25_GRDC_simyr2000.c130307.nc - - - - -lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_1850.c190119.nc - -lnd/clm2/rawdata/pftcftdynharv.0.05x0.05.LUH2.histsimyr2005.c190116/mksrf_landuse_clm52deg005_histLUH2_2005.c190119.nc - - - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_850.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_851.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_852.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_853.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_854.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_855.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_856.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_857.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_858.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_859.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_860.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_861.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_862.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_863.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_864.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_865.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_866.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_867.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_868.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_869.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_870.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_871.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_872.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_873.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_874.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_875.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_876.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_877.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_878.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_879.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_880.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_881.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_882.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_883.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_884.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_885.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_886.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_887.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_888.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_889.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_890.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_891.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_892.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_893.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_894.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_895.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_896.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_897.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_898.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_899.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_900.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_901.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_902.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_903.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_904.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_905.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_906.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_907.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_908.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_909.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_910.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_911.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_912.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_913.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_914.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_915.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_916.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_917.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_918.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_919.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_920.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_921.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_922.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_923.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_924.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_925.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_926.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_927.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_928.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_929.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_930.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_931.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_932.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_933.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_934.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_935.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_936.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_937.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_938.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_939.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_940.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_941.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_942.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_943.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_944.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_945.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_946.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_947.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_948.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_949.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_950.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_951.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_952.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_953.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_954.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_955.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_956.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_957.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_958.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_959.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_960.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_961.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_962.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_963.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_964.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_965.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_966.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_967.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_968.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_969.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_970.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_971.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_972.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_973.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_974.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_975.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_976.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_977.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_978.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_979.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_980.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_981.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_982.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_983.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_984.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_985.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_986.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_987.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_988.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_989.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_990.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_991.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_992.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_993.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_994.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_995.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_996.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_997.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_998.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_999.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1000.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1001.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1002.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1003.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1004.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1005.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1006.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1007.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1008.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1009.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1010.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1011.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1012.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1013.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1014.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1015.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1016.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1017.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1018.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1019.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1020.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1021.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1022.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1023.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1024.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1025.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1026.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1027.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1028.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1029.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1030.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1031.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1032.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1033.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1034.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1035.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1036.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1037.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1038.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1039.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1040.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1041.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1042.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1043.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1044.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1045.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1046.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1047.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1048.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1049.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1050.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1051.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1052.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1053.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1054.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1055.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1056.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1057.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1058.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1059.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1060.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1061.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1062.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1063.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1064.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1065.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1066.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1067.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1068.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1069.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1070.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1071.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1072.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1073.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1074.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1075.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1076.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1077.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1078.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1079.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1080.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1081.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1082.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1083.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1084.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1085.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1086.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1087.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1088.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1089.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1090.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1091.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1092.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1093.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1094.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1095.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1096.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1097.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1098.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1099.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1100.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1101.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1102.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1103.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1104.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1105.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1106.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1107.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1108.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1109.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1110.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1111.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1112.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1113.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1114.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1115.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1116.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1117.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1118.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1119.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1120.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1121.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1122.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1123.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1124.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1125.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1126.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1127.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1128.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1129.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1130.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1131.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1132.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1133.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1134.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1135.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1136.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1137.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1138.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1139.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1140.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1141.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1142.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1143.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1144.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1145.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1146.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1147.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1148.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1149.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1150.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1151.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1152.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1153.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1154.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1155.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1156.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1157.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1158.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1159.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1160.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1161.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1162.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1163.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1164.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1165.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1166.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1167.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1168.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1169.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1170.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1171.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1172.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1173.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1174.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1175.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1176.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1177.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1178.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1179.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1180.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1181.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1182.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1183.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1184.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1185.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1186.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1187.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1188.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1189.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1190.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1191.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1192.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1193.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1194.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1195.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1196.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1197.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1198.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1199.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1200.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1201.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1202.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1203.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1204.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1205.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1206.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1207.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1208.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1209.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1210.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1211.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1212.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1213.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1214.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1215.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1216.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1217.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1218.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1219.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1220.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1221.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1222.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1223.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1224.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1225.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1226.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1227.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1228.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1229.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1230.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1231.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1232.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1233.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1234.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1235.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1236.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1237.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1238.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1239.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1240.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1241.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1242.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1243.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1244.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1245.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1246.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1247.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1248.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1249.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1250.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1251.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1252.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1253.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1254.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1255.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1256.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1257.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1258.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1259.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1260.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1261.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1262.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1263.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1264.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1265.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1266.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1267.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1268.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1269.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1270.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1271.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1272.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1273.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1274.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1275.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1276.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1277.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1278.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1279.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1280.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1281.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1282.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1283.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1284.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1285.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1286.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1287.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1288.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1289.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1290.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1291.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1292.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1293.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1294.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1295.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1296.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1297.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1298.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1299.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1300.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1301.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1302.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1303.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1304.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1305.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1306.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1307.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1308.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1309.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1310.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1311.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1312.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1313.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1314.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1315.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1316.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1317.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1318.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1319.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1320.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1321.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1322.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1323.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1324.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1325.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1326.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1327.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1328.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1329.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1330.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1331.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1332.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1333.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1334.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1335.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1336.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1337.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1338.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1339.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1340.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1341.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1342.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1343.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1344.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1345.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1346.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1347.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1348.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1349.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1350.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1351.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1352.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1353.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1354.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1355.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1356.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1357.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1358.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1359.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1360.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1361.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1362.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1363.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1364.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1365.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1366.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1367.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1368.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1369.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1370.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1371.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1372.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1373.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1374.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1375.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1376.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1377.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1378.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1379.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1380.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1381.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1382.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1383.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1384.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1385.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1386.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1387.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1388.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1389.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1390.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1391.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1392.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1393.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1394.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1395.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1396.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1397.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1398.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1399.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1400.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1401.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1402.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1403.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1404.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1405.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1406.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1407.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1408.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1409.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1410.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1411.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1412.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1413.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1414.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1415.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1416.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1417.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1418.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1419.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1420.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1421.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1422.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1423.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1424.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1425.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1426.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1427.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1428.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1429.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1430.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1431.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1432.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1433.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1434.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1435.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1436.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1437.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1438.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1439.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1440.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1441.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1442.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1443.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1444.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1445.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1446.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1447.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1448.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1449.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1450.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1451.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1452.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1453.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1454.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1455.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1456.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1457.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1458.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1459.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1460.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1461.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1462.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1463.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1464.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1465.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1466.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1467.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1468.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1469.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1470.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1471.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1472.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1473.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1474.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1475.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1476.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1477.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1478.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1479.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1480.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1481.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1482.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1483.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1484.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1485.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1486.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1487.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1488.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1489.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1490.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1491.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1492.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1493.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1494.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1495.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1496.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1497.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1498.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1499.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1500.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1501.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1502.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1503.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1504.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1505.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1506.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1507.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1508.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1509.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1510.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1511.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1512.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1513.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1514.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1515.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1516.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1517.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1518.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1519.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1520.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1521.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1522.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1523.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1524.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1525.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1526.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1527.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1528.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1529.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1530.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1531.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1532.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1533.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1534.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1535.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1536.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1537.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1538.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1539.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1540.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1541.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1542.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1543.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1544.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1545.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1546.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1547.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1548.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1549.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1550.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1551.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1552.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1553.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1554.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1555.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1556.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1557.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1558.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1559.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1560.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1561.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1562.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1563.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1564.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1565.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1566.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1567.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1568.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1569.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1570.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1571.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1572.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1573.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1574.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1575.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1576.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1577.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1578.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1579.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1580.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1581.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1582.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1583.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1584.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1585.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1586.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1587.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1588.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1589.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1590.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1591.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1592.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1593.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1594.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1595.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1596.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1597.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1598.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1599.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1600.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1601.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1602.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1603.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1604.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1605.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1606.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1607.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1608.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1609.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1610.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1611.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1612.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1613.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1614.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1615.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1616.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1617.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1618.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1619.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1620.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1621.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1622.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1623.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1624.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1625.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1626.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1627.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1628.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1629.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1630.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1631.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1632.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1633.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1634.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1635.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1636.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1637.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1638.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1639.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1640.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1641.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1642.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1643.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1644.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1645.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1646.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1647.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1648.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1649.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1650.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1651.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1652.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1653.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1654.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1655.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1656.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1657.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1658.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1659.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1660.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1661.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1662.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1663.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1664.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1665.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1666.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1667.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1668.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1669.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1670.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1671.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1672.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1673.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1674.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1675.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1676.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1677.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1678.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1679.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1680.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1681.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1682.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1683.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1684.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1685.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1686.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1687.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1688.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1689.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1690.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1691.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1692.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1693.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1694.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1695.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1696.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1697.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1698.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1699.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1700.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1701.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1702.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1703.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1704.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1705.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1706.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1707.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1708.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1709.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1710.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1711.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1712.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1713.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1714.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1715.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1716.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1717.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1718.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1719.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1720.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1721.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1722.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1723.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1724.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1725.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1726.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1727.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1728.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1729.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1730.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1731.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1732.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1733.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1734.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1735.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1736.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1737.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1738.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1739.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1740.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1741.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1742.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1743.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1744.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1745.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1746.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1747.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1748.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1749.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1750.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1751.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1752.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1753.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1754.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1755.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1756.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1757.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1758.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1759.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1760.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1761.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1762.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1763.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1764.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1765.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1766.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1767.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1768.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1769.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1770.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1771.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1772.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1773.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1774.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1775.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1776.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1777.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1778.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1779.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1780.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1781.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1782.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1783.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1784.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1785.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1786.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1787.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1788.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1789.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1790.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1791.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1792.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1793.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1794.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1795.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1796.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1797.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1798.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1799.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1800.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1801.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1802.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1803.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1804.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1805.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1806.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1807.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1808.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1809.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1810.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1811.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1812.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1813.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1814.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1815.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1816.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1817.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1818.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1819.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1820.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1821.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1822.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1823.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1824.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1825.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1826.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1827.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1828.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1829.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1830.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1831.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1832.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1833.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1834.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1835.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1836.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1837.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1838.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1839.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1840.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1841.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1842.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1843.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1844.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1845.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1846.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1847.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1848.c171012.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012/mksrf_landuse_histclm50_LUH2_1849.c171012.nc - - - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1850.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1851.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1852.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1853.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1854.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1855.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1856.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1857.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1858.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1859.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1860.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1861.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1862.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1863.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1864.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1865.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1866.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1867.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1868.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1869.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1870.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1871.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1872.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1873.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1874.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1875.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1876.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1877.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1878.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1879.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1880.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1881.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1882.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1883.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1884.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1885.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1886.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1887.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1888.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1889.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1890.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1891.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1892.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1893.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1894.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1895.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1896.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1897.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1898.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1899.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1900.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1901.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1902.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1903.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1904.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1905.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1906.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1907.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1908.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1909.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1910.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1911.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1912.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1913.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1914.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1915.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1916.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1917.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1918.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1919.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1920.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1921.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1922.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1923.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1924.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1925.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1926.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1927.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1928.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1929.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1930.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1931.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1932.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1933.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1934.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1935.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1936.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1937.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1938.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1939.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1940.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1941.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1942.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1943.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1944.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1945.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1946.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1947.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1948.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1949.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1950.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1951.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1952.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1953.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1954.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1955.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1956.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1957.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1958.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1959.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1960.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1961.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1962.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1963.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1964.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1965.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1966.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1967.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1968.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1969.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1970.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1971.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1972.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1973.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1974.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1975.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1976.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1977.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1978.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1979.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1980.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1981.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1982.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1983.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1984.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1985.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1986.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1987.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1988.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1989.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1990.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1991.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1992.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1993.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1994.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1995.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1996.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1997.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1998.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1999.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2000.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2001.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2002.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2003.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2004.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2005.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2006.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2007.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2008.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2009.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2010.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2011.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2012.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2013.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2014.c170629.nc - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_2015.c170629.nc - - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.simyrPtVg.c181106/mksrf_landuse_potvegclm50_LUH2.c181106.nc - - - - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2016.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2017.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2018.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2019.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2020.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2021.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2022.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2023.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2024.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2025.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2026.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2027.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2028.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2029.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2030.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2031.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2032.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2033.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2034.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2035.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2036.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2037.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2038.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2039.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2040.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2041.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2042.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2043.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2044.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2045.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2046.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2047.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2048.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2049.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2050.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2051.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2052.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2053.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2054.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2055.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2056.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2057.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2058.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2059.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2060.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2061.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2062.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2063.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2064.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2065.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2066.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2067.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2068.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2069.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2070.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2071.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2072.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2073.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2074.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2075.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2076.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2077.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2078.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2079.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2080.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2081.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2082.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2083.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2084.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2085.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2086.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2087.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2088.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2089.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2090.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2091.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2092.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2093.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2094.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2095.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2096.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2097.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2098.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2099.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-2.6.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP26_clm5_2100.c181217.nc - - - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2016.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2017.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2018.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2019.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2020.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2021.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2022.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2023.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2024.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2025.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2026.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2027.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2028.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2029.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2030.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2031.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2032.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2033.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2034.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2035.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2036.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2037.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2038.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2039.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2040.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2041.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2042.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2043.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2044.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2045.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2046.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2047.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2048.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2049.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2050.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2051.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2052.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2053.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2054.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2055.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2056.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2057.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2058.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2059.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2060.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2061.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2062.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2063.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2064.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2065.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2066.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2067.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2068.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2069.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2070.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2071.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2072.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2073.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2074.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2075.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2076.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2077.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2078.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2079.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2080.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2081.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2082.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2083.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2084.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2085.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2086.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2087.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2088.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2089.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2090.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2091.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2092.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2093.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2094.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2095.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2096.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2097.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2098.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2099.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP3-7.0.simyr2016-2100.c181217/mksrf_landuse_SSP3RCP70_clm5_2100.c181217.nc - - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2016.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2017.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2018.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2019.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2020.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2021.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2022.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2023.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2024.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2025.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2026.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2027.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2028.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2029.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2030.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2031.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2032.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2033.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2034.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2035.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2036.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2037.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2038.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2039.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2040.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2041.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2042.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2043.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2044.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2045.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2046.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2047.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2048.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2049.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2050.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2051.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2052.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2053.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2054.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2055.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2056.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2057.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2058.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2059.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2060.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2061.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2062.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2063.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2064.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2065.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2066.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2067.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2068.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2069.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2070.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2071.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2072.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2073.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2074.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2075.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2076.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2077.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2078.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2079.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2080.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2081.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2082.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2083.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2084.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2085.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2086.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2087.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2088.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2089.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2090.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2091.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2092.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2093.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2094.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2095.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2096.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2097.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2098.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2099.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP5RCP34_clm5_2100.c181217.nc - - - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2016.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2017.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2018.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2019.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2020.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2021.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2022.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2023.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2024.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2025.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2026.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2027.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2028.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2029.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2030.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2031.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2032.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2033.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2034.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2035.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2036.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2037.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2038.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2039.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2040.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2041.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2042.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2043.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2044.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2045.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2046.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2047.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2048.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2049.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2050.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2051.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2052.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2053.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2054.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2055.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2056.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2057.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2058.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2059.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2060.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2061.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2062.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2063.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2064.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2065.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2066.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2067.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2068.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2069.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2070.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2071.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2072.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2073.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2074.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2075.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2076.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2077.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2078.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2079.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2080.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2081.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2082.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2083.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2084.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2085.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2086.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2087.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2088.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2089.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2090.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2091.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2092.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2093.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2094.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2095.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2096.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2097.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2098.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2099.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP2-4.5.simyr2016-2100.c181217/mksrf_landuse_SSP2RCP45_clm5_2100.c181217.nc - - - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2016.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2017.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2018.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2019.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2020.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2021.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2022.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2023.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2024.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2025.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2026.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2027.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2028.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2029.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2030.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2031.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2032.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2033.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2034.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2035.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2036.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2037.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2038.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2039.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2040.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2041.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2042.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2043.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2044.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2045.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2046.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2047.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2048.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2049.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2050.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2051.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2052.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2053.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2054.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2055.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2056.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2057.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2058.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2059.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2060.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2061.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2062.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2063.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2064.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2065.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2066.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2067.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2068.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2069.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2070.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2071.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2072.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2073.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2074.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2075.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2076.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2077.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2078.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2079.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2080.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2081.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2082.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2083.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2084.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2085.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2086.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2087.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2088.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2089.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2090.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2091.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2092.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2093.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2094.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2095.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2096.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2097.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2098.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2099.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP1-1.9.simyr2016-2100.c181217/mksrf_landuse_SSP1RCP19_clm5_2100.c181217.nc - - - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2016.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2017.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2018.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2019.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2020.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2021.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2022.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2023.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2024.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2025.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2026.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2027.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2028.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2029.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2030.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2031.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2032.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2033.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2034.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2035.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2036.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2037.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2038.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2039.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2040.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2041.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2042.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2043.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2044.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2045.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2046.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2047.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2048.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2049.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2050.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2051.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2052.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2053.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2054.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2055.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2056.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2057.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2058.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2059.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2060.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2061.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2062.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2063.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2064.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2065.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2066.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2067.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2068.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2069.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2070.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2071.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2072.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2073.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2074.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2075.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2076.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2077.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2078.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2079.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2080.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2081.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2082.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2083.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2084.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2085.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2086.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2087.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2088.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2089.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2090.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2091.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2092.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2093.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2094.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2095.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2096.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2097.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2098.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2099.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-3.4.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP34_clm5_2100.c181217.nc - - - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2016.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2017.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2018.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2019.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2020.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2021.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2022.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2023.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2024.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2025.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2026.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2027.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2028.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2029.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2030.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2031.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2032.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2033.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2034.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2035.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2036.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2037.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2038.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2039.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2040.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2041.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2042.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2043.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2044.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2045.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2046.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2047.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2048.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2049.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2050.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2051.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2052.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2053.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2054.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2055.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2056.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2057.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2058.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2059.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2060.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2061.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2062.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2063.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2064.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2065.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2066.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2067.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2068.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2069.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2070.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2071.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2072.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2073.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2074.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2075.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2076.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2077.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2078.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2079.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2080.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2081.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2082.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2083.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2084.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2085.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2086.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2087.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2088.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2089.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2090.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2091.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2092.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2093.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2094.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2095.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2096.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2097.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2098.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2099.c181217.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP4-6.0.simyr2016-2100.c181217/mksrf_landuse_SSP4RCP60_clm5_2100.c181217.nc - - - - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2016.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2017.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2018.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2019.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2020.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2021.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2022.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2023.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2024.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2025.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2026.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2027.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2028.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2029.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2030.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2031.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2032.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2033.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2034.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2035.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2036.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2037.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2038.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2039.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2040.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2041.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2042.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2043.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2044.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2045.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2046.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2047.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2048.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2049.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2050.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2051.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2052.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2053.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2054.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2055.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2056.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2057.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2058.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2059.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2060.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2061.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2062.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2063.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2064.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2065.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2066.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2067.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2068.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2069.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2070.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2071.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2072.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2073.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2074.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2075.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2076.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2077.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2078.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2079.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2080.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2081.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2082.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2083.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2084.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2085.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2086.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2087.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2088.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2089.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2090.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2091.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2092.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2093.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2094.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2095.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2096.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2097.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2098.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2099.c171005.nc - - -lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.SSP5-8.5.simyr2016-2100.c171005/mksrf_landuse_SSP5RCP85_clm5_2100.c171005.nc - - - - -atm/waccm/lb/LBC_17500116-20150116_CMIP6_0p5degLat_c180905.nc -atm/waccm/lb/LBC_1750-2015_CMIP6_GlobAnnAvg_c180926.nc - -atm/waccm/lb/LBC_20140116-25001216_CMIP6_SSP119_0p5degLat_c190514.nc -atm/waccm/lb/LBC_20140116-25001216_CMIP6_SSP126_0p5degLat_c180905.nc -atm/waccm/lb/LBC_20140116-25001216_CMIP6_SSP245_0p5degLat_c180905.nc -atm/waccm/lb/LBC_20140116-25001216_CMIP6_SSP370_0p5degLat_c180905.nc -atm/waccm/lb/LBC_20140116-25001216_CMIP6_SSP119_0p5degLat_c190514.nc -atm/waccm/lb/LBC_20140116-25001216_CMIP6_SSP460_0p5degLat_c180905.nc -atm/waccm/lb/LBC_20140116-25001216_CMIP6_SSP534os_0p5degLat_c180905.nc -atm/waccm/lb/LBC_20140116-25001216_CMIP6_SSP585_0p5degLat_c180905.nc - -atm/waccm/lb/LBC_2014-2500_CMIP6_SSP119_0p5degLat_GlobAnnAvg_c190514.nc -atm/waccm/lb/LBC_2014-2500_CMIP6_SSP126_0p5degLat_GlobAnnAvg_c190301.nc -atm/waccm/lb/LBC_2014-2500_CMIP6_SSP245_0p5degLat_GlobAnnAvg_c190301.nc -atm/waccm/lb/LBC_2014-2500_CMIP6_SSP370_0p5degLat_GlobAnnAvg_c190301.nc -atm/waccm/lb/LBC_2014-2500_CMIP6_SSP434_0p5degLat_GlobAnnAvg_c190514.nc -atm/waccm/lb/LBC_2014-2500_CMIP6_SSP460_0p5degLat_GlobAnnAvg_c190301.nc -atm/waccm/lb/LBC_2014-2500_CMIP6_SSP534os_0p5degLat_GlobAnnAvg_c190301.nc -atm/waccm/lb/LBC_2014-2500_CMIP6_SSP585_0p5degLat_GlobAnnAvg_c190301.nc - - From c4bdf919530d8915c5d54ce86dbeea98b11881ef Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Thu, 14 Mar 2024 14:40:35 -0600 Subject: [PATCH 512/614] Clean up line-too-long pylint complaints. --- python/ctsm/test/test_unit_modify_fsurdat.py | 3 ++- .../gen_mksurfdata_jobscript_multi.py | 22 ++++++++++++++----- .../gen_mksurfdata_jobscript_single.py | 3 ++- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/python/ctsm/test/test_unit_modify_fsurdat.py b/python/ctsm/test/test_unit_modify_fsurdat.py index 3b43e29a04..b796cd940d 100755 --- a/python/ctsm/test/test_unit_modify_fsurdat.py +++ b/python/ctsm/test/test_unit_modify_fsurdat.py @@ -390,7 +390,8 @@ def test_check_varlist_lists_wrongsizes(self): settings = {"var_lev1": lev1list} with self.assertRaisesRegex( SystemExit, - " Variable var_lev1 is 8 is of the wrong size. It should be = 9 in input settings dictionary", + " Variable var_lev1 is 8 is of the wrong size." + + " It should be = 9 in input settings dictionary", ): self.modify_fsurdat.check_varlist(settings) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 9b39f0e829..0e984a8c87 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -168,7 +168,13 @@ def main(): # Determine resolution sets that are referenced in commands # TODO slevis: When new resolutions become supported in ccs_config, the # first entry will change to - # "standard_res_no_crop": ["0.9x1.25", "1.9x2.5", "mpasa60", "mpasa60-3conus", "mpasa60-3centralUS"], + # "standard_res_no_crop": [ + # "0.9x1.25", + # "1.9x2.5", + # "mpasa60", + # "mpasa60-3conus", + # "mpasa60-3centralUS", + # ], # -------------------------- resolution_dict = { "standard_res_no_crop": ["0.9x1.25", "1.9x2.5", "mpasa60"], @@ -246,7 +252,8 @@ def main(): "mpasa480", ), "crop-global-present-nldas": ( - "--start-year 2000 --end-year 2000 --res", # TODO slevis: --hirespft uses old data for now, so keep out + # TODO slevis: --hirespft uses old data for now, so keep out + "--start-year 2000 --end-year 2000 --res", "nldas_res", ), "crop-global-1850": ( @@ -370,7 +377,8 @@ def main(): if not os.path.exists(args.bld_path): print( args.bld_path - + " directory does NOT exist -- build mksurdata_esmf before running this script -- using ./gen_mksurfdata_build.sh" + + " directory does NOT exist -- build mksurdata_esmf before running this script --" + + " using ./gen_mksurfdata_build.sh" ) sys.exit(1) @@ -396,13 +404,15 @@ def main(): runfile.write(f"#PBS -q {queue} \n") runfile.write(f"#PBS -l walltime={walltime} \n") runfile.write( - f"#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node}:mem=218GB \n" + "#PBS -l select=" + + f"{number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node}:mem=218GB \n" ) runfile.write( - f"# This is a batch script to run a set of resolutions for mksurfdata_esmf {scenario} \n" + f"# This is a batch script to run a set of resolutions for mksurfdata_esmf {scenario}\n" ) runfile.write( - "# NOTE: THIS SCRIPT IS AUTOMATICALLY GENERATED SO IN GENERAL YOU SHOULD NOT EDIT it!!\n\n" + "# NOTE: THIS SCRIPT IS AUTOMATICALLY GENERATED " + + "SO IN GENERAL YOU SHOULD NOT EDIT it!!\n\n" ) runfile.write("\n") diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index e0d6c32fee..6fe6fe7372 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -130,7 +130,8 @@ def main(): runfile.write(f"#PBS -A {account} \n") runfile.write("#PBS -q main \n") runfile.write( - f"#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node} \n" + "#PBS -l select=" + + f"{number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node} \n" ) elif machine == "casper": attribs = {"mpilib": "default"} From 58e7f48eae25dddd562aef5160dc1cb88dd99861 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Thu, 14 Mar 2024 15:08:25 -0600 Subject: [PATCH 513/614] gen_mksurfdata_jobscript_multi.py: Remove unused n_p. --- python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 0e984a8c87..d44ce2a346 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -416,8 +416,6 @@ def main(): ) runfile.write("\n") - n_p = int(tasks_per_node) * int(number_of_nodes) - # Run env_mach_specific.sh to control the machine dependent # environment including the paths to compilers and libraries # external to cime such as netcdf From 51bfc445012f8d4d7bd4a7cd769799ac3790d892 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Thu, 14 Mar 2024 15:09:09 -0600 Subject: [PATCH 514/614] gen_mksurfdata_jobscript_single.py: Remove unused import of sys. --- python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py | 1 - 1 file changed, 1 deletion(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 6fe6fe7372..f946ee287b 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -4,7 +4,6 @@ instructions, see README. """ import os -import sys import argparse import logging From a47288af58bd2a338a2d27881f2e986b144df5b5 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Thu, 14 Mar 2024 15:13:39 -0600 Subject: [PATCH 515/614] test_sys_mesh_modifier.py: Fix fsurdat_in complaints. --- python/ctsm/test/test_sys_mesh_modifier.py | 30 ++++++++++------------ 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/python/ctsm/test/test_sys_mesh_modifier.py b/python/ctsm/test/test_sys_mesh_modifier.py index 6b282fa0b0..63ac2044d4 100755 --- a/python/ctsm/test/test_sys_mesh_modifier.py +++ b/python/ctsm/test/test_sys_mesh_modifier.py @@ -44,10 +44,6 @@ def setUp(self): path_to_ctsm_root(), "tools/modify_input_files/modify_mesh_template.cfg" ) self.testinputs_path = os.path.join(path_to_ctsm_root(), "python/ctsm/test/testinputs") - fsurdat_in = os.path.join( - self.testinputs_path, - "surfdata_5x5_amazon_hist_16pfts_CMIP6_2000_c231031.nc", - ) self._tempdir = tempfile.mkdtemp() self._cfg_file_path = os.path.join(self._tempdir, "modify_mesh_mask.cfg") self._mesh_mask_in = os.path.join(self._tempdir, "mesh_mask_in.nc") @@ -72,7 +68,7 @@ def setUp(self): except subprocess.CalledProcessError as e: sys.exit(f"{e} ERROR using {configure_cmd}") - def createScripGridAndMask(self): + def createScripGridAndMask(self, fsurdat_in): """Create the SCRIP gird and mask file""" # Generate scrip file from fsurdat_in using nco # In the ctsm_py environment this requires running 'module load nco' @@ -86,14 +82,14 @@ def createScripGridAndMask(self): # This could also alturnatively be done, by using the stored SCRIP grid file for the resolution under CESM inputdata ncks_cmd = ( - f"ncks --rgr infer --rgr scrip={self.scrip_file} {self.fsurdat_in} {self.metadata_file}" + f"ncks --rgr infer --rgr scrip={self.scrip_file} {fsurdat_in} {self.metadata_file}" ) try: subprocess.check_call(ncks_cmd, shell=True) except subprocess.CalledProcessError as e: err_msg = ( f"{e} ERROR using ncks to generate {self.scrip_file} from " - + f"{self.fsurdat_in}; MOST LIKELY SHOULD INVOKE module load nco" + + f"{fsurdat_in}; MOST LIKELY SHOULD INVOKE module load nco" ) sys.exit(err_msg) # Run .env_mach_specific.sh to load esmf and generate mesh_mask_in @@ -109,13 +105,13 @@ def createScripGridAndMask(self): # Generate landmask_file from fsurdat_in self._lat_varname = "LATIXY" # same as in fsurdat_in self._lon_varname = "LONGXY" # same as in fsurdat_in - fsurdat_in_data = xr.open_dataset(self.fsurdat_in) + fsurdat_in_data = xr.open_dataset(fsurdat_in) assert self._lat_varname in fsurdat_in_data.variables assert self._lon_varname in fsurdat_in_data.variables self._lat_dimname = fsurdat_in_data[self._lat_varname].dims[0] self._lon_dimname = fsurdat_in_data[self._lat_varname].dims[1] - def createLandMaskFile(self): + def createLandMaskFile(self, fsurdat_in): """Create the LandMask file from the input fsurdat_in file""" if os.path.exists(self._landmask_file): os.remove(self._landmask_file) @@ -124,13 +120,13 @@ def createLandMaskFile(self): + "-A -v -s 'landmask=LANDFRAC_MKSURFDATA.convert(NC_INT)' " + f"-A -v -s {self._lat_varname}={self._lat_varname} " + f"-A -v -s {self._lon_varname}={self._lon_varname} " - + f"{self.fsurdat_in} {self._landmask_file}" + + f"{fsurdat_in} {self._landmask_file}" ) try: subprocess.check_call(ncap2_cmd, shell=True) except subprocess.CalledProcessError as e: sys.exit( - f"{e} ERROR using ncap2 to generate {self._landmask_file} from {self.fsurdat_in}" + f"{e} ERROR using ncap2 to generate {self._landmask_file} from {fsurdat_in}" ) def tearDown(self): @@ -147,13 +143,13 @@ def test_allInfo(self): For a case where the mesh remains unchanged, it's just output as ocean so the mesh is output as all zero's rather than the all 1's that came in. """ - self.fsurdat_in = os.path.join( + fsurdat_in = os.path.join( self.testinputs_path, "surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517.nc", ) - self.createScripGridAndMask() - self.createLandMaskFile() + self.createScripGridAndMask(fsurdat_in) + self.createLandMaskFile(fsurdat_in) self._create_config_file() # run the mesh_mask_modifier tool @@ -185,12 +181,12 @@ def test_modifyMesh(self): For a case where the mesh is changed. """ - self.fsurdat_in = os.path.join( + fsurdat_in = os.path.join( self.testinputs_path, "surfdata_5x5_amazon_hist_78pfts_CMIP6_2000_c230517_modify_mask.nc", ) - self.createScripGridAndMask() - self.createLandMaskFile() + self.createScripGridAndMask(fsurdat_in) + self.createLandMaskFile(fsurdat_in) self._create_config_file() if os.path.exists(self._mesh_mask_out): From 4fdcc8183c50a5b7bbc1188473fa0d81ee97186b Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Thu, 14 Mar 2024 15:17:08 -0600 Subject: [PATCH 516/614] gen_mksurfdata_namelist.py: Ignore warnings about missing netCDF4.Dataset. --- python/ctsm/toolchain/gen_mksurfdata_namelist.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/ctsm/toolchain/gen_mksurfdata_namelist.py b/python/ctsm/toolchain/gen_mksurfdata_namelist.py index 9d6eecbc9d..e81ade30dd 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_namelist.py +++ b/python/ctsm/toolchain/gen_mksurfdata_namelist.py @@ -297,6 +297,7 @@ def main(): if force_model_mesh_file is not None: # open mesh_file to read element_count and, if available, orig_grid_dims + # pylint: disable=no-name-in-module,no-member mesh_file = netCDF4.Dataset(force_model_mesh_file, "r") element_count = mesh_file.dimensions["elementCount"].size if "origGridDims" in mesh_file.variables: From 31ed3a14ec3e62ed0c8abd0b6d9f0ace8a6544a5 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Thu, 14 Mar 2024 15:57:49 -0600 Subject: [PATCH 517/614] Resolve dangerous-default-value warnings. --- python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py | 4 +++- python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py index c7f2df5d0a..6f6bd88553 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_multi.py @@ -47,10 +47,12 @@ def tearDown(self): os.chdir(self._original_wd) shutil.rmtree(self._tempdir, ignore_errors=True) - def createJS(self, nodes, tasks_per_node, scenario, option_list=[]): + def createJS(self, nodes, tasks_per_node, scenario, option_list=None): """ Create a JobScript by sending a list of options in """ + if option_list is None: + option_list = [] if len(option_list) > 1: sys.argv.extend(option_list) sys.argv.extend( diff --git a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py index 5913142a68..fdcc97ffd1 100755 --- a/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_sys_gen_mksurfdata_jobscript_single.py @@ -50,10 +50,12 @@ def tearDown(self): os.chdir(self._original_wd) shutil.rmtree(self._tempdir, ignore_errors=True) - def createJS(self, nodes, tasks_per_node, option_list=[]): + def createJS(self, nodes, tasks_per_node, option_list=None): """ Create a JobScript by sending a list of options in """ + if option_list is None: + option_list = [] if len(option_list) > 1: sys.argv.extend(option_list) sys.argv.extend( From ab84f1fc21ce08e91d0e9de2e7cbb7c297ca9ec3 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Thu, 14 Mar 2024 15:58:27 -0600 Subject: [PATCH 518/614] Ignore wrong-import-order complaints. Imports from CIME must come after `from ctsm import add_cime_to_path`. --- python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index f946ee287b..04a2ee1bb4 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -11,8 +11,10 @@ from ctsm.ctsm_logging import setup_logging_pre_config, add_logging_args, process_logging_args from ctsm.utils import abort from ctsm.path_utils import path_to_ctsm_root -from CIME.XML.env_mach_specific import EnvMachSpecific # pylint: disable=import-error -from CIME.BuildTools.configure import FakeCase # pylint: disable=import-error +from CIME.XML.env_mach_specific \ + import EnvMachSpecific # pylint: disable=import-error,wrong-import-order +from CIME.BuildTools.configure \ + import FakeCase # pylint: disable=import-error,wrong-import-order logger = logging.getLogger(__name__) From 2751a1d695f3b5d66a292ed8a61339ed0f7d5f94 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Thu, 14 Mar 2024 16:18:08 -0600 Subject: [PATCH 519/614] Refactor gen_mksurfdata_jobscript_single main() to under 50 statements. --- .../gen_mksurfdata_jobscript_single.py | 218 ++++++++++-------- 1 file changed, 117 insertions(+), 101 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 04a2ee1bb4..143c6692ea 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -94,6 +94,75 @@ def get_parser(): return parser +def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, runfile): + """ + Write run script (part 1) + """ + runfile.write("#!/bin/bash \n") + runfile.write("# Edit the batch directives for your batch system \n") + runfile.write(f"# Below are default batch directives for {machine} \n") + runfile.write("#PBS -N mksurfdata \n") + runfile.write("#PBS -j oe \n") + runfile.write("#PBS -k eod \n") + runfile.write("#PBS -S /bin/bash \n") + if machine == "derecho": + attribs = {"mpilib": "default"} + runfile.write("#PBS -l walltime=59:00 \n") + runfile.write(f"#PBS -A {account} \n") + runfile.write("#PBS -q main \n") + runfile.write( + "#PBS -l select=" + + f"{number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node} \n" + ) + elif machine == "casper": + attribs = {"mpilib": "default"} + runfile.write("#PBS -l walltime=1:00:00 \n") + runfile.write(f"#PBS -A {account} \n") + runfile.write("#PBS -q casper \n") + runfile.write( + f"#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:" + f"mpiprocs={tasks_per_node}:mem=80GB \n" + ) + elif machine == "izumi": + attribs = {"mpilib": "mvapich2"} + runfile.write("#PBS -l walltime=2:00:00 \n") + runfile.write("#PBS -q medium \n") + runfile.write(f"#PBS -l nodes={number_of_nodes}:ppn={tasks_per_node},mem=555GB -r n \n") + tool_path = os.path.dirname(os.path.abspath(__file__)) + runfile.write("\n") + runfile.write(f"cd {tool_path} \n") + + runfile.write("\n") + return attribs + + +def write_runscript_part2(namelist_file, runfile, executable, mksurfdata_path, env_mach_path): + """ + Write run script (part 2) + """ + runfile.write( + "# Run env_mach_specific.sh to control the machine " + "dependent environment including the paths to " + "compilers and libraries external to cime such as netcdf" + ) + runfile.write(f"\n. {env_mach_path}\n") + check = 'if [ $? != 0 ]; then echo "Error running env_mach_specific"; exit -4; fi' + runfile.write(f"{check} \n") + runfile.write( + "# Edit the mpirun command to use the MPI executable " + "on your system and the arguments it requires \n" + ) + output = f"{executable} {mksurfdata_path} < {namelist_file}" + runfile.write(f"{output} \n") + logger.info("run command is %s", output) + + check = ( + f'if [ $? != 0 ]; then echo "Error running for namelist {namelist_file}"; exit -4; fi' + ) + runfile.write(f"{check} \n") + runfile.write("echo Successfully ran resolution\n") + + def main(): """ See docstring at the top. @@ -118,110 +187,57 @@ def main(): # Write run script (part 1) # -------------------------- with open(jobscript_file, "w", encoding="utf-8") as runfile: - runfile.write("#!/bin/bash \n") - runfile.write("# Edit the batch directives for your batch system \n") - runfile.write(f"# Below are default batch directives for {machine} \n") - runfile.write("#PBS -N mksurfdata \n") - runfile.write("#PBS -j oe \n") - runfile.write("#PBS -k eod \n") - runfile.write("#PBS -S /bin/bash \n") - if machine == "derecho": - attribs = {"mpilib": "default"} - runfile.write("#PBS -l walltime=59:00 \n") - runfile.write(f"#PBS -A {account} \n") - runfile.write("#PBS -q main \n") - runfile.write( - "#PBS -l select=" - + f"{number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node} \n" - ) - elif machine == "casper": - attribs = {"mpilib": "default"} - runfile.write("#PBS -l walltime=1:00:00 \n") - runfile.write(f"#PBS -A {account} \n") - runfile.write("#PBS -q casper \n") - runfile.write( - f"#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:" - f"mpiprocs={tasks_per_node}:mem=80GB \n" - ) - elif machine == "izumi": - attribs = {"mpilib": "mvapich2"} - runfile.write("#PBS -l walltime=2:00:00 \n") - runfile.write("#PBS -q medium \n") - runfile.write(f"#PBS -l nodes={number_of_nodes}:ppn={tasks_per_node},mem=555GB -r n \n") - tool_path = os.path.dirname(os.path.abspath(__file__)) - runfile.write("\n") - runfile.write(f"cd {tool_path} \n") - - runfile.write("\n") + attribs = write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, runfile) - # -------------------------- - # Obtain mpirun command from env_mach_specific.xml - # -------------------------- - bld_path = args.bld_path - if not os.path.exists(bld_path): - abort("Input Build path (" + bld_path + ") does NOT exist, aborting") - # Get the ems_file object with standalone_configure=True - # and the fake_case object with mpilib=attribs['mpilib'] - # so as to use the get_mpirun function pointing to fake_case - ems_file = EnvMachSpecific(bld_path, standalone_configure=True) - fake_case = FakeCase( - compiler=None, mpilib=attribs["mpilib"], debug=False, comp_interface=None - ) - total_tasks = int(tasks_per_node) * int(number_of_nodes) - cmd = ems_file.get_mpirun( - fake_case, - attribs, - job="name", - exe_only=True, - overrides={ - "total_tasks": total_tasks, - }, - ) - # cmd is a tuple: - # cmd[0] contains the mpirun command (eg mpirun, mpiexe, etc) as string - # cmd[1] contains a list of strings that we append as options to cmd[0] - # The replace function removes unnecessary characters that appear in - # some such options - executable = f'{cmd[0]} {" ".join(cmd[1])}'.replace("ENV{", "").replace("}", "") - - mksurfdata_path = os.path.join(bld_path, "mksurfdata") - if not os.path.exists(mksurfdata_path): - abort( - "mksurfdata_esmf executable (" - + mksurfdata_path - + ") does NOT exist in the bld-path, aborting" - ) - env_mach_path = os.path.join(bld_path, ".env_mach_specific.sh") - if not os.path.exists(env_mach_path): - abort( - "Environment machine specific file (" - + env_mach_path - + ") does NOT exist in the bld-path, aborting" - ) - - # -------------------------- - # Write run script (part 2) - # -------------------------- - runfile.write( - "# Run env_mach_specific.sh to control the machine " - "dependent environment including the paths to " - "compilers and libraries external to cime such as netcdf" + # -------------------------- + # Obtain mpirun command from env_mach_specific.xml + # -------------------------- + bld_path = args.bld_path + if not os.path.exists(bld_path): + abort("Input Build path (" + bld_path + ") does NOT exist, aborting") + # Get the ems_file object with standalone_configure=True + # and the fake_case object with mpilib=attribs['mpilib'] + # so as to use the get_mpirun function pointing to fake_case + ems_file = EnvMachSpecific(bld_path, standalone_configure=True) + fake_case = FakeCase( + compiler=None, mpilib=attribs["mpilib"], debug=False, comp_interface=None + ) + total_tasks = int(tasks_per_node) * int(number_of_nodes) + cmd = ems_file.get_mpirun( + fake_case, + attribs, + job="name", + exe_only=True, + overrides={ + "total_tasks": total_tasks, + }, + ) + # cmd is a tuple: + # cmd[0] contains the mpirun command (eg mpirun, mpiexe, etc) as string + # cmd[1] contains a list of strings that we append as options to cmd[0] + # The replace function removes unnecessary characters that appear in + # some such options + executable = f'{cmd[0]} {" ".join(cmd[1])}'.replace("ENV{", "").replace("}", "") + + mksurfdata_path = os.path.join(bld_path, "mksurfdata") + if not os.path.exists(mksurfdata_path): + abort( + "mksurfdata_esmf executable (" + + mksurfdata_path + + ") does NOT exist in the bld-path, aborting" ) - runfile.write(f"\n. {env_mach_path}\n") - check = 'if [ $? != 0 ]; then echo "Error running env_mach_specific"; exit -4; fi' - runfile.write(f"{check} \n") - runfile.write( - "# Edit the mpirun command to use the MPI executable " - "on your system and the arguments it requires \n" + env_mach_path = os.path.join(bld_path, ".env_mach_specific.sh") + if not os.path.exists(env_mach_path): + abort( + "Environment machine specific file (" + + env_mach_path + + ") does NOT exist in the bld-path, aborting" ) - output = f"{executable} {mksurfdata_path} < {namelist_file}" - runfile.write(f"{output} \n") - logger.info("run command is %s", output) - check = ( - f'if [ $? != 0 ]; then echo "Error running for namelist {namelist_file}"; exit -4; fi' - ) - runfile.write(f"{check} \n") - runfile.write("echo Successfully ran resolution\n") + # -------------------------- + # Write run script (part 2) + # -------------------------- + with open(jobscript_file, "a", encoding="utf-8") as runfile: + write_runscript_part2(namelist_file, runfile, executable, mksurfdata_path, env_mach_path) print(f"echo Successfully created jobscript {jobscript_file}\n") From 9455a3345e30cdca16b5d6178c2aca13bae8595d Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Thu, 14 Mar 2024 16:24:01 -0600 Subject: [PATCH 520/614] Refactor gen_mksurfdata_jobscript_multi main() to under 50 statements. --- .../gen_mksurfdata_jobscript_multi.py | 141 +++++++++++------- 1 file changed, 88 insertions(+), 53 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index d44ce2a346..6e8d6ee3a7 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -137,6 +137,74 @@ def get_parser(): return parser +def write_runscript( + scenario, + jobscript_file, + number_of_nodes, + tasks_per_node, + account, + walltime, + queue, + target_list, + resolution_dict, + dataset_dict, + env_specific_script, + mksurfdata, + runfile, +): + """ + Write run script + """ + runfile.write("#!/bin/bash \n") + runfile.write(f"#PBS -A {account} \n") + runfile.write(f"#PBS -N mksrf_{scenario} \n") + runfile.write("#PBS -j oe \n") + runfile.write("#PBS -k eod \n") + runfile.write("#PBS -S /bin/bash \n") + runfile.write(f"#PBS -q {queue} \n") + runfile.write(f"#PBS -l walltime={walltime} \n") + runfile.write( + "#PBS -l select=" + + f"{number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node}:mem=218GB \n" + ) + runfile.write( + f"# This is a batch script to run a set of resolutions for mksurfdata_esmf {scenario}\n" + ) + runfile.write( + "# NOTE: THIS SCRIPT IS AUTOMATICALLY GENERATED " + + "SO IN GENERAL YOU SHOULD NOT EDIT it!!\n\n" + ) + runfile.write("\n") + + # Run env_mach_specific.sh to control the machine dependent + # environment including the paths to compilers and libraries + # external to cime such as netcdf + runfile.write(". " + env_specific_script + "\n") + check = "if [ $? != 0 ]; then echo 'Error running env_specific_script'; exit -4; fi" + runfile.write(f"{check} \n") + for target in target_list: + res_set = dataset_dict[target][1] + if res_set not in resolution_dict: + abort(f"Resolution is not in the resolution_dict: {res_set}") + for res in resolution_dict[res_set]: + namelist = f"{scenario}_{res}.namelist" + command = os.path.join(os.getcwd(), "gen_mksurfdata_namelist") + command = command + " " + dataset_dict[target][0] + " " + res + command = command + " --silent" + command = command + f" --namelist {namelist}" + print(f"command is {command}") + sys.argv = [x for x in command.split(" ") if x] + main_nml() + print(f"generated namelist {namelist}") + output = f"time mpiexec {mksurfdata} < {namelist}" + runfile.write(f"{output} \n") + check = f"if [ $? != 0 ]; then echo 'Error running resolution {res}'; exit -4; fi" + runfile.write(f"{check} \n") + runfile.write(f"echo Successfully ran resolution {res}\n") + + runfile.write(f"echo Successfully ran {jobscript_file}\n") + + def main(): """ See docstring at the top. @@ -169,12 +237,12 @@ def main(): # TODO slevis: When new resolutions become supported in ccs_config, the # first entry will change to # "standard_res_no_crop": [ - # "0.9x1.25", - # "1.9x2.5", - # "mpasa60", - # "mpasa60-3conus", - # "mpasa60-3centralUS", - # ], + # "0.9x1.25", + # "1.9x2.5", + # "mpasa60", + # "mpasa60-3conus", + # "mpasa60-3centralUS", + # ], # -------------------------- resolution_dict = { "standard_res_no_crop": ["0.9x1.25", "1.9x2.5", "mpasa60"], @@ -395,53 +463,20 @@ def main(): # -------------------------- with open(jobscript_file, "w", encoding="utf-8") as runfile: - runfile.write("#!/bin/bash \n") - runfile.write(f"#PBS -A {account} \n") - runfile.write(f"#PBS -N mksrf_{scenario} \n") - runfile.write("#PBS -j oe \n") - runfile.write("#PBS -k eod \n") - runfile.write("#PBS -S /bin/bash \n") - runfile.write(f"#PBS -q {queue} \n") - runfile.write(f"#PBS -l walltime={walltime} \n") - runfile.write( - "#PBS -l select=" - + f"{number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node}:mem=218GB \n" - ) - runfile.write( - f"# This is a batch script to run a set of resolutions for mksurfdata_esmf {scenario}\n" + write_runscript( + scenario, + jobscript_file, + number_of_nodes, + tasks_per_node, + account, + walltime, + queue, + target_list, + resolution_dict, + dataset_dict, + env_specific_script, + mksurfdata, + runfile, ) - runfile.write( - "# NOTE: THIS SCRIPT IS AUTOMATICALLY GENERATED " - + "SO IN GENERAL YOU SHOULD NOT EDIT it!!\n\n" - ) - runfile.write("\n") - - # Run env_mach_specific.sh to control the machine dependent - # environment including the paths to compilers and libraries - # external to cime such as netcdf - runfile.write(". " + env_specific_script + "\n") - check = "if [ $? != 0 ]; then echo 'Error running env_specific_script'; exit -4; fi" - runfile.write(f"{check} \n") - for target in target_list: - res_set = dataset_dict[target][1] - if res_set not in resolution_dict: - abort(f"Resolution is not in the resolution_dict: {res_set}") - for res in resolution_dict[res_set]: - namelist = f"{scenario}_{res}.namelist" - command = os.path.join(os.getcwd(), "gen_mksurfdata_namelist") - command = command + " " + dataset_dict[target][0] + " " + res - command = command + " --silent" - command = command + f" --namelist {namelist}" - print(f"command is {command}") - sys.argv = [x for x in command.split(" ") if x] - main_nml() - print(f"generated namelist {namelist}") - output = f"time mpiexec {mksurfdata} < {namelist}" - runfile.write(f"{output} \n") - check = f"if [ $? != 0 ]; then echo 'Error running resolution {res}'; exit -4; fi" - runfile.write(f"{check} \n") - runfile.write(f"echo Successfully ran resolution {res}\n") - - runfile.write(f"echo Successfully ran {jobscript_file}\n") print(f"echo Successfully created jobscript {jobscript_file}\n") From 25c0007696ffdb8baf227fa2a06053c80fed8049 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Thu, 14 Mar 2024 17:12:17 -0600 Subject: [PATCH 521/614] Refactor gen_mksurfdata_namelist.py to get all functions under 100 statements. --- .../ctsm/toolchain/gen_mksurfdata_namelist.py | 842 +++++++++++------- 1 file changed, 503 insertions(+), 339 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_namelist.py b/python/ctsm/toolchain/gen_mksurfdata_namelist.py index e81ade30dd..8b8a9b8828 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_namelist.py +++ b/python/ctsm/toolchain/gen_mksurfdata_namelist.py @@ -259,6 +259,7 @@ def main(): """ See docstring at the top. """ + # pylint: disable=too-many-statements args = get_parser().parse_args() process_logging_args(args) @@ -278,6 +279,167 @@ def main(): potveg = args.potveg_flag glc_nec = args.glc_nec + hires_pft, hires_soitex = process_hires_options(args, start_year, end_year) + + if force_model_mesh_file is not None: + open_mesh_file(force_model_mesh_file, force_model_mesh_nx, force_model_mesh_ny) + + hostname = os.getenv("HOSTNAME") + logname = os.getenv("LOGNAME") + + logger.info("hostname is %s", hostname) + logger.info("logname is %s", logname) + + if ssp_rcp == "none": + check_ssp_years(start_year, end_year) + + # determine pft_years - needed to parse xml file + pft_years_ssp, pft_years = determine_pft_years(start_year, end_year, potveg) + + # Create land-use txt file for a transient case. + # Determine the run type and if a transient run create output landuse txt file + if end_year > start_year: + run_type = "transient" + else: + run_type = "timeslice" + logger.info("run_type = %s", run_type) + + # error check on glc_nec + if (glc_nec <= 0) or (glc_nec >= 100): + raise argparse.ArgumentTypeError("ERROR: glc_nec must be between 1 and 99.") + + # create attribute list for parsing xml file + attribute_list = { + "hires_pft": hires_pft, + "hires_soitex": hires_soitex, + "pft_years": pft_years, + "pft_years_ssp": pft_years_ssp, + "ssp_rcp": ssp_rcp, + "res": res, + } + + # determine input rawdata + tool_path, must_run_download_input_data, rawdata_files = determine_input_rawdata( + start_year, + input_path, + attribute_list, + ) + + # determine output mesh + determine_output_mesh(res, force_model_mesh_file, input_path, rawdata_files, tool_path) + + # Determine num_pft + if nocrop_flag: + num_pft = "16" + else: + num_pft = "78" + logger.info("num_pft is %s", num_pft) + + # Write out if surface dataset will be created + if nosurfdata_flag: + logger.info("surface dataset will not be created") + else: + logger.info("surface dataset will be created") + + ( + landuse_fname, + fdyndat, + nlfname, + fsurdat, + fsurlog, + must_run_download_input_data, + ) = get_file_paths( + args, + start_year, + end_year, + ssp_rcp, + res, + pft_years, + run_type, + rawdata_files, + num_pft, + must_run_download_input_data, + ) + + git_desc_cmd = f"git -C {tool_path} describe" + try: + # The "git -C" option permits a system test to run this tool from + # elsewhere while running the git command from the tool_path + gitdescribe = subprocess.check_output(git_desc_cmd, shell=True).strip() + except subprocess.CalledProcessError as error: + # In case the "git -C" option is unavailable, as on casper (2022/5/24) + # Still, this does NOT allow the system test to work on machines + # without git -C + logger.info("git -C option unavailable on casper as of 2022/7/2 %s", error) + gitdescribe = subprocess.check_output("git describe", shell=True).strip() + gitdescribe = gitdescribe.decode("utf-8") + + # The below two overrides are only used for testing and validation + # it takes a long time to generate the mapping files + # from 1km to the following two resolutions since the output mesh has so few points + if res == "10x15": + mksrf_ftopostats_override = os.path.join( + input_path, "lnd", "clm2", "rawdata", "surfdata_topo_10x15_c220303.nc" + ) + logger.info("will override mksrf_ftopostats with = %s", mksrf_ftopostats_override) + else: + mksrf_ftopostats_override = "" + + # ---------------------------------------- + # Write output namelist file + # ---------------------------------------- + + with open(nlfname, "w", encoding="utf-8") as nlfile: + nlfile.write("&mksurfdata_input \n") + + # ------------------- + # raw input data + # ------------------- + must_run_download_input_data = write_nml_rawinput( + start_year, + force_model_mesh_file, + force_model_mesh_nx, + force_model_mesh_ny, + vic_flag, + rawdata_files, + landuse_fname, + mksrf_ftopostats_override, + nlfile, + must_run_download_input_data, + ) + + # ------------------- + # output data + # ------------------- + write_nml_outdata( + nosurfdata_flag, + vic_flag, + inlandwet, + glc_flag, + hostname, + logname, + num_pft, + fdyndat, + fsurdat, + fsurlog, + gitdescribe, + nlfile, + ) + + nlfile.write("/ \n") + + if must_run_download_input_data: + temp_nlfname = "surfdata.namelist" + os.rename(nlfname, temp_nlfname) + nlfname = temp_nlfname + + print(f"Successfully created input namelist file {nlfname}") + + +def process_hires_options(args, start_year, end_year): + """ + Process options related to hi-res + """ if args.hres_pft: if (start_year == 1850 and end_year == 1850) or (start_year == 2005 and end_year == 2005): hires_pft = "on" @@ -294,70 +456,85 @@ def main(): hires_soitex = "on" else: hires_soitex = "off" + return hires_pft, hires_soitex - if force_model_mesh_file is not None: - # open mesh_file to read element_count and, if available, orig_grid_dims - # pylint: disable=no-name-in-module,no-member - mesh_file = netCDF4.Dataset(force_model_mesh_file, "r") - element_count = mesh_file.dimensions["elementCount"].size - if "origGridDims" in mesh_file.variables: - orig_grid_dims = mesh_file.variables["origGridDims"] - if ( - int(force_model_mesh_nx) == orig_grid_dims[0] - and int(force_model_mesh_ny) == orig_grid_dims[1] - ): - mesh_file.close() - else: - error_msg = ( - "ERROR: Found variable origGridDims in " - f"{force_model_mesh_file} with values " - f"{orig_grid_dims[:]} that do not agree with the " - "user-entered mesh_nx and mesh_ny values of " - f"{[force_model_mesh_nx, force_model_mesh_ny]}." - ) - sys.exit(error_msg) - elif force_model_mesh_nx is None or force_model_mesh_ny is None: - error_msg = ( - "ERROR: You set --model-mesh so you MUST ALSO " - "SET --model-mesh-nx AND --model-mesh-ny" - ) - sys.exit(error_msg) - # using force_model_mesh_nx and force_model_mesh_ny either from the - # mesh file (see previous if statement) or the user-entered values - if element_count != int(force_model_mesh_nx) * int(force_model_mesh_ny): - error_msg = ( - "ERROR: The product of " - "--model-mesh-nx x --model-mesh-ny must equal " - "exactly elementCount in --model-mesh" - ) - sys.exit(error_msg) +def check_ssp_years(start_year, end_year): + """ + Check years associated with SSP period + """ + if int(start_year) > 2015: + error_msg = ( + "ERROR: if start-year > 2015 must add an --ssp_rcp " + "argument that is not none: valid opts for ssp-rcp " + f"are {valid_opts}" + ) + sys.exit(error_msg) + elif int(end_year) > 2015: + error_msg = ( + "ERROR: if end-year > 2015 must add an --ssp-rcp " + "argument that is not none: valid opts for ssp-rcp " + f"are {valid_opts}" + ) + sys.exit(error_msg) - hostname = os.getenv("HOSTNAME") - logname = os.getenv("LOGNAME") - logger.info("hostname is %s", hostname) - logger.info("logname is %s", logname) +def get_file_paths( + args, + start_year, + end_year, + ssp_rcp, + res, + pft_years, + run_type, + rawdata_files, + num_pft, + must_run_download_input_data, +): + """ + Get various file paths + """ + if run_type == "transient": + landuse_fname, must_run_download_input_data = handle_transient_run( + start_year, end_year, ssp_rcp, rawdata_files, num_pft, must_run_download_input_data + ) + print(f"Successfully created input landuse file {landuse_fname}") + else: + landuse_fname = "" + time_stamp = datetime.today().strftime("%y%m%d") if ssp_rcp == "none": - if int(start_year) > 2015: - error_msg = ( - "ERROR: if start-year > 2015 must add an --ssp_rcp " - "argument that is not none: valid opts for ssp-rcp " - f"are {valid_opts}" - ) - sys.exit(error_msg) - elif int(end_year) > 2015: - error_msg = ( - "ERROR: if end-year > 2015 must add an --ssp-rcp " - "argument that is not none: valid opts for ssp-rcp " - f"are {valid_opts}" - ) - sys.exit(error_msg) + if pft_years == "PtVg": + ssp_rcp_name = "PtVeg_nourb" + else: + ssp_rcp_name = "hist" + else: + ssp_rcp_name = ssp_rcp + if int(end_year) == int(start_year): + fdyndat = "" + else: + fdyndat = ( + f"landuse.timeseries_{res}_{ssp_rcp_name}" + f"_{start_year}-{end_year}_{num_pft}pfts_c{time_stamp}.nc" + ) - pft_years_ssp = "-999" + prefix = f"surfdata_{res}_{ssp_rcp_name}_{start_year}_{num_pft}pfts_c{time_stamp}." - # determine pft_years - needed to parse xml file + if args.namelist_fname is None: + nlfname = f"{prefix}namelist" + else: + nlfname = args.namelist_fname + + fsurdat = f"{prefix}nc" + fsurlog = f"{prefix}log" + return landuse_fname, fdyndat, nlfname, fsurdat, fsurlog, must_run_download_input_data + + +def determine_pft_years(start_year, end_year, potveg): + """ + determine pft_years - needed to parse xml file + """ + pft_years_ssp = "-999" if potveg: pft_years = "PtVg" elif int(start_year) == 1850 and int(end_year) == 1850: @@ -389,34 +566,247 @@ def main(): sys.exit(error_msg) logger.info("pft_years = %s", pft_years) - - # Create land-use txt file for a transient case. - # Determine the run type and if a transient run create output landuse txt file - if end_year > start_year: - run_type = "transient" + return pft_years_ssp, pft_years + + +def write_nml_outdata( + nosurfdata_flag, + vic_flag, + inlandwet, + glc_flag, + hostname, + logname, + num_pft, + fdyndat, + fsurdat, + fsurlog, + gitdescribe, + nlfile, +): + """ + Write output namelist file: output data + """ + # ------------------- + # output data files + # ------------------- + if nosurfdata_flag: + nlfile.write(" fsurdat = ' ' \n") else: - run_type = "timeslice" - logger.info("run_type = %s", run_type) + nlfile.write(f" fsurdat = '{fsurdat}'\n") + nlfile.write(f" fsurlog = '{fsurlog}' \n") + nlfile.write(f" fdyndat = '{fdyndat}' \n") + + # ------------------- + # output data logicals + # ------------------- + nlfile.write(f" numpft = {num_pft} \n") + nlfile.write(f" no_inlandwet = .{str(not inlandwet).lower()}. \n") + nlfile.write(f" outnc_3dglc = .{str(glc_flag).lower()}. \n") + nlfile.write(f" outnc_vic = .{str(vic_flag).lower()}. \n") + nlfile.write(" outnc_large_files = .false. \n") + nlfile.write(" outnc_double = .true. \n") + nlfile.write(f" logname = '{logname}' \n") + nlfile.write(f" hostname = '{hostname}' \n") + nlfile.write(f" gitdescribe = '{gitdescribe}' \n") + + +def write_nml_rawinput( + start_year, + force_model_mesh_file, + force_model_mesh_nx, + force_model_mesh_ny, + vic_flag, + rawdata_files, + landuse_fname, + mksrf_ftopostats_override, + nlfile, + must_run_download_input_data, +): + """ + Write output namelist file: raw input data + """ + # pylint: disable=too-many-statements + if force_model_mesh_file is None: + mksrf_fgrid_mesh_nx = rawdata_files["mksrf_fgrid_mesh_nx"] + mksrf_fgrid_mesh_ny = rawdata_files["mksrf_fgrid_mesh_ny"] + mksrf_fgrid_mesh = rawdata_files["mksrf_fgrid_mesh"] + else: + mksrf_fgrid_mesh_nx = force_model_mesh_nx + mksrf_fgrid_mesh_ny = force_model_mesh_ny + mksrf_fgrid_mesh = force_model_mesh_file + nlfile.write(f" mksrf_fgrid_mesh = '{mksrf_fgrid_mesh}' \n") + nlfile.write(f" mksrf_fgrid_mesh_nx = {mksrf_fgrid_mesh_nx} \n") + nlfile.write(f" mksrf_fgrid_mesh_ny = {mksrf_fgrid_mesh_ny} \n") + + for key, value in rawdata_files.items(): + if key == "mksrf_ftopostats" and mksrf_ftopostats_override != "": + nlfile.write(f" mksrf_ftopostats_override = '{mksrf_ftopostats_override}' \n") + elif "_fvic" not in key and "mksrf_fvegtyp" not in key and "mksrf_fgrid" not in key: + # write everything else + nlfile.write(f" {key} = '{value}' \n") + + if start_year <= 2015: + mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp"] + mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] + mksrf_fhrvtyp = rawdata_files["mksrf_fvegtyp"] + mksrf_fhrvtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] + mksrf_fpctlak = rawdata_files["mksrf_fvegtyp_lake"] + mksrf_furban = rawdata_files["mksrf_fvegtyp_urban"] + else: + mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp_ssp"] + mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] + mksrf_fhrvtyp = rawdata_files["mksrf_fvegtyp_ssp"] + mksrf_fhrvtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] + mksrf_fpctlak = rawdata_files["mksrf_fvegtyp_ssp_lake"] + mksrf_furban = rawdata_files["mksrf_fvegtyp_ssp_urban"] + if "%y" in mksrf_fvegtyp: + mksrf_fvegtyp = mksrf_fvegtyp.replace("%y", str(start_year)) + if "%y" in mksrf_fhrvtyp: + mksrf_fhrvtyp = mksrf_fhrvtyp.replace("%y", str(start_year)) + if "%y" in mksrf_fpctlak: + mksrf_fpctlak = mksrf_fpctlak.replace("%y", str(start_year)) + if "%y" in mksrf_furban: + mksrf_furban = mksrf_furban.replace("%y", str(start_year)) + if not os.path.isfile(mksrf_fvegtyp): + print("WARNING: input mksrf_fvegtyp file " f"{mksrf_fvegtyp} does not exist") + print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") + must_run_download_input_data = True + if not os.path.isfile(mksrf_fhrvtyp): + print("WARNING: input mksrf_fhrvtyp file " f"{mksrf_fhrvtyp} does not exist") + print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") + must_run_download_input_data = True + if not os.path.isfile(mksrf_fpctlak): + print("WARNING: input mksrf_fpctlak file " f"{mksrf_fpctlak} does not exist") + print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") + must_run_download_input_data = True + if not os.path.isfile(mksrf_furban): + print("WARNING: input mksrf_furban file " f"{mksrf_furban} does not exist") + print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") + must_run_download_input_data = True + nlfile.write(f" mksrf_fvegtyp = '{mksrf_fvegtyp}' \n") + nlfile.write(f" mksrf_fvegtyp_mesh = '{mksrf_fvegtyp_mesh}' \n") + nlfile.write(f" mksrf_fhrvtyp = '{mksrf_fhrvtyp}' \n") + nlfile.write(f" mksrf_fhrvtyp_mesh = '{mksrf_fhrvtyp_mesh}' \n") + nlfile.write(f" mksrf_fpctlak = '{mksrf_fpctlak}' \n") + nlfile.write(f" mksrf_furban = '{mksrf_furban}' \n") + + if vic_flag: + mksrf_fvic = rawdata_files["mksrf_fvic"] + nlfile.write(f" mksrf_fvic = '{mksrf_fvic}' \n") + mksrf_fvic_mesh = rawdata_files["mksrf_fvic_mesh"] + nlfile.write(f" mksrf_fvic_mesh = '{mksrf_fvic_mesh}' \n") + + nlfile.write(f" mksrf_fdynuse = '{landuse_fname} ' \n") + return must_run_download_input_data + + +def handle_transient_run( + start_year, end_year, ssp_rcp, rawdata_files, num_pft, must_run_download_input_data +): + """ + Settings and printout for when run_type is "transient" + """ + if ssp_rcp == "none": + landuse_fname = f"landuse_timeseries_hist_{start_year}-{end_year}_{num_pft}pfts.txt" + else: + landuse_fname = f"landuse_timeseries_{ssp_rcp}_{start_year}-{end_year}_{num_pft}pfts.txt" + + with open(landuse_fname, "w", encoding="utf-8") as landuse_file: + for year in range(start_year, end_year + 1): + year_str = str(year) + if year <= 2015: + file1 = rawdata_files["mksrf_fvegtyp"] + file2 = rawdata_files["mksrf_fvegtyp_urban"] + file3 = rawdata_files["mksrf_fvegtyp_lake"] + else: + file1 = rawdata_files["mksrf_fvegtyp_ssp"] + file2 = rawdata_files["mksrf_fvegtyp_ssp_urban"] + file3 = rawdata_files["mksrf_fvegtyp_ssp_lake"] + + landuse_input_fname = file1.replace("%y", year_str) + landuse_input_fnam2 = file2.replace("%y", year_str) + landuse_input_fnam3 = file3.replace("%y", year_str) + if not os.path.isfile(landuse_input_fname): + print("WARNING: landunit_input_fname: " f"{landuse_input_fname} does not exist") + print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") + must_run_download_input_data = True + if not os.path.isfile(landuse_input_fnam2): + print("WARNING: landunit_input_fnam2: " f"{landuse_input_fnam2} does not exist") + print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") + must_run_download_input_data = True + if not os.path.isfile(landuse_input_fnam3): + print("WARNING: landunit_input_fnam3: " f"{landuse_input_fnam3} does not exist") + print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") + must_run_download_input_data = True + + # -- Each line is written twice in the original perl code: + landuse_line = f"{landuse_input_fname:<196}{year_str}\n" + landuse_lin2 = f"{landuse_input_fnam2:<196}{year_str}\n" + landuse_lin3 = f"{landuse_input_fnam3:<196}{year_str}\n" + landuse_file.write(landuse_line) + landuse_file.write(landuse_line) + landuse_file.write(landuse_lin2) + landuse_file.write(landuse_lin3) + logger.debug("year : %s", year_str) + logger.debug(landuse_line) + return landuse_fname, must_run_download_input_data + + +def determine_output_mesh(res, force_model_mesh_file, input_path, rawdata_files, tool_path): + """ + determine output mesh + """ + xml_path = os.path.join(tool_path, "../../ccs_config/component_grids_nuopc.xml") + tree2 = ET.parse(xml_path) + root = tree2.getroot() + model_mesh = "" + for child1 in root: # this is domain tag + for _, value in child1.attrib.items(): + if value == res: + for child2 in child1: + if child2.tag == "mesh": + model_mesh = child2.text + rawdata_files["mksrf_fgrid_mesh"] = os.path.join( + input_path, model_mesh.strip("$DIN_LOC_ROOT/") + ) + if child2.tag == "nx": + rawdata_files["mksrf_fgrid_mesh_nx"] = child2.text + if child2.tag == "ny": + rawdata_files["mksrf_fgrid_mesh_ny"] = child2.text - # error check on glc_nec - if (glc_nec <= 0) or (glc_nec >= 100): - raise argparse.ArgumentTypeError("ERROR: glc_nec must be between 1 and 99.") + if not model_mesh and force_model_mesh_file is None: + valid_grids = [] + for child1 in root: # this is domain tag + for _, value in child1.attrib.items(): + valid_grids.append(value) + if res in valid_grids: + error_msg = ( + "ERROR: You have requested a valid grid for which " + "../../ccs_config/component_grids_nuopc.xml does not include a mesh " + "file. For a regular regional or 1x1 grid, you may generate the " + "fsurdat file using the subset_data tool instead. Alternatively " + "and definitely for curvilinear grids, you may generate " + "a mesh file using the workflow currently (2022/7) described in " + "https://github.com/ESCOMP/CTSM/issues/1773#issuecomment-1163432584" + "TODO Reminder to ultimately place these workflow instructions in " + "the User's Guide." + ) + sys.exit(error_msg) + else: + error_msg = f"ERROR: invalid input res {res}; " f"valid grid values are {valid_grids}" + sys.exit(error_msg) - # create attribute list for parsing xml file - attribute_list = { - "hires_pft": hires_pft, - "hires_soitex": hires_soitex, - "pft_years": pft_years, - "pft_years_ssp": pft_years_ssp, - "ssp_rcp": ssp_rcp, - "res": res, - } + +def determine_input_rawdata(start_year, input_path, attribute_list): + """ + determine input rawdata + """ + # pylint: disable=too-many-statements # create dictionary for raw data files names rawdata_files = {} - # determine input rawdata - _must_run_download_input_data = False + must_run_download_input_data = False tool_path = os.path.join(path_to_ctsm_root(), "tools", "mksurfdata_esmf") xml_path = os.path.join(tool_path, "gen_mksurfdata_namelist.xml") tree1 = ET.parse(xml_path) @@ -471,7 +861,7 @@ def main(): print( "WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES" ) - _must_run_download_input_data = True + must_run_download_input_data = True if item.tag == "mesh_filename": new_key = f"{child1.tag}_mesh" @@ -479,7 +869,7 @@ def main(): if not os.path.isfile(rawdata_files[new_key]): print("WARNING: input mesh file " f"{rawdata_files[new_key]} does not exist") print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") - _must_run_download_input_data = True + must_run_download_input_data = True if item.tag == "lake_filename": new_key = f"{child1.tag}_lake" @@ -492,271 +882,45 @@ def main(): if item.tag == "lookup_filename": new_key = f"{child1.tag}_lookup" rawdata_files[new_key] = os.path.join(input_path, item.text) + return tool_path, must_run_download_input_data, rawdata_files - # determine output mesh - xml_path = os.path.join(tool_path, "../../ccs_config/component_grids_nuopc.xml") - tree2 = ET.parse(xml_path) - root = tree2.getroot() - model_mesh = "" - for child1 in root: # this is domain tag - for _, value in child1.attrib.items(): - if value == res: - for child2 in child1: - if child2.tag == "mesh": - model_mesh = child2.text - rawdata_files["mksrf_fgrid_mesh"] = os.path.join( - input_path, model_mesh.strip("$DIN_LOC_ROOT/") - ) - if child2.tag == "nx": - rawdata_files["mksrf_fgrid_mesh_nx"] = child2.text - if child2.tag == "ny": - rawdata_files["mksrf_fgrid_mesh_ny"] = child2.text - if not model_mesh and force_model_mesh_file is None: - valid_grids = [] - for child1 in root: # this is domain tag - for _, value in child1.attrib.items(): - valid_grids.append(value) - if res in valid_grids: +def open_mesh_file(force_model_mesh_file, force_model_mesh_nx, force_model_mesh_ny): + """ + open mesh_file to read element_count and, if available, orig_grid_dims + """ + # pylint: disable=no-name-in-module,no-member + mesh_file = netCDF4.Dataset(force_model_mesh_file, "r") + element_count = mesh_file.dimensions["elementCount"].size + if "origGridDims" in mesh_file.variables: + orig_grid_dims = mesh_file.variables["origGridDims"] + if ( + int(force_model_mesh_nx) == orig_grid_dims[0] + and int(force_model_mesh_ny) == orig_grid_dims[1] + ): + mesh_file.close() + else: error_msg = ( - "ERROR: You have requested a valid grid for which " - "../../ccs_config/component_grids_nuopc.xml does not include a mesh " - "file. For a regular regional or 1x1 grid, you may generate the " - "fsurdat file using the subset_data tool instead. Alternatively " - "and definitely for curvilinear grids, you may generate " - "a mesh file using the workflow currently (2022/7) described in " - "https://github.com/ESCOMP/CTSM/issues/1773#issuecomment-1163432584" - "TODO Reminder to ultimately place these workflow instructions in " - "the User's Guide." + "ERROR: Found variable origGridDims in " + f"{force_model_mesh_file} with values " + f"{orig_grid_dims[:]} that do not agree with the " + "user-entered mesh_nx and mesh_ny values of " + f"{[force_model_mesh_nx, force_model_mesh_ny]}." ) sys.exit(error_msg) - else: - error_msg = f"ERROR: invalid input res {res}; " f"valid grid values are {valid_grids}" - sys.exit(error_msg) - - # Determine num_pft - if nocrop_flag: - num_pft = "16" - else: - num_pft = "78" - logger.info("num_pft is %s", num_pft) - - # Write out if surface dataset will be created - if nosurfdata_flag: - logger.info("surface dataset will not be created") - else: - logger.info("surface dataset will be created") - - if run_type == "transient": - if ssp_rcp == "none": - landuse_fname = f"landuse_timeseries_hist_{start_year}-{end_year}_{num_pft}pfts.txt" - else: - landuse_fname = ( - f"landuse_timeseries_{ssp_rcp}_{start_year}-{end_year}_{num_pft}pfts.txt" - ) - - with open(landuse_fname, "w", encoding="utf-8") as landuse_file: - for year in range(start_year, end_year + 1): - year_str = str(year) - if year <= 2015: - file1 = rawdata_files["mksrf_fvegtyp"] - file2 = rawdata_files["mksrf_fvegtyp_urban"] - file3 = rawdata_files["mksrf_fvegtyp_lake"] - else: - file1 = rawdata_files["mksrf_fvegtyp_ssp"] - file2 = rawdata_files["mksrf_fvegtyp_ssp_urban"] - file3 = rawdata_files["mksrf_fvegtyp_ssp_lake"] - - landuse_input_fname = file1.replace("%y", year_str) - landuse_input_fnam2 = file2.replace("%y", year_str) - landuse_input_fnam3 = file3.replace("%y", year_str) - if not os.path.isfile(landuse_input_fname): - print("WARNING: landunit_input_fname: " f"{landuse_input_fname} does not exist") - print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") - _must_run_download_input_data = True - if not os.path.isfile(landuse_input_fnam2): - print("WARNING: landunit_input_fnam2: " f"{landuse_input_fnam2} does not exist") - print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") - _must_run_download_input_data = True - if not os.path.isfile(landuse_input_fnam3): - print("WARNING: landunit_input_fnam3: " f"{landuse_input_fnam3} does not exist") - print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") - _must_run_download_input_data = True - - # -- Each line is written twice in the original perl code: - landuse_line = f"{landuse_input_fname:<196}{year_str}\n" - landuse_lin2 = f"{landuse_input_fnam2:<196}{year_str}\n" - landuse_lin3 = f"{landuse_input_fnam3:<196}{year_str}\n" - landuse_file.write(landuse_line) - landuse_file.write(landuse_line) - landuse_file.write(landuse_lin2) - landuse_file.write(landuse_lin3) - logger.debug("year : %s", year_str) - logger.debug(landuse_line) - print(f"Successfully created input landuse file {landuse_fname}") - else: - landuse_fname = "" - - time_stamp = datetime.today().strftime("%y%m%d") - if ssp_rcp == "none": - if pft_years == "PtVg": - ssp_rcp_name = "PtVeg_nourb" - else: - ssp_rcp_name = "hist" - else: - ssp_rcp_name = ssp_rcp - if int(end_year) == int(start_year): - fdyndat = "" - else: - fdyndat = ( - f"landuse.timeseries_{res}_{ssp_rcp_name}" - f"_{start_year}-{end_year}_{num_pft}pfts_c{time_stamp}.nc" + elif force_model_mesh_nx is None or force_model_mesh_ny is None: + error_msg = ( + "ERROR: You set --model-mesh so you MUST ALSO " + "SET --model-mesh-nx AND --model-mesh-ny" ) + sys.exit(error_msg) - prefix = f"surfdata_{res}_{ssp_rcp_name}_{start_year}_{num_pft}pfts_c{time_stamp}." - - if args.namelist_fname is None: - nlfname = f"{prefix}namelist" - else: - nlfname = args.namelist_fname - - fsurdat = f"{prefix}nc" - fsurlog = f"{prefix}log" - - git_desc_cmd = f"git -C {tool_path} describe" - try: - # The "git -C" option permits a system test to run this tool from - # elsewhere while running the git command from the tool_path - gitdescribe = subprocess.check_output(git_desc_cmd, shell=True).strip() - except subprocess.CalledProcessError as error: - # In case the "git -C" option is unavailable, as on casper (2022/5/24) - # Still, this does NOT allow the system test to work on machines - # without git -C - logger.info("git -C option unavailable on casper as of 2022/7/2 %s", error) - gitdescribe = subprocess.check_output("git describe", shell=True).strip() - gitdescribe = gitdescribe.decode("utf-8") - - # The below two overrides are only used for testing and validation - # it takes a long time to generate the mapping files - # from 1km to the following two resolutions since the output mesh has so few points - if res == "10x15": - mksrf_ftopostats_override = os.path.join( - input_path, "lnd", "clm2", "rawdata", "surfdata_topo_10x15_c220303.nc" + # using force_model_mesh_nx and force_model_mesh_ny either from the + # mesh file (see previous if statement) or the user-entered values + if element_count != int(force_model_mesh_nx) * int(force_model_mesh_ny): + error_msg = ( + "ERROR: The product of " + "--model-mesh-nx x --model-mesh-ny must equal " + "exactly elementCount in --model-mesh" ) - logger.info("will override mksrf_ftopostats with = %s", mksrf_ftopostats_override) - else: - mksrf_ftopostats_override = "" - - # ---------------------------------------- - # Write output namelist file - # ---------------------------------------- - - with open(nlfname, "w", encoding="utf-8") as nlfile: - nlfile.write("&mksurfdata_input \n") - - # ------------------- - # raw input data - # ------------------- - if force_model_mesh_file is None: - mksrf_fgrid_mesh_nx = rawdata_files["mksrf_fgrid_mesh_nx"] - mksrf_fgrid_mesh_ny = rawdata_files["mksrf_fgrid_mesh_ny"] - mksrf_fgrid_mesh = rawdata_files["mksrf_fgrid_mesh"] - else: - mksrf_fgrid_mesh_nx = force_model_mesh_nx - mksrf_fgrid_mesh_ny = force_model_mesh_ny - mksrf_fgrid_mesh = force_model_mesh_file - nlfile.write(f" mksrf_fgrid_mesh = '{mksrf_fgrid_mesh}' \n") - nlfile.write(f" mksrf_fgrid_mesh_nx = {mksrf_fgrid_mesh_nx} \n") - nlfile.write(f" mksrf_fgrid_mesh_ny = {mksrf_fgrid_mesh_ny} \n") - - for key, value in rawdata_files.items(): - if key == "mksrf_ftopostats" and mksrf_ftopostats_override != "": - nlfile.write(f" mksrf_ftopostats_override = '{mksrf_ftopostats_override}' \n") - elif "_fvic" not in key and "mksrf_fvegtyp" not in key and "mksrf_fgrid" not in key: - # write everything else - nlfile.write(f" {key} = '{value}' \n") - - if start_year <= 2015: - mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp"] - mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] - mksrf_fhrvtyp = rawdata_files["mksrf_fvegtyp"] - mksrf_fhrvtyp_mesh = rawdata_files["mksrf_fvegtyp_mesh"] - mksrf_fpctlak = rawdata_files["mksrf_fvegtyp_lake"] - mksrf_furban = rawdata_files["mksrf_fvegtyp_urban"] - else: - mksrf_fvegtyp = rawdata_files["mksrf_fvegtyp_ssp"] - mksrf_fvegtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] - mksrf_fhrvtyp = rawdata_files["mksrf_fvegtyp_ssp"] - mksrf_fhrvtyp_mesh = rawdata_files["mksrf_fvegtyp_ssp_mesh"] - mksrf_fpctlak = rawdata_files["mksrf_fvegtyp_ssp_lake"] - mksrf_furban = rawdata_files["mksrf_fvegtyp_ssp_urban"] - if "%y" in mksrf_fvegtyp: - mksrf_fvegtyp = mksrf_fvegtyp.replace("%y", str(start_year)) - if "%y" in mksrf_fhrvtyp: - mksrf_fhrvtyp = mksrf_fhrvtyp.replace("%y", str(start_year)) - if "%y" in mksrf_fpctlak: - mksrf_fpctlak = mksrf_fpctlak.replace("%y", str(start_year)) - if "%y" in mksrf_furban: - mksrf_furban = mksrf_furban.replace("%y", str(start_year)) - if not os.path.isfile(mksrf_fvegtyp): - print("WARNING: input mksrf_fvegtyp file " f"{mksrf_fvegtyp} does not exist") - print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") - _must_run_download_input_data = True - if not os.path.isfile(mksrf_fhrvtyp): - print("WARNING: input mksrf_fhrvtyp file " f"{mksrf_fhrvtyp} does not exist") - print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") - _must_run_download_input_data = True - if not os.path.isfile(mksrf_fpctlak): - print("WARNING: input mksrf_fpctlak file " f"{mksrf_fpctlak} does not exist") - print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") - _must_run_download_input_data = True - if not os.path.isfile(mksrf_furban): - print("WARNING: input mksrf_furban file " f"{mksrf_furban} does not exist") - print("WARNING: run ./download_input_data to try TO " "OBTAIN MISSING FILES") - _must_run_download_input_data = True - nlfile.write(f" mksrf_fvegtyp = '{mksrf_fvegtyp}' \n") - nlfile.write(f" mksrf_fvegtyp_mesh = '{mksrf_fvegtyp_mesh}' \n") - nlfile.write(f" mksrf_fhrvtyp = '{mksrf_fhrvtyp}' \n") - nlfile.write(f" mksrf_fhrvtyp_mesh = '{mksrf_fhrvtyp_mesh}' \n") - nlfile.write(f" mksrf_fpctlak = '{mksrf_fpctlak}' \n") - nlfile.write(f" mksrf_furban = '{mksrf_furban}' \n") - - if vic_flag: - mksrf_fvic = rawdata_files["mksrf_fvic"] - nlfile.write(f" mksrf_fvic = '{mksrf_fvic}' \n") - mksrf_fvic_mesh = rawdata_files["mksrf_fvic_mesh"] - nlfile.write(f" mksrf_fvic_mesh = '{mksrf_fvic_mesh}' \n") - - nlfile.write(f" mksrf_fdynuse = '{landuse_fname} ' \n") - - # ------------------- - # output data files - # ------------------- - if nosurfdata_flag: - nlfile.write(" fsurdat = ' ' \n") - else: - nlfile.write(f" fsurdat = '{fsurdat}'\n") - nlfile.write(f" fsurlog = '{fsurlog}' \n") - nlfile.write(f" fdyndat = '{fdyndat}' \n") - - # ------------------- - # output data logicals - # ------------------- - nlfile.write(f" numpft = {num_pft} \n") - nlfile.write(f" no_inlandwet = .{str(not inlandwet).lower()}. \n") - nlfile.write(f" outnc_3dglc = .{str(glc_flag).lower()}. \n") - nlfile.write(f" outnc_vic = .{str(vic_flag).lower()}. \n") - nlfile.write(" outnc_large_files = .false. \n") - nlfile.write(" outnc_double = .true. \n") - nlfile.write(f" logname = '{logname}' \n") - nlfile.write(f" hostname = '{hostname}' \n") - nlfile.write(f" gitdescribe = '{gitdescribe}' \n") - - nlfile.write("/ \n") - - if _must_run_download_input_data: - temp_nlfname = "surfdata.namelist" - os.rename(nlfname, temp_nlfname) - nlfname = temp_nlfname - - print(f"Successfully created input namelist file {nlfname}") + sys.exit(error_msg) From e096358c832ab292ddfd22dd5878826c7c788968 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Thu, 14 Mar 2024 17:19:57 -0600 Subject: [PATCH 522/614] Reformatting with black. --- python/ctsm/test/test_sys_mesh_modifier.py | 4 +--- .../toolchain/gen_mksurfdata_jobscript_single.py | 16 ++++++---------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/python/ctsm/test/test_sys_mesh_modifier.py b/python/ctsm/test/test_sys_mesh_modifier.py index 63ac2044d4..7366b78c6f 100755 --- a/python/ctsm/test/test_sys_mesh_modifier.py +++ b/python/ctsm/test/test_sys_mesh_modifier.py @@ -125,9 +125,7 @@ def createLandMaskFile(self, fsurdat_in): try: subprocess.check_call(ncap2_cmd, shell=True) except subprocess.CalledProcessError as e: - sys.exit( - f"{e} ERROR using ncap2 to generate {self._landmask_file} from {fsurdat_in}" - ) + sys.exit(f"{e} ERROR using ncap2 to generate {self._landmask_file} from {fsurdat_in}") def tearDown(self): """ diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 143c6692ea..9db728db63 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -11,10 +11,10 @@ from ctsm.ctsm_logging import setup_logging_pre_config, add_logging_args, process_logging_args from ctsm.utils import abort from ctsm.path_utils import path_to_ctsm_root -from CIME.XML.env_mach_specific \ - import EnvMachSpecific # pylint: disable=import-error,wrong-import-order -from CIME.BuildTools.configure \ - import FakeCase # pylint: disable=import-error,wrong-import-order +from CIME.XML.env_mach_specific import ( + EnvMachSpecific, +) # pylint: disable=import-error,wrong-import-order +from CIME.BuildTools.configure import FakeCase # pylint: disable=import-error,wrong-import-order logger = logging.getLogger(__name__) @@ -156,9 +156,7 @@ def write_runscript_part2(namelist_file, runfile, executable, mksurfdata_path, e runfile.write(f"{output} \n") logger.info("run command is %s", output) - check = ( - f'if [ $? != 0 ]; then echo "Error running for namelist {namelist_file}"; exit -4; fi' - ) + check = f'if [ $? != 0 ]; then echo "Error running for namelist {namelist_file}"; exit -4; fi' runfile.write(f"{check} \n") runfile.write("echo Successfully ran resolution\n") @@ -199,9 +197,7 @@ def main(): # and the fake_case object with mpilib=attribs['mpilib'] # so as to use the get_mpirun function pointing to fake_case ems_file = EnvMachSpecific(bld_path, standalone_configure=True) - fake_case = FakeCase( - compiler=None, mpilib=attribs["mpilib"], debug=False, comp_interface=None - ) + fake_case = FakeCase(compiler=None, mpilib=attribs["mpilib"], debug=False, comp_interface=None) total_tasks = int(tasks_per_node) * int(number_of_nodes) cmd = ems_file.get_mpirun( fake_case, From 31e5a39f6fa67d88a19b53be1f5470ea9c319719 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Thu, 14 Mar 2024 17:20:34 -0600 Subject: [PATCH 523/614] Add previous commit to .git-blame-ignore-revs. --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 887d27c308..5f19a43f3c 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -22,6 +22,7 @@ e4d38681df23ccca0ae29581a45f8362574e0630 a9d96219902cf609636886c7073a84407f450d9a d866510188d26d51bcd6d37239283db690af7e82 0dcd0a3c1abcaffe5529f8d79a6bc34734b195c7 +e096358c832ab292ddfd22dd5878826c7c788968 # Ran SystemTests and python/ctsm through black python formatter 5364ad66eaceb55dde2d3d598fe4ce37ac83a93c 8056ae649c1b37f5e10aaaac79005d6e3a8b2380 From a4235e104ab57e08e11e29407b1b8fac8c832937 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Thu, 14 Mar 2024 17:23:02 -0600 Subject: [PATCH 524/614] Resolve import-related complaints in gen_mksurfdata_jobscript_single.py. --- python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 9db728db63..f958d41e89 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -11,9 +11,9 @@ from ctsm.ctsm_logging import setup_logging_pre_config, add_logging_args, process_logging_args from ctsm.utils import abort from ctsm.path_utils import path_to_ctsm_root -from CIME.XML.env_mach_specific import ( +from CIME.XML.env_mach_specific import ( # pylint: disable=import-error,wrong-import-order EnvMachSpecific, -) # pylint: disable=import-error,wrong-import-order +) from CIME.BuildTools.configure import FakeCase # pylint: disable=import-error,wrong-import-order logger = logging.getLogger(__name__) From cf250338574522a4c4a9f138ca8192c9aa203e23 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 14 Mar 2024 17:49:26 -0600 Subject: [PATCH 525/614] As we determined in #2372 the irrigation part is just vestiges of an old dataset that is no longer used. It was no longer used in mksurfdata_map either but it was in place. Hence why it was kept here. So I've removed it now --- tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index 6ad82d6ea4..8397d026f3 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -23,13 +23,6 @@ - - - - - - - lnd/clm2/rawdata/pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c20230226/mksrf_soilcolor_ctsm52_histLUH2_2005.c20230226.nc From aa3ddba7696036f2ac4b1808666a402db61d0f24 Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Fri, 15 Mar 2024 09:34:00 -0600 Subject: [PATCH 526/614] Fix "gird" typo. --- python/ctsm/test/test_sys_mesh_modifier.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ctsm/test/test_sys_mesh_modifier.py b/python/ctsm/test/test_sys_mesh_modifier.py index 7366b78c6f..f94c86e547 100755 --- a/python/ctsm/test/test_sys_mesh_modifier.py +++ b/python/ctsm/test/test_sys_mesh_modifier.py @@ -69,7 +69,7 @@ def setUp(self): sys.exit(f"{e} ERROR using {configure_cmd}") def createScripGridAndMask(self, fsurdat_in): - """Create the SCRIP gird and mask file""" + """Create the SCRIP grid and mask file""" # Generate scrip file from fsurdat_in using nco # In the ctsm_py environment this requires running 'module load nco' # interactively From d8b6a5d80b3f92505a1d3c015461035b7954a45c Mon Sep 17 00:00:00 2001 From: Sam Rabin Date: Fri, 15 Mar 2024 12:50:45 -0600 Subject: [PATCH 527/614] gen_mksurfdata_namelist: Explain "pylint: disable=no-name-in-module,no-member". --- python/ctsm/toolchain/gen_mksurfdata_namelist.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/ctsm/toolchain/gen_mksurfdata_namelist.py b/python/ctsm/toolchain/gen_mksurfdata_namelist.py index 8b8a9b8828..8a953c39df 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_namelist.py +++ b/python/ctsm/toolchain/gen_mksurfdata_namelist.py @@ -890,6 +890,8 @@ def open_mesh_file(force_model_mesh_file, force_model_mesh_nx, force_model_mesh_ open mesh_file to read element_count and, if available, orig_grid_dims """ # pylint: disable=no-name-in-module,no-member + # The above "pylint: disable" is because pylint complains that netCDF4 + # has no member Dataset, even though it does. mesh_file = netCDF4.Dataset(force_model_mesh_file, "r") element_count = mesh_file.dimensions["elementCount"].size if "origGridDims" in mesh_file.variables: From 35b8de72ed1060662548d7e851e9a92382e6abc6 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 15 Mar 2024 12:54:37 -0600 Subject: [PATCH 528/614] Update namelist based on @slevis-lmwg review, this is clearly easier to read now and makes it shorter. Update the build-namelist unit tester and show that the clm4_5, clm5_0, and clm5_1 tests are all identical --- bld/namelist_files/namelist_defaults_ctsm.xml | 512 +++++------------- bld/unit_testers/build-namelist_test.pl | 4 +- 2 files changed, 135 insertions(+), 381 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 44d8ca7d8a..8a1f90ab4d 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -40,25 +40,18 @@ attributes from the config_cache.xml file (with keys converted to upper-case). clm5_1_GSWP3v1 clm6_0_GSWP3v1 - -clm2 -clm2 -clm2 -clm2 + +clm2 off -2 -2 -2 -1 -2 -2 -2 +2 +1 +2 1 -0 +0 .true. @@ -85,36 +78,25 @@ attributes from the config_cache.xml file (with keys converted to upper-case). -8760 20 - -.false. -.false. -.false. -.false. + +.false. -.true. -.true. -.true. +.true. .false. -2 -2 -2 +2 1 0 -.true. -.true. -.true. +.true. .false. -Medlyn2011 -Medlyn2011 -Medlyn2011 -Ball-Berry1987 +Medlyn2011 +Ball-Berry1987 lnd/clm2/isotopes/atm_delta_C13_CMIP6_1850-2015_yearly_v2.0_c190528.nc @@ -134,16 +116,9 @@ attributes from the config_cache.xml file (with keys converted to upper-case). lnd/clm2/isotopes/atm_delta_C14_CMIP6_SSP5B_3x1_global_1850-2100_yearly_c181209.nc -.true. -.false. -.true. -.false. -.true. -.false. -.false. - .false. - +.true. +.false. .false. @@ -158,78 +133,49 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ALL -0.50,0.30 -0.50,0.30 -0.50,0.30 +0.50,0.30 0.60,0.40 -ON_WASTEHEAT -ON_WASTEHEAT -ON_WASTEHEAT +ON_WASTEHEAT ON -1 -1 -1 +1 0 -FAST -FAST -FAST +FAST NONE .false. +.false. .true. -.false. -.false. -.false. 4SL_2m -20SL_8.5m -20SL_8.5m -20SL_8.5m +20SL_8.5m 10SL_3.5m -.false. -.false. -.true. -.false. -.false. -.true. -.false. -.false. -.true. +.false. +.false. +.true. .false. -1 -1 -1 +1 0 -1 -1 -1 -1 + +1 -1 -1 -1 +1 0 -1.d-2 -0.001d00 -1.d-2 -0.001d00 -1.d-2 -0.001d00 -1.d-2 +0.001d00 +1.d-2 1.d-2 @@ -242,9 +188,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 2.0d00 -.true. -.true. -.true. +.true. .false. .true. @@ -259,33 +203,24 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 0. 2. - -0. -2. - --2. -0. - --2. -0. - --2. -0. +-2. +0. + +0. +2. +.true. .false. -.true. -.true. -.true. -li2021gswpfrc -li2021gswpfrc +li2021gswpfrc li2016crufrc li2014qianfrc @@ -353,48 +288,32 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 0.28d00 -.false. -.false. -.false. +.false. .true. -.true. -.false. -.true. -.false. -.false. +.true. +.false. +.false. +.false. 40 3 -.true. -1.0 -0.05 - -.true. -1.0 -0.05 - -.true. -1.0 -0.05 - +.true. +1.0 +0.05 .false. 0.25 1.0 +1 0 -1 -1 -1 +1 1 -1 -1 -1 4 2 @@ -415,16 +334,11 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 14400 -3400. 0.6 -1.0 -1.0 -1.0 +1.0 0.5 0.1 - -.false. -.false. -.false. + .false. .false. @@ -435,23 +349,15 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .true. -12 -5 -12 -5 -12 -5 -5 +12 +5 +5 -10000.0 -5000.0 -10000.0 -5000.0 -10000.0 -5000.0 -1000.0 +10000.0 +5000.0 +1000.0 0.010d00 0.015d00 @@ -460,36 +366,24 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 0.02d00 0.05d00 -2000. -2000. -2000. +2000. 1.e30 -10.0d00 -10.0d00 -10.0d00 +10.0d00 10.0 -.true. -.true. -.true. +.true. .false. -'Vionnet2012' -'Vionnet2012' -'Vionnet2012' +'Vionnet2012' 'Anderson1976' -'Slater2017' -'Slater2017' -'Slater2017' +'Slater2017' 'TruncatedAnderson1976' +175.d00 100.d00 -175.d00 -175.d00 -175.d00 0.08d00 @@ -536,9 +430,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). simplicity, we tie the defaults for both of these options to the overall CLM phys version, rather than having some intermediate option that controls the defaults for both h2osno_max and glc_snow_persistence_max_days. --> -0 -0 -0 +0 7300 @@ -561,8 +453,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ZengWang2007 -Meier2022 Meier2022 +Meier2022 .true. .false. @@ -570,23 +462,14 @@ attributes from the config_cache.xml file (with keys converted to upper-case). -.true. -.false. -.true. -.false. -.true. -.false. -.false. +.false. +.true. +.false. -.true. -.false. -.true. -.false. -.true. -.false. -.false. -.false. +.true. +.false. +.false. .true. @@ -605,103 +488,73 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .true. .false. -.false. -.true. -.true. -.true. -.true. +.false. +.true. -0.17 -0.17 -0.17 + +0.17 unset .false. +.true. .false. -.true. -.true. -.true. -0.d+0 +0.d+0 0.5d00 0.5d00 +varytropicsbylat +12.0d00 +0.4d00 constant -varytropicsbylat -12.0d00 -0.4d00 -varytropicsbylat -12.0d00 -0.4d00 -varytropicsbylat -12.0d00 -0.4d00 - -3.d00 -3.d00 -3.d00 + +3.d00 1.d00 -.true. -DependsOnLat -.true. -DependsOnLat -.false. -Constant -.false. -.true. +Constant +DependsOnLat +DependsOnLat + +.false. +.true. +.true. + +.false. +.true. +.true. .false. -.true. -.true. -.true. .true. -.false. -.false. -.false. -.false. -.false. -.false. -.false. +.false. -.false. -.false. -.true. -.false. -.true. -.false. -.true. - -1.d-9 -1.d-9 -1.d-9 +.false. +.true. +.false. + +1.d-9 1.d-8 --6.d+1 --6.d+1 --6.d+1 +-6.d+1 -6.d+2 --6.d+0 --6.d+0 --6.d+0 +-6.d+0 -6.d+1 .false. -.false. .false. +.false. .false. Darcy LayerSum @@ -711,9 +564,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .false. -.true. -.true. -.true. +.true. +.false. @@ -1707,31 +1559,22 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c >lnd/clm2/surfdata_map/fates-sci.1.68.3_api.31.0.0_tools.1.0.1/LUH2_states_transitions_management.timeseries_4x5_hist_simyr1850-2015_c231101.nc -.true. -.true. -.true. .false. +.true. +.false. 0.0117d00 0.0006d00 0.83d-06 - -0.015d00 -0.015d00 -0.015d00 -0.015d00 + +0.015d00 -100.d00 -100.d00 -100.d00 +100.d00 20.d00 -1.d00 -1.d00 -1.d00 -1.d00 +1.d00 @@ -1742,8 +1585,7 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c lnd/clm2/snicardata/snicar_optics_480bnd_c012422.nc lnd/clm2/snicardata/snicar_optics_5bnd_c013122.nc -hexagonal_plate -hexagonal_plate +hexagonal_plate sphere sphere @@ -1756,23 +1598,9 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c .false. -2015 -2101 -2015 - -2015 -2101 -2015 - -2015 -2015 -2101 -2015 - -2015 -2015 -2101 -2015 +2015 +2101 +2015 2018 2018 @@ -1795,62 +1623,23 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c 2000 2000 -lnd/clm2/ndepdata/fndep_clm_hist_b.e21.BWHIST.f09_g17.CMIP6-historical-WACCM.ensmean_1849-2015_monthly_0.9x1.25_c180926.nc -lnd/clm2/ndepdata/fndep_clm_hist_b.e21.BWHIST.f09_g17.CMIP6-historical-WACCM.ensmean_1849-2015_monthly_0.9x1.25_c180926.nc -lnd/clm2/ndepdata/fndep_clm_hist_b.e21.BWHIST.f09_g17.CMIP6-historical-WACCM.ensmean_1849-2015_monthly_0.9x1.25_c180926.nc -lnd/clm2/ndepdata/fndep_clm_hist_b.e21.BWHIST.f09_g17.CMIP6-historical-WACCM.ensmean_1849-2015_monthly_0.9x1.25_c180926.nc +lnd/clm2/ndepdata/fndep_clm_hist_b.e21.BWHIST.f09_g17.CMIP6-historical-WACCM.ensmean_1849-2015_monthly_0.9x1.25_c180926.nc share/meshes/fv1.9x2.5_141008_ESMFmesh_c20191001.nc share/meshes/fv0.9x1.25_141008_polemod_ESMFmesh.nc -lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP5-8.5-WACCM_1849-2101_monthly_c191007.nc -lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP1-2.6-WACCM_1849-2101_monthly_c191007.nc -lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP2-4.5-WACCM_1849-2101_monthly_c191007.nc -lnd/clm2/ndepdata/fndep_clm_SSP370_b.e21.BWSSP370cmip6.f09_g17.CMIP6-SSP3-7.0-WACCM.002_1849-2101_monthly_0.9x1.25_c211216.nc -lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP5-8.5-WACCM_1849-2101_monthly_c191007.nc -lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP1-2.6-WACCM_1849-2101_monthly_c191007.nc -lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP2-4.5-WACCM_1849-2101_monthly_c191007.nc -lnd/clm2/ndepdata/fndep_clm_SSP370_b.e21.BWSSP370cmip6.f09_g17.CMIP6-SSP3-7.0-WACCM.002_1849-2101_monthly_0.9x1.25_c211216.nc - -lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP5-8.5-WACCM_1849-2101_monthly_c191007.nc -lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP1-2.6-WACCM_1849-2101_monthly_c191007.nc -lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP2-4.5-WACCM_1849-2101_monthly_c191007.nc -lnd/clm2/ndepdata/fndep_clm_SSP370_b.e21.BWSSP370cmip6.f09_g17.CMIP6-SSP3-7.0-WACCM.002_1849-2101_monthly_0.9x1.25_c211216.nc - -lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP5-8.5-WACCM_1849-2101_monthly_c191007.nc -lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP1-2.6-WACCM_1849-2101_monthly_c191007.nc -lnd/clm2/ndepdata/fndep_clm_f09_g17.CMIP6-SSP2-4.5-WACCM_1849-2101_monthly_c191007.nc -lnd/clm2/ndepdata/fndep_clm_SSP370_b.e21.BWSSP370cmip6.f09_g17.CMIP6-SSP3-7.0-WACCM.002_1849-2101_monthly_0.9x1.25_c211216.nc - -cycle -NDEP_month - -cycle -NDEP_month - -cycle -NDEP_month - -cycle -NDEP_month +cycle +NDEP_month bilinear @@ -1907,10 +1696,9 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c none none 106x174 -94x192 +360x720 94x192 -360x720 -360x720 +94x192 none none none @@ -1943,21 +1731,9 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c nn -2015 -2100 -2015 - -2015 -2100 -2015 - -2015 -2100 -2015 - -2015 -2100 -2015 +2015 +2100 +2015 2018 2018 @@ -2058,21 +1834,9 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c nn -2015 -2106 -2015 - -2015 -2106 -2015 - -2015 -2106 -2015 - -2015 -2106 -2015 +2015 +2106 +2015 2018 2018 @@ -2100,22 +1864,14 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c lnd/clm2/urbandata/CTSM52_tbuildmax_OlesonFeddema_2020_0.9x1.25_simyr1849-2106_c200605.nc -lnd/clm2/urbandata/CLM50_tbuildmax_Oleson_2016_0.9x1_ESMFmesh_cdf5_100621.nc - lnd/clm2/urbandata/CTSM52_tbuildmax_OlesonFeddema_2020_0.9x1.25_simyr1849-2106_c200605.nc -lnd/clm2/urbandata/CLM50_tbuildmax_Oleson_2016_0.9x1_ESMFmesh_cdf5_100621.nc - lnd/clm2/urbandata/CLM50_tbuildmax_Oleson_2016_0.9x1.25_simyr1849-2106_c160923.nc -lnd/clm2/urbandata/CLM50_tbuildmax_Oleson_2016_0.9x1_ESMFmesh_cdf5_100621.nc - lnd/clm2/urbandata/CLM45_tbuildmax_Oleson_2016_0.9x1.25_simyr1849-2106_c160923.nc -lnd/clm2/urbandata/CLM50_tbuildmax_Oleson_2016_0.9x1_ESMFmesh_cdf5_100621.nc nn @@ -2168,9 +1924,7 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c -TWS_inversion -TWS_inversion -TWS_inversion +TWS_inversion ZWT_inversion .true. .true. @@ -2259,8 +2013,8 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c off -low low +low .false. 0.26d00 diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 3613574ce3..1873378b40 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,10 +163,10 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 2587; +my $ntests = 3205; if ( defined($opts{'compare'}) ) { - $ntests += 1737; + $ntests += 2258; } plan( tests=>$ntests ); From e4575ec4dbba69e9d6aa350db4a2323a235e240b Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sat, 16 Mar 2024 00:58:27 -0600 Subject: [PATCH 529/614] Point to NGEET repo for FATES --- Externals_CLM.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals_CLM.cfg b/Externals_CLM.cfg index 69d13ca73b..378992c777 100644 --- a/Externals_CLM.cfg +++ b/Externals_CLM.cfg @@ -1,7 +1,7 @@ [fates] local_path = src/fates protocol = git -repo_url = https://github.com/rgknox/fates +repo_url = https://github.com/NGEET/fates tag = sci.1.72.2_api.34.0.0 required = True From 6ad1cbb98ed0589348515594abe06d6492476323 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 19 Mar 2024 09:26:47 -0600 Subject: [PATCH 530/614] Remove the now removed USUMC_nuopc test --- cime_config/testdefs/testlist_clm.xml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index b7906decb3..c9b5c572dc 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -2325,17 +2325,6 @@ - - - - - - - - - - - From c8ec169d42f76ebd738106b96b80685f9d6ae01a Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 19 Mar 2024 16:51:00 -0600 Subject: [PATCH 531/614] Fix the hostname matching to work on Derecho compute nodes --- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index e9d0fcfb23..c8b891c1c4 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -32,7 +32,7 @@ blddir=$cwd/tool_bld # may overwrite this default with command-line option (bel # May overwrite this default with command-line option --machine hostname=`hostname --short` case $hostname in - derecho* | r* ) + derecho* | dec* ) export MACH="derecho" pio_iotype=1 ;; From 2f8994b0e744c1b6dec6c946dccbfe2e3f78d782 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 21 Mar 2024 16:40:37 -0600 Subject: [PATCH 532/614] Update to new synthetic Hillslope test file that @samrabin made based on the ctsm5.2.0 dataset --- cime_config/testdefs/testmods_dirs/clm/Hillslope/user_nl_clm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/testdefs/testmods_dirs/clm/Hillslope/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/Hillslope/user_nl_clm index afdcf4d1fc..4fc6fc2373 100644 --- a/cime_config/testdefs/testmods_dirs/clm/Hillslope/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/Hillslope/user_nl_clm @@ -6,6 +6,6 @@ hillslope_transmissivity_method = 'LayerSum' hillslope_pft_distribution_method = 'PftLowlandUpland' hillslope_soil_profile_method = 'Uniform' -fsurdat = '$DIN_LOC_ROOT/lnd/clm2/testdata/surfdata_10x15_78pfts_simyr2000_synthetic_cosphill_1.3.nc' +fsurdat = '$DIN_LOC_ROOT/lnd/clm2/testdata/surfdata_10x15_hist_2000_78pfts_c240216.synthetic_hillslopes.nc' use_ssre = .false. From a9f2ca1e94ae6276cdcd2c22ecba5113a2a735c4 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 26 Mar 2024 13:42:37 -0600 Subject: [PATCH 533/614] Add a begining unit tester for the jobscript script --- ...st_unit_gen_mksurfdata_jobscript_single.py | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100755 python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py diff --git a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py new file mode 100755 index 0000000000..280fac871d --- /dev/null +++ b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 + +""" +Unit tests for gen_mksurfdata_jobscript_single.py subroutines: +""" + +import unittest +import os +import sys +import shutil + +import tempfile + +from ctsm import unit_testing +from ctsm.path_utils import path_to_ctsm_root +from ctsm.toolchain.gen_mksurfdata_jobscript_single import get_parser +from ctsm.toolchain.gen_mksurfdata_jobscript_single import write_runscript_part1 + +# Allow test names that pylint doesn't like; otherwise hard to make them +# readable +# pylint: disable=invalid-name + +# pylint: disable=protected-access + + +class TestFGenMkSurfJobscriptSingle(unittest.TestCase): + """Tests the gen_mksurfdata_jobscript_single subroutines""" + + def setUp(self): + """Setup for trying out the methods""" + testinputs_path = os.path.join(path_to_ctsm_root(), "python/ctsm/test/testinputs") + self._testinputs_path = testinputs_path + self._previous_dir = os.getcwd() + self._tempdir = tempfile.mkdtemp() + os.chdir(self._tempdir) + self._account = "ACCOUNT_NUMBER" + self._jobscript_file = "output_jobscript" + self._bld_path = os.path.join(self._tempdir, "tools_bld") + os.makedirs(self._bld_path) + self._nlfile = os.path.join(self._tempdir, "namelist_file") + self._sys_argv = [ + "gen_mksurfdata_jobscript_single", + "--bld-path", + self._bld_path, + "--namelist-file", + self._nlfile, + "--jobscript-file", + self._jobscript_file, + ] + + def tearDown(self): + """ + Remove temporary directory + """ + os.chdir(self._previous_dir) + shutil.rmtree(self._tempdir, ignore_errors=True) + + def add_args(self, machine, nodes, tasks): + """ " add arguments""" + self._sys_argv.append( + ["--machine", machine, "--number-of-nodes", nodes, "--tasks-per-node", tasks] + ) + + def tearDown(self): + """ + Remove temporary directory + """ + os.chdir(self._previous_dir) + shutil.rmtree(self._tempdir, ignore_errors=True) + + def test_simple_derecho_args(self): + """test simple derecho arguments""" + machine = "derecho" + nodes = 1 + tasks = 64 + self.add_args(machine, nodes, tasks) + args = get_parser() + with open(self._jobscript_file, "w", encoding="utf-8") as runfile: + attribs = write_runscript_part1(nodes, tasks, machine, self._account, runfile) + + +if __name__ == "__main__": + unit_testing.setup_for_tests() + unittest.main() From ba7b49daf015f4e339fa4362839c31ea497a9e22 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 26 Mar 2024 14:12:32 -0600 Subject: [PATCH 534/614] Add a check for the output batch on derecho that passes, and a check that fails for a bad machine -- need to refactor to have a check subroutine --- ...st_unit_gen_mksurfdata_jobscript_single.py | 27 +++++++++++++++++++ python/ctsm/test/testinputs/output_jobscript | 12 +++++++++ 2 files changed, 39 insertions(+) create mode 100644 python/ctsm/test/testinputs/output_jobscript diff --git a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py index 280fac871d..8690206378 100755 --- a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py @@ -35,6 +35,7 @@ def setUp(self): os.chdir(self._tempdir) self._account = "ACCOUNT_NUMBER" self._jobscript_file = "output_jobscript" + self._output_compare = os.path.join( self._testinputs_path, "output_jobscript" ) self._bld_path = os.path.join(self._tempdir, "tools_bld") os.makedirs(self._bld_path) self._nlfile = os.path.join(self._tempdir, "namelist_file") @@ -68,6 +69,18 @@ def tearDown(self): os.chdir(self._previous_dir) shutil.rmtree(self._tempdir, ignore_errors=True) + def assertFileContentsEqual(self, expected, filepath, msg=None): + """Asserts that the contents of the file given by 'filepath' are equal to + the string given by 'expected'. 'msg' gives an optional message to be + printed if the assertion fails. + + Copied from test_unit_job_launcher_no_batch should go to utils! """ + + with open(filepath, "r") as myfile: + contents = myfile.read() + + self.assertEqual(expected, contents, msg=msg) + def test_simple_derecho_args(self): """test simple derecho arguments""" machine = "derecho" @@ -78,6 +91,20 @@ def test_simple_derecho_args(self): with open(self._jobscript_file, "w", encoding="utf-8") as runfile: attribs = write_runscript_part1(nodes, tasks, machine, self._account, runfile) + self.assertFileContentsEqual( self._jobscript_file, self._outputcompare) + + def test_bad_machine(self): + """test bad machine name""" + machine = "zztop" + nodes = 1 + tasks = 64 + self.add_args(machine, nodes, tasks) + with self.assertRaisesRegex( + SystemExit, + "unrecognized machine", + ): + print( self._sys_argv ) + args = get_parser() if __name__ == "__main__": unit_testing.setup_for_tests() diff --git a/python/ctsm/test/testinputs/output_jobscript b/python/ctsm/test/testinputs/output_jobscript new file mode 100644 index 0000000000..ac85194339 --- /dev/null +++ b/python/ctsm/test/testinputs/output_jobscript @@ -0,0 +1,12 @@ +#!/bin/bash +# Edit the batch directives for your batch system +# Below are default batch directives for derecho +#PBS -N mksurfdata +#PBS -j oe +#PBS -k eod +#PBS -S /bin/bash +#PBS -l walltime=59:00 +#PBS -A ACCOUNT_NUMBER +#PBS -q main +#PBS -l select=1:ncpus=64:mpiprocs=64 + From 4e7eaf85c2b7056441e900999ec8573459385d4f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 26 Mar 2024 15:39:34 -0600 Subject: [PATCH 535/614] Get unit test working and move checking into a subroutine --- ...st_unit_gen_mksurfdata_jobscript_single.py | 37 ++++++++++++------- python/ctsm/test/testinputs/output_jobscript | 12 ------ .../gen_mksurfdata_jobscript_single.py | 15 +++++--- 3 files changed, 33 insertions(+), 31 deletions(-) delete mode 100644 python/ctsm/test/testinputs/output_jobscript diff --git a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py index 8690206378..0adb1b35cb 100755 --- a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py @@ -6,6 +6,7 @@ import unittest import os +import argparse import sys import shutil @@ -14,6 +15,7 @@ from ctsm import unit_testing from ctsm.path_utils import path_to_ctsm_root from ctsm.toolchain.gen_mksurfdata_jobscript_single import get_parser +from ctsm.toolchain.gen_mksurfdata_jobscript_single import check_parser_args from ctsm.toolchain.gen_mksurfdata_jobscript_single import write_runscript_part1 # Allow test names that pylint doesn't like; otherwise hard to make them @@ -35,11 +37,23 @@ def setUp(self): os.chdir(self._tempdir) self._account = "ACCOUNT_NUMBER" self._jobscript_file = "output_jobscript" - self._output_compare = os.path.join( self._testinputs_path, "output_jobscript" ) + self._output_compare = """#!/bin/bash +# Edit the batch directives for your batch system +# Below are default batch directives for derecho +#PBS -N mksurfdata +#PBS -j oe +#PBS -k eod +#PBS -S /bin/bash +#PBS -l walltime=59:00 +#PBS -A ACCOUNT_NUMBER +#PBS -q main +#PBS -l select=1:ncpus=64:mpiprocs=64 + +""" self._bld_path = os.path.join(self._tempdir, "tools_bld") os.makedirs(self._bld_path) self._nlfile = os.path.join(self._tempdir, "namelist_file") - self._sys_argv = [ + sys.argv = [ "gen_mksurfdata_jobscript_single", "--bld-path", self._bld_path, @@ -58,9 +72,9 @@ def tearDown(self): def add_args(self, machine, nodes, tasks): """ " add arguments""" - self._sys_argv.append( - ["--machine", machine, "--number-of-nodes", nodes, "--tasks-per-node", tasks] - ) + args_to_add = ["--machine", machine, "--number-of-nodes", str(nodes), "--tasks-per-node", str(tasks)] + for item in args_to_add: + sys.argv.append( item ) def tearDown(self): """ @@ -87,11 +101,12 @@ def test_simple_derecho_args(self): nodes = 1 tasks = 64 self.add_args(machine, nodes, tasks) - args = get_parser() + args = get_parser().parse_args() with open(self._jobscript_file, "w", encoding="utf-8") as runfile: attribs = write_runscript_part1(nodes, tasks, machine, self._account, runfile) + self.assertEqual( {"mpilib": "default"}, attribs, msg="attribs not as expected" ) - self.assertFileContentsEqual( self._jobscript_file, self._outputcompare) + self.assertFileContentsEqual( self._output_compare, self._jobscript_file ) def test_bad_machine(self): """test bad machine name""" @@ -99,12 +114,8 @@ def test_bad_machine(self): nodes = 1 tasks = 64 self.add_args(machine, nodes, tasks) - with self.assertRaisesRegex( - SystemExit, - "unrecognized machine", - ): - print( self._sys_argv ) - args = get_parser() + with self.assertRaises( SystemExit ): + args = get_parser().parse_args() if __name__ == "__main__": unit_testing.setup_for_tests() diff --git a/python/ctsm/test/testinputs/output_jobscript b/python/ctsm/test/testinputs/output_jobscript deleted file mode 100644 index ac85194339..0000000000 --- a/python/ctsm/test/testinputs/output_jobscript +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -# Edit the batch directives for your batch system -# Below are default batch directives for derecho -#PBS -N mksurfdata -#PBS -j oe -#PBS -k eod -#PBS -S /bin/bash -#PBS -l walltime=59:00 -#PBS -A ACCOUNT_NUMBER -#PBS -q main -#PBS -l select=1:ncpus=64:mpiprocs=64 - diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index f958d41e89..ccead74d93 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -93,6 +93,14 @@ def get_parser(): ) return parser +def check_parser_args( args ): + """ Checking for the argument parser values""" + if args.number_of_nodes < 1: + abort("Input argument --number_of_nodes is zero or negative and needs to be positive") + if args.tasks_per_node < 1: + abort("Input argument --tasks_per_node is zero or negative and needs to be positive") + if not os.path.exists(args.bld_path): + abort("Input Build path (" + args.bld_path + ") does NOT exist, aborting") def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, runfile): """ @@ -170,14 +178,11 @@ def main(): # -------------------------- args = get_parser().parse_args() process_logging_args(args) + check_parser_args( args ) namelist_file = args.namelist_file jobscript_file = args.jobscript_file number_of_nodes = args.number_of_nodes - if number_of_nodes < 1: - abort("Input argument --number_of_nodes is zero or negative and needs to be positive") tasks_per_node = args.tasks_per_node - if tasks_per_node < 1: - abort("Input argument --tasks_per_node is zero or negative and needs to be positive") machine = args.machine account = args.account @@ -191,8 +196,6 @@ def main(): # Obtain mpirun command from env_mach_specific.xml # -------------------------- bld_path = args.bld_path - if not os.path.exists(bld_path): - abort("Input Build path (" + bld_path + ") does NOT exist, aborting") # Get the ems_file object with standalone_configure=True # and the fake_case object with mpilib=attribs['mpilib'] # so as to use the get_mpirun function pointing to fake_case From 96a31610ad21869067db35dd7650397f213f6a99 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 26 Mar 2024 16:14:29 -0600 Subject: [PATCH 536/614] Fix pylint errors, run through black, make sure unit and sys tests pass, remove trailing whitespace --- ...st_unit_gen_mksurfdata_jobscript_single.py | 110 ++++++++++++------ .../gen_mksurfdata_jobscript_single.py | 46 ++++---- 2 files changed, 99 insertions(+), 57 deletions(-) diff --git a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py index 0adb1b35cb..4c82613a9a 100755 --- a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py @@ -6,7 +6,6 @@ import unittest import os -import argparse import sys import shutil @@ -18,13 +17,27 @@ from ctsm.toolchain.gen_mksurfdata_jobscript_single import check_parser_args from ctsm.toolchain.gen_mksurfdata_jobscript_single import write_runscript_part1 + +def add_args(machine, nodes, tasks): + """add arguments to sys.argv""" + args_to_add = [ + "--machine", + machine, + "--number-of-nodes", + str(nodes), + "--tasks-per-node", + str(tasks), + ] + for item in args_to_add: + sys.argv.append(item) + + # Allow test names that pylint doesn't like; otherwise hard to make them # readable # pylint: disable=invalid-name # pylint: disable=protected-access - - +# pylint: disable=too-many-instance-attributes class TestFGenMkSurfJobscriptSingle(unittest.TestCase): """Tests the gen_mksurfdata_jobscript_single subroutines""" @@ -37,17 +50,17 @@ def setUp(self): os.chdir(self._tempdir) self._account = "ACCOUNT_NUMBER" self._jobscript_file = "output_jobscript" - self._output_compare = """#!/bin/bash -# Edit the batch directives for your batch system -# Below are default batch directives for derecho -#PBS -N mksurfdata -#PBS -j oe -#PBS -k eod -#PBS -S /bin/bash -#PBS -l walltime=59:00 -#PBS -A ACCOUNT_NUMBER -#PBS -q main -#PBS -l select=1:ncpus=64:mpiprocs=64 + self._output_compare = """#!/bin/bash +# Edit the batch directives for your batch system +# Below are default batch directives for derecho +#PBS -N mksurfdata +#PBS -j oe +#PBS -k eod +#PBS -S /bin/bash +#PBS -l walltime=59:00 +#PBS -A ACCOUNT_NUMBER +#PBS -q main +#PBS -l select=1:ncpus=64:mpiprocs=64 """ self._bld_path = os.path.join(self._tempdir, "tools_bld") @@ -70,25 +83,12 @@ def tearDown(self): os.chdir(self._previous_dir) shutil.rmtree(self._tempdir, ignore_errors=True) - def add_args(self, machine, nodes, tasks): - """ " add arguments""" - args_to_add = ["--machine", machine, "--number-of-nodes", str(nodes), "--tasks-per-node", str(tasks)] - for item in args_to_add: - sys.argv.append( item ) - - def tearDown(self): - """ - Remove temporary directory - """ - os.chdir(self._previous_dir) - shutil.rmtree(self._tempdir, ignore_errors=True) - def assertFileContentsEqual(self, expected, filepath, msg=None): """Asserts that the contents of the file given by 'filepath' are equal to the string given by 'expected'. 'msg' gives an optional message to be printed if the assertion fails. - - Copied from test_unit_job_launcher_no_batch should go to utils! """ + + Copied from test_unit_job_launcher_no_batch should go to utils!""" with open(filepath, "r") as myfile: contents = myfile.read() @@ -100,22 +100,62 @@ def test_simple_derecho_args(self): machine = "derecho" nodes = 1 tasks = 64 - self.add_args(machine, nodes, tasks) + add_args(machine, nodes, tasks) args = get_parser().parse_args() + check_parser_args(args) with open(self._jobscript_file, "w", encoding="utf-8") as runfile: attribs = write_runscript_part1(nodes, tasks, machine, self._account, runfile) - self.assertEqual( {"mpilib": "default"}, attribs, msg="attribs not as expected" ) + self.assertEqual({"mpilib": "default"}, attribs, msg="attribs not as expected") + + self.assertFileContentsEqual(self._output_compare, self._jobscript_file) - self.assertFileContentsEqual( self._output_compare, self._jobscript_file ) + def test_zero_nodes(self): + """test for fail on zero nodes""" + machine = "derecho" + nodes = 0 + tasks = 64 + add_args(machine, nodes, tasks) + args = get_parser().parse_args() + with self.assertRaisesRegex( + SystemExit, + "Input argument --number_of_nodes is zero or negative and needs to be positive", + ): + check_parser_args(args) + + def test_zero_tasks(self): + """test for fail on zero tasks""" + machine = "derecho" + nodes = 5 + tasks = 0 + add_args(machine, nodes, tasks) + args = get_parser().parse_args() + with self.assertRaisesRegex( + SystemExit, + "Input argument --tasks_per_node is zero or negative and needs to be positive", + ): + check_parser_args(args) + + def test_bld_build_path(self): + """test for bad build path""" + machine = "derecho" + nodes = 10 + tasks = 64 + add_args(machine, nodes, tasks) + # Remove the build path directory + shutil.rmtree(self._bld_path, ignore_errors=True) + args = get_parser().parse_args() + with self.assertRaisesRegex(SystemExit, "Input Build path .+ does NOT exist, aborting"): + check_parser_args(args) def test_bad_machine(self): """test bad machine name""" machine = "zztop" nodes = 1 tasks = 64 - self.add_args(machine, nodes, tasks) - with self.assertRaises( SystemExit ): - args = get_parser().parse_args() + add_args(machine, nodes, tasks) + with self.assertRaises(SystemExit): + get_parser().parse_args() + if __name__ == "__main__": unit_testing.setup_for_tests() diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index ccead74d93..5deeb81f50 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -93,8 +93,9 @@ def get_parser(): ) return parser -def check_parser_args( args ): - """ Checking for the argument parser values""" + +def check_parser_args(args): + """Checking for the argument parser values""" if args.number_of_nodes < 1: abort("Input argument --number_of_nodes is zero or negative and needs to be positive") if args.tasks_per_node < 1: @@ -102,43 +103,44 @@ def check_parser_args( args ): if not os.path.exists(args.bld_path): abort("Input Build path (" + args.bld_path + ") does NOT exist, aborting") + def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, runfile): """ Write run script (part 1) """ - runfile.write("#!/bin/bash \n") - runfile.write("# Edit the batch directives for your batch system \n") - runfile.write(f"# Below are default batch directives for {machine} \n") - runfile.write("#PBS -N mksurfdata \n") - runfile.write("#PBS -j oe \n") - runfile.write("#PBS -k eod \n") - runfile.write("#PBS -S /bin/bash \n") + runfile.write("#!/bin/bash\n") + runfile.write("# Edit the batch directives for your batch system\n") + runfile.write(f"# Below are default batch directives for {machine}\n") + runfile.write("#PBS -N mksurfdata\n") + runfile.write("#PBS -j oe\n") + runfile.write("#PBS -k eod\n") + runfile.write("#PBS -S /bin/bash\n") if machine == "derecho": attribs = {"mpilib": "default"} - runfile.write("#PBS -l walltime=59:00 \n") - runfile.write(f"#PBS -A {account} \n") - runfile.write("#PBS -q main \n") + runfile.write("#PBS -l walltime=59:00\n") + runfile.write(f"#PBS -A {account}\n") + runfile.write("#PBS -q main\n") runfile.write( "#PBS -l select=" - + f"{number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node} \n" + + f"{number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node}\n" ) elif machine == "casper": attribs = {"mpilib": "default"} - runfile.write("#PBS -l walltime=1:00:00 \n") - runfile.write(f"#PBS -A {account} \n") - runfile.write("#PBS -q casper \n") + runfile.write("#PBS -l walltime=1:00:00\n") + runfile.write(f"#PBS -A {account}\n") + runfile.write("#PBS -q casper\n") runfile.write( f"#PBS -l select={number_of_nodes}:ncpus={tasks_per_node}:" - f"mpiprocs={tasks_per_node}:mem=80GB \n" + f"mpiprocs={tasks_per_node}:mem=80GB\n" ) elif machine == "izumi": attribs = {"mpilib": "mvapich2"} - runfile.write("#PBS -l walltime=2:00:00 \n") - runfile.write("#PBS -q medium \n") - runfile.write(f"#PBS -l nodes={number_of_nodes}:ppn={tasks_per_node},mem=555GB -r n \n") + runfile.write("#PBS -l walltime=2:00:00\n") + runfile.write("#PBS -q medium\n") + runfile.write(f"#PBS -l nodes={number_of_nodes}:ppn={tasks_per_node},mem=555GB -r n\n") tool_path = os.path.dirname(os.path.abspath(__file__)) runfile.write("\n") - runfile.write(f"cd {tool_path} \n") + runfile.write(f"cd {tool_path}\n") runfile.write("\n") return attribs @@ -178,7 +180,7 @@ def main(): # -------------------------- args = get_parser().parse_args() process_logging_args(args) - check_parser_args( args ) + check_parser_args(args) namelist_file = args.namelist_file jobscript_file = args.jobscript_file number_of_nodes = args.number_of_nodes From fd34f327233af3f3e6e17e31e0d7505e3ce2a3e8 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 26 Mar 2024 17:15:00 -0600 Subject: [PATCH 537/614] Move checking for executable and .env_mach_specific.sh file up to the check function and add tests for it and get make all to pass --- ...st_unit_gen_mksurfdata_jobscript_single.py | 36 +++++++++++++++++++ .../gen_mksurfdata_jobscript_single.py | 15 ++++++++ 2 files changed, 51 insertions(+) diff --git a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py index 4c82613a9a..5016105d3f 100755 --- a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py @@ -32,6 +32,11 @@ def add_args(machine, nodes, tasks): sys.argv.append(item) +def create_empty_file(filename): + """create an empty file""" + os.system("touch " + filename) + + # Allow test names that pylint doesn't like; otherwise hard to make them # readable # pylint: disable=invalid-name @@ -65,7 +70,16 @@ def setUp(self): """ self._bld_path = os.path.join(self._tempdir, "tools_bld") os.makedirs(self._bld_path) + self.assertTrue(os.path.isdir(self._bld_path)) self._nlfile = os.path.join(self._tempdir, "namelist_file") + create_empty_file(self._nlfile) + self.assertTrue(os.path.exists(self._nlfile)) + self._mksurf_exe = os.path.join(self._bld_path, "mksurfdata") + create_empty_file(self._mksurf_exe) + self.assertTrue(os.path.exists(self._mksurf_exe)) + self._env_mach = os.path.join(self._bld_path, ".env_mach_specific.sh") + create_empty_file(self._env_mach) + self.assertTrue(os.path.exists(self._env_mach)) sys.argv = [ "gen_mksurfdata_jobscript_single", "--bld-path", @@ -147,6 +161,28 @@ def test_bld_build_path(self): with self.assertRaisesRegex(SystemExit, "Input Build path .+ does NOT exist, aborting"): check_parser_args(args) + def test_mksurfdata_exist(self): + """test fails if mksurfdata does not exist""" + machine = "derecho" + nodes = 10 + tasks = 64 + add_args(machine, nodes, tasks) + args = get_parser().parse_args() + os.remove(self._mksurf_exe) + with self.assertRaisesRegex(SystemExit, "mksurfdata_esmf executable "): + check_parser_args(args) + + def test_env_mach_specific_exist(self): + """test fails if the .env_mach_specific.sh file does not exist""" + machine = "derecho" + nodes = 10 + tasks = 64 + add_args(machine, nodes, tasks) + args = get_parser().parse_args() + os.remove(self._env_mach) + with self.assertRaisesRegex(SystemExit, "Environment machine specific file"): + check_parser_args(args) + def test_bad_machine(self): """test bad machine name""" machine = "zztop" diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 5deeb81f50..c58d2fb4b8 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -103,6 +103,21 @@ def check_parser_args(args): if not os.path.exists(args.bld_path): abort("Input Build path (" + args.bld_path + ") does NOT exist, aborting") + mksurfdata_path = os.path.join(args.bld_path, "mksurfdata") + if not os.path.exists(mksurfdata_path): + abort( + "mksurfdata_esmf executable (" + + mksurfdata_path + + ") does NOT exist in the bld-path, aborting" + ) + env_mach_path = os.path.join(args.bld_path, ".env_mach_specific.sh") + if not os.path.exists(env_mach_path): + abort( + "Environment machine specific file (" + + env_mach_path + + ") does NOT exist in the bld-path, aborting" + ) + def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, runfile): """ From 7dbe3d23c210f197737b53557e4cd2a42085a446 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 26 Mar 2024 22:57:26 -0600 Subject: [PATCH 538/614] Refactor to move mpirun into it's own subroutine --- .../gen_mksurfdata_jobscript_single.py | 69 +++++++++---------- 1 file changed, 31 insertions(+), 38 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index c58d2fb4b8..422a4361f9 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -160,6 +160,36 @@ def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, run runfile.write("\n") return attribs +def get_mpirun( args, attribs ): + """ Get the mpirun command for this machine """ + bld_path = args.bld_path + # Get the ems_file object with standalone_configure=True + # and the fake_case object with mpilib=attribs['mpilib'] + # so as to use the get_mpirun function pointing to fake_case + ems_file = EnvMachSpecific(bld_path, standalone_configure=True) + fake_case = FakeCase(compiler=None, mpilib=attribs["mpilib"], debug=False, comp_interface=None) + total_tasks = int(args.tasks_per_node) * int(args.number_of_nodes) + cmd = ems_file.get_mpirun( + fake_case, + attribs, + job="name", + exe_only=True, + overrides={ + "total_tasks": total_tasks, + }, + ) + # cmd is a tuple: + # cmd[0] contains the mpirun command (eg mpirun, mpiexe, etc) as string + # cmd[1] contains a list of strings that we append as options to cmd[0] + # The replace function removes unnecessary characters that appear in + # some such options + executable = f'{cmd[0]} {" ".join(cmd[1])}'.replace("ENV{", "").replace("}", "") + + mksurfdata_path = os.path.join(bld_path, "mksurfdata") + env_mach_path = os.path.join(bld_path, ".env_mach_specific.sh") + + return (executable, mksurfdata_path, env_mach_path) + def write_runscript_part2(namelist_file, runfile, executable, mksurfdata_path, env_mach_path): """ @@ -185,7 +215,6 @@ def write_runscript_part2(namelist_file, runfile, executable, mksurfdata_path, e runfile.write(f"{check} \n") runfile.write("echo Successfully ran resolution\n") - def main(): """ See docstring at the top. @@ -212,43 +241,7 @@ def main(): # -------------------------- # Obtain mpirun command from env_mach_specific.xml # -------------------------- - bld_path = args.bld_path - # Get the ems_file object with standalone_configure=True - # and the fake_case object with mpilib=attribs['mpilib'] - # so as to use the get_mpirun function pointing to fake_case - ems_file = EnvMachSpecific(bld_path, standalone_configure=True) - fake_case = FakeCase(compiler=None, mpilib=attribs["mpilib"], debug=False, comp_interface=None) - total_tasks = int(tasks_per_node) * int(number_of_nodes) - cmd = ems_file.get_mpirun( - fake_case, - attribs, - job="name", - exe_only=True, - overrides={ - "total_tasks": total_tasks, - }, - ) - # cmd is a tuple: - # cmd[0] contains the mpirun command (eg mpirun, mpiexe, etc) as string - # cmd[1] contains a list of strings that we append as options to cmd[0] - # The replace function removes unnecessary characters that appear in - # some such options - executable = f'{cmd[0]} {" ".join(cmd[1])}'.replace("ENV{", "").replace("}", "") - - mksurfdata_path = os.path.join(bld_path, "mksurfdata") - if not os.path.exists(mksurfdata_path): - abort( - "mksurfdata_esmf executable (" - + mksurfdata_path - + ") does NOT exist in the bld-path, aborting" - ) - env_mach_path = os.path.join(bld_path, ".env_mach_specific.sh") - if not os.path.exists(env_mach_path): - abort( - "Environment machine specific file (" - + env_mach_path - + ") does NOT exist in the bld-path, aborting" - ) + (executable, mksurfdata_path, env_mach_path) = get_mpirun( args, attribs ) # -------------------------- # Write run script (part 2) From f7842be62b27b0c2db658ddac5d72f98d16a55b7 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 26 Mar 2024 23:56:52 -0600 Subject: [PATCH 539/614] Set derecho ncpus to 128, add failing tests for too many tasks --- ...st_unit_gen_mksurfdata_jobscript_single.py | 24 ++++++++++--------- .../gen_mksurfdata_jobscript_single.py | 13 ++++++---- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py index 5016105d3f..0c8b8d2cde 100755 --- a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py @@ -65,7 +65,7 @@ def setUp(self): #PBS -l walltime=59:00 #PBS -A ACCOUNT_NUMBER #PBS -q main -#PBS -l select=1:ncpus=64:mpiprocs=64 +#PBS -l select=1:ncpus=128:mpiprocs=64 """ self._bld_path = os.path.join(self._tempdir, "tools_bld") @@ -119,22 +119,24 @@ def test_simple_derecho_args(self): check_parser_args(args) with open(self._jobscript_file, "w", encoding="utf-8") as runfile: attribs = write_runscript_part1(nodes, tasks, machine, self._account, runfile) - self.assertEqual({"mpilib": "default"}, attribs, msg="attribs not as expected") + self.assertEqual({"mpilib": "default", "ncpus": 128}, attribs, msg="attribs not as expected") self.assertFileContentsEqual(self._output_compare, self._jobscript_file) - def test_zero_nodes(self): - """test for fail on zero nodes""" + def test_too_many_tasks(self): + """test trying to use too many tasks""" machine = "derecho" - nodes = 0 - tasks = 64 + nodes = 1 + tasks = 129 add_args(machine, nodes, tasks) args = get_parser().parse_args() - with self.assertRaisesRegex( - SystemExit, - "Input argument --number_of_nodes is zero or negative and needs to be positive", - ): - check_parser_args(args) + check_parser_args(args) + with open(self._jobscript_file, "w", encoding="utf-8") as runfile: + with self.assertRaisesRegex( + SystemExit, + "Number of tasks per node exceeds the number of processors per node on this machine" + ): + write_runscript_part1(nodes, tasks, machine, self._account, runfile) def test_zero_tasks(self): """test for fail on zero tasks""" diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 422a4361f9..87a55f4c16 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -131,16 +131,17 @@ def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, run runfile.write("#PBS -k eod\n") runfile.write("#PBS -S /bin/bash\n") if machine == "derecho": - attribs = {"mpilib": "default"} + attribs = {"mpilib": "default", "ncpus":128} runfile.write("#PBS -l walltime=59:00\n") runfile.write(f"#PBS -A {account}\n") runfile.write("#PBS -q main\n") + ncpus = attribs["ncpus"] runfile.write( "#PBS -l select=" - + f"{number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node}\n" + + f"{number_of_nodes}:ncpus={ncpus}:mpiprocs={tasks_per_node}\n" ) elif machine == "casper": - attribs = {"mpilib": "default"} + attribs = {"mpilib": "default", "ncpus":36} runfile.write("#PBS -l walltime=1:00:00\n") runfile.write(f"#PBS -A {account}\n") runfile.write("#PBS -q casper\n") @@ -149,7 +150,7 @@ def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, run f"mpiprocs={tasks_per_node}:mem=80GB\n" ) elif machine == "izumi": - attribs = {"mpilib": "mvapich2"} + attribs = {"mpilib": "mvapich2", "ncpus":48} runfile.write("#PBS -l walltime=2:00:00\n") runfile.write("#PBS -q medium\n") runfile.write(f"#PBS -l nodes={number_of_nodes}:ppn={tasks_per_node},mem=555GB -r n\n") @@ -158,6 +159,10 @@ def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, run runfile.write(f"cd {tool_path}\n") runfile.write("\n") + + # Make sure tasks_per_node doesn't exceed the number of cpus per node + #if tasks_per_node > attribs["ncpus"]: + #abort( "Number of tasks per node exceeds the number of processors per node on this machine" ) return attribs def get_mpirun( args, attribs ): From 64f5a0c0fffa230b54608ff4e4b366ae9df6051d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 27 Mar 2024 00:13:54 -0600 Subject: [PATCH 540/614] Get the unit test working --- .../test_unit_gen_mksurfdata_jobscript_single.py | 2 +- .../toolchain/gen_mksurfdata_jobscript_single.py | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py index 0c8b8d2cde..4e4cb51672 100755 --- a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py @@ -119,7 +119,7 @@ def test_simple_derecho_args(self): check_parser_args(args) with open(self._jobscript_file, "w", encoding="utf-8") as runfile: attribs = write_runscript_part1(nodes, tasks, machine, self._account, runfile) - self.assertEqual({"mpilib": "default", "ncpus": 128}, attribs, msg="attribs not as expected") + self.assertEqual({"mpilib": "default"}, attribs, msg="attribs not as expected") self.assertFileContentsEqual(self._output_compare, self._jobscript_file) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 87a55f4c16..6873cfee9a 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -131,17 +131,18 @@ def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, run runfile.write("#PBS -k eod\n") runfile.write("#PBS -S /bin/bash\n") if machine == "derecho": - attribs = {"mpilib": "default", "ncpus":128} + attribs = {"mpilib": "default"} runfile.write("#PBS -l walltime=59:00\n") runfile.write(f"#PBS -A {account}\n") runfile.write("#PBS -q main\n") - ncpus = attribs["ncpus"] + ncpus = 128 runfile.write( "#PBS -l select=" + f"{number_of_nodes}:ncpus={ncpus}:mpiprocs={tasks_per_node}\n" ) elif machine == "casper": - attribs = {"mpilib": "default", "ncpus":36} + attribs = {"mpilib": "default"} + ncpus = 36 runfile.write("#PBS -l walltime=1:00:00\n") runfile.write(f"#PBS -A {account}\n") runfile.write("#PBS -q casper\n") @@ -150,7 +151,8 @@ def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, run f"mpiprocs={tasks_per_node}:mem=80GB\n" ) elif machine == "izumi": - attribs = {"mpilib": "mvapich2", "ncpus":48} + attribs = {"mpilib": "mvapich2"} + ncpus = 48 runfile.write("#PBS -l walltime=2:00:00\n") runfile.write("#PBS -q medium\n") runfile.write(f"#PBS -l nodes={number_of_nodes}:ppn={tasks_per_node},mem=555GB -r n\n") @@ -161,8 +163,8 @@ def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, run runfile.write("\n") # Make sure tasks_per_node doesn't exceed the number of cpus per node - #if tasks_per_node > attribs["ncpus"]: - #abort( "Number of tasks per node exceeds the number of processors per node on this machine" ) + if tasks_per_node > ncpus: + abort( "Number of tasks per node exceeds the number of processors per node on this machine" ) return attribs def get_mpirun( args, attribs ): From 9660667b1267dcd4150889f5f39db540158be74a Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 27 Mar 2024 00:20:33 -0600 Subject: [PATCH 541/614] Run black --- .../test_unit_gen_mksurfdata_jobscript_single.py | 2 +- .../toolchain/gen_mksurfdata_jobscript_single.py | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py index 4e4cb51672..8867792ec2 100755 --- a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py @@ -134,7 +134,7 @@ def test_too_many_tasks(self): with open(self._jobscript_file, "w", encoding="utf-8") as runfile: with self.assertRaisesRegex( SystemExit, - "Number of tasks per node exceeds the number of processors per node on this machine" + "Number of tasks per node exceeds the number of processors per node on this machine", ): write_runscript_part1(nodes, tasks, machine, self._account, runfile) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 6873cfee9a..0cd29d7cbf 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -137,8 +137,7 @@ def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, run runfile.write("#PBS -q main\n") ncpus = 128 runfile.write( - "#PBS -l select=" - + f"{number_of_nodes}:ncpus={ncpus}:mpiprocs={tasks_per_node}\n" + "#PBS -l select=" + f"{number_of_nodes}:ncpus={ncpus}:mpiprocs={tasks_per_node}\n" ) elif machine == "casper": attribs = {"mpilib": "default"} @@ -164,11 +163,12 @@ def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, run # Make sure tasks_per_node doesn't exceed the number of cpus per node if tasks_per_node > ncpus: - abort( "Number of tasks per node exceeds the number of processors per node on this machine" ) + abort("Number of tasks per node exceeds the number of processors per node on this machine") return attribs -def get_mpirun( args, attribs ): - """ Get the mpirun command for this machine """ + +def get_mpirun(args, attribs): + """Get the mpirun command for this machine""" bld_path = args.bld_path # Get the ems_file object with standalone_configure=True # and the fake_case object with mpilib=attribs['mpilib'] @@ -222,6 +222,7 @@ def write_runscript_part2(namelist_file, runfile, executable, mksurfdata_path, e runfile.write(f"{check} \n") runfile.write("echo Successfully ran resolution\n") + def main(): """ See docstring at the top. @@ -248,7 +249,7 @@ def main(): # -------------------------- # Obtain mpirun command from env_mach_specific.xml # -------------------------- - (executable, mksurfdata_path, env_mach_path) = get_mpirun( args, attribs ) + (executable, mksurfdata_path, env_mach_path) = get_mpirun(args, attribs) # -------------------------- # Write run script (part 2) From c6cf922c45eb31f748a4559f4fc7c58de77d7732 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 27 Mar 2024 00:22:55 -0600 Subject: [PATCH 542/614] Add black to git-blame --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index f4b7b3edba..f6f5552e18 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -40,3 +40,4 @@ de9a30bfbbec36f9dcacc4380005ab596da47af4 cda0cf1412212e6f4363e6e8eb39f74c944b454d aa04d1f7d86cc2503b98b7e2b2d84dbfff6c316b 6c6f57e948bfa31e60b383536cc21663fedb8b70 +9660667b1267dcd4150889f5f39db540158be74a From 8315364f7115eb31744ce36337335efab159f51c Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 27 Mar 2024 14:01:56 -0600 Subject: [PATCH 543/614] pylint/black update Get pylint and black to pass --- ...st_unit_gen_mksurfdata_jobscript_single.py | 43 +++++++++++++++++++ .../gen_mksurfdata_jobscript_single.py | 27 ++++++------ 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py index 8867792ec2..988fdaf955 100755 --- a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py @@ -13,7 +13,10 @@ from ctsm import unit_testing from ctsm.path_utils import path_to_ctsm_root +from ctsm.path_utils import path_to_cime +from ctsm.os_utils import run_cmd_output_on_error from ctsm.toolchain.gen_mksurfdata_jobscript_single import get_parser +from ctsm.toolchain.gen_mksurfdata_jobscript_single import get_mpirun from ctsm.toolchain.gen_mksurfdata_jobscript_single import check_parser_args from ctsm.toolchain.gen_mksurfdata_jobscript_single import write_runscript_part1 @@ -88,6 +91,8 @@ def setUp(self): self._nlfile, "--jobscript-file", self._jobscript_file, + "--account", + self._account, ] def tearDown(self): @@ -123,6 +128,44 @@ def test_simple_derecho_args(self): self.assertFileContentsEqual(self._output_compare, self._jobscript_file) + def test_derecho_mpirun(self): + """ + test derecho mpirun. This would've helped caught a problem we ran into + It will also be helpful when externals are updated to guide to solutions + to problems + """ + machine = "derecho" + nodes = 4 + tasks = 128 + add_args(machine, nodes, tasks) + args = get_parser().parse_args() + check_parser_args(args) + self.assertEqual(machine, args.machine) + self.assertEqual(tasks, args.tasks_per_node) + self.assertEqual(nodes, args.number_of_nodes) + self.assertEqual(self._account, args.account) + # Create the env_mach_specific.xml file needed for get_mpirun + # This will catch problems with our usage of CIME objects + # Doing this here will also catch potential issues in the gen_mksurfdata_build.sh script + configure_path = os.path.join(path_to_cime(), "CIME", "scripts", "configure") + self.assertTrue(os.path.exists(configure_path)) + options = " --macros-format CMake --silent --compiler intel --machine " + machine + cmd = configure_path + options + cmd_list = cmd.split() + run_cmd_output_on_error( + cmd=cmd_list, errmsg="Trouble running configure", cwd=self._bld_path + ) + self.assertTrue(os.path.exists(self._env_mach)) + expected_attribs = {"mpilib": "default"} + with open(self._jobscript_file, "w", encoding="utf-8") as runfile: + attribs = write_runscript_part1(nodes, tasks, machine, self._account, runfile) + self.assertEqual(attribs, expected_attribs) + (executable, mksurfdata_path, env_mach_path) = get_mpirun(args, attribs) + expected_exe = "mpibind " + self.assertEquals(executable, expected_exe) + self.assertEqual(mksurfdata_path, self._mksurf_exe) + self.assertEqual(env_mach_path, self._env_mach) + def test_too_many_tasks(self): """test trying to use too many tasks""" machine = "derecho" diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 0cd29d7cbf..d200b57f72 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -168,7 +168,10 @@ def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, run def get_mpirun(args, attribs): - """Get the mpirun command for this machine""" + """ + Get the mpirun command for this machine + This requires a working env_mach_specific.xml file in the build directory + """ bld_path = args.bld_path # Get the ems_file object with standalone_configure=True # and the fake_case object with mpilib=attribs['mpilib'] @@ -241,20 +244,20 @@ def main(): account = args.account # -------------------------- - # Write run script (part 1) + # Write to file # -------------------------- with open(jobscript_file, "w", encoding="utf-8") as runfile: + # -------------------------- + # Write batch header (part 1) + # -------------------------- attribs = write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, runfile) - - # -------------------------- - # Obtain mpirun command from env_mach_specific.xml - # -------------------------- - (executable, mksurfdata_path, env_mach_path) = get_mpirun(args, attribs) - - # -------------------------- - # Write run script (part 2) - # -------------------------- - with open(jobscript_file, "a", encoding="utf-8") as runfile: + # -------------------------- + # Obtain mpirun command from env_mach_specific.xml + # -------------------------- + (executable, mksurfdata_path, env_mach_path) = get_mpirun(args, attribs) + # -------------------------- + # Write commands to run + # -------------------------- write_runscript_part2(namelist_file, runfile, executable, mksurfdata_path, env_mach_path) print(f"echo Successfully created jobscript {jobscript_file}\n") From c1fe45ae899769640650719c77e9b473924cf387 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 27 Mar 2024 14:12:52 -0600 Subject: [PATCH 544/614] pylint black changes --- .../ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py index 988fdaf955..4f3725c870 100755 --- a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py @@ -162,7 +162,7 @@ def test_derecho_mpirun(self): self.assertEqual(attribs, expected_attribs) (executable, mksurfdata_path, env_mach_path) = get_mpirun(args, attribs) expected_exe = "mpibind " - self.assertEquals(executable, expected_exe) + self.assertEqual(executable, expected_exe) self.assertEqual(mksurfdata_path, self._mksurf_exe) self.assertEqual(env_mach_path, self._env_mach) @@ -177,7 +177,8 @@ def test_too_many_tasks(self): with open(self._jobscript_file, "w", encoding="utf-8") as runfile: with self.assertRaisesRegex( SystemExit, - "Number of tasks per node exceeds the number of processors per node on this machine", + "Number of tasks per node exceeds the number of processors per node" + + " on this machine", ): write_runscript_part1(nodes, tasks, machine, self._account, runfile) From ae455fae3e73775eb8bc8a61147628d82ed5f7fb Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 27 Mar 2024 19:34:46 -0600 Subject: [PATCH 545/614] Move walltime and a few other things only in the multi script and not in the single script --- ...st_unit_gen_mksurfdata_jobscript_single.py | 17 ++++++--- .../gen_mksurfdata_jobscript_single.py | 38 +++++++++++++++---- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py index 4f3725c870..73b45578bb 100755 --- a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py @@ -65,10 +65,13 @@ def setUp(self): #PBS -j oe #PBS -k eod #PBS -S /bin/bash -#PBS -l walltime=59:00 +#PBS -l walltime=12:00:00 #PBS -A ACCOUNT_NUMBER #PBS -q main -#PBS -l select=1:ncpus=128:mpiprocs=64 +#PBS -l select=1:ncpus=128:mpiprocs=64:mem=218GB + +# This is a batch script to run a set of resolutions for mksurfdata_esmf input namelist +# NOTE: THIS SCRIPT IS AUTOMATICALLY GENERATED SO IN GENERAL YOU SHOULD NOT EDIT it!! """ self._bld_path = os.path.join(self._tempdir, "tools_bld") @@ -123,7 +126,9 @@ def test_simple_derecho_args(self): args = get_parser().parse_args() check_parser_args(args) with open(self._jobscript_file, "w", encoding="utf-8") as runfile: - attribs = write_runscript_part1(nodes, tasks, machine, self._account, runfile) + attribs = write_runscript_part1( + nodes, tasks, machine, self._account, args.walltime, runfile + ) self.assertEqual({"mpilib": "default"}, attribs, msg="attribs not as expected") self.assertFileContentsEqual(self._output_compare, self._jobscript_file) @@ -158,7 +163,9 @@ def test_derecho_mpirun(self): self.assertTrue(os.path.exists(self._env_mach)) expected_attribs = {"mpilib": "default"} with open(self._jobscript_file, "w", encoding="utf-8") as runfile: - attribs = write_runscript_part1(nodes, tasks, machine, self._account, runfile) + attribs = write_runscript_part1( + nodes, tasks, machine, self._account, args.walltime, runfile + ) self.assertEqual(attribs, expected_attribs) (executable, mksurfdata_path, env_mach_path) = get_mpirun(args, attribs) expected_exe = "mpibind " @@ -180,7 +187,7 @@ def test_too_many_tasks(self): "Number of tasks per node exceeds the number of processors per node" + " on this machine", ): - write_runscript_part1(nodes, tasks, machine, self._account, runfile) + write_runscript_part1(nodes, tasks, machine, self._account, args.walltime, runfile) def test_zero_tasks(self): """test for fail on zero tasks""" diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index d200b57f72..f6c4d60219 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -91,6 +91,14 @@ def get_parser(): required=False, default="mksurfdata_jobscript_single", ) + parser.add_argument( + "--walltime", + help="""Wallclock time for job submission default is 12:00:00)""", + action="store", + dest="walltime", + required=False, + default="12:00:00", + ) return parser @@ -119,9 +127,11 @@ def check_parser_args(args): ) -def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, runfile): +def write_runscript_part1( + number_of_nodes, tasks_per_node, machine, account, walltime, runfile, descrip="input namelist" +): """ - Write run script (part 1) + Write run script (part 1) Batch headers """ runfile.write("#!/bin/bash\n") runfile.write("# Edit the batch directives for your batch system\n") @@ -129,20 +139,22 @@ def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, run runfile.write("#PBS -N mksurfdata\n") runfile.write("#PBS -j oe\n") runfile.write("#PBS -k eod\n") + runfile.write("#PBS -S /bin/bash\n") if machine == "derecho": attribs = {"mpilib": "default"} - runfile.write("#PBS -l walltime=59:00\n") + runfile.write(f"#PBS -l walltime={walltime}\n") runfile.write(f"#PBS -A {account}\n") runfile.write("#PBS -q main\n") ncpus = 128 runfile.write( - "#PBS -l select=" + f"{number_of_nodes}:ncpus={ncpus}:mpiprocs={tasks_per_node}\n" + "#PBS -l select=" + + f"{number_of_nodes}:ncpus={ncpus}:mpiprocs={tasks_per_node}:mem=218GB\n" ) elif machine == "casper": attribs = {"mpilib": "default"} ncpus = 36 - runfile.write("#PBS -l walltime=1:00:00\n") + runfile.write(f"#PBS -l walltime={walltime}\n") runfile.write(f"#PBS -A {account}\n") runfile.write("#PBS -q casper\n") runfile.write( @@ -152,7 +164,7 @@ def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, run elif machine == "izumi": attribs = {"mpilib": "mvapich2"} ncpus = 48 - runfile.write("#PBS -l walltime=2:00:00\n") + runfile.write(f"#PBS -l walltime={walltime}\n") runfile.write("#PBS -q medium\n") runfile.write(f"#PBS -l nodes={number_of_nodes}:ppn={tasks_per_node},mem=555GB -r n\n") tool_path = os.path.dirname(os.path.abspath(__file__)) @@ -160,6 +172,13 @@ def write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, run runfile.write(f"cd {tool_path}\n") runfile.write("\n") + runfile.write( + f"# This is a batch script to run a set of resolutions for mksurfdata_esmf {descrip}\n" + ) + runfile.write( + "# NOTE: THIS SCRIPT IS AUTOMATICALLY GENERATED " + + "SO IN GENERAL YOU SHOULD NOT EDIT it!!\n\n" + ) # Make sure tasks_per_node doesn't exceed the number of cpus per node if tasks_per_node > ncpus: @@ -211,7 +230,7 @@ def write_runscript_part2(namelist_file, runfile, executable, mksurfdata_path, e "compilers and libraries external to cime such as netcdf" ) runfile.write(f"\n. {env_mach_path}\n") - check = 'if [ $? != 0 ]; then echo "Error running env_mach_specific"; exit -4; fi' + check = 'if [ $? != 0 ]; then echo "Error running env_mach_specific script"; exit -4; fi' runfile.write(f"{check} \n") runfile.write( "# Edit the mpirun command to use the MPI executable " @@ -242,6 +261,7 @@ def main(): tasks_per_node = args.tasks_per_node machine = args.machine account = args.account + walltime = args.walltime # -------------------------- # Write to file @@ -250,7 +270,9 @@ def main(): # -------------------------- # Write batch header (part 1) # -------------------------- - attribs = write_runscript_part1(number_of_nodes, tasks_per_node, machine, account, runfile) + attribs = write_runscript_part1( + number_of_nodes, tasks_per_node, machine, account, walltime, runfile + ) # -------------------------- # Obtain mpirun command from env_mach_specific.xml # -------------------------- From 76f38c23604fda75944b134c130dcbbfb018852a Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 27 Mar 2024 20:40:32 -0600 Subject: [PATCH 546/614] For the test to work with the latest externals, it needs to ask for a full node of processors --- cime_config/testdefs/testlist_clm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index c9b5c572dc..3d4dcb4904 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -3422,7 +3422,7 @@ - + From 51c4da197ee0bd056d7c8e8ea0fa4f0c0c2ec5c1 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 27 Mar 2024 22:42:08 -0600 Subject: [PATCH 547/614] Couple more features from multi over to single Add a couple features from multi over to single, so that multi can use the same code. --- .../ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py | 2 +- python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py index 73b45578bb..f09d91ccce 100755 --- a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py @@ -168,7 +168,7 @@ def test_derecho_mpirun(self): ) self.assertEqual(attribs, expected_attribs) (executable, mksurfdata_path, env_mach_path) = get_mpirun(args, attribs) - expected_exe = "mpibind " + expected_exe = "time mpibind " self.assertEqual(executable, expected_exe) self.assertEqual(mksurfdata_path, self._mksurf_exe) self.assertEqual(env_mach_path, self._env_mach) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index f6c4d60219..b69b6f08c1 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -126,9 +126,8 @@ def check_parser_args(args): + ") does NOT exist in the bld-path, aborting" ) - def write_runscript_part1( - number_of_nodes, tasks_per_node, machine, account, walltime, runfile, descrip="input namelist" + number_of_nodes, tasks_per_node, machine, account, walltime, runfile, descrip="input namelist", name="mksurfdata" ): """ Write run script (part 1) Batch headers @@ -136,7 +135,7 @@ def write_runscript_part1( runfile.write("#!/bin/bash\n") runfile.write("# Edit the batch directives for your batch system\n") runfile.write(f"# Below are default batch directives for {machine}\n") - runfile.write("#PBS -N mksurfdata\n") + runfile.write(f"#PBS -N {name}\n") runfile.write("#PBS -j oe\n") runfile.write("#PBS -k eod\n") @@ -212,7 +211,7 @@ def get_mpirun(args, attribs): # cmd[1] contains a list of strings that we append as options to cmd[0] # The replace function removes unnecessary characters that appear in # some such options - executable = f'{cmd[0]} {" ".join(cmd[1])}'.replace("ENV{", "").replace("}", "") + executable = f'time {cmd[0]} {" ".join(cmd[1])}'.replace("ENV{", "").replace("}", "") mksurfdata_path = os.path.join(bld_path, "mksurfdata") env_mach_path = os.path.join(bld_path, ".env_mach_specific.sh") From e662d8ec50cb50878ae701b3ae2ba00d45992e38 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 28 Mar 2024 00:27:18 -0600 Subject: [PATCH 548/614] Fix parser for update --- .../gen_mksurfdata_jobscript_single.py | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index b69b6f08c1..4a7966c60a 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -19,9 +19,9 @@ logger = logging.getLogger(__name__) -def get_parser(): +def base_get_parser(): """ - Get parser object for this script. + Get parser object for the gen_mksurfdata_jobscript scripts """ # set up logging allowing user control setup_logging_pre_config() @@ -76,13 +76,6 @@ def get_parser(): choices=["derecho", "casper", "izumi"], default="derecho", ) - parser.add_argument( - "--namelist-file", - help="""input namelist file (required)""", - action="store", - dest="namelist_file", - required=True, - ) parser.add_argument( "--jobscript-file", help="""output jobscript file to be submitted with qsub (default: %(default)s)""", @@ -99,8 +92,22 @@ def get_parser(): required=False, default="12:00:00", ) + return parser +def get_parser(): + """ + Get parser object for this script. + """ + parser = base_get_parser() + parser.add_argument( + "--namelist-file", + help="""input namelist file (required)""", + action="store", + dest="namelist_file", + required=True, + ) + return( parser ) def check_parser_args(args): """Checking for the argument parser values""" @@ -251,6 +258,7 @@ def main(): # -------------------------- # Obtain input args # -------------------------- + logging.setup_logging_pre_config() args = get_parser().parse_args() process_logging_args(args) check_parser_args(args) From d37213a3398dbf3e1f453829f49ebd4952521783 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 28 Mar 2024 01:00:14 -0600 Subject: [PATCH 549/614] Have the multi script use a good portion of the single script to enable not having to test both, which allows the SystemTest to be valid for just using the single script --- .../gen_mksurfdata_jobscript_multi.py | 158 ++++-------------- .../gen_mksurfdata_jobscript_single.py | 15 +- 2 files changed, 49 insertions(+), 124 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index 6e8d6ee3a7..a6990d80bd 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -5,11 +5,18 @@ """ import os import sys -import argparse +import logging -from ctsm.path_utils import path_to_ctsm_root -from ctsm.toolchain.gen_mksurfdata_namelist import main as main_nml from ctsm.utils import abort +from ctsm.toolchain.gen_mksurfdata_namelist import main as main_nml +from ctsm.ctsm_logging import process_logging_args +from ctsm.toolchain.gen_mksurfdata_jobscript_single import base_get_parser +from ctsm.toolchain.gen_mksurfdata_jobscript_single import check_parser_args +from ctsm.toolchain.gen_mksurfdata_jobscript_single import write_runscript_part1 +from ctsm.toolchain.gen_mksurfdata_jobscript_single import get_mpirun + + +logger = logging.getLogger(__name__) valid_scenarios = [ "global-potveg", @@ -59,64 +66,8 @@ def get_parser(): """ Get parser object for this script. """ - parser = argparse.ArgumentParser( - description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter - ) - - parser.print_usage = parser.print_help + parser = base_get_parser() - parser.add_argument( - "-v", - "--verbose", - help="ncrease output verbosity", - action="store_true", - ) - parser.add_argument( - "--account", - help="""account number (default P93300606)""", - action="store", - dest="account", - required=False, - default="P93300641", - ) - parser.add_argument( - "--bld-path", - help="""Path to build directory for mksurfdata_esmf""", - action="store", - dest="bld_path", - default=os.path.join(path_to_ctsm_root(), "tools", "mksurfdata_esmf", "tool_bld"), - ) - parser.add_argument( - "--number-of-nodes", - help="""number of derecho nodes requested (required)""", - action="store", - dest="number_of_nodes", - required=True, - ) - parser.add_argument( - "--tasks-per-node", - help="""number of mpi tasks per node for derecho requested""", - action="store", - dest="tasks_per_node", - required=False, - default="128", - ) - parser.add_argument( - "--walltime", - help="""Wallclock time for job submission default is 12:00:00)""", - action="store", - dest="walltime", - required=False, - default="12:00:00", - ) - parser.add_argument( - "--queue", - help="""Queue to submit to)""", - action="store", - dest="queue", - required=False, - default="main", - ) parser.add_argument( "--scenario", help="""scenario""", @@ -125,61 +76,50 @@ def get_parser(): dest="scenario", required=True, ) - parser.add_argument( - "--jobscript-file", - help="""output jobscript file to be submitted with qsub - [default: %(default)s]""", - action="store", - dest="jobscript_file", - required=False, - default="mksurfdata_jobscript_multi.sh", - ) + return parser def write_runscript( + args, scenario, jobscript_file, number_of_nodes, tasks_per_node, account, walltime, - queue, + machine, target_list, resolution_dict, dataset_dict, - env_specific_script, - mksurfdata, runfile, ): """ Write run script """ - runfile.write("#!/bin/bash \n") - runfile.write(f"#PBS -A {account} \n") - runfile.write(f"#PBS -N mksrf_{scenario} \n") - runfile.write("#PBS -j oe \n") - runfile.write("#PBS -k eod \n") - runfile.write("#PBS -S /bin/bash \n") - runfile.write(f"#PBS -q {queue} \n") - runfile.write(f"#PBS -l walltime={walltime} \n") - runfile.write( - "#PBS -l select=" - + f"{number_of_nodes}:ncpus={tasks_per_node}:mpiprocs={tasks_per_node}:mem=218GB \n" - ) - runfile.write( - f"# This is a batch script to run a set of resolutions for mksurfdata_esmf {scenario}\n" - ) - runfile.write( - "# NOTE: THIS SCRIPT IS AUTOMATICALLY GENERATED " - + "SO IN GENERAL YOU SHOULD NOT EDIT it!!\n\n" + # -------------------------- + # Write batch header (part 1) + # -------------------------- + name = f"mksrf_{scenario}" + attribs = write_runscript_part1( + number_of_nodes, + tasks_per_node, + machine, + account, + walltime, + runfile, + descrip=scenario, + name=name, ) - runfile.write("\n") + # -------------------------- + # Obtain mpirun command from env_mach_specific.xml + # -------------------------- + (executable, mksurfdata_path, env_mach_path) = get_mpirun(args, attribs) # Run env_mach_specific.sh to control the machine dependent # environment including the paths to compilers and libraries # external to cime such as netcdf - runfile.write(". " + env_specific_script + "\n") + runfile.write(". " + env_mach_path + "\n") check = "if [ $? != 0 ]; then echo 'Error running env_specific_script'; exit -4; fi" runfile.write(f"{check} \n") for target in target_list: @@ -196,7 +136,7 @@ def write_runscript( sys.argv = [x for x in command.split(" ") if x] main_nml() print(f"generated namelist {namelist}") - output = f"time mpiexec {mksurfdata} < {namelist}" + output = f"{executable} {mksurfdata_path} < {namelist}" runfile.write(f"{output} \n") check = f"if [ $? != 0 ]; then echo 'Error running resolution {res}'; exit -4; fi" runfile.write(f"{check} \n") @@ -213,13 +153,14 @@ def main(): # Obtain input args # -------------------------- args = get_parser().parse_args() + process_logging_args(args) + check_parser_args(args) scenario = args.scenario jobscript_file = args.jobscript_file number_of_nodes = args.number_of_nodes tasks_per_node = args.tasks_per_node account = args.account walltime = args.walltime - queue = args.queue # -------------------------- # Determine target list @@ -434,48 +375,23 @@ def main(): ), } - # -------------------------- - # TODO Here, reuse code from gen_mksurfdata_jobscript_single - # that's found in the section titled "Obtain mpirun command ..." - # -------------------------- - - # -------------------------- - # Make sure files exist or exit - # -------------------------- - if not os.path.exists(args.bld_path): - print( - args.bld_path - + " directory does NOT exist -- build mksurdata_esmf before running this script --" - + " using ./gen_mksurfdata_build.sh" - ) - sys.exit(1) - - env_specific_script = os.path.join(args.bld_path, ".env_mach_specific.sh") - if not os.path.exists(env_specific_script): - print(env_specific_script + " does NOT exist") - sys.exit(1) - mksurfdata = os.path.join(args.bld_path, "mksurfdata") - if not os.path.exists(mksurfdata): - print(mksurfdata + " does NOT exist") - sys.exit(1) # -------------------------- # Write run script # -------------------------- with open(jobscript_file, "w", encoding="utf-8") as runfile: write_runscript( + args, scenario, jobscript_file, number_of_nodes, tasks_per_node, account, walltime, - queue, + args.machine, target_list, resolution_dict, dataset_dict, - env_specific_script, - mksurfdata, runfile, ) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index 4a7966c60a..e3cd2f931e 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -95,6 +95,7 @@ def base_get_parser(): return parser + def get_parser(): """ Get parser object for this script. @@ -107,7 +108,8 @@ def get_parser(): dest="namelist_file", required=True, ) - return( parser ) + return parser + def check_parser_args(args): """Checking for the argument parser values""" @@ -133,8 +135,16 @@ def check_parser_args(args): + ") does NOT exist in the bld-path, aborting" ) + def write_runscript_part1( - number_of_nodes, tasks_per_node, machine, account, walltime, runfile, descrip="input namelist", name="mksurfdata" + number_of_nodes, + tasks_per_node, + machine, + account, + walltime, + runfile, + descrip="input namelist", + name="mksurfdata", ): """ Write run script (part 1) Batch headers @@ -258,7 +268,6 @@ def main(): # -------------------------- # Obtain input args # -------------------------- - logging.setup_logging_pre_config() args = get_parser().parse_args() process_logging_args(args) check_parser_args(args) From 91d880af4c7ee2fe4f83f0c7e3fcf0c4ceb87cea Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 28 Mar 2024 01:49:09 -0600 Subject: [PATCH 550/614] Make tasks-per-node not required as multi script was setup, and allow default jobscript name to change --- python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 2 +- python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index a6990d80bd..d0ad313867 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -66,7 +66,7 @@ def get_parser(): """ Get parser object for this script. """ - parser = base_get_parser() + parser = base_get_parser(default_js_name="mksurfdata_jobscript_multi") parser.add_argument( "--scenario", diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index e3cd2f931e..a04265ba84 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -7,6 +7,7 @@ import argparse import logging + from ctsm import add_cime_to_path # pylint: disable=unused-import from ctsm.ctsm_logging import setup_logging_pre_config, add_logging_args, process_logging_args from ctsm.utils import abort @@ -19,7 +20,7 @@ logger = logging.getLogger(__name__) -def base_get_parser(): +def base_get_parser(default_js_name="mksurfdata_jobscript_single"): """ Get parser object for the gen_mksurfdata_jobscript scripts """ @@ -62,7 +63,8 @@ def base_get_parser(): action="store", dest="tasks_per_node", type=int, - required=True, + required=False, + default="128", ) parser.add_argument( "--machine", @@ -82,7 +84,7 @@ def base_get_parser(): action="store", dest="jobscript_file", required=False, - default="mksurfdata_jobscript_single", + default=default_js_name, ) parser.add_argument( "--walltime", From bd4977b152b0357e5550a2143df8a6162403c18f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 29 Mar 2024 11:26:24 -0600 Subject: [PATCH 551/614] Get working, needed to remove the real_parameter things added in new tests for ctsm5.2, that were removed in the update --- bld/unit_testers/build-namelist_test.pl | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 09b0b35aae..4296bd492a 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,10 +163,10 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 2137; +my $ntests = 1990; if ( defined($opts{'compare'}) ) { - $ntests += 1371; + $ntests += 1201; } plan( tests=>$ntests ); @@ -1351,7 +1351,6 @@ sub cat_and_create_namelistinfile { $cfiles->shownmldiff( "default", "standard" ); if ( defined($opts{'compare'}) ) { $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode ); - $cfiles->dodiffonfile( "$real_par_file", "$options", $mode ); $cfiles->comparefiles( "$options", $mode, $opts{'compare'} ); } @@ -1436,7 +1435,6 @@ sub cat_and_create_namelistinfile { $cfiles->shownmldiff( "default", "standard" ); if ( defined($opts{'compare'}) ) { $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode ); - $cfiles->dodiffonfile( "$real_par_file", "$options", $mode ); $cfiles->comparefiles( "$options", $mode, $opts{'compare'} ); } if ( defined($opts{'generate'}) ) { @@ -1573,7 +1571,6 @@ sub cat_and_create_namelistinfile { $cfiles->shownmldiff( "default", "standard" ); if ( defined($opts{'compare'}) ) { $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode ); - $cfiles->dodiffonfile( "$real_par_file", "$options", $mode ); $cfiles->comparefiles( "$options", $mode, $opts{'compare'} ); } if ( defined($opts{'generate'}) ) { From 3d3606045228beeb0d084ad679d452e95d506b24 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 29 Mar 2024 14:22:35 -0600 Subject: [PATCH 552/614] Fix test numbers and remove real files added as they were removed on master --- bld/unit_testers/build-namelist_test.pl | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index acac8db5e4..b57f917ea4 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,10 +163,10 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 2755; +my $ntests = 2455; if ( defined($opts{'compare'}) ) { - $ntests += 1842; + $ntests += 1511; } plan( tests=>$ntests ); @@ -1351,7 +1351,6 @@ sub cat_and_create_namelistinfile { $cfiles->shownmldiff( "default", "standard" ); if ( defined($opts{'compare'}) ) { $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode ); - $cfiles->dodiffonfile( "$real_par_file", "$options", $mode ); $cfiles->comparefiles( "$options", $mode, $opts{'compare'} ); } @@ -1436,7 +1435,6 @@ sub cat_and_create_namelistinfile { $cfiles->shownmldiff( "default", "standard" ); if ( defined($opts{'compare'}) ) { $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode ); - $cfiles->dodiffonfile( "$real_par_file", "$options", $mode ); $cfiles->comparefiles( "$options", $mode, $opts{'compare'} ); } if ( defined($opts{'generate'}) ) { @@ -1573,7 +1571,6 @@ sub cat_and_create_namelistinfile { $cfiles->shownmldiff( "default", "standard" ); if ( defined($opts{'compare'}) ) { $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode ); - $cfiles->dodiffonfile( "$real_par_file", "$options", $mode ); $cfiles->comparefiles( "$options", $mode, $opts{'compare'} ); } if ( defined($opts{'generate'}) ) { From fb54519c1a3dbc7c9e9ee39738e33c90fffdd32d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 1 Apr 2024 17:05:10 -0600 Subject: [PATCH 553/614] Fix test number --- bld/unit_testers/build-namelist_test.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 65c3fe5bc4..b57f917ea4 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -166,7 +166,7 @@ sub cat_and_create_namelistinfile { my $ntests = 2455; if ( defined($opts{'compare'}) ) { - $ntests += 1341; + $ntests += 1511; } plan( tests=>$ntests ); From 5be997d58e8d687416c040ae03462657276d5796 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 1 Apr 2024 17:05:46 -0600 Subject: [PATCH 554/614] Simplify clm_start_type as done elsewhere --- .../namelist_defaults_overall.xml | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_overall.xml b/bld/namelist_files/namelist_defaults_overall.xml index 96db00478a..ffe5dbd515 100644 --- a/bld/namelist_files/namelist_defaults_overall.xml +++ b/bld/namelist_files/namelist_defaults_overall.xml @@ -22,23 +22,12 @@ determine default values for namelists. --> -arb_ic -arb_ic -arb_ic -arb_ic -arb_ic -arb_ic -startup -startup -startup -startup -startup -startup -arb_ic -arb_ic -arb_ic -arb_ic +arb_ic cold +cold +cold +startup +startup arb_ic From b55ef252837e4d14314a9b56ae1338f547b4f695 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 1 Apr 2024 17:38:25 -0600 Subject: [PATCH 555/614] Update documentation to refer to derecho rather than cheyenne --- tools/README | 4 ++-- tools/mksurfdata_esmf/Makefile | 2 +- tools/mksurfdata_esmf/README | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/README b/tools/README index 9c4ad64ba1..b0dcba8836 100644 --- a/tools/README +++ b/tools/README @@ -196,12 +196,12 @@ III. Process sequence to create input datasets needed to run CTSM file for CTSM. Output domain files will be named according to the input OCN/LND gridnames. - 5.) Create surface datasets with mksurfdata_esmf on cheyenne + 5.) Create surface datasets with mksurfdata_esmf on Derecho (See mksurfdata_esmf/README for more help on doing this) - gen_mksurfdata_build.sh to build - gen_mksurfdata_namelist to build the namelist - - gen_mksurfdata_jobscript_single to build a batch script to run on cheyenne + - gen_mksurfdata_jobscript_single to build a batch script to run on Derecho - Submit the batch script just created above - This step uses the results of step (3) entered into the XML database diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile index a0d5fa5445..fc81d48079 100644 --- a/tools/mksurfdata_esmf/Makefile +++ b/tools/mksurfdata_esmf/Makefile @@ -15,7 +15,7 @@ # make crop-numa # # NOTE: The default behavior is to parallelize data set creation using -# the batch system by submitting jobs to the batch queue (on cheyenne). +# the batch system by submitting jobs to the batch queue (on Derecho). # # In all cases where "--scenario $@" appears, the code executes the # recipe for the specific target/scenario that it finds in diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 7aa5c92588..1f7fa65270 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -64,7 +64,7 @@ Building the executable (working in tools/mksurfdata_esmf) > ./gen_mksurfdata_build.sh # For machines with a cime build # Note: The pio_iotype value gets set and written to a simple .txt file # by this build script. The value depends on your machine. If not running -# on cheyenne, casper, izumi, or hobart, you may need to update this, though +# on derecho, casper, or izumi, you may need to update this, though # a default value does get set for other machines. ======================= From d5dc4e8beb196f6b19255a0377281b53a4eabcdb Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 1 Apr 2024 17:40:29 -0600 Subject: [PATCH 556/614] Remove mention of mkmapdata files --- .gitignore | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.gitignore b/.gitignore index 195441facf..5885db2237 100644 --- a/.gitignore +++ b/.gitignore @@ -105,13 +105,6 @@ unit_test_build # Tools executables /tools/mkprocdata_map/mkprocdata_map -# mkmapdata output files -/tools/mkmapdata/PET*.RegridWeightGen.Log -/tools/mkmapdata/regrid.*.out -/tools/mkmapdata/regrid.*.err -/tools/mkmapdata/regrid.o* -/tools/mkmapdata/map*.nc - # run_neon output directories /tools/site_and_regional/listing.csv /tools/site_and_regional/????/ From 8a9132a6d27793170c71598747e59a6029899494 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 1 Apr 2024 17:43:40 -0600 Subject: [PATCH 557/614] Remove more mentions of mkmapdata --- tools/README | 1 - tools/mkprocdata_map/README | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/README b/tools/README index b0dcba8836..78a2cccb09 100644 --- a/tools/README +++ b/tools/README @@ -11,7 +11,6 @@ I. General directory structure: crop_calendars --- Regrid and process GGCMI sowing and harvest date files for use in CTSM. mkmapgrids ------- Create regular lat/lon SCRIP grid files - mkmapgrids ------- Create regular lat/lon SCRIP grid files needed by mkmapdata mkprocdata_map --- Convert output unstructured grids into a 2D format that can be plotted easily diff --git a/tools/mkprocdata_map/README b/tools/mkprocdata_map/README index f5ac71b1ff..92ffb4856c 100644 --- a/tools/mkprocdata_map/README +++ b/tools/mkprocdata_map/README @@ -47,8 +47,7 @@ the output. However, you may want to wrap this in a job script to run it on multiple processors (using mpirun), and you may have to set other - machine-specific environment variables. You can follow the method - used in tools/mkmapdata/mkmapdata.sh. + machine-specific environment variables. (4) Build the mkprocdata_map tool. From the current directory, do the following: From dffdb3e0edf7a4587a2968d7f682073a8e31ac9a Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 1 Apr 2024 17:49:55 -0600 Subject: [PATCH 558/614] Remove ctsm_case which isn't being used anymore. I checked and I beleive the error checking in it was moved to the new gen_mksurfdata_* scripts --- python/ctsm/toolchain/ctsm_case.py | 427 ----------------------------- 1 file changed, 427 deletions(-) delete mode 100755 python/ctsm/toolchain/ctsm_case.py diff --git a/python/ctsm/toolchain/ctsm_case.py b/python/ctsm/toolchain/ctsm_case.py deleted file mode 100755 index 333af0833a..0000000000 --- a/python/ctsm/toolchain/ctsm_case.py +++ /dev/null @@ -1,427 +0,0 @@ -# 2020-11-08 Negin Sobhani -""" -This module includes the definition for CtsmCase class for the purpose of gen_mksurf_namelist. -""" - -# -- Import libraries -# -- Import Python Standard Libraries - -import os -import re -import sys -import logging - -from datetime import datetime - -from ctsm.git_utils import get_ctsm_git_describe - -# -- import local classes for this script -logger = logging.getLogger(__name__) - - -class CtsmCase: - """ - A class to encapsulate different ctsm cases. - - ... - - Attributes - --------- - res : str - resolution from a list of acceptable options. - glc_nec : str - number of glacier elevation classes. - ssp_rcp : str - Shared Socioeconomic Pathway and Representative - Concentration Pathway Scenario name. - crop_flag : bool - Crop flag for determining number of pfts - input_path : str - Raw data input path - vic_flag : bool - Flag for VIC model - glc_flag : bool - Flag for 3D glacier model - start_year : str - Simulation start year - end_year : str - Simulation end year - - Methods - ------- - check_endyear: - Check if end_year is bigger than start year - in a ctsm case. - check_run_type: - Determine if a ctsm case is transient or - time-slice. - check_num_pft: - Determine num_pft based on crop_flag for a - ctsm case. - build_landuse_filename: - Build the land-use filename for a transient - case. - create_landuse_file: - Create land-use txt file for a transient case. - build_namelist_filename - Build the name of the namelist/control file - for a ctsm case. - create_namelist_file: - Build the namelist/control file for a ctsm - case. - """ - - # pylint: disable=too-many-instance-attributes - - def __init__( - self, - res, - glc_nec, - ssp_rcp, - crop_flag, - input_path, - vic_flag, - glc_flag, - start_year, - end_year, - hres_flag, - ): - self.res = res - self.glc_nec = glc_nec - self.ssp_rcp = ssp_rcp - self.crop_flag = crop_flag - self.input_path = input_path - self.vic_flag = vic_flag - self.glc_flag = glc_flag - self.start_year = start_year - self.end_year = end_year - self.hres_flag = hres_flag - self.lu_fname = None - self.namelist_fname = None - self.ssp_val = None - self.rcp_val = None - - # -- check if end year value is a valid value - self.check_endyear() - - # -- Determine if the case is transient - self.check_run_type() - - # -- determine the num_pft - self.check_num_pft() - - def __str__(self): - return ( - str(self.__class__) - + "\n" - + "\n".join((str(key) + " = " + str(value) for key, value in self.__dict__.items())) - ) - - def check_endyear(self): - """ - check if end_year is valid. - - Raises: - Error is end_year is smaller than start_year - """ - if self.end_year < self.start_year: - sys.exit( - "ERROR: end_year should be bigger than the start_year : " - + self.start_year.__str__() - + "." - ) - - def check_run_type(self): - """ - Determine if a ctsm case is transient or - time-slice. - """ - if self.end_year > self.start_year: - self.run_type = "transient" - else: - self.run_type = "timeslice" - logger.debug(" run_type = %s", self.run_type) - - def check_num_pft(self): - """ - determine the num_pft - """ - if self.crop_flag: - self.num_pft = "78" - else: - self.num_pft = "16" - logger.debug(" crop_flag = %s => num_pft = %i", self.crop_flag.__str__(), self.num_pft) - - def build_landuse_filename(self): - """ - Build the land-use filename for a transient - case. - """ - if self.run_type == "transient": - lu_fname = ( - "landuse_timeseries_hist_" - + self.num_pft.__str__() - + "pfts_simyr" - + self.start_year.__str__() - + "-" - + self.end_year.__str__() - + ".txt" - ) - else: - lu_fname = "" - self.lu_fname = lu_fname - - def create_landuse_file(self): - """ - Create land-use txt file for a transient case. - """ - self.build_landuse_filename() - with open(self.lu_fname, "w", encoding="utf-8") as lu_file: - - for year in range(self.start_year, self.end_year + 1): - - # -- choose different files for years of 850-1850: - if 849 < year < 1850: - lu_input_fname = os.path.join( - self.input_path, - "pftcftdynharv.0.25x0.25.LUH2.histsimyr0850-1849.c171012", - "mksrf_landuse_histclm50_LUH2_" + str(year) + ".c171012.nc", - ) - elif 1849 < year < 2016: - lu_input_fname = os.path.join( - self.input_path, - "pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412", - "mksrf_landuse_histclm50_LUH2_" + str(year) + ".c170412.nc", - ) - elif 2015 < year < 2106: - self.decode_ssp_rcp() - lu_input_fname = os.path.join( - self.input_path, - "pftcftdynharv.0.25x0.25." + self.ssp_rcp + ".simyr2016-2100.c181217", - "mksrf_landuse_SSP" - + self.ssp_val - + "RCP" - + self.rcp_val - + "_clm5_" - + str(year) - + ".c181217.nc", - ) - else: - logger.warning("year: %i not valid.", year) - - # -- Check if the land-use input file exist: - if not os.path.isfile(lu_input_fname): - logger.debug("lu_input_fname: %s", lu_input_fname) - logger.warning("land-use input file does not exist for year: %i.", year) - - # TODO: make the space/tab exactly the same as pl code: - lu_line = lu_input_fname + "\t\t\t" + str(year) + "\n" - - # -- Each line is written twice in the original pl code: - lu_file.write(lu_line) - lu_file.write(lu_line) - - logger.debug("year : %s", year) - logger.debug(lu_line) - - print("Successfully created land use file : ", self.lu_fname, ".") - print("-------------------------------------------------------") - - def build_namelist_filename(self): - """ - Build namelist file name. - """ - time_stamp = datetime.today().strftime("%y%m%d") - namelist_fname = ( - "surfdata_" - + self.res - + "_" - + self.ssp_rcp - + "_" - + self.num_pft - + "pfts_CMIP6_" - + self.start_year.__str__() - + "-" - + self.end_year.__str__() - + "_c" - + time_stamp - + ".namelist" - ) - - self.namelist_fname = namelist_fname - - def create_namelist_file(self): - """ - Build the namelist/control file for a ctsm case. - """ - - self.build_landuse_filename() - if self.run_type == "transient": - self.create_landuse_file() - - self.build_namelist_filename() - with open(self.namelist_fname, "w", encoding="utf-8") as namelist_file: - - label = get_ctsm_git_describe() - - dst_mesh = which_mesh(self.res) - - logger.debug("dst mesh is : %s", dst_mesh) - - if self.run_type == "transient": - use_transient = ".true." - else: - use_transient = ".false" - - # pylint: disable=line-too-long - - nl_template = ( - "&clmexp\n" - "nglcec = " + self.glc_nec + "\n" - "mksrf_fsoitex = " + self.input_path + "mksrf_soitex.10level.c201018.nc" + "\n" - "mksrf_forganic = " - + self.input_path - + "mksrf_organic_10level_5x5min_ISRIC-WISE-NCSCD_nlev7_c120830.nc" - + "\n" - "mksrf_flakwat = " - + self.input_path - + "mksrf_LakePnDepth_3x3min_simyr2004_csplk_c151015.nc" - + "\n" - "mksrf_fwetlnd = " + self.input_path + "mksrf_lanwat.050425.nc" + "\n" - "mksrf_fmax = " + self.input_path + "mksrf_fmax_3x3min_USGS_c120911.nc" + "\n" - "mksrf_fglacier = " - + self.input_path - + "mksrf_glacier_3x3min_simyr2000.c120926.nc" - + "\n" - "mksrf_fvocef = " - + self.input_path - + "mksrf_vocef_0.5x0.5_simyr2000.c110531.nc" - + "\n" - "mksrf_furbtopo = " + self.input_path + "mksrf_topo.10min.c080912.nc" + "\n" - "mksrf_fgdp = " - + self.input_path - + "mksrf_gdp_0.5x0.5_AVHRR_simyr2000.c130228.nc" - + "\n" - "mksrf_fpeat = " - + self.input_path - + "mksrf_peatf_0.5x0.5_AVHRR_simyr2000.c130228.nc" - + "\n" - "mksrf_fsoildepth = " - + self.input_path - + "mksf_soilthk_5x5min_ORNL-Soil_simyr1900-2015_c170630.nc" - + "\n" - "mksrf_fabm = " - + self.input_path - + "mksrf_abm_0.5x0.5_AVHRR_simyr2000.c130201.nc" - + "\n" - "outnc_double = .true. \n" - "all_urban = .false.\n" - "no_inlandwet = .true. \n" - "mksrf_furban = " - + self.input_path - + "mksrf_urban_0.05x0.05_simyr2000.c170724.nc" - + "\n" - "gitdescribe = " + label + "\n" - "mksrf_ftopostats = " - + self.input_path - + "mksrf_topostats_1km-merge-10min_HYDRO1K-merge-nomask_simyr2000.c130402.nc" - + "\n" - "mksrf_fvegtyp = " - + self.input_path - + "pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629/mksrf_landuse_histclm50_LUH2_1850.c170629.nc" - + "\n" - "mksrf_fsoicol = " - + self.input_path - + "pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_soilcolor_CMIP6_simyr2005.c170623.nc" - + "\n" - "mksrf_flai = " - + self.input_path - + "pftcftlandusedynharv.0.25x0.25.MODIS.simyr1850-2015.c170412/mksrf_lai_78pfts_simyr2005.c170413.nc" - + "\n" - "fdyndat = ''\n" - "numpft = " + self.num_pft + "\n" - "dst_mesh_file = " + self.input_path + dst_mesh + "\n" - "\n&transient\n" - "use_transient = " + use_transient + "\n" - "start_year = " + self.start_year.__str__() + "\n" - "end_year = " + self.end_year.__str__() + "\n" - "mksrf_dyn_lu = " - + self.input_path - + "pftcftdynharv.0.25x0.25.LUH2.histsimyr1850-2015.c170629" - + "\n" - "mksrf_fdynuse = " + self.lu_fname + "\n" - "\n&vic\n" - "use_vic = " + self.vic_flag.__str__() + "\n" - "mksrf_fvic = " - + self.input_path - + "mksrf_vic_0.9x1.25_GRDC_simyr2000.c130307.nc\n" - "outnc_vic = \n" - "\n&glc\n" - "use_glc = " + self.glc_flag.__str__() + "\n" - "outnc_3dglc = \n" - "/\n" - ) - # pylint: enable=line-too-long - - namelist_file.write(nl_template) - - print("Successfully created namelist file : ", self.namelist_fname, ".") - print("--------------------------------------------------------") - - def decode_ssp_rcp(self): - """ - Decode ssp_rcp strings because - the raw filenames and folder names - are not consistent. - - For example: - folder names have ssp_rcp as SSP1-2.6 - - but the files in these folders have - ssp_rcp as SSP1RCP26 - """ - - if self.ssp_rcp != "hist": - temp = re.sub("[^0-9]", "", self.ssp_rcp) - self.ssp_val = temp[0] - self.rcp_val = temp[1:] - else: - sys.exit( - "ERROR: \n" - + "\t Please choose a ssp_rcp scenario for years beyond 2015 using --ssp_rcp flag." - ) - - -def which_mesh(res): - """ - Figure out the dst mesh file for each res - """ - switcher = { - "512x1024": "lnd/clm2/mappingdata/grids/SCRIPgrid_512x1024_nomask_c110308.nc", - "128x256": "lnd/clm2/mappingdata/grids/SCRIPgrid_128x256_nomask_c110308.nc", - "94x192": "lnd/clm2/mappingdata/grids/SCRIPgrid_94x192_nomask_c110308.nc", - "64x128": "lnd/clm2/mappingdata/grids/SCRIPgrid_64x128_nomask_c110308.nc", - "48x96": "lnd/clm2/mappingdata/grids/SCRIPgrid_48x96_nomask_c110308.nc", - "32x64": "lnd/clm2/mappingdata/grids/SCRIPgrid_32x64_nomask_c110308.nc", - "8x16": "lnd/clm2/mappingdata/grids/SCRIPgrid_8x16_nomask_c110308.nc", - "0.23x0.31": "lnd/clm2/mappingdata/grids/SCRIPgrid_0.23x0.31_nomask_c110308.nc", - "0.47x0.63": "lnd/clm2/mappingdata/grids/SCRIPgrid_0.47x0.63_nomask_c170914.nc", - "0.9x1.25": "lnd/clm2/mappingdata/grids/0.9x1.25_c110307.nc", - "1.9x2.5": "lnd/clm2/mappingdata/grids/1.9x2.5_c110308.nc", - "2.5x3.33": "lnd/clm2/mappingdata/grids/SCRIPgrid_2.5x3.33_nomask_c110308.nc", - "4x5": "lnd/clm2/mappingdata/grids/SCRIPgrid_4x5_nomask_c110308.nc", - "10x15": "lnd/clm2/mappingdata/grids/SCRIPgrid_10x15_nomask_c110308.nc", - "C384": "atm/cam/coords/C384_SCRIP_desc.181018.nc", - "C192": "atm/cam/coords/C192_SCRIP_desc.181018.nc", - "C96": "atm/cam/coords/C96_SCRIP_desc.181018.nc", - "C48": "atm/cam/coords/C48_SCRIP_desc.181018.nc", - "C24": "atm/cam/coords/C24_SCRIP_desc.181018.nc", - "ne240np4": "lnd/clm2/mappingdata/grids/SCRIPgrid_ne240np4_nomask_c091227.nc", - "ne120np4": "lnd/clm2/mappingdata/grids/SCRIPgrid_ne120np4_nomask_c101123.nc", - "ne60np4": "lnd/clm2/mappingdata/grids/SCRIPgrid_ne60np4_nomask_c100408.nc", - "ne30np4": "lnd/clm2/mappingdata/grids/SCRIPgrid_ne30np4_nomask_c101123.nc", - "ne16np4": "lnd/clm2/mappingdata/grids/SCRIPgrid_ne16np4_nomask_c110512.nc", - "360x720cru": "lnd/clm2/mappingdata/grids/SCRIPgrid_360x720_nomask_c120830.nc", - } - - return switcher.get(res, "nothing") From 4dddeece1e37680e9133794ffeb7c769e9c47bf0 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 1 Apr 2024 17:52:19 -0600 Subject: [PATCH 559/614] Remove scrip grid namelist items needed for mkmapdata --- .../namelist_definition_ctsm.xml | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index aceb89f7aa..cfa06dd6f3 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -1374,35 +1374,6 @@ Toggle to turn on the dynamic root model Toggle to turn on on diagnostic Snow Radiative Effect - - - - - -SCRIP format grid data file - - - -Flag to pass to the ESMF mapping utility, telling it what kind of large -file support is needed for an output file generated with this grid as -either the source or destination ('none', '64bit_offset' or 'netcdf4'). - - - -Flag to pass to the ESMF mapping utility, telling it what kind of grid -file this is (SCRIP or UGRID). - - - -For UGRID files, flag to pass to the ESMF mapping utility, telling it the -name of the dummy variable that has all of the topology information stored -in its attributes. (Only used if scripgriddata_src_type = UGRID.) - - From 2033097be065200b5784998cefd7c32225f2baf5 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 1 Apr 2024 17:59:39 -0600 Subject: [PATCH 560/614] Remove this file as the site_and_regional one is being used --- tools/mksurfdata_esmf/default_data_1850.cfg | 27 --------------------- 1 file changed, 27 deletions(-) delete mode 100644 tools/mksurfdata_esmf/default_data_1850.cfg diff --git a/tools/mksurfdata_esmf/default_data_1850.cfg b/tools/mksurfdata_esmf/default_data_1850.cfg deleted file mode 100644 index e05c937b86..0000000000 --- a/tools/mksurfdata_esmf/default_data_1850.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[main] -clmforcingindir = /glade/p/cesmdata/inputdata - -[datm_gswp3] -dir = atm/datm7/atm_forcing.datm7.GSWP3.0.5d.v1.c170516 -domain = domain.lnd.360x720_gswp3.0v1.c170606.nc -solardir = Solar -precdir = Precip -tpqwdir = TPHWL -solartag = clmforc.GSWP3.c2011.0.5x0.5.Solr. -prectag = clmforc.GSWP3.c2011.0.5x0.5.Prec. -tpqwtag = clmforc.GSWP3.c2011.0.5x0.5.TPQWL. -solarname = CLMGSWP3v1.Solar -precname = CLMGSWP3v1.Precip -tpqwname = CLMGSWP3v1.TPQW - -[surfdat] -dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -surfdat_78pft = surfdata_0.9x1.25_hist_78pfts_CMIP6_1850-2015_c231031.nc - -[landuse] -dir = lnd/clm2/surfdata_esmf/ctsm5.2.0 -landuse_78pft = landuse.timeseries_0.9x1.25_hist_78_CMIP6_1850-2015_c231031.nc - -[domain] -file = share/domains/domain.lnd.fv0.9x1.25_gx1v7.151020.nc - From 6902bfaca607c5cc6451c2a22ca9c8fb2835bc34 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 1 Apr 2024 18:16:34 -0600 Subject: [PATCH 561/614] Update README file removing specific problems we ran into during development that are no longer releent, but also adding some notes about specific problems found or caveats --- tools/mksurfdata_esmf/README | 69 ++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 38 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 1f7fa65270..1a05a56f83 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -28,9 +28,9 @@ In addition for the build: python, bash-shell, CMake and GNU-Make are required These libraries need to be built such that they can all work together in the same executable. Hence, the above order may be required in building them. -========================================= -Use cime to manage the build requirements -========================================= +======================================================================= +Use cime to manage the build requirements (but see IMPORTANT NOTE below) +======================================================================= For users working on cime machines you can use the build script to build the tool. On other machines you'll need to do a port to cime and tell how to build @@ -53,9 +53,31 @@ and able to be referenced with the env variable PIO which will need to be in the porting instructions for the machine. Currently an independent PIO library is not available on cime ported machines. -======================= +================================================= +IMPORTANT NOTE: ONLY WORKING ON DERECHO CURRENTLY +================================================= + +Currently we have only tested and ran on Derecho. In the longer +term we will make sure the process works for other CESM machines. + +Here's one issue tracking progress for this. + +https://github.com/ESCOMP/CTSM/issues/2341 + +======================================================== +IMPORTANT THERE HAVE BEEN PROBLEMS with REGIONAL grids!! +======================================================== + +See + +https://github.com/ESCOMP/CTSM/issues/2430 + +In general we recommend using subset_data and/or fsurdat_modifier +for regional grids. + +========================================================== Building the executable (working in tools/mksurfdata_esmf) -======================= +========================================================== # Before starting, be sure that you have run > ./manage_externals/checkout_externals @@ -67,9 +89,9 @@ Building the executable (working in tools/mksurfdata_esmf) # on derecho, casper, or izumi, you may need to update this, though # a default value does get set for other machines. -======================= +================================ Running for a single submission: -======================= +================================ # Work in the ctsm_pylib environment, which requires the following steps: > module unload python; module load conda > cd ../..; ./py_env_create @@ -91,9 +113,9 @@ Running for a single submission: > qsub mksurfdata_jobscript_single # Read note about regional grids below. -======================= +=============================================== Running for the generation of multiple datasets -======================= +=============================================== # Work in the ctsm_pylib environment, as explained in earlier section. # gen_mksurfdata_jobscript_multi runs ./gen_mksurfdata_namelist for you > ./gen_mksurfdata_jobscript_multi --help @@ -108,32 +130,3 @@ Running for the generation of multiple datasets NOTES ================ ------------------------------------- -slevis HAS LISTED ISSUES ENCOUNTERED ------------------------------------- -0) New 30-sec raw data for soil texture fails. Try requesting more mem. -1) Soil color & texture and ag fire peak month outputs too high in .log - TODO? Change frac_o from always 1. -2) Pct lake has chged in the .log bc the old diagnostic omitted mask_i frac_o -3) Slope, stddev have chged in the .log bc the old diag. used frac_o - --------------------------------------- -ALL raw dataset .nc FILES MUST BE cdf5 --------------------------------------- -> nccopy -k cdf5 oldfile newfile -------------------------------------------------------------- -LAI raw dataset .nc FILE MUST HAVE "unlimited" time dimension -------------------------------------------------------------- -ncks --mk_rec_dmn time file_with_time_equals_12.nc -o file_with_time_unlimited.nc - --------------------------------------------------------- -Override options removed that need to be placed in fsurdat_modifier -and/or subset_data: --------------------------------------------------------- ---soil_clay --soil_sand for setting to these values everywhere ---all_urban = .true. -Normalize so that sum(urban_classes_o(n,:)) = 100 for all n, even for grid -cells where pcturb_o(n) = 0 (in the case where pcturb_o(n) = 0, come up with an -arbitrary assignment of urban into the different classes). -See comments in the normalize_urbn_by_tot subroutine for how urban_classes_o is -determined when the total % urban is 0, according to the input data. From 041cb8a070bd5fa83f2fe431d3071a3532e990fe Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 2 Apr 2024 10:57:55 -0600 Subject: [PATCH 562/614] Update tools/mksurfdata_esmf/README From suggestion by @slevis-lmwg in review. Co-authored-by: Samuel Levis --- tools/mksurfdata_esmf/README | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README index 1a05a56f83..91a4a822f2 100644 --- a/tools/mksurfdata_esmf/README +++ b/tools/mksurfdata_esmf/README @@ -57,10 +57,7 @@ is not available on cime ported machines. IMPORTANT NOTE: ONLY WORKING ON DERECHO CURRENTLY ================================================= -Currently we have only tested and ran on Derecho. In the longer -term we will make sure the process works for other CESM machines. - -Here's one issue tracking progress for this. +Currently we have run and tested mksurfdata_esmf on Derecho. Please see this github issue about mksurfdata_esmf on other CESM machines: https://github.com/ESCOMP/CTSM/issues/2341 From b408d0900d928130820b9e5fa9fee23a7087d5eb Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 2 Apr 2024 11:10:28 -0600 Subject: [PATCH 563/614] Change README file to markdown --- tools/mksurfdata_esmf/{README => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tools/mksurfdata_esmf/{README => README.md} (100%) diff --git a/tools/mksurfdata_esmf/README b/tools/mksurfdata_esmf/README.md similarity index 100% rename from tools/mksurfdata_esmf/README rename to tools/mksurfdata_esmf/README.md From f60066a2973b9dfd60b02ce930c440402ef29868 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 2 Apr 2024 12:01:36 -0600 Subject: [PATCH 564/614] Bring in Markdown formatting --- tools/mksurfdata_esmf/README.md | 232 +++++++++++++++++++++----------- 1 file changed, 155 insertions(+), 77 deletions(-) diff --git a/tools/mksurfdata_esmf/README.md b/tools/mksurfdata_esmf/README.md index 91a4a822f2..a51b3a0867 100644 --- a/tools/mksurfdata_esmf/README.md +++ b/tools/mksurfdata_esmf/README.md @@ -1,6 +1,15 @@ -======= -Purpose -======= +# Instructions for Using mksurfdata_esmf to Create Surface Datasets + +## Table of contents +1. [Purpose] +1. [Building] +1. [Running for a Single Submission] +1. [Running for the Generation of Multiple Datasets] +1. [NOTES] + +## ======= +## Purpose +## ======= This tool is intended to generate fsurdat files (surface datasets) for the CTSM. It can generate global, regional, and single-point fsurdat files, as long as a mesh file is available for the grid. @@ -9,28 +18,38 @@ The subset_data tool allows users to make fsurdat files from existing fsurdat files when a mesh file is unavailable. Generally, users should consider the subset_data tool for generating regional and single-point fsurdat files. -=================== -Build Requirements: -=================== +## ======== +## Building +## ======== + +### ================== +### Build Requirements +### ================== mksurfdata_esmf is a distributed memory parallel program (using Message Passing Interface -- MPI) that utilizes both ESMF (Earth System Modelling Framework) for regridding as well as PIO (Parallel I/O) and NetCDF output. As such, libraries must be built for the following: -1) MPI -2) NetCDF -3) PIO -4) ESMF +1. MPI +2. NetCDF +3. PIO +4. ESMF In addition for the build: python, bash-shell, CMake and GNU-Make are required These libraries need to be built such that they can all work together in the same executable. Hence, the above order may be required in building them. -======================================================================= -Use cime to manage the build requirements (but see IMPORTANT NOTE below) -======================================================================= +CTSM externals that are required are: cime and ccs_config. See below on getting +those. A python environment that includes particular packages is also required +we demonstrate how to use the ctsm_pylib environment that we support in CTSM. + +Note, PNETCDF is an optional library that can be used, but is NOT required. + +#### ======================================================================= +#### Use cime to manage the build requirements (but see IMPORTANT NOTE below) +#### ======================================================================= For users working on cime machines you can use the build script to build the tool. On other machines you'll need to do a port to cime and tell how to build @@ -44,26 +63,140 @@ run the model on your machine, you will be able to build the tool there. To get a list of the machines that have been ported to cime: +``` shell cd ../../cime/scripts # assumes we are in tools/mksurfdata_esmf ./query_config --machines +``` -NOTE: +#### NOTE: In addition to having a port to cime, the machine also needs to have PIO built and able to be referenced with the env variable PIO which will need to be in -the porting instructions for the machine. Currently an independent PIO library -is not available on cime ported machines. +the porting instructions for the machine. An independent PIO library +is available on supported CESM machines. -================================================= -IMPORTANT NOTE: ONLY WORKING ON DERECHO CURRENTLY -================================================= +`#FF0000` +[!IMPORTANT] +#### ================================================= +#### IMPORTANT NOTE: ONLY WORKING ON DERECHO CURRENTLY +#### ================================================= Currently we have run and tested mksurfdata_esmf on Derecho. Please see this github issue about mksurfdata_esmf on other CESM machines: https://github.com/ESCOMP/CTSM/issues/2341 -======================================================== -IMPORTANT THERE HAVE BEEN PROBLEMS with REGIONAL grids!! -======================================================== +`#000000` +### ======================= +### Building the executable +### ======================= + + Before starting, be sure that you have run + +``` shell + ./manage_externals/checkout_externals +``` + +This will bring in CIME and ccs_config which are required for building. + +``` shell +cd tools/mksurfdata_esmf + ./gen_mksurfdata_build.sh # For machines with a cime build +``` + + Note: The pio_iotype value gets set and written to a simple .txt file + by this build script. The value depends on your machine. If not running + on derecho, casper, or izumi, you may need to update this, though + a default value does get set for other machines. + +## =============================== +## Running for a single submission +## =============================== + Work in the ctsm_pylib environment, which requires the following steps: + +``` shell + module unload python; module load conda + cd ../..; ./py_env_create + conda activate ctsm_pylib; cd tools/mksurfdata_esmf +``` + +to generate your target namelist: + +``` shell + ./gen_mksurfdata_namelist --help +``` + +for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: + +``` shell + ./gen_mksurfdata_namelist --res --start-year --end-year +``` + +[!TIP] + **IF FILES ARE MISSING FROM** /inputdata, a target namelist will be generated + but with a generic name and with warning to run `./download_input_data` next. + **IF A SMALLER SET OF FILES IS STILL MISSING AFTER RUNNING** `./download_input_data` + and rerunning `./gen_mksurfdata_namelist`, then rerun + `./gen_mksurfdata_namelist with your options needed. + and rerun `./download_input_data` until + `./gen_mksurfdata_namelist` finds all files. + + Example, to generate your target jobscript (again use --help for instructions): + +``` shell + ./gen_mksurfdata_jobscript_single --number-of-nodes 2 --tasks-per-node 128 --namelist-file target.namelist + qsub mksurfdata_jobscript_single +``` + + Read note about regional grids at the end. + +## =============================================== +## Running for the generation of multiple datasets +## =============================================== + Work in the ctsm_pylib environment, as explained in earlier section. + gen_mksurfdata_jobscript_multi runs `./gen_mksurfdata_namelist` for you + +``` shell + ./gen_mksurfdata_jobscript_multi --help + ./gen_mksurfdata_jobscript_multi --number-of-nodes 2 --scenario global-present + qsub mksurfdata_jobscript_multi +``` + + If you are looking to generate all (or a large number of) the datasets or the + single-point (1x1) datasets, you are best off using the Makefile. For example + +``` shell + make all # ...or + make all-subset +``` + +## ===== +## NOTES +## ===== + +[!TIP] +# ===================================================== +# Guidelines for input datasets to mksurfdata_esmf +# ===================================================== + +ALL raw datasets \*.nc **FILES MUST NOT BE NetCDF4**. + +Example to convert to CDF5 + +``` shell +nccopy -k cdf5 oldfile newfile +``` + +The LAI raw dataset \*.nc **FILE MUST HAVE** an "unlimited" time dimension + +Example to change time to unlimted dimension using the NCO operator ncks. + +``` shell +ncks --mk_rec_dmn time file_with_time_equals_12.nc -o file_with_time_unlimited.nc +``` + +[!CAUTION] +# ======================================================== +# IMPORTANT THERE HAVE BEEN PROBLEMS with REGIONAL grids!! +# ======================================================== See @@ -72,58 +205,3 @@ https://github.com/ESCOMP/CTSM/issues/2430 In general we recommend using subset_data and/or fsurdat_modifier for regional grids. -========================================================== -Building the executable (working in tools/mksurfdata_esmf) -========================================================== - -# Before starting, be sure that you have run -> ./manage_externals/checkout_externals -# because without it we have come across strange behavior, such as transient -# file generation (1850-2015) that aborts in the 1870s for no apparent reason. -> ./gen_mksurfdata_build.sh # For machines with a cime build -# Note: The pio_iotype value gets set and written to a simple .txt file -# by this build script. The value depends on your machine. If not running -# on derecho, casper, or izumi, you may need to update this, though -# a default value does get set for other machines. - -================================ -Running for a single submission: -================================ -# Work in the ctsm_pylib environment, which requires the following steps: -> module unload python; module load conda -> cd ../..; ./py_env_create -> conda activate ctsm_pylib; cd tools/mksurfdata_esmf -# to generate your target namelist: -> ./gen_mksurfdata_namelist --help -# for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: -> ./gen_mksurfdata_namelist --res --start-year --end-year -# IF FILES ARE MISSING FROM /inputdata, a target namelist will be generated -# but with a generic name and with warning to run ./download_input_data next. -# IF A SMALLER SET OF FILES IS STILL MISSING AFTER RUNNING ./download_input_data -# and rerunning ./gen_mksurfdata_namelist, then rerun -# ./gen_mksurfdata_namelist with --vic selected (and iteratively additional -# options if still necessary) and rerun ./download_input_data until -# ./gen_mksurfdata_namelist finds all files. - -# to generate your target jobscript (again --help for instructions): -> ./gen_mksurfdata_jobscript_single --number-of-nodes 2 --tasks-per-node 128 --namelist-file target.namelist -> qsub mksurfdata_jobscript_single -# Read note about regional grids below. - -=============================================== -Running for the generation of multiple datasets -=============================================== -# Work in the ctsm_pylib environment, as explained in earlier section. -# gen_mksurfdata_jobscript_multi runs ./gen_mksurfdata_namelist for you -> ./gen_mksurfdata_jobscript_multi --help -> ./gen_mksurfdata_jobscript_multi --number-of-nodes 2 --scenario global-present -> qsub mksurfdata_jobscript_multi -# If you are looking to generate all (or a large number of) the datasets or the -# single-point (1x1) datasets, you are best off using the Makefile. For example -> make all # ...or -> make all-subset - -================ -NOTES -================ - From ae2eada8edde422a5f2a9c57cc3ff2a1b05d4515 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 2 Apr 2024 12:15:50 -0600 Subject: [PATCH 565/614] Work on markdown formatting --- tools/mksurfdata_esmf/README.md | 84 ++++++++++++++++----------------- 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/tools/mksurfdata_esmf/README.md b/tools/mksurfdata_esmf/README.md index a51b3a0867..cd5260764d 100644 --- a/tools/mksurfdata_esmf/README.md +++ b/tools/mksurfdata_esmf/README.md @@ -1,15 +1,15 @@ # Instructions for Using mksurfdata_esmf to Create Surface Datasets ## Table of contents -1. [Purpose] -1. [Building] -1. [Running for a Single Submission] -1. [Running for the Generation of Multiple Datasets] -1. [NOTES] +1. [#purpose] +1. [#building] +1. [#running-for-a-single-submission] +1. [#running-for-the-generation-of-multiple-datasets] +1. [#notes] -## ======= + ## Purpose -## ======= + This tool is intended to generate fsurdat files (surface datasets) for the CTSM. It can generate global, regional, and single-point fsurdat files, as long as a mesh file is available for the grid. @@ -18,13 +18,13 @@ The subset_data tool allows users to make fsurdat files from existing fsurdat files when a mesh file is unavailable. Generally, users should consider the subset_data tool for generating regional and single-point fsurdat files. -## ======== + ## Building -## ======== + -### ================== + ### Build Requirements -### ================== + mksurfdata_esmf is a distributed memory parallel program (using Message Passing Interface -- MPI) that utilizes both ESMF (Earth System Modelling Framework) @@ -47,9 +47,7 @@ we demonstrate how to use the ctsm_pylib environment that we support in CTSM. Note, PNETCDF is an optional library that can be used, but is NOT required. -#### ======================================================================= #### Use cime to manage the build requirements (but see IMPORTANT NOTE below) -#### ======================================================================= For users working on cime machines you can use the build script to build the tool. On other machines you'll need to do a port to cime and tell how to build @@ -74,20 +72,19 @@ and able to be referenced with the env variable PIO which will need to be in the porting instructions for the machine. An independent PIO library is available on supported CESM machines. -`#FF0000` -[!IMPORTANT] -#### ================================================= + #### IMPORTANT NOTE: ONLY WORKING ON DERECHO CURRENTLY -#### ================================================= + -Currently we have run and tested mksurfdata_esmf on Derecho. Please see this github issue about mksurfdata_esmf on other CESM machines: + +> [!IMPORTANT] +> Currently we have run and tested mksurfdata_esmf on Derecho. Please see this github issue about mksurfdata_esmf on other CESM machines: https://github.com/ESCOMP/CTSM/issues/2341 -`#000000` -### ======================= + ### Building the executable -### ======================= + Before starting, be sure that you have run @@ -107,9 +104,9 @@ cd tools/mksurfdata_esmf on derecho, casper, or izumi, you may need to update this, though a default value does get set for other machines. -## =============================== + ## Running for a single submission -## =============================== + Work in the ctsm_pylib environment, which requires the following steps: ``` shell @@ -130,14 +127,14 @@ for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: ./gen_mksurfdata_namelist --res --start-year --end-year ``` -[!TIP] - **IF FILES ARE MISSING FROM** /inputdata, a target namelist will be generated - but with a generic name and with warning to run `./download_input_data` next. - **IF A SMALLER SET OF FILES IS STILL MISSING AFTER RUNNING** `./download_input_data` - and rerunning `./gen_mksurfdata_namelist`, then rerun - `./gen_mksurfdata_namelist with your options needed. - and rerun `./download_input_data` until - `./gen_mksurfdata_namelist` finds all files. +> [!TIP] +> **IF FILES ARE MISSING FROM** /inputdata, a target namelist will be generated +> but with a generic name and with warning to run `./download_input_data` next. +> **IF A SMALLER SET OF FILES IS STILL MISSING AFTER RUNNING** `./download_input_data` +> and rerunning `./gen_mksurfdata_namelist`, then rerun +> `./gen_mksurfdata_namelist with your options needed. +> and rerun `./download_input_data` until +> `./gen_mksurfdata_namelist` finds all files. Example, to generate your target jobscript (again use --help for instructions): @@ -148,9 +145,9 @@ for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: Read note about regional grids at the end. -## =============================================== + ## Running for the generation of multiple datasets -## =============================================== + Work in the ctsm_pylib environment, as explained in earlier section. gen_mksurfdata_jobscript_multi runs `./gen_mksurfdata_namelist` for you @@ -168,16 +165,14 @@ for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: make all-subset ``` -## ===== + ## NOTES -## ===== + -[!TIP] -# ===================================================== # Guidelines for input datasets to mksurfdata_esmf -# ===================================================== -ALL raw datasets \*.nc **FILES MUST NOT BE NetCDF4**. +> [!TIP] +> ALL raw datasets \*.nc **FILES MUST NOT BE NetCDF4**. Example to convert to CDF5 @@ -185,7 +180,8 @@ Example to convert to CDF5 nccopy -k cdf5 oldfile newfile ``` -The LAI raw dataset \*.nc **FILE MUST HAVE** an "unlimited" time dimension +> [!TIP] +> The LAI raw dataset \*.nc **FILE MUST HAVE** an "unlimited" time dimension Example to change time to unlimted dimension using the NCO operator ncks. @@ -193,14 +189,14 @@ Example to change time to unlimted dimension using the NCO operator ncks. ncks --mk_rec_dmn time file_with_time_equals_12.nc -o file_with_time_unlimited.nc ``` -[!CAUTION] # ======================================================== # IMPORTANT THERE HAVE BEEN PROBLEMS with REGIONAL grids!! # ======================================================== -See - -https://github.com/ESCOMP/CTSM/issues/2430 +> [!CAUTION] +> See +> +> https://github.com/ESCOMP/CTSM/issues/2430 In general we recommend using subset_data and/or fsurdat_modifier for regional grids. From 024b680abe9339d1b35dff4eaa573593321a7c9c Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 2 Apr 2024 12:24:27 -0600 Subject: [PATCH 566/614] More formatting --- tools/mksurfdata_esmf/README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tools/mksurfdata_esmf/README.md b/tools/mksurfdata_esmf/README.md index cd5260764d..b5d6190eb6 100644 --- a/tools/mksurfdata_esmf/README.md +++ b/tools/mksurfdata_esmf/README.md @@ -1,11 +1,11 @@ # Instructions for Using mksurfdata_esmf to Create Surface Datasets ## Table of contents -1. [#purpose] -1. [#building] -1. [#running-for-a-single-submission] -1. [#running-for-the-generation-of-multiple-datasets] -1. [#notes] +1. [Purpose](#purpose) +1. [Building](#building) +1. [Running a Single Submission](#running-for-a-single-submission) +1. [Running for Multiple Datasets](#running-for-the-generation-of-multiple-datasets) +1. [Notes](#notes) ## Purpose @@ -189,9 +189,7 @@ Example to change time to unlimted dimension using the NCO operator ncks. ncks --mk_rec_dmn time file_with_time_equals_12.nc -o file_with_time_unlimited.nc ``` -# ======================================================== -# IMPORTANT THERE HAVE BEEN PROBLEMS with REGIONAL grids!! -# ======================================================== +### IMPORTANT THERE HAVE BEEN PROBLEMS with REGIONAL grids!! > [!CAUTION] > See From 377007261499fee43a0e0c1ebb492d9483f1f347 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 2 Apr 2024 12:39:13 -0600 Subject: [PATCH 567/614] Add some links to within document --- tools/mksurfdata_esmf/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/mksurfdata_esmf/README.md b/tools/mksurfdata_esmf/README.md index b5d6190eb6..e8b4b212d6 100644 --- a/tools/mksurfdata_esmf/README.md +++ b/tools/mksurfdata_esmf/README.md @@ -41,13 +41,13 @@ In addition for the build: python, bash-shell, CMake and GNU-Make are required These libraries need to be built such that they can all work together in the same executable. Hence, the above order may be required in building them. -CTSM externals that are required are: cime and ccs_config. See below on getting +CTSM externals that are required are: cime and ccs_config. See [Building](#building-the-executable) on getting those. A python environment that includes particular packages is also required we demonstrate how to use the ctsm_pylib environment that we support in CTSM. Note, PNETCDF is an optional library that can be used, but is NOT required. -#### Use cime to manage the build requirements (but see IMPORTANT NOTE below) +#### Use cime to manage the build requirements (but see [IMPORTANT NOTE](important note-only-working-on-derecho-currently)) For users working on cime machines you can use the build script to build the tool. On other machines you'll need to do a port to cime and tell how to build From a350e4928fc3cdde1e0b732f4425c140077dc614 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 2 Apr 2024 22:12:43 -0600 Subject: [PATCH 568/614] Add some links, seperate lines for shell cmds Use line return in place of ; in shell examples. Add some links --- tools/mksurfdata_esmf/README.md | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/tools/mksurfdata_esmf/README.md b/tools/mksurfdata_esmf/README.md index e8b4b212d6..3c551d0388 100644 --- a/tools/mksurfdata_esmf/README.md +++ b/tools/mksurfdata_esmf/README.md @@ -47,7 +47,9 @@ we demonstrate how to use the ctsm_pylib environment that we support in CTSM. Note, PNETCDF is an optional library that can be used, but is NOT required. -#### Use cime to manage the build requirements (but see [IMPORTANT NOTE](important note-only-working-on-derecho-currently)) +#### Use cime to manage the build requirements + +See [IMPORTANT NOTE](important note-only-working-on-derecho-currently) For users working on cime machines you can use the build script to build the tool. On other machines you'll need to do a port to cime and tell how to build @@ -62,7 +64,8 @@ run the model on your machine, you will be able to build the tool there. To get a list of the machines that have been ported to cime: ``` shell -cd ../../cime/scripts # assumes we are in tools/mksurfdata_esmf +# Assuming pwd is the tools/mksurfdata_esmf directory +cd ../../cime/scripts # or ../../../../cime/scripts for a CESM checkout ./query_config --machines ``` @@ -89,13 +92,14 @@ https://github.com/ESCOMP/CTSM/issues/2341 Before starting, be sure that you have run ``` shell - ./manage_externals/checkout_externals +# Assuming pwd is the tools/mksurfdata_esmf directory + ./manage_externals/checkout_externals # Assuming at the top level of the CTSM/CESM checkout ``` This will bring in CIME and ccs_config which are required for building. ``` shell -cd tools/mksurfdata_esmf +# Assuming pwd is the tools/mksurfdata_esmf directory ./gen_mksurfdata_build.sh # For machines with a cime build ``` @@ -107,23 +111,31 @@ cd tools/mksurfdata_esmf ## Running for a single submission - Work in the ctsm_pylib environment, which requires the following steps: + +### Setup ctsm_pylib + Work in the ctsm_pylib environment, which requires the following steps when + running on Derecho. On other machines it will be similar but might be different + in order to get conda in your path and activate the ctsm_pylib environment. ``` shell - module unload python; module load conda - cd ../..; ./py_env_create - conda activate ctsm_pylib; cd tools/mksurfdata_esmf +# Assuming pwd is the tools/mksurfdata_esmf directory + module load conda + cd ../.. # or ../../../.. for a CESM checkout) + ./py_env_create # Assuming at the top level of the CTSM/CESM checkout + conda activate ctsm_pylib ``` to generate your target namelist: ``` shell +# Assuming pwd is the tools/mksurfdata_esmf directory ./gen_mksurfdata_namelist --help ``` for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: ``` shell +# Assuming pwd is the tools/mksurfdata_esmf directory ./gen_mksurfdata_namelist --res --start-year --end-year ``` @@ -139,6 +151,7 @@ for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: Example, to generate your target jobscript (again use --help for instructions): ``` shell +# Assuming pwd is the tools/mksurfdata_esmf directory ./gen_mksurfdata_jobscript_single --number-of-nodes 2 --tasks-per-node 128 --namelist-file target.namelist qsub mksurfdata_jobscript_single ``` @@ -152,7 +165,7 @@ for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: gen_mksurfdata_jobscript_multi runs `./gen_mksurfdata_namelist` for you ``` shell - ./gen_mksurfdata_jobscript_multi --help +# Assuming pwd is the tools/mksurfdata_esmf directory ./gen_mksurfdata_jobscript_multi --number-of-nodes 2 --scenario global-present qsub mksurfdata_jobscript_multi ``` @@ -161,6 +174,7 @@ for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: single-point (1x1) datasets, you are best off using the Makefile. For example ``` shell +# Assuming pwd is the tools/mksurfdata_esmf directory make all # ...or make all-subset ``` From 468bf33e4d67d06c4215ee6a3a72ca3c791d1346 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 3 Apr 2024 21:50:02 -0600 Subject: [PATCH 569/614] Remove cesm3_dev tests that are already part of aux_clm --- cime_config/testdefs/testlist_clm.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 0f365e81df..bb9378959c 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -45,7 +45,6 @@ - @@ -93,7 +92,6 @@ - From d35a53592c890dad59512242da8f674a147e1dec Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 5 Apr 2024 13:24:32 -0600 Subject: [PATCH 570/614] Correct includes for clm60 testmods --- .../clm/clm60cam6LndTuningModeCiso/include_user_mods | 2 +- .../clm/clm60cam6LndTuningMode_1979Start/include_user_mods | 2 +- .../clm/clm60cam6LndTuningMode_2013Start/include_user_mods | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeCiso/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeCiso/include_user_mods index aa76c52034..3dabdc9aeb 100644 --- a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeCiso/include_user_mods +++ b/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeCiso/include_user_mods @@ -1 +1 @@ -../clm51cam6LndTuningMode +../clm60cam6LndTuningMode diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_1979Start/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_1979Start/include_user_mods index aa76c52034..3dabdc9aeb 100644 --- a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_1979Start/include_user_mods +++ b/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_1979Start/include_user_mods @@ -1 +1 @@ -../clm51cam6LndTuningMode +../clm60cam6LndTuningMode diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_2013Start/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_2013Start/include_user_mods index aa76c52034..3dabdc9aeb 100644 --- a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_2013Start/include_user_mods +++ b/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_2013Start/include_user_mods @@ -1 +1 @@ -../clm51cam6LndTuningMode +../clm60cam6LndTuningMode From 8c7c2e8126e09a66b026d5f2bb1840a83159403f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 5 Apr 2024 14:03:44 -0600 Subject: [PATCH 571/614] Add some expected fails, and increase wallclock limits on some tests --- cime_config/testdefs/ExpectedTestFails.xml | 18 ++++++++++++++++-- cime_config/testdefs/testlist_clm.xml | 6 +++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index 8e108e1016..545aa93237 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -36,16 +36,30 @@ - + + + PEND + #2460 + + + + FAIL - Not opened yet but first posted here: https://github.com/ESCOMP/CTSM/pull/2318#discussion_r1484696000 + CDEPS/#243 + + + FAIL + #2444 + + + FAIL diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index bb9378959c..9cef66a032 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -17,7 +17,7 @@ - + @@ -260,7 +260,7 @@ - + @@ -449,7 +449,7 @@ - + From ca7df348fcec007073fb670e69e4468d40979025 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 5 Apr 2024 15:59:17 -0600 Subject: [PATCH 572/614] Increase another wallclock time --- cime_config/testdefs/testlist_clm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 9cef66a032..54864cb8a6 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -251,7 +251,7 @@ - + From 9d49e9e80751b8efa4db2c4d748d5b682dd64608 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 8 Apr 2024 12:52:05 -0600 Subject: [PATCH 573/614] Test list updates for clm60 Remove nvhpc test from ctsm_sci since not passing. Keep the one expected fail for nvhpc. Change the Expected fails for Clm51 to Clm60. Remove the mpasa3p75 test as it's experimental and requires a huge number of processors. --- cime_config/testdefs/ExpectedTestFails.xml | 25 ++++++++-------------- cime_config/testdefs/testlist_clm.xml | 18 ++-------------- 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index 545aa93237..956d932b4b 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -29,13 +29,6 @@ - - - PEND - #2370 - - - PEND @@ -67,21 +60,21 @@ - + FAIL #1733 - + FAIL #1733 - + FAIL #2310 @@ -92,7 +85,7 @@ - + FAIL #2310 @@ -103,7 +96,7 @@ - + FAIL #2310 @@ -114,7 +107,7 @@ - + FAIL #2310 @@ -125,7 +118,7 @@ - + FAIL #2310 @@ -145,7 +138,7 @@ - + FAIL #2321 @@ -173,7 +166,7 @@ - + FAIL #2261 diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 54864cb8a6..75073a6ecd 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -53,7 +53,7 @@ - + @@ -209,15 +209,6 @@ --> - - - - - - - - - @@ -1978,7 +1969,6 @@ - @@ -2121,11 +2111,7 @@ - - - - - + From 6c4e1a6d87bacee84af88eeb13ecf65647444fe7 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 8 Apr 2024 13:36:32 -0600 Subject: [PATCH 574/614] Pass in the build directory for mksurfdata_esmf from the case to the jobscript so the test case is completely self-contained --- cime_config/SystemTests/mksurfdataesmf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 4e9800024e..70858e5e8a 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -64,7 +64,7 @@ def build_phase(self, sharedlib_only=False, model_only=False): nml_script_path = os.path.join(self._tool_path, "gen_mksurfdata_namelist") gen_jobscript_path = os.path.join(self._tool_path, "gen_mksurfdata_jobscript_single") gen_mksurfdata_namelist = f"{nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}" - gen_mksurfdata_jobscript = f"{gen_jobscript_path} --number-of-nodes 1 --tasks-per-node 64 --namelist-file {self._fsurdat_namelist}" + gen_mksurfdata_jobscript = f"{gen_jobscript_path} --number-of-nodes 1 --tasks-per-node 64 --namelist-file {self._fsurdat_namelist} --bld-path {self._tool_bld}" # Rm tool_bld and build executable that will generate fsurdat try: @@ -76,6 +76,7 @@ def build_phase(self, sharedlib_only=False, model_only=False): try: subprocess.check_call(f"{build_script_path} --blddir {self._tool_bld}", shell=True) except subprocess.CalledProcessError as e: + print( f"build directory = {self._tool_bld}\n" ) sys.exit( f"{e} ERROR RUNNING {build_script_path}. DETAILS IN {self._TestStatus_log_path}" ) From 665cf86102e09b4c4c5a140700676dca23bc55a9 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 8 Apr 2024 13:39:13 -0600 Subject: [PATCH 575/614] Black reformat --- cime_config/SystemTests/mksurfdataesmf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 70858e5e8a..301141f02a 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -76,7 +76,7 @@ def build_phase(self, sharedlib_only=False, model_only=False): try: subprocess.check_call(f"{build_script_path} --blddir {self._tool_bld}", shell=True) except subprocess.CalledProcessError as e: - print( f"build directory = {self._tool_bld}\n" ) + print(f"build directory = {self._tool_bld}\n") sys.exit( f"{e} ERROR RUNNING {build_script_path}. DETAILS IN {self._TestStatus_log_path}" ) From bf06b87ae3cc74d41a62a1c21fc55e7780f66876 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 8 Apr 2024 15:18:56 -0600 Subject: [PATCH 576/614] Add black commit --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 549c8a7e4a..0c9bf10954 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -42,3 +42,4 @@ cda0cf1412212e6f4363e6e8eb39f74c944b454d aa04d1f7d86cc2503b98b7e2b2d84dbfff6c316b 6c6f57e948bfa31e60b383536cc21663fedb8b70 9660667b1267dcd4150889f5f39db540158be74a +665cf86102e09b4c4c5a140700676dca23bc55a9 From 2fb80700361c92313c998d520c0c2409b10613a7 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 8 Apr 2024 15:31:14 -0600 Subject: [PATCH 577/614] Move cesm3_dev testlist to aux_clm Move the ne30 tests that were in the cesm3_dev test list to the aux_clm. And remove the cesm3_dev testlist. --- cime_config/testdefs/ExpectedTestFails.xml | 2 -- cime_config/testdefs/testlist_clm.xml | 10 +++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index 956d932b4b..f223dc0c0f 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -43,8 +43,6 @@ - - diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 75073a6ecd..b61e26ddd7 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -65,7 +65,7 @@ - + @@ -74,7 +74,7 @@ - + @@ -83,7 +83,7 @@ - + @@ -101,7 +101,7 @@ - + @@ -110,7 +110,7 @@ - + From 850f2bd3c09204af553d998636a69824a73d4592 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 8 Apr 2024 18:08:44 -0600 Subject: [PATCH 578/614] Remove izumi_nag for ne30 from prealpha list, make sure all prealpha and aux_cime_baselines tests are run in aux_clm --- cime_config/testdefs/testlist_clm.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index b61e26ddd7..200572fa48 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -550,7 +550,6 @@ - @@ -1251,6 +1250,7 @@ + @@ -1407,6 +1407,7 @@ + From b904b5aea865a185824a1974c64511d3b5726968 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 8 Apr 2024 18:59:13 -0600 Subject: [PATCH 579/614] Update changelog files for ctsm5.2, also update UpdateChangeLog script so can make a ctsm5.2.0 tag --- doc/.ChangeLog_template | 9 +- doc/ChangeLog | 227 ++++++++++++++++++++++++++++++++++++++++ doc/ChangeSum | 1 + doc/UpdateChangelog.pl | 3 +- 4 files changed, 233 insertions(+), 7 deletions(-) diff --git a/doc/.ChangeLog_template b/doc/.ChangeLog_template index a1170a61cf..7e44f6872c 100644 --- a/doc/.ChangeLog_template +++ b/doc/.ChangeLog_template @@ -33,8 +33,6 @@ Bugs fixed CTSM issues fixed (include CTSM Issue #): -Known bugs introduced in this tag (include issue #): - Notes of particular relevance for users --------------------------------------- [Remove any lines that don't apply. Remove entire section if nothing applies.] @@ -98,10 +96,6 @@ infrastructure should be run when appropriate, as described below. derecho - - tools-tests (test/tools) (if tools have been changed): - - derecho - - python testing (if python code has changed; see instructions in python/README.md; document testing done): (any machine) - @@ -127,6 +121,9 @@ infrastructure should be run when appropriate, as described below. any other testing (give details below): + ctsm_sci + derecho ---- + If the tag used for baseline comparisons was NOT the previous tag, note that here: diff --git a/doc/ChangeLog b/doc/ChangeLog index f822c5a72e..58e46cbb4a 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,231 @@ =============================================================== +Tag name: ctsm5.2.0 +Originator(s): erik (Erik Kluzek) +Date: Wed Apr 3 01:17:18 MDT 2024 +One-line Summary: New surface datasets and new mksurfdata_esmf tool to create them + +Purpose and description of changes +---------------------------------- + +Changes to CTSM: +================ + +All new surface datasets. Transient urban and lake by default turned on for transient cases. +Ocean is run as baresoil rather than wetland (for clm6_0). The urban streams file was also +updated. The new surface datasets have new updated input datasets (see below). + +New surface datasets: +===================== + +The new surface datasets are incompatible with previous versions (for example the ctsm5.1 series) +ctsm5.2.0 and following versions also can NOT use the previous ctsm5.1 datasets. + +See the section below about the new datasets used in their creation. Improvements in how landunits +on coastal areas was also done. + +The following fields were added and removed to the list of fields on the datasets. + +Fields added: + ORGC, BULK, CFRAG, PHAQ (soil data) + mapunits (map units for the soil dataset) + LANDFRAC_MKSURFDATA + PCT_OCEAN (previously PCT_WETLAND was used) + +Fields removed: + AREA, PFTDATA_MASK + +New mksurfdata_esmf Tool: +========================= + +Implement a parallel version of mksurfdata (mksurfdata_esmf) that uses ESMF regridding directly +in mksurfdata so that offline mapping files don't have to be created as a separate step. This +allows mksurfdata to create surface datasets at much higher resolutions + +The build for the tool is based on the CESM/CIME build system and uses cmake. This allows the build +to be kept up with changes in CESM. Currently it's only setup and working on Derecho. But, this design +will enable it to be built and run on any CESM supported machine (or a machine that a user ports to). + +Any input grid from ccs_config can be used, or the user can supply their own mesh file to define +the output grid. The user no longer has to add to the list of valid resolutions as in mksurfdata_map. + +Creation of supported single point datasets. These datasets are created through the use of subset_data. + +Test datasets for dynUrban, dynLake, and dynPFT is done with a simple NCO script. + +All datasets can be easily made by running "make all" in the tools/mksurfdata_esmf directory. + +For instructions see: + tools/mksurfdata_esmf/README.md + +New input datasets to mksurfdata_esmf: +====================================== + +New soil dataset: ISRIC/WISE dataset Batjes (2016) https://doi.org/10.1016/j.geoderma.2016.01.034 +New PFT, soil-color, LAI dataset: Created by Lawrence P.J. 2022 +New Glacier datasets: Glacier outlines from RGI version 6 (Arendt et al., 2017). + vector data for GrIS and AIS retrieved from BedMachine version 4 and version 2 (Morlighem et al., 2017, 2020), respectively. + 30-arcsec topography/land mask retrieved GMTED2010 (Danielson and Gesch, 2011). +New urban datasets: Gao and O'Neill (2021) and Gao and Pesaresi (2022), Oleson and Feddema (2020) +New lake datasets: HydroLake: Messager et. al. (2016) + +Contributors +------------ +@mvertens @ekluzek @jedwards4b @billsacks @wwieder @lawrencepj1 @negin513 @dlawrenncar @olyson + +Significant changes to scientifically-supported configurations +-------------------------------------------------------------- + +Does this tag change answers significantly for any of the following physics configurations? +(Details of any changes will be given in the "Answer changes" section below.) + + [Put an [X] in the box for any configuration with significant answer changes.] + +[x] clm5_1 + +[x] clm5_0 + +[x] ctsm5_0-nwp + +[x] clm4_5 + + +Bugs fixed +---------- + +CTSM issues fixed (include CTSM Issue #): + Fixes #1903 Create new surface datasets, CTSM5.2 branch + Fixes #1716 Wetland area and areas of landunits in coastal grid cells + should be determined more rigorously + Fixes #1556 Remake PCT_PFT raw datasets to NOT force landunit area to 100%, + and some other fixes needed to PCT_PFT raw datasets + Fixes #1878 Convert wetlands to bare ground + Fixes #2131 Add a "successfully completed" message to mksurfdata_esmf when + the landuse.timeseries file is made + Fixes #2218 CTSM5.2 branch dies weirdly when clm5.0/ctsm5.1 datasets are + used -- die with an error + Fixes #2278 Allow CTSM to output history files interpolated to a regular + grid (for example from SE unstructured grids to a FV grid) + +Notes of particular relevance for users +--------------------------------------- + +Caveats for users (e.g., need to interpolate initial conditions): + These surface datasets can NOT be used in previous versions of the model + Older surface datasets can NOT be used with this model version + +Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): + New CLM_PHYSICS_VERSION option of clm6_0 added (use it rather than clm5_1) + New compsets for Clm60 added + New namelist item: convert_ocean_to_land (default true for clm5_1 and clm6_0 physics) + +Changes made to namelist defaults (e.g., changed parameter values): + clm5_1 physics options copied to clm6_0 + do_transient_lake and do_transient_urban set to TRUE for transient cases + +Changes to the datasets (e.g., parameter, surface or initial files): + New ctsm6.0 parameter file copied from the ctsm5.1 verison + fsurdat and landuse.timeseries datasets all updated + urbantv streams datasets updated + Some initial condition datasets updated to go with the new datasets + +Notes of particular relevance for developers: +--------------------------------------------- + +Caveats for developers (e.g., code that is duplicated that requires double maintenance): + The namelist_defaults_ctsm.xml file was simplified which should make it easier to work with +Changes to tests or testing: + New system test in prealpha and aux_clm to create a surface dataset and run with it + ctsm_sci testlist updated to run all CESM3 supported datasets + See this document for the list of supported grids: + https://docs.google.com/spreadsheets/d/1Osq56e423CF107zhoNQ0VS7-iH_JXLF9AtCvBdXyfJ4 + +Testing summary: regular ctsm_sci fates mosart rtm tools python +---------------- + + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + build-namelist tests (if CLMBuildNamelist.pm has changed): + + derecho - PASS (1396 tests compare different because of the namelist changes) + + python testing (if python code has changed; see instructions in python/README.md; document testing done): + + derecho - PASS + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + + fates tests: (give name of baseline if different from CTSM tagname, normally fates baselines are fates-sci.1.72.2_api.34.0.0-ctsm5.2.0) + derecho ----- + izumi ------- + + any other testing (give details below): + + ctsm_sci + derecho ---- PASS + + rtm (rtm1_0_79_ctsm5.2.0) + derecho ---- + + mosart (mosart1_0_49_ctsm5.2.0) + derecho ---- + +If the tag used for baseline comparisons was NOT the previous tag, note that here: ctsm5.1.dev175 + + +Answer changes +-------------- + +Changes answers relative to baseline: Yes! + + Summarize any changes to answers, i.e., + - what code configurations: All + - what platforms/compilers: All + - nature of change: new climate + + Discussion on the new datasets and new results are here: + + https://github.com/ESCOMP/CTSM/discussions/1868 + + It includes case comparision + +Other details +------------- + +Pull Requests that document the changes (include PR ids): +(https://github.com/ESCOMP/ctsm/pull) + + #2417 -- Addition of clm6_0 physics option + #2447 -- Update ctsm5.2 branch to ctsm5.1.dev175 + #2427 -- Merge ctsm5.2 branch up to ctsm5.1.dev174 + #2424 -- Clean up "make all" for 5.2 branch tag: bfb type: code cleanup + #2318 -- Workaround for transient Smallville tests #1673 + testing all new datasets + #1586 -- Enable the mksurfdata_map to generate landuse_timeseries for dynamic urban and lake + #2327 -- Working on Derecho + #2008 -- Get the Makefile working for CTSM5.2 surface dataset creation + #2164 -- Distinguish between ocean and wetland in fsurdat files + #2016 -- Preparing alpha-ctsm5.2.mksrf.16_ctsm5.1.dev123 tag + #1946 -- Newest raw datasets for pft, lai, soilcolor + #1873 -- Ctsm52 various updates + #1920 -- mksurfdata: Rework mapping of landunits to handle coastal areas more rigorously + #1890 -- Add option to convert wetlands to land; apply it by default for CLM51 physics + #1866 -- Remove pftmask from history and PFTDATA_MASK from fsurdat files + #1732 -- New soiltex for ctsm5.2.mksurfdata + #1853 -- Implement GaoOneill raw urban datasets and OlesonFeddema urban + properties into mksurfdata_esmf. + #1796 -- Add consistency checks for mesh_nx mesh_ny relative to mesh_file in + gen_mksurfdata_namelist.py + #1748 -- Enable mksurfdata esmf to build and run on casper and izumi + #1756 -- Add mksurfdata_esmf system test to test-suite tag: support tools only + #1721 -- cmake build working on cheyenne for mksurfdata_esmf + #1746 -- Change repo_url from git@... to https:... for ccs_config + #1728 -- Accelerate generation of transient data with mksurfdata_esmf + #1663 -- New parallel surface dataset generation with online regridding + +=============================================================== +=============================================================== Tag name: ctsm5.1.dev175 Originator(s): slevis (Samuel Levis,UCAR/TSS,303-665-1310) Date: Thu 21 Mar 2024 05:49:04 PM MDT diff --git a/doc/ChangeSum b/doc/ChangeSum index e8c32d90a8..c027721724 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ Tag Who Date Summary ============================================================================================================================ + ctsm5.2.0 multiple 04/03/2024 New mksurfdata_esmf tool to create new surface datasets that are in place ctsm5.1.dev175 slevis 03/21/2024 merge-b4bdev-20240321 ctsm5.1.dev174 olyson 03/14/2024 Improve vegetation health at high latitudes ctsm5.1.dev173 rgknox 03/13/2024 New FATES namelist variable: fates_history_dimlevel diff --git a/doc/UpdateChangelog.pl b/doc/UpdateChangelog.pl index 4a5329175b..67be182b8d 100755 --- a/doc/UpdateChangelog.pl +++ b/doc/UpdateChangelog.pl @@ -67,7 +67,8 @@ sub usage { $tag = $ARGV[0]; $sum = $ARGV[1]; - if ( $tag !~ /ctsm[0-9]\.[0-9]\.(dev[0-9][0-9][0-9]|[0-9][0-9])/ ) { + # Tags should be something like ctsm5.3.dev001 or ctsm5.3.0 + if ( ($tag !~ /ctsm[0-9]\.[0-9]\.(dev[0-9][0-9][0-9]|[0-9][0-9])/) && ($tag !~ /ctsm[0-9]\.([0-9])\.([0-9])/) ) { print "ERROR: bad tagname: $tag\n"; usage(); } From b32df77723fe9d7e5f86aa886804799a6cf827a2 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 10 Apr 2024 13:44:29 -0600 Subject: [PATCH 580/614] Put new ctsm5.2 finidat files in initdata_esmf/ctsm5.2 directory --- bld/namelist_files/namelist_defaults_ctsm.xml | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 47273636f4..db36e222b5 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -439,7 +439,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). -lnd/clm2/paramdata/ctsm51_params.c240208.nc +lnd/clm2/paramdata/ctsm60_params.c240208.nc lnd/clm2/paramdata/ctsm51_params.c240208.nc lnd/clm2/paramdata/clm50_params.c240208.nc lnd/clm2/paramdata/clm45_params.c240208.nc @@ -959,7 +959,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ic_ymd="18500101" sim_year="1850" do_transient_pfts=".false." ic_tod="0" glc_nec="10" use_crop=".true." irrigate=".false." lnd_tuning_mode="clm5_0_GSWP3v1" ->lnd/clm2/initdata_map/clmi.I1850Clm50BgcCrop-ciso.1366-01-01.0.9x1.25_gx1v7_simyr1850_c240223.nc +>lnd/clm2/initdata_esmf/ctsm5.2/clmi.I1850Clm50BgcCrop-ciso.1366-01-01.0.9x1.25_gx1v7_simyr1850_c240223.nc @@ -967,7 +967,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ic_ymd="18500101" sim_year="1850" do_transient_pfts=".false." ic_tod="0" glc_nec="10" use_crop=".true." irrigate=".false." lnd_tuning_mode="clm5_0_CRUv7" ->lnd/clm2/initdata_map/clmi.I1850Clm50BgcCropCru-ciso.1526-01-01.0.9x1.25_gx1v7_simyr1850_c240223.nc +>lnd/clm2/initdata_esmf/ctsm5.2/clmi.I1850Clm50BgcCropCru-ciso.1526-01-01.0.9x1.25_gx1v7_simyr1850_c240223.nc @@ -996,7 +996,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ic_ymd="18500101" sim_year="1850" do_transient_pfts=".false." ic_tod="0" glc_nec="10" use_crop=".true." irrigate=".false." lnd_tuning_mode="clm5_1_GSWP3v1" ->lnd/clm2/initdata_map/clmi.I1850Clm50BgcCrop-ciso.1366-01-01.0.9x1.25_gx1v7_simyr1850_c240223.nc +>lnd/clm2/initdata_esmf/ctsm5.2/clmi.I1850Clm50BgcCrop-ciso.1366-01-01.0.9x1.25_gx1v7_simyr1850_c240223.nc @@ -1018,7 +1018,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ic_ymd="18500101" sim_year="1850" do_transient_pfts=".false." ic_tod="0" glc_nec="10" use_crop=".true." irrigate=".false." lnd_tuning_mode="clm6_0_GSWP3v1" ->lnd/clm2/initdata_map/clmi.I1850Clm50BgcCrop-ciso.1366-01-01.0.9x1.25_gx1v7_simyr1850_c240223.nc +>lnd/clm2/initdata_esmf/ctsm5.2/clmi.I1850Clm50BgcCrop-ciso.1366-01-01.0.9x1.25_gx1v7_simyr1850_c240223.nc @@ -1039,7 +1039,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ic_ymd="20110101" sim_year="2000" do_transient_pfts=".false." ic_tod="0" glc_nec="10" use_crop=".true." irrigate=".true." lnd_tuning_mode="clm4_5_GSWP3v1" ->lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc +>lnd/clm2/initdata_esmf/ctsm5.2/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc @@ -1047,7 +1047,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ic_ymd="20110101" sim_year="2000" do_transient_pfts=".false." ic_tod="0" glc_nec="10" use_crop=".true." irrigate=".true." lnd_tuning_mode="clm4_5_CRUv7" ->lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc +>lnd/clm2/initdata_esmf/ctsm5.2/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc @@ -1055,19 +1055,19 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ic_ymd="20110101" sim_year="2000" do_transient_pfts=".false." ic_tod="0" glc_nec="10" use_crop=".true." irrigate=".true." lnd_tuning_mode="clm5_0_GSWP3v1" ->lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc +>lnd/clm2/initdata_esmf/ctsm5.2/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc +>lnd/clm2/initdata_esmf/ctsm5.2/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc +>lnd/clm2/initdata_esmf/ctsm5.2/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc @@ -1076,7 +1076,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). ic_ymd="20110101" sim_year="2000" do_transient_pfts=".false." ic_tod="0" glc_nec="10" use_crop=".true." irrigate=".true." lnd_tuning_mode="clm5_0_CRUv7" ->lnd/clm2/initdata_map/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc +>lnd/clm2/initdata_esmf/ctsm5.2/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc From ec9af2d713fb680f255236ae31163be5dee9f61c Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 10 Apr 2024 13:54:52 -0600 Subject: [PATCH 581/614] Just update mksurfdata_map to mksurfdata_esmf using VS code --- doc/source/lilac/specific-atm-models/wrf-tools.rst | 4 ++-- .../CLM50_Tech_Note_Transient_Landcover.rst | 8 ++++---- doc/source/tech_note/Urban/CLM50_Tech_Note_Urban.rst | 2 +- .../running-PTCLM/adding-ptclm-site-data.rst | 2 +- .../running-single-point-configurations.rst | 6 +++--- .../running-special-cases/Running-with-irrigation.rst | 2 +- .../using-clm-tools/building-the-clm-tools.rst | 8 ++++---- .../creating-input-for-surface-dataset-generation.rst | 6 +++--- .../using-clm-tools/creating-surface-datasets.rst | 10 +++++----- .../using-clm-tools/observational-sites-datasets.rst | 2 +- .../using-clm-tools/what-are-the-clm-tools.rst | 8 ++++---- 11 files changed, 29 insertions(+), 29 deletions(-) diff --git a/doc/source/lilac/specific-atm-models/wrf-tools.rst b/doc/source/lilac/specific-atm-models/wrf-tools.rst index 0366bc1582..f67a05ea0a 100644 --- a/doc/source/lilac/specific-atm-models/wrf-tools.rst +++ b/doc/source/lilac/specific-atm-models/wrf-tools.rst @@ -52,9 +52,9 @@ is described in here. ./gen_domain -m /glade/work/$USER/ctsm/nldas_grid/scrip/wrf2clm_mapping_noneg.nc -o wrf2clm_ocn_noneg -l wrf2clm_lnd_noneg -6. Create surface datasets in ``tools/mksurfdata_map``:: +6. Create surface datasets in ``tools/mksurfdata_esmf``:: - ./mksurfdata.pl -res usrspec -usr_gname "nldas" -usr_gdate "190124" -usr_mapdir "/glade/work/$USER/ctsm/nldas_grid/map" -y 2000 -exedir "/glade/u/home/$USER/src/ctsm/ctsm_surfdata/tools/mksurfdata_map" -no-crop + ./mksurfdata.pl -res usrspec -usr_gname "nldas" -usr_gdate "190124" -usr_mapdir "/glade/work/$USER/ctsm/nldas_grid/map" -y 2000 -exedir "/glade/u/home/$USER/src/ctsm/ctsm_surfdata/tools/mksurfdata_esmf" -no-crop Merge WRF initial conditions into an existing CTSM initial condition file -------------------------------------------------------------------------- diff --git a/doc/source/tech_note/Transient_Landcover/CLM50_Tech_Note_Transient_Landcover.rst b/doc/source/tech_note/Transient_Landcover/CLM50_Tech_Note_Transient_Landcover.rst index c221a14d28..99ee5ab676 100644 --- a/doc/source/tech_note/Transient_Landcover/CLM50_Tech_Note_Transient_Landcover.rst +++ b/doc/source/tech_note/Transient_Landcover/CLM50_Tech_Note_Transient_Landcover.rst @@ -107,9 +107,9 @@ To represent the LUH2 transient LULCC dataset in CLM5, the annual fractional com To support this translation task the CLM5 Land Use Data tool has been built that extends the methods described in Lawrence et al (2012) to include all the new functionality of CMIP6 and CLM5 LULCC. The tool translates each of the LUH2 land units for a given year into fractional PFT and CFT values based on the current day CLM5 data for the land unit in that grid cell. The current day land unit descriptions are generated from from 1km resolution MODIS, MIRCA2000, ICESAT, AVHRR, SRTM, and CRU climate data products combined with reference year LUH2 land unit data, usually set to 2005. Where the land unit does not exist in a grid cell for the current day, the land unit description is generated from nearest neighbors with an inverse distance weighted search algorithm. -The Land Use Data tool produces raw vegetation, crop, and management data files which are combined with other raw land surface data to produce the CLM5 initial surface dataset and the dynamic *landuse.timeseries* dataset with the CLM5 mksurfdata_map tool. The schematic of this entire process from LUH2 time series and high resolution current day data to the output of CLM5 surface datasets from the mksurfdata_map tool is shown in Figure 21.2. +The Land Use Data tool produces raw vegetation, crop, and management data files which are combined with other raw land surface data to produce the CLM5 initial surface dataset and the dynamic *landuse.timeseries* dataset with the CLM5 mksurfdata_esmf tool. The schematic of this entire process from LUH2 time series and high resolution current day data to the output of CLM5 surface datasets from the mksurfdata_esmf tool is shown in Figure 21.2. -The methodology for creating the CLM5 transient PFT and CFT dataset is based on four steps which are applied across all of the historical and future time series. The first step involves generating the current day descriptions of natural and managed vegetation PFTs at 1km resolution from the global source datasets, and the current day description of crop CFTs at the 10km resolution from the MIRCA 2000 datasets. The second step combines the current day (2005) LUH2 land units with the current day CLM5 PFT and CFT distributions to get CLM5 land unit descriptions in either PFTs or CFTs at the LUH2 resolution of 0.25 degrees. The third step involves combining the LUH2 land unit time series with the CLM5 PFT and CFT descriptions for that land unit to generate the CLM5 raw PFT and CFT time series in the *landuse.timeseries* file. At this point in the process management information in terms of fertilizer, irrigation and wood harvest are added to the CLM5 PFT and CFT data to complete the CLM5 raw PFT and CFT files. The final step is to combine these files with the other raw CLM5 surface data files in the mksurfdata_map tool. +The methodology for creating the CLM5 transient PFT and CFT dataset is based on four steps which are applied across all of the historical and future time series. The first step involves generating the current day descriptions of natural and managed vegetation PFTs at 1km resolution from the global source datasets, and the current day description of crop CFTs at the 10km resolution from the MIRCA 2000 datasets. The second step combines the current day (2005) LUH2 land units with the current day CLM5 PFT and CFT distributions to get CLM5 land unit descriptions in either PFTs or CFTs at the LUH2 resolution of 0.25 degrees. The third step involves combining the LUH2 land unit time series with the CLM5 PFT and CFT descriptions for that land unit to generate the CLM5 raw PFT and CFT time series in the *landuse.timeseries* file. At this point in the process management information in terms of fertilizer, irrigation and wood harvest are added to the CLM5 PFT and CFT data to complete the CLM5 raw PFT and CFT files. The final step is to combine these files with the other raw CLM5 surface data files in the mksurfdata_esmf tool. .. _Figure Schematic of land cover change: @@ -123,8 +123,8 @@ The methodology for creating the CLM5 transient PFT and CFT dataset is based on Schematic of translation of annual LUH2 land units to CLM5 plant and crop functional types. -.. _Figure Workflow of CLM5 Land Use Data Tool and Mksurfdata_map Tool: +.. _Figure Workflow of CLM5 Land Use Data Tool and mksurfdata_esmf Tool: .. figure:: image3.png - Workflow of CLM5 Land Use Data Tool and Mksurfdata_map Tool + Workflow of CLM5 Land Use Data Tool and mksurfdata_esmf Tool diff --git a/doc/source/tech_note/Urban/CLM50_Tech_Note_Urban.rst b/doc/source/tech_note/Urban/CLM50_Tech_Note_Urban.rst index e9bfb5eb57..8777c7be74 100644 --- a/doc/source/tech_note/Urban/CLM50_Tech_Note_Urban.rst +++ b/doc/source/tech_note/Urban/CLM50_Tech_Note_Urban.rst @@ -19,7 +19,7 @@ Present day global urban extent and urban properties were developed by :ref:`Jac For each of 33 distinct regions across the globe, thermal (e.g., heat capacity and thermal conductivity), radiative (e.g., albedo and emissivity) and morphological (e.g., height to width ratio, roof fraction, average building height, and pervious fraction of the canyon floor) properties are provided for each of the density classes. Building interior minimum and maximum temperatures are prescribed based on climate and socioeconomic considerations. The surface dataset creation routines (see CLM5.0 User's Guide) aggregate the data to the desired resolution. -An optional urban properties dataset, including a tool that allows for generating future urban development scenarios is also available (:ref:`Oleson and Feddema (2018) `). This will become the default dataset in future model versions. As described in :ref:`Oleson and Feddema (2018) ` the urban properties dataset in :ref:`Jackson et al. (2010) ` was modified with respect to wall and roof thermal properties to correct for biases in heat transfer due to layer and building type averaging. Further changes to the dataset reflect the need for scenario development, thus allowing for the creation of hypothetical wall types, and the easier interchange of wall facets. The new urban properties tool is available as part of the Toolbox for Human-Earth System Integration & Scaling (THESIS) tool set (http://www.cgd.ucar.edu/iam/projects/thesis/thesis-urbanproperties-tool.html; :ref:`Feddema and Kauffman (2016) `). The driver script (urban_prop.csh) specifies three input csv files (by default, mat_prop.csv, lam_spec.csv, and city_spec.csv; (:numref:`Figure schematic of THESIS urban properties tool`)) that describe the morphological, radiative, and thermal properties of urban areas, and generates a global dataset at 0.05° latitude by longitude in NetCDF format (urban_properties_data.05deg.nc). A standalone NCL routine (gen_data_clm.ncl) can be run separately after the mksurfdata_map tool creates the CLM surface dataset. This creates a supplementary streams file of setpoints for the maximum interior building temperature at yearly time resolution. +An optional urban properties dataset, including a tool that allows for generating future urban development scenarios is also available (:ref:`Oleson and Feddema (2018) `). This will become the default dataset in future model versions. As described in :ref:`Oleson and Feddema (2018) ` the urban properties dataset in :ref:`Jackson et al. (2010) ` was modified with respect to wall and roof thermal properties to correct for biases in heat transfer due to layer and building type averaging. Further changes to the dataset reflect the need for scenario development, thus allowing for the creation of hypothetical wall types, and the easier interchange of wall facets. The new urban properties tool is available as part of the Toolbox for Human-Earth System Integration & Scaling (THESIS) tool set (http://www.cgd.ucar.edu/iam/projects/thesis/thesis-urbanproperties-tool.html; :ref:`Feddema and Kauffman (2016) `). The driver script (urban_prop.csh) specifies three input csv files (by default, mat_prop.csv, lam_spec.csv, and city_spec.csv; (:numref:`Figure schematic of THESIS urban properties tool`)) that describe the morphological, radiative, and thermal properties of urban areas, and generates a global dataset at 0.05° latitude by longitude in NetCDF format (urban_properties_data.05deg.nc). A standalone NCL routine (gen_data_clm.ncl) can be run separately after the mksurfdata_esmf tool creates the CLM surface dataset. This creates a supplementary streams file of setpoints for the maximum interior building temperature at yearly time resolution. .. Figure 12.1. Schematic representation of the urban land unit diff --git a/doc/source/users_guide/running-PTCLM/adding-ptclm-site-data.rst b/doc/source/users_guide/running-PTCLM/adding-ptclm-site-data.rst index d085c2f689..b95831427f 100644 --- a/doc/source/users_guide/running-PTCLM/adding-ptclm-site-data.rst +++ b/doc/source/users_guide/running-PTCLM/adding-ptclm-site-data.rst @@ -38,7 +38,7 @@ There is a mechanism for giving site-specific land-use change in PTCLMmkdata. Ad trans_year,pft_f1,pft_c1,pft_f2,pft_c2,pft_f3,pft_c3,pft_f4,pft_c4,pft_f5,pft_c5,har_vh1,har_vh2,har_sh1,har_sh2,har_sh3,graze,hold_harv,hold_graze -This file only requires a line for each year where a transition or harvest happens. As in the "pftdata" file above "pft_f" refers to the fraction and "pft_c" refers to the PFT index, and only up to five vegetation types are allowed to co-exist. The last eight columns have to do with harvesting and grazing. The last two columns are whether to hold harvesting and/or grazing constant until the next transition year and will just be either 1 or 0. This file will be converted by the **PTCLM_sitedata/cnvrt_trnsyrs2_pftdyntxtfile.pl** script in the PTCLMmkdata directory to a format that **mksurfdata_map** can read that has an entry for each year for the range of years valid for the compset in question. +This file only requires a line for each year where a transition or harvest happens. As in the "pftdata" file above "pft_f" refers to the fraction and "pft_c" refers to the PFT index, and only up to five vegetation types are allowed to co-exist. The last eight columns have to do with harvesting and grazing. The last two columns are whether to hold harvesting and/or grazing constant until the next transition year and will just be either 1 or 0. This file will be converted by the **PTCLM_sitedata/cnvrt_trnsyrs2_pftdyntxtfile.pl** script in the PTCLMmkdata directory to a format that **mksurfdata_esmf** can read that has an entry for each year for the range of years valid for the compset in question. .. _converting-ameriflux-for-ptclmmkdata: diff --git a/doc/source/users_guide/running-single-points/running-single-point-configurations.rst b/doc/source/users_guide/running-single-points/running-single-point-configurations.rst index 8588da8b99..9d2b68456b 100644 --- a/doc/source/users_guide/running-single-points/running-single-point-configurations.rst +++ b/doc/source/users_guide/running-single-points/running-single-point-configurations.rst @@ -152,7 +152,7 @@ Example: Creating a surface dataset for a single point > ./mknoocnmap.pl -p 40,255 -n $GRIDNAME # Set pointer to MAPFILE just created that will be used later > setenv MAPFILE `pwd`/map_${GRIDNAME}_noocean_to_${GRIDNAME}_nomask_aave_da_${CDATE}.nc - # create the mapping files needed by mksurfdata_map. + # create the mapping files needed by mksurfdata_esmf. > cd ../.././mkmapdata > setenv GRIDFILE ../mkmapgrids/SCRIPgrid_${GRIDNAME}_nomask_${CDATE}.nc > ./mkmapdata.sh -r $GRIDNAME -f $GRIDFILE -t regional @@ -167,7 +167,7 @@ Example: Creating a surface dataset for a single point # Save the location where the domain file was created > setenv GENDOM_PATH `pwd` # Finally create the surface dataset - > cd ../../../../lnd/clm/tools/|version|/mksurfdata_map/src + > cd ../../../../lnd/clm/tools/|version|/mksurfdata_esmf/src > gmake > cd .. > ./mksurfdata.pl -r usrspec -usr_gname $GRIDNAME -usr_gdate $CDATE @@ -186,7 +186,7 @@ Example: Setting up a case from the single-point surface dataset just created > ./link_dirtree $CSMDATA $MYCSMDATA # Copy the file you created above to your new $MYCSMDATA location following the CLMUSRDAT # naming convention (leave off the creation date) - > cp $CESMROOT/$CTSMROOT/tools/mksurfdata_map/surfdata_${GRIDNAME}_simyr1850_$CDATE.nc \ + > cp $CESMROOT/$CTSMROOT/tools/mksurfdata_esmf/surfdata_${GRIDNAME}_simyr1850_$CDATE.nc \ $MYCSMDATA/lnd/clm2/surfdata_map/surfdata_${GRIDNAME}_simyr1850.nc > cd $CESMROOT/scripts > ./create_newcase -case my_usernldatasets_test -res CLM_USRDAT -compset I1850Clm50BgcCropCru \ diff --git a/doc/source/users_guide/running-special-cases/Running-with-irrigation.rst b/doc/source/users_guide/running-special-cases/Running-with-irrigation.rst index 12fa76af5b..f19b489731 100644 --- a/doc/source/users_guide/running-special-cases/Running-with-irrigation.rst +++ b/doc/source/users_guide/running-special-cases/Running-with-irrigation.rst @@ -6,7 +6,7 @@ Running with irrigation =================================== -In CLM4.0 irrigation isn't an allowed option. In CLM4.5 irrigation can ONLY be used WITH crop. With CLM5.0 irrigation can be used whether crop is on or not -- **BUT** if crop is off, your surface datasets **HAVE** to have irrigation defined appropriately. Right now *ALL* surface datasets without crop enabled have irrigation hard-wired on. In order to create datasets with irrigation off, you'd need to make changes to ``mksurfdata_map`` in order to have all generic crops to be non-irrigated. To turn on irrigation in |version| we simply add "-irrig on" to ``CLM_BLDNML_OPTS``. +In CLM4.0 irrigation isn't an allowed option. In CLM4.5 irrigation can ONLY be used WITH crop. With CLM5.0 irrigation can be used whether crop is on or not -- **BUT** if crop is off, your surface datasets **HAVE** to have irrigation defined appropriately. Right now *ALL* surface datasets without crop enabled have irrigation hard-wired on. In order to create datasets with irrigation off, you'd need to make changes to ``mksurfdata_esmf`` in order to have all generic crops to be non-irrigated. To turn on irrigation in |version| we simply add "-irrig on" to ``CLM_BLDNML_OPTS``. Example: Irrigation Simulation ------------------------------------------ diff --git a/doc/source/users_guide/using-clm-tools/building-the-clm-tools.rst b/doc/source/users_guide/using-clm-tools/building-the-clm-tools.rst index 09725c8afc..95e0333d6d 100644 --- a/doc/source/users_guide/using-clm-tools/building-the-clm-tools.rst +++ b/doc/source/users_guide/using-clm-tools/building-the-clm-tools.rst @@ -6,15 +6,15 @@ The CLM FORTRAN tools all have similar makefiles, and similar options for building. The tools **cprnc** and **gen_domain** use the CIME configure/build system which is described in the next section. -The Makefiles (for **mksurfdata_map** and **mkprocdata_map**) use GNU Make extensions and thus require that you use GNU make to use them. They also auto detect the type of platform you are on, using "uname -s" and set the compiler, compiler flags and such accordingly. There are also environment variables that can be set to set things that must be customized. All the tools use NetCDF and hence require the path to the NetCDF libraries and include files. On some platforms (such as Linux) multiple compilers can be used, and hence there are env variables that can be set to change the FORTRAN and/or "C" compilers used. The tools also allow finer control, by also allowing the user to add compiler flags they choose, for both FORTRAN and "C", as well as picking the compiler, linker and and add linker options. Finally the tools allow you to turn optimization on (which is off by default but on for **mksurfdata_map**) with the OPT flag so that the tool will run faster. +The Makefiles (for **mksurfdata_esmf** and **mkprocdata_map**) use GNU Make extensions and thus require that you use GNU make to use them. They also auto detect the type of platform you are on, using "uname -s" and set the compiler, compiler flags and such accordingly. There are also environment variables that can be set to set things that must be customized. All the tools use NetCDF and hence require the path to the NetCDF libraries and include files. On some platforms (such as Linux) multiple compilers can be used, and hence there are env variables that can be set to change the FORTRAN and/or "C" compilers used. The tools also allow finer control, by also allowing the user to add compiler flags they choose, for both FORTRAN and "C", as well as picking the compiler, linker and and add linker options. Finally the tools allow you to turn optimization on (which is off by default but on for **mksurfdata_esmf**) with the OPT flag so that the tool will run faster. -Options used by all: **mksurfdata_map** +Options used by all: **mksurfdata_esmf** - ``LIB_NETCDF`` -- sets the location of the NetCDF library. - ``INC_NETCDF`` -- sets the location of the NetCDF include files. - ``USER_FC`` -- sets the name of the FORTRAN compiler. -Options used by: **mkprocdata_map**, and **mksurfdata_map** +Options used by: **mkprocdata_map**, and **mksurfdata_esmf** - ``MOD_NETCDF`` -- sets the location of the NetCDF FORTRAN module. - ``USER_LINKER`` -- sets the name of the linker to use. @@ -69,7 +69,7 @@ More details on each environment variable. .. warning:: Note, that depending on the compiler answers may be different when SMP is activated. ``OPT`` - This variable flags if compiler optimization should be used when compiling the tool. It can be set to either ``TRUE`` or ``FALSE``, by default it is set to for both **mksurfdata_map** and **mkprocdata_map**. Turning this on should make the tool run much faster. + This variable flags if compiler optimization should be used when compiling the tool. It can be set to either ``TRUE`` or ``FALSE``, by default it is set to for both **mksurfdata_esmf** and **mkprocdata_map**. Turning this on should make the tool run much faster. .. warning:: Note, you should expect that answers will be different when ``OPT`` is activated. diff --git a/doc/source/users_guide/using-clm-tools/creating-input-for-surface-dataset-generation.rst b/doc/source/users_guide/using-clm-tools/creating-input-for-surface-dataset-generation.rst index 276394e2b9..a727631a6c 100644 --- a/doc/source/users_guide/using-clm-tools/creating-input-for-surface-dataset-generation.rst +++ b/doc/source/users_guide/using-clm-tools/creating-input-for-surface-dataset-generation.rst @@ -40,12 +40,12 @@ If you want to create a regular latitude/longitude single-point or regional grid See :numref:`Figure mknoocnmap.pl` for a visual representation of this process. -Creating mapping files for mksurfdata_map +Creating mapping files for mksurfdata_esmf ============================================== ``mkmapdata.sh`` uses the above SCRIP grid input files to create SCRIP mapping data files (uses ESMF). -The bash shell script ``$CTSMROOT/tools/mkmapgrids/mkmapdata.sh`` uses ``ESMF_RegridWeightGen`` to create a list of maps from the raw datasets that are input to ``mksurfdata_map``. Each dataset that has a different grid, or land-mask needs a different mapping file for it, but many different raw datasets share the same grid/land-mask as other files. Hence, there doesn't need to be a different mapping file for EACH raw dataset---just for each raw dataset that has a DIFFERENT grid or land-mask. See :numref:`Figure mkmapdata.sh` for a visual representation of how this works. The bash script figures out which mapping files it needs to create and then runs ``ESMF_RegridWeightGen`` for each one. You can then either enter the datasets into the XML database (see Chapter :numref:`adding-new-resolutions-section`), or leave the files in place and use the ``-res usrspec -usr_gname -usr_gdate`` options to ``mksurfdata_map``. ``mkmapdata.sh`` has a help option with the following +The bash shell script ``$CTSMROOT/tools/mkmapgrids/mkmapdata.sh`` uses ``ESMF_RegridWeightGen`` to create a list of maps from the raw datasets that are input to ``mksurfdata_esmf``. Each dataset that has a different grid, or land-mask needs a different mapping file for it, but many different raw datasets share the same grid/land-mask as other files. Hence, there doesn't need to be a different mapping file for EACH raw dataset---just for each raw dataset that has a DIFFERENT grid or land-mask. See :numref:`Figure mkmapdata.sh` for a visual representation of how this works. The bash script figures out which mapping files it needs to create and then runs ``ESMF_RegridWeightGen`` for each one. You can then either enter the datasets into the XML database (see Chapter :numref:`adding-new-resolutions-section`), or leave the files in place and use the ``-res usrspec -usr_gname -usr_gdate`` options to ``mksurfdata_esmf``. ``mkmapdata.sh`` has a help option with the following :: ../../tools/mkmapdata/mkmapdata.sh @@ -104,4 +104,4 @@ The bash shell script ``$CTSMROOT/tools/mkmapgrids/mkmapdata.sh`` uses ``ESMF_Re Details of running mkmapdata.sh -Each of the raw datasets for ``mksurfdata_map`` needs a mapping file to map from the output grid you are running on to the grid and land-mask for that dataset. This is what ``mkmapdata.sh`` does. To create the mapping files you need a SCRIP grid file to correspond with each resolution and land mask that you have a raw data file in ``mksurfdata_map``. Some raw datasets share the same grid and land mask -- hence they can share the same SCRIP grid file. The output maps created here go into ``mksurfdata_map`` see :numref:`Figure Workflow of CLM5 Land Use Data Tool and Mksurfdata_map Tool`. +Each of the raw datasets for ``mksurfdata_esmf`` needs a mapping file to map from the output grid you are running on to the grid and land-mask for that dataset. This is what ``mkmapdata.sh`` does. To create the mapping files you need a SCRIP grid file to correspond with each resolution and land mask that you have a raw data file in ``mksurfdata_esmf``. Some raw datasets share the same grid and land mask -- hence they can share the same SCRIP grid file. The output maps created here go into ``mksurfdata_esmf`` see :numref:`Figure Workflow of CLM5 Land Use Data Tool and mksurfdata_esmf Tool`. diff --git a/doc/source/users_guide/using-clm-tools/creating-surface-datasets.rst b/doc/source/users_guide/using-clm-tools/creating-surface-datasets.rst index cfaa8527cd..d2e2ef7c89 100644 --- a/doc/source/users_guide/using-clm-tools/creating-surface-datasets.rst +++ b/doc/source/users_guide/using-clm-tools/creating-surface-datasets.rst @@ -14,7 +14,7 @@ When just creating a replacement file for an existing one, the relevant tool sho Data Flow for Creation of Surface Datasets from Raw SCRIP Grid Files -Starting from a SCRIP grid file that describes the grid you will run the model on, you first run ```mkmapdata.sh`` to create a list of mapping files. See :numref:`Figure mkmapdata.sh` for a more detailed view of how ``mkmapdata.sh`` works. The mapping files tell ``mksurfdata_map`` how to map between the output grid and the raw datasets that it uses as input. The output of ``mksurfdata_map`` is a surface dataset that you then use for running the model. See :numref:`Figure Workflow of CLM5 Land Use Data Tool and Mksurfdata_map Tool` for a more detailed view of how ``mksurfdata_map`` works. +Starting from a SCRIP grid file that describes the grid you will run the model on, you first run ```mkmapdata.sh`` to create a list of mapping files. See :numref:`Figure mkmapdata.sh` for a more detailed view of how ``mkmapdata.sh`` works. The mapping files tell ``mksurfdata_esmf`` how to map between the output grid and the raw datasets that it uses as input. The output of ``mksurfdata_esmf`` is a surface dataset that you then use for running the model. See :numref:`Figure Workflow of CLM5 Land Use Data Tool and mksurfdata_esmf Tool` for a more detailed view of how ``mksurfdata_esmf`` works. :numref:`Figure Data_Flow_Legend` is the legend for this figure (:numref:`Figure Data_Flow`) and other figures in this chapter (:numref:`Figure Global-Domain` and :numref:`Figure mknoocnmap.pl`). @@ -26,7 +26,7 @@ Starting from a SCRIP grid file that describes the grid you will run the model o Green arrows define the input to a program, while red arrows define the output. Cylinders define files that are either created by a program or used as input for a program. Boxes are programs. -You start with a description of a SCRIP grid file for your output grid file and then create mapping files from the raw datasets to it. Once, the mapping files are created **mksurfdata_map** is run to create the surface dataset to run the model. +You start with a description of a SCRIP grid file for your output grid file and then create mapping files from the raw datasets to it. Once, the mapping files are created **mksurfdata_esmf** is run to create the surface dataset to run the model. Creating a Complete Set of Files for Input to CLM ------------------------------------------------- @@ -39,13 +39,13 @@ Creating a Complete Set of Files for Input to CLM Next use gen_domain to create a domain file for use by DATM and CLM. This is required, unless a domain file was already created. See the Section called Creating a domain file for CLM and DATM for more information on this. -3. Create mapping files for mksurfdata_map (if NOT already done) +3. Create mapping files for mksurfdata_esmf (if NOT already done) - Create mapping files for mksurfdata_map with mkmapdata.sh in $CTSMROOT/tools/mkmapdata. See the Section called Creating mapping files that mksurfdata_map will use for more information on this. + Create mapping files for mksurfdata_esmf with mkmapdata.sh in $CTSMROOT/tools/mkmapdata. See the Section called Creating mapping files that mksurfdata_esmf will use for more information on this. 4. Create surface datasets - Next use mksurfdata_map to create a surface dataset, using the mapping datasets created on the previous step as input. There is a version for either clm4_0 or |version| for this program. See the Section called Using mksurfdata_map to create surface datasets from grid datasets for more information on this. + Next use mksurfdata_esmf to create a surface dataset, using the mapping datasets created on the previous step as input. There is a version for either clm4_0 or |version| for this program. See the Section called Using mksurfdata_esmf to create surface datasets from grid datasets for more information on this. 5. Enter the new datasets into the build-namelist XML database The last optional thing to do is to enter the new datasets into the build-namelist XML database. See Chapter 3 for more information on doing this. This is optional because the user may enter these files into their namelists manually. The advantage of entering them into the database is so that they automatically come up when you create new cases. diff --git a/doc/source/users_guide/using-clm-tools/observational-sites-datasets.rst b/doc/source/users_guide/using-clm-tools/observational-sites-datasets.rst index 385ec159aa..50a7969281 100644 --- a/doc/source/users_guide/using-clm-tools/observational-sites-datasets.rst +++ b/doc/source/users_guide/using-clm-tools/observational-sites-datasets.rst @@ -6,6 +6,6 @@ Observational Sites Datasets ******************************* -There are two ways to customize datasets for a particular observational site. The first is to customize the input to the tools that create the dataset, and the second is to overwrite the default data after you've created a given dataset. Depending on the tool it might be easier to do it one way or the other. In Table :numref:`reqd-files-table` we list the files that are most likely to be customized and the way they might be customized. Of those files, the ones you are most likely to customize are: ``fatmlndfrc``, ``fsurdat``, ``faerdep`` (for DATM), and ``stream_fldfilename_ndep``. Note ``mksurfdata_map`` as documented previously has options to overwrite the vegetation and soil types. For more information on this also see :ref:`creating-your-own-singlepoint-dataset`. ``PTCLM`` uses these methods to customize datasets; see Chapter :numref:`running-PTCLM`. +There are two ways to customize datasets for a particular observational site. The first is to customize the input to the tools that create the dataset, and the second is to overwrite the default data after you've created a given dataset. Depending on the tool it might be easier to do it one way or the other. In Table :numref:`reqd-files-table` we list the files that are most likely to be customized and the way they might be customized. Of those files, the ones you are most likely to customize are: ``fatmlndfrc``, ``fsurdat``, ``faerdep`` (for DATM), and ``stream_fldfilename_ndep``. Note ``mksurfdata_esmf`` as documented previously has options to overwrite the vegetation and soil types. For more information on this also see :ref:`creating-your-own-singlepoint-dataset`. ``PTCLM`` uses these methods to customize datasets; see Chapter :numref:`running-PTCLM`. Another aspect of customizing your input datasets is customizing the input atmospheric forcing datasets; see :ref:`creating-your-own-singlepoint-dataset` for more information on this. :ref:`converting-ameriflux-for-ptclmmkdata` has information on using the AmeriFlux tower site data as atmospheric forcing. diff --git a/doc/source/users_guide/using-clm-tools/what-are-the-clm-tools.rst b/doc/source/users_guide/using-clm-tools/what-are-the-clm-tools.rst index 6921e4dafd..664e23a220 100644 --- a/doc/source/users_guide/using-clm-tools/what-are-the-clm-tools.rst +++ b/doc/source/users_guide/using-clm-tools/what-are-the-clm-tools.rst @@ -16,7 +16,7 @@ The list of generally important scripts and programs are as follows. #. *./mkmapdata* to create SCRIP mapping data file from SCRIP grid files (uses ESMF). -#. *mksurfdata_map* to create surface datasets from grid datasets (clm4_0 and |version| versions). +#. *mksurfdata_esmf* to create surface datasets from grid datasets (clm4_0 and |version| versions). #. *./mkprocdata_map* to interpolate output unstructured grids (such as the CAM HOMME dy-core "ne" grids like ne30np4) into a 2D regular lat/long grid format that can be plotted easily. Can be used by either clm4_0 or |version|. @@ -26,7 +26,7 @@ The list of generally important scripts and programs are as follows. In the sections to come we will go into detailed description of how to use each of these tools in turn. First, however we will discuss the common environment variables and options that are used by all of the FORTRAN tools. Second, we go over the outline of the entire file creation process for all input files needed by CLM for a new resolution, then we turn to each tool. In the last section we will discuss how to customize files for particular observational sites. -The FORTRAN tools (mksurfdata_map and mkprocdata_map) run, with a namelist (mksurfdata_map) to provide options, or with command line arguments (mkprocdata_map). +The FORTRAN tools (mksurfdata_esmf and mkprocdata_map) run, with a namelist (mksurfdata_esmf) to provide options, or with command line arguments (mkprocdata_map). In the following sections, we will outline how to make these files available for build-namelist so that you can easily create simulations that include them. In the chapter on single-point and regional datasets we also give an alternative way to enter new datasets without having to edit files. @@ -34,12 +34,12 @@ In the following sections, we will outline how to make these files available for Running FORTRAN tools with namelists ------------------------------------ -**mksurfdata_map** runs with a namelist that is read from standard input. Hence, you create a namelist and then run them by redirecting the namelist file into standard input as follows: +**mksurfdata_esmf** runs with a namelist that is read from standard input. Hence, you create a namelist and then run them by redirecting the namelist file into standard input as follows: :: ./program < namelist -There is a sample namelist called ``$CTSMROOT/tools/mksurfdata_map/mksurfdata_map.namleist`` that shows you what the namelist should look like. **mksurfdata_map** also has a script that creates the namelist and runs the program for you. Namelists that you create should be similar to the example namelist. The namelist values are also documented along with the other namelists in the: +There is a sample namelist called ``$CTSMROOT/tools/mksurfdata_esmf/mksurfdata_esmf.namleist`` that shows you what the namelist should look like. **mksurfdata_esmf** also has a script that creates the namelist and runs the program for you. Namelists that you create should be similar to the example namelist. The namelist values are also documented along with the other namelists in the: :: $CTSMROOT/bld/namelist_files/namelist_definition.xml`` file From 91a4906605ab18649655843aa1c12dccae13bb2c Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 10 Apr 2024 14:00:40 -0600 Subject: [PATCH 582/614] remove some no longer needed mksurfdata_map settings --- .gitignore | 1 - .../namelist_definition_ctsm.xml | 203 ------------------ 2 files changed, 204 deletions(-) diff --git a/.gitignore b/.gitignore index 5885db2237..9cd97ae20e 100644 --- a/.gitignore +++ b/.gitignore @@ -95,7 +95,6 @@ ctsm.input_data_list.previous /tools/mksurfdata_esmf/mksurfdata_jobscript_single /tools/mksurfdata_esmf/pio_iotype.txt /tools/mksurfdata_esmf/*.sh -/tools/mksurfdata_esmf/mksrf_*.o* /tools/mksurfdata_esmf/tool_bld /tools/mksurfdata_esmf/pio_iotype.txt diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index cfa06dd6f3..73f933d3f6 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -1374,209 +1374,6 @@ Toggle to turn on the dynamic root model Toggle to turn on on diagnostic Snow Radiative Effect - - - - -Output of "git describe" to give the tag/commit the version being used corresponds to - - - -Filename for mksurfdata_map to remap raw data into the output surface dataset - - - -Plant Function Type dataset for mksurfdata - - - -Harvest dataset for mksurfdata - - - -Dataset for percent glacier land-unit for mksurfdata - - - -Dataset for glacier region ID for mksurfdata - - - -Dataset for topography used to define urban threshold - - - -Leaf Area Index dataset for mksurfdata - - - -Soil texture dataset for mksurfdata - - - -Soil color dataset for mksurfdata - - - -Soil max fraction dataset for mksurfdata - - - -High resolution land mask/fraction dataset for mksurfdata -(used for glacier_mec land-units) - - - -Type of grid to create for mksurfdata - - - -Grid file at the output resolution for mksurfdata - - - -Text file with filepaths (or list of XML elements) for vegetation fractions -and harvesting for each year to run over for mksurfdata to be able to model -transient land-use change - - - -High resolution topography dataset for mksurfdata -(used for glacier_mec land-units) - - - -Irrigation dataset for mksurfdata - - - -Organic soil dataset for mksurfdata - - - -Lake water dataset for mksurfdata - - - -Wetland dataset for mksurfdata - - - -Urban dataset for mksurfdata - - - -Biogenic Volatile Organic Compounds (VOC) emissions dataset for mksurfdata - - - -GDP dataset for mksurfdata - - - -Peat dataset for mksurfdata - - - -Soil depth dataset for mksurfdata - - - -Agricultural burning dominant month dataset for mksurfdata - - - -Topography statistics dataset for mksurfdata - - - -VIC parameters dataset for mksurfdata - - - -If TRUE, output variables in double precision for mksurfdata - - - -If TRUE, ignore other files, and set the output percentage to 100% urban and -zero for other land-use types. - - - -If TRUE, set wetland to 0% over land (renormalizing other landcover types as needed); -wetland will only be used for ocean points. - - - -Number of Plant Functional Types (excluding bare-soil) - - - -Plant Function Type index to override global file with for mksurfdata - - - -Plant Function Type fraction to override global file with for mksurfdata - - - -Soil color index to override global file with for mksurfdata - - - -Soil maximum fraction to override global file with for mksurfdata - - - -Soil percent sand to override global file with for mksurfdata - - - -Soil percent clay to override global file with for mksurfdata - - - From c9f13bd4e56efb92d6e10d1050882c4c7d28a587 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 10 Apr 2024 14:24:04 -0600 Subject: [PATCH 583/614] Remove comments about mksurfdata_map --- tools/README | 8 +++++--- tools/README.filecopies | 15 ++++----------- tools/mkprocdata_map/src/Makefile | 4 ++-- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/tools/README b/tools/README index 78a2cccb09..7fc72f04fb 100644 --- a/tools/README +++ b/tools/README @@ -59,7 +59,7 @@ II. Notes on building/running for each of the above tools: so that you can use the debugger, and with bounds-checking, and float trapping on. To speed up do the following... - gmake OPT=TRUE (by default already on for mksurfdata_map) + gmake OPT=TRUE Also some of the tools allow for OpenMP shared memory parallelism (such as mksurfdata) with @@ -78,8 +78,10 @@ II. Notes on building/running for each of the above tools: mksurfdata_esmf has a cime configure and CMake based build using the following files: - CMakeLists.txt -- Tells CMake how to build the source code - Makefile -------- GNU makefile to link the program together + gen_mksurfdata_build.sh - Build mksurfdata_esmf + src/CMakeLists.txt ------ Tells CMake how to build the source code + Makefile ---------------- GNU makefile to link the program together + cmake ------------------- CMake macros for finding libraries mkmapgrids, and site_and_regional only contain scripts so don't have the above build files. diff --git a/tools/README.filecopies b/tools/README.filecopies index 5ab2bc96d1..a96dff1ab7 100644 --- a/tools/README.filecopies +++ b/tools/README.filecopies @@ -1,27 +1,20 @@ tools/README.filecopies May/26/2011 There are several files that are copies of the original files from -either CTSM src/main, cime/src/share/utils, -cime/src/share/unit_test_stubs, or copies from other tool -directories. By having copies the tools can all be made stand-alone, +either CTSM src/utils or src/main, or share/src. +By having copies the tools can all be made stand-alone, but any changes to the originals will have to be put into the tool directories as well. I. Files that are IDENTICAL: - 1. csm_share files copied that should be identical to cime/share/utils: + 1. csm_share files copied that should be identical to share/src: shr_kind_mod.F90 shr_const_mod.F90 - shr_log_mod.F90 - shr_timer_mod.F90 shr_string_mod.F90 shr_file_mod.F90 - 2. csm_share files copied that should be identical to cime/share/csm_share/unit_testers: - - test_mod.F90 - II. Files with differences 1. csm_share files copied with differences: @@ -32,7 +25,7 @@ II. Files with differences fileutils.F90 --- Remove use of masterproc and spmdMod and endrun in abortutils. - 3. Files in mksurfdata_map + 3. Files in mksurfdata_esmf mkvarpar.F90 nanMod.F90 diff --git a/tools/mkprocdata_map/src/Makefile b/tools/mkprocdata_map/src/Makefile index 6f07deb741..42f797b3c2 100644 --- a/tools/mkprocdata_map/src/Makefile +++ b/tools/mkprocdata_map/src/Makefile @@ -1,4 +1,4 @@ -# Makefile for mksurfdata_map +# Makefile for mkprocdata_map EXENAME = ../mkprocdata_map @@ -7,4 +7,4 @@ ifeq ($(OPT),$(null)) OPT := TRUE endif -include Makefile.common \ No newline at end of file +include Makefile.common From 146d44adfe1e2f89438409c63eaead66509bf86b Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 10 Apr 2024 17:36:12 -0600 Subject: [PATCH 584/614] Updates to ChangeLog from @slevis-lmwg review, and a few additions from going through issues --- doc/ChangeLog | 28 +++++++++++++++++++++------- doc/ChangeSum | 2 +- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index 58e46cbb4a..337445490e 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm5.2.0 -Originator(s): erik (Erik Kluzek) -Date: Wed Apr 3 01:17:18 MDT 2024 +Originator(s): many (see below) +Date: Wed Apr 10 17:35:36 MDT 2024 One-line Summary: New surface datasets and new mksurfdata_esmf tool to create them Purpose and description of changes @@ -26,9 +26,9 @@ on coastal areas was also done. The following fields were added and removed to the list of fields on the datasets. Fields added: - ORGC, BULK, CFRAG, PHAQ (soil data) + ORGC, BULK, CFRAG, PHAQ (soil data) (currently NOT used by CTSM) mapunits (map units for the soil dataset) - LANDFRAC_MKSURFDATA + LANDFRAC_MKSURFDATA (for reference NOT used by CTSM) PCT_OCEAN (previously PCT_WETLAND was used) Fields removed: @@ -70,7 +70,8 @@ New lake datasets: HydroLake: Messager et. al. (2016) Contributors ------------ -@mvertens @ekluzek @jedwards4b @billsacks @wwieder @lawrencepj1 @negin513 @dlawrenncar @olyson +@mvertens @ekluzek @slevis-lmwg @jedwards4b @billsacks @wwieder @lawrencepj1 @negin513 @dlawrenncar @olyson +@keerzhang1 @fang-bowen @Face2sea @adamrher @samsrabin Significant changes to scientifically-supported configurations -------------------------------------------------------------- @@ -103,8 +104,11 @@ CTSM issues fixed (include CTSM Issue #): the landuse.timeseries file is made Fixes #2218 CTSM5.2 branch dies weirdly when clm5.0/ctsm5.1 datasets are used -- die with an error - Fixes #2278 Allow CTSM to output history files interpolated to a regular - grid (for example from SE unstructured grids to a FV grid) + Fixes #1483 hcru surface datasets + Fixes #2228 sys test requirements for mksurfdata_esmf + Fixes #90 Remove need for fatmgrid + Fixes #80 Improve modularity of mksurfdata_map + Fixes #1878 Convert wetlands to bare-ground Notes of particular relevance for users --------------------------------------- @@ -113,6 +117,16 @@ Caveats for users (e.g., need to interpolate initial conditions): These surface datasets can NOT be used in previous versions of the model Older surface datasets can NOT be used with this model version + IMPORTANT NOTE FOR USERS FOR REGIONAL CASES: + Because of this issue: + + https://github.com/ESCOMP/CTSM/issues/2430 + + We recommend that users use subset_data to subset your region from a global + grid. This could mean creating a global grid at the resolution you need (if + not standard) and then use subset_data on it to get the region of + interest. + Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): New CLM_PHYSICS_VERSION option of clm6_0 added (use it rather than clm5_1) New compsets for Clm60 added diff --git a/doc/ChangeSum b/doc/ChangeSum index c027721724..a62eeeac91 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm5.2.0 multiple 04/03/2024 New mksurfdata_esmf tool to create new surface datasets that are in place + ctsm5.2.0 many 04/10/2024 New mksurfdata_esmf tool to create new surface datasets that are in place ctsm5.1.dev175 slevis 03/21/2024 merge-b4bdev-20240321 ctsm5.1.dev174 olyson 03/14/2024 Improve vegetation health at high latitudes ctsm5.1.dev173 rgknox 03/13/2024 New FATES namelist variable: fates_history_dimlevel From 5b1ee03f5c8b1af4cd5ab19f3674ba33f7e2c0b2 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 10 Apr 2024 18:13:12 -0600 Subject: [PATCH 585/614] Add cam7.0 LND_TUNING options --- cime_config/config_component.xml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index c9f9e2d0ec..41fc8f737d 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -66,7 +66,10 @@ Atm forcing options: CRUv7 GSWP3 + CAM4.0 + CAM5.0 CAM6.0 + CAM7.0 QIAN (not tuned) 1PT (not tuned) NLDAS2 (not tuned) @@ -74,8 +77,8 @@ Other atm forcing options are invalid to run CLM and will result in an error. UNSET - - clm5_0_cam6.0,clm5_0_GSWP3v1,clm5_0_CRUv7,clm5_0_QIAN,clm5_0_1PT,clm5_0_NLDAS2,clm5_0_ERA5,clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_QIAN,clm4_5_cam6.0,clm4_5_1PT,clm4_5_NLDAS2,clm4_5_ERA5,clm5_1_CRUv7,clm5_1_GSWP3v1,clm5_1_cam6.0,clm5_1_QIAN,clm5_1_1PT,clm5_1_NLDAS2,clm5_1_ERA5,clm6_0_CRUv7,clm6_0_GSWP3v1,clm6_0_cam6.0,clm6_0_QIAN,clm6_0_1PT,clm6_0_NLDAS2,clm6_0_ERA5 + + clm5_0_cam6.0,clm5_0_cam7.0,clm5_0_GSWP3v1,clm5_0_CRUv7,clm5_0_QIAN,clm5_0_1PT,clm5_0_NLDAS2,clm5_0_ERA5,clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_QIAN,clm4_5_cam6.0,clm4_5_cam7.0,clm4_5_1PT,clm4_5_NLDAS2,clm4_5_ERA5,clm5_1_CRUv7,clm5_1_GSWP3v1,clm5_1_cam6.0,clm5_1_QIAN,clm5_1_1PT,clm5_1_NLDAS2,clm5_1_ERA5,clm6_0_CRUv7,clm6_0_GSWP3v1,clm6_0_cam6.0,clm6_0_cam7.0,clm6_0_QIAN,clm6_0_1PT,clm6_0_NLDAS2,clm6_0_ERA5 @@ -84,6 +87,7 @@ clm4_5_CRUv7 clm4_5_GSWP3v1 clm4_5_cam6.0 + clm4_5_cam7.0 clm4_5_cam6.0 clm4_5_QIAN clm4_5_QIAN @@ -96,6 +100,7 @@ clm5_0_GSWP3v1 clm5_0_GSWP3v1 clm5_0_cam6.0 + clm5_0_cam7.0 clm5_0_cam6.0 clm5_0_QIAN clm5_0_QIAN @@ -113,6 +118,7 @@ clm6_0_GSWP3v1 clm6_0_GSWP3v1 clm6_0_cam6.0 + clm6_0_cam7.0 clm6_0_cam6.0 clm6_0_QIAN clm6_0_QIAN From 705d0c76adce8268ef1fdfaf9020dff92ed3f2e5 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 10 Apr 2024 18:26:15 -0600 Subject: [PATCH 586/614] make default gen_mksurfdata generated scripts have a .sh extension --- .gitignore | 4 ++-- cime_config/SystemTests/mksurfdataesmf.py | 4 ++-- python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py | 2 +- python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py | 2 +- tools/README | 4 ++-- tools/mksurfdata_esmf/README.md | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 9cd97ae20e..1da8072fed 100644 --- a/.gitignore +++ b/.gitignore @@ -91,8 +91,8 @@ ctsm.input_data_list.previous /tools/mksurfdata_esmf/mksurfdata_in /tools/mksurfdata_esmf/surfdata_*.nc /tools/mksurfdata_esmf/landuse.timeseries_*.nc -/tools/mksurfdata_esmf/mksurfdata_jobscript_multi -/tools/mksurfdata_esmf/mksurfdata_jobscript_single +/tools/mksurfdata_esmf/mksurfdata_jobscript_multi.sh +/tools/mksurfdata_esmf/mksurfdata_jobscript_single.sh /tools/mksurfdata_esmf/pio_iotype.txt /tools/mksurfdata_esmf/*.sh /tools/mksurfdata_esmf/tool_bld diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 301141f02a..f5de3c4592 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -35,7 +35,7 @@ def __init__(self, case): time_stamp = datetime.today().strftime("%y%m%d") self._res = "10x15" # see important comment in script's docstring self._model_yr = "1850" - self._jobscript = os.path.join(self._get_caseroot(), "mksurfdata_jobscript_single") + self._jobscript = os.path.join(self._get_caseroot(), "mksurfdata_jobscript_single.sh") self._fsurdat_namelist = os.path.join( self._get_caseroot(), f"surfdata_{self._res}_hist_{self._model_yr}_78pfts_c{time_stamp}.namelist", @@ -62,7 +62,7 @@ def build_phase(self, sharedlib_only=False, model_only=False): # Paths and strings build_script_path = os.path.join(self._tool_path, "gen_mksurfdata_build.sh") nml_script_path = os.path.join(self._tool_path, "gen_mksurfdata_namelist") - gen_jobscript_path = os.path.join(self._tool_path, "gen_mksurfdata_jobscript_single") + gen_jobscript_path = os.path.join(self._tool_path, "gen_mksurfdata_jobscript_single.sh") gen_mksurfdata_namelist = f"{nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}" gen_mksurfdata_jobscript = f"{gen_jobscript_path} --number-of-nodes 1 --tasks-per-node 64 --namelist-file {self._fsurdat_namelist} --bld-path {self._tool_bld}" diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py index d0ad313867..6deb50ebfb 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_multi.py @@ -66,7 +66,7 @@ def get_parser(): """ Get parser object for this script. """ - parser = base_get_parser(default_js_name="mksurfdata_jobscript_multi") + parser = base_get_parser(default_js_name="mksurfdata_jobscript_multi.sh") parser.add_argument( "--scenario", diff --git a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py index a04265ba84..ff793165d9 100755 --- a/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/toolchain/gen_mksurfdata_jobscript_single.py @@ -20,7 +20,7 @@ logger = logging.getLogger(__name__) -def base_get_parser(default_js_name="mksurfdata_jobscript_single"): +def base_get_parser(default_js_name="mksurfdata_jobscript_single.sh"): """ Get parser object for the gen_mksurfdata_jobscript scripts """ diff --git a/tools/README b/tools/README index 7fc72f04fb..70a2807214 100644 --- a/tools/README +++ b/tools/README @@ -198,7 +198,7 @@ III. Process sequence to create input datasets needed to run CTSM gridnames. 5.) Create surface datasets with mksurfdata_esmf on Derecho - (See mksurfdata_esmf/README for more help on doing this) + (See mksurfdata_esmf/README.md for more help on doing this) - gen_mksurfdata_build.sh to build - gen_mksurfdata_namelist to build the namelist @@ -216,7 +216,7 @@ III. Process sequence to create input datasets needed to run CTSM ./gen_mksurfdata_build.sh ./gen_mksurfdata_namelist --res 0.9x1.25 --start-year 1850 --end-year 1850 ./gen_mksurfdata_jobscript_single --number-of-nodes 24 --tasks-per-node 12 --namelist-file target.namelist - qsub mksurfdata_jobscript_single + qsub mksurfdata_jobscript_single.sh NOTE that surface dataset will be used by default for fatmgrid - and it will contain the lat,lon,edges and area values for the atm grid - ASSUMING that diff --git a/tools/mksurfdata_esmf/README.md b/tools/mksurfdata_esmf/README.md index 3c551d0388..a748c3d721 100644 --- a/tools/mksurfdata_esmf/README.md +++ b/tools/mksurfdata_esmf/README.md @@ -153,7 +153,7 @@ for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: ``` shell # Assuming pwd is the tools/mksurfdata_esmf directory ./gen_mksurfdata_jobscript_single --number-of-nodes 2 --tasks-per-node 128 --namelist-file target.namelist - qsub mksurfdata_jobscript_single + qsub mksurfdata_jobscript_single.sh ``` Read note about regional grids at the end. @@ -167,7 +167,7 @@ for example try --res 1.9x2.5 --start-year 1850 --end-year 1850: ``` shell # Assuming pwd is the tools/mksurfdata_esmf directory ./gen_mksurfdata_jobscript_multi --number-of-nodes 2 --scenario global-present - qsub mksurfdata_jobscript_multi + qsub mksurfdata_jobscript_multi.sh ``` If you are looking to generate all (or a large number of) the datasets or the From 9b5ef2221876e9e5e4a7781d0da1be6672588d5c Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 10 Apr 2024 18:31:51 -0600 Subject: [PATCH 587/614] Remove the .sh exention from gen_mksurfdata_build.sh as one of the parts of #2446 --- cime_config/SystemTests/mksurfdataesmf.py | 2 +- .../test/test_unit_gen_mksurfdata_jobscript_single.py | 2 +- tools/README | 6 +++--- tools/mksurfdata_esmf/README.md | 2 +- tools/mksurfdata_esmf/gen_mksurfdata_build.sh | 8 ++++---- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index f5de3c4592..03295201ac 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -60,7 +60,7 @@ def build_phase(self, sharedlib_only=False, model_only=False): # if the test stops and gets restarted. if sharedlib_only: # Paths and strings - build_script_path = os.path.join(self._tool_path, "gen_mksurfdata_build.sh") + build_script_path = os.path.join(self._tool_path, "gen_mksurfdata_build") nml_script_path = os.path.join(self._tool_path, "gen_mksurfdata_namelist") gen_jobscript_path = os.path.join(self._tool_path, "gen_mksurfdata_jobscript_single.sh") gen_mksurfdata_namelist = f"{nml_script_path} --res {self._res} --start-year {self._model_yr} --end-year {self._model_yr}" diff --git a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py index f09d91ccce..5038c6b3e1 100755 --- a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py +++ b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py @@ -151,7 +151,7 @@ def test_derecho_mpirun(self): self.assertEqual(self._account, args.account) # Create the env_mach_specific.xml file needed for get_mpirun # This will catch problems with our usage of CIME objects - # Doing this here will also catch potential issues in the gen_mksurfdata_build.sh script + # Doing this here will also catch potential issues in the gen_mksurfdata_build script configure_path = os.path.join(path_to_cime(), "CIME", "scripts", "configure") self.assertTrue(os.path.exists(configure_path)) options = " --macros-format CMake --silent --compiler intel --machine " + machine diff --git a/tools/README b/tools/README index 70a2807214..568dc1239b 100644 --- a/tools/README +++ b/tools/README @@ -78,7 +78,7 @@ II. Notes on building/running for each of the above tools: mksurfdata_esmf has a cime configure and CMake based build using the following files: - gen_mksurfdata_build.sh - Build mksurfdata_esmf + gen_mksurfdata_build ---- Build mksurfdata_esmf src/CMakeLists.txt ------ Tells CMake how to build the source code Makefile ---------------- GNU makefile to link the program together cmake ------------------- CMake macros for finding libraries @@ -200,7 +200,7 @@ III. Process sequence to create input datasets needed to run CTSM 5.) Create surface datasets with mksurfdata_esmf on Derecho (See mksurfdata_esmf/README.md for more help on doing this) - - gen_mksurfdata_build.sh to build + - gen_mksurfdata_build to build - gen_mksurfdata_namelist to build the namelist - gen_mksurfdata_jobscript_single to build a batch script to run on Derecho - Submit the batch script just created above @@ -213,7 +213,7 @@ III. Process sequence to create input datasets needed to run CTSM Example: for 0.9x1.25 resolution fro 1850 cd mksurfdata_esmf - ./gen_mksurfdata_build.sh + ./gen_mksurfdata_build ./gen_mksurfdata_namelist --res 0.9x1.25 --start-year 1850 --end-year 1850 ./gen_mksurfdata_jobscript_single --number-of-nodes 24 --tasks-per-node 12 --namelist-file target.namelist qsub mksurfdata_jobscript_single.sh diff --git a/tools/mksurfdata_esmf/README.md b/tools/mksurfdata_esmf/README.md index a748c3d721..11cb69c681 100644 --- a/tools/mksurfdata_esmf/README.md +++ b/tools/mksurfdata_esmf/README.md @@ -100,7 +100,7 @@ This will bring in CIME and ccs_config which are required for building. ``` shell # Assuming pwd is the tools/mksurfdata_esmf directory - ./gen_mksurfdata_build.sh # For machines with a cime build + ./gen_mksurfdata_build # For machines with a cime build ``` Note: The pio_iotype value gets set and written to a simple .txt file diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh index c8b891c1c4..974c1929a5 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build.sh +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build.sh @@ -6,7 +6,7 @@ usage() { echo "" echo "***********************************************************************" echo "usage:" - echo "./gen_mksurfdata_build.sh" + echo "./gen_mksurfdata_build" echo "" echo "valid arguments: " echo "[-h|--help] " @@ -14,14 +14,14 @@ usage() { echo "[-v|--verbose] " echo " Run in verbose mode" echo "[-b|--blddir ] " - echo " Overrides default, which is /tool_bld in the same directory as ./gen_mksurfdata_build.sh" + echo " Overrides default, which is /tool_bld in the same directory as ./gen_mksurfdata_build" echo "[-m|--machine ] " echo " Overrides default MACH" echo "***********************************************************************" } -# Current working directory: the location of ./gen_mksurfdata_build.sh +# Current working directory: the location of ./gen_mksurfdata_build cwd=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) # Default settings @@ -102,7 +102,7 @@ cd $blddir # Write pio_iotype to file with name pio_iotype.txt pio_iotype_filepath=../pio_iotype.txt # one up from /tool_bld if [ ! -f "$pio_iotype_filepath" ]; then - echo 'VALUE OF pio_iotype WRITTEN BY gen_mksurfdata_build.sh AND USED BY mksurfdata (i.e. THE FORTRAN EXECUTABLE):' > $pio_iotype_filepath + echo 'VALUE OF pio_iotype WRITTEN BY gen_mksurfdata_build AND USED BY mksurfdata (i.e. THE FORTRAN EXECUTABLE):' > $pio_iotype_filepath echo $pio_iotype >> $pio_iotype_filepath else echo "Use existing $pio_iotype_filepath file" From 6bfb9af0f65f6079d0d186de1fcef58da6803451 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 10 Apr 2024 22:12:37 -0600 Subject: [PATCH 588/614] Remove mkmapdata and mksurfdata from the template file --- bld/namelist_files/namelist_definition.xsl | 23 ---------------------- 1 file changed, 23 deletions(-) diff --git a/bld/namelist_files/namelist_definition.xsl b/bld/namelist_files/namelist_definition.xsl index 545d810e52..7917cc262f 100644 --- a/bld/namelist_files/namelist_definition.xsl +++ b/bld/namelist_files/namelist_definition.xsl @@ -252,18 +252,6 @@

      These are namelist items that appear in the CLM Tools under components/clm/tools.

      - - - - - - - - - - -
      CLM mksurfdata
      NameTypeDescription
      Valid values
      - @@ -276,17 +264,6 @@
      CLM mkgriddata
      Name
      - - - - - - - - - - -
      CLM mkmapdata
      NameTypeDescription
      Valid values
      From 7cd7f8081c9fdfe53c6da3a0208e1773d6fc1dae Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 12 Apr 2024 15:47:52 -0600 Subject: [PATCH 589/614] Update doc/ChangeLog From @slevis-lmwg suggestion. Co-authored-by: Samuel Levis --- doc/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index af1a74b43a..56f1ef9d19 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -27,7 +27,7 @@ The following fields were added and removed to the list of fields on the dataset Fields added: ORGC, BULK, CFRAG, PHAQ (soil data) (currently NOT used by CTSM) - mapunits (map units for the soil dataset) + mapunits (map units from the soil dataset) LANDFRAC_MKSURFDATA (for reference NOT used by CTSM) PCT_OCEAN (previously PCT_WETLAND was used) From babd28124af7fc7ff3c27a946bde1be42a535b84 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 12 Apr 2024 17:13:42 -0600 Subject: [PATCH 590/614] Get namelist working Update namelist with needed cam4.0, cam5.0, and clm6_0 changes so that the namelist tester works and compares as expected to the previous version. --- bld/namelist_files/namelist_defaults_ctsm.xml | 30 +++++++++++++++++-- .../namelist_defaults_overall.xml | 2 ++ bld/unit_testers/build-namelist_test.pl | 4 +-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index ab6b5772aa..ae38b758cf 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -245,10 +245,22 @@ attributes from the config_cache.xml file (with keys converted to upper-case). >30.0d00 20.0d00 +20.0d00 +20.0d00 20.0d00 +20.0d00 +20.0d00 20.0d00 +20.0d00 +20.0d00 80.0d00 0.85d00 0.98d00 @@ -260,10 +272,22 @@ attributes from the config_cache.xml file (with keys converted to upper-case). >0.010d00 0.008d00 +0.008d00 +0.008d00 0.008d00 +0.008d00 +0.008d00 0.008d00 +0.008d00 +0.008d00 0.17d-3 1.6d-4 0.33d00 @@ -642,7 +666,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). - + .true. .false. .false. .false. +.false. +.false. -.false. +.false. + + + + FAIL + MOSART#91 + + + From 6926f4b84e8179a1adea9987d702678ac6e50217 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 19 Apr 2024 11:02:46 -0600 Subject: [PATCH 607/614] Add more notes about the testlists --- cime_config/testdefs/testlist_clm.xml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index cdbe058890..05526b3529 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -1,14 +1,15 @@ From 78b22676464a843f35f9049fffddb87b4e3af182 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 19 Apr 2024 12:52:11 -0600 Subject: [PATCH 608/614] More expected fails because of long filenames --- cime_config/testdefs/ExpectedTestFails.xml | 25 ++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index 108ed50065..9c5339f2d5 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -154,8 +154,29 @@ #2454 - - + + + + FAIL + #2310 + + + FAIL + #2310 + + + + + + FAIL + #2310 + + + FAIL + #2310 + + + From 1c99a7bead49ffdb8c03c4f4171f6c4474b745c7 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 19 Apr 2024 19:32:33 -0600 Subject: [PATCH 609/614] Update the README files --- README | 58 +++++++++---------- README.CHECKLIST.new_case | 2 + README.NUOPC_driver.md | 11 +--- README.md | 12 +++- README_EXTERNALS.rst | 5 ++ .../namelist_definition_ctsm.xml | 3 +- doc/.ChangeLog_template | 12 ++-- doc/.release-ChangeLog_template | 5 -- doc/ChangeLog | 10 ++-- doc/IMPORTANT_NOTES | 39 +++++++++---- doc/Quickstart.GUIDE | 16 ++--- 11 files changed, 92 insertions(+), 81 deletions(-) diff --git a/README b/README index 3df6868d40..18cc2b1458 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ -$CTSMROOT/README 06/08/2018 +$CTSMROOT/README 04/19/2023 -Community Terrestrial Systems Model (CTSM) science version 5.1 series -- source code, tools, +Community Terrestrial Systems Model (CTSM) science version 5.2 series -- source code, tools, offline-build and test scripts. This gives you everything you need to run CTSM with CESM with the CMEPS driver and CDEPS data models to provide CRU NCEP or GSWP3 forcing data in place of a modeled atmosphere. @@ -35,23 +35,29 @@ this checkout. For a CESM checkout $CIMEROOT will be the "cime" directory beneath the top level directory. For a CTSM checkout $CIMEROOT will be $CTSMROOT/cime. +IMPORTANT NOTE ABOUT (deprecated) + +Anything marked with (deprecated) is something is going to be removed in a future update. +Often this means it will be replaced with something else. + + General directory structure ($CTSMROOT): doc --------------- Documentation of CTSM. -bld --------------- Template, configure and build-namelist scripts for clm. +bld --------------- build-namelist scripts for CTSM. src --------------- CTSM Source code. lilac ------------- Lightweight Infrastructure for Land-Atmosphere Coupling (for coupling to a host atmosphere model) -test -------------- CTSM Testing scripts for CTSM offline tools. +test -------------- CTSM Testing scripts for CTSM offline tools (deprecated) tools ------------- CTSM Offline tools to prepare input datasets and process output. cime_config ------- Configuration files of cime for compsets and CTSM settings -manage_externals -- Script to manage the external source directories +manage_externals -- Script to manage the external source directories (deprecated) py_env_create ----- Script to setup the python environment for CTSM python tools using conda -python ------------ Some python modules mostly for use by run_sys_tests (but could be used elsewhere l +python ------------ Python modules used in tools and testing and automated checking of ALL CTSM python scirpts Directory structure only for a CTSM checkout: components -------- Other active sub-components needed for CTSM to run (river routing and land-ice models) -libraries --------- CESM libraries: MCT (Model Coupling Toolkit) and PIO +libraries --------- CESM libraries: MCT (Model Coupling Toolkit) and PIO (deprecated) share ------------- CESM shared code ccs_config -------- CIME configure files (for grids, compsets, and machines) for CESM @@ -59,17 +65,17 @@ cime/scripts --------------- cesm/cime driver scripts components/cmeps -------------------- CESM top level driver (for NUOPC driver [which is the default]) source code. components/cdeps -------------------- CESM top level data model shared code (for NUOPC driver). -cime/src/externals ------------------ CESM external utility codes (genf90) components/cism --------------------- CESM Community land Ice Sheet Model. components/mosart ------------------- Model for Scale Adaptive River Transport components/rtm ---------------------- CESM River Transport Model. -components/cpl7 --------------------- CESM top level driver for MCT driver (being deprecated) +components/cpl7 --------------------- CESM top level driver for MCT driver (deprecated will be removed) Top level documentation ($CTSMROOT): README ------------------- This file +README.md ---------------- File that displays on github under https::/github.com/ESCOMP/CTSM.git README.rst --------------- File that displays under the project in github -README_EXTERNALS.rst ----- Information on how to work with subversion externals for clm +README_EXTERNALS.rst ----- Information on how to work with manage_externals for CTSM (deprecated) CODE_OF_CONDUCT.md ------- Code of Conduct for how to work with each other on the CTSM project Copyright ---------------- CESM Copyright file doc/UpdateChangeLog.pl --- Script to add documentation on a tag to the @@ -93,7 +99,7 @@ bld/namelist_files/namelist_defaults_ctsm.xml ----- Default values Important files in main directories (under $CTSMROOT): ============================================================================================= -Externals.cfg --------------- File for management of the main high level externals +Externals.cfg --------------- File for management of the main high level external (deprecated) Externals_CLM.cfg ----------- File for management of the CTSM specific externals (i.e. FATES) run_sys_tests --------------- Python script to send the standard CTSM testing off (submits @@ -104,18 +110,15 @@ parse_cime.cs.status -------- Script to parse test status files cs.status.* crea (can be used along with run_sys_tests) doc/Quickstart.GUIDE -------- Quick guide to using NUOPC scripts. doc/IMPORTANT_NOTES --------- Some important notes about this version of - clm, configuration modes and namelist items + CTSM, configuration modes and namelist items that are not validated or functional. doc/ChangeLog --------------- Detailed list of changes for each model version. doc/ChangeSum --------------- Summary one-line list of changes for each model version. -doc/README ------------------ Documentation similar to this file doc/UsersGuide -------------- CTSM Users Guide doc/IMPORTANT_NOTES --------- Some important notes on caveats for some configurations/namelist items -bld/README ------------------ Description of how to use the configure and - build-namelist scripts. -bld/configure --------------- Script to prepare CTSM to be built. +bld/README ------------------ Description of how to use the build-namelist scripts. bld/build-namelist ---------- Script to build CTSM namelists. cime_config/buildnml ------------- Build the CTSM namelist for CIME @@ -128,22 +131,15 @@ cime_config/testdefs ------------- Directory for specification of CTSM testing cime_config/testdefs/ExpectedTestFails.xml -- List of tests that are expected to fail cime_config/usermods_dirs -------- Directories of sets of user-modification subdirs (These are directories that add specific user modifications to - simulations created using "cime/scripts/create_newcase --user-mods-dir". - Current sub directories are for various CMIP6 configurations) - -test/tools/test_driver.sh -- Script for general software testing of - CTSM's offline tools. + simulations created using "cime/scripts/create_newcase --user-mods-dir".) tools/mksurfdata_esmf --------- Directory to build program to create surface dataset at any resolution. tools/mkprocdata_map ---------- Process history data from unstructed grids to a gridded format. -tools/mkmapgrids -------------- NCL script to create a SCRIP grid file for a regular lat/lon grid -tools/modify_fsurdat ---------- Script to modify existing surface datasets in standard ways -tools/ncl_scripts ------------ Directory of NCL and perl scripts to do various - tasks. Most notably to plot perturbation error growth - testing and to extract regional information from - global datasets for single-point/regional simulations. +tools/mkmapgrids -------------- NCL script to create a SCRIP grid file for a regular lat/lon grid (deprecated) +tools/crop_calendars ---------- Tools to process and process and create crop calendar datasets for CTSM +tools/modify_input_files ------ Script to modify existing CTSM input datasets in standard ways tools/site_and_regional ------- Scripts to create input datasets for single site and regional cases, primarily by modifying existing global datasets tools/contrib ----------------- Miscellansous useful scripts for pre and post processing @@ -166,6 +162,7 @@ scr/fates --------- FATES model and sub-directories Functionally Assembled Terrestrial Ecosystem Simulator (FATES) Experimental Ecosystem Demography model src/utils --------- Utility codes +src/self_tests ---- Internal testing (unit tests run as a part of a CTSM simulation) src/unit_test_shr - Unit test shared modules for unit testing src/unit_test_stubs Unit test stubs that replicate CTSM code simpler @@ -175,11 +172,10 @@ src/unit_test_stubs Unit test stubs that replicate CTSM code simpler cd $CIMEROOT/scripts ./create_newcase # get help on how to run create_newcase - ./create_newcase --case testI --res f19_g17_gl4 --compset I2000Clm50BgcCrop + ./create_newcase --case testI --res f19_g17_gl4 --compset I2000Clm60BgcCrop # create new "I" case for default machine at 1.9x2.5_gx1v7 - # with 4km greenland ice sheetres resolution - # "I2000Clm50BgcCrop" case is clm5_0 active, datm8, and inactive ice/ocn - # With no-evolve ice-sheet, and MOSART for river-routing + # "I2000Clm60BgcCrop" case is clm6_0 physics, CDEPS, and inactive ice/ocn/glc + # and MOSART for river-routing cd testI ./case.setup # create the $CASE.run file ./case.build # build model and create namelists diff --git a/README.CHECKLIST.new_case b/README.CHECKLIST.new_case index d3b37bc7c3..71ba4a8284 100644 --- a/README.CHECKLIST.new_case +++ b/README.CHECKLIST.new_case @@ -22,6 +22,8 @@ General Checklist to always do: (./xmlquery LND_TUNING_MODE) - For an "I compset" make sure you are running over the right forcing years (usually ./xmlquery -p DATM_YR) + - Again for an "I compset" make sure the DATM streams are operating over the right years + (look at the CaseDocs/datm.streams.xml file) - First and align year for streams should be the start year of a historical simulation (./xmlquery RUN_STARTDATE) (grep stream_year_first CaseDocs/lnd_in; grep model_year_align CaseDocs/lnd_in) diff --git a/README.NUOPC_driver.md b/README.NUOPC_driver.md index 578ba4aa8d..ba0b70c2c0 100644 --- a/README.NUOPC_driver.md +++ b/README.NUOPC_driver.md @@ -41,15 +41,10 @@ nuopc.runseq is a text file that determines how the driver operates. You can cha by having an updated copy in your case directory. -## What if I want to use the previous MCT driver? - -The MCT driver will be available for sometime going forward, but -new development won't go into it, and it will eventually be removed. -But, if you have to... -Use the "--driver mct" command line option to create_newcase -You can set COMP_INTERFACE in a case as well, but it won't create it with everything needed -so we recommend setting up a case from scratch. +## What if I want to use the MCT driver? +The MCT driver is now deprecated, and will be removed. So at this point we don't +suggest using it anymore. For more notes see: diff --git a/README.md b/README.md index 9de22e3663..045af9f6a1 100644 --- a/README.md +++ b/README.md @@ -50,12 +50,18 @@ Software engineering team: - [Ryan Knox](https://github.com/rgknox) Science team: -- [Dave Lawrence](https://github.com/dlawrenncar) - [Will Wieder](https://github.com/wwieder) +- [Dave Lawrence](https://github.com/dlawrenncar) - [Danica Lombardozzi](https://github.com/danicalombardozzi) - [Keith Oleson](https://github.com/olyson) - [Sean Swenson](https://github.com/swensosc) -- [Jackie Shuman](https://github.com/jkshuman) - [Peter Lawrence](https://github.com/lawrencepj1) -- [Rosie Fisher](https://github.com/rosiealice) - Gordon Bonan + +FATES Project: +- https://github.com/NGEET/fates?tab=readme-ov-file + +Perturbed Parameter Experiment (PPE) Science team: +- [Katie Dagon] (https://github.com/katiedagon) +- [Daniel Kennedy] (https://github.com/djk2120) +- [Linnea Hawkins] (https://github.com/linniahawkins) \ No newline at end of file diff --git a/README_EXTERNALS.rst b/README_EXTERNALS.rst index 47632f3111..ed7a068991 100644 --- a/README_EXTERNALS.rst +++ b/README_EXTERNALS.rst @@ -1,6 +1,11 @@ Obtaining the full model code and associated scripting infrastructure ===================================================================== +[!CAUTION] +This is deprecated and will be replaced with git submodules. See +https://github.com/ESCOMP/CTSM/pull/2443 + + CTSM is released via GitHub. You will need some familiarity with git in order to modify the code and commit these changes. However, to simply checkout and run the code, no git knowledge is required other than what is documented in the following steps. diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 3e3a5170dc..99b3163450 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -171,7 +171,7 @@ dust optics type for SNICAR snow albedo calculation snow grain shape used in SNICAR snow albedo calculation -(snicar_dust_optics='hexagonal_plate' is supported in ctsm5.1 and 'sphere' in older model versions; others are EXPERIMENTAL, UNSUPPORTED, and UNTESTED!) +(snicar_snw_shape='hexagonal_plate' is supported in ctsm5.1 and 'sphere' in older model versions; others are EXPERIMENTAL, UNSUPPORTED, and UNTESTED!) Toggle to turn on use of LAI streams in place of the LAI on the surface dataset when using Satellite Phenology mode. -(EXPERIMENTAL, UNSUPPORTED, and UNTESTED!) --mach cheyenne --res f09_g16_gl4 -compset I2000Clm50BgcCrop + ./create_newcase --case --mach derecho --res f09_g16_gl4 -compset I2000Clm60BgcCrop (./create_newcase -help -- to get help on the script) # Setup the case @@ -39,8 +39,8 @@ Process: Information on Compsets: - "I" compsets are the ones with clm and NUOPC driver and CDEPS data models without ice and ocean. - Most of the "I" compsets for CLM5.0 use the GSWP3v1 data with solar following + "I" compsets are the ones with CTSM and NUOPC driver and CDEPS data models without ice and ocean. + Most of the "I" compsets for ctsm5.0 physics and use the GSWP3v1 data with solar following the cosine of solar zenith angle, precipitation constant, and other variables linear interpolated in time (and with appropriate time-stamps on the date). From 82b6a1c25407a5fd34abb5b4c61662636ff95c77 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 19 Apr 2024 19:43:02 -0600 Subject: [PATCH 610/614] More README and ChangeLog updates --- bld/namelist_files/use_cases/README | 4 +--- doc/.ChangeLog_template | 4 +++- doc/.release-ChangeLog_template | 21 ++++++++------------- doc/ChangeLog | 12 ++++++++---- doc/ChangeSum | 2 +- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/bld/namelist_files/use_cases/README b/bld/namelist_files/use_cases/README index e55fd9285b..f139759b57 100644 --- a/bld/namelist_files/use_cases/README +++ b/bld/namelist_files/use_cases/README @@ -2,9 +2,7 @@ $CTSMROOT/namelist_files/use_cases/README Jun/08/2018 Naming Convention for CLM use-cases -It's important that this naming convention be followed so that the PTCLMmkdata.py -utility can parse the use-cases appropriately. The build-namelist script also -checks for conformance with these conventions and won't work for names that +The build-namelist script checks for conformance with these conventions and won't work for names that don't follow the convention. Ending suffix requires one of these endings: _transient, _control or _pd diff --git a/doc/.ChangeLog_template b/doc/.ChangeLog_template index 57977b8899..d7ba696835 100644 --- a/doc/.ChangeLog_template +++ b/doc/.ChangeLog_template @@ -18,6 +18,8 @@ Does this tag change answers significantly for any of the following physics conf [Put an [X] in the box for any configuration with significant answer changes.] +[ ] clm6_0 + [ ] clm5_1 [ ] clm5_0 @@ -77,7 +79,7 @@ here is guidance on different available levels of system testing: d) regular (regular tests on normal machines if CTSM source is modified) e) release (regular tests plus the fates, ctsm_sci, mosart and rtm test lists and normally all of the ancillary tests (build-namelist, python, etc.) - would be run as well) + would be run as well) In addition, various other tests of the tools, python and namelist script infrastructure should be run when appropriate, as described below. diff --git a/doc/.release-ChangeLog_template b/doc/.release-ChangeLog_template index 6a06400506..73c9c99e35 100644 --- a/doc/.release-ChangeLog_template +++ b/doc/.release-ChangeLog_template @@ -32,36 +32,31 @@ Testing: build-namelist tests: - cheyenne - + derecho - unit-tests (components/clm/src): - cheyenne - - izumi ---- - - tools-tests (components/clm/test/tools): - - cheyenne - + derecho - izumi ---- regular tests (aux_clm): - cheyenne_intel ---- - cheyenne_gnu ------ + derecho_intel ---- + derecho_gnu ------ izumi_nag --------- izumi_pgi --------- izumi_intel ------- regular tests (prealpha): - cheyenne_intel - - cheyenne_gnu --- + derecho_intel - + derecho_gnu --- izumi_nag ------ regular tests (prebeta): - cheyenne_intel - - cheyenne_gnu --- + derecho_intel - + derecho_gnu --- izumi_nag ------ Summary of Answer changes: diff --git a/doc/ChangeLog b/doc/ChangeLog index 80467466cf..a850f2b8fb 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm5.2.0 Originator(s): many (see below) -Date: Wed Apr 10 17:35:36 MDT 2024 +Date: Fri 19 Apr 2024 07:15:10 PM MDT One-line Summary: New surface datasets and new mksurfdata_esmf tool to create them Purpose and description of changes @@ -14,6 +14,8 @@ All new surface datasets. Transient urban and lake by default turned on for tran Ocean is run as baresoil rather than wetland (for clm6_0). The urban streams file was also updated. The new surface datasets have new updated input datasets (see below). +Update the README files. + New surface datasets: ===================== @@ -81,6 +83,8 @@ Does this tag change answers significantly for any of the following physics conf [Put an [X] in the box for any configuration with significant answer changes.] +[x] clm6_0 (new) + [x] clm5_1 [x] clm5_0 @@ -173,7 +177,7 @@ Testing summary: regular ctsm_sci fates mosart rtm tools python fates tests: (give name of baseline if different from CTSM tagname, normally fates baselines are fates-sci.1.72.2_api.34.0.0-ctsm5.2.0) derecho ----- OK - izumi ------- OK (also ERS_D_Ld30.f45_f45_mg37.I2000Clm50FatesCruRsGs.izumi_nag.clm-FatesColdLandUse FAIL because of conda issues) + izumi ------- OK any other testing (give details below): @@ -185,9 +189,9 @@ Testing summary: regular ctsm_sci fates mosart rtm tools python mosart (mosart1_0_49_ctsm5.2.0) derecho ---- OK - izumi ------ (conda issues) + izumi ----- PASS -If the tag used for baseline comparisons was NOT the previous tag, note that here: ctsm5.1.dev175 +If the tag used for baseline comparisons was NOT the previous tag, note that here: ctsm5.1.dev176 Answer changes diff --git a/doc/ChangeSum b/doc/ChangeSum index bc0ba2036f..1bd8668bb6 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm5.2.0 many 04/10/2024 New mksurfdata_esmf tool to create new surface datasets that are in place + ctsm5.2.0 many 04/19/2024 New mksurfdata_esmf tool to create new surface datasets that are in place ctsm5.1.dev176 afoster 04/04/2024 Merge b4b-dev ctsm5.1.dev175 slevis 03/21/2024 merge-b4bdev-20240321 ctsm5.1.dev174 olyson 03/14/2024 Improve vegetation health at high latitudes From bf67eacc3b421f70e7ab27c7fd23790510ff71e0 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 19 Apr 2024 20:32:00 -0600 Subject: [PATCH 611/614] Also add this test to the RUN fail for #2373 --- cime_config/testdefs/ExpectedTestFails.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index 9c5339f2d5..fe6a54c221 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -187,6 +187,10 @@ + + FAIL + #2373 + FAIL FATES#701 From da0dba0b7d9ee8b6124a5e738c7e9fc559c06365 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sat, 20 Apr 2024 00:33:56 -0600 Subject: [PATCH 612/614] Update change files --- doc/ChangeLog | 16 ++++++++++++---- doc/ChangeSum | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index a850f2b8fb..ce1a4f4815 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm5.2.0 Originator(s): many (see below) -Date: Fri 19 Apr 2024 07:15:10 PM MDT +Date: Sat 20 Apr 2024 12:33:33 AM MDT One-line Summary: New surface datasets and new mksurfdata_esmf tool to create them Purpose and description of changes @@ -146,6 +146,11 @@ Changes to the datasets (e.g., parameter, surface or initial files): urbantv streams datasets updated Some initial condition datasets updated to go with the new datasets +Things being deprecated (which will be removed): + manage_externlas will be removed for git submodules + mkmapgrids and other NCL scripts + tools/test directory + Notes of particular relevance for developers: --------------------------------------------- @@ -175,13 +180,17 @@ Testing summary: regular ctsm_sci fates mosart rtm tools python derecho ----- OK izumi ------- OK - fates tests: (give name of baseline if different from CTSM tagname, normally fates baselines are fates-sci.1.72.2_api.34.0.0-ctsm5.2.0) + fates tests: (fates-sci.1.72.2_api.34.0.0-ctsm5.2.0) derecho ----- OK izumi ------- OK any other testing (give details below): - ctsm_sci + mksurfdata_esmf + derecho ---- run "make all" to create all datasets (completes in 2-6 hours) + (crop-global-SSP2-4.5-ne30 was longest at 6 hr, most completed in 3.5 hours) + + ctsm_sci (ctsm_sci-ctsm5.2.0) derecho ---- PASS rtm (rtm1_0_79_ctsm5.2.0) @@ -193,7 +202,6 @@ Testing summary: regular ctsm_sci fates mosart rtm tools python If the tag used for baseline comparisons was NOT the previous tag, note that here: ctsm5.1.dev176 - Answer changes -------------- diff --git a/doc/ChangeSum b/doc/ChangeSum index 1bd8668bb6..00b4277647 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm5.2.0 many 04/19/2024 New mksurfdata_esmf tool to create new surface datasets that are in place + ctsm5.2.0 many 04/20/2024 New mksurfdata_esmf tool to create new surface datasets that are in place ctsm5.1.dev176 afoster 04/04/2024 Merge b4b-dev ctsm5.1.dev175 slevis 03/21/2024 merge-b4bdev-20240321 ctsm5.1.dev174 olyson 03/14/2024 Improve vegetation health at high latitudes From 9c690578a3508c172736143ced049e1e4900e647 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 22 Apr 2024 12:24:05 -0600 Subject: [PATCH 613/614] Update rule for tags --- doc/UpdateChangelog.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/UpdateChangelog.pl b/doc/UpdateChangelog.pl index 67be182b8d..7191f2e857 100755 --- a/doc/UpdateChangelog.pl +++ b/doc/UpdateChangelog.pl @@ -41,7 +41,7 @@ sub usage { To document a new tag - $ProgName ctsm5.2.dev099 "Description of this tag" + $ProgName ctsm5.3.099 "Description of this tag" EOF } @@ -67,8 +67,8 @@ sub usage { $tag = $ARGV[0]; $sum = $ARGV[1]; - # Tags should be something like ctsm5.3.dev001 or ctsm5.3.0 - if ( ($tag !~ /ctsm[0-9]\.[0-9]\.(dev[0-9][0-9][0-9]|[0-9][0-9])/) && ($tag !~ /ctsm[0-9]\.([0-9])\.([0-9])/) ) { + # Tags should be something like ctsm5.3.001 or ctsm5.3.0 + if ( ($tag !~ /ctsm[0-9]\.[0-9]\.([0-9][0-9][0-9]|[0-9][0-9])/) && ($tag !~ /ctsm[0-9]\.([0-9])\.([0-9])/) ) { print "ERROR: bad tagname: $tag\n"; usage(); } From 69248747fa478599f8b2e4dcb9ee584f3f38fc7f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 22 Apr 2024 14:11:18 -0600 Subject: [PATCH 614/614] Change file update --- doc/ChangeLog | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++ doc/ChangeSum | 1 + 2 files changed, 104 insertions(+) diff --git a/doc/ChangeLog b/doc/ChangeLog index ce1a4f4815..671f5020de 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,107 @@ =============================================================== +Tag name: ctsm5.2.001 +Originator(s): erik (Erik Kluzek,UCAR/TSS,303-497-1326) +Date: Mon 22 Apr 2024 02:10:55 PM MDT +One-line Summary: Merge b4b-dev + +Purpose and description of changes +---------------------------------- + +Some fixes for run_neon that came up in ctsm5.1.dev172. +Small bug fix for units of vector format hillslope hydrology. +Start adding PLUMBER2 users-mods (NOT functional) + + +Significant changes to scientifically-supported configurations +-------------------------------------------------------------- + +Does this tag change answers significantly for any of the following physics configurations? +(Details of any changes will be given in the "Answer changes" section below.) + + [Put an [X] in the box for any configuration with significant answer changes.] + +[ ] clm6_0 + +[ ] clm5_1 + +[ ] clm5_0 + +[ ] ctsm5_0-nwp + +[ ] clm4_5 + + +Bugs fixed +---------- + +List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: + #2470 -- NEON case won't build + #2471 -- run_neon calendar issues + #2474 -- externals prevent creation of directory + #2414 -- Correct subset_data error checking + #2437 -- externals update broke NEON features + #2435 -- Issues with run_neon with the --experiment flag starting in ctsm5.1.dev172 + Partial for #2137 -- Create csv file and user-mod directories for PLUMBER2 sites + +Notes of particular relevance for users +--------------------------------------- + +Caveats for users (e.g., need to interpolate initial conditions): + NOTE: The new PLUMBER2 user-mods can NOT be used right now! + More changes need to happen before PLUMBER2 sites can be run + +Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): + New namelist item: lai_dtlimit (when use_lai_streams is on) + User-mod directories are coming in for: PLUMBER2 + +Notes of particular relevance for developers: +--------------------------------------------- +Caveats for developers (e.g., code that is duplicated that requires double maintenance): + Introduces some NCL scripts for PLUMBER2 that we need to convert to python + +Testing summary: regular +---------------- + + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + build-namelist tests (if CLMBuildNamelist.pm has changed): + + derecho - PASS + + python testing (if python code has changed; see instructions in python/README.md; document testing done): + + derecho - PASS + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + +If the tag used for baseline comparisons was NOT the previous tag, note that here: + + +Answer changes +-------------- + +Changes answers relative to baseline: No bit-for-bit + +Other details +------------- + +Pull Requests that document the changes (include PR ids): +(https://github.com/ESCOMP/ctsm/pull) + +@ekluzek @olyson @slevis-lmwg @TeaganKing @wwieder + +#2155 -- PLUMBER2 plumbing (csv file, wrapper script, usermods, and scripts). +#2477 -- One-line fix for izumi NEON-MOAB test error introduced in #2472 +#2472 -- B4b neon tag: simple bfb +#2475 -- fix units for vector hh output +#2435 -- experiment bug fix + + +=============================================================== +=============================================================== Tag name: ctsm5.2.0 Originator(s): many (see below) Date: Sat 20 Apr 2024 12:33:33 AM MDT diff --git a/doc/ChangeSum b/doc/ChangeSum index 00b4277647..2451783ec2 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ Tag Who Date Summary ============================================================================================================================ + ctsm5.2.001 erik 04/22/2024 Merge b4b-dev ctsm5.2.0 many 04/20/2024 New mksurfdata_esmf tool to create new surface datasets that are in place ctsm5.1.dev176 afoster 04/04/2024 Merge b4b-dev ctsm5.1.dev175 slevis 03/21/2024 merge-b4bdev-20240321
      CLM mkgriddata

      6djK-hvW!DC~V@jL*PfEuem6XIzk_& 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 YO=R~(3EC^G;SNu*jrd0kg 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

      KtVxUT6$@m(cGuqpuDT+G#%OUH2Yg=qteC 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 z zGvPs`MNMOl;U2-JE8~KdBbh?URY!sa>9st{X-wH{h2zK)7wsGlW{VX^+L*A630pnF zO-yL>2pgEt?h#&Pg5BX!K4MCz6-RzJ)SsD9r(8mhyD72tDsgc@EnIY=br>>?;5Dx;LRbb4Y6Kxt<0FnML7+x}6$eHg5V%}V;9`V!|0c9QrkoE7 zCXO!0<&4X$;(r8G6Mmn1hUDT!Hy3aiO7kS1D?!uZcQUbxGXYO6ZYI_siT^Yo z7~7Kj01P}^a@pzTlJ+a9_&Aq!znjZ8q{}LSr$BF0RrN?Q2wo-|gpdyoWYR`1p`t-7 zrJ$UGRD`f`%7h9KB->O};Mg4m>C#2vI56jWCg-Zm#TmvGE?&iWu#49*9yW|8K~;_no;h1GxO*6x1jamH7HHc5?tA$w@!48m6c(h(VQ z>NDXI5GYABf`)LskqPG#Gj5FalIJi*`0|g2InZ&7dn3p`k;bGge9YVQdSLQZv^j+wi6w;ncgLJtq1c4YnH*efjR{ zb(h*K9s z$q4R+5eYPcdzWAY_b$N*?p=Zr+`9xLxOWLga1R2;KZR(F;NE31f_s->1otk%2<}~i z5!|~3Be-`7MsR<0+!Vt$`xdh?p=Zr+`EKR(eUTtdB6?)S|Gj7 zJ^_;g6ZW@gRxwn>Uy0G?hBy>Z8h3wu?U=FG&RYTHvK25I{mt7SP*$%lTLIK7WG7%E z^EGJ^xhj{Pfa96!?F96)cisvpm#qLwgSS7R%4I9y9QN*Q1@zu|E5PcbcLK!!3=_T8 z`xiR_eRwATpae1Yz6euI{{V9+3IpyePs)vVhZw=n_nUwL5li(&5pYCkOF?@6`Izt0*lP8S?0OO?yu@z)^dS=!IBymVS|<|AB?P|5l!T-hYebH@z=SjO+^yk6+eTcRQX zsf8r3zX?K`f?YAeb&~e@i@N-cH0#W-nH%~4$(nQT?jySYx3vGiy4n4@WBp90nP3N$ zN^MtV8B$fG;tDL(|7(3!-2ZzVI<(H($l#k1m8B}$d|t36`zsR$U1+d5)31e-2jBf( z<6rgZNWYKx7w%N)_apyWgI{r80=MAT5dO6pzsB>gt?9_1VOZfz(;3XMD$c<2L$YQ6 zMs4a8bY@L>^|lGG(T-Hy<_7TJ{i9g>J%PBPHtmK)VM@vnrd{#b{}@z@8`Ng}nu_T> z*P6~Q1uuaj_=?e(mj2gjbH^2oC^RVUQE}=2?1g=pfnr3(XTRrB7bPsf?A)oOLUzNN zI}^6t=C_MF3Lgcu!$G_gxr>^i;XiLh>+!L1b9Fu9G#<9`X!6eX)n$|NR(#oMlk!Wv zyQwSBI~)xV>I+l(wWswjOcx<*%8#Hhd#nBK#}QPX7P|~G2Q_DN5)$i z(?d+zDKMK6XfH z;XOx^_yr_l#;_UZzYR}`Og0ZxXKEc8? zDGeOXeUew!0^iMAp?B4th|RfPVr$&p#P+V5gqS6^HH#%Sr_a|o#!A_|6REYr@A}$O z^Wt#yQ`Lg7UW6Owf2(!*eWJF3_$m_z8DhJ79mGE~ahM@~tlB_)n~5ny{75}@4RlhO zXx)Y|Y1tqBr+O95?jxbzE-}Tnv0(9ELL`MR;`~tMJpheVA(}ux^A*C@3$1*Ze{I0Z z5sd0ba4HZ;@pc#yLXa*Hfiz8z1_5GUO(8AQ#l%7i*2F?8s@D^thbEB5X)_TjG=Vf} zUnRn>nm~HEpA%uICXg;^-Z~KW(*)A>9YTZygDElku0@(cin{-yXlgZq zR9=TRgRo2!NUe1$5iZjN(nvgq2s8>&nURWXh6oLsgET#FB7&m{q~!S+5pH1uwu(qa z^bMlisaZ(l^HU~bPd%cpqnL>NPf@VMq6<=2Tscvcfg@AYgV zY}N!)dA(#k+Mjw&Q%JG(c4GO9CXi0+!&D;gX#(l$K1CecG=Y>l|4M|FbOEG;oCu5iR;&y|fB4$|ZNn&LGC(v$4OXGVQX@fLVO zj`6v`3IiPpIean>3L3|YZCA)K&t)Vbhm432a%etRJ5jEFd~6Q z$l(%^6y2ODib86k&of?$LkF2M*nT!N8Z+~Nk_Rdm5+4E=zvT8ucK zNLq~0-J_2RsWH;{4-8J99wSKLBsE4AWzHtEeg~QK7*!dQJ@EzncU5ErBPlZS0O1o~ zfJ~Z3FxBANC~*j3t)yx0Hw66A|n_{k5R|e=4X5#bWEf)35=x1sD^Xg znu_t4g6yit2u{*sRHK-))gR=qm*;q9^r?mZR&h>Y#wHVD5&A!u=P6A8e=pCu?BA0I zAxr;TaoYd?<++ICHl_SuiZjEEUU6E*p`2YvACzXZBv+6@kK{W%yDk>_PB8>I&ig;4 zQn{q#Sn^E1v-HQ*p3V_Jrs_u1+6&5zv@*hL0R~~bNN$8_#N`EMkwl|!*HtKYkCL@c z-H)ls&h(#BtJzkENd8CwCGO4LekX+FQ;0Dq`6B+ul7GSfNb(c>FG+lZ|Djg zIz^x1CfXxnB}DHvA$qR~R#CMB3DHqah~jEOR8d zHfut3TN9$xnh;IdglNhppdyP8c|tT~6Qb#w5EWNDAv&%J(MnB-R%$|2RTH9|n#ftf z{za)ZK^m_JO%z@eqVSp!P1l5Ix+X+nHX*922~k{4h&rk+4P}+7610m%4`n3_9^_)` z2TX9c2Ul(xS+R2M$nHf2)N#wyOzkpqBA|Wz4>Krzlqm^?fA?Fd#bjFvD=|JytQB-wH@>knm$weR5^XrOfZEXp=DjeyfE;2 zWEEim6B?Ot17aD*xM?15E79T+4G-%Y(nhU@e@47`Y@jG}`YH!+S|Elh*B}tVcQ9^d zd<)!1aG))W$tuD@z_fVGv2k4u@OZ{$;YeSVMBZ4Nts;yQ78Hq^23PFt8aR*P@Ypz2 zk6*+e4W6&(@v*V0$tA8iV-*)$Y>c|!B`z|YqiM!(vws}gott;Cn#&+|usRgkrf`Fm z+vfm2u02Cpf!G$z7QX#?8TbM!D_GfzvXo_@9NoYs90eeyMa!c;Kvry&dIn)p{X#8> zyx2vjxkWr1zs9(pNO_KnI5twf=z3~8FP2iIe@az_V~pp;MyNLdC-Y*oj#Kd(Fb;;$ z@d2u}zoFR)^s22Ja&aD|kZh~&m=illwZYSu;Kb^5e(XTC9dH1eCTwEPj~$@C20V^o z%L1#g$lH0NOezrE$tAT0Ran3qZ**`>y^oYBBY={&M1vD~vJrQ> zRDuSFnT5Ipv(x4h%p}w$m`SKhph>8`5&v9@nT5IpGYcIUGFhitsFWh@w3$4aoi^b^ z`phKMC74O5OOQz@rYQPLS1 zm&MFNU4of~?v`VUfo7q)jnfesQx0YlDvSu*OhR3PnS^Qrrq17?Z6_XuSk4W60+5vP z>G);BUVz`r@!aq7HM@KpeSELr_s4kNa{0md>cq2{v5vy z7ZFw(RB;2iHW)OVlr|P)+~T13J--Me+LZ>5tcD{E zNbGoEy&sK<_|bR=h{}gKCpH1CHlduo4(NVCLEJU{4B#UM-mG2&e8#{Q^^Og^+2A+T z$AGUJ_=9psb^2V8WKfEP#_7{dp1ffiOgyLDsanYIW$^18d$iBhAGHRS}8Ptokrpd|zd)y<4Y3X1{ zFc=;9A<$bW14c*eg)%!$$_zKq9tp%vmp&qoBM@e?C><`@H!4!08hX)tE<2U*(6r7qD8pG8JR zgF$y&c6=BRolGY;d%(a6fEO6n!83sB4ca3OIIg993aZo{U{s{g5F^T`2U6Fvzs3v|o!zZ7L?8se9d2@mpW zJT$x1rBlYaB_uJYaF!O092UD8B+N8a4C^n#EVKqbMB`TN?u4D9q$Nz>3X0#zSf{33sSg8 zG_nU&!~owjj+L&^8^m7K8J*(Rq~w*4%m|OBH+CSHiq8>eAmFX@VkKfK?K8o z*W{AK^IQWva<>ECU|>sR2Vge?H%Gn$eAz&|A*zt#9}V6b^^M=b0q;hO;i@}Ca6ntM z51?-5!2#Q%)D(u9QMf%yAB_nHZjZV(^V>~#gs=XHi%z}#PTNhYN4l9-8uJO)=7#6vL2W!Q~};Dta| z7^gf#N170Rb1X$PzcG{^YQpqV``g3buMDNTQ`i38vD8W`U0#F#H*QQ&bic)~^`#>x zp$Feq%q6~SAGPKp$}yMtb@=rHHF82TZU>5^)gr#6b6axcP^YzIWN-NO!b2!JhP@*14r525IhN#2}k7U!`So@5e|Ca&yPw zs2rG%OYzGZiYY&~#CIT7!5->t3}=P|lRf@ZpOTEq=^Z%wiYqSnwh^M2BD){(${FD4X%FMU2p2o*9nxQpHFdAKYr08IJZ+ z#HKEWJ7fhj4ZaN+iuy5o6mK(^!3(TW7y-pTe7b?c30B^Gc5H7JcMyyQ-@J1bXEU}J zi#vq4=1ff-&f*RsuGPf6VSEBfLfdq9Y#8r%3T&{?&KrtDrh@8c0xZy=VP=>L}wO|U?67{M3Eptau63J?0{enfPuycDhfUmKEr|$ z6&2Kn7*Nb$dZwq~dn(5F|5R0XPuQ7d*Z2LM^Ph8Ir>d(fb#>kDx_A0M1vRB@^OW?q zTpbbcNdl=lBH;EZnI}+ngrM{`TpgibP2thunKaw!)-*yD`3}_)q7f&eIuiCY1n5a` z&E=6?u4Sy_KC#u2KDLwfe0nRcj!2)CGt*l}RY#7@NN>T_k;%;Q5dU70sw4XT1+57` z!DS#D*$`KCPGvltWX3!(Bj`K_>#63B2MMO3_(DJ9?Z>5%W7AN4q2D6kz~I5@_^CDh z7Wq>tl$@8|#i3`ZgN5982C5yAx(S(2WfG~IApV>#SpGOU>5;-oo)-w3;#BozSMkHj z)YAhxdRUq3Cc-K`Qa51)_P(ZWayBtyPIUK9I8oh%If1TFK|Y-=vc?j|oGoJLOyNZM zp`)prScIvYScIvY2xoLLbrXx=x(PkEY%!*AViBfrViD%~YzCdMRP zHwk-$5DJ>YiA9*giA9*ZcNSslCKh4pCKh4pCKh4pCK`b%geja@5>q&_2vaz*2vaw) z2vaw)2vav1XDbYGcki?x@Z9hwtO4;)DB%ZFII##*II##*H+jr5kFA>+AMeHdIfQ>7 zS-RM|3Fr`i5NQf0NVz&*V+$vSp{a+^?{^c`Lkyj%hn!*QV(TG>ZhhXFvW6|Qgt3Jf zCNzbU{ZqMcf^=|bs;!$yTBEuN=MP;s$#>FK$FyMIFyHghRS~(dQ`iR6*e>l7P4U9P zmZBDtKwNR8yV+qgJlAuf(s zh>IiS1E%ES$bE(j7e^iy$P`DOHlP$oUMj%wqN}$lsw0rO-!w~cADV3>7f0x>H1p)*2!|(KC}N8v7X6QiE2&&# z@NvbFXN>f!xF~K#Z&}6`NAk1@;iyY%C8HKw92sitkLXi)rY(+OO2ijOa!f39al}S1 ziX(`>?xvB8BXrOm`;Utw>kP!j5weBbxHz)av~h9dkU*w5LT8GB)D%ZX8c>QOYYezC z%+-;qN4BoFQY6zpGb)lNLxHLXvZ;}@#FC4OBxac6_7aRPa^B6LJxPav)JSkgQ{`p_ zivv<3DRKren7#`N(Ot|gTu~`@ALIH+$FR&f{9Z#>M|jFH7#Tk@D7HG{A|Bb<5u(B@ z;AC!LkmIW(H=11#S4W;UP@^zaM?Nl%k>d4;>DAkeA3@Fu+o~EK9)scAyldT1#lk=UNfmwsv~*|nCgfHr8=VH+*C(SG<~HyGSq-l9XW37cCicc zDn@OQ^K>@V;EG-IcNtek5J_AYsb}gUn`zt#iVBf?fwSp1t}a4lBMvD}zf=}th_i1i z19A49Vj#}G%K*{lH5^wLv6CjM#+*Eh(z7ulFWMnVu2TuKXvIp0NuyC7D8loVQq{ne zN}P0KsMD#c(ZO4U1&JwdG<5Ib!bqoPToqw|Q&nUi1vf!l6{&}4#nTNnBHe^Vhm;}* z{doZ6{}ysFq+_e9q=X^|)Xb%lzllpAc3`M@p>re^H7q{11Y*&#B@l~F#HBXx;<@l~ zDiQLx<9&&gK;l*=b&dDe6$Tq7`|fruuK2!NxOF2_8_9Y~Y9kZyH`{rn zbwo0;^m8I4QNAa^N4=JulS_j;}T!YDP~R;9(B= zVX@hO_p#ln{?+;OX^{ z^B&+n?ZqoKv0|W);|n>HP>T@TE?drJ9b=oA)<&|aPBfyEbQ06nE%y%xm%G75Y}+VY z;%wX9D1mJu=Y62Xw$01^U{k*_*`~^C2TzEyYO}HGG`4C2h){M|L64)G-TW!^JcWZq z#n0mMSnxribhnl0%u^7vEnUoJ-jJEiJlN5%X3^2?=0yMyW;bsUW;ZXaL1A|D7QwrD zZ00S(Z00S(Z00Ru+l^SB(Nho>V|McvVRrL9ZG9p(7aN<*QxHN2{mf?GBFtvqB4{%o zrjtS~#_Z-T!tCZP!tCZP!tCZP!ffU(!ffU(!ffUVf!#lO8#PUO3c`|@-MmGZ-F#nL z)S%tGo>ue}gz7cLRDb{=H-g zmqZBnAVn~tC;J<;%QZTu;`a4DpH3sReGPl+Bad(-^ZxZL1M&W~BW5YT%tgK4E?5|j-LL~p<{1a^vZ>fWylm=cAYL}DHc-9uuw}f-Kw;jszHLC>wO)bj%Ug*s z8&ck!UM-N>oW5v4xpV(t1Ip&Kql}EXbAQ~h?Lo^~iBI`SIt>DCPNU*82O^TjXU(Q& zH>x+IW)z|~qpE)6V0Y&lb!OvWP;WeIILFka#=&A|*M{O?NToChb_w&msBO2JJTDlG z8M(NvCjFo$E<~~)2hQfG_^l=t>bL`MHD?*9QF<7wL&ni<%4w0F&!OF9%IMg;>^ADFl-GVW5+d40(ptxAr!`gBB6w2m z*zICe)>Cs@1bcc>t5%y^20N*Vp;E<{i%k{IHZ$TfxyuSAqUW+AfK zfU*#|$AGdB`MUvSA@YO)D_w{TC@3@`Y%{tIslrxqD~?OyfTS5ce#P;;@m3^Qv-bgK zr&ipGgPten$;4A@wt;wRtu_!(t!E6xQ|oO5$%-S-7{n`%XNojaUUBpnpHyMRK~uF# zQ*xV;p0*?_Di5Viq(xX&mm0rCm{j0VSUYy9aiXy=ZOMlA!J=^N6M@G}Yl3w}{aV@= zyskLQK)kM4XrKhkipxzKFDsrC$Sfxw5XWVo1;Et z*ApD|3`QcE)Qc@$e`X>rZHcfupCEl=_N(|~_r@le~OIaxdu z8}Qqq{21T=S-`1voy_7PWEKw>(a;bSiHq#3fwLJdZt?Je3?)uPr2B6FHV|jHbQw9k zu9lvXKFvU!;l=~{-xm)Z49|$RHq+Ov;^HAHQK>;)Dl8tNo3VH(Q6F>(u4%x_1$G)O z7q(Lj62$f7KkKXEErS=U>D{oxF#k4t9G0i?Dqeo#l(rSNct`q+z>va zF|rlEbmA)1L+IJHkMTF#85~x17DU!*H6P-7e#5F>!-MHfc+>v4MiRC_Mu1tb*m+$0xI_OAjHqegf8-? zCEMfNBw@fNBw@erge>erge>e!7Aym*fVjpXxIeseTGSwBs7ODWD1^{9p>G79j;x zb<#<}q0SrX>XU+V!}KHYd?}6;+<~BVOUI_=OEItJF2Ei~|0(zb5X$;EEq4$`B*k-W z6O%gHBZ4V)T!g>bPP2ZJI<{cLOrPd=a_ZQ#7v1YPZ{d%j@T082Bu+|wXCVUj5E|R) z?&rf^`Z&J&&V^`u8l-$@2Jj}p-+&hR1h-u3J9h)tr&8n2O?_uOVCQENSh{~jYJG?J z5`S;$eJj%1;4#s12DYt84Yzi(UN()JS9nr-up)JUyLFJ*F~KU*!+9G0B8v2Ih)+b3 z9?oZgBZ~A8MOuIvE7HRuzE+WeP$XEfFX(~a<(Wk3Iwdk*$(j~MZ)Zo8PP5|FHVtVtjJ7sm@#@F4@tx$%bW%f6!FM1 z_DDpLWzH!viYyaFN{u4RdN{<`y5#a`MJ|g~#1oJ(O=n~I2tqnvt#v>Soy?RoE03*6 z3rP3|q#T>hDp~S^2wfbbm=+oq+b109<5`C|Pw|}6)WrVPP@iJ|F#cvcd&UlA4-L~p zHFOKd{s-7SdvlzY`|u+>O@Y|wkCT$;bOwH(#=i!^^l^N7&P4Eax_;y7k6}HCz|M1K z5{948#<^~(dCmfY`=C3$JlvDg(m4a)Z#_$tSc*nwmDbW(g6}WirM~GEY`|xXVJ6|^ zt(L-IE;HCwX5du}?UM2 z>d)OE(laxhXDoKt)(v{fd$Q;NHe4fDq-D!UWy`o_(a{Zj0AJQr^yBmWa&E#moEOrm z8+pHFGxGi(p#F=0WKMtSS_d48XU$9;JQ zb)Rn$&n+T&i9a0#hP_)l#glTqaQD82JC>Sz56c~m^WZ>P@0{n4v+o>eGijjeeM+z}tKzWbkws6lMY=<(y7H7@ z-MWT1hr}PkYXf-o1g~c+;dO|4=?;itxpjKN6|iY@<4UlX~Dv?B7vb>ZD9C-Xs7vet_c9a0z3yuK<{+G5djo= z^F%-a+8drbQ04SPTCzUUjdW5zrHORFrZ>mHwbHpUI*&M4#;ubbH{EENY51*Cni=32 zX63@H{Q+e6)fKquR?AJpbw_J%fMdAr7jE65+M}9TN2?kdN8oxI6Z%;grYThLn5OO> z7|i6{+>HlOvua~R0ge&%fruIcQD10LL#!y>X!X{xWd=Bg*{{NEd>e4_zK(h%!Amh{cgES#BOA$iDPN*RM-wKS`M;Z3R`xtbCE{pmm$#c*Xtq-1(ImTv)p zGgTB@VN-HuSX#+Wj=T&_&RVbpgCHg7nr10Phv5-~=rGowjxG@$Zh;O>MaovND4Qla zv=Ha0ZwCa^buz;{plo_>MU!zU`6V5l4L7$Ghl{osW)FkemT3c3A6$`J$~fT)h{hP= zlZE&x5WfQAG7u+|b_+{GhZqJUg+Z4lIBo_EKBnt`5CC6q(HKKKLx}sKy=c1F+1UmG z8W*Q~JS|G7^LhU4nO=u~N0Eash+jHof|8EMr@4p}OkcneDY&Z7xk$tmLChd6<~}P% zH|~MOJfc1zo`z|ySn1yW0AS87AAo|cYJd%UNnSS!`ybH$^Ynr0@Stc1qtQ_FXgnyy zzk#^Hc>`60!NJ1p1aY2Eu@7Gln}Vt{8c9kdw0v0`2oF(;$F?F+6=c;ZL3u*ZTL<<%}BaP)# z77)aru7$jMB8uki8q0+&1*<22K$AH0Ai|5XR5}m^YQ)fB!3nE@>N-md-e9FVDGog( zB?d!CWQua?Dux0cABg?{(T(81f_Xsq%;u<|dz?Fq2< zKoqFr;lYCNN6>fDTp6O5TnS3Y*IbN|z(A$ZAVgR487SV0=t?freYCC{qcEZ?Uim{b zA4PP>FH?-^6Qc(WFHrMogbdn2L0qpn z@^&d56a{L*$YA|pG)6R0=v|HJQ&OA|L_7{!n$ez=ON4bFAjd5hxshET8f)SK7O^dQ z*EgGN`<873%>dAd%jZ|oK)=IF4=|@Ur(~8fh z>BYg=>uT8Y2OPtHi}0TU{%}iC1Wey(M0;d)JNDry91*HN2s@u?L74?!OB6E#Ut067}rq$(_20wFmu(n$>lx z79#lx>p{RVN(6j-g?S80_%DoiDjI7%50Moo2Rn5GtED+uyESYj0*;YbBobeO#J*Z$ z#HqT`I#t7#xrXZw;7ttd0V0O`iNgIIaKA`%pKON=jkgyXb1J0Q9c&J04uGb5=~YYp zsFXq%dwUHZzJlP1eqT_uI>zni`O^VMv_|^vI6w%#h1#E0P#cZYYb90tJyu&Y5Jw^X zYS?O|VXKjbtww-jG#V!gc@E;<_EL$9Y1WUr@wzZ}Npzj^X@r%oVJlt3R{B|S{s0^! zeTB5=L;8JM`Y|y+p!?QJ3h9mkHEZ+xw2wo zcNIqgomQi_EiM7(CDlBLrQ#A` zqqgkN-W0V~qy3WQ13kDQfm5n%xS+Ke;*@e&T;2L48kVbAQO!bJhXNPi2cmTV%sO1B zbpTwTdY>IE7{3*me?cmJ9=Ae26_sdc@JlQ#K{bK|a4mxn3|E= zLlAMo%fM`1AtEAnIew=Vo)Af37Z1QLwhKg`SUX@B;MwRT1Hu{b_>0E?IZ0*Mh>lg4@9s1s{RXjqnnNUrftVwrAA;!c zxmq;Pv7#r5=*4LNS&OFIaP)C}x-l|18X;n6Y=9_bF?z3=1q6+aZ0u7 zth%(71VXm)DrZu#>EOFr$L-;C;3IxogCSZkgpY%u>*{!o(fAmYks*rFxGQOVFKeth zi0`1W4~T!nD5EKy8`NGX6MoSs1AMG9cZf3Yf#5f-OrG6i>qZ&0Js2a65W%#61LAEf z82h&jO`*5gn1z|Zs9BSPwPtfoL3vYMrPPbJd1e%UyH^^}^N92ZY-tlD`6g zIeXNAW;7cCN4&eGE5`awQN1|`F0G(C8o#eZ^$dve_%w&ebkvB5RzS3i)(S9d)m3W+ zI7%xh^@%7o0PW7D;?KA3l;K7!yk*c4*gj1z8lXgC5TXHH_dwB2YrrWj00gTr79wzL zdpI440=0PxChBaU-qBKXYLs}Vda<_4SzFw01;TnPT>4g7dLY%Is>&=#4|sF8Z4hsz6o~wF==a5C;>d_e zx>5W{r41k!#i*|-BI;{|c$zLxKul-VZZoO@V^t%~>WF4#tXU(gSzFQU@96g9<)Yay zc8Jkk2-z7)JXJ`mkwwWS=RS&Ft47eM?S6yzAZKV1;Ng0FZVaZ#mN762PI z@j2*<$8(S|fr;2i8MC`s^EN2HyF#ov5zpDs$MNY#@$)wL8Hj^c^X-C&gvky;d}1}< z6`^R{fNeph3xEl0^%*;Ue_1*Z1?sBl!TLp1cS`F@kx;Dto!&PUrvR#Frw8-f97BiZ z*NBocL`Nt&KGo^gQe2*(=2rvUJVZlk(&%$>O~ZD7rD40j(y-m#ofB~zm-{Xhei`p$ zk)#!xY!yP|JETx1R?G=B>dYE}Cy$CP+pVD8>d@AgV&~S+dvCi zJeRmO6;H6rrD|I^9gx{e;XFk|?l!UIyen~eTc_I14AvS#x4d{it=kUZ!C@Y6z!Y-b zU^mwnG~AD2>>}?;b?%1raSWrr0JuP{pNRt(R)GEE>m=r;*dcyVWLtR}w(G9HWt& z#xv+Lcxbg&C=&5#Y<5EOh<}YW0?}9yRWIVvDMoFtz*cR*F=_*jQ9CPN^u8T>f4*K_ zGusvkE0nK}vX-E4(6+i-qEn2P1#wyej?ofujFugniI$H;%YN6&a7U^|Xxt8!Xc?9u zo#b~zT=+BtJKTU{G-@8F5#Sh&07q*?FLk2FdGk)htg*lDhdrs;(mMVYosW} zM9k3k3{T7JgL|(@ZD%>>9+%?cL=@rZyYqQl6OlwylDB~=O)h(}kQVNy5FjyEXrx=(-5s`O$ zQZ7c5=Z{PA`Ee;yakcZ+RQ_BKj`NHSXZ7B~V1rm?Q_jax{0W?*$8cg=o+5q;*=emU zss4gUf2GQO@_y=ss!uie%RD~;Tg9q$LcE@FT+(n%kW0K?dE8#osdrl5V^t>A^I;|C z!#7c#D!dInI)T7~LacwQW~?58{%LswtJH^`Su2CD#I-qRsgetV4U^5hc^3rR(agK; zg5asKVf6h4@w1>tX|OQi>|8KE*g{P#4Q8I}--6V-16RpPjmvxQxD>x9rBJUyjYRS7 z*@N9rif1|gm&dhV$EA`U*RJ^iJ+8f7Uo=lCLn_B-=)K68Q=QF+aLFumoO|)tkoc(` zA19@a<9q@yK6VKIbpP?x0-VS3p_Lvlm#Z%BYtN*owRbIndQ>brLPP=3P;cUbE1)Ok zG`ukq-(LbQ|2nyhV!6Vt62lhIw^BL^M-CBa1HFd7r5tc3`2jS|B-T1o3k;qQXRZ zd{|VN;z?iPI8C6!JgtHlMjD{uIjaF~5|NLxa2x0OC0IF=o4T+PAp6NG!LF2|d1Xov z?=#T51_aZ+qrh^w?~w7!Z~|$;B07%sq~pQyf1-J()^WV6PQNgi)Bk(mQ1;_ajt%V!Jp2+<%G(6xMziO)@BR`%^0u71Y#M+(b&(N^bB0^l$qqC|Y!!r2AOcFamAF=aG{DcgMOTkU-JR%69xD#9viGsKv z6vI9t#7dM%(B(}a?q`b21Too1h9d*fTO#A^F3~X(ILmd;L#JQRIpAHXD<*_p2&{`l z5%8`vb*uCXT;~y>Ti+vNiZ>d##Ug-)=L<> z-P(Gq>%0Q=#s|gLB5Y;o|T3xy*IGM5pcLYE_wy+Ks67CNU56k&)bthy&t$NEYj;(x)lJI;!*maU&?iI;!*m z@eB}R9aZ{(pgVSl59_EULR%JQ^b-L!Z>T%-3CK(VY1nA`N(Vn2~=Y zdZw?#%>9?^{0Set`ouuGZli8u0~{@M{Fol}at#o_03pg#t|1Do z3SWbWb=395TYl@MPuqR1cU?{!WC`79u@Ct2Z1 zAB(4_fp~474A}WKFk1LHJ~W(}VFnDR79_GT3`!!5n22meh+7&N6DcccidtA^;xZ+O z=RhGgQ&s}S3lK(=%x3pQHfv4}nT+Jr%bx+vYha~KE@H%wgbY5rA^D4Gl!~R*(k`dTGScJ3rWN5%UOvJ5L57Axw9fz#|h2Im#1e zQ4zE749UtfL(6jLWqfp5BE+fa=)Ba15RLrV`@K%lgOHqqFSu-WSHmt2)(<}e%z!2a zo16WqfS$mIa0CFcdw*Hrqv$|5R8|B0Tcf=T{=En}0q@w)Z}!lKPWeSF@mrJV=wv!0 zlr{zU5l>A#%nABWzL3dPoQJXmeXv4JaaKbMNr!uu`m=$M-^Jid%tanB=`;a+QcCwP z#Tqrmxd&aF!9)0&v>;vsVj5E%5=4!r_-&Pplpu)5k3%6J^Gh%%f`rD7FY;PSZFW1N zpi_!-0r-hGHZRTWoPygN0_|QJ=pxUT3jE~KK-Uz9mht1k5ewMmp7hZvP8quA{UV0< zwM&~YTGoP04995(*+7Wl_!46{U=r{fhu0n~Nr8A2UC&~}_X~n3NNN7TI8hJ+b^?L* zaA0PP87nepsq-!k=C+EgzPGOk%n{|^XXR;iy(Yy`P<}LCrm*=^y_J@S%92cBbjWIk zeHJ>=kH>s~3jr^JUQ`Ru155$oJOKhc+h*a{7#25l_^Iy~(mn%QgmJp_ z`&jJL$MN+<>%cq{GL>Xf(9xm5@+1f{Dbk{@hKwSAHN=p3d|DK#f-N7C77%^V()lw& zAiHL03a5ZENUwRo@c7jShJJhy0HQ#>dwH;d^P)O-d9Z%HPG}j_j9T~Ld6oJ;HuqE@ zyQU3N9j^!$c9Vb?tr89yI)(F%_E0RM{aot18r(fT%~`akO92pfp+&TZt{Ixbd2tch zgOr~K3~N6U>fl+7vH%c~32;?eprgtcR@?4Ri135<&H=i<;zpEDnwTcY!=R|cC%iSvPG2s(HEOtrW=*tpegpr=O^15ZVG$zcG8B;Fnd!RXvUYTnhsru7mr)O6j| z16Kzdh9~od5>JsI_VLu6&oG`a{zTZVVi<)PJfli8^;(9pH_-5AhOsyJOz0nC7z-}I zk@!M7t2x(s5vsk8f6T}M;@i(qOa4zZCi8P#FYr%D3a8qu?W$Tp>Wi#ec}=ip_<78e zfYfOUWR zq4*Iar|8P9| zIt3WeN*z$(1Y1T&zOr^T~Gj70;)B1vMHuzORwQ zG=(nY;Fe8Orv~u9YW(%8#jU}da2ud_59Du(nmaV;zzFPtQZ=Fr5PYAorSsZoXagd; z2M}n9mA3%DV{OsH845>VlP7BZ19P7~j;{yaN@`XQhZgw(Qy)3z@5@Dg^~kNk+Tjrp zft}eRzrTmm6wS^gMy$Mm5Jc}xW5i{QXh(=rAb2CD36?QjWIL>4xRF1#hnRIaV7IiD z0dHlnSU{BKw=*0x&AYkxE>GGi&ZHJ%GgA08*`otV*AcP(1Dt_S>Kp|9SuMr(q7-9$ zsdHjF1_EvTLL6Ty+ahNH;8i#NQl}5vohxXmfQ39`*jjN9b|I;yqW$mSfi>I;1LuE3 z@ctEPWll?c6;;-)NL%g{0~`dd0dH?zQb=1FrSA1Oo$3Z>2#C%0>ewarqY13EHigWElSwn-p1x&qq98U5;fJSpK+c5H|HzX4`uRaoEHc_42x)w zp8AaFe=FME(nbb+l)+X8e3`-GwD+9D->AKtgLP+r3Cyctgp$E>f7(IkzkuImc*k;o z_WOE%cyfG>lLuYi?lp)V{gnxjTr_+Edhz(4<$gkt{d89bnhW9x5Ez5ux8pYsG6r8R z_vdL!M+V`@a(_NBJb@cP6kZEmkmERuu;Kg`(gNQ3f0NkF)HQ*c@;W7|2~Z~wQFlT| zpE{H|~ zuZMGmpAegUX8aKNh3LTxYu)udReDFT$z&Np?6LFEVH!B_5W+Kpi5kRQe?Caq{sC-% zk%cEQ+{nVE47Vy6;Lt$+dIyRxG?4Sb9s^nCFX-p+NUmVS4!qX2c3oa5lDL3(yY`J! zyAD>19*~_Is_rF z4u$ZLS$C01SRF$6N{s>`FAg7P-BhI8zU*R@tA4jsLT%#;0b+#8TK8UsZoJg8 zt7klH4_Cu@PrXK8Q!?5dPOC5L)%vnXu1BY);#|}V((3hRif#BdhQIB=x7qw{55E1A zza3hUrh6P&k)GC|$2T}54+vFzYjAX*{JV(Np=D|HE(V_Nji=RH$KO^iPpdC$^TtPk zNKv_IO>jPCV?UCL0f@~5TZ1#t(rh3}v%xpbrYtRa|E7EmXy$mDI=5t?po+C5FBO|Q z_i7L;$n&=aJJ-;)~SI$^6Ij(cf`3DR8D7g&(eR7vPVfh%78`a(yS@EGe|jq~49tbDH#~DulZn z-{m=*{(is5iz3AO2Xy%|6a73Oc@Tf-M^JpGh{r2WxOk{)O^?|S_cVg|F&l!Y5ByJ}$*K=MB- zIOeztZh?Z`1`cAqVif!!xq|0t1#{g0SwV7F?cqT0?KV)orSyv;F{3Wp|EA4Y z%EnNjZg=yrmJ=)JS4^>1e5S3ShkhczC#<3s{N)s0sAKqX4&K&}V!0$2=ITj`E*O49_3SNinhC_Mx1wSin5wm0i#%Oz*IpW@ zCC$8eEpJbvO>U649ozu|Te%K&&=%GqNtPcH-13J=h%W#P|dc=vR_IUAU zR4RTZTDJ`w#9oNxlAZ3hKqcNdHHkXYJwbf1tVGbP>kq<6QP2IMu-Rxpx2-x8kMN>HB01JF)QX zD-3)Z!#h?4_PGVB?9pJ|@Y%r7#h-7?zU58=NXJ-XTY(DLC#>Rp;P#Cd6{lMjrA?v? z&kFbi77ghc*-zZhtcFJz{thq&G(RDm{t0WC<*a6vR+a@mflAFE3%1Htz|dU814JtV zU%9WT@sB~#TYzoQUKI7D{K1+%2wc~xqFHk+-00)@q)jx#9b*k^-!Xg!_(?!kSgM!y*z8}f_{bd$Wn-K@gazJ5r61cWN zhZdqk2M{cnF-T7OdBu1rOSg(rBvK#VTv< z#}ghB-&hcmtQ;V8QjOAjOLDDupy|RD3AAofGr87X>A?~bHwHx2*LqC6))NzI{aSLZ zKSk5oWeK$Yt`e;;FfN62IY!4cXRLTKxg1B8uGswZRuL09~)An3U=-gjus zn^Y^|kdLJ8MP~@}kkrTmA5sZ%I$9zz2*f#7FPb?(uwDaLFU%Yu3RLcMIA&)&P>oh4 z&?K!Wxgu+lDsp$cA`d21sjrig-Gik&5=nO%)Y+0H`k# zDRKs$1dyF_Ob+3rf%!bgghN9IIK~Xkh=htfAFYVZztX@WHO3wAUKM?VpX?=E#eO#no|8N2PCoa4g>{j z{xK}i)~E-bx5~$Cp84W&uTee+dw)r27^x~N{|~GD4pH80zi7{IRc#JMP&A8GluqC> zZVrLqn>7-KcBf0e*aEGRRiNHBs=xb}R6iE4y4lRds6OO)s!syJ)Qc0SJ{P~+N~XHg zS%=J>AgaFCo1(i!xAr=XHib-#>I;vj`XwOvIFaf>Ooe2sw>7HI0a5i;9~!T^+119V zeq&PA*GOpJ4}vo<5w9P%D`Pae_+6B!j%6IeIQl-z7*-ubCxS>+|B{K0f2So2y)Lw> zAHj|Vh}A&IL_LPZE)YCXpM`34{9z6dc3P@dd$CYDfTohmMeDDkwcb~W*7q2#y$%10 z*002CeITLMUnkYt|0kN7UZv*lv1z2DYkxCJzV?@ttlz~1w03PvAS$}H<}XQI+Zs)o zYsIynN4s`fqvQcG1X4USk~f2>`T;R7Uh4}JYTYZ5)_L@zu*_Q}nn!`+=z6vGm0+#e zve$x#vvi{@g%GHO*c2mDQ$!pE1jpcHBN7N3gV7R8K``UGsz{6+Ge<)MekQ~7kBG93 z#7mAR@g@))zP>6FAC9-tB<5I&_Z?5-E)bl#fhFn!NiwfK6)({wrC5otCzW`wjN_SO z@gTL5Al!z~qK}h>#=Mi7nkbA}_?}A(%$FeDLsXFkCe{yx_{!=&kEDlJK`d!V0 zr7I8+CMr0M17^kQK`34K0Y{<`)&5K%$k<=U;FaDR)x3Y$%o3vmFHl-QQk-|R4*lbG zFmV#2L-BERcmiWK=f(t%>D@fnj9EpkMkLkh{CKTmuFb|XryNJCZP4nUiM0AWiB>#b z%adw#Tf9~#!ee|jHknq>%XrO3`=p!HIj`CAs(2;X$~x!{k=zBuUaJFT5+L3LB9gm+ z;GkI!A$iqTV=!|*M2nSb!=%ytfF4OB-N{KHxtWRujW8h)N9l6 z^m-TsCu|nIB9|c2>tH2%4T3Nac_T9WDc1urCtk0`3H922JiQKrAootuE3)b!y~4P= zm|(HQ+umD~>h(;#UV9Vj^>wsf>d@;b`uz#iFL!NtGgxb6JGmb}?f93Hg^4zd*&rt|{4EyT9Gyx>HMmb-W*RF_V6=bd=L*0L&VS*e-K0SUyJXQ zqz|yg?eVQh!-%RI-wu|fP5Td)Q|PAN ze;elkzW9U6cqdqL@|_w>sbEi8S{-K&Zm-nkm79lyf#2S&rF~gO?1=OjzERB3J!tjN z!C=cQ3#Ju0W7PZ)gUvDx0Wdzsq#2Bw{b8_GP$00XL~`|iD9JJsf0dsJeD&O_f#-g#3cZAab}mo|DYSeQ)s;P;aA zhTL}Q<@b^+2F;UN)$9FWcYS1Ayg?M=y=Ba3Qs+O0s!iM!O*ZWgSDiGovq$~%elTM; zJ-DBE!eR29h)r%4WlydGsha;mutzdq@A@d%ULE-$nB6FuO8jdi9jQ&5=a0o&{dmf$ zX&(mL^Vx^oSqCc)>rC`5|BWhej2|99R$0fpw3ZLoTjIV^k@On~ayLSNmRri`L z^3ZEGKj$pV&XxFqT>+o?r$+sOmr2s5^J6gZfQs%UN=*h^W>9gFE>J+fsiAGfL69-T zk3$ngor)kvPF}$l8lCv(G}4LA0W)Ou_Z?`5Lk94q+H4$Ehf2A}=>r5d)<6)!b4-A} zU;1n}00L((5d3Squ=_f`u7NDPrAhy~B^3{umVUC~vtZ4_x6w#$pyE9F;Sk_y52(Y3 z?HfIf-D<=i`Wf(C2p|K}P`j$O)jiSaFIe5_cvh1a;;p_1vI5>OD_C6;Z}op+^&1aL zxJ8ftFJKTm`VlXbXfL$${sk{gMyJ2vg|m<6g()D2_rgBN3V4qk-wTZ$$8*v{6}`~F zJ`Y?m7G`NLj08=!W8qSC`U_sT`gmTrA%PeE4Os#2u?k*@n*rhV>KQxN;dD;^R%Y7#>*pj z0wWJ#mZCU{7xlQGi5mc;f&kd$0h;#d>!Z^^kw0^*JA*R{Jrm`>n{z@JKY7G+?*`0f zJTSyL0lP(ym)14(J44C~9{*i#WVRr|6m4vRPtEbU-Q@i2sa+P8XlXrQyuwdB_2Bi z^yIN6_*?B58=UrkNV|Pb+>`{1Z_miskSCx3|VePR4 zf5l_B;6dg8ix~T@a*su&ro;A%w{bSvpPOeVFttar*8^ zqTu?l_)hc7i6h>|=KzEW2f&SoSp5hxBoLAG=@?R z$Io`x!$L<7}GVXPi{k=^Q6;;n22>ZaUYtCO#eI`0pLG@0MA>kII`l(j+sEMRi zKOd?Wyj5`&-iJh4u~#%@tTrVFH_NI$3a6k`6-=S``c`U6)XdSQTme(wcw0<)GAf`R zwfFQYnzC7&^3`84r9q7Q<~UOiJB^8N|x7gH^Y`|-c`3AwRhccGHu*s_>y$T zF}d!G&_l)nr`1+zHc+qMt@b!p9la85n~5$R9+i>6fwqJ|5QX(dc{@&52gdG{aYPA@ z?#Raj#?XH-ItILr^c9$}PXT*6V~aJGjeQa5!oxCfZ32`BkO@fAZFwdLah3^NkK}~H zm8-`7ffIbFa&QiHBic7XD^9=xw^epRAm0ojPQk6j3G@W1I01*_#yR20vUn%p&~D>| zkJ#MaaZdOrV~0mO;e9xv_t#_%eyg3%f5Zv*LPeR0>ykO)2z4W^4uMujLN%OFSYVv6 zxl$+O4K_~LR>29|D>wm%)fgwNMaO`5Vw@8;GIoBn6OO1stUVw@^5|TM#A=t4Keg&psrxUKk&l!Q z&P6}AHno{#Ad)nV8>1S-MK{oeLoD&W+_DHl7PKFZ}v=ApWiM|Yc3l;U`PnH3{Hcn_<+c=>*mw_?p zr6Zxz4466GI3ej}Aj%0*mw}n+h#Jv-QX?|g!t)uMtFe4790Mm@*Fl`HC;Bq*3slsR zkjx3o!Hy%LeI4V3jZ9m$=`aPobR<;jgxjnWl3oU)oDg*xs5^q3&?wFc%@|u8?Sxry z!dWHagt3`48T54U*ELQ^dKqX3cI<@ipsoI8U;%pRNT@Ue4uhEZ%Yey%`Z5sZgs98F zw`^|jI4Atb*x}Jm2*U{vpEg)E`rT&0bvo@wGT@)a+Wz*T@{QHV_hsm%hrCj28;vy9 zZnOE`t^p|IGT>0ay{erRcqpiIT*4{B%hWw%&9&x$oHL}m8oBUrP1AY&7 zJmja_$J48G8MqR?^pID28K{AB%5g3OQBF7(xeR=Vj=1v2IpJr4a@HCuo-z;%L%x<6rkC`9mGJuy*NhHj(kEB=UGH@4q=}4$F18%fVNO~EFazfN) z;3qbBSDX|6%h>(VPB;K3yuC=A5VITT*T^^_>24tHbnS%YpsoIH;P2?ABcW0!w1F5M z33fLy%B%rpHxT87sLQ}sbi_T>I45jp?2%|Ed5;9}*!v(xkE}H|F55>L8vMPtFh>R7rpd|SDNkVfVJaf`zR+wW&5Rg zj2mar#yMd%V~0mOp(C7d={@3vaCEj`*338|X|}%#?AQt0L96F@HEKU!pqGw>O0)d~ z5ObVtA62}H%JxUt+=+2c_=U0aqn*%?!u}y~LgVN~|7FdM6ZUf&;Tsh ze`M}!nFWP zc`YXhF?x&i677Uda6;#g#R;pTv;C7$QLpGY7bkE+ z>e<=}M?tG2p&Hq~WgFv!%1b=0Ax1|+vJy{}6QZ)ce>_Ek=YiPkdk$lBHP(}LA}Zo= z!Xw{_6V{j;dD&>#3l+r)@=!(sClrC5hiLx7$?XLkc4$E(3L=p zI01LnNF25^1NDjyx6E=+bKD_V8pvaA>%wf-UYHg9LCmU+$4ltrP~UA3DrVv3rChO% ztFTaj7q+99*aN>;Vvlcv zu?M4}?P;Os&;I!FSt;|UHtfmE9HKhrgbMX0XJv))xC4xNJkIQ3^uMecc89Szp;Y;o8$FABJtG@`d^tpMCImM{rBrib;SRxCTjhI#YX>wRb8#Z|8vnxFVvE+ zRzY_s#ONfB5;YLWU&jAOa9=Vee;pG2`#}F@^@gbLBl?>(9MON}B&~m~jz<6LK~5`RBKgs=h0z_g@ zb@K70=v9?`oH5ndgZH+?#aps`{37g`J3#D-StkEx?Wvfbzl0#ZJ{F&7?5R$Eo`zmk z$mOiG#wf8TW_`R9LX+j|>y16%S$iaDRBio5FV+=%D$m!CS$nFUuhab4pr0l7#H^1u zLTIvlT`*mb&p$v^{e0~$G4@oRue(8vjtoAF+FO6Pt5vwF@%ae74!AO#-95? zRQ-JYiM0oQuVj6Ez}i#weBA~1ygE(nxiFQ@lKtfw-HkmJ^Yy~>Ku8JaN)S~)Uq6dp z5^w7&wdZ<>scya=NbxpT?71;IUw7?c?5UWqN6gUn%mh*O^Yv!*5_=9+x_&+%V#Jp*<+=7YtA5pU?ITeCwX0<=kMu)Le7N?tuD6-X6?1Lf*`T7_ z^a6;gpKE_ZFBy)?b8SzEk;zc?T)P+cG^R)U@F|VXwe$KIdn)GI_l!MTKvex)`yP6U zJ(cI$->p3xE9_l1$A_1$O?(7<)XieghUi>7w6C$JVy@je2iDX0tOil_bL~#_5_>Ao zweLere6BV3SQF;j5sv$B*wb!{*t3pDiQ)|n^w^0Uu7i`g41#`L$R|B%0{Sg9{brlm zsf0^s;?rBF2;MQ5wCO}YbslRO&~KsXol?1Hq65BPcQTc_i*!+2e&?v>HVf4XXQiSj z_y0t(U94E;diBUZg%oR)K(Q83Y{*^zFFdxV3W|L$inU6hSYIgi;r|oG_E$l%Yw|Jv zc(Z)0V!N7$3d5~G^?17A-wseXPO=}fdh|g%<|Lu7K`n`f$oy9(! zWT5=DRKL!lx+tE#-s1Q!KwlC|IO3GhYIR!2ctW7>RJA%KK<`!o3|0ju&#O5dLQPe@E}@38 zZSZY>wYEzg40GqD0d`#$~m-{=`s$`l4$ny8_=krLDYMg0{~qP-_jh z1>-fuF!xt=L-85{Jw@H02)$aJQ<8xCPSv4%0`zXxsb?s^P9E;ACNUF|v~pc~#w$0W zXM8v#!Um`#JwrLM7DfVZ-bwL+Y}&f3>|V**&Q|++CFIG`cVF*>{m^!AtQvZ^OFx zNraxFdi6^{y;^;g2z{rzwSNNY-D<^vczYpI^i|6T#<%HwbSE}5$s?)1YB?xg7KifI zL}<+Y!3n7ERK6hz&~d&saobXTJv7uf+@~#_z4I8Z>ds>PR|l88U9(Ugz-J-uIA@yEFZS7eWWGB@HP#vlJ} zX+%pcgA4GVe>^u6yb=FW-%z&=3pI9UpQoN37OLycI!}ExEYvh`H&IO}20DFss9WcY z2y9ybr3!AKukGn;%?0%JL{9_oaXmxZk!^QD{r!ONOe;TscqpZg%3Ttwsdmo~)lxl{ zg!0uB^FkS&2jsg&IN8$Y>7G%NF(AKjrZ<}q*mf zYB+hRy)tp|AXtE8K)%|yDAd61lBrgW!slhqKCq!L?0MUT_9+`xzSH~d}ME&{zSl=)i(;y;1`ZsLm$;dbfv>s2R9M6FK zVIXRp=kaFOF3P~#p^4)JV90P_n>O~0DC$tu1YesO>`(yBiJE9z2-f3i+1S$|%j0Rq z4Oo-323+J(7mdTJ$;SE_#?# zjU#24(=@0@JrHqIx{-rpQX($NG(J;Gb_cgD1N3l|lacJ8!j zcKaEjVvqCi%V@a%KM41L>)9zh`D^)qmWQT0HMe(luXntTWB)wwdcA5wS!jd1abWq+ zWuehd*2aN-SQqpIZtTiX6W47$rF{8Cp|);T+bOoO?UeFI*M#oQb?@&~KK_Q#R3~eD zCu|hy6L7b8Dt~Q5=zhoj_~P=ijiE_S)}f1SYCMdq(!wIsb2qEs9n~MVV1*=VdWY3h6=JkUfy^|=pH94ZIq=?8&&?!&d`-PnWr{5 zRoFVtTIIYNI$b@#H&j@&zd;9F^VQo%jd&R;qr=Og3^knov){_`?M26Zu2}v2O6Y>D z-Nl+`z};P3e&MU38m{}r$>mq=3q9*(eR;BN{PN`Tar;9j1>7Zj%5QoXQz2`~9@_}q zr1wL!^4*ILm+$)y1Ddtwuuh!;cg^AQzDGhWeeR4<`K%v9tDUUbp?+dVz?~f`|Lvzx zclhbmM}s98<#n&xwso(T-{_R|^}8R}Qy-?5JfAaS$^4nqCUZo&FTPo>9!x8#opq>Q zf5Yrhz48NTB^P+}+TEaWj#C@8l@!kbHL0*~g?Po;G9Dn3IKlIW@fVyLZm~8PnRI=keb9@XbH@UipjzxY%$HxaMniMg!ONc5%{w zaMw8A8jjn_Tjo57|I-{d%Znebp6vBG?lB7Su-lIi|8enskb5`2YruV%nx(=0Cx3sA zTYup1FVT0?K}bK94vyD#+@hB{(N}QsL+qv$0-mAPO`F`;sQu16amWe&#y7sA8~+p0s}|&s za;FoEev?Vji&y{~A7j#5cO;0eGmOPMZ0uV13~qrlTvFk`T8eNI7m=6@cXvR&npM&u zcfI3X=sW>yvmEyuP^*7um9%d7EBV63|Imds{q$3U3{G{(E@|ioBE>mT-J4U=IL+(y zWB;h-*(L3q_3CfgC1X=H_o+wYjL|LiKiDN$qBx z7hl-zvm7kqqN|u3VN^e>0tLOYZ|fe!ZY>B5-8z!27kKM9RVKl|7ZQc zg&9&LZa@t&;NE=14(r#BI=iss^5LsqD_`qBcp?ws>3vV@G--+i$m0|s7vpAiz`e!v zihPwJtV=_P=&wgZIE9C>vFci@TXzj>MYcnNRV4X4o@l z*16|RJ$KgmHsl}Mxpl4o+1A9!c8YuzztnT^PSO>~y+MhT(PZ-`AF@SoORtQlB?l5k zo}uVZ6siJ6-zX+StIGr$?io8!ZK_*xNfsa70#6C5Q@xV@?)ZUfdA*V?S>vrYipCEt zZ&$x$zR$T<-PWY!p3G}))Ano2M>Q?^D8_m%(Lv1CHPxm%6tUb298Dld00 znP2Mfq)f-*!3G3D79wjXU zW`Xvq>Nu)6U$reN&ds9h@RUKaHq-dC4Ze7=;MXXpc5y2;wr5F>`^XSAqi4x!?&@Lc zp`IltxyOd9qdiOJx>L?jlTIo*$6b7udiJD}Qn&3CHK|ug19jxYEti#7VflJ>hZe8B~0`1Jhhi_ zch6TxdzZ9#CoE8n`vAUqff~@Kq?@~Tp;|@o;f3nGdRj(qsYWlu*FIDUNLg_!t)X~1^cVSo!Y*4(AWxac;T7PoMPp*HXdc2|L72c@6ZdiO1x8HQ9 zx}s6>Wd445n|k)tlJDH^Pn17&8phKd^`<)94@SKCmTKI;A+YHomENrQ z3hq?;>}qxkYGeYworxBRRY#jPDCzPgFJ zqNUcTepB^$%i@uYzqOS*JQ!B|*h-bO(iSgnqn4WQ^V_M*hoJr1cIu%aC1+r%tpY=# z)LXq(Xehigu)kV06iUA}LOo0PM@Fin^!Jics_`)VJu*s-7>53HMym_y@4qLj+v)Ft z8EP-JPoJ%R8HQ2#d70`s9DI&lq!tW^oI@9@mruYb_s7QkluOjn;Uz8FEV)D$^&2H% zJ&}mL?nOe;+M4KdFI9a;K(}kIP*=1q?#n!`yhgn~qNH1!W^0AVm$?FWlenSC6+Z?!^4}KB$h4DjDi-+M)W4E_uNH z^?7x4H0&Avg6eoW?ECN~HM3aL{<&A(emZEsctssO9g+0j>uSUqpjq?=>DWHKi`F6Q zP4z6{&wR7|*N(;G92WGiR5h-1@pJtBkpk8DOb9txpeCJ3%GOku)8EN8)k9}O(V{|i znEno|rD}|WLp-%r->${&)urP~8qt>Lo^c>P)J(lje_J&#f4OUMp5t$YqQ#BFRE@L2 z85^AuXM+QFH>>FH4$NTs`^X4&nEo~!t!j*iidko<0pl@j|C*$3r@yyNSAP#8X7@Mr zc%HpdU4Bl<-EO~oRL2Q0`=*E0stM@(_@nBf2_?6=t3OsFCZhecH1*3wC~{qzYCH+D zKhIE;CV}@!+2uD*Dk*i`vf--6xoAj3Or47f(s_b<_gr+iWrA|1;P1Emx0dQX1v#h3 zL^Xntf19Z4^eSHJ-`~RHDV(itGT$#R3!Z23)SJNC1q~PYBgyZ`b=M~+Vny2 zQQOwl>Y-`KO~7=RExVK>zK3tH6)ks@4A~U?CNT%Q|CDNmkB2eKi6-iNlXXe$L2TXGu5Y1*Z6l|s22)#-x=5H@(3Hj`Sk{L5ARd277X`Iuq^Le zb#OQeG3;k`c$O~oln9kKTNm(yR%*dW-{5mh;xDSPqkLU#kaI3n@pE)E*WvdW{QipH zYuY;b1Jf`IL(t-+!?hRIG>B5o*O4okpadlI;kb z`qW9%4feFDQHY6CeHNx9*z;vU=U#k(&ks638gxFfb3msq=zM6G0N-ZMyQ>qoq(p`# zs=RT&E;eI#22Shjsm(#>ZYus(ZH)Q&eHXtm-5sBa-yQgEaf#!(_}z@(h#r=QU8_4S zB)G$#x>S0quo9ihQvCja-|Pg(x8pbNQg?k1evjjKT%zOK>~BYvo9&CR5qG>y9ll)~ z|Q==Q%&)BC|_(J?P;5R?X@dNnHyxd*a;y0{U*Fz55NT zQ1O$r|CpQ~v!}NH($dwS#X9xn>87dc5hh(F+@$9oM(x@`PF9WIU+|kb*zw2k+koG} zLmXc{M1|e0`~IW)`flC#UwgfJ|L&A`!+)5qR@|e1s~%7%mumSB52{mnzL`yH^&GXe zQs*w!T{o-c0T)-T6drBI8{(zMjlZu zAJFk_{#I?AuJdBpjo+)-0?4;Cs6NYe*!NDW70XlBgm3>%&79#|Y4xses@{B1m*@VD zYWGavZp%LJttxNUGfWfD?*8iI6)DrgKTTB&3ia@1*z<$bx|KQ)U52WJS$e25Y{DqD zaTfAF<{I_FDm{?iI$9;n274n*^;xa!Yu-3DceR#1G+rH>jl7P&UQL*T^VmshH_yMz zS1CmZpE_L)TBFNQaeQkKf?J8p)^1J>{ zHMc^u<9Dg3Vm&e$y~FpanZ>C4F=c9Fv2U~G?>wsFD^orR|KmB8atrG3&dqAIuh^!z%1C z?Uyed-rDoAl(u2vU4K`D9#6Tt$)@n(s_gNU8^bp?Rjn5Iwl_7eEj8<{_Ac<vaRXDO-(Qug%ndg4(^%x5&!c z-mC^ap^M$8SZ(~P8RfP9-Fj;KM9S;otDaLYY|vT1WvgoWq|W-jSJYVZJAb!Y@uZ$J zmG4o9pVaX+>{WwHb$q!q^#9NOr~3FQ?ami|s|G!tvOIk2DfRKwDbvoq^(VL3dX5@Y z>1(5|S>zjI_3!vitzV?8+k|Z!q0W6qH=~v<)QV?xysxxYrxyF}RFle5V)W8>N@RF_ z2en{{o&&|q*8gIs&)Ef{j}*tYQ?)LZ8|&^ z`}UxBjT3mLGcy`#HE#Vjt((;tcBre=DEWueSf*e1Fh^j5fBWKyCg)!+^&`$3sb0O? z*R!dKzA{zCZ_=5&?Fu#4{*F?2nctD))eGkL?VHqL^Lt~SYWb}G?V7I!ncoi6)m-!2 zsz9wXzmsREkDpB$+-#R#($foi>W(G8_@?G!V z)N6D$Kv#3o9}9L<`^w@J>*5^mqfR`V(zRJ+vFGV^AseiPxmb@yqE-Xcy1bM&;cNP< zkDgEIp;u_spm$O_pI@SNwqvzM-|1BPE>s=w^R;MU_@G{Hq2a z&-AL*1sN&4RaGqV4`38>{Sq;x;$R?pj&<7zBfpMR*AfL4|HdNwl` zkKT}>-ZteO{x@B@2Q-PfQGNWbp4gi6jyI~Y+fzC>Gv{~f<)Ns}De+eD_KoV~)|8Gd zO`9;nKd@%BM4fz8+wr;keJyOD#gj5r+2)j<=NqN?T$kB;z1We|MxDRRcY%#8EYC#d zQoO>Q+rYQyWvJq1+G|bV*Ynh%ZBY6>&t$8ks$ZrjWJWku-;HliNwA?hP03IqV(bR2L?CT5!P>5%zpV9YU38|Dkf0a)C_e{$6(8L z=QI~XcXd~*%iEo29L?x#n3kauUV_dCf39;9IyTan=^5(t<;eXgeX;u`B=?iP_(ex$ z)jAersLn4#@+2;7RV2<(V_!v8JT)Uj{rf>}X_J-9Z_ZE`mE+=r!k~-1*%|5%EwSNy z%vEz~jKAA+y^d9mdY(5=y}4C)9VWgBw*{=WCg^hBR37;cWoiY_yDe95 zzJ~f+zTDJhN0qKnEe*?6%hwUvb>(W%>rmWYu4eGO;|jHc=ZjYajPZ5Q`S6v_7;$f; zbZJ_!MBfOkbUleVe|e>v`-bjG%z5iou2EQ}lvV0YEwJZvR;j3m^;m6`URkAD*6LiD z^R{c$pjtg*nDeP?TtgeBR`g10XO|ufu34j2Xcen|zETGt){`2;Pd}-mDskTP8I{8G zis#i#p4V(ul|0|`s@l!-V{fWoc)s&pmGB7S`RGG6f#-wkRTj zS;emPCG*f>HNy_dsAsp7S|A21ik^~Hj>b<;N&7ln^fZ&NZs zU;KNmZq!C{dE_W{(WAI%(qfbv^(Z2^L|+v1;yQh?U?*Z*rZ3*6WQV@^HzUZ_3;Vz9 zOc~TPw@g=Kw2I%SEnv=n!AiegJshCtWe+^&yP%oj%Ug|7mG7kVY+){LxWtt+CPIbj zX_WfmF+Cy}LGh(JT57%5$7x-lr*B4U^yAR_6>%Hz5yCdeB@N2#)Rbxs=Y*X#8o zO-?$h==*&U%?y}1Qb+i%E{?gV3%=-|5hPjbE-qH3RR|b9YLvRaN~d80ZqygAny%7Z zbj=L9cr5rL=9(bMN`287LCWYL$(G=YUSonJ)xj5?vqq^$)+5nfV}mYcj}N+N^OvBD z?bnV{mp*|oAKo}h-N1{>r|RtRV#0KtC@<#D(01iTTA{nJwb^Wr%GjXY+LZdkxoQE= z)qJ&)=QrINIPX>xI6r=S;QYlqROOS1XU)RE`R#uVoKL(naDJ6vB|HWFD@p@A?ykUj zlSP5^Z``@H&ijjls(tQ~pvwJs@Ws@-gCt+z!WQ)UdsI|45>L5LrSQDVvcP%s2UVr! zHo=oCbd9Y>mCsleba8lf(8cv@f-dwwf)DtH{@3dP=lU`DLjUjafJFbxZ+l@gssGb< zW5zNb4P^MzDw{E@6a7R$=jSKY%)g;fi=GagpZ84QeDy|i-d+8%SI_m*_2Y-QO}1Iv z^X{9}$bGuQHT;)N>KUHv|6SL3zW4dS`IRpO&h>xy8n_=}_5ZDEJlFq`sqtL@uOV}O zzKOqc?I_#-RjHPh`eEGhXZ6E4!yEr6jpH4j18@9~E<(TY|Dia(Q0v?Lul-QH@(<)k z|2vNFc;04zfbac8jr;^U`X4OZ&hxg1)prNL(~qgoG;e0|roTq7GCtGYo4E*lm0cbF zM0Z@hYIMhC1m;WSGe3n^;6vW-E@nBk^vA8$Zmnet-T0AbRsTuKh3W^bWYY+I_t>S; z@dcz|z6Ctt0MZD2D%WYTp+6_84r+<5D*ai_k)Nd` z*c6*C%d}?s>3mTt{e?zbDjVY7XVhnnAsRo}=SukdW?u`dq(5Re@F1f7VW*4sy5=t0 zn_ff-1K&e)g5_FZL-+eay{|*t>S_E`mdd-#_{xj0aq=nE^K>-##e*?x=!UC6G+DpD@8<+XE$^t4ieyGGH z_~=VWP=D}49n?xTg#KEFiuxxm^rt3N3NQ3`8q`dEVGG#!k%K@1ZE*du0F|J#Xq6h@ zv==4RZ>$GOs9*OElu*Ab9VnrG(Kt}Tf8FXz_*a+Up{=M<{rYSBFHobiN}WzWm);fI z^u3y?QT>wU?OMm4fAoNQhUf9C)n`0ckEnC&p>x>=HIV181)X2>WPtzk$*u3#r_75` zb(2$DZC(6zO1~y5E-AH>@;#o~ack~(DW8R%KkMe=dDA9ME6lrD?>5rQfLFD>)SON7 zdKJ%~*Xx>5FUfuqplm2t#@by=}ww8wYb0rP_tI1o~I7{JEghGDNb#^b>P2K znl0UWb8+g{@U25`P0cvpq~BUS`#@^KnkA|K3}it^pEYvKHDiYAnDzd=Nz0CpNoq z>aD@y`sN2;>5SSqO+1vC^FH}1=AP7qCVBk^sEm73M_f21IS=Vfo1x1!wPZ%|{9?84 z?$oYLruFlwTBAHIsh|4(p41*qrVSjRV(v}-zQeTqDPFJnvx<5R9eGWk(SxoT)~j&p z>`B*l?K^F%PsJ}yZR?*lwO^w~zfg_-je?|5!N5kr<)H#3mN{nh@JXSPX)efLMvu%M z-NglrAFwr@~@v|zyhmEWYiKT9Dg zU%k<%XIphgS?Xw=LY_~3{PUHqx7L@XE(y2(y;b{nWLUttw@!L6wRw}R_peNSFic&( zI(0`=x1(=s(fz5X!val$xMqE7`>KlJkZkCn>_Ne@scP}VsYzQe31F_9; z3CyqwOq$`XdNVIpg;%B)G|4ZXuVzz|P zyv^2(*^?&cS}(@uX>UZke5L6^yQahs1OZ zZQ4)k=grD1X$-GVgTr6Y=W<`8oMD>u$(ypZZbNGBRTpuKJ$GPnZ@u1qwW?+Kg_m-d zIQNuuBY87y5D(%;UsWAR&Ao_`g|APyBdw0i{$8QCblnw}&_`u{tu5C>z3_EvyY>wi zIVG!sKTY)iR@IA$T0HVd$)AbO^-BKwXFSTQzVpxcd0vAW^i68Ju%l}3H>nr;&-bF& z|CwG3uW0L^@e91#KjqOLE6fWzns_a}bd)&=driDnUd+HEPybV`(4&dh+Ut?31>$Jp zweb!t|1*A}mwWgjp{-w(@Y?<#yq#ARq~Dl+6EDUq2@){ICSH55^iO%LS9|==628dG zJ@IF}gXcB;5AURNda+mg%l`;8@95Pk6?HWAoA6V!RaBEJda1bYQX~B`mwGR#eqreX zuVHICGi`q_0*~7k%6oz53O-cxFr8>o#TtEP&fPKIo;Oz8rNExIK%bd}OGQNY*Z`*f z)!y$?ulAQB!f1p%VC5Hk^(Zy@N$>{2qjXNfbS-(mx>}-s7t33E1#mEYW!LKmUgEf4 zyN)}CK(Gt}V!_9QSA*-#dG?qBz6o4!e6>e0_yKTjS$ix7KMmf;Qte`^Am}m6HGd}X z1b8AiOYkCi8n`i~Io<}(0cTC@11|t??$o`n4EO6cI3EHg{38OCfF~h96Ri-Y^*4dH z18)t!6Py|90$wlT?+1QFbKAsNMMEI)X1kieb2e{0coI1Er+{aH8|O7gF?cC>H;27N zmUr~3;B)%vq-)~$L*PB^ygL^GR$G3t7YFAm1>Xc-1s(zZA@~OH3&Fny-vJ&2-n5BM z-+1qS2v~J-O&o6!0n))E&pL09Lqyq@>+bXxS9AH``QWwS)4}J1_we890U;>!K^3(HF9g@&?a>{)Na*(mFA@4zgD(Wvm-fiE+~3kG6@tkKumrpX0?Y$nE%+kv z4d86wE5U07Uk|>+aO3|>U^4`JL;`Pt9|Dg=hW3IV5&TQ=F1YzzoiSw_!3TqP0B3>6oukWd0wfB-WCTb9KNlsQ2R=gZ zMc~lgU!(HDHD;Cknkt?51B=Rw~;4uS(hptnNV07t;jM}T?Yrv+aG z9#P_Il=>^d+X%kialh9U0+wJi0wfClHh2;^ORyh2UGT5LGr?(s|AJ>*uIrzIW;zGP z87GQ}V!#Uo?+HF%B#;8WQ1DUUOM>Gu_MZqrd9Xn9S>S8IIia`{e3Rf0g6{yQQ&)lS z68r_t{iekGh2Sj&s26-6_;GOEpV;Ftcmp_V^c46R!JB9WldgArf%AU`Xahmy?FBYs z@^0YKg7*iH5qvm!oZva&JsLUM-wX(R5U}|z08a+zAap-?n$TYhK2-2$!7~Ma-48*w z5PSqa5u6FvgXaqUli&q{hifM=Rb2$m*>($X{}Kq=!j`cRtOchNbqB8&`hCG`h5nV` zdxU-l_z}nb`b$RcxE6v25nwWSSM1XnV3j+ac#{A%` zh5j<|Dxv={_%@;cRFqENG>@Gkz>5fQNCc<_KPvS94(=@sb<%_2&B0lt--37bivXt~ z@QDCndbl$g9U=5vfM*N+i@*zoeh=^xa6fZ&IRxb*z+mvTB7rgBTZH~Z@LHii1N=a! zzTdkQf+HfpV(_!z@z(Ns+bDS4UtLx6UTz(DGI%TK*MMh&cL9IHay|bqf`AJSA0ogq zaE@~S1TP2ghKP=XZxi~zg6|MKO5Y$DQ`Q=8{GSQLLac-#JFLeK#MW@rI;oZw~PUBS6dPzjzR^f!V}6nuMg%>Q#C;KIUg1Xw5n z90V^F{22HW!G8f?DtMHhof;D?yA$(&F0sTyP%8o?fbRs?6B~P^fbRj<>kRhD0Iw7J z6TlBJ{y_*Z6M{n!xYa4Wj0YZ#jM6k^;BEYB^KYqFhs{?%|CZW&^0uYUw26pzFVv2J zGk;%$e*+!~{oge=tA_O_UB(t*&RJ>o<30VxP}%RPz5GR3sA0IC`j*ZtPnHNi!19*f zGpk&_xFB-{^h<^Q80aTIfha6@qdR5i@*L<^7S`JFHZ#Fh9H1 zo95?tb<+Htcql%tcgx6KE(!j9M$P>rwNu!Ehwe)29hUdd3;OSWA3B`Y+u!DZ%M(^E zJmz&Xcx%M)FO(tovrzpb;G+&Y&Z*cj@Ylf^PXl=7=T_hEX=k>_e<66w2^xp#v*7Ix zxdeE>5Uy7)jkm7>XU`Z3zD?-203Yz!F6rRs9dY_}yW!xsfpZ0QG1U%j8EP z5UT$=_$k5P0l&|G!UbSe?}6Z=2FKZ)_JO~2(s7pfAo%)Ij&rH^FnE_AL*qFLegNFh zsy+e1)2CekI?I2-{r?H&zkyHxuj8!J2wjDyM!yDU&7B9H|C7^4D@gHLL9iME+PFP< z^sgZSJobSl>dkY~diPmz&J5dqaGrCS4rcoLuD@Sx`BIE64EDH+Z>l@Lm(*DE^LKTZ z{_*Fwcad-aEJfM{;6B$yc`Lvxz;)MTkM-cy;QGOlJzfOg1NQq~0oMbaJ=%l!0C!fRJr2PR2zdWm1HNBG^d|Tbp}!aWtkC}oym`manmcW| zZiI0V(235`MK@KQ1kRdh3qC^dOTZ_BvnNdk&j*i$2}Xh!8gBewuMpT{0t6)pz~*!_ z_)>71Y$5nsq5lB*CU7>_$H2FNn{;jadme(F5U`omg4cnw1RsMR5d2H z3LJ5vPTy4ZX$UTX;6mLa8Q!6jvl;t#K4t9+&OwC_S$hc1hpdT$^C7FRliwx4i1?H> zNd(|i)?~r?kTp$kK4eW7ygLdu6g=GZf1Wo0f)NmOLQRYSF94@=T@PLa&MKV=z7U*F zeFu0sIDN?9SJ$nn>RJe{L&AKv7#HVih@6joOTmXhe;E?k1%4U$qu^)2%?E$Y@tos+ zFDBk4K*1XbkSur|c#hzQ!Ak@`1zsU|6Wzg>0&lZi*FO_(1Hl0ipd0uZ!TW>9bPg@R zaPVZobHHc$mIvF;!h6 zI3FWb2+rqM{%u0AR(J9yq66SuV9EhM1kMhGPxugKHPl4Bqc(#Hc3Fy1_ zw+n*f0f8;SXW*wrM909-2>oBdy&ldqELd}Wt8Yvb3C@CD++L?|1kFW&UI@@e@Tb ziimyz&lmhWeIsCMv{1y;0lX+w-|t-pK}o2ezC37>%=Q3NZQH>=FTHgVzb}2R|Tq zIe5L`>%fl&b7Ox#821vKGlpSYZ+tMG7|QuzJiS*a=Y#QFUnqAE#`V6~zMbCR$ zs-#c>ADGwn59NGdUY{Jw`M}&u4dr}b9(P43kJ1Ya#>DAYVgAn&bN_knpwIxZ2v9mC zlqY~!4GZNd;I+d;IrqKSk0eL?%Rm4xlLFJ9>2J}1$Bhoo65L8_oDyRgn%?aiGw9QP_)lUfJ8=>#r7|OSU$4v_5yTSeGd7*-X5adn?<;TEF zr-t$_$WYbvP~IB6c19>~!UEiExnBR#z#M!@!kZl$;1`ylD3nL(l{@j!Ggf+AGHfY`HPsI*Dnm^Pk?(EQ&_N7;Bj|_>L-|tn)!eF z;!r^fOK^86&j2sIH|7pub5JVV35MK!%3Es&{^>+}#dkB4QtWOl2 z8|!^R@!0mqo%LBF05{NQ3(gJnIp8!IH_#UfeQuO50_P&O-Y4(Y|4Sg?nh!V1mx=(~ z5WiG#Zip`z@t6(qrg>KgeeQ3sT7kZrCg2A54G6$hD{gS#0Zx7HW3LsQ``CAa(;2ys z{V4Tq{cC%2zxr_sVB-Z?c549VvfKUO5i3J|<#q5#!MXjsIXG8b{oH?^C<1K8Y}F_D z+u%teqW$36LjP;<9KrwVxZj&7B5J0yW^A@l1c(7I6}%_-5)n@d_y(ar3cT8KUH`P@ zLsn&EcgWQG!f6u;Qomsz(NRe1%CiMUqtj6_!6Q2Jor+ ze4*bOyg=}-;DsWd%fXj{H_rdBhM-(TbRGC=5m5p77NLJT_%^}Iz;}ek1R`G0c=XtS`cuBsD7fL7o>!MlJbiFlI0vxWXJ z@EpU9|3_Hg)&Kedf{7xc>EH`RL?z&*g5L+eM8s1Gz9C58w!gnYP#q*NdD;QKNksH_ z@I6BRU*L6up8(%4;_(g= z7yKFU1A=b{KV-SCf7<2)2_aH!X!4-J4;ML%51b+oQM)2L>9UjK~ zpE>;;f;bW2ICxjVe*^C!c#9tB!UgXH?rY>|e?AD38U?QX4FXRVd>nY1;8VcU1)mQ- zRPej~5R4FlHQV_*n_JK6@qhDQ7yP`3HIQoqNCtF!Lf>=zZq5OT(%bkTn-ruo(RreNJZeC z!MU!o8k}2Rxw=sWt~a9E;}ct5`jcPwEi>%|5fC)fSu^jw?ZWG4xrX1xJsD?uJ;bugP;E>6r9VTOTlT%6u-8C85yb|I0q4NJ+)eJuD{j@ z&h^@Df^Tl>;;#j#iMfF6KLi1th%3&gMMQ%U(OD5uU+|bmUCl8buD$!fnK0MtGaU~s z0&sD^5CK>d^Yn?Sq4^@B$>8PSoWqX;uK^#38XXLN9Nd{$`(IxOA|G=lpp83&CxUA~ zwnvI}E}dMZ^Xe?{d^lY#oQ_UC3p{R;)31iU-HC1%0Wy&Qy_!4Gvjpc(^lZVo6Fo<8 zuFFmY*X6MXH;m?MZrdLPT(B(^0kB}}%@@3Jy;gAUR9zxC*KwBxxNHAh$Xy)}*qm}9 zcdg*uBD+CwF7R#=oa?(=1fSJWr*E8VhY)n#n*jN^vP1-!i~yyA z^Ks}>!TI>KTyQ>lt_bCUZ^l(Y!1nq+npv)BW~abwz#~!B7wZSFW>BezY1sU_gZIdF z%}?(su!md2*NXs$LUZKt1&$-&x&rLMujCySoL|X1E;v6{*C6RDq0I31%2*9ss`871$$uElHaR=;5-Pp&1na?epA#QmDmilN9dP<9}xQI>l+6% zov(kywR;ZJmxBA&8m|4HHwL317-0p0Z^?0E*HI*JE;2L|37-bnGdX)q06!}@cc4YA zcfMldG3_q}0iq#bLEHRoe025W8>~akpOoeo)J8j zHTs0BYEI8HSVN86_J8_)D+oq33Y;wug6D&?1joQjzsvKA`-vY- z`!}}SCIUpE%iJM&EO@Pm=qtoiC-mP2-!J%!;Qj*;u%~+hf|w1i>R5sdB-}yp#n6uf z=NK^o`aYq*06fWYf8*#^jEIsEfL-zw@DU=SA>f&U_XE!YXNJ0f=Z5HO`+up6XiShF zBG4}fffsHWvo_$2zZH0r=GOn2KxYWDL`37jbHUlSPX;dp=e^%N@Fn1ke-U_9 zARgELxNT`uKwztg+m^P81h{LdP9(q=#*T}4xEbgSI6J5&kve^2%jl?!8GD zywZAayf^lB?M*?)BZ+QJEeP4uXEZm1P%e5*I^$r}M5!MMoQsgWon8h`ThcUZg+8mg z8l0nLD?PoA1-#8J z2j|p{x7ihf^Desz-1I;8;B9s_1k5RKvui{|TyWS1t_x%j_L#Ncmw$d))4P4Bc5@-!v3c0eB1N-y=Vy7oH$Om5uD?CjNqIHbP#+z z#``$Ir+|00T-QGn<^-e%0_Y6dgEN+7aF$@ED}gr@oRdt>d~(6*6N`~>0k}1pu|KC) zMG$aLZ3+@t0#2Vu0AB{qE_M|Xs1W*3fLDRDU@vNJ=l?YjFyXfmU?(`IV*9}NgL7Q} z3cLZl6KXCN8I9iPY~L9?3Os2e=Krj^Uv%A?;W$eK_z?-r2k(lAIIXS#*Dt2pgVXRW z;GCFr(Y7}6?*VUI|L1)ExCp@cf5hKh3HV%KH!>Or&O4;-;OXGZ=tl5-aAv5VA30hG z0ZmYe0OjEPm`54-2EiAAZv*Fz$`F(0@HV*;^PVsRJO-TlysPzr zbKZ~w{d92pPy%?C<7WQrj#vot5r8F_f)bPn9tHhn;PfHh?N)=gMf|*1tOa*7CEfmb zb6E!gO~6;-j(~HWfOp4dz?m@DeA+zgYK~K}lb5++-CGwre7EbRxqbezK2&gp5$H*y z_e3b4OuoVKIFzgmJPw@wL=AX1aP||QfcMti^goT?VK@uH00f{3INk1wk|iQxu6$;J zb5P-WKsGq1+guMQ1lRG~^gS*JltREM7uN$efV0ElVsfqETzozRPE)SO;M4$4r{2t$ zfFhrBHe-Oj2+#qXCHoRQ4txM=g7=C!Lcf)^h3Rl6f^#hB44&_YKs&iT`a)130*vEK z2Amn448BD0O54T8d;d73yUw7ayPp1Yv`;4?SHK0+5#>z)o;x zh<*DZ@XknJCiJ};S1^5Pj|t$-!A(Z3{WBm)gn$bLDd3sl?CD~`3&49I0e02p;Ouas zpuZM89{RegcJu#Q2;v}MUtKREVpn|}yc_h{RkwM;mAET7yX0hW*3fC|jQT&YZSXs< zX8Z2ubFE-LS^@be%k_>0crWjevcaptsn1pNTqMj}Fy1*8fSdlu9=t^=qyU^d9Et?z z9nyTkd52UYIOqQh1#g`HmkI&rbW6Z>zhn>I7c3L{ye}vhoO8z2A|A{!{oYy#cnkI- z=6Y2k00*0DkpLgFZ4#VM&1wXH0`YILT-QHKwhDqB2*3<+x?KxSeLjBMB@*D{w>^UM z;ZDnBmyY|Gmww*>Jq) zaNGu*9TA7)WN;40oDpS%vzaBJ-Isu~pBT@MZnK#GFF=4DBBDz0dT^HDAov;ZPR>Ug zzm|K`_u8gG#~NLu!J{ANAKufpsypg6-Oy3)Bg^&wjSL;Nyr0191n;EZ7_|?f1s@LH zAoxLk1R(B3X969sJ$9pHS>WtIwu9$@b5z_2J|CQu)iUs<;L(VmHSMo}paldRRH{V+ zO<=Q~;OyHu?AC#EIzJN$9|5PyCV-!H-0yKv$$%hci>nE8I!lt^DbUXX=kT2XULbfZ zcqzE6Io|?tPOUfy)qu-EWj{E*eU7!U{*Q?8A?*nESV{h5=vecJ;b#6{BLo`| zpjPl_!RrKn8GOIs-&wA2O((mAb7A6B;JKQc{>S5J_A3O{2*A;-OJC>Jn*<*PUIWe= z`UO>e1~tSEild+Rk~6W6-=^|<(N_hjxj|)|JS3CxkcIufgDuo!FlV%x!zH5Hb2e{ zo4@Rwi~3P;#x~$|Qa4%E^Z#TB*zPM4AQPNDBd6yR!P%7_gMJ}6ovRCa%p!1h?XAJ9 z3^%!9fJ)r6eG{%Vf{uAAer8%b6+JO6(qE0pm?_rAHgMKPsco8i_XGL_Hu3wwdps4| z8L?>|LOjeKt z&}uydr|XSy-0$^A;pls%2*BpQ5x%!n@a^E`g6{^e5d0u`RS4IeGo8CSM4<0k;TJW6 z)48{SvjChvGzfi8AI=E=i^-5(9DK!99ZSriB2sV;714szPvgM3QcK592d5Lz?}ln_ z2PfIFO+*0ccSYdR?^c7;@7Pb(fYT>94XF!o434l(0|Z=yb{&}B=C|F|5P1Uhdw?^6 z@i5s4!6!h!K=7H(b^4}fUMdn8f`~Q1#;&Kjbja=}?cGhvWI5zk`W0nZ1wHxb4O zCm`XaBEU@Wa={mXR|sB=1gZp|0$wfnc+K4tDj^tx0NVub2VN^U+sZC*)=(5`Vh=c7 zla2AvtGGj@3A!MGBM3kzDnp6Sh=lq0)7ug1jC@=gDL7ZQqZ_&F1UxQn$21C@xAQ@8 zoZx(L+(U3aX!Z%t;WHVWHMG)?`B@qStRi-lnIa-S;?4%=ohToP7YO}DIwjM~6bZf( z++QLDT+A;Od@}+p75pvma>4h4R|x(kc$MS+#^%SFYBd6!>nz}Lh}j|{;t;a~oHfVM ze-F4$&mJ5Z>O$hz_UAO>5Cm+;vGCrbAp!KiwE;g3PUlSlKMT$bab#%znsZWSD8uNR zK{y%$mUsdp>Hy9)_%iSwLcbC`37i?~hmj-=T&vk*BlJgTZvCG*+73acNMJX3j);|FzI(fob|(jt88bPF;rp z0};^`HUa(i0_O2LHG51!!f{jFjYU`JPe8)WUk~j7XM(o@ztZY!W3yk$hJYpJjb#CN zOC-RKYoXw5t>xgCLBANLuLWnpY^yZReii~Qt+83gyx~f~3~`J|6r5vCIyg-kixQ6j z=fpArJXiDXCX*}~edTvEjt3pf`>Bj6+E?ZyB1#{I336cq-t(=4$?BhWrs0j~9`NXD z$LZ5QfX4~mBFXqxN6+WD{{J1wRBs5f5P%8LlqJY0Ym}y3EjUeC1J1{^H07=ku6>10 zS`R^6WQaCC6B5Al*z-o$I#cS#Xb+k=4xAQX>q`>)*7U|#hC;x#fGF598=O5XeIj2Z zK%Xc9X94IF<>0IdHsfl|ZO2GwWINs=639S?>cFYbW_d*Lnb1E2&Kfc-M|xO2V@1YDRXLquJ{dHYido(|p`Cg_I*vca{QJvKr=7n}vy&byQO5U{FuBft{D z4}z~2{22HKaN52LGPDhxCTJ@r*2FJJ;3zm-0f&x=w_KHybLfZzr|rMO z*pv+Jr(hohSrE{P-Ucra5xodr3Qik80bUNynpg$CAynV*CFqdGDYihsDoO$02~N{w zfbSOxEJgxH!C8O_(D&YUHN*nXv|KOU#Xvx(SbzYD;4DEg5=a;NQ^2zY9}ivtuA{Zb z5bzSijsJ64?+3vW1fcD^fUgE;D=0%oYrxqGc)PF@T)U1vc)L&sZVGJMAMY2AK)|Zz z?ZRondAks?(^V<;dAraCoHaLD4+_S_J-}&VJ84}2ElK(gPeX8$kEmH zf1X#2(XSMvAIJO0!OI2z0K7`@pTKJb?{c{tcDI3ZnD%qcb`x?+0hd&31Yd=k*aA-5 zKLNfIoE;JO9@L9?@NmTM9T9>|8LiFnedI(^o}Uo_VXBOSds5z(DCfS#j)vjkO$ zs7ge{DVh%nw?WNuiZ&FS8RZl$`yDKd(1|!l%NGGSMVk-K=f<3(m4dUM;1sP~#KS3C z6?j|BKN@e2w?V)XaC*K+BoKw+_>kb7q8$hCgqnzje)D&o53zM5@X>t_2)MGGf&e4H zX-iJgGQnA;8PJ~y&aq$ucoBF!GBgw1zZwEo9p`8pz#B(J1lR`NI0%977y6uv9R+8N zZiN0>$Mx2IVfK&e!MgsNV^obY2yxoSK~piC-IGJgV}nNMH(hpR8?dx!*9A>kyE0LS@ckw7dGP7?{x`$vfQ*;=wSw@%0s{D_2eL;`H@ z6GZ~-9|}YQ+tD27gEM}1KqZ0rZTcR2zJ(%znTTkqNMHinyGS4dyaJqq+bbA7y=iN# zS8-JBe2z}vcw;pJaMHSOmcV!B>LU z3%(xwsNkEy8w7s~{0w;G{*k>9c)Ojq>q~ol2_7l>#wu9o6tHT;OE>92+r@n)eFw|!;cEi|76-AIKQZOW;bp^X##$N&-);> z74V-(L<-JN`9%xPPXfjW-uOvCa@YTP9>0Rvg96+5Jda;Z^a;+dEG7%y_~N_Z{HGHm z1o!j%j#)y$??L7W&hJO&3eN9M76{JII2H+x?^gP~5+UH{7fS`_w*{99&ab4E3(l{k zRS3?Hq*Yn2>z}sgSJJ9Q0DdK{MsR*5ZJXfyN?NVp{7BlaU~cTsucXxl3pD3f(hdmD zucXxr&ab2$6`cPCqd{={s{)`at-(z@tLR$epa1|*y7c!#3IlO*qhuw}|I&NnF zfKylLEiGnLY_mr^o#)MC2Smh)L%4oV%iJxeZ*=3g4-rLy7lCsD;!^Mu!AFCaHpYYY z$J^*QB+MHQ-bN>Zw?)Fdjm`w;Y`F0*8oV9!dH1_e#B;M66{1$keNMJ8` zSCPP%;J!ctwgH|3PZRpB&e1)IX*MGu(7tAmN?Q~0-s*KMljGM8P{&I3quXrgQ###t zEPBNgHyB*!n*&}dI9pAQh=={qMDVW25Bs4~$Nl>A`|e;zRE+>#z}XS)0q+dX+xP}> zt}_(tl9-B!_{f=(3mNQ@V?wyL8hf%u&PXIpx&ZVK5;9ebC4ST>LsJa*}Fb8|mG6e8} zGeec&L%~_q>;Q8F-w6G}0C%lsI|QW=u&Q^1uLfsT9|W%sL}W93419-(hdpeah^KY9 zPTx4o5eQf^cClv!=ek1kk6jJv#$^w-vbUdQJ97Ls-D<>Ql@%~UaehR^j)f&i1gE!i zVv+@}y8(OLZJVXuT`%Sb+rWED#a;6=aH7EokS+ogf@cYyfr#P` zgl0%VKUe6#30_3*`aiwbj8!BeI*tIP41kQby~35OT<{6VP}OIl85#urD(JHr`)5N? zBLtkHh5q~Cb%HNo4SgOO&reR@@70R{UG@Gu(-AcYUd$R25sibs_iShf zJI%G1W>;D;4>9YtBCjuM<_X$285#|0fv}BQ2xdNmM{ma3#g1NE(5JVLB zuh595AV4kxaAMQDaDOm`)#68eL{YXs*k zJhwhHp4rf^eHQ<9fhDVipiV@@CmwN!LnC?*`t?HpNAL#0`9!6@F&@8XkGMguWZrYm ziI|~G@MyvL$foMc&Sf>;fpb>vuZExl1e{jy6cKS+eFVG{^f|4LIN~zIcsQ$$17}9Lkulxzz<*uf zv^p07m_QWfbfqGJDcVM6>b6!S5X(6rI7^%WegNFfCAIxiAUF;|3`#a02}FGDO2)Zi z2J~aVIa!?mo(RtMhMC|)MLa`H{AT{20|BSc3lN}CL{tX81iURWS_!^Z#KUQL4LCEp z5&AndxBkzZZinEINMJYkX_3G|@W^jm4Kab%sJRZ{G(i*aWN>W)o4)sBn6qUj1T?`f zNFX1aCWykIQUcD|bEW0+-mgb=Nr9F;;XE=UdZHvFm9$<$I3&dB?ptr_Y+Y7x8d0jRjdLIBV)r$H#lxh3vr^c}8UDRhzKhASIrt z(iAU4pYeP;Se5P2E>I6n6ODn1egJ1{W&y%lx{6>UVF4}_oCWA9IP-Ib<9?5=_P@I~M(*k8aO*4%bn z6ikGm1_7AUDd4-nnea^T!{F>7=YpRF=U`d_9@E;@gtn~fIQ1^mXu0z?twn;Q#hR zKojhNAiPbev+M(p1!qPNf+vDAp2OfnL_9~qZvgkx#wQ>s76JYXem^*E{~P!Qa5`Ot z-ic*ubUQdRbRPJ}q1^Aag5W3w%usu9??P7-O!$cH=vsR1!Rd7W22TQ~)1A`XjE$wK zS+>2zVQf5ah{>qgZh!!~K=x>51ueZv;Iw6X@M3V0Y4#l26&UUuI8B0vEVV_CSBY9avf)&aAtHC z_&gEMeDE?6&mBW_`o>wF5Q0SrutV_s!2bar>n!G#gP#DW(<$(#?Lu4AW8fXz`9lRy zLeL)pSmI6KW5Aj4i{LZB>2%w{?*`{>!<*pi!A<{Tk6jSF00C|M5%@dcwB;w@2L=Bp z_zA&}fJel*0@LUG|ArtI0^0Hv_+{YC(9ht51owuzcK;V}X0#djOmHUL!g0S>3IUz& zLIkJ)rwKZMzW~mRb^+fh;zp(!mokv z5DD)D-wPgt`G@xb1jitt3HE|FxyaQJGx`~LTX5RA9=sPg>6|!D+IS!*u#)0`eLJwAmR1*eCcO;NJ<}^lBH+ zAKMJ4G z0s(V641AY}C=>iJIO7=){;S{3Vw&+ ze+6F+&WtXxT+jcXgMbO&j{xt3)45iHe*@07>4(81;$6w;bXDMOz-i*A!Fw8R{GYab z4uY!?fcz!!zX-kq{AO_4{%!C@;56lK@HOBjL$>{W48h-m1g6~_0IvmShQ0v*1e^(f z1O7cYP4hi?)6OBb_fB7}(>Kj84g%)%R|H4`XGGz{T{F8zM076rbit#+?-INn_#>VD zE=RO|M+ja<06JYa@DIV6p+xX+1@8y$bqOtT3V1B|MXvwzyg?9L4gsBR1o${`I^7uX zB5*q0wcw@Tbh;bC9|ET-{rM35O$crVe^c;z;Gcri_P2xo08Ueuf`@l?HNgzs>$u-* zCj`q8AQ7B7eF%IoI1^qAemyu%^91-jaJKu6;L9x6_0OEX06~?AXdCz|BBD3I_X++k z`1gYU9lTk$AfGe#-w#1&2j!xaM~VoKDvq{5Uvm+!{QryDKqG84KR7JLdls#6xhI2+#w32smxu8+-yd zP1zrOHaIhM1^D7dj`lYcf(i(jp;6$^fivN8;O~IbG}nXw3!Em%1wRAMj86AM(EJit zMT}@RcsFoHbPM=Zf-eNWUhu`>#o)Ak8MuEr1a!I;5IhCW3{`-?A^79q2f&%pr@>Ew zGvVjK&+lOi?APyfyJIT^2~ME5PPpR@@Dbp2y7$0yz-i-;z-NKel%Ikx4&mDVUqJA1 zh(N!J4*oniZGQs%U2xj+C-8&d%+Md;Cj@UcQnw~E|BvVy+B_~W0?lK=nQ%MsKHxM> zC-4k#n&1-fd~jy8H+YHW*8dsN00>ryh^_+vo8ZI2-w}Ka_!r=`{dM5KfNP&~?QaqU ztr9|8!F2FT1)l>x6r3f#4g4l>ChP~l9h^RQ??|1#sp>Tl(CHpTfGyy3It9KHoHl+O z{4;Pm-P7PF1b-g<9RH=Ew%-cDMc}mk8{mDxY0LM(uLfs^J_5f%@K3>u!2QhW7ZBV7 z0Tccf{84cF$_en7!D)h@!0W)7(LcbCgvR6dnq@c>{3as00K8qIt05-P4!n=xoxn$d z)ApBuPXlL1*V}SE|GyIgmTUk5D8a7+uK{O5kd|1+X5 zAXqFC_!j(8!B2p11*h$Q0^bWxr~3o^7O8-x&h#8!D-{Gz+V8TEr)}@C-@lfe+qt`<9_c)2x$9B z2oU9SH9=cW2k!{Z49x-WC-`mPBfyzaKln|S>-uNH_d;+B0?_Fm1YZtL6DaU%aAx#z z@Eszar@{Xb9FMX8^AMZ}7HGZ|{MEe=ZI;%XF=vS>I6GUjTj)IBnk! z+$VS^@L_^q0zLt}@tZfjAt-`?ORfXJ7lYHrSAi?RhlBqOoEaShUJFiVyv`57ClJtP zlfZufr_H8=H|ytWh&49{ye&90dK-8GI5Wg_{Z|RWy$Fyk_=Dgxz*zzX?gwYhJr2GS zoEdr={3*u+>;KO~upI%I)2-kifivMZz`q7(&AkWy8#rt3Bk;CK!8NDb-=`3CgMc~x z0(>AiGxRO^Xu(f_PZ9hl@Dgwq;19#i{C_zFth#1;6Q7xst^;R=E&zW?@OI$ugEOO@ z!2bo#gf9UZls;LOl%;Clr3U!&7ERecx&=JZ|!_z9c|KM3BUe`pOU z@JqniV?GW(2%I(dH27FQ1kCC45KIGShPHw)6#NbFm4d$qUJcFyd<6amxSv(`DFpi< zV1~W`KPvdQ;J<-0qbI;y4{$Zagnt500Ech+y+0rr0s*V8*=T2)8^Kw17l6+KXGYtB zF9K(VI)PUReu?E~{a*-rBfw5@mS6z*=iscltH4iyGeg6{Ba&TBkdFaxZ+N!$bLR9q z2zny`6P^TqH8`8)bnr>wthqUAMQvKA>&t;#*rw!p+&TJ~;M~Ev3H*Qd(h9!7MBh$T z?MRDk88Oh6jmEjx%EH#TpY`^~|E$iZ*@0Ep^;(;iq9!g!%uvMQ*%q)u--CWtZ|H|R z{d(~99**ZWbNr0vrV*zjGhS!M&mUvC-%G#2<;zu=12^02$WoU=fAR}l zhD!83t2su3*XB4rG{Nz2^yQzu7CA}l2e|6BGcBt9923L4hJSHu5(Q#aR6ID=E;Hn@J(fu8~TJQtlHQ*7@|I%^4 zw*>lybO*i_I?K6DiSy+%Q(oz-Wwu;Xz;fMZx8;S<$CB~!d@Vq!I^L` z1b812k<;^sqlQ?qw0br;TLi6G5X?<=B&)EGbX)Y5r$zQW03lt4i5wPugbm}LsPks` zMJ{&MGoSJ?2h%!>V9^eH%vU13lUG;{Vtwzxa1w+HESKO1IKo2ztaBcvv1GgE<*QI7d`4R$_jC<`*fipw2Xjqvu0XcV`M}xD(<<`=9v|Q5t zE*Q(PL0ia_Zv;5o*R$Z6g1-!&CHNcaa9vubL8T&k=5{qWy8)K^X`%nI$!({W(aT&e z*(MG<>;rBNZ#iMh7WSK!`ePn&fjBfWjXvN^n>9OBa8}WE;Oth9wQyBbAoR~08{ETt z>cM?!=lW^?g;3`B%|us$qnq^TcaI5uR@_S>Q5I?!IL(Yq`n`h?a6Zpcof4caDr&i_ zHTn@-RC~eMGJAltcG#i@TAmvCdN*IG7>WSQDO=99g2$-4_Hjy43mFaF-O9p}0xEv* zL6>iB9D5Ab)-YXJ+`Q}TbsQENt^rRkcf1Z=BkQFF;-NvVhraJ!#Dn;!f=5?c?)Qo= zaS~d#JtCsdvLd^Kvti$Yh)Umd3DjaHL{I1seHw)BH!LK6-F30%$3eg*P0LOb3E#&O zh?3E=w?dyoGF|OX5&uIvo(OgKzO>eM{^vio%2|TxGu-ds?88}6tyepJa$2GXcw5vs z3w|Xy+b=6>tmA>z1Gc@XA^}#^0+9eKs$A&Pa!(3C;VIQtfQ#|=WC$rppu7%a*?;B2S=ZDEV(_a1_P z;}HGzIl<}o?}4*&*-kzeoZfT-oEf4wg+F2ntlg0nNOx*&1)lC4-O=by;Ov<>X-X2D z?tL{l6Q(y^4{m!noxaD0GDAefhINPFbk_%hBhvBEEguDE0qB;S1UIjE*~RQvgf+mt`>1?k4O-PSs1AZX^Z*-%+OW!++5>FHf@SU)m1z!*S1>hVG4}#y_n1C&x$9K_I zfipvUSQU?pi1@bKMsVIb@U6KmA|k$hS1aP-+jJj*^G=6vNb?pAK--?5NI|v#70B~B2-O6C0&u-;<#{>UpiUpgC0PHZ?Z`}vZ0-&Sw z{vT`S9q&ZZ{r|c2B9Kc50heAx2qKEgm0X&1LT>_l>75{;pkjgrk!Ea!DzTuTsKJ5_ zF)E0HVg$u5!Gb83AQrITcjkOP^XTsDd47NW;>)|?ea@VjIdkUB>}IoBO>QU0pSmYz zl5HWklguXM7d%{N?T+w7<>^Uy!WIY*Nc4PFe=RvlZtwWE4c$R*8#GpX&Wv#ORgN%s zFxEr+sBb;D;D2~}x#p$=?!D3;J(GB@ZYy^0Lqi?k5X5}kx;ja2L&6TtlRj>T_%-tX zY%J^$d_;lmfgOSqK5mDg%>8I6FM=sM1TB2rCgk4a4cW0Z#zRpq@MLnh_kXzV3C+zA zB(oR-MN4V&ShEpQ-r)s?16IE{c&H?5u|wAV!I^4?K{l#?WPxlM6iAgqfpP;;ajYh| zeQ<1D%j<%>tl&KIP(yFUp+x^f9ctwDmP4&kTFXSjv$`4PWs}t$5x4o`04k05ff45l zH0DG7*cwSSTfigai=|j1d#FQ+#GpeRszx`9{dy{SaFvv_TbNhKU2?k>f0ul+j~^wE z`1o(+5BThtA7uJfFRC{C1a%=$?g2E&Mt)=AbyaK`xNT5t@+CeV(%g6;QZQ0F7Up;l zqrRGA?C6;lV`xqhK|QtA*Pz)fkY)uoYe%U+-`C??gzFJIg%Pv*YpI|5x4u~;U!vey zU&TFy*Hv*=9F%@2^%nJG|2Cv$$H?!?kjVE@qWZ_0?k14%PXc8=2?Bk0Gor_a`2_M3K0c4UjE~<*-i#fyE7S(^kZ?V!w#ScA z;Lwl?!TV|Qv&gOfr<&XI8TbZ&kN*#TTI}eBuW*(qM$BImRTcF)y-6G~3hWjBbI6^} zC}4RT&Hr1)9W^&Yrk+6x$ufEdktY-2{4hgJ)jVnnq_#s4mUbz1wHBC%o5XxEu~K+l zb&6qbhh`)BpFVCAbGREiP>uGVrv1&$cvfN!?V%yHe3htL{vit_o2?aYhv2y8|IHJp zMPEO@h81^b#ibLoKh>Wc?P3A-vX}QIcYTJ&3a_gIz7EW${&=7M_2iR<>zK2SjZ-k)SKuLX=M`^* zc94f&^>RDX6~n6s4F6XFEz8$i1eqh`o2lQJ zJT$_qe+hZg$NOt8XM1WS3dCt>f-OMqlFuhsS3uwL+sIvV8)Em8r+xZQlRKkknf@zf z4eg~MHVPHwM5>h86iJUqdmH+TH8ci1P5p{``(X65&)H?7B=#Lqk#EDGK%_^0Rt&e#3GxmJ9P* z=O5(RJ%~NaD~&Yf^dsf>d3gi!44na0LsbKk)L|iF^RC6= zHaSG=^ul(|9W_e26=Ua;Vnk2b6-aG0$zRZ1)>-O1(T)AG}LUZHJW~{)bii^ox`YIkIysl~{9n-O8TQrUZ zF7Oq&o&|#RM34=-O>X3ulx`G&i~+9 zRvg@oiZgV@59Deuc$%jbe`sFKtSd40jM-gPOT6=i4wOc6h_=w5JiHM+ z&GEijy4ti!?X-7x>25F8ZSuVJLY{qB_z} z{3BGHr04pOJAaRcYJ@$Qn8-h>=f@m5^thhYg?uA;hw!>8$#@UZFAtJuef(K57k!nr zX2$3@`eg&?Bl6r>@GPg5?Ui#gdd0x~&u8uzk=q3R6YXSY(LVP+#av9cNndx!Pq<%q zC?P)Y?(0--tyStjkFxt`V|Kpg#^+(5&%2Wk^6_E9_0JZp^zNLeQh(T&y!vb>^z{^6 z;WHE`cYXX`^6@_Yvhcd9k+0&ziK4IdnErsnUvg+uriiJplP;xSLHfKAd8`Y#y``ie zapagb(pwI-MpDcD3tF)%#)eXpMI61FVl_v<(XSB0dNFzST5vZ{#OeX^+$G?F_TW3n zlhh9Zt9Qvm3!xuoR-tPkuoWCf>;J%^Y~sYXx-T{5(4*N{jPGQhJA0E)_wi}u z5g)%DRyX4Cs2rlti*mlotU(9|*n>C7vp)U-dCtebCRb~{c77!f_;|^2rc?PXl;aar zgFw0DocF3xV$pH!lQwebQK+>{!cvdYkGx1cko?h|;H8S8Ka<63JvGh}1XR&7V&cozgsBiZ%JIRwi{Wr;9C%5|Vf=5-xC-{y9KJf8k;}Hv4AI~R0 z=Hm^>b3WcqbMars_$jJXtOUB&i3Lvi3JfAwz8)8mm+|qrej@)~%tilTvETz< zb9PB7^9_nsX0g%}VJ`5Vx2p{`Hv<_X*vm=2>p(tCg9AgfZQRsfi(=Jr{Scv7TFy+EEmAKY%*4$!{qYveKT$|~X$_}UfwAMMJ8|9iXA{r-Eq zBIN#d#eLQPr(H>(fbBZN{-pj#yV5iNd%NN@{(HMZQFQ9exPUM(B^fixULE@x7lbqD!i8dnWVcV z1Y8CJixrz<`k_w+eZ?H%wUp~C)*+F1T6ZHXho~!B`U*)PB4z_LKAk*FUX^?fdBmr` zfIQ~o3(4a?ej|8gmGlXgqj~G)(B=^qPg5(#W;{V2%15)c2jt}|7OD(!$X6^z9wUDi z&M-gbY?76#^52~iAh*sizaC@sgFb!pLmq~QeEcYR*vIMA5z6%mtXCsGZoL}w@#Cx@ z?&JDSR5Rv2?ZyJDjn< zlDmDuGqhiJni;`*dILj4B`BzuxczS(%gyBw?Ep2E{NB6u9zh=a8r)vOn4!7sTt}h0 za9NnWiQF9lo@DdxA&*}Hj?U^2zQ9|k2n7zC_YMn0CbB?z2y$rl863(d-pMPdkyi_c zCOBLuhiKR7Xri+K7Se2@4bEe}pt3=j^Kl!rr~F*oH*@1u9dyRFd?>iS^QNv>U}uZE z4QKpzsBM&&@o|?O$lgF-vcNP}+}&q?4)v4EjJ`gb2-26=QIHYAKm2C$$XZn3@_JC5 z+*uADCSRwy>2ZcV4$!`xby;$0rwLd)y^j4`pt+rnIUnb|R_)m{>mfTGLq7fpM%s>O zz~?|aqBVWoj;Q13?B5cfV>zN~vyVR``gNnKna_|N>7b9>k^8`B$VNbWpT2c$#Mf`@ z*ZIQrOtFr#j*a;W>}1bg_i^j+jE`G~pYrkDUWbQ#?X?c??&H?sVLxZHYS#146gpN7 z^XdO*YK43StOH$N0XqSW|p?i`vY3~g4MB0&6&0w8sl&Q4xMr6kAsWDOdPJqVGRyX;jj;f z!#MmZhiK`UX3C%Vo7Z#9Kjal4XSTOk)g=E9;F~VwfAeMK4tdG~9$Ra!*WKvfKCb?M zH7N8y8q^OJvtFH3?aSUWHJ_1Xm(?O&z+48-p1^`>hsfSab)8Rtw&>SV&M};oWQ(JQ z>#Q9PwO(zN+-_&St0xuw$Q7Amafjw+Ym&&7D5xq|uGLS_2(isiNlAT%!zS3Qv0HPq zmOJAni>AGn`!;LpPCK@XpRgvH{mdOQ3{-b2xl-8&Jd8($G ze6rRc@}iX_(7BfL(7oi+*jD<|&!g@2$D{j&jvfW`-*Ca1)d-;zonOuTR9KjCr|wmhCW^R zBYAwnSj}}haYU>=quXIB_@VV*cZrE6JVarUTmH0Se+2Bn!L_zmGiK20c!}zIu^d_2~yfhrdT2zYqGhLAgYm zG6gl-l)94r+s%Hn`r70#UF>yW%fz;_dYn2^>~6%cXIN|y`P{}RHh`_0On$6B_+0Yq z$Wy!q79+odTphwV*~`xx!CR@n*7O$DrIk=(7YiJk3!W(lUgde+zdQ4bRhjS&H8L|y zX#W%0d2`@_+_FK!Gjv>a^7Lsq)FnTUJUa;^Y(Kl{YPhMX-9T!D9)nM_Vpo6bo;(xQ z_mt^Zh!z*vlF{Y*UB1rI!+cl8x3J_V>k(~wwUyTk4b>+Pw&pck=9P}*nUZk6OFoo* zym=(Q(sN$_TVB&BNZx@4**kO=TkgX9HvI1=kIc|_PUu&b6>KL@-+@3)v!VM8H>1_& zQ~j=iE)l;kr2qc&I?a-y?=ka(9IXn8MQ7<5P-7lE6F)sb$^^MQo~OAP!q7>qacqa` zOZ`&I5um?SKvi?dd$;q>jAi7Zs+a+G-aZT-)oTx2>9EPWSs;Cw(Z!yAsJUs-u~Xg# zouq#7F~qkW!eUpUV}XrDVmU%PmB>Sz&5-L2M}Q7#NI~k_!JYz_kawMlX|RSnj?v`7 zd<1QP9k`nO=s2WElv3&rYv0_pu3rJ;X}u<^%@m|7dtLN&;@%2+g!WJzFn2cVmksv! z$<^na*zDl9ww~)SIRYHIQdh$vshS7`SFGtKkcYnY+Gz*gN=1GcBC2-ida%HVVptPD zE(uHH3^%b@a-Mw`T|(V&J0dI)WJ;~qJYQc7cI&S~VGhD`)c>hB+*Yd;#GjJysOJr@ z6XXwiS%%-wnN`&QDHn;@@Dt`MQAsIHP!1A)JnBmo*Ja#Ff zHBLT(Jegyd($00{vu`rd(p0HySn);*)Dzx``;_4(jG}K)qvy3~@_Q`#Th%;7>t?KAnD2i;d1a^j)n%3 z2ZkfQtq&(_ZgQ4$8ad0Jt6U>IU+1z}V%TH>^NNWbyw~3dURk-ITyza>r|KciWGUWA zt`=f;#yC?Rv-;gIK0)fgMn1YdoLN=Jrg`Pa)9c{04Et2#S_Vw;YIx0dwvHB|+Q zKq|9)nW^OQE^us)72j<2n|gEQTFW<>j{R$kkfNZ>b|j3^9EmT;QxBsDL3-j8`BP23 zo-1)ZJP|2_2(S&RLLMj&F1I0?2&_+m+tj-{Tuh#sK1}+QmcL33OB7ZwI43{!fVX4U z7_8SImWq9Y@s6?7dh+lE2v|EKw~-$(Pgm8i=^UUVZ@hXf@ICN;yf{i+M!w(t1fYJ|;q6bJi89epeNpJ96xzdZ89bL7*?H>-aqVj<1?hmgA$d*{al^5k&@p$*RY;GI-# z2ON@NdzZ67e9lB^uXV_Mhe>HO&>--r%8kc7cUbW}7I3~rKjQ4)t>iOe=yzK#Mq9~4 zvk<%1&LQ&gLl6j6N}__J*8U*VplSM4i9Ps}g48YOnVn3Pm$1icnLapj7m#NjK*ZXC z=tCYbU-8thEIXh-HFOGU6x~4aRp!T~^s8hkIjB|S$tPjX4)~**o9&S6`#9+h>MP%N z?<1+E?s1Ak?@to@hgzVT61VE!$c#J3ywf8YGv5c-uRsH6v>}h1#~$ccnEmZZ{=hk1 zh0m40NMC^-A)jOg_ZWdR?K%C<^f~O?0)9`E$?Axi z6o>8)@=VbLX;g|$E3*_$OAZ(>Bv~7RdX}G$A&PK_E(RZ=!k=Q#5Tl`fT3{NKT!Rfy z8S-H?lwItd?Gf_KHwa>MRH>U2vm5B-v0BXO+miVSj7gp5wVA~(+veSpzfYc<1Vaw{ zeO&D5EAl=+{Z0MkLGL83wM_gGRq5McC`8wv4}ogb8x`BUJ(T>Z4PB&xGvu#QQ^>>S zyS4gd7wI|Vfx4`i_Lo`yt%-$M`jaOLHd7G45{?RpIi+4CPgTP}M92@3=N0u7Vzb!^ z@@#jneud?Xsgkwry9wu+cP8-XqRtp?hsY!5al86uQ`<1|)OPQA*L3pa9p1se(Qt|5 zJE;*nokg`S3tU8=+k&p!02@fYa%m^g{ENd@L>}02h447-TqT_UP>GpM3d$9&pl&)k zMg(EDel2;IhTeSg1i53LoS|QK=wBlrZhlHuzs|2I2lalUsEM9a$0<(T249Ccr%SHH zXh$}AH(_^LI<^|Lh{wVYuU7p!*!Fh!_nj*tLjeu`2GEa*zjRV;9lkt>#@#Sgs#~)g~)pCHA}=0;V{N-STK#=}r9loIIE*}& zfqffdGli==s}##Gd6Ri>0=w=iYJXq4vsl@~X}`^CMBk!@Tf^)3FUUi?QBQ_$`Q7p| z(6<>c|4#JJ*@=yp9q<<9@s%7uj%!GBeX3twDSmJfVg=ny0n_*igG5DN@X1>R8HaK< zO)fsy8*?|42PXCxeTS3a9`f*$Xo79>lZMOu-(xj4Lc^w-&&Y3BP$(7)+4%3s0|Vil z9JgkFlE3D=*Q3&1bk5^&T8KSq46f(j4FjYCyB>68fxvjoTUVq?jUZ2&N66@x!vyD)9pnH+-?Xv#jtyiTs1(V3P|-z9Vd@hN5zU2 zl)M`~R`;XF8S*;hu?4U%`Nepztrj$p!5B!Dz_%Di#bKOD?o9Tskyn%du&cK;YA9oT z9r-=J?d6N)?m;v;&8B6*^=$-q4H82cj?$Mb5adU7j!1QmBTw>LoXs5Nb-0?05}yn^ z(nnp!A&>BD1?fsKbOHGxDKna~PR;Bn+ZB<%qsJV%SoXgb7 zvAu}A`t&ZMIh!f6D|ic)e#TqD2o?x`1YafTlStzB^REl8$O5MG5~%g_^x$bY*Q=^(E( z^jDHQ7kPv8p2U&1+ObdAdK!)s{WROVk36yz1M9My!a86 zBxYZvFE_TQctbDb*D=g4gUD0oco&En|mY5+l2iba2+xWbUm!n1nGHLr5_pi{Zqyd%jt~VIJu>yKC#saa@=%9_|1iAAP^mBB}!{mW&m7AUz9o=9y#ET_?7Ra0~0@GKui$(*iQQ9m|zf@mf& zjOtSIxOv8-ex=NxsQ!N#1$S-7>adZyY7%*HmTOd%YKg=3sdQ z&y%Zj5tA;n)_ay$LHe^D`-*(1%)ID7A#<7nXAvCrg~H3Z7aq!1LQG~@!Nue^9_}oP zuQr4JaPpNQG}MOVO!CZ!7*Sb=b^U6g7MK*}`YuN3^m=k9d1^lvWE&zGaDDBt z$m_AAERY-@7Smx4;TiIvFQzKrkA6EZOc4Dn=72hfTunwy1&g7jZH2Sda*slv%cvUp z6KzaafVc;F>b4>Q0s3I1<@dukVVb_uaI*%sTTPAhv9VGz!rYi55C4Vo3CKCuc z57=#JoB~zg-QRB_cZa~YHga}pF5A!=-fifY)Q@$9epZ^L)ZgTx%HTP}O&+TAAbOm; z*R)8#7!J+Jv)_*t9AwJBh+K`t5F|O+my?H^qXO%RBCDT+ha9n{)NIY8vQsU~8XRL!HEc0tlCw$&B#Z|v!C{BA_6-Ee^3zN z^^c%PwRaM?7wX%^+B^hDISL&Nvg5r(9Gyh*SGQx2i0P`-GV<&QOaeQ_ljNBR-mLPJ zt){mt_1jC|Z<2>{h)kE`^c8qz^*O)5!>px#MY{r<(d@vBuon)AS=E%>eUULWe{|F5LL*?5HrY{1=+$m^mP&Q)4$I=*BSI$lPU^uzO6 z?6`bA;Gb^?yh9#*!JDJLCQp_}Vo%df$%oPJF|!MWbRe%JTrROsIEOleUcu--PoJGn zo^I#$&E=L)K)B@?C8NmW>luce)H4j13pLkKBl4p+?r$gm{nbv=z9DSEW134?l=ddN z52)|*^fAC*eMcU@3N5x*&5J)GUeNI{9BvD-g31u6EbpC9GVq#eZZ2e~5)me@chg~%p?K1CI51ubJZm4XQja|JFy^z% zW}OGFpJ2EVF0%Wqo-ClIj}_H8D{!r$O_)~^#!iGh!h2wB1?Fq*W~Y3L_Zr*zah=vT zJS&&{^uSs{oQ8tF9m`ho^rM&{N%mkb`7OR1?!F>dwV4VT%zu*q@$WA^n9A!sYNPx- z^G=_a#h>-g(L(ZM({WOHnkI*n2T!1BHaHhpUd$DJCnN{8oIH1>cNT2~@1~NMVK8#6 z;8_-knFo{Vm%TCf4RTes_R#r{1Woi z9CXDF??CcBKO>KyGu1LHc%z@RB)|fj z$dlVJ5@C+*>*S%6$W%${f1r6kHVISN)Sxy;5z+<1_mT z39^FDnwtu`kMl0^qlD`(u=;M1pKa`zAgp^MEykXOPrhZ>*IA9|R@7IAWRywEyu`5OaiY#UUnP$l;u}D9XhQM`5<0uw0-Rcu1`Oi7abZJ#sVtUM;ers zzxu{4&Be=2ymB$_v{;`_-rj6|NkhWr(B=kO4%ufri(5j7m5;NZK30zN7S z{v~;a7kym%@K^G9X-o|GPyd+X6YxZG8Nw&djy=3vJxqL>_C1iuFjz>mG9FXg~S4OFK_$E~gTSb#V16rj|o25E;wV zLPI~1hnb>W@(NF)$Ke43gxKVHF8Tb<-Gx8h9|igdm-mTt`xaD)j?lokX1ed9&Quym z4MvuYu;n+Ct1@2KZzRv%Jy5KNnHqNdM;{(@IV2x~>+fkeCK&Y9eOB;23)H`-i}349 z$wB=|e#dzTwzIkSDEAaR5SxdF+LN*tR?toOY(iS?nNp6{0EDdfSU zhy@!|*OO<8Fy?8rQ>`)Fq=1qS+jr3&)J<=OZjQPilYh4WQ+f}bQ1)pCau&mCH|!0_ zgS@xJI;|afb~v0Fq5VGK-PBY4I}3`?{li%x(`k(G6ldHd%WGn|Yz0xnWpQ0Wjo1!^ zwAI)|o?3-Tk8^FM-XxDagGi6Ci-*bGzu*$or*B3f?^7L%8yuiN8`v%`(Pw9~uzFh` zHiST>>LSKNOcEW)m+}ty5PdR)JjrnjlFuerpK*-ns=G8dGbAUeUIz{BtLJTj5;%Lx zR)M8`wt`J2!t|QMsc?im@Ekheh*bYpP~t>b?+)^w!I+0%L6@Lj z+NWPZ>VHH2^CpZ=I|fIk=NR73B^aI%1@$3N*~>A^)~oHva|69z?M}XH2U3dN{4OL9 z4;U^D3a~+I$df0H^UR{0FLHGs1@WWf1mx(6XUGHVygkm4s~-l7ev%a&B~QJA(TS9X z{XZ-}zmtGQW;0-x!NBv{6(-m8X{z6usdt5Mak|iG=yR3WdBde>O#Uj>pZY=Hhp3;| z)?Z?l>@|ZWoq6!G9hODp;W_A(?d)pu)Ev|ler$jwqOVO-id`mUZoQbfsatD zAIG@Y25X+ReAwkyzp);;HA!nAV?m*8I#Yhvpo|hhUg?RQj2A)R(uuo zS^xDc7Wl!NEY^_+U-sszr^%PC#Ne!9v)&+&OyJ-%D2{-)QYC#K6#vWushU`xZT2d$ zgM(bM)_>leXWvB&%{x87fz#gD8?3oGQ*u)?r9n&CtjW~B#CLD$Qqk8RS^2&xaj&)i z+eoqCUIjysf>&2r-VPjK17y}Y%*&iT&{gZ3#j8(gHtnXLm%=$(_yelK9M{$6+x3_R9s8$%<%HK z)t?CWWZ9R^;MJ8=AB{`0f?Y-+?s=a@H~TKG{!X6m3zP9uC|YVKx~m4lZFZ4y$O9XS zpvWelN1oow7SL@S!K3QCMac5MaHjUx0+U13YRrh5Z1N-;sy^*4fp%6-iq=e-0E zB{w3`XUJ=j$0z=4D(d>x`C5=)Oh1p0XFGPk(vJm#%a8-?$@nz#1Kco#*r3Ja?loZ{ zHr3om9(xmsKFkI^tGS%iI8!*r6zpYz;9saXLYHRA<5gGzJ@>Qb4fO19IiQPF{4pC; zA`MTtk9yBfYmmoE_ZuRrcFbB(Fl0B9YXeq%DS4@Fy+yx%SvjaNnwue;>`NE(67P)E zH`T;h?COz)qW=U#W-WO#gd}R0=%;C}CPU8-#1ZP}-nc^S*soFjCe=jM%N+1t@NbZA zsZJia7z1v33(d{f^;i3@MRccrs4N04C6y^Pjy$#xnJ1J7!2<9WDsTh(VF&y!7D&wX zo~68;C>*WVoR78GcrD`d+Al1Yt-~dZ^{ZFVzg)F3LXzYaEcdmy3HjG+Q2jO3?+RXB zsT$m4ad^iVfyqX7uVm52^Sv#<$7+<^X5U3$p>DbY+#8^^kI7@^*IV@~mWTR}lZQ)k zIEsOnc-6Q=-!wlE3CCu%b2K+=T82-mvBP(+=-1Pq?E3uIK?M0q@vh+cu&?^jP^3NL z!;as0a%U%21^ZF{46Dymc9(W;C0AREH0h{&MnRl{^t8!BCXgq|a{|kfjObR^;n@V#MJJ zefJD_H|0D_ud!*9v_OWdtarF>qM?}iSvUPkF-NR0T$Z|x)W}>9ci4RTj4gRBRuH?B z-$x#9J5DTG{bQCdMj*Kiu)hq~cZ6?V&f)0cDk-C(<5G=IzUostw>PHgM(47=GA0pEz_TWkKY!KmK zSBgEBH|i{wkstK60?p0#?sZ-WzmN^eQa_VIgT#*M%Wo8@Ef|70TU!1#4r)X1pq{I_ z@leYt*oE6v(wRKe#5?y#C60{K8Ez`YxA{J>zJ~nVB!cZL`eQwLCJ1v5{gEQC#s`03 z8PmV$NuI01y#@Q70Ux2}?!_jh4l6irE0~A^VHQw((7#AkL_mtXBDvcMn^v29>Lm)t z>xHcy#i=FU#NU@ZzIUt`N|u1VX_ou$w7uE#5vV>>68d*bHF=xl5PiYc)?%WF9d_y! za(6n>E+jmJAl-G|Dc3HfgzFiQGvJ!ndv^4-$hQMgJBomh}x z)Q?J`;%KIA{uJ_T4fw}i0K0~KYq86v_A~6(3i8a0m={TH@!|#$$Vl}PFv*zc`^()Om>P4R0 zgLH0_-h{;LN%~>M*H9c=R0Kne`Q_xPOHeFFCp;j>-?@_ZZ3?f z%VAZY zlB-&sg*;Urf*;83+T--3#4YF zfL-q9kcTTWz0uGT^5Af9Qrlp-ba6X1uJ?WU{VnoXYb+fudZ<1izq+6Y2!r~B)t`#E zh_MBw_oM6m`k*IG$!me@t<_yUYUAzacd`^zD4| zVB5Z;7$#pq?rt;n>aA6Xg8Qu@-xJ|pCl9>rot9bhYF{Jw-p3%=_8NNpK~)4t0otj4 zrM_A-4h=GY+w1>JzilRl{=(hE*g|ovRRhh<7An39E_InFIv6g4HUNwWRM?UtZw)4ny0kgjA!Bgy6dkTUZ`bm{G3I>q7 z$2kEw*ptc6d!Uc#$K|iSQAKk(M;Yne&TgfCWFVqanGTrx-=rXZBrGOu63LPW-$Mbr zDCNC_o;mxxo;aI4(+JrMi9)H?I`n!dT&Yd-iRfvA9|83Ix8JCLNe6LA8 zMR_aCstO0-fXrL)e3rZ}d2$6D(3d0Cid_Bb4Ye-d`pb&@u@2;DXt)-bAdmS@^5@e~ zYC7~I)L%{>dTM}>jLiq+*@v($C8_^3c|2pb-g?HxSYS^gKcYVbJ50IijWd8a9d|;+ z(Xt28|6ogRGa8deeAmO73_+0c*38_0tK^qhg4mHLr_nE738{jxnP z^)9E#hhv4?yw`v{@=Q~tfDp544{~>Bf6H1zg8Jd5QH}L(~ zN&X@9JN-BY)`oIx@=#Ow*XG0?P-Z^^YlpEM0wozt0xbUudEDvZ&gK4c4}@0T=8RF29DZG z{ZxhVq8Mj;v*hY>Z$D0hN7a3Uux#B>2^F0E0XnD_qCk!gxkz(acl)n`A}bh3{bWf@ zNtb*Uc|bg_l!H?0cJfdIqpvHq+38^;Fq@`6JE;=?)4QM?AkW^71Qq6>A16;8#H_Ry zPg#r63Lm0V$+IR%Ga`e~n%d;K>gcQuqYKE@rGrJ$MnzBZ_%yF`#*xRq26ySS1>icR zFT|N-oPy;n;FLl9=Gc`@Ug)l z%KHeO2%JFX$<=`;YLKhl!vxs*(Uv^?J7#i_4edc5s)#X4!;BhY`BxK#1Wkuc9aAYt z9)+O@4c(mRKVQ#-IK^)Jp;9hQ@%`l4Dno?F<*!mtk~_YiO?r#`Hs6C~50f`YV?No8 zROVyxhkmTcJ~TK}0X5`9puVo*-R?Cdk6koe6q9UF7xG2>Fmfxn4ID&%qwkwV^T|Wk zm=Mz=6k%wrq`>V9M`bvn?k9JA_rIq#H=z;t{p48I+9@?sni!%-Pm*VPBerFP%%WTN z6NJWFv$1AuV$T|rPvG5baG+9s$b;1}^TX`GSj|nQ2>p4tSgm*nX(1^x4Pz?*$;e&KH9KptGU@z$M}0^BWSWG^&LKeC_+Bo@(U2g0rIQJ<6oo6 zc70n8`}&s9A7_awJfPG)ERgYC`+9~v^a$o}mR&hS?v8`6Wc|?=Pm-rD_GY-UpP|F? zjVAg`-3*(06sWZ@l+_~hYD*sbY^?m-Ugz#de#wVu`s2)Gqck^{vO?Uk*t3!AjK28% zR+fxM&=rSWd5C-iZ?T3{{}M2{x*c6fQ-2S6l22$1u?3%y$L@y(J4U~Q>z`$~nWkx| z`eFFwj~fv`l{q6@l4rh$zRV=;gx=)t0OUsN!g1se_+hoCIgs zAcuTGv`{K=8NWgDwC`uaE+w@UQu&>sK=)EB#nqW#WAnmjoQrx^Cs5)AJBhR9 zpaP%6L#b=MyR>G8%Ra6XHIg;PNs$0of-A^l-Ml$z9(kQfxN`X`DpG5$#kwhKT-Vkc zSFc!&==;=&@P>*QZG1`YK0j7Sx+DaDk~_ElYaFyF{|gg%`6|r^AuXnz=9(KXWqglE z?g*~GNKyyOw%y+h6hrzJh~eH{@<^e7o+z}81>BG~Djp(_zlp23E~n5A^4u8cr`XUB z$nWxfwPf)LdHik^_%pzp<{evmx!=p-R~nnTc)+_@EN zx!t&pAb+=RS5cg8{+g*ilY-peVG-D=cnf*(Tkob|1G%b%9_OT#QrpQp`?jiYSo@cG zWBXIhWy6)c3{%~X*&i&BZG#Hzj;`iWcp?-SFIC!wra5`|1*8DG;p#~4w1=G}8#+R` z{KH(C>@$^mZdvS#QjDpEmhXTAtlhiF?`(~^@p?HJ-fp<;9n#cD|2a-X0Y>#9@?gJ- z!qIP~j%se!m-fE9q>Fux9;bbe*r`mu_EN-(y++#xT%YI-_l`|(Es)RD&WcFIA^EG+ z1R7G@gv7`fkw5(?7N@OCu>Cogc z%}w8vJf~DF`4{zrhv>r+sH@B|_@rnpwiVydPIL0WL+E;jcG`pMUlW>pg;>b3KwlQf zZu6#$apY}xb`gDh@;k@sZ$%u3Xy;bVjc=1@W{G|r?Nn=o>n)}XYD1-(QLvSU;@goD z?X$LCNz}hZ-}-TYVs~ee6u`=_)aT@7eZNI>lKhdhjJ$=!R973{Ew$U|@A6yHYbVDbrL zd+Hi>Vtk$z&!WKLU4miq>&PFR)lG=K*0!8H{Hix?tS49ePE3+^wvbPiCz0{8cNr~w z(FkPj?59fG54uVr`{C#j^6XpQt@rQbp+=KLKT`vBrqOwJ(rO3fu|ntP+>G3u+e z#)p^wb6?x56l9CAZ?sP~`ItOj8KWIwLysp4m+5WBUlhB%56||a+;?zDs1mlbNfxU^ zo_9-6A&1B>B+m^VBE%){MSjKgy@Y&0ekFJ(l^KKmiuL%-ED$P(APE*niM8bMbFe~W zX(*YveYx((6BIkIBMOr&_A+^fkKIeL*t_Hp_d>g_A^(j$+{3$0RQ?|R2polbRS6Vm z2|ijmdy$mv`E?-+r0zif6a!%pdG2=TXIb%N%_ZCaybgqcu+ZpBtlw%&a(iJtc0YOL zv-(KM1*KtNH+ireMn1+Cd`uqL$5oa!{b6}KbUg_(s`?M6>v)n$6M3(H(KHA*+m*i~ zdA6K)D>F!Q>D4dj6}_e=TK$0t7rPI*&T!M)c6U(Y@-3aE9RtguIS-JRXoeY&`K{Cw zwq!I-jdU6wwto7U-0?k?`UH9W25;L-|A-;ay^JAu*!Z)_QzwxpBlJ@%@Tj`1Vi!St zWRmK}0v$r$CXXOb#t`Z@5l%5qoB_^^o)P@DJU!!8XMeR$T z+87qi5a;b=^7LsmD9pYtxB8pVe(bee?6m|g6ySmvdaoSFkI%ZD}{yFCU+&@d?AK^HuZ;TF1}K{NI98;X)F-< zs6Pk;??!T$KPZN3l)8&NT*BLdhc!3*uhc1wMSI%cMt!Ha@u6POgLL8>)=&`w%+8!+ znm5p@kw-!_fy3|A550~-%Fs^jpWwLxEzx6SY<+V#xjPs^pv+k4`c+Q~lAKZjR&xb; zdToCpaSq;<VJS1MA(8wnu{wh z^15;j^_^Fd5v<3a0I#k;xIxo?tAIAYX9Uu;Z&)x$;Nv}@?1Z3F-xcQ1&^xGMi{aaZKf8O<#Mxcxm-d+UEe`heqdL&l2^Xe zn_6~}&$Ci;nC9jRY0`IZ{QcB#$IJS*6VHoB$t~o` z-3WH;%IC-fTM;A<^$(FxZ|_Yl-;!s23(+6o`fkD}m>6iN;_vWD@R707AiKmiA&=ba zt@twXFL`warIZ>)9&UoMNVDtnh4UXOQE^>Cxi(9z?XwYpcHGvHXO@nU0%^AK$wb~d zJt6l{T)Y3}BJRSt{e(Pu0$sD_PLLm6f<#e?6Rg}H=yJT|aIs_OMSb#unD=D38@N7+ z9Pf?u!CGL}gJ!;u*Cx=AYKr*Jv7y(KyT5xIdWYc>9-F8UztNi$o+r;bXn{+M?^=sX z;K=|zc8ol5ODE~#_0<2JJjayhic~)m=TC7-b=4u&T~LR{kkp&Q=UwzT7b+?_ADzmw zs;=ZEJ783*RYS=u$TKq$(Js9|JCVOZ59UIOXAXq3AEY>Gt9czha@g|c$OEO}fgt&Q za&^GFA2~*zK4+Y?$DSVM{bhP8r_1eH$b0>3b$#JIyHs^14_w2#*wx{Nn{lc;i5jXu z#z|2lW;LSA^*ghZ`-o=`_23ot083^L!*-G-pCV5W_qJuf)&I_`{}p-QCv1UjjxByh zMl!0xHQ_*)71xG9)$=`ayrt%{am)9v9s{Z0a{~tG2pc+wyv-bp_n<1MU@^HXm)x4_ zy)P@in}W>6m~LT?^pl25)W1%R8NRP&e?{KA6OtTP6Lp$A?7O44;@{GD6|OZ(>dur# z6Y7%RF{_7w?;P+;z^kig8=``_;HtY3NYh4JlOvf1+4wo+k-LhdOqwMZkteUd0-PJO z)#RB;NRI*9d4}9QiOvNW)_cJ9qm+1ixpt_$K4yV%g|YH)JFUJW&+#k1X{f6|$!m}4 zCgkms5acU8vGrOQJUmi>3#=NGCuIW}{b%vKl!CbjI*IBU7U)eL_yuv|o&~`y@>m$d zo~8b+LUn#w1tTb1tJIHhAP@gmG5puPE=nzp2(a=j2IKE%1{*pYi0xpfzLJhx@-&qFxtpRLk zsl>ha>l9q882X`t==fB&s||VR2E@FbuwBU`J<;zR&AH?UpF>8tHvmHs^1vPfuHNAjTue@hBn>c1PPY zY-5bv>F2%5bGNk^y^k7=#^c0$2^0Pv^7xf-w8NS{viv@57Hqc7k^f#3>%eTbpm<3g zsrua4{;-;Lc_q!Y4_c{58{=Fy$SYPs2vlg+7|~6##ASvX_m%8#-%S{;-2fIdFu6L)Nx}B+B7buts<9u*93y{fKqoP9 zfYs-fmVWDx;;->$vRV+RYztJ7Vu5y+cS1wMthg6>>$AOaHp=SP!O&)DXFhqXm#Mds zQc0%V&GR$M}II5Ze@WReHX}*gwK3vhq}W#OU7I`qt@zvkp^`3Tr4thhb-1m8WWJvBFHhQWWI z85+0F7C~JV=H1=Q8|pS1az~?L#esf=ycjc(bxr)TMM=u~bc zruigxwwdMSyvs`m@=tx&7W$FL_|^Cr?MwiVs;l}Uzx3enUd008&oR&J2I>}ab*CAY zf9~B+kk|b89R*sxg*?cMoiwkWvv#_g4o}nnQ*wZU*;BBW+(-T^xpNQ=ig7bsx;#AO z489Oa@hI{)ZbbEV&|>5%$2)KCA`icY z4TjC1o5^F%5Y|aLd?)y5mE|w**qzl|)=+aqfL-6dA&=yH^HK4$(C;*N2R7Wx87@ml zU20@w7^)q^bX z01HG~ql+$m@+5i1U5LTfwfF&)q;BgokKn}XS)?&5>e zY*76Q@Zp&^Itf2UL#@eU6UPd7c6=?^!~!ZF7RXkGUo8KK{Q2jQ6#CM? z$H`R%lj!wlhHR+P*By;p)Dg_?IQ46g&pFowf*$EXjQtBJa3bTyP^zXJR3UlnBb>6^ zOSS#UGyM82s@G@kjd4+clQhl(74*7nc*r-0&NW=}Qvo&7 zdk_V7whknBBk+|&i?hkqa&*!1`Q+izlSMPbrro5unU!Ha0h4n>Js|pchU!x+yZ1u) zxdK;}x5z`+j}@Ci+B`}=@*1o{l}n*mkn_mhZxHYi)^i7WO3{~$mo4Ohg9r$_3EfE^8iM^phQq%fTt`%E zZzA}D1!9kR&x=oMZq8t0zB8C=mC^Cs0bE#^$GB^uxfzr+2ZerBmr=jEeAQ0Zk0nB> zu@tx;BPBZQ*)`;uhoI@O2X~P_*$oT(j}_pe?c|{@IDfRBI7q&DU?)+WYW|v5ZIEB7 zE%}|1OT3n?f-YrWMs~`GzEZWxop#=A)>ds27{LPR2!_}u zf*Is3#}`TkY>!%KxD3f1)QC)E6Br!Z$YT|}o2EVF;Th<9kkkERYv)pQF~}~S&^+*8 zzJGQG`ua-!am+)zm8o3~zDl3Lf??;?1?0gh$Z0x_$g7b268@}qJ76_Rb8~?~otP!$ zb#`nn^^-eH$MiG_G3=L8klNv$&>L+9w<31zt?RqV)pmF;a1LtDkcYm7eune*BzeVy zT|}{^NqjQHs-wrjSKtZT<8#QreYvL;_=w@(g}ld?h>j`j*^tET&*|WtPw`jfQO|Jp z?{>|NLtOq0nJj$T@IBN|7I;VcY4Y&pNPIRu>?IGLkGTQ`L^j;Q~f_ZzRwEyAfN~vbi{D8;^Aj0p|I3iYRed2@}q3v2MpQU&7diDT|jd%wO;`4OW&*UZMpyT!ot#n=VFPTHO za9K?)@{sS=vva{KtJIU;6{#>$__F@a)NGau^AXq9-c2HouGV5{c4Kd|pJTBYfAl=X zX6z<+S7IE)jQr2Y$M=HU-lYEb~0oQ@GpN8m{s`b$Ss)OOL2U)>|J7v4 z+An6l#+zfF1$aJHpFH*%(to-X8rhCqmBONdmg-Dr?feM+0Q)ozTz|lD77C;&xS0jA zU9g{sFcYmMA9;yvKh?0aP+$jn>OJf;0t~PZ$m44f7ctuZf;{qxImK?MzwgBgPEe5U ziw0#_phDu_UHVbKb?eh1Gm(&NAYVkDz8*YGXZM$4(XkX?`xj1#*U?{BlLz~G6YDZ^ z#b30u&E7&D;E%l7*1cry?Dfva_k^p&L%Ry{qgh+{1FzCACU$Z#xc-uGHAI&^C7r zd0hv1tw!i-=6P=>IG?4ljsD$or6=T#Z%c8uA(7-IRMC`j_Nr-oOGu zKJ7ov0_(}clQ7D0@@<+s5;tjTO!GZV`T%*F*G*&fQS>l*qya42CjUVms|HU7n6PR! z!GHy;pzAJM+}v>7ei>~m@AcK)Vcu8_le?Y0E6!xguZ9;Qw7HP{_5R-7!ad~i>%IEV z3dgnEcc>HLZ-F+Tr#{i#?6s$_LGEB$SKm?po=KfWvtc6?_=DWxvmes5b9Pf>M_+O% z4v#G%|G&o01iZ;&>*G_PY_g<)rGSNCQCUk0w50+`S_*<}VHMe$LfN;lg9wQWiyH({ zUKBqKxS_H{5UY66;D%mN1Bi->1VunEYPgRJB7S@`^Z$?6H_zku+}`I(@|!bf=A1cm zX5KgN(m`^$BK8({l;Mc)Q5FnBf$+AshvrQ3&_17*G%M2z#q~1$i1`$ZQue7JRyT7= z-cfSz_4YGV-;obXg9DLmgs9$HcT)JCF4t|E$)7@g!{UGFWEo;mZ|B3m=CHwO-A&}egHRFd?=*7PWkf`T z{7$Vd_&AIG2kg7Wm&hG&+pRf7KJhqahk1$88FC+Arsra}E|bSTwjY@_>Y&ZY6p;?H(2`jjw~+gN6}q!wcKIc6nMpR{ zng?HXl)TFdbyJ@C^ac5(9mv}=7@M_nF;vL~_JuE-Jks56KtB0X0To&~LcGi#b!S1m z8)mPXW9o0Xm2sp;<21kiCpeQ*(Jz>o%}A5GR*TJ_LE>ky_Yin&YfK&qNv`rw)le%VbP;<1I7eS9B0C|=-8+}g9?2rFzq0mm;S|Bl?*6AhRpr&?z?A&~M4 zs;1`%LbE&8zV$Q&?73yLr;y@BuYKY z$h}i|I7|8UBx)_>*TI!;9R*#Z2@M$YWn4b(nJnD&>>>B@%x3~U6CX&fk5>4kE4omero0$n-*^8`?p=UnnWX6r3$*Da z!ub}Q7-z%nQ6K`NF{fPQH%hLq&3P&1+MG$&`Ojohp3iE@8ED^ByNf*Z1==^O#-mD| z{GXpUZ7rsKQOb*dA^yyadyU-J7u|}|jxWI*h;U;BreMJ@=vR6nhPXHvyY4G%qoG#h zt`&$a7l*izeDQRw*SU1?Q1UTXV_lxl{!Sy07oxvDy6bk$ac*Iwk(rNh^0BRzRpEo~ zyzzt4C!VLgxOcp6MW61IpZ-an%moh=pcBW)6DhY7{R}Se^&W|dWqebmE1VK}4vR+u zdPE~~{|M~4&F-c>x$EEDLsQ;O9#6x3@Y44K$sM_BD`Ct8>l(Rl7lX-j;)osxQ`1E9E5jvP|GOqKz@_Kj zvmX^bDht%~PjHW99Jr5)n*3O-6&;`h-zSf5hC>3nR6eki+*chTX~O@a<`fdvnlI(K zglgBLO>fH2&Fv*u8_xJ#=nk>k4U+5YoKmhe8Ay58HjIIpDi!33MfR~-0xr|`YFcg5i^uZ6fH+--(9*|a1)E8=P-0m`s+p0+Dshm#OtHE{p6$i zA$|W$`6J|sJW<_vlGD2}upji4t9-d6asQNavs^&U(ZZy_d4MrdZ`eJvA4YZfPW zp}#)1--q1)f_<47L!M|*hKAX%spLLpT%+e!^7vM4@55ZqR)9AU$(Bgn<~OUy(66nm z7f$&#xsp6~2<|r-{2=+tTd{0nzbwQV^28nX#QO(%yglsjUIBCJyS2OIZ*?2XH8BaO zB??3ZUqWayrAu;swAvRdgrGwPQohkgm^iPJ&m&Lpp?wR{u2@Cx)t9iVC5Q!ESm5*{ za?A!}KY3^_*2*|X?hyH{lZv$lZi~e!^7vN!i2f$I3iKEc)b*M>MOLlnLF71&PSA=> zC^skHvK%36uKma(f3+#{*c=*g1Gz}K4ZciqwWpl8m=ewTu9S(a`7n8GIi{|ctIclm zkPks?R^P*tt36tb4WjF_6WWgKCDnvhUNCyxe|nP1$~~ro6udX(vJXr@=EtILkhPUsVOF^XW&;r{GyC zNia(M46d|dbjFeLD9UE!&MInPg;?AUt>%%3C&H02U@?GP^hVMMQ2!Wkd3NYTsTOU; z3R74i;&RnnM7D!*JXM(;bcigY^O9v&`(>gt2adHn} z6wPFT?`515aRQ44Vn{|uT)pDd!r*e~|v zw}$e`B?zk+!|)k$?>QcBaJ77i{Ek7z+Ib78|4rzZ*Po~SYJHd$_P>WU4`<;Irn0W%pC}ik_G*tA-pGXY{osPx2lk7v&2j$3tT_p~)y+eFH0m%dsvQKAPP1KE~dx zK}(E$u06c(CHFpUKLmY@{D(HZl>I_rgygHq8LhzNJn-;f8opa&7U z>WY)U}Wl&(wpaLF5Bdo=rTB+_?bB_F)xzgnHibbIkkBV9mXMpyp$Y>s!g=J+Ppe=JZ-!F zCm3Vx9z2!M9YP{O9{Cm#6VF7!CGssvq>~1P;Ensi4~}s>PBnfYe{g7TE%-9?p$A-E zz*-vvl;nVpV1?uX45*iUy5u_Kc}C5NcEt+Hd+%o+W4_uzp86BWGvpC{y@iYjVcDQ&=+V#Q38y_G>-UF;LVq9>^_eJ@xvpVBpb#0? z9MP6Yu69K4q%58{Q{L-E13tQXmTBND^n~c4#pKcHkT;3=e#!9@Naqn+6jM%!Cs-lw z;1-Q8-KV(9KYb5T!kdna7G_i5kiS-nRqJsEUHSmno_q;|@hj2a5;l;@|`pyQ zpDov2cftbkE_hJro1oI;=GE8V+Bl7tD zXxPPuTWiiQ!pi+cp2QtV+1KAd2tGn%Lqt2_f3U*trBL)W`xX$4_2r# z8^)T`^G<8s1$q5U8~oEn|5IKv7#?t?yqk0kxpyzZ;Ljz1+&>Jx7hD=vlZRH?6XIiN z?K!me8l@aOMlrS=A&)+T2_ELS{o81r$bg}VRfeF~{)g?pYG&Q`n>5jde?0o1-~c0> zWp|*T+_?~qnqBrSs?EACHgy3hI~p5c&>=A zE7t{1{a+#OlcBC6?9272@HqJks)AlBVt;;m|Ibg~m`}mq)F)X#Z6Z3dj6SV@6L^9z z+j5Y%lw9w@du%{UbX`x%yC&GD*hq5UFpRNTp5}n}mX8s{;P}|U8r^{W)t6gdLH-04 zh342#H@>8}GPL|{O6trFlPjz|4Khe?cA|Ymd|O;6ZV8YKa!TpV3fv6byIrM;a#;wIL7e z!RqRxyqo-09!+~GKZe{t6PdsyqZ#C(pVb~iu2wEqSZONsNAeU*5sw%?9=p!~8~z7* zJR6=%P|xe+fj)N69XI?mPFh>K8e3jmeWQU}iel z(e~t_b_`YODJ9>Rj^$-|b@X(SzBAP+6C+P0Y;F-ebMg?QVK2@N5`>y#EJVqsv z&ym0U9GeT|;ye#g*=Vh?Fe>&v_Kc=8S4pmygUel20Cau3Qr*d3US4h8(IvEY5ObD`Z?efqdc$*lmsqR*?Jq+T;IG z@(`C&GrM<@d-;G>!`}c8ibq?(j`|$*Q>H>S?4}}g;IHI?Rj|WLJL>x3kLU#MTIoQi zr#yhfu|d6k8XPhpxogn-EpsO&+a-Ce75{K<*rlOlJ5_!*{~e z1Y3VobDYikj50~)_XOMekz9Q)UAt93LZc_1Sl+^m+2|YD~fa z-4G`iIdG?0n@^Dky!Ip33*^yU=nt`HHO6bxGlka!+x;wPr3!S{dO<{l-eRy&Vk~*& zDU4j4MlF(D&)R18S^EIxosYvgW}m!E%QqKJp10&+i8mmhDH41=rt#VdRiL`o-!%hQrJ8E>m3Ij_ypo9i8&7$=HuLXz3H=;VfoI zHva~=yi&IisosoEf))HNv7AS!=nQ#in?2Ysk~?0p?>jOoXjmO^7aP8oTeumvr^7tr>d6WjMBOf;m8Cl=lt9DvXu^`4< z@}pFAfILvso~aY$4!-ElOZi{P#ZC5(Hkt@eM83pSH!;#ya=p`X{A72XhZO=J!V?kW z3G!r0ZkRzHYk^n^utTfJ9o?~G6NM<)M4lMUcTAe3^t>t9IbKV~m|Wi_KYpM@^OhWf zv*eMn2re^Su9yUiOA<}$rE!hM?&n@58w@i zZz)E?B;7xBztXRoEd8PrR-XDKx2OKy&|t2ryk2tkvumUt1~Ed-11UdsJ(lgo?8$8M z=mR{EqNS_I!^N=3^!yRO6b>=Q52gvC_pBLBWz>5&uR`E*q1!vg0vSjO#w7)I`22;Z9yO(Bm?ws&-?hi;tlff{r2Sk1$nR0=(4#XTug;2p*WTu6Ge^4U8Q#4w$of#l^O1gU;%}a zzhTnHIRyrhPpF3VdP+U?uAE%F?A2i7I`Apv&XoIL?;yX1Pu8Cbaj_X(-pTtdtPgP@ zW2_KuHbILz*r8*Fm&4CaD*BGRD(^6AMP6kZyb|byU9fYPt>`ZFwuwZvqM(t-oz zLn?|jX-h>%$v@#6?CZ0mN%E(8f!kmnDqJS_b+^aCmD72?c~)NplzBM+vpl@3_JjzoE=#(^woiiEQTNa&RYk_%%4hOCBK)rMyyLm*HLQ+o*#^ z|0LKErQKg?F02C$-5J?cXP}RXXUcW2o$PyE#Z^knznT)s9HcZa)wGdZrL?OZ0bQpN zYnGUr!C|Z^QqB_1BKPu<4`J3^PVP)1qRgXu)=I8-byuhmlz$x9ZIll*hXc)C>NW68 z5nW)P;YU<~&eNw^HGCzS@@u_9Tp)MG#%p4(E_2L;oBV_AL)?!1^OOf^mynNIgq6|^ zeHnOAL=s4IetL5OE4VT-ST6E=Bv-bVru>$%*~qU!IxySM*T@rdkqpfi;A8U0Mm5ed zcNvS%ssg$36k{;F7)<%-$yv1cGyCzxRph=LH0+}13KUnqo#>-PWDg_+O_@Pnex_8{ zIhBE`OUMI#eHxhE#{J}T=fa0)nR&J=u1B$w5~owHL_JO(=1CkU8WQKplfNM@A`GOO zvtetPmpgbVpGEGx3O)#MCgy?5QRLAdIxa*nqlhn5GJF*I@|0&(%_4u3ulqW}hVLX7 zFC(%|GJc5M@uk|j%0V;Pc$X^BK6#5G;a?EJ33}}$d4LO!pG{pNk6nU|F51{Y=3AA# z0(Ciu$Xk>Dl=6a|0`LaH=|p5ZSYe=5-b9|+pNxOz>VNXW)Dn3C!al~xQ{=8AWx9XK zOmuUft`>Zc#mP2yzZ^Gwm5Oe8mX~dxBadHgKZ;J91LIr|LO!Nz$+uQYt}{)(J=3&@ zyj*>%B43!u=}krcdiDqzP43{EqoZtKDS1Z9BVFz%_g-n&vz7c_{hmqLzS%~-z=BJI zFga#&m_L+UThP&N!5PXYE3j_~vqQg<`}!j9I5`k?=E6fUo~jHedA0hsU_rH%CvUpQ z!zowR_ahJW!@-bANTbQ4#mEwJr1ak+a_2o58Xt#ph2;9ED)BO06zAl9m=#1z`xtK{ z_ZOkz2o=3W?)bMo34BH#ss(uyLqC$crVVbZd+4OAYtDm<&ZYcbovpZPw)}--bS#!kExmNH=lwFC>#2Q8_wF0y^Fl_32gXpQ`tcNZ6{A0v>(sELhkGi zJti+4B#(tK4sp8aJIUqpE`JN-A&Xb5mos2KBjW`86kvs`$WK0C-}iaQYYr{d8rs!? zqCVt_8|>pViQM;#>ZlC45F;Zb3sh)(`4kWigLr@yoK1aNvybxI$rrza!05}4zDn+o zVl59fM29{jk7QGi3NUq;^KVt41~l8T0JbMzfQZ?ewNYFTd1v)WE~l|+Q=pZd86>%$ zm-X%QGGJ;B2&qr%(6JcZGRx+}NV=MpC&c{X{V8iRtqzFu)@U34U@3v&+kqr7ht?QWHf-{$dgh=(8r8(=bqGE*>CH9EKesHvgIA zGQ@+TCZB((Ryy@}niXP0>>+rG{9?+p)au;|hdB5i@|e~lL@N! zCEn|VFqVyBL3kxXQ*cNZDz2B``zYak2tF}E_1vElF-jyH<+@Q9bsRPld0$Z?bR6UD zl5Z^}kEJ}Upci@nln3nHOrBhhiElF0 zLh`@}7;jA5sJXCixK5sY+(x083zNrWjs4_~Bqp25GRMfpD0>Vg$z99Kv>6V1Ni2tv z7kSQBo($1{x!^&uB;_%}{aGP#EoV7{bP{<+J&gTUIx{G_%Bxd&p@E6H`zarL1KBFh zhM%N-YyJD&6@MP?itX0<)^b$#v7WdQ4vDh;gX9BJ?sz{z9&I>58jm#E9|vQPqS34nFU3L==ca5rc_>n@8xGLG#fs})#cE0<`KoY}Z`P7W z^D%$J7!vUudAv8KsgD}pBEOv{9TCm)fl=i5@K$VW1m)%yJSbXS1>fI7pEL}?_UK_` zWEXwgnmn->9SV>ak~=$MEF$bsKk`LwOLW(Nqx@*iX^sA2KYJQQ_dS8G7+cpVuD$d> zlyJR;>EocX7s(UP!M{%G-ACRc<>?d0$Q^gt*WYu7|AO^8N@rXG4~nOkAx%$a1DUtM zOU-#HjNvYF=V$hHuGH{H?U6Q_JhT%Xa?yKB$z!i5c{yldT5Pev;l$hyv!_w=zC&@% z&Mk7*sK0-buda$=Nas5KrQ~W#R-|ka&nbEB^GmFmcox15X?;S}x*evA!`MNaOqxU9 z>$g%Z*_=JdCl5V>IpbrGedNwgu*77qDd6%Z{pQ5l*U+A21B!?Cvx(*iJuJUW=e0)7N%xO|0;6cOz@yaCb>se&xF1?yIT>XOz!cR6c*e?26ppMJ_ROI=;`GT~RhO zP^P|4m&IkR#?P3ZtK3(VSJdghk?Pv@zmh7d_;1Ai%Z}y!oi3~6D0kD~-`X~GNKZBP zBZ~VE@1?z8lvnuw7+E@W*nh;!$_DoDJIq(yvtL-Q<(*vAws4gDc#WCUCrp_*VS43_quu}NTbJMF$wAL8tL*ZmJJG1!#CbC( zmCc<}KC5EJL;>~D0#{6&H-GNzC1sTj_qw}X(ey7`bm&Z-RW`o7qHOA{`IY_O za_`HwN`|_#tI8QvS@Uc6%5-Z;i6^IK#k~3Db0?OURo-{jy}m})-wjb^i==y2jlXMR zZr8HPdw+E&vaF+jxE)rayQgO5;||Z|253@Fv&zjmo}D$CrFOA=vFT!2<)C(+jaAn_ zHoj%eKkYi5>sga0z4PakklvZ+_e|>ASbI$_c9`Q1j(#|_hlS^Kwn zI%c$PD-m-2P^X7?^L zTFaM1tgGM9itqHaY((l+RQ`Q>P#zwx-`udF)xJ(aP0JaTHf9wCbXk_1`0CGL6-SjX zy8*ZE2E5I>P2vWht^xjZ4W&!1*Q1`?+WwOd>e~L3*2So&;IH4We_nnMusm?mxv$5rbbw8qX^*YENa*7}i+{Ak@GzdDlmDw3!Zv-Zn6 z85ddSBB*?YY?a-f+zj&u$Cy>1TaZz(+f!I2W?8rF_PDDitOCnFMm{R}!`+@Xj>JX? z4IGYD8!_R0!IS04{h)nxz{S*<7x4K?ai-9 delta 732687 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𽌭(aYdb0NDD<}lh1jCRkfmavQjhUQ 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�Mp@K)HywfY|Uw+4}Sv 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�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 z%0A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 diff --git a/tools/mksurfdata_esmf/src/mksurfdata.F90 b/tools/mksurfdata_esmf/src/mksurfdata.F90 index a04f9a7984..f52dfb1eb2 100644 --- a/tools/mksurfdata_esmf/src/mksurfdata.F90 +++ b/tools/mksurfdata_esmf/src/mksurfdata.F90 @@ -386,8 +386,8 @@ program mksurfdata ! Make inland water [pctlak, pctwet] [flakwat] [fwetlnd] zero_out_lake = all_urban .or. all_veg zero_out_wetland = all_urban .or. all_veg .or. no_inlandwet - ! call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & - ! zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc) + call mklakwat(mksrf_flakwat_mesh, mksrf_flakwat, mesh_model, & + zero_out_lake, zero_out_wetland, pctlak, pctwet, lakedepth, rc) ! if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in calling mklatwat') call ESMF_LogWrite("After mklakwat", ESMF_LOGMSG_INFO) From f4b44e320e528ff799637c30205f873a025bd339 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 25 Jan 2022 19:15:06 -0700 Subject: [PATCH 027/614] fixed problems in organicMod.F90 --- .../gen_mksurfdata_namelist.xml | 2 +- tools/mksurfdata_esmf/src/CMakeLists.txt | 3 + tools/mksurfdata_esmf/src/mkfileMod.F90 | 205 ++- tools/mksurfdata_esmf/src/mkharvestMod.F90 | 36 +- tools/mksurfdata_esmf/src/mkindexmapMod.F90 | 1214 ++++++++--------- tools/mksurfdata_esmf/src/mklanwatMod.F90 | 8 +- tools/mksurfdata_esmf/src/mkorganicMod.F90 | 57 +- tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 | 6 +- tools/mksurfdata_esmf/src/mkpioMod.F90 | 104 +- tools/mksurfdata_esmf/src/mksurfdata | Bin 4224448 -> 0 bytes tools/mksurfdata_esmf/src/mksurfdata.F90 | 258 ++-- .../src/mkurbanparCommonMod.F90 | 161 +-- tools/mksurfdata_esmf/src/mkurbanparMod.F90 | 917 ++++++++----- 13 files changed, 1511 insertions(+), 1460 deletions(-) delete mode 100755 tools/mksurfdata_esmf/src/mksurfdata diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml index ae61df294e..ecc76c5be2 100644 --- a/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml +++ b/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml @@ -97,7 +97,7 @@ - lnd/clm2/rawdata/mksrf_urban_0.05x0.05_simyr2000.c120621.nc + lnd/clm2/rawdata/mksrf_urban_0.05x0.05_simyr2000.c220125.nc lnd/clm2/mappingdata/grids/UNSTRUCTgrid_0.5x0.5_nomask_c200129.nc diff --git a/tools/mksurfdata_esmf/src/CMakeLists.txt b/tools/mksurfdata_esmf/src/CMakeLists.txt index e4b94dde89..00224aa6e0 100644 --- a/tools/mksurfdata_esmf/src/CMakeLists.txt +++ b/tools/mksurfdata_esmf/src/CMakeLists.txt @@ -25,6 +25,9 @@ set(SRCFILES mkvarctl.F90 mkesmfMod.F90 mkutilsMod.F90 mkchecksMod.F90 + mkindexmapMod.F90 + mkurbanparMod.F90 + mkurbanparCommonMod.F90 nanMod.F90 shr_const_mod.F90 shr_kind_mod.F90 diff --git a/tools/mksurfdata_esmf/src/mkfileMod.F90 b/tools/mksurfdata_esmf/src/mkfileMod.F90 index 8f4fd5d87b..7e6a3de131 100644 --- a/tools/mksurfdata_esmf/src/mkfileMod.F90 +++ b/tools/mksurfdata_esmf/src/mkfileMod.F90 @@ -6,8 +6,8 @@ module mkfileMod use shr_sys_mod , only : shr_sys_getenv, shr_sys_abort use mkutilsMod , only : get_filename, chkerr use mkvarpar , only : nlevsoi, numrad, numstdpft -#ifdef TODO use mkurbanparMod, only : numurbl, nlevurb +#ifdef TODO use mkglcmecMod , only : nglcec use mkpftMod , only : mkpftAtt use mksoilMod , only : mksoilAtt @@ -20,6 +20,12 @@ module mkfileMod implicit none private + interface mkfile_output + module procedure mkfile_output_int1d + module procedure mkfile_output_real1d + module procedure mkfile_output_real2d + end interface mkfile_output + public :: mkfile_fsurdat character(len=*) , parameter :: u_FILE_u = & @@ -29,23 +35,24 @@ module mkfileMod contains !================================================================================= - subroutine mkfile_fsurdat(nx, ny, mesh_model, dynlanduse, & - pctlak, pctwet, lakedepth, organic) + subroutine mkfile_fsurdat(nx, ny, mesh_o, dynlanduse, & + pctlak, pctwet, lakedepth, organic, urban_classes, urban_region) ! input/output variables integer , intent(in) :: nx integer , intent(in) :: ny logical , intent(in) :: dynlanduse - type(ESMF_Mesh) , intent(in) :: mesh_model + type(ESMF_Mesh) , intent(in) :: mesh_o real(r8), pointer, intent(in) :: pctlak(:) ! percent of grid cell that is lake real(r8), pointer, intent(in) :: pctwet(:) ! percent of grid cell that is wetland real(r8), pointer, intent(in) :: lakedepth(:) ! lake depth (m) real(r8), pointer, intent(in) :: organic(:,:) ! organic + real(r8), pointer, intent(in) :: urban_classes(:,:) ! percent cover of each urban class, as % of total urban area + integer , pointer, intent(in) :: urban_region(:) ! urban region ID #ifdef TODO type(harvestDataType) , intent(in) :: harvdata #endif - ! local variables type(file_desc_t) :: pioid character(len=256) :: varname @@ -58,11 +65,7 @@ subroutine mkfile_fsurdat(nx, ny, mesh_model, dynlanduse, & integer :: rc integer :: n, i logical :: define_mode - type(io_desc_t) :: pio_iodesc - type(var_desc_t) :: pio_varid character(len=256) :: lev1name - real(r8), pointer :: rpointer1d(:) - real(r8), pointer :: rpointer2d(:,:) character(len=*), parameter :: subname=' (mkfile_fsurdat) ' !----------------------------------------------------------------------- @@ -101,64 +104,29 @@ subroutine mkfile_fsurdat(nx, ny, mesh_model, dynlanduse, & if (.not. dynlanduse) then - varname = 'PCT_LAKE' - longname = 'percent_lake' - units = 'unitless' - rpointer1d => pctlak - if (define_mode) then - call mkpio_def_spatial_var(pioid, trim(varname), xtype, trim(longname), trim(units)) - else - call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - rcode = pio_inq_varid(pioid, trim(varname), pio_varid) - call pio_write_darray(pioid, pio_varid, pio_iodesc, rpointer1d, rcode) - call pio_freedecomp(pioid, pio_iodesc) - end if - - varname = 'PCT_WETLAND' - longname = 'percent_wetland' - units = 'unitless' - rpointer1d => pctwet - if (define_mode) then - call mkpio_def_spatial_var(pioid, trim(varname), xtype, trim(longname), trim(units)) - else - call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - rcode = pio_inq_varid(pioid, trim(varname), pio_varid) - call pio_write_darray(pioid, pio_varid, pio_iodesc, rpointer1d, rcode) - call pio_freedecomp(pioid, pio_iodesc) - end if - - varname = 'LAKEDEPTH' - longname = 'lake depth' - units = 'm' - rpointer1d => lakedepth - if (define_mode) then - call mkpio_def_spatial_var(pioid, trim(varname), xtype, trim(longname), trim(units)) - else - ! inquire about varid here - call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - rcode = pio_inq_varid(pioid, trim(varname), pio_varid) - call pio_write_darray(pioid, pio_varid, pio_iodesc, rpointer1d, rcode) - call pio_freedecomp(pioid, pio_iodesc) - end if - - varname = 'ORGANIC' - longname = 'organic matter density at soil levels' - units = 'kg/m3 (assumed carbon content 0.58 gC per gOM)' - lev1name = 'nlevsoi' - rpointer2d => organic - if (define_mode) then - call mkpio_def_spatial_var(pioid, trim(varname), xtype, trim(lev1name), trim(longname), trim(units)) - else - ! inquire about varid here - call mkpio_iodesc_output(pioid, mesh_model, trim(varname), pio_iodesc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) - rcode = pio_inq_varid(pioid, trim(varname), pio_varid) - call pio_write_darray(pioid, pio_varid, pio_iodesc, rpointer2d, rcode) - call pio_freedecomp(pioid, pio_iodesc) - end if + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_LAKE', 'percent_lake', & + 'unitless', pctlak, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call mkfile_output(pioid,define_mode, mesh_o, xtype, 'PCT_WETLAND', 'percent_wetland', & + 'unitless', pctwet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'LAKEDEPTH', 'lake_depth', & + 'm', lakedepth, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call mkfile_output(pioid, define_mode, mesh_o, xtype, 'ORGANIC', 'organic matter density at soil levels', & + 'kg/m3 (assumed carbon content 0.58 gC per gOM)', organic, lev1name='nlevsoi', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! call mkfile_output(pioid, define_mode, mesh_o, xtype, 'PCT_URBAN', 'percent urban for each density type', & + ! 'unitless', urban_classes, lev1name='numurbl', rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! call mkfile_output(pioid, define_mode, mesh_o, 'URBAN_REGION_ID', 'urban region ID', & + ! 'unitless', urban_region, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end do @@ -206,17 +174,15 @@ subroutine mkfile_define_dims(pioid, nx, ny, dynlanduse) rcode = pio_def_dim(pioid, 'nglcecp1', nglcec+1, dimid) #endif else -#ifdef TODO rcode = pio_def_dim(pioid, 'numurbl', numurbl, dimid) rcode = pio_def_dim(pioid, 'nlevurb', nlevurb, dimid) -#endif rcode = pio_def_dim(pioid, 'numrad' , numrad, dimid) rcode = pio_def_dim(pioid, 'nchar' , 256, dimid) end if end subroutine mkfile_define_dims -!================================================================================= + !================================================================================= subroutine mkfile_define_atts(pioid, dynlanduse) ! input/output variables @@ -368,4 +334,103 @@ subroutine mkfile_define_atts(pioid, dynlanduse) end subroutine mkfile_define_atts + !================================================================================= + subroutine mkfile_output_int1d(pioid, define_mode, mesh, varname, longname, units, ipointer, rc) + + ! input/output variables + type(file_desc_t) , intent(inout) :: pioid + logical , intent(in) :: define_mode + type(ESMF_Mesh) , intent(in) :: mesh + character(len=*) , intent(in) :: varname + character(len=*) , intent(in) :: longname + character(len=*) , intent(in) :: units + integer , pointer :: ipointer(:) + integer , intent(out) :: rc + + ! local variables + type(io_desc_t) :: pio_iodesc + type(var_desc_t) :: pio_varid + integer :: rcode + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (define_mode) then + call mkpio_def_spatial_var(pioid, trim(varname), PIO_INT, trim(longname), trim(units)) + else + call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + call pio_write_darray(pioid, pio_varid, pio_iodesc, ipointer, rcode) + call pio_freedecomp(pioid, pio_iodesc) + end if + end subroutine mkfile_output_int1d + + !================================================================================= + subroutine mkfile_output_real1d(pioid, define_mode, mesh, xtype, varname, longname, units, rpointer, rc) + + ! input/output variables + type(file_desc_t), intent(inout) :: pioid + logical , intent(in) :: define_mode + type(ESMF_Mesh) , intent(in) :: mesh + integer , intent(in) :: xtype + character(len=*), intent(in) :: varname + character(len=*), intent(in) :: longname + character(len=*), intent(in) :: units + real(r8) , pointer :: rpointer(:) + integer , intent(out) :: rc + + ! local variables + type(io_desc_t) :: pio_iodesc + type(var_desc_t) :: pio_varid + integer :: rcode + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (define_mode) then + call mkpio_def_spatial_var(pioid, trim(varname), xtype, trim(longname), trim(units)) + else + call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + call pio_write_darray(pioid, pio_varid, pio_iodesc, rpointer, rcode) + call pio_freedecomp(pioid, pio_iodesc) + end if + end subroutine mkfile_output_real1d + + !================================================================================= + subroutine mkfile_output_real2d(pioid, define_mode, mesh, xtype, varname, longname, units, rpointer, lev1name, rc) + + ! input/output variables + type(file_desc_t), intent(inout) :: pioid + logical , intent(in) :: define_mode + type(ESMF_Mesh) , intent(in) :: mesh + integer , intent(in) :: xtype + character(len=*), intent(in) :: varname + character(len=*), intent(in) :: longname + character(len=*), intent(in) :: units + character(len=*), intent(in) :: lev1name + real(r8) , pointer :: rpointer(:,:) + integer , intent(out) :: rc + + ! local variables + type(io_desc_t) :: pio_iodesc + type(var_desc_t) :: pio_varid + integer :: rcode + !----------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (define_mode) then + call mkpio_def_spatial_var(pioid, trim(varname), xtype, trim(lev1name), trim(longname), trim(units)) + else + call mkpio_iodesc_output(pioid, mesh, trim(varname), pio_iodesc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) call shr_sys_abort('error in generating an iodesc for '//trim(varname)) + rcode = pio_inq_varid(pioid, trim(varname), pio_varid) + call pio_write_darray(pioid, pio_varid, pio_iodesc, rpointer, rcode) + call pio_freedecomp(pioid, pio_iodesc) + end if + end subroutine mkfile_output_real2d + end module mkfileMod diff --git a/tools/mksurfdata_esmf/src/mkharvestMod.F90 b/tools/mksurfdata_esmf/src/mkharvestMod.F90 index 9459a1bfc6..6f576b73d4 100644 --- a/tools/mksurfdata_esmf/src/mkharvestMod.F90 +++ b/tools/mksurfdata_esmf/src/mkharvestMod.F90 @@ -136,7 +136,7 @@ subroutine init( this, dims2nd, ns_i, ns_o, init_value ) !----------------------------------------------------------------------- if ( size(dims2nd) /= numharv )then write(*,*) subname//':ERROR:: dims2nd given to init is not the right size' - call abort() + call shr_sys_abort() end if this%CFTdimsize = 64 this%PFTdimsize = 15 @@ -162,7 +162,7 @@ subroutine init( this, dims2nd, ns_i, ns_o, init_value ) this%indicesPFT(n) = numPFT else write(*,*) 'ERROR:: dims2nd is not the right size (should be 0, 15, or 64) = ', dims2nd(n) - call abort() + call shr_sys_abort() end if end if end do @@ -225,7 +225,7 @@ function get1DFieldPtr( this, nfield, output ) result(ptr1D) ptr1D => this%OutData1D(:,this%indices1D(nfield)) end if else - call abort() + call shr_sys_abort() end if end function get1DFieldPtr @@ -276,7 +276,7 @@ function get2DFieldPtr( this, nfield, output ) result(ptr2D) end if end if else - call abort() + call shr_sys_abort() end if end function get2DFieldPtr @@ -394,7 +394,7 @@ logical function isField1D( this, nfield ) if ( mkharvest_fieldInBounds( nfield ) )then if ( this%dims2nd(nfield) == 0 ) isField1D = .true. else - call abort() + call shr_sys_abort() end if end function isField1D @@ -429,7 +429,7 @@ logical function isField2D( this, nfield ) if ( mkharvest_fieldInBounds( nfield ) )then if ( this%dims2nd(nfield) /= 0 ) isField2D = .true. else - call abort() + call shr_sys_abort() end if end function isField2D @@ -555,14 +555,14 @@ subroutine mkharvest_init( ns_o, init_val, harvdata, fharvest, constant ) else if ( ret == nf_noerr )then else write(*,*) 'ERROR:: bad return code from NetCDF get attribute= '// nf_strerror(ret) - call abort() + call shr_sys_abort() end if call get_dim_lengths(ncid, mkharvest_fieldname(ifld, constant=lconstant), ndims, dim_lengths) if ( ns_i == 0 )then ns_i = dim_lengths(1)*dim_lengths(2) else if ( ns_i /= dim_lengths(1)*dim_lengths(2) )then write(*,*) 'ERROR:: bad dimension sizes for variable = ', mkharvest_fieldname(ifld, constant=lconstant) - call abort() + call shr_sys_abort() end if if ( ndims == 2 )then dims2nd(ifld) = 0 @@ -570,7 +570,7 @@ subroutine mkharvest_init( ns_o, init_val, harvdata, fharvest, constant ) dims2nd(ifld) = dim_lengths(3) else write(*,*) 'ERROR:: bad dimensionality for variable = ', mkharvest_fieldname(ifld, constant=lconstant) - call abort() + call shr_sys_abort() end if end if @@ -663,7 +663,7 @@ character(len=harlen) function mkharvest_fieldname( nfield, constant ) mkharvest_fieldname = harvest_const_fieldnames(nfield) end if else - call abort() + call shr_sys_abort() end if end function mkharvest_fieldname @@ -699,7 +699,7 @@ character(len=CL) function mkharvest_units( nfield ) if ( mkharvest_fieldInBounds( nfield ) )then mkharvest_units = harvest_units(nfield) else - call abort() + call shr_sys_abort() end if end function mkharvest_units @@ -735,7 +735,7 @@ character(len=CL) function mkharvest_longname( nfield ) if ( mkharvest_fieldInBounds( nfield ) )then mkharvest_longname = harvest_longnames(nfield) else - call abort() + call shr_sys_abort() end if end function mkharvest_longname @@ -896,7 +896,7 @@ subroutine mkharvest(ldomain, mapfname, datfname, ndiag, harvdata) ns_i = tdomain%ns ns_o = ldomain%ns allocate(frac_dst(ns_o), stat=ier) - if (ier /= 0) call abort() + if (ier /= 0) call shr_sys_abort() write (6,*) 'Open harvest file: ', trim(datfname) call check_ret(nf_open(datfname, 0, ncid), subname) @@ -1016,14 +1016,14 @@ subroutine mkharvest(ldomain, mapfname, datfname, ndiag, harvdata) if ( any(oride_harv == real_undef ) )then write(6,*) subname, ' error some override harvesting fields set ', & 'and others are not = ', oride_harv - call abort() + call shr_sys_abort() end if do k = 1, harvdata%num1Dfields() m = ind1D(k) if ( oride_harv(m) < 0.0_r8 .or. oride_harv(m) > 100.0_r8 )then write(6,*) subname, ' error override harvesting field out of range', & oride_harv(m), ' field = ', mkharvest_fieldname(m) - call abort() + call shr_sys_abort() end if end do do no = 1,ns_o @@ -1079,18 +1079,18 @@ subroutine mkharvest_parse_oride( string ) call shr_string_betweenTags( string, harv_start, harv_end, substring, rc ) if ( rc /= 0 )then write(6,*) subname//'Trouble finding harvest start end tags' - call abort() + call shr_sys_abort() end if read(substring,*) oride_harv(1:numharv-1) call shr_string_betweenTags( string, graz_start, graz_end, substring, rc ) if ( rc /= 0 )then write(6,*) subname//'Trouble finding grazing start end tags' - call abort() + call shr_sys_abort() end if read(substring,*) oride_harv(numharv) if ( harvest_fieldnames(numharv) /= 'GRAZING' )then write(6,*) subname, ' grazing is NOT last field as was expected' - call abort() + call shr_sys_abort() end if !----------------------------------------------------------------------- diff --git a/tools/mksurfdata_esmf/src/mkindexmapMod.F90 b/tools/mksurfdata_esmf/src/mkindexmapMod.F90 index 5f8e74af2b..cfc2adbc09 100644 --- a/tools/mksurfdata_esmf/src/mkindexmapMod.F90 +++ b/tools/mksurfdata_esmf/src/mkindexmapMod.F90 @@ -1,619 +1,521 @@ module mkindexmapMod -!----------------------------------------------------------------------- -!BOP -! -! !MODULE: mkindexmapMod -! -! !DESCRIPTION: -! Module containing subroutines for making maps of index data. -! -! This includes a routine for making a map using the dominant type among the input grid -! cells making up a given output cell, as well as routines for using an index map as -! indices into a lookup table, to essentially paint-by-number some other field, and some -! other related routines -! -! WJS (2-1-12): There is a lookup_2d subroutine, but not a lookup_1d (or any other -! dimensionality). That is simply because I needed lookup_2d, but have not yet needed a -! routine of other dimensionalities. In the future, it would probably be helpful to at -! least have lookup_1d and lookup_1d_netcdf. If this is done, see my notes under the -! lookup_2d_netcdf routine for some thoughts on avoiding duplication. -! -! -! !USES: - use shr_kind_mod, only : r8 => shr_kind_r8 - use mkncdio, only : nf_max_name - use mkgridmapMod, only : gridmap_type - - implicit none - private - -! !PUBLIC TYPES: -! - ! dim_slice_type: stores information about dimensions that we use for slicing a multi- - ! dimensional variable - type dim_slice_type - character(len=nf_max_name) :: name ! name of this dimension - integer :: val ! index to use for the slice - end type dim_slice_type - public :: dim_slice_type -! -! !PUBLIC MEMBER FUNCTIONS: - public :: get_dominant_indices ! make output map based on dominant type in each grid cell - public :: get_max_indices ! make output map based on maximum type in each grid cell - public :: lookup_2d ! create map based on a 2-d lookup table - public :: lookup_2d_netcdf ! wrapper to lookup_2d; first read table from netcdf file - public :: which_max ! get index of the maximum value in an array -! -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -!EOP -!------------------------------------------------------------------------------ -contains -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: get_dominant_indices -! -! !INTERFACE: -subroutine get_dominant_indices(gridmap, src_array, dst_array, minval, maxval, nodata, filter, mask_src) -! -! !DESCRIPTION: -! Fills an output array on the destination grid (dst_array) whose values are equal to the -! (weighted) dominant value in the source grid cells overlapping a given destination grid -! cell -! -! Ignores all values in src_array that are less than minval or greater than maxval (treats -! those values the same as if they had wt=0). (Note: for memory-use efficiency, it is -! best if the indices are designed such that most values between minval and maxval are -! actually used, since an array is allocated of size (maxval - minval + 1)*gridmap%nb.) -! -! The filter argument can be used to exclude certain overlaps -- if provided, we only -! consider overlaps where filter is .true. If not provided, filter is treated as being -! .true. everywhere. -! -! Output grid cells with no contributing valid source points are given the nodata value -! -! !ARGUMENTS: - implicit none - type(gridmap_type), intent(in) :: gridmap ! provides mapping from src -> dst - integer , intent(in) :: src_array(:) ! input values; length gridmap%na - integer , intent(out):: dst_array(:) ! output values; length gridmap%nb - integer , intent(in) :: minval ! minimum valid value in src_array - integer , intent(in) :: maxval ! maximum valid value in src_array - integer , intent(in) :: nodata ! value to assign to dst_array where there are no valid source points - integer , intent(in) :: mask_src(:) - - logical, intent(in), optional :: filter(:) ! only consider overlaps where filter is .true.; length gridmap%ns -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - logical, allocatable :: lfilter(:) ! local version of filter - logical, allocatable :: hasdata(:) ! true if an output cell has any valid data; - real(r8), allocatable :: weights(:,:) ! summed weight of each index value for each output cell - - integer :: n, ni, no - integer :: k - integer :: maxindex - real(r8) :: wt - real(r8) :: maxwt - - character(len=*), parameter :: subname = "get_dominant_indices" -!----------------------------------------------------------------------- - - ! Error-check inputs and initialize local variables - - if (size(src_array) /= gridmap%na .or. & - size(dst_array) /= gridmap%nb) then - write(6,*) subname//' ERROR: incorrect sizes of src_array or dst_array' - write(6,*) 'size(src_array) = ', size(src_array) - write(6,*) 'gridmap%na = ', gridmap%na - write(6,*) 'size(dst_array) = ', size(dst_array) - write(6,*) 'gridmap%nb = ', gridmap%nb - call abort() - end if - if (size(mask_src) /= size(src_array)) then - write(6,*) subname//' ERROR: incorrect size of mask_src' - write(6,*) 'size(mask_src) = ', size(mask_src) - write(6,*) 'size(src_array) = ', size(src_array) - call abort() - end if - - allocate(lfilter(gridmap%ns)) - - if (present(filter)) then - if (size(filter) /= gridmap%ns) then - write(6,*) subname//' ERROR: incorrect size of filter' - write(6,*) 'size(filter) = ', size(filter) - write(6,*) 'gridmap%ns = ', gridmap%ns - call abort() - end if - - lfilter(:) = filter(:) - else - lfilter(:) = .true. - end if - - allocate(hasdata(gridmap%nb)) - hasdata(:) = .false. - allocate(weights(minval:maxval, gridmap%nb)) - weights(minval:maxval,:) = 0. - - ! Determine weight of each index value for each output (destination) cell - - do n = 1, gridmap%ns - if (lfilter(n)) then - ni = gridmap%src_indx(n) - no = gridmap%dst_indx(n) - wt = gridmap%wovr(n) * mask_src(ni) - k = src_array(ni) - if (k >= minval .and. k <= maxval) then - ! Note: if we were doing something like weighted sums, I think we would - ! want to divide wt by gridmap%frac_dst(no), as is done in - ! gridmap_areaave_default. But since all we care about is the relative - ! values of weights for a given destination cell, this is unnecessary - weights(k,no) = weights(k,no) + wt - hasdata(no) = .true. - end if - end if - end do - - ! Determine output values - ! Note: if a given destination cell has no contributing source points (thus - ! hasdata(no) = false), or the max weight of any index overlapping this destination - ! cell is <= 0, then the output value there will be nodata. - ! (I don't think this latter condition -- weight <= 0 -- is possible, but we handle - ! it anyway) - - dst_array(:) = nodata - do no = 1, gridmap%nb - if (hasdata(no)) then - call which_max(weights(:,no), maxwt, maxindex, lbound=minval) - if (maxwt > 0.) then - dst_array(no) = maxindex - end if - end if - end do - - deallocate(lfilter, weights, hasdata) - -end subroutine get_dominant_indices -!------------------------------------------------------------------------------ - -!----------------------------------------------------------------------- -subroutine get_max_indices(gridmap, src_array, dst_array, nodata, mask_src) - ! - ! !DESCRIPTION: - ! Fills an output array on the destination grid (dst_array) whose values are equal to - ! the maximum value in the source grid cells overlapping a given destination grid cell. - ! - ! The frequency of occurrence of the source values is irrelevant. For example, if the - ! value 1 appears in 99% of source cells overlapping a given destination cell and the - ! value 2 appears in just 1%, we'll put 2 in the destination cell because it is the - ! maximum value. - ! - ! Output grid cells with no contributing valid source points are given the nodata value + !----------------------------------------------------------------------- + ! Module containing subroutines for making maps of index data. ! - ! !ARGUMENTS: - type(gridmap_type) , intent(in) :: gridmap ! provides mapping from src -> dst - integer , intent(in) :: src_array(:) ! input values; length gridmap%na - integer , intent(out) :: dst_array(:) ! output values; length gridmap%nb - integer , intent(in) :: nodata ! value to assign to dst_array where there are no valid source points - integer , intent(in) :: mask_src(:) ! mask at the source resolution + ! This includes a routine for making a map using the dominant type among the input grid + ! cells making up a given output cell, as well as routines for using an index map as + ! indices into a lookup table, to essentially paint-by-number some other field, and some + ! other related routines ! - ! !LOCAL VARIABLES: - logical, allocatable :: hasdata(:) ! true if an output cell has any valid data; - integer :: n, ni, no - real(r8) :: wt - integer :: src_val - - character(len=*), parameter :: subname = 'get_max_indices' + ! WJS (2-1-12): There is a lookup_2d subroutine, but not a lookup_1d (or any other + ! dimensionality). That is simply because I needed lookup_2d, but have not yet needed a + ! routine of other dimensionalities. In the future, it would probably be helpful to at + ! least have lookup_1d and lookup_1d_netcdf. If this is done, see my notes under the + ! lookup_2d_netcdf routine for some thoughts on avoiding duplication. !----------------------------------------------------------------------- - ! Error-check inputs - - if (size(src_array) /= gridmap%na .or. & - size(dst_array) /= gridmap%nb) then - write(6,*) subname//' ERROR: incorrect sizes of src_array or dst_array' - write(6,*) 'size(src_array) = ', size(src_array) - write(6,*) 'gridmap%na = ', gridmap%na - write(6,*) 'size(dst_array) = ', size(dst_array) - write(6,*) 'gridmap%nb = ', gridmap%nb - call abort() - end if - if (size(mask_src) /= size(src_array)) then - write(6,*) subname//' ERROR: incorrect size of mask_src' - write(6,*) 'size(mask_src) = ', size(mask_src) - write(6,*) 'size(src_array) = ', size(src_array) - call abort() - end if - - ! Initialize local variables - allocate(hasdata(gridmap%nb)) - hasdata(:) = .false. - - do n = 1, gridmap%ns - ni = gridmap%src_indx(n) - wt = gridmap%wovr(n) * mask_src(ni) - if (wt > 0._r8) then - no = gridmap%dst_indx(n) - src_val = src_array(ni) - if (.not. hasdata(no)) then - hasdata(no) = .true. - dst_array(no) = src_val - else if (src_val > dst_array(no)) then - dst_array(no) = src_val - end if - end if - end do - - do no = 1, gridmap%nb - if (.not. hasdata(no)) then - dst_array(no) = nodata - end if - end do - -end subroutine get_max_indices - + use ESMF + use pio + use shr_kind_mod, only : r8 => shr_kind_r8, cs => shr_kind_cs + use shr_sys_mod , only : shr_sys_abort + + implicit none + private + + ! public types: + ! dim_slice_type: stores information about dimensions that we use for slicing a multi- + ! dimensional variable + type dim_slice_type + character(len=CS) :: name ! name of this dimension + integer :: val ! index to use for the slice + end type dim_slice_type + public :: dim_slice_type + + ! public member functions: + public :: get_dominant_indices ! make output map based on dominant type in each grid cell + public :: get_max_indices ! make output map based on maximum type in each grid cell + public :: lookup_2d ! create map based on a 2-d lookup table + public :: lookup_2d_netcdf ! wrapper to lookup_2d; first read table from netcdf file + public :: which_max ! get index of the maximum value in an array !------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: lookup_2d -! -! !INTERFACE: -subroutine lookup_2d(index1, index2, lookup_table, fill_val, data, ierr, & - nodata, valid_entries, invalid_okay) -! -! !DESCRIPTION: -! Creates a data array using a paint-by-number approach according to a lookup table -! -! This routine operates on a 2-d lookup table. There are therefore two index arrays -! (index1 and index2); these index arrays are on the same grid as the desired data array -! (thus, index1, index2 and data must all have the same length). Each output point, n, is -! then generally determined as: -! -! data(n) = lookup_table(index1(n), index2(n)) -! -! fill_val: value to put in data array where either: -! (a) index1 or index2 are equal to nodata (if nodata is given) -! Note that this condition does NOT result in ierr being set -! (b) valid_entries(index1(n), index2(n)) is false (if valid_entries is given) -! Note that this condition also results in ierr being set, unless invalid_okay is -! present and .true. -! (If valid_entries is not given, it is treated as being .true. everywhere) -! (c) index1 or index2 out of range -! Note that this condition also results in ierr being set -! -! ierr: error return code (if non-0, indicates first error encountered): -! 0: no error -! 1: attempt to assign values from the lookup table that are invalid according -! to valid_entries (note: this is not considered an error if invalid_okay is -! present and .true.) -! 2: attempt to access an out-of-range index in lookup table -! WJS (2-2-12): My main reason for using ierr rather than aborting in case of error -! is to facilitate unit testing -! -! !ARGUMENTS: - implicit none - integer , intent(in) :: index1(:) ! index into dim 1 of lookup_table - integer , intent(in) :: index2(:) ! index into dim 2 of lookup_table - real(r8), intent(in) :: lookup_table(:,:) - real(r8), intent(in) :: fill_val ! value to put in data where we don't have a valid value (see above for details) - real(r8), intent(out):: data(:) ! output arary - integer , intent(out):: ierr ! error return code (0 = no error) - - ! nodata flag in index1 and index2 (see above for details): - integer, intent(in), optional :: nodata - - ! which entries are considered valid (see above for details): - logical, intent(in), optional :: valid_entries(:,:) - - ! invalid_okay: if true, then assigning fill_val because valid_entries is false does - ! NOT raise an error flag (invalid_okay defaults to false, meaning an error is - ! raised in this case): - logical, intent(in), optional :: invalid_okay -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - integer :: n - integer :: i1, i2 - integer :: data_size ! size of index1, index2 and data arrays - integer :: table_n1 ! size of dimension 1 of lookup table - integer :: table_n2 ! size of dimension 2 of lookup table - logical :: linvalid_okay ! local version of invalid_okay - logical, allocatable :: lvalid_entries(:,:) ! local version of valid_entries - - character(len=*), parameter :: subname = 'lookup_2d' -!----------------------------------------------------------------------- - - ierr = 0 - - ! Error-check array sizes - - data_size = size(data) - if (size(index1) /= data_size .or. size(index2) /= data_size) then - write(6,*) subname//' ERROR: data array sizes do not match' - write(6,*) 'size(data) = ', data_size - write(6,*) 'size(index1) = ', size(index1) - write(6,*) 'size(index2) = ', size(index2) - call abort() - end if - - table_n1 = size(lookup_table,1) - table_n2 = size(lookup_table,2) - if (present(valid_entries)) then - if (size(valid_entries,1) /= table_n1 .or. size(valid_entries,2) /= table_n2) then - write(6,*) subname//' ERROR: size of valid_entries does not match lookup_table' - write(6,*) 'size(lookup_table) = ', table_n1, table_n2 - write(6,*) 'size(valid_entries) = ', size(valid_entries,1), & - size(valid_entries,2) - call abort() - end if - end if - - ! Set local version of invalid_okay & valid_entries - - if (present(invalid_okay)) then - linvalid_okay = invalid_okay - else - linvalid_okay = .false. - end if - - allocate(lvalid_entries(table_n1, table_n2)) - if (present(valid_entries)) then - lvalid_entries(:,:) = valid_entries(:,:) - else - lvalid_entries(:,:) = .true. - end if - - ! Do the lookups - - do n = 1, data_size - i1 = index1(n) - i2 = index2(n) - - ! First handle special cases: - - ! index is nodata flag (this is NOT an error) - if (present(nodata)) then - if (i1 == nodata .or. i2 == nodata) then - data(n) = fill_val - cycle - end if - end if - - ! index out of range - if (i1 <= 0 .or. i1 > table_n1 .or. & - i2 <= 0 .or. i2 > table_n2) then - data(n) = fill_val - if (ierr == 0) ierr = 2 - cycle - end if - - ! lookup table entry is invalid - if (.not. lvalid_entries(i1, i2)) then - data(n) = fill_val - if (.not. linvalid_okay) then - if (ierr == 0) ierr = 1 - end if - cycle - end if - - ! Finally, the "normal" case, if none of the special cases were triggered: - data(n) = lookup_table(i1, i2) - end do - - deallocate(lvalid_entries) - -end subroutine lookup_2d -!------------------------------------------------------------------------------ - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: lookup_2d_netcdf -! -! !INTERFACE: -subroutine lookup_2d_netcdf(ncid, tablename, lookup_has_invalid, & - dimname1, dimname2, n_extra_dims, & - index1, index2, fill_val, data, ierr, & - extra_dims, nodata, invalid_okay) -! -! !DESCRIPTION: -! Wrapper to lookup_2d that first reads the lookup table from a netcdf file -! -! If lookup_has_invalid is false, then we treat all lookup table entries as valid data -! (i.e., all valid_entries are true in the call to lookup_2d). If lookup_has_invalid is -! true, then we read the _FillValue attribute for the lookup table variable, and consider -! any table entry with value _FillValue to be an invalid entry, thus putting fill_val in -! these data locations (and raising an error flag unless invalid_okay is present and -! true). -! -! The dimension given by dimname1 -- with the associated indices given by index1 -- is the -! fastest-varying dimension in the lookup table. Dimension dimname2 (associated with -! index2) is the second-fastest-varying dimension. Similarly, extra_dims should be ordered -! from faster-varying to slowest-varying dimension. (The first dimension in extra_dims is -! the third-fastest-varying dimension in the lookup table.) -! -! n_extra_dims gives the number of extra dimensions (in addition to the first two) in the -! lookup table. We take a single 2-d slice of the lookup table, by using a single value of -! each of these other dimensions. If n_extra_dims > 0, then extra_dims must be present, -! with at least n_extra_dims entries. Each entry in extra_dims gives the name of a -! dimension and the dimension index to use for the slice. -! -! If size(extra_dims) > n_extra_dims, then we use the first n_extra_dims entries in -! extra_dims. If n_extra_dims = 0, then extra_dims is ignored. -! -! Note that we ignore any coordinate variables associated with the dimensions of the -! lookup table; we simply treat the lookup table indices as 1,2,3,... -! -! See the lookup_2d documentation for documentation of some other arguments -! -! WJS (2-1-12): Some thoughts on avoiding duplication if we eventually want similar -! routines, lookup_1d_netcdf, lookup_3d_netcdf, etc.: -! -! Much of the code in lookup_2d_netcdf could then be pulled out to a shared subroutine -! (e.g., much of the error-checking code). -! -! Or, maybe better: we could try to make a single lookup_netcdf subroutine that handles -! 1-d, 2-d and any other dimensionality. To do that, we would (1) make a generic interface -! (of which lookup_1d and lookup_2d would be implementations); (2) change the repeated -! arguments in lookup_2d_netcdf (*1 and *2) to arrays -- maybe using an array of a derived -! type containing these arguments; (3) if possible, initially read the lookup table into a -! 1-d array (if the netcdf call allows reading a n-d array into a 1-d array) (if netcdf -! doesn't allow this, then I think we could achieve the same thing by reading 1-d slices -! of the lookup table in a loop, building the full lookup table as a long 1-d array); (4) -! in the call to the generic 'lookup' function, reshape the 1-d lookup table -! appropriately. (Note: I think it would be challenging to combine lookup_1d and lookup_2d -! (etc.) into a single routine using a similar method.) -! -! !USES: - use mkncdio -! !ARGUMENTS: - implicit none - integer , intent(in) :: ncid ! ID of an open netcdf file - character(len=*), intent(in) :: tablename ! name of the lookup table variable - logical , intent(in) :: lookup_has_invalid ! should we use _FillValue? (see above) - character(len=*), intent(in) :: dimname1 ! name of the first (fastest-varying) dimension of the lookup table - character(len=*), intent(in) :: dimname2 ! name of the second dimension of the lookup table - integer , intent(in) :: n_extra_dims ! number of extra dimensions in the lookup table - ! The following arguments are passed directly to lookup_2d: - integer , intent(in) :: index1(:) ! index into dim 1 of lookup table - integer , intent(in) :: index2(:) ! index into dim 2 of lookup table - real(r8) , intent(in) :: fill_val ! value to put in data where we don't have a valid value - real(r8) , intent(out):: data(:) ! output array - integer , intent(out):: ierr ! error return code from the call to lookup_2d - - ! slice to use if lookup table variable has more than 2 dimensions: - type(dim_slice_type), intent(in), optional :: extra_dims(:) - - ! nodata flag in index1 and index2, passed directly to lookup_2d: - integer , intent(in), optional :: nodata - - ! flag for whether trying to use a lookup table value that is equal to the _FillValue - ! should raise an error flag - ! (irrelevant if lookup_has_invalid is .false.) - ! (passed directly to lookup_2d - see the documentation there for more details) - logical , intent(in), optional :: invalid_okay -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - integer :: varid ! netcdf variable id of the lookup table - integer :: ndims ! total number of dimensions of lookup table - integer :: ndims_expected ! value we expect for ndims, for error checking - integer :: i - real(r8) :: table_fillval ! value of the _FillValue attribute for the lookup table - character(len=nf_max_name), allocatable :: dimnames(:) ! dimension names - integer , allocatable :: dimids(:) ! dimension ids - integer , allocatable :: dimlens(:) ! dimension lengths - integer , allocatable :: starts(:) ! starting indices for reading lookup table - integer , allocatable :: counts(:) ! dimension counts for reading lookup table - real(r8), allocatable :: lookup_table(:,:) - logical , allocatable :: valid_entries(:,:) ! which entries of the lookup table are considered valid - - character(len=*), parameter :: subname = 'lookup_2d_netcdf' -!----------------------------------------------------------------------- - - ! Error-check extra_dims - - if (n_extra_dims > 0) then - if (.not. present(extra_dims)) then - write(6,*) subname//' ERROR: extra_dims must be present for n_extra_dims > 0' - call abort() - end if - - if (size(extra_dims) < n_extra_dims) then - write(6,*) subname//' ERROR: not enough extra dimensions given' - write(6,*) 'n_extra_dims = ', n_extra_dims - write(6,*) 'size(extra_dims) = ', size(extra_dims) - call abort() - end if - end if - - ! Determine number of expected dimensions in the table, and actual number of - ! dimensions in the netcdf file - - ndims_expected = 2 + n_extra_dims - - call check_ret(nf_inq_varid (ncid, tablename, varid), subname) - call check_ret(nf_inq_varndims (ncid, varid, ndims), subname) - if (ndims /= ndims_expected) then - write(6,*) subname//' ERROR: unexpected number of dimensions in ', & - trim(tablename) - write(6,*) 'ndims = ', ndims - write(6,*) 'expected (based on n_extra_dims): ', ndims_expected - call abort() - end if - - ! Get dimension names & sizes, and error-check them - - allocate(dimids(ndims), dimlens(ndims), dimnames(ndims)) - call check_ret(nf_inq_vardimid (ncid, varid, dimids), subname) - do i = 1, ndims - call check_ret(nf_inq_dimname (ncid, dimids(i), dimnames(i)), subname) - call check_ret(nf_inq_dimlen (ncid, dimids(i), dimlens(i)), subname) - end do - - call check_dimname(dimnames(1), dimname1, 1) - call check_dimname(dimnames(2), dimname2, 2) - do i = 1, n_extra_dims - call check_dimname(dimnames(2+i), extra_dims(i)%name, 2+i) - call check_dimsize(dimlens(2+i), extra_dims(i)%val, 2+i) - end do - - ! Read the lookup table; if the given variable has more than 2 dimensions, we read - ! a single 2-d slice - - allocate(starts(ndims), counts(ndims)) - allocate(lookup_table(dimlens(1), dimlens(2))) - starts(1:2) = 1 - counts(1:2) = dimlens(1:2) - do i = 1, n_extra_dims - starts(2+i) = extra_dims(i)%val - counts(2+i) = 1 - end do - call check_ret(nf_get_vara_double (ncid, varid, starts, counts, lookup_table), subname) - - ! Determine which entries are valid - - allocate(valid_entries(size(lookup_table, 1), size(lookup_table, 2))) - valid_entries(:,:) = .true. - if (lookup_has_invalid) then - call check_ret(nf_get_att_double (ncid, varid, '_FillValue', table_fillval), subname) - where (lookup_table == table_fillval) - valid_entries = .false. - end where - end if - - ! Do the lookups - - call lookup_2d(index1, index2, lookup_table, fill_val, data, ierr, nodata=nodata, & - valid_entries=valid_entries, invalid_okay=invalid_okay) - - deallocate(valid_entries) - deallocate(lookup_table) - deallocate(starts, counts) - deallocate(dimids, dimlens, dimnames) - contains !------------------------------------------------------------------------------ - subroutine check_dimname(actual, expected, i) - ! Make sure names are equal; if not, stop with an error message + + subroutine get_dominant_indices(factorindexlist, factorlist, & + src_array, dst_array, minval, maxval, nodata, filter) + ! + ! Fills an output array on the destination grid (dst_array) whose values are equal to the + ! (weighted) dominant value in the source grid cells overlapping a given destination grid + ! cell + ! + ! Ignores all values in src_array that are less than minval or greater than maxval (treats + ! those values the same as if they had wt=0). (Note: for memory-use efficiency, it is + ! best if the indices are designed such that most values between minval and maxval are + ! actually used, since an array is allocated of size (maxval - minval + 1)*gridmap%nb.) + ! + ! The filter argument can be used to exclude certain overlaps -- if provided, we only + ! consider overlaps where filter is .true. If not provided, filter is treated as being + ! .true. everywhere. + ! + ! Output grid cells with no contributing valid source points are given the nodata value + ! + ! input/output variables + integer , pointer :: factorindexlist(:,:) + real(r8) , pointer :: factorlist(:) + integer , intent(in) :: src_array(:) ! input values; length gridmap%na + integer , intent(out):: dst_array(:) ! output values; length gridmap%nb + integer , intent(in) :: minval ! minimum valid value in src_array + integer , intent(in) :: maxval ! maximum valid value in src_array + integer , intent(in) :: nodata ! value to assign to dst_array where there are no valid source points + logical, optional , intent(in) :: filter(:) ! only consider overlaps where filter is .true.; length gridmap%ns + + ! local variables + logical , allocatable :: lfilter(:) ! local version of filter + logical , allocatable :: hasdata(:) ! true if an output cell has any valid data; + real(r8), allocatable :: weights(:,:) ! summed weight of each index value for each output cell + integer :: n, ni, no + integer :: k + integer :: maxindex + real(r8) :: wt + real(r8) :: maxwt + integer :: ns_o + character(len=*), parameter :: subname = "get_dominant_indices" + !----------------------------------------------------------------------- + + ns_o = size(dst_array) + allocate(lfilter(ns_o)) + + if (present(filter)) then + if (size(filter) /= ns_o) then + write(6,*) subname//' ERROR: incorrect size of filter' + write(6,*) 'size(filter) = ', size(filter) + write(6,*) 'ns_o = ', ns_o + call shr_sys_abort() + end if + lfilter(:) = filter(:) + else + lfilter(:) = .true. + end if + + allocate(hasdata(ns_o)) + hasdata(:) = .false. + allocate(weights(minval:maxval, ns_o)) + weights(minval:maxval,:) = 0. + + ! Determine weight of each index value for each output (destination) cell + do n = 1, size(factorlist) + ni = factorIndexList(1,n) + no = factorIndexList(2,n) + wt = factorList(n) + k = src_array(ni) + if (k >= minval .and. k <= maxval) then + weights(k,no) = weights(k,no) + wt + hasdata(no) = .true. + end if + end do + + ! Determine output values + ! Note: if a given destination cell has no contributing source points (thus + ! hasdata(no) = false), or the max weight of any index overlapping this destination + ! cell is <= 0, then the output value there will be nodata. + ! (I don't think this latter condition -- weight <= 0 -- is possible, but we handle + ! it anyway) + + dst_array(:) = nodata + do no = 1, ns_o + if (hasdata(no)) then + call which_max(weights(:,no), maxwt, maxindex, lbound=minval) + if (maxwt > 0.) then + dst_array(no) = maxindex + end if + end if + end do + + deallocate(lfilter, weights, hasdata) + + end subroutine get_dominant_indices + + !------------------------------------------------------------------------------ + subroutine get_max_indices(factorindexlist, factorlist, src_array, dst_array, nodata) + ! + ! Fills an output array on the destination grid (dst_array) whose values are equal to + ! the maximum value in the source grid cells overlapping a given destination grid cell. + ! + ! The frequency of occurrence of the source values is irrelevant. For example, if the + ! value 1 appears in 99% of source cells overlapping a given destination cell and the + ! value 2 appears in just 1%, we'll put 2 in the destination cell because it is the + ! maximum value. + ! + ! Output grid cells with no contributing valid source points are given the nodata value + ! + ! input/output variables + integer , pointer :: factorindexlist(:,:) + integer , pointer :: factorlist(:) + integer , intent(in) :: src_array(:) ! input values + integer , intent(out) :: dst_array(:) ! output values + integer , intent(in) :: nodata ! value to assign to dst_array where there are no valid source points + + ! local variables: + logical, allocatable :: hasdata(:) ! true if an output cell has any valid data; + integer :: n, ni, no + real(r8) :: wt + integer :: src_val + integer :: ns_o + character(len=*), parameter :: subname = 'get_max_indices' + !----------------------------------------------------------------------- + + ! Initialize local variables + ns_o = size(dst_array) + allocate(hasdata(ns_o)) + hasdata(:) = .false. + + do n = 1, size(factorlist) + ni = factorIndexList(1,n) + no = factorIndexList(2,n) + wt = factorList(n) + if (wt > 0._r8) then + src_val = src_array(ni) + if (.not. hasdata(no)) then + hasdata(no) = .true. + dst_array(no) = src_val + else if (src_val > dst_array(no)) then + dst_array(no) = src_val + end if + end if + end do + + do no = 1, ns_o + if (.not. hasdata(no)) then + dst_array(no) = nodata + end if + end do + + end subroutine get_max_indices + + !------------------------------------------------------------------------------ + subroutine lookup_2d(index1, index2, lookup_table, fill_val, data, ierr, & + nodata, valid_entries, invalid_okay) + ! + ! Creates a data array using a paint-by-number approach according to a lookup table + ! + ! This routine operates on a 2-d lookup table. There are therefore two index arrays + ! (index1 and index2); these index arrays are on the same grid as the desired data array + ! (thus, index1, index2 and data must all have the same length). Each output point, n, is + ! then generally determined as: + ! + ! data(n) = lookup_table(index1(n), index2(n)) + ! + ! fill_val: value to put in data array where either: + ! (a) index1 or index2 are equal to nodata (if nodata is given) + ! Note that this condition does NOT result in ierr being set + ! (b) valid_entries(index1(n), index2(n)) is false (if valid_entries is given) + ! Note that this condition also results in ierr being set, unless invalid_okay is + ! present and .true. + ! (If valid_entries is not given, it is treated as being .true. everywhere) + ! (c) index1 or index2 out of range + ! Note that this condition also results in ierr being set + ! + ! ierr: error return code (if non-0, indicates first error encountered): + ! 0: no error + ! 1: attempt to assign values from the lookup table that are invalid according + ! to valid_entries (note: this is not considered an error if invalid_okay is + ! present and .true.) + ! 2: attempt to access an out-of-range index in lookup table + ! WJS (2-2-12): My main reason for using ierr rather than aborting in case of error + ! is to facilitate unit testing + ! + ! input/output variables + integer , intent(in) :: index1(:) ! index into dim 1 of lookup_table + integer , intent(in) :: index2(:) ! index into dim 2 of lookup_table + real(r8), intent(in) :: lookup_table(:,:) + real(r8), intent(in) :: fill_val ! value to put in data where we don't have a valid value (see above for details) + real(r8), intent(out):: data(:) ! output arary + integer , intent(out):: ierr ! error return code (0 = no error) + + ! nodata flag in index1 and index2 (see above for details): + integer, intent(in), optional :: nodata + + ! which entries are considered valid (see above for details): + logical, intent(in), optional :: valid_entries(:,:) + + ! invalid_okay: if true, then assigning fill_val because valid_entries is false does + ! NOT raise an error flag (invalid_okay defaults to false, meaning an error is + ! raised in this case): + logical, intent(in), optional :: invalid_okay + + ! local variables: + integer :: n + integer :: i1, i2 + integer :: data_size ! size of index1, index2 and data arrays + integer :: table_n1 ! size of dimension 1 of lookup table + integer :: table_n2 ! size of dimension 2 of lookup table + logical :: linvalid_okay ! local version of invalid_okay + logical, allocatable :: lvalid_entries(:,:) ! local version of valid_entries + character(len=*), parameter :: subname = 'lookup_2d' + !----------------------------------------------------------------------- + + ierr = 0 + + ! Error-check array sizes + + data_size = size(data) + if (size(index1) /= data_size .or. size(index2) /= data_size) then + write(6,*) subname//' ERROR: data array sizes do not match' + write(6,*) 'size(data) = ', data_size + write(6,*) 'size(index1) = ', size(index1) + write(6,*) 'size(index2) = ', size(index2) + call shr_sys_abort() + end if + + table_n1 = size(lookup_table,1) + table_n2 = size(lookup_table,2) + if (present(valid_entries)) then + if (size(valid_entries,1) /= table_n1 .or. size(valid_entries,2) /= table_n2) then + write(6,*) subname//' ERROR: size of valid_entries does not match lookup_table' + write(6,*) 'size(lookup_table) = ', table_n1, table_n2 + write(6,*) 'size(valid_entries) = ', size(valid_entries,1), & + size(valid_entries,2) + call shr_sys_abort() + end if + end if + + ! Set local version of invalid_okay & valid_entries + + if (present(invalid_okay)) then + linvalid_okay = invalid_okay + else + linvalid_okay = .false. + end if + + allocate(lvalid_entries(table_n1, table_n2)) + if (present(valid_entries)) then + lvalid_entries(:,:) = valid_entries(:,:) + else + lvalid_entries(:,:) = .true. + end if + + ! Do the lookups + + do n = 1, data_size + i1 = index1(n) + i2 = index2(n) + + ! First handle special cases: + + ! index is nodata flag (this is NOT an error) + if (present(nodata)) then + if (i1 == nodata .or. i2 == nodata) then + data(n) = fill_val + cycle + end if + end if + + ! index out of range + if (i1 <= 0 .or. i1 > table_n1 .or. & + i2 <= 0 .or. i2 > table_n2) then + data(n) = fill_val + if (ierr == 0) ierr = 2 + cycle + end if + + ! lookup table entry is invalid + if (.not. lvalid_entries(i1, i2)) then + data(n) = fill_val + if (.not. linvalid_okay) then + if (ierr == 0) ierr = 1 + end if + cycle + end if + + ! Finally, the "normal" case, if none of the special cases were triggered: + data(n) = lookup_table(i1, i2) + end do + + deallocate(lvalid_entries) + + end subroutine lookup_2d + + !------------------------------------------------------------------------------ + subroutine lookup_2d_netcdf(pioid, tablename, lookup_has_invalid, & + dimname1, dimname2, n_extra_dims, & + index1, index2, fill_val, data, ierr, & + extra_dims, nodata, invalid_okay) + ! + ! Wrapper to lookup_2d that first reads the lookup table from a netcdf file + ! + ! If lookup_has_invalid is false, then we treat all lookup table entries as valid data + ! (i.e., all valid_entries are true in the call to lookup_2d). If lookup_has_invalid is + ! true, then we read the _FillValue attribute for the lookup table variable, and consider + ! any table entry with value _FillValue to be an invalid entry, thus putting fill_val in + ! these data locations (and raising an error flag unless invalid_okay is present and + ! true). + ! + ! The dimension given by dimname1 -- with the associated indices given by index1 -- is the + ! fastest-varying dimension in the lookup table. Dimension dimname2 (associated with + ! index2) is the second-fastest-varying dimension. Similarly, extra_dims should be ordered + ! from faster-varying to slowest-varying dimension. (The first dimension in extra_dims is + ! the third-fastest-varying dimension in the lookup table.) + ! + ! n_extra_dims gives the number of extra dimensions (in addition to the first two) in the + ! lookup table. We take a single 2-d slice of the lookup table, by using a single value of + ! each of these other dimensions. If n_extra_dims > 0, then extra_dims must be present, + ! with at least n_extra_dims entries. Each entry in extra_dims gives the name of a + ! dimension and the dimension index to use for the slice. + ! + ! If size(extra_dims) > n_extra_dims, then we use the first n_extra_dims entries in + ! extra_dims. If n_extra_dims = 0, then extra_dims is ignored. + ! + ! Note that we ignore any coordinate variables associated with the dimensions of the + ! lookup table; we simply treat the lookup table indices as 1,2,3,... + ! + ! See the lookup_2d documentation for documentation of some other arguments + ! + ! WJS (2-1-12): Some thoughts on avoiding duplication if we eventually want similar + ! routines, lookup_1d_netcdf, lookup_3d_netcdf, etc.: + ! + ! Much of the code in lookup_2d_netcdf could then be pulled out to a shared subroutine + ! (e.g., much of the error-checking code). + ! + ! Or, maybe better: we could try to make a single lookup_netcdf subroutine that handles + ! 1-d, 2-d and any other dimensionality. To do that, we would (1) make a generic interface + ! (of which lookup_1d and lookup_2d would be implementations); (2) change the repeated + ! arguments in lookup_2d_netcdf (*1 and *2) to arrays -- maybe using an array of a derived + ! type containing these arguments; (3) if possible, initially read the lookup table into a + ! 1-d array (if the netcdf call allows reading a n-d array into a 1-d array) (if netcdf + ! doesn't allow this, then I think we could achieve the same thing by reading 1-d slices + ! of the lookup table in a loop, building the full lookup table as a long 1-d array); (4) + ! in the call to the generic 'lookup' function, reshape the 1-d lookup table + ! appropriately. (Note: I think it would be challenging to combine lookup_1d and lookup_2d + ! (etc.) into a single routine using a similar method.) + ! + ! input/output variables + type(file_desc_t) , intent(inout) :: pioid + character(len=*) , intent(in) :: tablename ! name of the lookup table variable + logical , intent(in) :: lookup_has_invalid ! should we use _FillValue? (see above) + character(len=*) , intent(in) :: dimname1 ! name of the first (fastest-varying) dimension of the lookup table + character(len=*) , intent(in) :: dimname2 ! name of the second dimension of the lookup table + integer , intent(in) :: n_extra_dims ! number of extra dimensions in the lookup table + + ! The following arguments are passed directly to lookup_2d: + integer , intent(in) :: index1(:) ! index into dim 1 of lookup table + integer , intent(in) :: index2(:) ! index into dim 2 of lookup table + real(r8) , intent(in) :: fill_val ! value to put in data where we don't have a valid value + real(r8) , intent(out) :: data(:) ! output array + integer , intent(out) :: ierr ! error return code from the call to lookup_2d + + ! slice to use if lookup table variable has more than 2 dimensions: + type(dim_slice_type), intent(in), optional :: extra_dims(:) + + ! nodata flag in index1 and index2, passed directly to lookup_2d: + integer , intent(in), optional :: nodata + + ! flag for whether trying to use a lookup table value that is equal to the _FillValue + ! should raise an error flag + ! (irrelevant if lookup_has_invalid is .false.) + ! (passed directly to lookup_2d - see the documentation there for more details) + logical , intent(in), optional :: invalid_okay + + ! !LOCAL VARIABLES: + type(var_desc_t) :: pio_varid + integer :: ndims ! total number of dimensions of lookup table + integer :: ndims_expected ! value we expect for ndims, for error checking + integer :: i ! index + integer :: rcode ! error status + real(r8) :: table_fillval ! value of the _FillValue attribute for the lookup table + character(len=CS), allocatable :: dimnames(:) ! dimension names + integer , allocatable :: dimids(:) ! dimension ids + integer , allocatable :: dimlens(:) ! dimension lengths + integer , allocatable :: starts(:) ! starting indices for reading lookup table + integer , allocatable :: counts(:) ! dimension counts for reading lookup table + real(r8), allocatable :: lookup_table(:,:) + logical , allocatable :: valid_entries(:,:) ! which entries of the lookup table are considered valid + character(len=*), parameter :: subname = 'lookup_2d_netcdf' + !----------------------------------------------------------------------- + + ! Error-check extra_dims + if (n_extra_dims > 0) then + if (.not. present(extra_dims)) then + write(6,*) subname//' ERROR: extra_dims must be present for n_extra_dims > 0' + call shr_sys_abort() + end if + + if (size(extra_dims) < n_extra_dims) then + write(6,*) subname//' ERROR: not enough extra dimensions given' + write(6,*) 'n_extra_dims = ', n_extra_dims + write(6,*) 'size(extra_dims) = ', size(extra_dims) + call shr_sys_abort() + end if + end if + + ! Determine number of expected dimensions in the table, and actual number of + ! dimensions in the netcdf file + + ndims_expected = 2 + n_extra_dims + + rcode = pio_inq_varid(pioid, trim(tablename), pio_varid) + rcode = pio_inq_varndims(pioid, pio_varid, ndims) + if (ndims /= ndims_expected) then + write(6,*) subname//' ERROR: unexpected number of dimensions in ', & + trim(tablename) + write(6,*) 'ndims = ', ndims + write(6,*) 'expected (based on n_extra_dims): ', ndims_expected + call shr_sys_abort() + end if + + ! Get dimension names & sizes, and error-check them + allocate(dimids(ndims), dimlens(ndims), dimnames(ndims)) + rcode = pio_inq_vardimid (pioid, pio_varid, dimids) + do i = 1, ndims + rcode = pio_inq_dimname (pioid, dimids(i), dimnames(i)) + rcode = pio_inq_dimlen (pioid, dimids(i), dimlens(i)) + end do + call check_dimname(dimnames(1), dimname1, 1) + call check_dimname(dimnames(2), dimname2, 2) + do i = 1, n_extra_dims + call check_dimname(dimnames(2+i), extra_dims(i)%name, 2+i) + call check_dimsize(dimlens(2+i), extra_dims(i)%val, 2+i) + end do + + ! Read the lookup table; if the given variable has more than 2 dimensions, we read + ! a single 2-d slice + + allocate(starts(ndims), counts(ndims)) + allocate(lookup_table(dimlens(1), dimlens(2))) + starts(1:2) = 1 + counts(1:2) = dimlens(1:2) + do i = 1, n_extra_dims + starts(2+i) = extra_dims(i)%val + counts(2+i) = 1 + end do + rcode = pio_get_var(pioid, pio_varid, starts, counts, lookup_table) + + ! Determine which entries are valid + + allocate(valid_entries(size(lookup_table, 1), size(lookup_table, 2))) + valid_entries(:,:) = .true. + if (lookup_has_invalid) then + rcode = pio_get_att(pioid, pio_varid, '_FillValue', table_fillval) + where (lookup_table == table_fillval) + valid_entries = .false. + end where + end if + + ! Do the lookups + call lookup_2d(index1, index2, lookup_table, fill_val, data, ierr, nodata=nodata, & + valid_entries=valid_entries, invalid_okay=invalid_okay) + + deallocate(valid_entries) + deallocate(lookup_table) + deallocate(starts, counts) + deallocate(dimids, dimlens, dimnames) + + contains + + !------------------------------------------------------------------------------ + subroutine check_dimname(actual, expected, i) + ! Make sure names are equal; if not, stop with an error message character(len=*), intent(in) :: actual, expected integer , intent(in) :: i ! dimension number, for output purposes @@ -623,13 +525,13 @@ subroutine check_dimname(actual, expected, i) write(6,*) 'dimension #', i write(6,*) 'actual: ', trim(actual) write(6,*) 'expected: ', trim(expected) - call abort() + call shr_sys_abort() end if - end subroutine check_dimname + end subroutine check_dimname -!------------------------------------------------------------------------------ - subroutine check_dimsize(length, index, i) - ! Make sure dimension length is long enough; if not, stop with an error message + !------------------------------------------------------------------------------ + subroutine check_dimsize(length, index, i) + ! Make sure dimension length is long enough; if not, stop with an error message integer, intent(in) :: length, index integer, intent(in) :: i ! dimension number, for output purposes @@ -640,58 +542,44 @@ subroutine check_dimsize(length, index, i) write(6,*) 'dimension #', i write(6,*) 'index: ', index write(6,*) 'length: ', length - call abort() + call shr_sys_abort() end if - end subroutine check_dimsize - -end subroutine lookup_2d_netcdf -!------------------------------------------------------------------------------ - -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: which_max -! -! !INTERFACE: -subroutine which_max(arr, maxval, maxindex, lbound) -! -! !DESCRIPTION: -! Returns maximum value in arr along with the index of the maximum value -! -! If multiple values are tied, returns index of the first maximum -! -! !ARGUMENTS: - implicit none - real(r8), intent(in) :: arr(:) - real(r8), intent(out):: maxval ! maximum value in arr(:) - integer , intent(out):: maxindex ! first index of maxval - - ! lower bound of indices of arr; if not supplied, assumed to be 1: - integer , intent(in), optional :: lbound -! -! !REVISION HISTORY: -! Author: Bill Sacks -! -! -! !LOCAL VARIABLES: -!EOP - integer :: i -!----------------------------------------------------------------------- - - maxindex = 1 - maxval = arr(1) - - do i = 2, size(arr) - if (arr(i) > maxval) then - maxindex = i - maxval = arr(i) - end if - end do - - if (present(lbound)) then - maxindex = maxindex + (lbound - 1) - end if -end subroutine which_max -!------------------------------------------------------------------------------ + end subroutine check_dimsize + + end subroutine lookup_2d_netcdf + + !------------------------------------------------------------------------------ + subroutine which_max(arr, maxval, maxindex, lbound) + ! + ! Returns maximum value in arr along with the index of the maximum value + ! + ! If multiple values are tied, returns index of the first maximum + ! + ! !ARGUMENTS: + real(r8), intent(in) :: arr(:) + real(r8), intent(out):: maxval ! maximum value in arr(:) + integer , intent(out):: maxindex ! first index of maxval + + ! lower bound of indices of arr; if not supplied, assumed to be 1: + integer , intent(in), optional :: lbound + + ! !LOCAL VARIABLES: + integer :: i + !----------------------------------------------------------------------- + + maxindex = 1 + maxval = arr(1) + + do i = 2, size(arr) + if (arr(i) > maxval) then + maxindex = i + maxval = arr(i) + end if + end do + + if (present(lbound)) then + maxindex = maxindex + (lbound - 1) + end if + end subroutine which_max end module mkindexmapMod diff --git a/tools/mksurfdata_esmf/src/mklanwatMod.F90 b/tools/mksurfdata_esmf/src/mklanwatMod.F90 index 633d049f7e..4d98f8f4ae 100644 --- a/tools/mksurfdata_esmf/src/mklanwatMod.F90 +++ b/tools/mksurfdata_esmf/src/mklanwatMod.F90 @@ -9,7 +9,7 @@ module mklanwatMod use pio use shr_kind_mod , only : r8 => shr_kind_r8, r4 => shr_kind_r4 use shr_sys_mod , only : shr_sys_abort - use mkvarpar , only : re + use mkvarpar , only : re use mkpioMod , only : mkpio_get_rawdata, pio_iotype, pio_ioformat, pio_iosystem use mkesmfMod , only : regrid_rawdata use mkutilsMod , only : chkerr @@ -127,7 +127,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & ! Read in the input data allocate(lake_i(ns_i), stat=rcode) if (rcode/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'PCT_LAKE', mesh_i, lake_i, scale_by_landmask=.true., rc=rc) + call mkpio_get_rawdata(pioid, 'PCT_LAKE', mesh_i, lake_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Regrid lake_i to lake_o - this also returns lake_i to be used in the global sums below @@ -159,7 +159,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & ! read in rawdata allocate(swmp_i(ns_i), stat=rcode) if (rcode/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'PCT_WETLAND', mesh_i, lake_i, scale_by_landmask=.true., rc=rc) + call mkpio_get_rawdata(pioid, 'PCT_WETLAND', mesh_i, lake_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! regrid swmp_i to swmp_o - this also returns swmp_i to be used in the global sums below @@ -190,7 +190,7 @@ subroutine mklakwat(file_mesh_i, file_data_i, mesh_o, & ! read in rawdata allocate(lakedepth_i(ns_i), stat=rcode) if (rcode/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, 'LAKEDEPTH', mesh_i, lakedepth_i, scale_by_landmask=.true., rc=rc) + call mkpio_get_rawdata(pioid, 'LAKEDEPTH', mesh_i, lakedepth_i, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! regrid lakedepth_i to lakedepth_o - this also returns lakedepth_i to be used in the global sums below diff --git a/tools/mksurfdata_esmf/src/mkorganicMod.F90 b/tools/mksurfdata_esmf/src/mkorganicMod.F90 index cf7d3df7ab..e6f2668494 100644 --- a/tools/mksurfdata_esmf/src/mkorganicMod.F90 +++ b/tools/mksurfdata_esmf/src/mkorganicMod.F90 @@ -55,6 +55,8 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) real(r8), allocatable :: data_i(:,:) real(r8), allocatable :: data_o(:,:) character(len=256) :: varname + real(r8), allocatable :: frac_i(:) + real(r8), allocatable :: frac_o(:) character(len=*), parameter :: subname = 'mkorganic' !----------------------------------------------------------------------- @@ -73,7 +75,6 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) call ESMF_VMLogMemInfo("After pio_openfile "//trim(file_data_i)) ! Get dimensions of raw data. - ! NOTE: ! - raw data is dimensions (lon,lat,lev) ! - input read from pio has dimensions(n,lev) ! - esmf field dataptr has dimensions (lev,n) @@ -107,7 +108,7 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) ! Input data is read into (ns_i,nlay) array and then transferred to data_i(nlay,ns_i) allocate(data_i(nlay,ns_i),stat=ier) if (ier/=0) call shr_sys_abort() - call mkpio_get_rawdata(pioid, varname, mesh_i, data_i, scale_by_landmask=.true., rc=rc) + call mkpio_get_rawdata(pioid, varname, mesh_i, data_i, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After mkpio_getrawdata in "//trim(subname)) @@ -132,20 +133,41 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_VMLogMemInfo("After regridstore in "//trim(subname)) - ! Regrid raw data to model resolution + ! Regrid data_i to data_o and frac_i to frac_o call regrid_rawdata(field_i, field_o, routehandle, data_i, data_o, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMLogMemInfo("After regrid_data in "//trim(subname)) - ! Close the file - call pio_closefile(pioid) - call ESMF_VMLogMemInfo("After pio_freedecomp in "//trim(subname)) - - ! Now compute organic_o - need to remember that nlay is innermost dimension in data_o - ! but outermost dimension in organic_o do l = 1,nlevsoi do n = 1,size(organic_o, dim=1) organic_o(n,l) = data_o(l,n) + end do + end do + + ! Determine frac_o (regrid frac_i to frac_o) + allocate(frac_i(ns_i)) + allocate(frac_o(ns_o)) + call mkpio_get_rawdata(pioid, 'LANDMASK', mesh_i, frac_i, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldDestroy(field_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_FieldDestroy(field_o, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + field_i = ESMF_FieldCreate(mesh_i, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_o = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call regrid_rawdata(field_i, field_o, routehandle, frac_i, frac_o, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMLogMemInfo("After regrid_data in data_i "//trim(subname)) + + ! Divide organic_o by frac_o + do n = 1,ns_o + if (frac_o(n) > 0._r8) then + organic_o(n,:) = organic_o(n,:) / frac_o(n) + end if + end do + do l = 1,nlevsoi + do n = 1,size(organic_o, dim=1) if ((organic_o(n,l)) > 130.000001_r8) then write (6,*) trim(subname)//' error: organic = ',organic_o(n,l), & ' greater than 130.000001 for n,lev ',n,l @@ -154,13 +176,16 @@ subroutine mkorganic(file_mesh_i, file_data_i, mesh_o, organic_o, rc) enddo end do + ! Close the file + call pio_closefile(pioid) + call ESMF_VMLogMemInfo("After pio_closefile in "//trim(subname)) + ! Release memory - ! TODO: something is hanging here - ! call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - ! call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() - ! call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) + call ESMF_RouteHandleDestroy(routehandle, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_MeshDestroy(mesh_i, nogarbage = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) call shr_sys_abort() + call ESMF_VMLogMemInfo("After destroy operations in "//trim(subname)) if (root_task) then write (ndiag,'(a,i8)') 'Successfully made organic matter ' diff --git a/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 b/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 index 4a9ea12f97..9c009a3d8e 100644 --- a/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpftUtilsMod.F90 @@ -69,7 +69,7 @@ subroutine convert_from_p2g_default(pct_p2g, pctnatpft, pctcft) if (ubound(pct_p2g, 1) /= cft_ub) then write(6,*) subname, ' ERROR: upper bound of pct_p2g should be cft_ub' write(6,*) 'ubound(pct_p2g), cft_ub = ', ubound(pct_p2g), cft_ub - call abort() + call shr_sys_abort() end if allocate(default_natpft(natpft_lb:natpft_ub)) @@ -135,7 +135,7 @@ subroutine convert_from_p2g_missing_crops(pct_p2g, pctcft_saved, pctnatpft, pctc if (num_cft == 0) then write(6,*) subname, ' ERROR: this routine should only be called when running with prognostic crops' write(6,*) '(i.e., with num_cft > 0)' - call abort() + call shr_sys_abort() end if do pft_index = natpft_ub + 1, ubound(pct_p2g, 1) @@ -146,7 +146,7 @@ subroutine convert_from_p2g_missing_crops(pct_p2g, pctcft_saved, pctnatpft, pctc write(6,*) '(we do not currently handle the case where the transient input dataset' write(6,*) 'has non-zero areas for both pft 15 and pft 16)' write(6,*) 'pft_index, area = ', pft_index, pct_p2g(pft_index) - call abort() + call shr_sys_abort() end if end do diff --git a/tools/mksurfdata_esmf/src/mkpioMod.F90 b/tools/mksurfdata_esmf/src/mkpioMod.F90 index 29b60668ee..2f774c14e5 100644 --- a/tools/mksurfdata_esmf/src/mkpioMod.F90 +++ b/tools/mksurfdata_esmf/src/mkpioMod.F90 @@ -24,8 +24,9 @@ module mkpioMod private :: mkpio_defvar interface mkpio_get_rawdata - module procedure mkpio_get_rawdata1d - module procedure mkpio_get_rawdata2d + module procedure mkpio_get_rawdata1d_int + module procedure mkpio_get_rawdata1d_real + module procedure mkpio_get_rawdata2d_real end interface mkpio_get_rawdata interface mkpio_def_spatial_var @@ -50,14 +51,55 @@ module mkpioMod contains !=============================================================== - subroutine mkpio_get_rawdata1d(pioid, varname, mesh_i, data_i, scale_by_landmask, rc) + subroutine mkpio_get_rawdata1d_int(pioid, varname, mesh_i, data_i, rc) + + ! input/output variables + type(file_desc_t), intent(inout) :: pioid + character(len=*) , intent(in) :: varname ! field name in rawdata file + type(ESMF_Mesh) , intent(in) :: mesh_i + integer , intent(inout) :: data_i(:) ! input raw data + integer , intent(out) :: rc + + ! local variables + type(var_desc_t) :: pio_varid + integer :: pio_vartype + type(io_desc_t) :: pio_iodesc_data + type(io_desc_t) :: pio_iodesc_mask + integer :: lsize + integer :: rcode + integer :: n + character(len=*), parameter :: subname = 'mkpio_get_rawdata1d' + !------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Get data_i - Read in varname from filename + lsize = size(data_i) + + ! Create io descriptor for input raw data + ! This will query the raw data file for the dimensions of the variable varname and + ! create iodesc for either single or multi level input data + call mkpio_iodesc_rawdata(mesh_i, trim(varname), pioid, pio_varid, pio_vartype, pio_iodesc_data, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Read the input raw data + call ESMF_VMLogMemInfo("After mkpio_iodesc_data for varname "//trim(varname)) + call pio_read_darray(pioid, pio_varid, pio_iodesc_data, data_i, rcode) + call ESMF_VMLogMemInfo("After call to pio_read_darrayy for varname "//trim(varname)) + call pio_freedecomp(pioid, pio_iodesc_data) + call ESMF_VMLogMemInfo("After call to pio_freedecomp for "//trim(varname)) + call ESMF_LogWrite("At end of "//trim(subname), ESMF_LOGMSG_INFO) + + end subroutine mkpio_get_rawdata1d_int + + !=============================================================== + subroutine mkpio_get_rawdata1d_real(pioid, varname, mesh_i, data_i, rc) ! input/output variables type(file_desc_t), intent(inout) :: pioid character(len=*) , intent(in) :: varname ! field name in rawdata file type(ESMF_Mesh) , intent(in) :: mesh_i real(r8) , intent(inout) :: data_i(:) ! input raw data - logical , intent(in) :: scale_by_landmask integer , intent(out) :: rc ! local variables @@ -108,32 +150,16 @@ subroutine mkpio_get_rawdata1d(pioid, varname, mesh_i, data_i, scale_by_landmask call pio_freedecomp(pioid, pio_iodesc_data) call ESMF_VMLogMemInfo("After call to pio_freedecomp for "//trim(varname)) - ! Read in the variable LANDMASK and scale the input data by landmask if appropriate - ! if (scale_by_landmask) then - ! call mkpio_iodesc_rawdata(mesh_i, 'LANDMASK', pioid, pio_varid, pio_vartype, pio_iodesc_mask, rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return - ! allocate(landmask(lsize)) - ! call pio_read_darray(pioid, pio_varid, pio_iodesc_mask, landmask, rcode) - ! do n = 1,lsize - ! data_i(n) = data_i(n)*landmask(n) - ! end do - ! deallocate(landmask) - ! call pio_freedecomp(pioid, pio_iodesc_mask) - ! end if - - call ESMF_VMLogMemInfo("At end of "//trim(subname)) - - end subroutine mkpio_get_rawdata1d + end subroutine mkpio_get_rawdata1d_real !=============================================================== - subroutine mkpio_get_rawdata2d(pioid, varname, mesh_i, data_i, scale_by_landmask, rc) + subroutine mkpio_get_rawdata2d_real(pioid, varname, mesh_i, data_i, rc) ! input/output variables type(file_desc_t) , intent(inout) :: pioid character(len=*) , intent(in) :: varname ! field name in rawdata file type(ESMF_Mesh) , intent(in) :: mesh_i real(r8) , intent(inout) :: data_i(:,:) ! input raw data - logical, optional , intent(in) :: scale_by_landmask integer , intent(out) :: rc ! local variables @@ -194,39 +220,7 @@ subroutine mkpio_get_rawdata2d(pioid, varname, mesh_i, data_i, scale_by_landmask end if call pio_freedecomp(pioid, pio_iodesc_data) - ! Read in the variable LANDMASK and scale the input data by landmask if appropriate - if (scale_by_landmask) then - call mkpio_iodesc_rawdata(mesh_i, 'LANDMASK', pioid, pio_varid, pio_vartype, pio_iodesc_mask, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_LogWrite("Reading ing LANDMASK", ESMF_LOGMSG_INFO) - allocate(landmask(lsize)) - if (pio_vartype == PIO_REAL) then - allocate(data_real1d(lsize)) - call pio_read_darray(pioid, pio_varid, pio_iodesc_mask, data_real1d, rcode) - do n = 1,lsize - landmask(n) = data_real1d(n) - end do - deallocate(data_real1d) - else if (pio_vartype == PIO_DOUBLE) then - allocate(data_double1d(lsize)) - call pio_read_darray(pioid, pio_varid, pio_iodesc_mask, data_double1d, rcode) - do n = 1,lsize - landmask(n) = real(data_double1d(n), kind=r4) - end do - deallocate(data_double1d) - end if - do l = 1,nlev - do n = 1,lsize - data_i(l,n) = data_i(l,n) * landmask(n) - end do - end do - call ESMF_LogWrite("Finished read in LANDMASK", ESMF_LOGMSG_INFO) - deallocate(landmask) - call pio_freedecomp(pioid, pio_iodesc_mask) - end if - - end subroutine mkpio_get_rawdata2d + end subroutine mkpio_get_rawdata2d_real !=============================================================== subroutine mkpio_iodesc_rawdata( mesh, varname, pioid, pio_varid, pio_vartype, pio_iodesc, rc) diff --git a/tools/mksurfdata_esmf/src/mksurfdata b/tools/mksurfdata_esmf/src/mksurfdata deleted file mode 100755 index 5a8e95c7a7594bfa05cc997267e1ecd06e78d45c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4224448 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�w|wH(;8?$aI^#x>y~iSF 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 delta 754296 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 nLr_4?-7JQ%za2Br$1 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

    e|@;k;rc5BHJ_ zC?mbn$< zUPcc7=~@yv8vr1%t1<$^rHXsrMFQ(Z6jOL5$}{x@GGCU!AB};)M?Hc4@xatM%EjYE zV51-@j(~aj;5tf!miC<`jAH`vsnhBtiwk@lh3t}Xfe*%4j0@1vVwr;J@)o2}My>o) zSiJ(3;RKWc`oHm-MI#n1usZ;M26zVTWpmi}L6n3)htxbWzxvb-|I4}Q(Q*-RMyV3;AL8W)ADA1A^$zzIaEoT>j*&NAgWW6~1Ih`hMKPoh);rZa!;3Dpqm9$2XxaL{k;OuhwSPzMP1^{SU8-)Ns$yWwQGS2$P z=NhmZ75S)lCQ~OnR6fy4j__zThY?OpqBzaLXBy@jqvjRr>+IViJSVq%QPH=JOA9#D zm~PiaZ44b$v+mSK8ulc%4lDN_KktCJ6F?~CBb*SP^Gmey-@cXE;K^0eNYe$$G#*Cm zOm)eWrfIHkyPKvtYnnO}pf6sLuEHqnURlkwx0WNaTN_P>JI@0Y-FmsuScj?o0|x?& zN6T3}GUpRc=qx?vtUWKl3tJIHLUaTW@eY0M!~VZoK@$i;_aO|_gtD2w*? zw-=oWCf4x@_{%(tkoVxb6# zyW=MnhoPg4gON_b#J4@JAeU?lUUBp$a!f;5sU2o!2Yq=?cAz{s$+1qlqh4d<)E6Gc zSfA|(cVqp!YdCx;jwX~|UsUNq*6c$tGjPXIfuMTD*o{fH3EW3NtH4sg)|!q2-|V%{OKeQ%;fS~o zcU}kZl{Q~vM+e6!EKtQ31GQZSoTc%JK<%-%)GSSxoTWA4zC^T{ymI4%dFl$i=SX$2 zrJfexCV(RNf)ueM<(ax!8o8fSBj-4(%+1mkq^e<_lJ}Q)5`BdbndYEZSBBn_LT8@n zONBlpbf!7z)F~Cv-kL&Zp6G8D`l!&E=Ah4r(Ve>}erS*?~w zri=8~s-7*XhpE*=)8ykwxLm=~cSv#&=t`3Z2Xk%qGWWWZfrS`b9lce^x5E>Mb>{sX zs&;`>6z*Fc@`C%xkl(@BWR5>XY%9`mDurYV0Qua5fIP=T4#cXvVStcV3-VqRwWCO! z6)ETx;R@OxE&_hwD7Jq@XiUR(b`lhSVl{bq~6XGmaH8F%bP zhr}5uIs7#pkC|2$2Y74yn$8jWBW_>FI{1NdCrtCV;(Kv10Hz4>A)@wtwG_JxJlk8y zzjzy4JEqn$^=69Z5sLTh7_Hiy-l=`4Gg?kF=uf`m*u~Hp(*$E&z}kL{uUl~NjB$c- z=@G1Gvnpb075R2F6H}k)bkhoJPv4cARFIe)LF1$%JSzG>%Z`fmKSMuu`+m%Np9}HDFaPS+9f0vp0%-+giKFo)psk7=nsYSX2t%DdFVWd| z^e@C9<*3%8w{7dB?2B7Uv!h133+y(04EK}+$K2C<>*=0W;ToP7?<%O^LkrJydZ0UKYv7*p7pRnP-w)>f$Te4|!N%i2 z!;(ETB*jv#DwsOO;y1*g$vV%)%Sa>Ik&^X}#gg?R9t@pFcPDfn*}kZEgtZh3yW)>` z9C85H$eBd6XyfvM6H0lK~;<*8#s@Qi{U;+G`Rma-1q(3hq*&8Dc|^1OiF5f zfYk-cfJCJ{PhHaUoF%Q~CPz*+_^FX?`l9Fg>9579{7pNSOuAofGXdAGpdpn?y)7b^GRu?ACQ-xG>F|OUcPnV~GT&y!aF2ZpyX_RA zF~xQQ<(YZ`VZOA@j@TI__J2IFeF?F6vj_$UCd0xka1PnqMqn^9vYpcJ36y)?H-iMW ziYTUG*nvb?h^#DupT8Rf{@D|lb+unD0gtGN2^M3fiP?_qd6KXLh zQ|^rFNUi~AFnL?kPrg+8RArrec_2VhReTHX+rw%HAG25KX-_ zhJc4DAJ&}!Yd+@34kptAVftkR}I#Wo~QBdRpYV!H=E>KpZZpPpxG&u^USXd0%o zgZPla)pRx)xwJVVx8AOeT)43#{Gl-QHxH19%ULXCg+Kmg(z*;c{TDaQ@-khr<(D;` zPoaH3?R*NC`13UWT=k)0g<7|3A6DoBzqdbKQ@i7ZmF@>OkOKf~jP|^{v9Kd7b5-M%yI&XwJJjYv zFUhi5wEQLRzS!qbEx%Wxt_=sNi+o`=B~$n>Z&cxG7T!Ym7@0BU+vP&U$g8bzEek&o z6ut>9y⩰KOt8Wip?EqtyO=G}V4B1&@T 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�B|icHjprSfVyo2GbmOf-9W{h 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